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
This commit is contained in:
parent
ee30546c00
commit
a3eede2cc2
|
|
@ -61,6 +61,18 @@ bool AddOverrideTransform::handleBeginSource(clang::CompilerInstance &CI,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AddOverrideFactory : TransformFactory {
|
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 {
|
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
return new AddOverrideTransform(Opts);
|
return new AddOverrideTransform(Opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "clang/Frontend/CompilerInstance.h"
|
#include "clang/Frontend/CompilerInstance.h"
|
||||||
#include "clang/Tooling/Tooling.h"
|
#include "clang/Tooling/Tooling.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
|
|
@ -132,4 +133,36 @@ FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
|
||||||
return new ActionFactory(Finder, /*Owner=*/ *this);
|
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() {}
|
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);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -222,16 +222,74 @@ private:
|
||||||
unsigned DeferredChanges;
|
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.
|
/// \brief A factory that can instantiate a specific transform.
|
||||||
///
|
///
|
||||||
/// Each transform should subclass it and implement the \c createTransform()
|
/// Each transform should subclass this class and implement
|
||||||
/// methods. Use \c TransformFactoryRegistry to register the transform globally.
|
/// \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:
|
/// Example:
|
||||||
/// \code
|
/// \code
|
||||||
/// class MyTransform : public Transform { ... };
|
/// class MyTransform : public Transform { ... };
|
||||||
///
|
///
|
||||||
/// struct MyFactory : TransformFactory {
|
/// 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 {
|
/// Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
/// return new MyTransform(Opts);
|
/// return new MyTransform(Opts);
|
||||||
/// }
|
/// }
|
||||||
|
|
@ -249,6 +307,17 @@ class TransformFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~TransformFactory();
|
virtual ~TransformFactory();
|
||||||
virtual Transform *createTransform(const TransformOptions &) = 0;
|
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;
|
typedef llvm::Registry<TransformFactory> TransformFactoryRegistry;
|
||||||
|
|
|
||||||
|
|
@ -37,17 +37,35 @@ void Transforms::registerTransforms() {
|
||||||
I->getName(), cl::desc(I->getDesc()), cl::cat(TransformCategory));
|
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
|
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(),
|
for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(),
|
||||||
E = TransformFactoryRegistry::end();
|
E = TransformFactoryRegistry::end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
bool OptionEnabled = *Options[I->getName()];
|
bool ExplicitlyEnabled = *Options[I->getName()];
|
||||||
|
bool OptionEnabled = EnableAllTransformsByDefault || ExplicitlyEnabled;
|
||||||
|
|
||||||
if (!OptionEnabled)
|
if (!OptionEnabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
llvm::OwningPtr<TransformFactory> Factory(I->instantiate());
|
llvm::OwningPtr<TransformFactory> Factory(I->instantiate());
|
||||||
|
if (Factory->supportsCompilers(RequiredVersions))
|
||||||
ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
|
ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
|
||||||
|
else if (ExplicitlyEnabled)
|
||||||
|
llvm::errs() << "note: " << '-' << I->getName()
|
||||||
|
<< ": transform not available for specified compilers\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ class Option;
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
class Transform;
|
class Transform;
|
||||||
struct TransformOptions;
|
struct TransformOptions;
|
||||||
|
struct CompilerVersions;
|
||||||
|
|
||||||
typedef Transform *(*TransformCreator)(const TransformOptions &);
|
typedef Transform *(*TransformCreator)(const TransformOptions &);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -57,7 +58,8 @@ public:
|
||||||
/// \brief Instantiate all transforms that were selected on the command line.
|
/// \brief Instantiate all transforms that were selected on the command line.
|
||||||
///
|
///
|
||||||
/// Call *after* parsing options.
|
/// 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
|
/// \brief Return an iterator to the start of a container of instantiated
|
||||||
/// transforms.
|
/// transforms.
|
||||||
|
|
@ -68,6 +70,8 @@ public:
|
||||||
const_iterator end() const { return ChosenTransforms.end(); }
|
const_iterator end() const { return ChosenTransforms.end(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool hasAnyExplicitOption() const;
|
||||||
|
|
||||||
typedef llvm::StringMap<llvm::cl::opt<bool> *> OptionMap;
|
typedef llvm::StringMap<llvm::cl::opt<bool> *> OptionMap;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,13 @@ int LoopConvertTransform::apply(FileOverrides &InputStates,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LoopConvertFactory : TransformFactory {
|
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 {
|
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
return new LoopConvertTransform(Opts);
|
return new LoopConvertTransform(Opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,13 @@ ReplaceAutoPtrTransform::apply(FileOverrides &InputStates,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ReplaceAutoPtrFactory : TransformFactory {
|
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 {
|
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
return new ReplaceAutoPtrTransform(Opts);
|
return new ReplaceAutoPtrTransform(Opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,13 @@ int UseAutoTransform::apply(FileOverrides &InputStates,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UseAutoFactory : TransformFactory {
|
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 {
|
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
return new UseAutoTransform(Opts);
|
return new UseAutoTransform(Opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,13 @@ int UseNullptrTransform::apply(FileOverrides &InputStates,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UseNullptrFactory : TransformFactory {
|
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 {
|
Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
|
||||||
return new UseNullptrTransform(Opts);
|
return new UseNullptrTransform(Opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include "clang/Frontend/FrontendActions.h"
|
#include "clang/Frontend/FrontendActions.h"
|
||||||
#include "clang/Tooling/CommonOptionsParser.h"
|
#include "clang/Tooling/CommonOptionsParser.h"
|
||||||
#include "clang/Tooling/Tooling.h"
|
#include "clang/Tooling/Tooling.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/Signals.h"
|
#include "llvm/Support/Signals.h"
|
||||||
|
|
||||||
|
|
@ -36,8 +38,8 @@ TransformOptions GlobalOptions;
|
||||||
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
||||||
static cl::extrahelp MoreHelp(
|
static cl::extrahelp MoreHelp(
|
||||||
"EXAMPLES:\n\n"
|
"EXAMPLES:\n\n"
|
||||||
"Use 'auto' type specifier, no compilation database:\n\n"
|
"Apply all transforms on a given file, no compilation database:\n\n"
|
||||||
" cpp11-migrate -use-auto path/to/file.cpp -- -Ipath/to/include/\n"
|
" cpp11-migrate path/to/file.cpp -- -Ipath/to/include/\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Convert for loops to the new ranged-based for loops on all files in a "
|
"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"
|
"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"
|
"Make use of both nullptr and the override specifier, using git ls-files:\n"
|
||||||
"\n"
|
"\n"
|
||||||
" git ls-files '*.cpp' | xargs -I{} cpp11-migrate -p build/path \\\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(
|
static cl::opt<RiskLevel, /*ExternalStorage=*/true> MaxRiskLevel(
|
||||||
"risk", cl::desc("Select a maximum risk level:"),
|
"risk", cl::desc("Select a maximum risk level:"),
|
||||||
|
|
@ -113,6 +118,68 @@ static cl::opt<bool, /*ExternalStorage=*/true> EnableHeaderModifications(
|
||||||
cl::location(GlobalOptions.EnableHeaderModifications),
|
cl::location(GlobalOptions.EnableHeaderModifications),
|
||||||
cl::init(false));
|
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,
|
/// \brief Creates the Reformatter if the format style option is provided,
|
||||||
/// return a null pointer otherwise.
|
/// return a null pointer otherwise.
|
||||||
///
|
///
|
||||||
|
|
@ -161,10 +228,13 @@ int main(int argc, const char **argv) {
|
||||||
GlobalOptions.EnableTiming = (TimingDirectoryName != NoTiming);
|
GlobalOptions.EnableTiming = (TimingDirectoryName != NoTiming);
|
||||||
|
|
||||||
// Check the reformatting style option
|
// Check the reformatting style option
|
||||||
bool BadStyle = false;
|
bool CmdSwitchError = false;
|
||||||
llvm::OwningPtr<Reformatter> ChangesReformatter(
|
llvm::OwningPtr<Reformatter> ChangesReformatter(
|
||||||
handleFormatStyle(argv[0], BadStyle));
|
handleFormatStyle(argv[0], CmdSwitchError));
|
||||||
if (BadStyle)
|
|
||||||
|
CompilerVersions RequiredVersions =
|
||||||
|
handleSupportedCompilers(argv[0], CmdSwitchError);
|
||||||
|
if (CmdSwitchError)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Populate the ModifiableHeaders structure if header modifications are
|
// Populate the ModifiableHeaders structure if header modifications are
|
||||||
|
|
@ -176,10 +246,14 @@ int main(int argc, const char **argv) {
|
||||||
.readListFromFile(IncludeFromFile, ExcludeFromFile);
|
.readListFromFile(IncludeFromFile, ExcludeFromFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
TransformManager.createSelectedTransforms(GlobalOptions);
|
TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
|
||||||
|
|
||||||
if (TransformManager.begin() == TransformManager.end()) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,16 @@ cpp11-migrate Usage
|
||||||
``<source#>`` specifies the path to the source to migrate. This path may be
|
``<source#>`` specifies the path to the source to migrate. This path may be
|
||||||
relative to the current directory.
|
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
|
General Command Line Options
|
||||||
============================
|
============================
|
||||||
|
|
@ -113,6 +122,54 @@ General Command Line Options
|
||||||
with other accepted changes. Re-applying the transform will resolve deferred
|
with other accepted changes. Re-applying the transform will resolve deferred
|
||||||
changes.
|
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>]
|
.. option:: -perf[=<directory>]
|
||||||
|
|
||||||
Turns on performance measurement and output functionality. The time it takes to
|
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
|
The time recorded for a transform includes parsing and creating source code
|
||||||
replacements.
|
replacements.
|
||||||
|
|
||||||
|
.. _transform-specific-command-line-options:
|
||||||
|
|
||||||
Transform-Specific Command Line Options
|
Transform-Specific Command Line Options
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
};
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -302,3 +302,25 @@ TEST(Transform, isFileModifiable) {
|
||||||
Tool.run(tooling::newFrontendActionFactory(&Finder));
|
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"));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue