diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -467,6 +467,10 @@ void VisitBindingDecl(const BindingDecl *D) { if (Traversal == TK_IgnoreUnlessSpelledInSource) return; + + if (const auto *V = D->getHoldingVar()) + Visit(V); + if (const auto *E = D->getBinding()) Visit(E); } diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp --- a/clang/unittests/AST/ASTTraverserTest.cpp +++ b/clang/unittests/AST/ASTTraverserTest.cpp @@ -1157,6 +1157,46 @@ f = 42; } +typedef __typeof(sizeof(int)) size_t; + +struct Pair +{ + int x, y; +}; + +// Note: these utilities are required to force binding to tuple like structure +namespace std +{ + template + struct tuple_size + { + }; + + template <> + struct tuple_size + { + static constexpr size_t value = 2; + }; + + template + struct tuple_element + { + using type = int; + }; + +}; + +template +int &&get(Pair &&p); + +void decompTuple() +{ + Pair p{1, 2}; + auto [a, b] = p; + + a = 3; +} + )cpp", {"-std=c++20"}); @@ -1492,6 +1532,48 @@ |-BindingDecl 'f' |-BindingDecl 's' `-BindingDecl 't' +)cpp"); + } + + { + auto FN = ast_matchers::match( + functionDecl(hasName("decompTuple"), + hasDescendant(decompositionDecl().bind("decomp"))), + AST2->getASTContext()); + EXPECT_EQ(FN.size(), 1u); + + EXPECT_EQ( + dumpASTString(TK_AsIs, FN[0].getNodeAs("decomp")), + R"cpp( +DecompositionDecl '' +|-CXXConstructExpr +| `-ImplicitCastExpr +| `-DeclRefExpr 'p' +|-BindingDecl 'a' +| |-VarDecl 'a' +| | `-CallExpr +| | |-ImplicitCastExpr +| | | `-DeclRefExpr 'get' +| | `-ImplicitCastExpr +| | `-DeclRefExpr '' +| `-DeclRefExpr 'a' +`-BindingDecl 'b' + |-VarDecl 'b' + | `-CallExpr + | |-ImplicitCastExpr + | | `-DeclRefExpr 'get' + | `-ImplicitCastExpr + | `-DeclRefExpr '' + `-DeclRefExpr 'b' +)cpp"); + + EXPECT_EQ(dumpASTString(TK_IgnoreUnlessSpelledInSource, + FN[0].getNodeAs("decomp")), + R"cpp( +DecompositionDecl '' +|-DeclRefExpr 'p' +|-BindingDecl 'a' +`-BindingDecl 'b' )cpp"); } }