steveire created this revision. steveire added reviewers: aaron.ballman, alexfh. steveire requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95740 Files: clang/include/clang/AST/ASTNodeTraverser.h clang/lib/ASTMatchers/ASTMatchFinder.cpp clang/unittests/AST/ASTTraverserTest.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -2591,6 +2591,31 @@ Code, traverse(TK_IgnoreUnlessSpelledInSource, M), std::make_unique<VerifyIdIsBoundTo<Expr>>("allExprs", 1))); } + + Code = R"cpp( +void foo() +{ + int arr[3]; + auto &[f, s, t] = arr; + + f = 42; +} + )cpp"; + { + auto M = bindingDecl(hasName("f"), has(expr())); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = integerLiteral(hasAncestor(bindingDecl(hasName("f")))); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } + { + auto M = declRefExpr(hasAncestor(bindingDecl(hasName("f")))); + EXPECT_TRUE(matches(Code, traverse(TK_AsIs, M))); + EXPECT_FALSE(matches(Code, traverse(TK_IgnoreUnlessSpelledInSource, M))); + } } TEST(Traversal, traverseNoImplicit) { Index: clang/unittests/AST/ASTTraverserTest.cpp =================================================================== --- clang/unittests/AST/ASTTraverserTest.cpp +++ clang/unittests/AST/ASTTraverserTest.cpp @@ -1148,6 +1148,15 @@ { hasDefaultArg(42); } + +void decomposition() +{ + int arr[3]; + auto &[f, s, t] = arr; + + f = 42; +} + )cpp", {"-std=c++20"}); @@ -1443,6 +1452,46 @@ CallExpr |-DeclRefExpr 'hasDefaultArg' `-IntegerLiteral +)cpp"); + } + + { + auto FN = ast_matchers::match( + functionDecl(hasName("decomposition"), + hasDescendant(decompositionDecl().bind("decomp"))), + AST2->getASTContext()); + EXPECT_EQ(FN.size(), 1u); + + EXPECT_EQ( + dumpASTString(TK_AsIs, FN[0].getNodeAs<DecompositionDecl>("decomp")), + R"cpp( +DecompositionDecl '' +|-DeclRefExpr 'arr' +|-BindingDecl 'f' +| `-ArraySubscriptExpr +| |-ImplicitCastExpr +| | `-DeclRefExpr '' +| `-IntegerLiteral +|-BindingDecl 's' +| `-ArraySubscriptExpr +| |-ImplicitCastExpr +| | `-DeclRefExpr '' +| `-IntegerLiteral +`-BindingDecl 't' + `-ArraySubscriptExpr + |-ImplicitCastExpr + | `-DeclRefExpr '' + `-IntegerLiteral +)cpp"); + + EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, + FN[0].getNodeAs<DecompositionDecl>("decomp")), + R"cpp( +DecompositionDecl '' +|-DeclRefExpr 'arr' +|-BindingDecl 'f' +|-BindingDecl 's' +`-BindingDecl 't' )cpp"); } } Index: clang/lib/ASTMatchers/ASTMatchFinder.cpp =================================================================== --- clang/lib/ASTMatchers/ASTMatchFinder.cpp +++ clang/lib/ASTMatchers/ASTMatchFinder.cpp @@ -1216,6 +1216,8 @@ ScopedChildren = true; if (FD->isTemplateInstantiation()) ScopedTraversal = true; + } else if (isa<BindingDecl>(DeclNode)) { + ScopedChildren = true; } ASTNodeNotSpelledInSourceScope RAII1(this, ScopedTraversal); Index: clang/include/clang/AST/ASTNodeTraverser.h =================================================================== --- clang/include/clang/AST/ASTNodeTraverser.h +++ clang/include/clang/AST/ASTNodeTraverser.h @@ -438,6 +438,8 @@ } void VisitBindingDecl(const BindingDecl *D) { + if (Traversal == TK_IgnoreUnlessSpelledInSource) + return; if (const auto *E = D->getBinding()) Visit(E); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits