Adapts the FrontendAction convenience functions so that it can be

used with classes that generate ASTConsumers; this allows decoupling
the ASTConsumer generation from the Frontend library (like, for example,
the MatchFinder in the upcoming ASTMatcher patch).

llvm-svn: 159760
This commit is contained in:
Manuel Klimek 2012-07-05 18:13:01 +00:00
parent 4d6c832165
commit 5da9dcb275
4 changed files with 30 additions and 15 deletions

View File

@ -35,6 +35,7 @@
#include "clang/Basic/FileManager.h" #include "clang/Basic/FileManager.h"
#include "clang/Basic/LLVM.h" #include "clang/Basic/LLVM.h"
#include "clang/Driver/Util.h" #include "clang/Driver/Util.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/ArgumentsAdjusters.h"
#include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/CompilationDatabase.h"
#include <string> #include <string>
@ -74,18 +75,18 @@ template <typename T>
FrontendActionFactory *newFrontendActionFactory(); FrontendActionFactory *newFrontendActionFactory();
/// \brief Returns a new FrontendActionFactory for any type that provides an /// \brief Returns a new FrontendActionFactory for any type that provides an
/// implementation of newFrontendAction(). /// implementation of newASTConsumer().
/// ///
/// FactoryT must implement: FrontendAction *newFrontendAction(). /// FactoryT must implement: ASTConsumer *newASTConsumer().
/// ///
/// Example: /// Example:
/// struct ProvidesFrontendActions { /// struct ProvidesASTConsumers {
/// FrontendAction *newFrontendAction(); /// clang::ASTConsumer *newASTConsumer();
/// } Factory; /// } Factory;
/// FrontendActionFactory *FactoryAdapter = /// FrontendActionFactory *FactoryAdapter =
/// newFrontendActionFactory(&Factory); /// newFrontendActionFactory(&Factory);
template <typename FactoryT> template <typename FactoryT>
FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory); FrontendActionFactory *newFrontendActionFactory(FactoryT *ConsumerFactory);
/// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag. /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
/// ///
@ -201,21 +202,34 @@ FrontendActionFactory *newFrontendActionFactory() {
} }
template <typename FactoryT> template <typename FactoryT>
FrontendActionFactory *newFrontendActionFactory(FactoryT *ActionFactory) { FrontendActionFactory *newFrontendActionFactory(FactoryT *ConsumerFactory) {
class FrontendActionFactoryAdapter : public FrontendActionFactory { class FrontendActionFactoryAdapter : public FrontendActionFactory {
public: public:
explicit FrontendActionFactoryAdapter(FactoryT *ActionFactory) explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory)
: ActionFactory(ActionFactory) {} : ConsumerFactory(ConsumerFactory) {}
virtual clang::FrontendAction *create() { virtual clang::FrontendAction *create() {
return ActionFactory->newFrontendAction(); return new ConsumerFactoryAdaptor(ConsumerFactory);
} }
private: private:
FactoryT *ActionFactory; class ConsumerFactoryAdaptor : public clang::ASTFrontendAction {
public:
ConsumerFactoryAdaptor(FactoryT *ConsumerFactory)
: ConsumerFactory(ConsumerFactory) {}
clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
llvm::StringRef) {
return ConsumerFactory->newASTConsumer();
}
private:
FactoryT *ConsumerFactory;
};
FactoryT *ConsumerFactory;
}; };
return new FrontendActionFactoryAdapter(ActionFactory); return new FrontendActionFactoryAdapter(ConsumerFactory);
} }
} // end namespace tooling } // end namespace tooling

View File

@ -19,7 +19,6 @@
#include "clang/Driver/Driver.h" #include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h" #include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"

View File

@ -56,6 +56,7 @@ protected:
FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {} FindConsumer(TestVisitor *Visitor) : Visitor(Visitor) {}
virtual void HandleTranslationUnit(clang::ASTContext &Context) { virtual void HandleTranslationUnit(clang::ASTContext &Context) {
Visitor->Context = &Context;
Visitor->TraverseDecl(Context.getTranslationUnitDecl()); Visitor->TraverseDecl(Context.getTranslationUnitDecl());
} }
@ -68,8 +69,7 @@ protected:
TestAction(TestVisitor *Visitor) : Visitor(Visitor) {} TestAction(TestVisitor *Visitor) : Visitor(Visitor) {}
virtual clang::ASTConsumer* CreateASTConsumer( virtual clang::ASTConsumer* CreateASTConsumer(
CompilerInstance& compiler, llvm::StringRef dummy) { CompilerInstance&, llvm::StringRef dummy) {
Visitor->Context = &compiler.getASTContext();
/// TestConsumer will be deleted by the framework calling us. /// TestConsumer will be deleted by the framework calling us.
return new FindConsumer(Visitor); return new FindConsumer(Visitor);
} }

View File

@ -104,7 +104,9 @@ TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
} }
struct IndependentFrontendActionCreator { struct IndependentFrontendActionCreator {
FrontendAction *newFrontendAction() { return new SyntaxOnlyAction; } ASTConsumer *newASTConsumer() {
return new FindTopLevelDeclConsumer(NULL);
}
}; };
TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) { TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {