Hi revane, arielbernal, tareqsiraj,

cpp11-migrate: Add command line option to enables transforms automatically.

It is now possible to states what compilers we wants to support on the command
line, the tranform will be selected automatically.

The new option is `-toward` by I'm open to suggestion for the name (`-to`,
`-targets`, `-P` for platform, ...):

As stated in the documentation the usage is like this (to migrate toward Clang
>= 3.2 and GCC >= 4.7):

  cpp11-migrate -toward clang-3.2 -toward gcc-4.7 <args...>

http://llvm-reviews.chandlerc.com/D1154

Files:
  cpp11-migrate/AddOverride/AddOverride.cpp
  cpp11-migrate/AddOverride/AddOverride.h
  cpp11-migrate/Core/Transforms.cpp
  cpp11-migrate/Core/Transforms.h
  cpp11-migrate/tool/Cpp11Migrate.cpp
  docs/MigratorUsage.rst
  test/cpp11-migrate/Combined/compilers.cpp
Index: cpp11-migrate/AddOverride/AddOverride.cpp
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.cpp
+++ cpp11-migrate/AddOverride/AddOverride.cpp
@@ -22,12 +22,6 @@
 using clang::ast_matchers::MatchFinder;
 using namespace clang::tooling;
 using namespace clang;
-namespace cl = llvm::cl;
-
-static cl::opt<bool> DetectMacros(
-    "override-macros",
-    cl::desc("Detect and use macros that expand to the 'override' keyword."),
-    cl::cat(TransformsOptionsCategory));
 
 int AddOverrideTransform::apply(FileOverrides &InputStates,
                                 const CompilationDatabase &Database,
Index: cpp11-migrate/AddOverride/AddOverride.h
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.h
+++ cpp11-migrate/AddOverride/AddOverride.h
@@ -27,8 +27,8 @@
 /// member functions overriding base class virtual functions.
 class AddOverrideTransform : public Transform {
 public:
-  AddOverrideTransform(const TransformOptions &Options)
-      : Transform("AddOverride", Options) {}
+  AddOverrideTransform(const TransformOptions &Options, bool DetectMacros)
+      : Transform("AddOverride", Options), DetectMacros(DetectMacros) {}
 
   /// \see Transform::run().
   virtual int apply(FileOverrides &InputStates,
@@ -40,6 +40,7 @@
 
 private:
   AddOverrideFixer *Fixer;
+  bool DetectMacros;
 };
 
 #endif // CPP11_MIGRATE_ADD_OVERRIDE_H
Index: cpp11-migrate/Core/Transforms.cpp
===================================================================
--- cpp11-migrate/Core/Transforms.cpp
+++ cpp11-migrate/Core/Transforms.cpp
@@ -13,38 +13,228 @@
 //===----------------------------------------------------------------------===//
 
 #include "Core/Transforms.h"
-#include "Core/Transform.h"
+#include "AddOverride/AddOverride.h"
+#include "LoopConvert/LoopConvert.h"
+#include "ReplaceAutoPtr/ReplaceAutoPtr.h"
+#include "UseAuto/UseAuto.h"
+#include "UseNullptr/UseNullptr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
 
 namespace cl = llvm::cl;
 
-static cl::OptionCategory TransformCategory("Transforms");
+/// \brief Convenience class to handle versions.
+struct Version {
+  unsigned Major;
+  unsigned Minor;
 
-Transforms::~Transforms() {
-  for (std::vector<Transform*>::iterator I = ChosenTransforms.begin(),
-       E = ChosenTransforms.end(); I != E; ++I) {
-    delete *I;
+  Version() : Major(0), Minor(0) {}
+  Version(unsigned Major) : Major(Major), Minor(0) {}
+  Version(unsigned Major, unsigned Minor) : Major(Major), Minor(Minor) {}
+
+  bool operator<(Version RHS) const {
+    if (Major < RHS.Major)
+      return true;
+    if (Major == RHS.Major)
+      return Minor < RHS.Minor;
+    return false;
   }
-  for (OptionVec::iterator I = Options.begin(),
-       E = Options.end(); I != E; ++I) {
-    delete I->first;
+
+  bool operator==(Version RHS) const {
+    return Major == RHS.Major && Minor == RHS.Minor;
+  }
+
+  bool operator!=(Version RHS) const { return !(*this == RHS); }
+  bool operator>(Version RHS) const { return RHS < *this; }
+  bool operator<=(Version RHS) const { return !(*this > RHS); }
+  bool operator>=(Version RHS) const { return !(*this < RHS); }
+
+  bool isNullVersion() const { return Minor == 0 && Major == 0; }
+
+  static Version createFromString(llvm::StringRef VersionStr, bool *Valid) {
+    assert(Valid && "non-null argument expected.");
+    llvm::StringRef MajorStr, MinorStr;
+    Version V;
+
+    *Valid = true;
+    llvm::tie(MajorStr, MinorStr) = VersionStr.split('.');
+    if (!MinorStr.empty())
+      *Valid = !MinorStr.getAsInteger(10, V.Minor);
+    *Valid = *Valid && !MajorStr.getAsInteger(10, V.Major);
+    return V;
   }
+};
+
+/// \brief Category to group all transforms together in the command line help
+static cl::OptionCategory TransformCategory("Transforms");
+
+typedef Transform *(*TransformCreator)(const TransformOptions &);
+template <typename T>
+Transform *ConstructTransform(const TransformOptions &Options) {
+  return new T(Options);
 }
 
-void Transforms::registerTransform(llvm::StringRef OptName,
-                                   llvm::StringRef Description,
-                                   TransformCreator Creator) {
-  Options.push_back(OptionVec::value_type(
-      new cl::opt<bool>(OptName.data(), cl::desc(Description.data()),
-                        cl::cat(TransformCategory)),
-      Creator));
+struct TransformOption {
+  // Function that returns true if the option can skip the compiler version
+  // check because the option is C++11 "aware" (e.g: uses of a macro that
+  // expands only on the supported compilers).
+  typedef bool (*Cpp11AwareOpt)();
+
+  TransformOption(const char *OptName, const char *Desc, Version ClangVersion,
+                  Version GCCVersion, Version ICCVersion, Version MSVCVersion,
+                  TransformCreator Creator, Cpp11AwareOpt Cpp11AwareChecker = 0)
+      : Opt(OptName, cl::desc(Desc), cl::cat(TransformCategory)),
+        ClangVersion(ClangVersion), GCCVersion(GCCVersion),
+        ICCVersion(ICCVersion), MSVCVersion(MSVCVersion), Creator(Creator),
+        Cpp11AwareChecker(Cpp11AwareChecker) {}
+
+  const cl::opt<bool> Opt;
+  // Versions of the compilers since the feature has been implemented
+  // @{
+  const Version ClangVersion;
+  const Version GCCVersion;
+  const Version ICCVersion;
+  const Version MSVCVersion;
+  // @}
+  const TransformCreator Creator;
+  // if non-null can be called to decide wether or not the compilers should
+  // check if the feature is supported or not.
+  const Cpp11AwareOpt Cpp11AwareChecker;
+};
+
+static cl::opt<bool> DetectMacros(
+    "override-macros",
+    cl::desc("Detect and use macros that expand to the 'override' keyword."),
+    cl::cat(TransformsOptionsCategory));
+
+// ConstructTransform "specialization" that handles the forwarding of the
+// "override-macros" option to the AddOverrideTransform constructor.
+Transform *ConstructAddoverrideTransform(const TransformOptions &Options) {
+  return new AddOverrideTransform(Options, DetectMacros);
 }
 
-void
-Transforms::createSelectedTransforms(const TransformOptions &GlobalOptions) {
-  for (OptionVec::iterator I = Options.begin(),
-       E = Options.end(); I != E; ++I) {
-    if (*I->first) {
-      ChosenTransforms.push_back(I->second(GlobalOptions));
+// if "-override-macros" is provided we assume the macros is C++11 aware and we
+// can skip the supported compilers version check.
+static bool AddOverrideCpp11AwareMacros() { return DetectMacros; }
+
+// Add more transforms into this array
+static TransformOption TransformOpts[] = {
+  TransformOption("add-override",
+                  "Make use of override specifier where possible",
+                  /*Clang=*/Version(3, 0),
+                  /*GCC=*/Version(4, 7),
+                  /*ICC=*/Version(14),
+                  /*MSVC=*/Version(8), &ConstructAddoverrideTransform,
+                  &AddOverrideCpp11AwareMacros),
+  TransformOption(
+      "loop-convert", "Make use of range-based for loops where possible",
+      /*Clang=*/Version(3, 0),
+      /*GCC=*/Version(4, 6),
+      /*ICC=*/Version(13),
+      /*MSVC=*/Version(11), &ConstructTransform<LoopConvertTransform>),
+  TransformOption("replace-auto_ptr",
+                  "Replace auto_ptr (deprecated) by unique_ptr (EXPERIMENTAL)",
+                  /*Clang=*/Version(3, 0),
+                  /*GCC=*/Version(4, 6),
+                  /*ICC=*/Version(13),
+                  /*MSVC=*/Version(11),
+                  &ConstructTransform<ReplaceAutoPtrTransform>),
+  TransformOption("use-auto", "Use of 'auto' type specifier",
+                  /*Clang=*/Version(2, 9),
+                  /*GCC=*/Version(4, 4),
+                  /*ICC=*/Version(12),
+                  /*MSVC=*/Version(10), &ConstructTransform<UseAutoTransform>),
+  TransformOption("use-nullptr", "Make use of nullptr keyword where possible",
+                  /*Clang=*/Version(3, 0),
+                  /*GCC=*/Version(4, 6),
+                  /*ICC=*/Version(12, 1),
+                  /*MSVC=*/Version(10),
+                  &ConstructTransform<UseNullptrTransform>)
+};
+
+cl::list<std::string> Platforms(
+    "toward", cl::value_desc("platform"), cl::ZeroOrMore,
+    cl::desc(
+        "Add a platform to be supported by the migration.\n"
+        "All transforms supported by all of the given platforms"
+        " will be used for the migration.\n"
+        "Currently supports:\n"
+        "\tc++11, clang-VERSION, gcc-VERSION, icc-VERSION and msvc-VERSION\n"
+        "where VERSION is MAJOR[.MINOR], example:\n"
+        "\tcpp11-migrate -toward clang-3.1 -toward gcc-4.7 -toward icc-12.1 "
+        "-toward msvc-11 <args...>"));
+
+Transforms::~Transforms() {
+  for (std::vector<Transform *>::iterator I = ChosenTransforms.begin(),
+                                          E = ChosenTransforms.end();
+       I != E; ++I)
+    delete *I;
+}
+
+void Transforms::createSelectedTransforms(const TransformOptions &Options) {
+  Version ClangVersion, GCCVersion, ICCVersion, MSVCVersion;
+  bool Cpp11Enabled = false;
+
+  for (std::vector<std::string>::iterator I = Platforms.begin(),
+                                          E = Platforms.end();
+       I != E; ++I) {
+    llvm::StringRef Platform = *I;
+
+    if (Platform == "c++11") {
+      Cpp11Enabled = true;
+    } else {
+      // Assume "plaform-version" format
+      llvm::StringRef VersionStr;
+      llvm::tie(Platform, VersionStr) = Platform.split('-');
+
+      Version *V = llvm::StringSwitch<Version *>(Platform)
+          .Case("clang", &ClangVersion).Case("gcc", &GCCVersion)
+          .Case("icc", &ICCVersion).Case("msvc", &MSVCVersion).Default(NULL);
+
+      if (V == NULL) {
+        llvm::errs() << Platform << ": unsupported platform\n";
+        return;
+      }
+      if (VersionStr.empty()) {
+        llvm::errs() << Platform << ": missing version number in platform\n";
+        return;
+      }
+      bool Valid;
+      Version Version = Version::createFromString(VersionStr, &Valid);
+
+      if (!Valid) {
+        llvm::errs() << Platform << ": invalid version " << VersionStr << "\n";
+        return;
+      }
+      // keep only the lowest version
+      if (V->isNullVersion() || Version < *V)
+        *V = Version;
+
+      // If a compiler with version is provided, enable C++11 implicitly,
+      // unsupported transforms will be filtered-out when the compilers versions
+      // are checked.
+      Cpp11Enabled = true;
     }
   }
+
+  for (std::size_t I = 0; I < llvm::array_lengthof(TransformOpts); ++I) {
+    const TransformOption &TO = TransformOpts[I];
+    bool SkipVersionCheck = TO.Cpp11AwareChecker && TO.Cpp11AwareChecker();
+
+    if (!SkipVersionCheck)
+      // skip the transform if not supported by the compiler
+      if ((!ClangVersion.isNullVersion() && ClangVersion < TO.ClangVersion) ||
+          (!GCCVersion.isNullVersion() && GCCVersion < TO.GCCVersion) ||
+          (!ICCVersion.isNullVersion() && ICCVersion < TO.ICCVersion) ||
+          (!MSVCVersion.isNullVersion() && MSVCVersion < TO.MSVCVersion))
+        continue;
+
+    // neither C++11 is enabled nor the option is provided explicitly, no reason
+    // to apply the transform
+    if (!Cpp11Enabled && !TO.Opt)
+      continue;
+
+    ChosenTransforms.push_back(TO.Creator(Options));
+  }
 }
Index: cpp11-migrate/Core/Transforms.h
===================================================================
--- cpp11-migrate/Core/Transforms.h
+++ cpp11-migrate/Core/Transforms.h
@@ -17,44 +17,21 @@
 #ifndef CPP11_MIGRATE_TRANSFORMS_H
 #define CPP11_MIGRATE_TRANSFORMS_H
 
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/StringRef.h"
-
 #include <vector>
 
-// Forward declarations
-namespace llvm {
-namespace cl {
-class Option;
-} // namespace cl
-} // namespace llvm
 class Transform;
 struct TransformOptions;
 
-typedef Transform *(*TransformCreator)(const TransformOptions &);
-template <typename T>
-Transform *ConstructTransform(const TransformOptions &Options) {
-  return new T(Options);
-}
-
 /// \brief Class encapsulating the creation of command line bool options
 /// for each transform and instantiating transforms chosen by the user.
 class Transforms {
 public:
   typedef std::vector<Transform*> TransformVec;
   typedef TransformVec::const_iterator const_iterator;
 
 public:
-
   ~Transforms();
 
-  /// \brief Registers a transform causing the transform to be made available
-  /// on the command line.
-  ///
-  /// Be sure to register all transforms *before* parsing command line options.
-  void registerTransform(llvm::StringRef OptName, llvm::StringRef Description,
-                         TransformCreator Creator);
-
   /// \brief Instantiate all transforms that were selected on the command line.
   ///
   /// Call *after* parsing options.
@@ -67,14 +44,9 @@
   /// \brief Return an iterator to the end of a container of instantiated
   /// transforms.
   const_iterator end() const { return ChosenTransforms.end(); }
-
 private:
-  typedef std::vector<std::pair<llvm::cl::opt<bool>*, TransformCreator> >
-    OptionVec;
 
-private:
   TransformVec ChosenTransforms;
-  OptionVec Options;
 };
 
 #endif // CPP11_MIGRATE_TRANSFORMS_H
Index: cpp11-migrate/tool/Cpp11Migrate.cpp
===================================================================
--- cpp11-migrate/tool/Cpp11Migrate.cpp
+++ cpp11-migrate/tool/Cpp11Migrate.cpp
@@ -20,11 +20,6 @@
 #include "Core/SyntaxCheck.h"
 #include "Core/Transform.h"
 #include "Core/Transforms.h"
-#include "LoopConvert/LoopConvert.h"
-#include "UseNullptr/UseNullptr.h"
-#include "UseAuto/UseAuto.h"
-#include "AddOverride/AddOverride.h"
-#include "ReplaceAutoPtr/ReplaceAutoPtr.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
@@ -112,24 +107,6 @@
   llvm::sys::PrintStackTraceOnErrorSignal();
   Transforms TransformManager;
 
-  TransformManager.registerTransform(
-      "loop-convert", "Make use of range-based for loops where possible",
-      &ConstructTransform<LoopConvertTransform>);
-  TransformManager.registerTransform(
-      "use-nullptr", "Make use of nullptr keyword where possible",
-      &ConstructTransform<UseNullptrTransform>);
-  TransformManager.registerTransform(
-      "use-auto", "Use of 'auto' type specifier",
-      &ConstructTransform<UseAutoTransform>);
-  TransformManager.registerTransform(
-      "add-override", "Make use of override specifier where possible",
-      &ConstructTransform<AddOverrideTransform>);
-  TransformManager.registerTransform(
-      "replace-auto_ptr", "Replace auto_ptr (deprecated) by unique_ptr"
-                          " (EXPERIMENTAL)",
-      &ConstructTransform<ReplaceAutoPtrTransform>);
-  // Add more transform options here.
-
   // This causes options to be parsed.
   CommonOptionsParser OptionsParser(argc, argv);
 
Index: docs/MigratorUsage.rst
===================================================================
--- docs/MigratorUsage.rst
+++ docs/MigratorUsage.rst
@@ -76,6 +76,59 @@
   with other accepted changes. Re-applying the transform will resolve deferred
   changes.
 
+.. option:: -toward <platform>
+
+  Select the platforms to support. The transforms will be selected automatically
+  to work on all selected platform.
+
+  There is a special platform **c++11** that enables all transforms.
+
+  ``cpp11-migrate -toward c++11 <args..>``
+
+
+  And there is four compilers supported, the transforms are enabled according to
+  this table:
+
+  ================  =====  ===  ====  ====
+  Transforms        clang  gcc  icc   mscv
+  ================  =====  ===  ====  ====
+  AddOverride (1)   3.0    4.7  14    8
+  LoopConvert       3.0    4.6  13    11
+  ReplaceAutoPtr    3.0    4.6  13    11
+  UseAuto           2.9    4.4  12    10
+  UseNullptr        3.0    4.6  12.1  10
+  ================  =====  ===  ====  ====
+
+  (1): if *-override-macros* is provided it's assumed that the macros is C++11
+  aware and the transform is enabled without regard to the supported compilers.
+
+
+  The version has to be provided like this `-toward COMPILER-VERSION`.
+
+  Some examples:
+
+  1. If we want to support `Clang >= 3`, `GCC >= 4.6` and `MSVC >= 11`:
+
+     ``cpp11-migrate -toward clang-3.0 -toward gcc-4.6 -toward msvc-11
+     <args..>``
+
+     Enables LoopConvert, ReplaceAutoPtr, UseAuto, UseNullptr.
+
+  2. If we want to support `icc >= 12` and a C++11-aware macro exists for the
+     `override` identifier:
+
+     ``cpp11-migrate -toward icc-12 -override-macros <args..>``
+
+     Enables AddOverride and UseAuto.
+
+
+  .. warning::
+
+    If your version of Clang depends on the GCC headers (e.g: when `libc++` is
+    not used), then you probably want to add the GCC version to the targetted
+    platforms as well.
+
+ 
 .. option:: -perf[=<directory>]
 
   Turns on performance measurement and output functionality. The time it takes to
Index: test/cpp11-migrate/Combined/compilers.cpp
===================================================================
--- /dev/null
+++ test/cpp11-migrate/Combined/compilers.cpp
@@ -0,0 +1,141 @@
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward c++11 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=CPP11 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward clang-2.9 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=CLANG-29 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward clang-2.9 -override-macros %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=CLANG-29-OV-MACROS -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward clang-3.0 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=CLANG-30 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward gcc-4.4 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=GCC-44 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward gcc-4.6 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=GCC-46 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward gcc-4.7 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=GCC-47 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward icc-12 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=ICC-12 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward icc-12.1 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=ICC-121 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward icc-13 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=ICC-13 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward icc-14 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=ICC-14 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward msvc-8 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=MSVC-8 -input-file=%t.cpp %s
+//
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -toward msvc-11 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=MSVC-11 -input-file=%t.cpp %s
+
+// Test add overrides
+struct A {
+  virtual A *clone() = 0;
+};
+
+#define LLVM_OVERRIDE override
+
+struct B : A {
+  virtual B *clone();
+  // CPP11: virtual B *clone() override;
+  // CLANG-29-OV-MACROS: virtual B *clone() LLVM_OVERRIDE;
+  // CLANG-29: virtual B *clone();
+  // CLANG-30: virtual B *clone() override;
+  // GCC-46: virtual B *clone();
+  // GCC-47: virtual B *clone() override;
+  // ICC-13: virtual B *clone();
+  // ICC-14: virtual B *clone() override;
+  // MSVC-8: virtual B *clone() override;
+};
+
+// Test loop-convert
+void pass(int);
+void f_1() {
+int arr[] = {1,2,3};
+ for (int i = 0; i < 3; ++i)
+    pass(arr[i]);
+  // CPP11: for (auto & elem : arr)
+  // CPP11-NEXT: pass(elem);
+  // CLANG-29: for (int i = 0; i < 3; ++i)
+  // CLANG-29-NEXT: pass(arr[i]);
+  // CLANG-30: for (auto & elem : arr)
+  // CLANG-30-NEXT: pass(elem);
+  // GCC-44: for (int i = 0; i < 3; ++i)
+  // GCC-44-NEXT: pass(arr[i]);
+  // GCC-46: for (auto & elem : arr)
+  // GCC-46-NEXT: pass(elem);
+  // ICC-12: for (int i = 0; i < 3; ++i)
+  // ICC-12-NEXT: pass(arr[i]);
+  // ICC-13: for (auto & elem : arr)
+  // ICC-13-NEXT: pass(elem);
+  // MSVC-8: for (int i = 0; i < 3; ++i)
+  // MSVC-8-NEXT: pass(arr[i]);
+  // MSVC-11: for (auto & elem : arr)
+  // MSVC-11-NEXT: pass(elem);
+}
+
+// Test replace auto-ptr
+namespace std {
+template <class T> class auto_ptr {};
+template <class T> class unique_ptr {};
+}
+void f_2() {
+  std::auto_ptr<int> s;
+  // CPP11: std::unique_ptr<int> s;
+  // CLANG-29: std::auto_ptr<int> s;
+  // CLANG-30: std::unique_ptr<int> s;
+  // GCC-44: std::auto_ptr<int> s;
+  // GCC-46: std::unique_ptr<int> s;
+  // ICC-12: std::auto_ptr<int> s;
+  // ICC-13: std::unique_ptr<int> s;
+  // MSVC-8: std::auto_ptr<int> s;
+  // MSVC-11: std::unique_ptr<int> s;
+}
+
+// Test use auto
+struct MyType {};
+void f_3() {
+  MyType *a = new MyType();
+  // CPP11: auto a = new MyType();
+  // CLANG-29: auto a = new MyType();
+  // GCC-44: auto a = new MyType();
+  // ICC-12: auto a = new MyType();
+  // MSVC-8: MyType *a = new MyType();
+  // MSVC-10: auto a = new MyType();
+}
+
+// Test use nullptr
+void f_4() {
+  int *p = 0;
+  // CPP11: int *p = nullptr;
+  // CLANG-29: int *p = 0;
+  // CLANG-30: int *p = nullptr;
+  // GCC-4.4: int *p = 0;
+  // GCC-4.6: int *p = nullptr;
+  // ICC-12: int *p = 0;
+  // ICC-121: int *p = nullptr;
+  // MSVC-8: int *p = 0;
+  // MSVC-10: int *p = nullptr;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to