diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index 41be3738e707dd..69957a952d17cb 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -837,6 +837,14 @@ class MatchASTVisitor : public RecursiveASTVisitor, if (EnableCheckProfiling) Timer.setBucket(&TimeByBucket[MP.second->getID()]); BoundNodesTreeBuilder Builder; + + { + TraversalKindScope RAII(getASTContext(), MP.first.getTraversalKind()); + if (getASTContext().getParentMapContext().traverseIgnored(DynNode) != + DynNode) + continue; + } + if (MP.first.matches(DynNode, this, &Builder)) { MatchVisitor Visitor(ActiveASTContext, MP.second); Builder.visitMatches(&Visitor); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index c67c40ed960acc..06c2bbc29e5c58 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2519,6 +2519,78 @@ template<> bool timesTwo(bool){ EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); } + + Code = R"cpp( +struct B { + B(int); +}; + +B func1() { return 42; } + )cpp"; + { + auto M = expr(ignoringImplicit(integerLiteral(equals(42)).bind("intLit"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = expr(unless(integerLiteral(equals(24)))).bind("intLit"); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 7))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = + expr(anyOf(integerLiteral(equals(42)).bind("intLit"), unless(expr()))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = expr(allOf(integerLiteral(equals(42)).bind("intLit"), expr())); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = expr(integerLiteral(equals(42)).bind("intLit"), expr()); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = expr(optionally(integerLiteral(equals(42)).bind("intLit"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("intLit", 1))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("intLit", 1))); + } + { + auto M = expr().bind("allExprs"); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_AsIs, M), + std::make_unique>("allExprs", 7))); + EXPECT_TRUE(matchAndVerifyResultTrue( + Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + std::make_unique>("allExprs", 1))); + } } TEST(Traversal, traverseNoImplicit) {