Hi revane, arielbernal, tareqsiraj,
This change is to prepare my upcoming patch for the '-support' command (see
http://llvm-reviews.chandlerc.com/D1154).
It makes the transforms register themselves using llvm::Registry. This is
similar to some other usages in Clang (LLVM passes, Clang-Tidy modules,
Compilation database plugins, ...).
http://llvm-reviews.chandlerc.com/D1196
Files:
cpp11-migrate/AddOverride/AddOverride.cpp
cpp11-migrate/Core/Transform.cpp
cpp11-migrate/Core/Transform.h
cpp11-migrate/Core/Transforms.cpp
cpp11-migrate/Core/Transforms.h
cpp11-migrate/LoopConvert/LoopConvert.cpp
cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
cpp11-migrate/UseAuto/UseAuto.cpp
cpp11-migrate/UseNullptr/UseNullptr.cpp
cpp11-migrate/tool/Cpp11Migrate.cpp
Index: cpp11-migrate/AddOverride/AddOverride.cpp
===================================================================
--- cpp11-migrate/AddOverride/AddOverride.cpp
+++ cpp11-migrate/AddOverride/AddOverride.cpp
@@ -59,3 +59,17 @@
Fixer->setPreprocessor(CI.getPreprocessor());
return Transform::handleBeginSource(CI, Filename);
}
+
+struct AddOverrideFactory : TransformFactory {
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new AddOverrideTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<AddOverrideFactory>
+X("add-override", "Make use of override specifier where possible");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int AddOverrideTransformAnchorSource = 0;
Index: cpp11-migrate/Core/Transform.cpp
===================================================================
--- cpp11-migrate/Core/Transform.cpp
+++ cpp11-migrate/Core/Transform.cpp
@@ -128,7 +128,8 @@
Timings.push_back(std::make_pair(Label.str(), Duration));
}
-FrontendActionFactory *
-Transform::createActionFactory(MatchFinder &Finder) {
+FrontendActionFactory *Transform::createActionFactory(MatchFinder &Finder) {
return new ActionFactory(Finder, /*Owner=*/ *this);
}
+
+TransformFactory::~TransformFactory() {}
Index: cpp11-migrate/Core/Transform.h
===================================================================
--- cpp11-migrate/Core/Transform.h
+++ cpp11-migrate/Core/Transform.h
@@ -20,8 +20,8 @@
#include "clang/Tooling/Refactoring.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Registry.h"
#include "llvm/Support/Timer.h"
-
#include <string>
#include <vector>
@@ -222,4 +222,36 @@
unsigned DeferredChanges;
};
+/// \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.
+///
+///
+/// Example:
+/// \code
+/// class MyTransform : public Transform { ... };
+///
+/// struct MyFactory : TransformFactory {
+/// Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+/// return new MyTransform(Opts);
+/// }
+/// };
+///
+/// // Register the factory using this statically initialized variable.
+/// static TransformFactoryRegistry::Add<MyFactory>
+/// X("my-transform", "<Short description of my transform>");
+///
+/// // This anchor is used to force the linker to link in the generated object
+/// // file and thus register the factory.
+/// volatile int MyTransformAnchorSource = 0;
+/// \endcode
+class TransformFactory {
+public:
+ virtual ~TransformFactory();
+ virtual Transform *createTransform(const TransformOptions &) = 0;
+};
+
+typedef llvm::Registry<TransformFactory> TransformFactoryRegistry;
+
#endif // CPP11_MIGRATE_TRANSFORM_H
Index: cpp11-migrate/Core/Transforms.cpp
===================================================================
--- cpp11-migrate/Core/Transforms.cpp
+++ cpp11-migrate/Core/Transforms.cpp
@@ -20,31 +20,34 @@
static cl::OptionCategory TransformCategory("Transforms");
Transforms::~Transforms() {
- for (std::vector<Transform*>::iterator I = ChosenTransforms.begin(),
- E = ChosenTransforms.end(); I != E; ++I) {
+ for (std::vector<Transform *>::iterator I = ChosenTransforms.begin(),
+ E = ChosenTransforms.end();
+ I != E; ++I)
delete *I;
- }
- for (OptionVec::iterator I = Options.begin(),
- E = Options.end(); I != E; ++I) {
- delete I->first;
- }
+
+ for (OptionMap::iterator I = Options.begin(), E = Options.end(); I != E; ++I)
+ delete I->getValue();
}
-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));
+void Transforms::registerTransforms() {
+ for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(),
+ E = TransformFactoryRegistry::end();
+ I != E; ++I)
+ Options[I->getName()] = new cl::opt<bool>(
+ I->getName(), cl::desc(I->getDesc()), cl::cat(TransformCategory));
}
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));
- }
+ for (TransformFactoryRegistry::iterator I = TransformFactoryRegistry::begin(),
+ E = TransformFactoryRegistry::end();
+ I != E; ++I) {
+ bool OptionEnabled = *Options[I->getName()];
+
+ if (!OptionEnabled)
+ continue;
+
+ llvm::OwningPtr<TransformFactory> Factory(I->instantiate());
+ ChosenTransforms.push_back(Factory->createTransform(GlobalOptions));
}
}
Index: cpp11-migrate/Core/Transforms.h
===================================================================
--- cpp11-migrate/Core/Transforms.h
+++ cpp11-migrate/Core/Transforms.h
@@ -48,12 +48,11 @@
~Transforms();
- /// \brief Registers a transform causing the transform to be made available
- /// on the command line.
+ /// \brief Registers all available transforms causing them 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);
+ void registerTransforms();
/// \brief Instantiate all transforms that were selected on the command line.
///
@@ -69,12 +68,11 @@
const_iterator end() const { return ChosenTransforms.end(); }
private:
- typedef std::vector<std::pair<llvm::cl::opt<bool>*, TransformCreator> >
- OptionVec;
+ typedef llvm::StringMap<llvm::cl::opt<bool> *> OptionMap;
private:
TransformVec ChosenTransforms;
- OptionVec Options;
+ OptionMap Options;
};
#endif // CPP11_MIGRATE_TRANSFORMS_H
Index: cpp11-migrate/LoopConvert/LoopConvert.cpp
===================================================================
--- cpp11-migrate/LoopConvert/LoopConvert.cpp
+++ cpp11-migrate/LoopConvert/LoopConvert.cpp
@@ -66,3 +66,17 @@
return 0;
}
+
+struct LoopConvertFactory : TransformFactory {
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new LoopConvertTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<LoopConvertFactory>
+X("loop-convert", "Make use of range-based for loops where possible");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int LoopConvertTransformAnchorSource = 0;
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.cpp
@@ -48,3 +48,18 @@
return 0;
}
+
+struct ReplaceAutoPtrFactory : TransformFactory {
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new ReplaceAutoPtrTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<ReplaceAutoPtrFactory>
+X("replace-auto_ptr", "Replace std::auto_ptr (deprecated) by std::unique_ptr"
+ " (EXPERIMENTAL)");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int ReplaceAutoPtrTransformAnchorSource = 0;
Index: cpp11-migrate/UseAuto/UseAuto.cpp
===================================================================
--- cpp11-migrate/UseAuto/UseAuto.cpp
+++ cpp11-migrate/UseAuto/UseAuto.cpp
@@ -47,3 +47,17 @@
return 0;
}
+
+struct UseAutoFactory : TransformFactory {
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new UseAutoTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<UseAutoFactory>
+X("use-auto", "Use of 'auto' type specifier");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int UseAutoTransformAnchorSource = 0;
Index: cpp11-migrate/UseNullptr/UseNullptr.cpp
===================================================================
--- cpp11-migrate/UseNullptr/UseNullptr.cpp
+++ cpp11-migrate/UseNullptr/UseNullptr.cpp
@@ -48,3 +48,17 @@
return 0;
}
+
+struct UseNullptrFactory : TransformFactory {
+ Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE {
+ return new UseNullptrTransform(Opts);
+ }
+};
+
+// Register the factory using this statically initialized variable.
+static TransformFactoryRegistry::Add<UseNullptrFactory>
+X("use-nullptr", "Make use of nullptr keyword where possible");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the factory.
+volatile int UseNullptrTransformAnchorSource = 0;
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,23 +107,7 @@
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.
+ TransformManager.registerTransforms();
// This causes options to be parsed.
CommonOptionsParser OptionsParser(argc, argv);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits