@@ -26,6 +26,19 @@ using namespace clang;
26
26
// Visitor that collects unexpanded parameter packs
27
27
// ----------------------------------------------------------------------------
28
28
29
+ // / \brief Retrieve the depth and index of a parameter pack.
30
+ static std::pair<unsigned , unsigned >
31
+ getDepthAndIndex (NamedDecl *ND) {
32
+ if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
33
+ return std::make_pair (TTP->getDepth (), TTP->getIndex ());
34
+
35
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
36
+ return std::make_pair (NTTP->getDepth (), NTTP->getIndex ());
37
+
38
+ TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
39
+ return std::make_pair (TTP->getDepth (), TTP->getIndex ());
40
+ }
41
+
29
42
namespace {
30
43
// / \brief A class that collects unexpanded parameter packs.
31
44
class CollectUnexpandedParameterPacksVisitor :
@@ -36,23 +49,44 @@ namespace {
36
49
37
50
SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
38
51
39
- bool InLambda;
40
-
52
+ bool InLambda = false ;
53
+ unsigned DepthLimit = (unsigned )-1 ;
54
+
55
+ void addUnexpanded (NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
56
+ if (auto *PVD = dyn_cast<ParmVarDecl>(ND)) {
57
+ // For now, the only problematic case is a generic lambda's templated
58
+ // call operator, so we don't need to look for all the other ways we
59
+ // could have reached a dependent parameter pack.
60
+ auto *FD = dyn_cast<FunctionDecl>(PVD->getDeclContext ());
61
+ auto *FTD = FD ? FD->getDescribedFunctionTemplate () : nullptr ;
62
+ if (FTD && FTD->getTemplateParameters ()->getDepth () >= DepthLimit)
63
+ return ;
64
+ } else if (getDepthAndIndex (ND).first >= DepthLimit)
65
+ return ;
66
+
67
+ Unexpanded.push_back ({ND, Loc});
68
+ }
69
+ void addUnexpanded (const TemplateTypeParmType *T,
70
+ SourceLocation Loc = SourceLocation()) {
71
+ if (T->getDepth () < DepthLimit)
72
+ Unexpanded.push_back ({T, Loc});
73
+ }
74
+
41
75
public:
42
76
explicit CollectUnexpandedParameterPacksVisitor (
43
- SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
44
- : Unexpanded(Unexpanded), InLambda( false ) { }
77
+ SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
78
+ : Unexpanded(Unexpanded) { }
45
79
46
80
bool shouldWalkTypesOfTypeLocs () const { return false ; }
47
-
81
+
48
82
// ------------------------------------------------------------------------
49
83
// Recording occurrences of (unexpanded) parameter packs.
50
84
// ------------------------------------------------------------------------
51
85
52
86
// / \brief Record occurrences of template type parameter packs.
53
87
bool VisitTemplateTypeParmTypeLoc (TemplateTypeParmTypeLoc TL) {
54
88
if (TL.getTypePtr ()->isParameterPack ())
55
- Unexpanded. push_back ( std::make_pair ( TL.getTypePtr (), TL.getNameLoc () ));
89
+ addUnexpanded ( TL.getTypePtr (), TL.getNameLoc ());
56
90
return true ;
57
91
}
58
92
@@ -63,7 +97,7 @@ namespace {
63
97
// / Ideally, this routine would never be used.
64
98
bool VisitTemplateTypeParmType (TemplateTypeParmType *T) {
65
99
if (T->isParameterPack ())
66
- Unexpanded. push_back ( std::make_pair (T, SourceLocation ()) );
100
+ addUnexpanded (T );
67
101
68
102
return true ;
69
103
}
@@ -72,18 +106,18 @@ namespace {
72
106
// / parameter packs in an expression.
73
107
bool VisitDeclRefExpr (DeclRefExpr *E) {
74
108
if (E->getDecl ()->isParameterPack ())
75
- Unexpanded. push_back ( std::make_pair ( E->getDecl (), E->getLocation () ));
109
+ addUnexpanded ( E->getDecl (), E->getLocation ());
76
110
77
111
return true ;
78
112
}
79
113
80
114
// / \brief Record occurrences of template template parameter packs.
81
115
bool TraverseTemplateName (TemplateName Template) {
82
- if (TemplateTemplateParmDecl *TTP
83
- = dyn_cast_or_null<TemplateTemplateParmDecl>(
84
- Template.getAsTemplateDecl ()))
116
+ if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
117
+ Template.getAsTemplateDecl ())) {
85
118
if (TTP->isParameterPack ())
86
- Unexpanded.push_back (std::make_pair (TTP, SourceLocation ()));
119
+ addUnexpanded (TTP);
120
+ }
87
121
88
122
return inherited::TraverseTemplateName (Template);
89
123
}
@@ -141,7 +175,13 @@ namespace {
141
175
// / \brief Suppress traversal of non-parameter declarations, since
142
176
// / they cannot contain unexpanded parameter packs.
143
177
bool TraverseDecl (Decl *D) {
144
- if ((D && isa<ParmVarDecl>(D)) || InLambda)
178
+ auto *PVD = dyn_cast_or_null<ParmVarDecl>(D);
179
+ // A function parameter pack is a pack expansion, so cannot contain
180
+ // an unexpanded parameter pack.
181
+ if (PVD && PVD->isParameterPack ())
182
+ return true ;
183
+
184
+ if (PVD || InLambda)
145
185
return inherited::TraverseDecl (D);
146
186
147
187
return true ;
@@ -175,25 +215,26 @@ namespace {
175
215
return true ;
176
216
177
217
bool WasInLambda = InLambda;
178
- InLambda = true ;
218
+ unsigned OldDepthLimit = DepthLimit ;
179
219
180
- // If any capture names a function parameter pack, that pack is expanded
181
- // when the lambda is expanded.
182
- for (LambdaExpr::capture_iterator I = Lambda->capture_begin (),
183
- E = Lambda->capture_end ();
184
- I != E; ++I) {
185
- if (I->capturesVariable ()) {
186
- VarDecl *VD = I->getCapturedVar ();
187
- if (VD->isParameterPack ())
188
- Unexpanded.push_back (std::make_pair (VD, I->getLocation ()));
189
- }
190
- }
220
+ InLambda = true ;
221
+ if (auto *TPL = Lambda->getTemplateParameterList ())
222
+ DepthLimit = TPL->getDepth ();
191
223
192
224
inherited::TraverseLambdaExpr (Lambda);
193
225
194
226
InLambda = WasInLambda;
227
+ DepthLimit = OldDepthLimit;
195
228
return true ;
196
229
}
230
+
231
+ // / Suppress traversal within pack expansions in lambda captures.
232
+ bool TraverseLambdaCapture (LambdaExpr *Lambda, const LambdaCapture *C,
233
+ Expr *Init) {
234
+ if (C->isPackExpansion ())
235
+ return true ;
236
+ return inherited::TraverseLambdaCapture (Lambda, C, Init);
237
+ }
197
238
};
198
239
}
199
240
@@ -220,13 +261,33 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
220
261
if (Unexpanded.empty ())
221
262
return false ;
222
263
223
- // If we are within a lambda expression, that lambda contains an unexpanded
264
+ // If we are within a lambda expression and referencing a pack that is not
265
+ // a parameter of the lambda itself, that lambda contains an unexpanded
224
266
// parameter pack, and we are done.
225
267
// FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
226
268
// later.
269
+ SmallVector<UnexpandedParameterPack, 4 > GenericLambdaParamReferences;
227
270
for (unsigned N = FunctionScopes.size (); N; --N) {
228
271
if (sema::LambdaScopeInfo *LSI =
229
272
dyn_cast<sema::LambdaScopeInfo>(FunctionScopes[N-1 ])) {
273
+ if (LSI->isGenericLambda ()) {
274
+ for (auto &Param : Unexpanded) {
275
+ auto *PD = dyn_cast_or_null<ParmVarDecl>(
276
+ Param.first .dyn_cast <NamedDecl *>());
277
+ if (PD && PD->getDeclContext () == LSI->CallOperator )
278
+ GenericLambdaParamReferences.push_back (Param);
279
+ }
280
+ }
281
+
282
+ // If we have references to a parameter of a generic lambda, only
283
+ // diagnose those ones. We don't know whether any other unexpanded
284
+ // parameters referenced herein are actually unexpanded; they might
285
+ // be expanded at an outer level.
286
+ if (!GenericLambdaParamReferences.empty ()) {
287
+ Unexpanded = GenericLambdaParamReferences;
288
+ break ;
289
+ }
290
+
230
291
LSI->ContainsUnexpandedParameterPack = true ;
231
292
return false ;
232
293
}
@@ -520,19 +581,6 @@ ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
520
581
PackExpansionExpr (Context.DependentTy , Pattern, EllipsisLoc, NumExpansions);
521
582
}
522
583
523
- // / \brief Retrieve the depth and index of a parameter pack.
524
- static std::pair<unsigned , unsigned >
525
- getDepthAndIndex (NamedDecl *ND) {
526
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
527
- return std::make_pair (TTP->getDepth (), TTP->getIndex ());
528
-
529
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
530
- return std::make_pair (NTTP->getDepth (), NTTP->getIndex ());
531
-
532
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
533
- return std::make_pair (TTP->getDepth (), TTP->getIndex ());
534
- }
535
-
536
584
bool Sema::CheckParameterPacksForExpansion (
537
585
SourceLocation EllipsisLoc, SourceRange PatternRange,
538
586
ArrayRef<UnexpandedParameterPack> Unexpanded,
0 commit comments