diff options
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchFinder.h | 7 | ||||
-rw-r--r-- | lib/ASTMatchers/ASTMatchFinder.cpp | 10 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 21 |
3 files changed, 38 insertions, 0 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h index ba8e0a7ecc..30b4050e1c 100644 --- a/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -85,7 +85,14 @@ public: class MatchCallback { public: virtual ~MatchCallback(); + + /// \brief Called on every match by the \c MatchFinder. virtual void run(const MatchResult &Result) = 0; + + /// \brief Called at the start of each translation unit. + /// + /// Optionally override to do per translation unit tasks. + virtual void onStartOfTranslationUnit() {} }; /// \brief Called when parsing is finished. Intended for testing only. diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp index b081f5426e..8ecb26e8c1 100644 --- a/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/lib/ASTMatchers/ASTMatchFinder.cpp @@ -315,6 +315,15 @@ public: ActiveASTContext(NULL) { } + void onStartOfTranslationUnit() { + for (std::vector<std::pair<const internal::DynTypedMatcher*, + MatchCallback*> >::const_iterator + I = MatcherCallbackPairs->begin(), E = MatcherCallbackPairs->end(); + I != E; ++I) { + I->second->onStartOfTranslationUnit(); + } + } + void set_active_ast_context(ASTContext *NewActiveASTContext) { ActiveASTContext = NewActiveASTContext; } @@ -649,6 +658,7 @@ private: ParsingDone->run(); } Visitor.set_active_ast_context(&Context); + Visitor.onStartOfTranslationUnit(); Visitor.TraverseDecl(Context.getTranslationUnitDecl()); Visitor.set_active_ast_context(NULL); } diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 8861881efa..ad5469348d 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -3366,5 +3366,26 @@ TEST(MatchFinder, CanMatchStatementsRecursively) { new VerifyRecursiveMatch<clang::Stmt>("if", declStmt()))); } +class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback { +public: + VerifyStartOfTranslationUnit() : Called(false) {} + virtual void run(const MatchFinder::MatchResult &Result) { + EXPECT_TRUE(Called); + } + virtual void onStartOfTranslationUnit() { + Called = true; + } + bool Called; +}; + +TEST(MatchFinder, InterceptsStartOfTranslationUnit) { + MatchFinder Finder; + VerifyStartOfTranslationUnit VerifyCallback; + Finder.addMatcher(decl(), &VerifyCallback); + OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder)); + ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;")); + EXPECT_TRUE(VerifyCallback.Called); +} + } // end namespace ast_matchers } // end namespace clang |