[clang-tools-extra] r187360 - cpp11-migrate: Add -for-compilers command line switch.

Guillaume Papin guillaume.papin at epitech.eu
Mon Jul 29 08:58:47 PDT 2013


Author: papin_g
Date: Mon Jul 29 10:58:47 2013
New Revision: 187360

URL: http://llvm.org/viewvc/llvm-project?rev=187360&view=rev
Log:
cpp11-migrate: Add -for-compilers command line switch.

This change add a new option command line option -for-compilers that allows the
user to enable multiple transforms automatically.

Another difference is that now all transforms are enabled by default.

Added:
    clang-tools-extra/trunk/test/cpp11-migrate/Combined/compilers.cpp
Removed:
    clang-tools-extra/trunk/test/cpp11-migrate/no_xform.cpp
Modified:
    clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp
    clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp
    clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h
    clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.cpp
    clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.h
    clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp
    clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
    clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp
    clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp
    clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp
    clang-tools-extra/trunk/docs/MigratorUsage.rst
    clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp

Modified: clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/AddOverride/AddOverride.cpp Mon Jul 29 10:58:47 2013
@@ -61,6 +61,18 @@ bool AddOverrideTransform::handleBeginSo
 }
 
 struct AddOverrideFactory : TransformFactory {
+  AddOverrideFactory() {
+    // if detecting macros is enabled, do not impose requirements on the
+    // compiler. It is assumed that the macros use is "C++11-aware", meaning it
+    // won't expand to override if the compiler doesn't support the specifier.
+    if (!DetectMacros) {
+      Since.Clang = Version(3, 0);
+      Since.Gcc = Version(4, 7);
+      Since.Icc = Version(14);
+      Since.Msvc = Version(8);
+    }
+  }
+
   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
     return new AddOverrideTransform(Opts);
   }

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Transform.cpp Mon Jul 29 10:58:47 2013
@@ -20,6 +20,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/STLExtras.h"
 
 using namespace clang;
 
@@ -132,4 +133,36 @@ FrontendActionFactory *Transform::create
   return new ActionFactory(Finder, /*Owner=*/ *this);
 }
 
+Version Version::getFromString(llvm::StringRef VersionStr) {
+  llvm::StringRef MajorStr, MinorStr;
+  Version V;
+
+  llvm::tie(MajorStr, MinorStr) = VersionStr.split('.');
+  if (!MinorStr.empty()) {
+    llvm::StringRef Ignore;
+    llvm::tie(MinorStr, Ignore) = MinorStr.split('.');
+    if (MinorStr.getAsInteger(10, V.Minor))
+      return Version();
+  }
+  if (MajorStr.getAsInteger(10, V.Major))
+    return Version();
+  return V;
+}
+
 TransformFactory::~TransformFactory() {}
+
+namespace {
+bool versionSupported(Version Required, Version AvailableSince) {
+  // null version, means no requirements, means supported
+  if (Required.isNull())
+    return true;
+  return Required >= AvailableSince;
+}
+} // end anonymous namespace
+
+bool TransformFactory::supportsCompilers(CompilerVersions Required) const {
+  return versionSupported(Required.Clang, Since.Clang) &&
+         versionSupported(Required.Gcc, Since.Gcc) &&
+         versionSupported(Required.Icc, Since.Icc) &&
+         versionSupported(Required.Msvc, Since.Msvc);
+}

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Transform.h Mon Jul 29 10:58:47 2013
@@ -222,16 +222,74 @@ private:
   unsigned DeferredChanges;
 };
 
+/// \brief Describes a version number of the form major[.minor] (minor being
+/// optional).
+struct Version {
+  explicit Version(unsigned Major = 0, unsigned Minor = 0)
+      : 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;
+  }
+
+  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 isNull() const { return Minor == 0 && Major == 0; }
+  unsigned getMajor() const { return Major; }
+  unsigned getMinor() const { return Minor; }
+
+  /// \brief Creates a version from a string of the form \c major[.minor].
+  ///
+  /// Note that any version component after \c minor is ignored.
+  ///
+  /// \return A null version is returned on error.
+  static Version getFromString(llvm::StringRef VersionStr);
+
+private:
+  unsigned Major;
+  unsigned Minor;
+};
+
+/// \brief Convenience structure to store the version of some compilers.
+struct CompilerVersions {
+  Version Clang, Gcc, Icc, Msvc;
+};
+
 /// \brief A factory that can instantiate a specific transform.
 ///
-/// Each transform should subclass it and implement the \c createTransform()
-/// methods. Use \c TransformFactoryRegistry to register the transform globally.
+/// Each transform should subclass this class and implement
+/// \c createTransform().
+///
+/// In the sub-classed factory constructor, specify the earliest versions since
+/// the compilers in \c CompilerVersions support the feature introduced by the
+/// transform. See the example below.
+///
+/// Note that you should use \c TransformFactoryRegistry to register the
+/// transform globally.
 ///
 /// Example:
 /// \code
 /// class MyTransform : public Transform { ... };
 ///
 /// struct MyFactory : TransformFactory {
+///   MyFactory() {
+///     Since.Clang = Version(3, 0);
+///     Since.Gcc = Version(4, 7);
+///     Since.Icc = Version(12);
+///     Since.Msvc = Version(10);
+///   }
+///
 ///   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
 ///     return new MyTransform(Opts);
 ///   }
@@ -249,6 +307,17 @@ class TransformFactory {
 public:
   virtual ~TransformFactory();
   virtual Transform *createTransform(const TransformOptions &) = 0;
+
+  /// \brief Whether the transform is supported by the required compilers or
+  /// not.
+  bool supportsCompilers(CompilerVersions Required) const;
+
+protected:
+  /// \brief Since when the C++11 feature introduced by this transform has been
+  /// available.
+  ///
+  /// Can be set by the sub-class in the constructor body.
+  CompilerVersions Since;
 };
 
 typedef llvm::Registry<TransformFactory> TransformFactoryRegistry;

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.cpp Mon Jul 29 10:58:47 2013
@@ -37,17 +37,35 @@ void Transforms::registerTransforms() {
         I->getName(), cl::desc(I->getDesc()), cl::cat(TransformCategory));
 }
 
+bool Transforms::hasAnyExplicitOption() const {
+  for (OptionMap::const_iterator I = Options.begin(), E = Options.end(); I != E;
+       ++I)
+    if (*I->second)
+      return true;
+  return false;
+}
+
 void
-Transforms::createSelectedTransforms(const TransformOptions &GlobalOptions) {
+Transforms::createSelectedTransforms(const TransformOptions &GlobalOptions,
+                                     const CompilerVersions &RequiredVersions) {
+  // if at least one transform is set explicitly on the command line, do not
+  // enable non-explicit ones
+  bool EnableAllTransformsByDefault = !hasAnyExplicitOption();
+
   for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(),
                                           E = TransformFactoryRegistry::end();
        I != E; ++I) {
-    bool OptionEnabled = *Options[I->getName()];
+    bool ExplicitlyEnabled = *Options[I->getName()];
+    bool OptionEnabled = EnableAllTransformsByDefault || ExplicitlyEnabled;
 
     if (!OptionEnabled)
       continue;
 
     llvm::OwningPtr<TransformFactory> Factory(I->instantiate());
-    ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
+    if (Factory->supportsCompilers(RequiredVersions))
+      ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
+    else if (ExplicitlyEnabled)
+      llvm::errs() << "note: " << '-' << I->getName()
+                   << ": transform not available for specified compilers\n";
   }
 }

Modified: clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.h?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.h (original)
+++ clang-tools-extra/trunk/cpp11-migrate/Core/Transforms.h Mon Jul 29 10:58:47 2013
@@ -30,6 +30,7 @@ class Option;
 } // namespace llvm
 class Transform;
 struct TransformOptions;
+struct CompilerVersions;
 
 typedef Transform *(*TransformCreator)(const TransformOptions &);
 template <typename T>
@@ -57,7 +58,8 @@ public:
   /// \brief Instantiate all transforms that were selected on the command line.
   ///
   /// Call *after* parsing options.
-  void createSelectedTransforms(const TransformOptions &Options);
+  void createSelectedTransforms(const TransformOptions &Options,
+                                const CompilerVersions &RequiredVersions);
 
   /// \brief Return an iterator to the start of a container of instantiated
   /// transforms.
@@ -68,6 +70,8 @@ public:
   const_iterator end() const { return ChosenTransforms.end(); }
 
 private:
+  bool hasAnyExplicitOption() const;
+
   typedef llvm::StringMap<llvm::cl::opt<bool> *> OptionMap;
 
 private:

Modified: clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/LoopConvert/LoopConvert.cpp Mon Jul 29 10:58:47 2013
@@ -68,6 +68,13 @@ int LoopConvertTransform::apply(FileOver
 }
 
 struct LoopConvertFactory : TransformFactory {
+  LoopConvertFactory() {
+    Since.Clang = Version(3, 0);
+    Since.Gcc = Version(4, 6);
+    Since.Icc = Version(13);
+    Since.Msvc = Version(11);
+  }
+
   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
     return new LoopConvertTransform(Opts);
   }

Modified: clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp Mon Jul 29 10:58:47 2013
@@ -50,6 +50,13 @@ ReplaceAutoPtrTransform::apply(FileOverr
 }
 
 struct ReplaceAutoPtrFactory : TransformFactory {
+  ReplaceAutoPtrFactory() {
+    Since.Clang = Version(3, 0);
+    Since.Gcc = Version(4, 6);
+    Since.Icc = Version(13);
+    Since.Msvc = Version(11);
+  }
+
   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
     return new ReplaceAutoPtrTransform(Opts);
   }

Modified: clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/UseAuto/UseAuto.cpp Mon Jul 29 10:58:47 2013
@@ -49,6 +49,13 @@ int UseAutoTransform::apply(FileOverride
 }
 
 struct UseAutoFactory : TransformFactory {
+  UseAutoFactory() {
+    Since.Clang = Version(2, 9);
+    Since.Gcc = Version(4, 4);
+    Since.Icc = Version(12);
+    Since.Msvc = Version(10);
+  }
+
   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
     return new UseAutoTransform(Opts);
   }

Modified: clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/UseNullptr/UseNullptr.cpp Mon Jul 29 10:58:47 2013
@@ -50,6 +50,13 @@ int UseNullptrTransform::apply(FileOverr
 }
 
 struct UseNullptrFactory : TransformFactory {
+  UseNullptrFactory() {
+    Since.Clang = Version(3, 0);
+    Since.Gcc = Version(4, 6);
+    Since.Icc = Version(12, 1);
+    Since.Msvc = Version(10);
+  }
+
   Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
     return new UseNullptrTransform(Opts);
   }

Modified: clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp (original)
+++ clang-tools-extra/trunk/cpp11-migrate/tool/Cpp11Migrate.cpp Mon Jul 29 10:58:47 2013
@@ -24,6 +24,8 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
 
@@ -36,8 +38,8 @@ TransformOptions GlobalOptions;
 static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 static cl::extrahelp MoreHelp(
     "EXAMPLES:\n\n"
-    "Use 'auto' type specifier, no compilation database:\n\n"
-    "  cpp11-migrate -use-auto path/to/file.cpp -- -Ipath/to/include/\n"
+    "Apply all transforms on a given file, no compilation database:\n\n"
+    "  cpp11-migrate path/to/file.cpp -- -Ipath/to/include/\n"
     "\n"
     "Convert for loops to the new ranged-based for loops on all files in a "
     "subtree\nand reformat the code automatically using the LLVM style:\n\n"
@@ -47,7 +49,10 @@ static cl::extrahelp MoreHelp(
     "Make use of both nullptr and the override specifier, using git ls-files:\n"
     "\n"
     "  git ls-files '*.cpp' | xargs -I{} cpp11-migrate -p build/path \\\n"
-    "    -use-nullptr -add-override -override-macros {}\n");
+    "    -use-nullptr -add-override -override-macros {}\n"
+    "\n"
+    "Apply all transforms supported by both clang >= 3.0 and gcc >= 4.7:\n\n"
+    "  cpp11-migrate -for-compilers=clang-3.0,gcc-4.7 foo.cpp -- -Ibar\n");
 
 static cl::opt<RiskLevel, /*ExternalStorage=*/true> MaxRiskLevel(
     "risk", cl::desc("Select a maximum risk level:"),
@@ -113,6 +118,68 @@ static cl::opt<bool, /*ExternalStorage=*
     cl::location(GlobalOptions.EnableHeaderModifications),
     cl::init(false));
 
+cl::opt<std::string> SupportedCompilers(
+    "for-compilers", cl::value_desc("string"),
+    cl::desc("Select transforms targeting the intersection of\n"
+             "language features supported by the given compilers.\n"
+             "Takes a comma-seperated list of <compiler>-<version>.\n"
+             "\t<compiler> can be any of: clang, gcc, icc, msvc\n"
+             "\t<version> is <major>[.<minor>]\n"));
+
+/// \brief Extract the minimum compiler versions as requested on the command
+/// line by the switch \c -for-compilers.
+///
+/// \param ProgName The name of the program, \c argv[0], used to print errors.
+/// \param Error If an error occur while parsing the versions this parameter is
+/// set to \c true, otherwise it will be left untouched.
+static CompilerVersions handleSupportedCompilers(const char *ProgName,
+                                                 bool &Error) {
+  if (SupportedCompilers.getNumOccurrences() == 0)
+    return CompilerVersions();
+  CompilerVersions RequiredVersions;
+  llvm::SmallVector<llvm::StringRef, 4> Compilers;
+
+  llvm::StringRef(SupportedCompilers).split(Compilers, ",");
+
+  for (llvm::SmallVectorImpl<llvm::StringRef>::iterator I = Compilers.begin(),
+                                                        E = Compilers.end();
+       I != E; ++I) {
+    llvm::StringRef Compiler, VersionStr;
+    llvm::tie(Compiler, VersionStr) = I->split('-');
+    Version *V = llvm::StringSwitch<Version *>(Compiler)
+        .Case("clang", &RequiredVersions.Clang)
+        .Case("gcc", &RequiredVersions.Gcc).Case("icc", &RequiredVersions.Icc)
+        .Case("msvc", &RequiredVersions.Msvc).Default(NULL);
+
+    if (V == NULL) {
+      llvm::errs() << ProgName << ": " << Compiler
+                   << ": unsupported platform\n";
+      Error = true;
+      continue;
+    }
+    if (VersionStr.empty()) {
+      llvm::errs() << ProgName << ": " << *I
+                   << ": missing version number in platform\n";
+      Error = true;
+      continue;
+    }
+
+    Version Version = Version::getFromString(VersionStr);
+    if (Version.isNull()) {
+      llvm::errs()
+          << ProgName << ": " << *I
+          << ": invalid version, please use \"<major>[.<minor>]\" instead of \""
+          << VersionStr << "\"\n";
+      Error = true;
+      continue;
+    }
+    // support the lowest version given
+    if (V->isNull() || Version < *V)
+      *V = Version;
+  }
+  return RequiredVersions;
+}
+
 /// \brief Creates the Reformatter if the format style option is provided,
 /// return a null pointer otherwise.
 ///
@@ -161,10 +228,13 @@ int main(int argc, const char **argv) {
   GlobalOptions.EnableTiming = (TimingDirectoryName != NoTiming);
 
   // Check the reformatting style option
-  bool BadStyle = false;
+  bool CmdSwitchError = false;
   llvm::OwningPtr<Reformatter> ChangesReformatter(
-      handleFormatStyle(argv[0], BadStyle));
-  if (BadStyle)
+      handleFormatStyle(argv[0], CmdSwitchError));
+
+  CompilerVersions RequiredVersions =
+      handleSupportedCompilers(argv[0], CmdSwitchError);
+  if (CmdSwitchError)
     return 1;
 
   // Populate the ModifiableHeaders structure if header modifications are
@@ -176,10 +246,14 @@ int main(int argc, const char **argv) {
         .readListFromFile(IncludeFromFile, ExcludeFromFile);
   }
 
-  TransformManager.createSelectedTransforms(GlobalOptions);
+  TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
 
   if (TransformManager.begin() == TransformManager.end()) {
-    llvm::errs() << argv[0] << ": No selected transforms\n";
+    if (SupportedCompilers.empty())
+      llvm::errs() << argv[0] << ": no selected transforms\n";
+    else
+      llvm::errs() << argv[0]
+                   << ": no transforms available for specified compilers\n";
     return 1;
   }
 

Modified: clang-tools-extra/trunk/docs/MigratorUsage.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/MigratorUsage.rst?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/MigratorUsage.rst (original)
+++ clang-tools-extra/trunk/docs/MigratorUsage.rst Mon Jul 29 10:58:47 2013
@@ -7,7 +7,16 @@ cpp11-migrate Usage
 ``<source#>`` specifies the path to the source to migrate. This path may be
 relative to the current directory.
 
-At least one transform must be enabled.
+By default all transformations are applied. There are two ways to enable a
+subset of the transformations:
+
+1. Explicitly, by referring to the transform options directly, see
+   :ref:`transform-specific-command-line-options`.
+2. Implicitly, based on the compilers to support, see
+   :ref:`-for-compilers=\<string\> <for-compilers-option>`.
+
+If both ways of specifying transforms are used only explicitly specified
+transformations that are supported by the given compilers will be applied.
 
 General Command Line Options
 ============================
@@ -113,6 +122,54 @@ General Command Line Options
   with other accepted changes. Re-applying the transform will resolve deferred
   changes.
 
+.. _for-compilers-option:
+
+.. option:: -for-compilers=<string>
+
+  Select transforms targeting the intersection of language features supported by
+  the given compilers.
+
+  Four compilers are 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 are C++11
+  aware and the transform is enabled without regard to the supported compilers.
+
+  The structure of the argument to the `-for-compilers` option is
+  **<compiler>-<major ver>[.<minor ver>]** where **<compiler>** is one of the
+  compilers from the above table.
+
+  Some examples:
+
+  1. To support `Clang >= 3.0`, `gcc >= 4.6` and `MSVC >= 11`:
+
+     ``cpp11-migrate -for-compilers=clang-3.0,gcc-4.6,msvc-11 <args..>``
+
+     Enables LoopConvert, ReplaceAutoPtr, UseAuto, UseNullptr.
+
+  2. To support `icc >= 12` while using a C++11-aware macro for the `override`
+     virtual specifier:
+
+     ``cpp11-migrate -for-compilers=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 targeted
+    platforms as well.
+
 .. option:: -perf[=<directory>]
 
   Turns on performance measurement and output functionality. The time it takes to
@@ -124,6 +181,8 @@ General Command Line Options
   The time recorded for a transform includes parsing and creating source code
   replacements.
 
+.. _transform-specific-command-line-options:
+
 Transform-Specific Command Line Options
 =======================================
 

Added: clang-tools-extra/trunk/test/cpp11-migrate/Combined/compilers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/Combined/compilers.cpp?rev=187360&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/Combined/compilers.cpp (added)
+++ clang-tools-extra/trunk/test/cpp11-migrate/Combined/compilers.cpp Mon Jul 29 10:58:47 2013
@@ -0,0 +1,63 @@
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -for-compilers=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 -for-compilers=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 -for-compilers=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 -for-compilers=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 -for-compilers=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 -for-compilers=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 -for-compilers=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 -for-compilers=msvc-8 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=MSVC-8 -input-file=%t.cpp %s
+//
+// Test multiple compilers
+// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -for-compilers=clang-3.0,gcc-4.6,gcc-4.7 %t.cpp -- -std=c++11
+// RUN: FileCheck -check-prefix=MULTIPLE -input-file=%t.cpp %s
+//
+// Test unknown platform
+// RUN: not cpp11-migrate -for-compilers=foo-10 %t.cpp -- -std=c++11
+//
+// Test when no transforms can be selected because the compiler lacks support of
+// the needed C++11 features
+// RUN: not cpp11-migrate -for-compilers=clang-2.0 %t.cpp -- -std=c++11
+
+// Test add overrides
+struct A {
+  virtual A *clone() = 0;
+};
+
+#define LLVM_OVERRIDE override
+
+struct B : A {
+  virtual B *clone();
+  // 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;
+  // MULTIPLE: virtual B *clone();
+};

Removed: clang-tools-extra/trunk/test/cpp11-migrate/no_xform.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/cpp11-migrate/no_xform.cpp?rev=187359&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/cpp11-migrate/no_xform.cpp (original)
+++ clang-tools-extra/trunk/test/cpp11-migrate/no_xform.cpp (removed)
@@ -1,6 +0,0 @@
-// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: not cpp11-migrate %t.cpp --
-
-int main(int argc, char** argv) {
-  return 0;
-}

Modified: clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp?rev=187360&r1=187359&r2=187360&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/cpp11-migrate/TransformTest.cpp Mon Jul 29 10:58:47 2013
@@ -302,3 +302,25 @@ TEST(Transform, isFileModifiable) {
     Tool.run(tooling::newFrontendActionFactory(&Finder));
   }
 }
+
+TEST(VersionTest, Interface) {
+  Version V;
+
+  ASSERT_TRUE(V.isNull());
+  ASSERT_TRUE(Version(1) < Version(1, 1));
+  ASSERT_TRUE(Version(1) < Version(2));
+  ASSERT_TRUE(Version(1, 1) < Version(2));
+  ASSERT_TRUE(Version(1, 1) == Version(1, 1));
+  ASSERT_EQ(Version(1).getMajor(), unsigned(1));
+  ASSERT_EQ(Version(1).getMinor(), unsigned(0));
+  ASSERT_EQ(Version(1, 2).getMinor(), unsigned(2));
+}
+
+TEST(VersionTest, getFromString) {
+  ASSERT_EQ(Version(1), Version::getFromString("1"));
+  ASSERT_EQ(Version(1, 2), Version::getFromString("1.2"));
+  ASSERT_TRUE(Version::getFromString("foo").isNull());
+  ASSERT_TRUE(Version::getFromString("1bar").isNull());
+  // elements after major.minor are ignored
+  ASSERT_EQ(Version(1, 2), Version::getFromString("1.2.3"));
+}





More information about the cfe-commits mailing list