diff options
6 files changed, 90 insertions, 31 deletions
diff --git a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp index df0ed10d9bd..0deb8d22f2c 100644 --- a/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp +++ b/clang-tools-extra/cpp11-migrate/AddOverride/AddOverride.cpp @@ -37,12 +37,6 @@ int AddOverrideTransform::apply(const FileContentsByPath &InputStates, FileContentsByPath &ResultStates) { RefactoringTool AddOverrideTool(Database, SourcePaths); - for (FileContentsByPath::const_iterator I = InputStates.begin(), - E = InputStates.end(); - I != E; ++I) { - AddOverrideTool.mapVirtualFile(I->first, I->second); - } - unsigned AcceptedChanges = 0; MatchFinder Finder; @@ -53,8 +47,8 @@ int AddOverrideTransform::apply(const FileContentsByPath &InputStates, Finder.addMatcher(makeCandidateForOverrideAttrMatcher(), &Fixer); - if (int result = AddOverrideTool.run( - newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) { + if (int result = + AddOverrideTool.run(createActionFactory(Finder, InputStates))) { llvm::errs() << "Error encountered during translation.\n"; return result; } diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp index 97597d63047..a781e912002 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.cpp +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.cpp @@ -1,11 +1,79 @@ #include "Core/Transform.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Rewrite/Core/Rewriter.h" #include "llvm/Support/raw_ostream.h" using namespace clang; +namespace { + +using namespace tooling; +using namespace ast_matchers; + +/// \brief Custom FrontendActionFactory to produce FrontendActions that handle +/// overriding source file contents before parsing. +/// +/// The nested class FactoryAdaptor overrides BeginSourceFileAction to override +/// source file contents before parsing happens. Both Begin and +/// EndSourceFileAction call corresponding callbacks provided by +/// SourceFileCallbacks. +class ActionFactory : public clang::tooling::FrontendActionFactory { +public: + ActionFactory(MatchFinder &Finder, const FileContentsByPath &Overrides, + SourceFileCallbacks &Callbacks) + : Finder(Finder), Overrides(Overrides), Callbacks(Callbacks) {} + + virtual FrontendAction *create() LLVM_OVERRIDE { + return new FactoryAdaptor(Finder, Overrides, Callbacks); + } + +private: + class FactoryAdaptor : public ASTFrontendAction { + public: + FactoryAdaptor(MatchFinder &Finder, const FileContentsByPath &Overrides, + SourceFileCallbacks &Callbacks) + : Finder(Finder), Overrides(Overrides), Callbacks(Callbacks) {} + + ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) { + return Finder.newASTConsumer(); + } + + virtual bool BeginSourceFileAction(CompilerInstance &CI, + StringRef Filename) LLVM_OVERRIDE { + if (!ASTFrontendAction::BeginSourceFileAction(CI, Filename)) + return false; + + FileContentsByPath::const_iterator I = Overrides.find(Filename.str()); + if (I != Overrides.end()) + // If an override exists, use it. + CI.getSourceManager() + .overrideFileContents(CI.getFileManager().getFile(I->first), + llvm::MemoryBuffer::getMemBuffer(I->second)); + + return Callbacks.handleBeginSource(CI, Filename); + } + + virtual void EndSourceFileAction() LLVM_OVERRIDE { + Callbacks.handleEndSource(); + return ASTFrontendAction::EndSourceFileAction(); + } + + private: + MatchFinder &Finder; + const FileContentsByPath &Overrides; + SourceFileCallbacks &Callbacks; + }; + + MatchFinder &Finder; + const FileContentsByPath &Overrides; + SourceFileCallbacks &Callbacks; +}; + +} // namespace + void collectResults(clang::Rewriter &Rewrite, const FileContentsByPath &InputStates, FileContentsByPath &Results) { @@ -55,3 +123,9 @@ void Transform::handleEndSource() { void Transform::addTiming(llvm::StringRef Label, llvm::TimeRecord Duration) { Timings.push_back(std::make_pair(Label.str(), Duration)); } + +FrontendActionFactory * +Transform::createActionFactory(MatchFinder &Finder, + const FileContentsByPath &InputStates) { + return new ActionFactory(Finder, InputStates, *this); +} diff --git a/clang-tools-extra/cpp11-migrate/Core/Transform.h b/clang-tools-extra/cpp11-migrate/Core/Transform.h index 17ec6ce9120..632d30b1496 100644 --- a/clang-tools-extra/cpp11-migrate/Core/Transform.h +++ b/clang-tools-extra/cpp11-migrate/Core/Transform.h @@ -49,6 +49,9 @@ namespace clang { namespace tooling { class CompilationDatabase; } // namespace tooling +namespace ast_matchers { +class MatchFinder; +} // namespace ast_matchers } // namespace clang /// \brief The key is the path of a file, which is mapped to a @@ -233,6 +236,13 @@ protected: const TransformOptions &Options() { return GlobalOptions; } + /// \brief Subclasses call this function to create a FrontendActionFactory to + /// pass to ClangTool. The factory returned by this function is responsible + /// for overriding source file contents with results of previous transforms. + clang::tooling::FrontendActionFactory * + createActionFactory(clang::ast_matchers::MatchFinder &Finder, + const FileContentsByPath &InputStates); + private: const std::string Name; const TransformOptions &GlobalOptions; diff --git a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp index 38659f854fa..355dfa362e1 100644 --- a/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp +++ b/clang-tools-extra/cpp11-migrate/LoopConvert/LoopConvert.cpp @@ -31,12 +31,6 @@ int LoopConvertTransform::apply(const FileContentsByPath &InputStates, FileContentsByPath &ResultStates) { RefactoringTool LoopTool(Database, SourcePaths); - for (FileContentsByPath::const_iterator I = InputStates.begin(), - E = InputStates.end(); - I != E; ++I) { - LoopTool.mapVirtualFile(I->first, I->second); - } - StmtAncestorASTVisitor ParentFinder; StmtGeneratedVarNameMap GeneratedDecls; ReplacedVarsMap ReplacedVars; @@ -63,8 +57,7 @@ int LoopConvertTransform::apply(const FileContentsByPath &InputStates, Options().MaxRiskLevel, LFK_PseudoArray); Finder.addMatcher(makePseudoArrayLoopMatcher(), &PseudoarrrayLoopFixer); - if (int result = LoopTool.run( - newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) { + if (int result = LoopTool.run(createActionFactory(Finder, InputStates))) { llvm::errs() << "Error encountered during translation.\n"; return result; } diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp index 3c75246ea34..2a76b304ad5 100644 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp +++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp @@ -26,11 +26,6 @@ int UseAutoTransform::apply(const FileContentsByPath &InputStates, FileContentsByPath &ResultStates) { RefactoringTool UseAutoTool(Database, SourcePaths); - for (FileContentsByPath::const_iterator I = InputStates.begin(), - E = InputStates.end(); - I != E; ++I) - UseAutoTool.mapVirtualFile(I->first, I->second); - unsigned AcceptedChanges = 0; MatchFinder Finder; @@ -42,8 +37,7 @@ int UseAutoTransform::apply(const FileContentsByPath &InputStates, Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators); Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew); - if (int Result = UseAutoTool.run( - newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) { + if (int Result = UseAutoTool.run(createActionFactory(Finder, InputStates))) { llvm::errs() << "Error encountered during translation.\n"; return Result; } diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp index 58c6d438b61..fa5811bae3b 100644 --- a/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp +++ b/clang-tools-extra/cpp11-migrate/UseNullptr/UseNullptr.cpp @@ -31,12 +31,6 @@ int UseNullptrTransform::apply(const FileContentsByPath &InputStates, FileContentsByPath &ResultStates) { RefactoringTool UseNullptrTool(Database, SourcePaths); - for (FileContentsByPath::const_iterator I = InputStates.begin(), - E = InputStates.end(); - I != E; ++I) { - UseNullptrTool.mapVirtualFile(I->first, I->second); - } - unsigned AcceptedChanges = 0; MatchFinder Finder; @@ -46,8 +40,8 @@ int UseNullptrTransform::apply(const FileContentsByPath &InputStates, Finder.addMatcher(makeCastSequenceMatcher(), &Fixer); - if (int result = UseNullptrTool.run( - newFrontendActionFactory(&Finder, /*Callbacks=*/ this))) { + if (int result = + UseNullptrTool.run(createActionFactory(Finder, InputStates))) { llvm::errs() << "Error encountered during translation.\n"; return result; } |