Author: pcc Date: Thu Nov 7 16:30:32 2013 New Revision: 194222 URL: http://llvm.org/viewvc/llvm-project?rev=194222&view=rev Log: Re-introduce MatchFinder::addDynamicMatcher.
Differential Revision: http://llvm-reviews.chandlerc.com/D2114 Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h?rev=194222&r1=194221&r2=194222&view=diff ============================================================================== --- cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h (original) +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchFinder.h Thu Nov 7 16:30:32 2013 @@ -136,6 +136,17 @@ public: MatchCallback *Action); /// @} + /// \brief Adds a matcher to execute when running over the AST. + /// + /// This is similar to \c addMatcher(), but it uses the dynamic interface. It + /// is more flexible, but the lost type information enables a caller to pass + /// a matcher that cannot match anything. + /// + /// \returns \c true if the matcher is a valid top-level matcher, \c false + /// otherwise. + bool addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, + MatchCallback *Action); + /// \brief Creates a clang ASTConsumer that finds all matches. clang::ASTConsumer *newASTConsumer(); Modified: cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp?rev=194222&r1=194221&r2=194222&view=diff ============================================================================== --- cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp (original) +++ cfe/trunk/lib/ASTMatchers/ASTMatchFinder.cpp Thu Nov 7 16:30:32 2013 @@ -811,6 +811,30 @@ void MatchFinder::addMatcher(const TypeL MatcherCallbackPairs.push_back(std::make_pair(NodeMatch, Action)); } +bool MatchFinder::addDynamicMatcher(const internal::DynTypedMatcher &NodeMatch, + MatchCallback *Action) { + if (NodeMatch.canConvertTo<Decl>()) { + addMatcher(NodeMatch.convertTo<Decl>(), Action); + return true; + } else if (NodeMatch.canConvertTo<QualType>()) { + addMatcher(NodeMatch.convertTo<QualType>(), Action); + return true; + } else if (NodeMatch.canConvertTo<Stmt>()) { + addMatcher(NodeMatch.convertTo<Stmt>(), Action); + return true; + } else if (NodeMatch.canConvertTo<NestedNameSpecifier>()) { + addMatcher(NodeMatch.convertTo<NestedNameSpecifier>(), Action); + return true; + } else if (NodeMatch.canConvertTo<NestedNameSpecifierLoc>()) { + addMatcher(NodeMatch.convertTo<NestedNameSpecifierLoc>(), Action); + return true; + } else if (NodeMatch.canConvertTo<TypeLoc>()) { + addMatcher(NodeMatch.convertTo<TypeLoc>(), Action); + return true; + } + return false; +} + ASTConsumer *MatchFinder::newASTConsumer() { return new internal::MatchASTConsumer(&MatcherCallbackPairs, ParsingDone); } Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=194222&r1=194221&r2=194222&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Thu Nov 7 16:30:32 2013 @@ -40,6 +40,18 @@ TEST(IsDerivedFromDeathTest, DiesOnEmpty } #endif +TEST(Finder, DynamicOnlyAcceptsSomeMatchers) { + MatchFinder Finder; + EXPECT_TRUE(Finder.addDynamicMatcher(decl(), NULL)); + EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), NULL)); + EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)), NULL)); + + // Do not accept non-toplevel matchers. + EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), NULL)); + EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), NULL)); + EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), NULL)); +} + TEST(Decl, MatchesDeclarations) { EXPECT_TRUE(notMatches("", decl(usingDecl()))); EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;", @@ -651,11 +663,18 @@ public: : Id(Id), ExpectedCount(ExpectedCount), Count(0), ExpectedName(ExpectedName) {} - ~VerifyIdIsBoundTo() { + void onEndOfTranslationUnit() LLVM_OVERRIDE { if (ExpectedCount != -1) EXPECT_EQ(ExpectedCount, Count); if (!ExpectedName.empty()) EXPECT_EQ(ExpectedName, Name); + Count = 0; + Name.clear(); + } + + ~VerifyIdIsBoundTo() { + EXPECT_EQ(0, Count); + EXPECT_EQ("", Name); } virtual bool run(const BoundNodes *Nodes) { Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h?rev=194222&r1=194221&r2=194222&view=diff ============================================================================== --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h (original) +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h Thu Nov 7 16:30:32 2013 @@ -26,6 +26,7 @@ public: virtual ~BoundNodesCallback() {} virtual bool run(const BoundNodes *BoundNodes) = 0; virtual bool run(const BoundNodes *BoundNodes, ASTContext *Context) = 0; + virtual void onEndOfTranslationUnit() {} }; // If 'FindResultVerifier' is not NULL, sets *Verified to the result of @@ -44,6 +45,11 @@ public: } } + void onEndOfTranslationUnit() LLVM_OVERRIDE { + if (FindResultReviewer) + FindResultReviewer->onEndOfTranslationUnit(); + } + private: bool *const Verified; BoundNodesCallback *const FindResultReviewer; @@ -54,15 +60,23 @@ testing::AssertionResult matchesConditio const T &AMatcher, bool ExpectMatch, llvm::StringRef CompileArg) { - bool Found = false; + bool Found = false, DynamicFound = false; MatchFinder Finder; Finder.addMatcher(AMatcher, new VerifyMatch(0, &Found)); + if (!Finder.addDynamicMatcher(AMatcher, new VerifyMatch(0, &DynamicFound))) + return testing::AssertionFailure() << "Could not add dynamic matcher"; OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder)); // Some tests use typeof, which is a gnu extension. std::vector<std::string> Args(1, CompileArg); if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } + if (Found != DynamicFound) { + return testing::AssertionFailure() << "Dynamic match result (" + << DynamicFound + << ") does not match static result (" + << Found << ")"; + } if (!Found && ExpectMatch) { return testing::AssertionFailure() << "Could not find match in \"" << Code << "\""; _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
