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 @@ -1212,6 +1212,10 @@ class CXXRecordDecl : public RecordDecl {
12121212 // / if this is a closure type.
12131213 CXXMethodDecl *getLambdaCallOperator () const ;
12141214
1215+ // / Retrieve the dependent lambda call operator of the closure type
1216+ // / if this is a templated closure type.
1217+ FunctionTemplateDecl *getDependentLambdaCallOperator () const ;
1218+
12151219 // / Retrieve the lambda static invoker, the address of which
12161220 // / is returned by the conversion operator, and the body of which
12171221 // / is forwarded to the lambda call operator.
Original file line number Diff line number Diff line change @@ -1902,6 +1902,10 @@ class LambdaExpr final : public Expr,
19021902 // / lambda expression.
19031903 CXXMethodDecl *getCallOperator () const ;
19041904
1905+ // / Retrieve the function template call operator associated with this
1906+ // / lambda expression.
1907+ FunctionTemplateDecl *getDependentCallOperator () const ;
1908+
19051909 // / If this is a generic lambda expression, retrieve the template
19061910 // / parameter list associated with it, or else return null.
19071911 TemplateParameterList *getTemplateParameterList () const ;
Original file line number Diff line number Diff line change @@ -1369,17 +1369,25 @@ static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
13691369}
13701370#endif
13711371
1372- CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator () const {
1373- if (!isLambda ()) return nullptr ;
1372+ NamedDecl* getLambdaCallOperatorHelper ( const CXXRecordDecl &RD) {
1373+ if (!RD. isLambda ()) return nullptr ;
13741374 DeclarationName Name =
1375- getASTContext ().DeclarationNames .getCXXOperatorName (OO_Call);
1376- DeclContext::lookup_result Calls = lookup (Name);
1375+ RD. getASTContext ().DeclarationNames .getCXXOperatorName (OO_Call);
1376+ DeclContext::lookup_result Calls = RD. lookup (Name);
13771377
13781378 assert (!Calls.empty () && " Missing lambda call operator!" );
13791379 assert (allLookupResultsAreTheSame (Calls) &&
13801380 " More than one lambda call operator!" );
1381+ return Calls.front ();
1382+ }
1383+
1384+ FunctionTemplateDecl* CXXRecordDecl::getDependentLambdaCallOperator () const {
1385+ NamedDecl *CallOp = getLambdaCallOperatorHelper (*this );
1386+ return dyn_cast<FunctionTemplateDecl>(CallOp);
1387+ }
13811388
1382- NamedDecl *CallOp = Calls.front ();
1389+ CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator () const {
1390+ NamedDecl *CallOp = getLambdaCallOperatorHelper (*this );
13831391 if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp))
13841392 return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl ());
13851393
Original file line number Diff line number Diff line change @@ -1205,6 +1205,11 @@ CXXMethodDecl *LambdaExpr::getCallOperator() const {
12051205 return Record->getLambdaCallOperator ();
12061206}
12071207
1208+ FunctionTemplateDecl *LambdaExpr::getDependentCallOperator () const {
1209+ CXXRecordDecl *Record = getLambdaClass ();
1210+ return Record->getDependentLambdaCallOperator ();
1211+ }
1212+
12081213TemplateParameterList *LambdaExpr::getTemplateParameterList () const {
12091214 CXXRecordDecl *Record = getLambdaClass ();
12101215 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