Author: Stephen Kelly Date: 2020-12-22T12:09:32Z New Revision: 3b879fc97305849026db0e856920d318fadbc04b
URL: https://github.com/llvm/llvm-project/commit/3b879fc97305849026db0e856920d318fadbc04b DIFF: https://github.com/llvm/llvm-project/commit/3b879fc97305849026db0e856920d318fadbc04b.diff LOG: [ASTMatchers] Traverse-ignore range-for implementation details Differential Revision: https://reviews.llvm.org/D93596 Added: Modified: clang/include/clang/AST/RecursiveASTVisitor.h clang/lib/ASTMatchers/ASTMatchFinder.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 61e524793ec7..1426e569eabe 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -468,6 +468,8 @@ template <typename Derived> class RecursiveASTVisitor { DEF_TRAVERSE_TMPL_INST(Function) #undef DEF_TRAVERSE_TMPL_INST + bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); + private: // These are helper methods used by more than one Traverse* method. bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); @@ -497,7 +499,6 @@ template <typename Derived> class RecursiveASTVisitor { bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node); bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node); - bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); bool PostVisitStmt(Stmt *S); }; diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp index cc9537144524..762885fa0052 100644 --- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -463,6 +463,22 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>, bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit); bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL); + bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue) { + if (auto *RF = dyn_cast<CXXForRangeStmt>(S)) { + for (auto *SubStmt : RF->children()) { + if (SubStmt == RF->getInit() || SubStmt == RF->getLoopVarStmt() || + SubStmt == RF->getRangeInit() || SubStmt == RF->getBody()) { + TraverseStmt(SubStmt, Queue); + } else { + ASTNodeNotSpelledInSourceScope RAII(this, true); + TraverseStmt(SubStmt, Queue); + } + } + return true; + } + return RecursiveASTVisitor<MatchASTVisitor>::dataTraverseNode(S, Queue); + } + // Matches children or descendants of 'Node' with 'BaseMatcher'. bool memoizedMatchesRecursively(const DynTypedNode &Node, ASTContext &Ctx, const DynTypedMatcher &Matcher, diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 10d2d6ec3916..a3a3a911b85c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2580,6 +2580,31 @@ struct CtorInitsNonTrivial : NonTrivial 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))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = unaryOperator(hasOperatorName("++")); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = declStmt(hasSingleDecl(varDecl(matchesName("__range")))); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = declStmt(hasSingleDecl(varDecl(matchesName("__begin")))); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = declStmt(hasSingleDecl(varDecl(matchesName("__end")))); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } Code = R"cpp( void rangeFor() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits