Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h =================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h @@ -163,6 +163,9 @@ ASTContext &Context); /// @} + /// \brief Finds all matches in the given AST. + void matchAST(ASTContext &Context); + /// \brief Registers a callback to notify the end of parsing. /// /// The provided closure is called after parsing is done, before the AST is Index: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp =================================================================== --- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp +++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp @@ -744,25 +744,19 @@ class MatchASTConsumer : public ASTConsumer { public: - MatchASTConsumer( - std::vector > * - MatcherCallbackPairs, - MatchFinder::ParsingDoneTestCallback *ParsingDone) - : Visitor(MatcherCallbackPairs), ParsingDone(ParsingDone) {} + MatchASTConsumer(MatchFinder *Finder, + MatchFinder::ParsingDoneTestCallback *ParsingDone) + : Finder(Finder), ParsingDone(ParsingDone) {} private: virtual void HandleTranslationUnit(ASTContext &Context) { if (ParsingDone != NULL) { ParsingDone->run(); } - Visitor.set_active_ast_context(&Context); - Visitor.onStartOfTranslationUnit(); - Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - Visitor.onEndOfTranslationUnit(); - Visitor.set_active_ast_context(NULL); + Finder->matchAST(Context); } - MatchASTVisitor Visitor; + MatchFinder *Finder; MatchFinder::ParsingDoneTestCallback *ParsingDone; }; @@ -836,7 +830,7 @@ } ASTConsumer *MatchFinder::newASTConsumer() { - return new internal::MatchASTConsumer(&MatcherCallbackPairs, ParsingDone); + return new internal::MatchASTConsumer(this, ParsingDone); } void MatchFinder::match(const clang::ast_type_traits::DynTypedNode &Node, @@ -846,6 +840,14 @@ Visitor.match(Node); } +void MatchFinder::matchAST(ASTContext &Context) { + internal::MatchASTVisitor Visitor(&MatcherCallbackPairs); + Visitor.set_active_ast_context(&Context); + Visitor.onStartOfTranslationUnit(); + Visitor.TraverseDecl(Context.getTranslationUnitDecl()); + Visitor.onEndOfTranslationUnit(); +} + void MatchFinder::registerTestCallbackAfterParsing( MatchFinder::ParsingDoneTestCallback *NewParsingDone) { ParsingDone = NewParsingDone; Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h @@ -11,12 +11,14 @@ #define LLVM_CLANG_UNITTESTS_AST_MATCHERS_AST_MATCHERS_TEST_H #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/ASTUnit.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" namespace clang { namespace ast_matchers { +using clang::tooling::buildASTFromCodeWithArgs; using clang::tooling::newFrontendActionFactory; using clang::tooling::runToolOnCodeWithArgs; using clang::tooling::FrontendActionFactory; @@ -121,6 +123,21 @@ return testing::AssertionFailure() << "Verified unexpected result in \"" << Code << "\""; } + + VerifiedResult = false; + OwningPtr AST(buildASTFromCodeWithArgs(Code, Args)); + if (!AST.get()) + return testing::AssertionFailure() << "Parsing error in \"" << Code + << "\" while building AST"; + Finder.matchAST(AST->getASTContext()); + if (!VerifiedResult && ExpectResult) { + return testing::AssertionFailure() + << "Could not verify result in \"" << Code << "\" with AST"; + } else if (VerifiedResult && !ExpectResult) { + return testing::AssertionFailure() + << "Verified unexpected result in \"" << Code << "\" with AST"; + } + return testing::AssertionSuccess(); } Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4114,6 +4114,12 @@ OwningPtr Factory(newFrontendActionFactory(&Finder)); ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;")); EXPECT_TRUE(VerifyCallback.Called); + + VerifyCallback.Called = false; + OwningPtr AST(tooling::buildASTFromCode("int x;")); + ASSERT_TRUE(AST.get()); + Finder.matchAST(AST->getASTContext()); + EXPECT_TRUE(VerifyCallback.Called); } class VerifyEndOfTranslationUnit : public MatchFinder::MatchCallback { @@ -4135,6 +4141,12 @@ OwningPtr Factory(newFrontendActionFactory(&Finder)); ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;")); EXPECT_TRUE(VerifyCallback.Called); + + VerifyCallback.Called = false; + OwningPtr AST(tooling::buildASTFromCode("int x;")); + ASSERT_TRUE(AST.get()); + Finder.matchAST(AST->getASTContext()); + EXPECT_TRUE(VerifyCallback.Called); } TEST(EqualsBoundNodeMatcher, QualType) {