diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -13,18 +13,19 @@ #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H +#include "clang/AST/ASTLambda.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" -#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" -#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" #include "clang/AST/LambdaCapture.h" @@ -2061,10 +2062,8 @@ (!D->isDefaulted() || getDerived().shouldVisitImplicitCode()); if (const auto *MD = dyn_cast(D)) { - if (const CXXRecordDecl *RD = MD->getParent()) { - if (RD->isLambda()) { - VisitBody = VisitBody && getDerived().shouldVisitLambdaBody(); - } + if (isLambdaCallOperator(MD)) { + VisitBody = VisitBody && getDerived().shouldVisitLambdaBody(); } } diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -474,6 +474,42 @@ EXPECT_TRUE(notMatches("void f() { int z = 3; [&z](){}; }", HasCaptureThis)); } +TEST(Matcher, MatchesMethodsOnLambda) { + StringRef Code = R"cpp( +struct A { + ~A() {} +}; +void foo() +{ + A a; + auto l = [a] { }; + auto lCopy = l; + auto lPtrDecay = +[] { }; + (void)lPtrDecay; +} +)cpp"; + + EXPECT_TRUE(matches( + Code, cxxConstructorDecl( + hasBody(compoundStmt()), + hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))), + isCopyConstructor()))); + EXPECT_TRUE(matches( + Code, cxxConstructorDecl( + hasBody(compoundStmt()), + hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l"))))), + isMoveConstructor()))); + EXPECT_TRUE(matches( + Code, cxxDestructorDecl( + hasBody(compoundStmt()), + hasAncestor(lambdaExpr(hasAncestor(varDecl(hasName("l")))))))); + EXPECT_TRUE(matches( + Code, cxxConversionDecl(hasBody(compoundStmt(has(returnStmt( + hasReturnValue(implicitCastExpr()))))), + hasAncestor(lambdaExpr(hasAncestor( + varDecl(hasName("lPtrDecay")))))))); +} + TEST(Matcher, isClassMessage) { EXPECT_TRUE(matchesObjC( "@interface NSString +(NSString *) stringWithFormat; @end "