File tree Expand file tree Collapse file tree 6 files changed +49
-8
lines changed
Expand file tree Collapse file tree 6 files changed +49
-8
lines changed Original file line number Diff line number Diff line change @@ -1172,6 +1172,10 @@ class CXXRecordDecl : public RecordDecl {
11721172 // / if this is a closure type.
11731173 CXXMethodDecl *getLambdaCallOperator () const ;
11741174
1175+ // / Retrieve the dependent lambda call operator of the closure type
1176+ // / if this is a templated closure type.
1177+ FunctionTemplateDecl *getDependentLambdaCallOperator () const ;
1178+
11751179 // / Retrieve the lambda static invoker, the address of which
11761180 // / is returned by the conversion operator, and the body of which
11771181 // / is forwarded to the lambda call operator.
Original file line number Diff line number Diff line change @@ -1907,6 +1907,10 @@ class LambdaExpr final : public Expr,
19071907 // / lambda expression.
19081908 CXXMethodDecl *getCallOperator () const ;
19091909
1910+ // / Retrieve the function template call operator associated with this
1911+ // / lambda expression.
1912+ FunctionTemplateDecl *getDependentCallOperator () const ;
1913+
19101914 // / If this is a generic lambda expression, retrieve the template
19111915 // / parameter list associated with it, or else return null.
19121916 TemplateParameterList *getTemplateParameterList () const ;
Original file line number Diff line number Diff line change @@ -1399,17 +1399,25 @@ static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
13991399}
14001400#endif
14011401
1402- CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator () const {
1403- if (!isLambda ()) return nullptr ;
1402+ NamedDecl* getLambdaCallOperatorHelper ( const CXXRecordDecl &RD) {
1403+ if (!RD. isLambda ()) return nullptr ;
14041404 DeclarationName Name =
1405- getASTContext ().DeclarationNames .getCXXOperatorName (OO_Call);
1406- DeclContext::lookup_result Calls = lookup (Name);
1405+ RD. getASTContext ().DeclarationNames .getCXXOperatorName (OO_Call);
1406+ DeclContext::lookup_result Calls = RD. lookup (Name);
14071407
14081408 assert (!Calls.empty () && " Missing lambda call operator!" );
14091409 assert (allLookupResultsAreTheSame (Calls) &&
14101410 " More than one lambda call operator!" );
1411+ return Calls.front ();
1412+ }
1413+
1414+ FunctionTemplateDecl* CXXRecordDecl::getDependentLambdaCallOperator () const {
1415+ NamedDecl *CallOp = getLambdaCallOperatorHelper (*this );
1416+ return dyn_cast<FunctionTemplateDecl>(CallOp);
1417+ }
14111418
1412- NamedDecl *CallOp = Calls.front ();
1419+ CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator () const {
1420+ NamedDecl *CallOp = getLambdaCallOperatorHelper (*this );
14131421 if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp))
14141422 return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl ());
14151423
Original file line number Diff line number Diff line change @@ -1218,6 +1218,11 @@ CXXMethodDecl *LambdaExpr::getCallOperator() const {
12181218 return Record->getLambdaCallOperator ();
12191219}
12201220
1221+ FunctionTemplateDecl *LambdaExpr::getDependentCallOperator () const {
1222+ CXXRecordDecl *Record = getLambdaClass ();
1223+ return Record->getDependentLambdaCallOperator ();
1224+ }
1225+
12211226TemplateParameterList *LambdaExpr::getTemplateParameterList () const {
12221227 CXXRecordDecl *Record = getLambdaClass ();
12231228 return Record->getGenericLambdaTemplateParameterList ();
Original file line number Diff line number Diff line change @@ -80,7 +80,10 @@ class CGBuilder : public StmtVisitor<CGBuilder> {
8080 }
8181
8282 void VisitLambdaExpr (LambdaExpr *LE) {
83- if (CXXMethodDecl *MD = LE->getCallOperator ())
83+ if (FunctionTemplateDecl *FTD = LE->getDependentCallOperator ())
84+ for (FunctionDecl *FD : FTD->specializations ())
85+ G->VisitFunctionDecl (FD);
86+ else if (CXXMethodDecl *MD = LE->getCallOperator ())
8487 G->VisitFunctionDecl (MD);
8588 }
8689
Original file line number Diff line number Diff line change 1- // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
1+ // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s -fblocks -std=c++14 2>&1 | FileCheck %s
22
33int get5 () {
44 return 5 ;
@@ -68,8 +68,25 @@ void templUser() {
6868}
6969}
7070
71+ namespace Lambdas {
72+ void Callee (){}
73+
74+ void f1 () {
75+ [](int i) {
76+ Callee ();
77+ }(1 );
78+ [](auto i) {
79+ Callee ();
80+ }(1 );
81+ }
82+ }
83+
7184// CHECK:--- Call graph Dump ---
72- // CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ SomeNS::templ SomeNS::templUser $}}
85+ // CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call SomeNS::templ SomeNS::templ SomeNS::templUser Lambdas::Callee Lambdas::f1 Lambdas::f1\(\)::\(anonymous class\)::operator\(\) Lambdas::f1\(\)::\(anonymous class\)::operator\(\) $}}
86+ // CHECK-NEXT: {{Function: Lambdas::f1 calls: Lambdas::f1\(\)::\(anonymous class\)::operator\(\) Lambdas::f1\(\)::\(anonymous class\)::operator\(\) $}}
87+ // CHECK-NEXT: {{Function: Lambdas::f1\(\)::\(anonymous class\)::operator\(\) calls: Lambdas::Callee $}}
88+ // CHECK-NEXT: {{Function: Lambdas::f1\(\)::\(anonymous class\)::operator\(\) calls: Lambdas::Callee $}}
89+ // CHECK-NEXT: {{Function: Lambdas::Callee calls: $}}
7390// CHECK-NEXT: {{Function: SomeNS::templUser calls: SomeNS::templ SomeNS::templ $}}
7491// CHECK-NEXT: {{Function: SomeNS::templ calls: eee $}}
7592// CHECK-NEXT: {{Function: SomeNS::templ calls: ccc $}}
You can’t perform that action at this time.
0 commit comments