Author: Stephen Kelly Date: 2021-01-05T21:29:37Z New Revision: 16c6e9c58e9ae50a775945e6b407f1891f353d2f
URL: https://github.com/llvm/llvm-project/commit/16c6e9c58e9ae50a775945e6b407f1891f353d2f DIFF: https://github.com/llvm/llvm-project/commit/16c6e9c58e9ae50a775945e6b407f1891f353d2f.diff LOG: [ASTMatchers] Fix child traversal over range-for loops Differential Revision: https://reviews.llvm.org/D94031 Added: Modified: clang/lib/ASTMatchers/ASTMatchFinder.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Removed: ################################################################################ diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index 99d95838af61..39bdb94e62c6 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -236,6 +236,20 @@ class MatchChildASTVisitor ScopedIncrement ScopedDepth(&CurrentDepth); return traverse(TAL); } + bool TraverseCXXForRangeStmt(CXXForRangeStmt *Node) { + if (!Finder->isTraversalIgnoringImplicitNodes()) + return VisitorBase::TraverseCXXForRangeStmt(Node); + if (!Node) + return true; + ScopedIncrement ScopedDepth(&CurrentDepth); + if (auto *Init = Node->getInit()) + if (!match(*Init)) + return false; + if (!match(*Node->getLoopVariable()) || !match(*Node->getRangeInit()) || + !match(*Node->getBody())) + return false; + return VisitorBase::TraverseStmt(Node->getBody()); + } bool TraverseLambdaExpr(LambdaExpr *Node) { if (!Finder->isTraversalIgnoringImplicitNodes()) return VisitorBase::TraverseLambdaExpr(Node); @@ -575,8 +589,6 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, if (isTraversalIgnoringImplicitNodes()) { IgnoreImplicitChildren = true; - if (Node.get<CXXForRangeStmt>()) - ScopedTraversal = true; } ASTNodeNotSpelledInSourceScope RAII(this, ScopedTraversal); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index e706ea4b2a54..19ab6187d960 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2553,7 +2553,9 @@ struct CtorInitsNonTrivial : NonTrivial int arr[2]; for (auto i : arr) { - + if (true) + { + } } } )cpp"; @@ -2596,6 +2598,33 @@ struct CtorInitsNonTrivial : NonTrivial EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); } + { + auto M = cxxForRangeStmt(hasDescendant(ifStmt())); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + EXPECT_TRUE(matches( + Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt( + hasSingleDecl(varDecl(hasName("i"))))))))); + EXPECT_TRUE( + matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, + cxxForRangeStmt(has(varDecl(hasName("i"))))))); + } + { + EXPECT_TRUE(matches( + Code, traverse(TK_AsIs, cxxForRangeStmt(has(declStmt(hasSingleDecl( + varDecl(hasInitializer(declRefExpr( + to(varDecl(hasName("arr"))))))))))))); + EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, + cxxForRangeStmt(has(declRefExpr( + to(varDecl(hasName("arr"))))))))); + } + { + auto M = cxxForRangeStmt(has(compoundStmt())); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_TRUE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } { auto M = binaryOperator(hasOperatorName("!=")); EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); @@ -2659,7 +2688,8 @@ struct CtorInitsNonTrivial : NonTrivial true, {"-std=c++20"})); } { - auto M = cxxForRangeStmt(has(declStmt())); + auto M = + cxxForRangeStmt(has(declStmt(hasSingleDecl(varDecl(hasName("i")))))); EXPECT_TRUE( matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); EXPECT_FALSE( @@ -2679,6 +2709,19 @@ struct CtorInitsNonTrivial : NonTrivial matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), true, {"-std=c++20"})); } + { + auto M = cxxForRangeStmt( + has(declStmt(hasSingleDecl(varDecl( + hasName("a"), + hasInitializer(declRefExpr(to(varDecl(hasName("arr"))))))))), + hasLoopVariable(varDecl(hasName("i"))), + hasRangeInit(declRefExpr(to(varDecl(hasName("a")))))); + EXPECT_TRUE( + matchesConditionally(Code, traverse(TK_AsIs, M), true, {"-std=c++20"})); + EXPECT_TRUE( + matchesConditionally(Code, traverse(TK_IgnoreUnlessSpelledInSource, M), + true, {"-std=c++20"})); + } Code = R"cpp( void hasDefaultArg(int i, int j = 0) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits