diff options
author | Guillaume Papin <guillaume.papin@epitech.eu> | 2013-07-29 15:58:47 +0000 |
---|---|---|
committer | Guillaume Papin <guillaume.papin@epitech.eu> | 2013-07-29 15:58:47 +0000 |
commit | a3eede2cc2673c6db8f0ef6a05e5e424e07dbacf (patch) | |
tree | 7982da794d40f792d76e61946b6652341dca36f0 | |
parent | ee30546c007d26d9c0c6f15b0e291a8bb0e651f9 (diff) | |
download | bcm5719-llvm-a3eede2cc2673c6db8f0ef6a05e5e424e07dbacf.tar.gz bcm5719-llvm-a3eede2cc2673c6db8f0ef6a05e5e424e07dbacf.zip |
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.
llvm-svn: 187360
14 files changed, 397 insertions, 21 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp index d044002e10d..db38fa64b56 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp @@ -61,6 +61,18 @@ bool AddOverrideTransform::handleBeginSource(clang::CompilerInstance &CI, } 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); } diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp index ac3375316bb..92520638502 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp @@ -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::createActionFactory(MatchFinder &Finder) { 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); +} diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h index ca610b82b9d..bb8c116726d 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.h +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h @@ -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; diff --git a/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp b/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp index d58e4c6af70..93701796e24 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/Transforms.cpp @@ -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"; } } diff --git a/clang-tools-extra/cpp11-migrate/Core/Transforms.h b/clang-tools-extra/cpp11-migrate/Core/Transforms.h index 527474d0568..18369407dda 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transforms.h +++ b/clang-tools-extra/cpp11-migrate/Core/Transforms.h @@ -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: diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp index 965ae4b25d0..73c2560e796 100644 --- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp +++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp @@ -68,6 +68,13 @@ int LoopConvertTransform::apply(FileOverrides &InputStates, } 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); } diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp index 9d281ecdd67..47dce8e7c89 100644 --- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp +++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp @@ -50,6 +50,13 @@ ReplaceAutoPtrTransform::apply(FileOverrides &InputStates, } 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); } diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp index 47c2cd53215..ccf49d88c92 100644 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp +++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp @@ -49,6 +49,13 @@ int UseAutoTransform::apply(FileOverrides &InputStates, } 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); } diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp index ba433ec77ae..afeec4a10af 100644 --- a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp +++ b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp @@ -50,6 +50,13 @@ int UseNullptrTransform::apply(FileOverrides &InputStates, } 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); } diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp index 2ee4a069ff3..10370f959e2 100644 --- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp +++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp @@ -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=*/true> EnableHeaderModifications( 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; } diff --git a/clang-tools-extra/docs/MigratorUsage.rst b/clang-tools-extra/docs/MigratorUsage.rst index 72403bbcd61..3bb6b41bef8 100644 --- a/clang-tools-extra/docs/MigratorUsage.rst +++ b/clang-tools-extra/docs/MigratorUsage.rst @@ -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 ======================================= diff --git a/clang-tools-extra/test/cpp11-migrate/Combined/compilers.cpp b/clang-tools-extra/test/cpp11-migrate/Combined/compilers.cpp new file mode 100644 index 00000000000..14b29978693 --- /dev/null +++ b/clang-tools-extra/test/cpp11-migrate/Combined/compilers.cpp @@ -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(); +}; diff --git a/clang-tools-extra/test/cpp11-migrate/no_xform.cpp b/clang-tools-extra/test/cpp11-migrate/no_xform.cpp deleted file mode 100644 index 2845e3f9f44..00000000000 --- a/clang-tools-extra/test/cpp11-migrate/no_xform.cpp +++ /dev/null @@ -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; -} diff --git a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp index c58aeb227ca..b8efc9b5840 100644 --- a/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp +++ b/clang-tools-extra/unittests/cpp11-migrate/TransformTest.cpp @@ -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")); +} |