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 {
1172
1172
// / if this is a closure type.
1173
1173
CXXMethodDecl *getLambdaCallOperator () const ;
1174
1174
1175
+ // / Retrieve the dependent lambda call operator of the closure type
1176
+ // / if this is a templated closure type.
1177
+ FunctionTemplateDecl *getDependentLambdaCallOperator () const ;
1178
+
1175
1179
// / Retrieve the lambda static invoker, the address of which
1176
1180
// / is returned by the conversion operator, and the body of which
1177
1181
// / 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,
1907
1907
// / lambda expression.
1908
1908
CXXMethodDecl *getCallOperator () const ;
1909
1909
1910
+ // / Retrieve the function template call operator associated with this
1911
+ // / lambda expression.
1912
+ FunctionTemplateDecl *getDependentCallOperator () const ;
1913
+
1910
1914
// / If this is a generic lambda expression, retrieve the template
1911
1915
// / parameter list associated with it, or else return null.
1912
1916
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) {
1399
1399
}
1400
1400
#endif
1401
1401
1402
- CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator () const {
1403
- if (!isLambda ()) return nullptr ;
1402
+ NamedDecl* getLambdaCallOperatorHelper ( const CXXRecordDecl &RD) {
1403
+ if (!RD. isLambda ()) return nullptr ;
1404
1404
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);
1407
1407
1408
1408
assert (!Calls.empty () && " Missing lambda call operator!" );
1409
1409
assert (allLookupResultsAreTheSame (Calls) &&
1410
1410
" 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
+ }
1411
1418
1412
- NamedDecl *CallOp = Calls.front ();
1419
+ CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator () const {
1420
+ NamedDecl *CallOp = getLambdaCallOperatorHelper (*this );
1413
1421
if (const auto *CallOpTmpl = dyn_cast<FunctionTemplateDecl>(CallOp))
1414
1422
return cast<CXXMethodDecl>(CallOpTmpl->getTemplatedDecl ());
1415
1423
Original file line number Diff line number Diff line change @@ -1218,6 +1218,11 @@ CXXMethodDecl *LambdaExpr::getCallOperator() const {
1218
1218
return Record->getLambdaCallOperator ();
1219
1219
}
1220
1220
1221
+ FunctionTemplateDecl *LambdaExpr::getDependentCallOperator () const {
1222
+ CXXRecordDecl *Record = getLambdaClass ();
1223
+ return Record->getDependentLambdaCallOperator ();
1224
+ }
1225
+
1221
1226
TemplateParameterList *LambdaExpr::getTemplateParameterList () const {
1222
1227
CXXRecordDecl *Record = getLambdaClass ();
1223
1228
return Record->getGenericLambdaTemplateParameterList ();
Original file line number Diff line number Diff line change @@ -80,7 +80,10 @@ class CGBuilder : public StmtVisitor<CGBuilder> {
80
80
}
81
81
82
82
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 ())
84
87
G->VisitFunctionDecl (MD);
85
88
}
86
89
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
2
2
3
3
int get5 () {
4
4
return 5 ;
@@ -68,8 +68,25 @@ void templUser() {
68
68
}
69
69
}
70
70
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
+
71
84
// 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: $}}
73
90
// CHECK-NEXT: {{Function: SomeNS::templUser calls: SomeNS::templ SomeNS::templ $}}
74
91
// CHECK-NEXT: {{Function: SomeNS::templ calls: eee $}}
75
92
// CHECK-NEXT: {{Function: SomeNS::templ calls: ccc $}}
You can’t perform that action at this time.
0 commit comments