1 | //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/ |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | //===----------------------------------------------------------------------===/ |
7 | // |
8 | // This file implements semantic analysis for C++0x variadic templates. |
9 | //===----------------------------------------------------------------------===/ |
10 | |
11 | #include "TypeLocBuilder.h" |
12 | #include "clang/AST/DynamicRecursiveASTVisitor.h" |
13 | #include "clang/AST/Expr.h" |
14 | #include "clang/AST/ExprObjC.h" |
15 | #include "clang/AST/TypeLoc.h" |
16 | #include "clang/Sema/Lookup.h" |
17 | #include "clang/Sema/ParsedAttr.h" |
18 | #include "clang/Sema/ParsedTemplate.h" |
19 | #include "clang/Sema/ScopeInfo.h" |
20 | #include "clang/Sema/Sema.h" |
21 | #include "clang/Sema/SemaInternal.h" |
22 | #include "clang/Sema/Template.h" |
23 | #include "llvm/Support/SaveAndRestore.h" |
24 | #include <optional> |
25 | |
26 | using namespace clang; |
27 | |
28 | //---------------------------------------------------------------------------- |
29 | // Visitor that collects unexpanded parameter packs |
30 | //---------------------------------------------------------------------------- |
31 | |
32 | namespace { |
33 | /// A class that collects unexpanded parameter packs. |
34 | class CollectUnexpandedParameterPacksVisitor |
35 | : public DynamicRecursiveASTVisitor { |
36 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; |
37 | |
38 | bool InLambdaOrBlock = false; |
39 | unsigned DepthLimit = (unsigned)-1; |
40 | |
41 | #ifndef NDEBUG |
42 | bool ContainsIntermediatePacks = false; |
43 | #endif |
44 | |
45 | void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) { |
46 | if (auto *VD = dyn_cast<VarDecl>(Val: ND)) { |
47 | // For now, the only problematic case is a generic lambda's templated |
48 | // call operator, so we don't need to look for all the other ways we |
49 | // could have reached a dependent parameter pack. |
50 | auto *FD = dyn_cast<FunctionDecl>(Val: VD->getDeclContext()); |
51 | auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr; |
52 | if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit) |
53 | return; |
54 | } else if (ND->isTemplateParameterPack() && |
55 | getDepthAndIndex(ND).first >= DepthLimit) { |
56 | return; |
57 | } |
58 | |
59 | Unexpanded.push_back(Elt: {ND, Loc}); |
60 | } |
61 | |
62 | void addUnexpanded(const TemplateTypeParmType *T, |
63 | SourceLocation Loc = SourceLocation()) { |
64 | if (T->getDepth() < DepthLimit) |
65 | Unexpanded.push_back(Elt: {T, Loc}); |
66 | } |
67 | |
68 | public: |
69 | explicit CollectUnexpandedParameterPacksVisitor( |
70 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) |
71 | : Unexpanded(Unexpanded) { |
72 | ShouldWalkTypesOfTypeLocs = false; |
73 | |
74 | // We need this so we can find e.g. attributes on lambdas. |
75 | ShouldVisitImplicitCode = true; |
76 | } |
77 | |
78 | //------------------------------------------------------------------------ |
79 | // Recording occurrences of (unexpanded) parameter packs. |
80 | //------------------------------------------------------------------------ |
81 | |
82 | /// Record occurrences of template type parameter packs. |
83 | bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override { |
84 | if (TL.getTypePtr()->isParameterPack()) |
85 | addUnexpanded(T: TL.getTypePtr(), Loc: TL.getNameLoc()); |
86 | return true; |
87 | } |
88 | |
89 | /// Record occurrences of template type parameter packs |
90 | /// when we don't have proper source-location information for |
91 | /// them. |
92 | /// |
93 | /// Ideally, this routine would never be used. |
94 | bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override { |
95 | if (T->isParameterPack()) |
96 | addUnexpanded(T); |
97 | |
98 | return true; |
99 | } |
100 | |
101 | /// Record occurrences of function and non-type template |
102 | /// parameter packs in an expression. |
103 | bool VisitDeclRefExpr(DeclRefExpr *E) override { |
104 | if (E->getDecl()->isParameterPack()) |
105 | addUnexpanded(ND: E->getDecl(), Loc: E->getLocation()); |
106 | |
107 | return true; |
108 | } |
109 | |
110 | /// Record occurrences of template template parameter packs. |
111 | bool TraverseTemplateName(TemplateName Template) override { |
112 | if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( |
113 | Val: Template.getAsTemplateDecl())) { |
114 | if (TTP->isParameterPack()) |
115 | addUnexpanded(ND: TTP); |
116 | } |
117 | |
118 | #ifndef NDEBUG |
119 | ContainsIntermediatePacks |= |
120 | (bool)Template.getAsSubstTemplateTemplateParmPack(); |
121 | #endif |
122 | |
123 | return DynamicRecursiveASTVisitor::TraverseTemplateName(Template); |
124 | } |
125 | |
126 | /// Suppress traversal into Objective-C container literal |
127 | /// elements that are pack expansions. |
128 | bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) override { |
129 | if (!E->containsUnexpandedParameterPack()) |
130 | return true; |
131 | |
132 | for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { |
133 | ObjCDictionaryElement Element = E->getKeyValueElement(Index: I); |
134 | if (Element.isPackExpansion()) |
135 | continue; |
136 | |
137 | TraverseStmt(S: Element.Key); |
138 | TraverseStmt(S: Element.Value); |
139 | } |
140 | return true; |
141 | } |
142 | //------------------------------------------------------------------------ |
143 | // Pruning the search for unexpanded parameter packs. |
144 | //------------------------------------------------------------------------ |
145 | |
146 | /// Suppress traversal into statements and expressions that |
147 | /// do not contain unexpanded parameter packs. |
148 | bool TraverseStmt(Stmt *S) override { |
149 | Expr *E = dyn_cast_or_null<Expr>(Val: S); |
150 | if ((E && E->containsUnexpandedParameterPack()) || InLambdaOrBlock) |
151 | return DynamicRecursiveASTVisitor::TraverseStmt(S); |
152 | |
153 | return true; |
154 | } |
155 | |
156 | /// Suppress traversal into types that do not contain |
157 | /// unexpanded parameter packs. |
158 | bool TraverseType(QualType T) override { |
159 | if ((!T.isNull() && T->containsUnexpandedParameterPack()) || |
160 | InLambdaOrBlock) |
161 | return DynamicRecursiveASTVisitor::TraverseType(T); |
162 | |
163 | return true; |
164 | } |
165 | |
166 | /// Suppress traversal into types with location information |
167 | /// that do not contain unexpanded parameter packs. |
168 | bool TraverseTypeLoc(TypeLoc TL) override { |
169 | if ((!TL.getType().isNull() && |
170 | TL.getType()->containsUnexpandedParameterPack()) || |
171 | InLambdaOrBlock) |
172 | return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL); |
173 | |
174 | return true; |
175 | } |
176 | |
177 | /// Suppress traversal of parameter packs. |
178 | bool TraverseDecl(Decl *D) override { |
179 | // A function parameter pack is a pack expansion, so cannot contain |
180 | // an unexpanded parameter pack. Likewise for a template parameter |
181 | // pack that contains any references to other packs. |
182 | if (D && D->isParameterPack()) |
183 | return true; |
184 | |
185 | return DynamicRecursiveASTVisitor::TraverseDecl(D); |
186 | } |
187 | |
188 | /// Suppress traversal of pack-expanded attributes. |
189 | bool TraverseAttr(Attr *A) override { |
190 | if (A->isPackExpansion()) |
191 | return true; |
192 | |
193 | return DynamicRecursiveASTVisitor::TraverseAttr(At: A); |
194 | } |
195 | |
196 | /// Suppress traversal of pack expansion expressions and types. |
197 | ///@{ |
198 | bool TraversePackExpansionType(PackExpansionType *T) override { |
199 | return true; |
200 | } |
201 | bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) override { |
202 | return true; |
203 | } |
204 | bool TraversePackExpansionExpr(PackExpansionExpr *E) override { |
205 | return true; |
206 | } |
207 | bool TraverseCXXFoldExpr(CXXFoldExpr *E) override { return true; } |
208 | bool TraversePackIndexingExpr(PackIndexingExpr *E) override { |
209 | return DynamicRecursiveASTVisitor::TraverseStmt(S: E->getIndexExpr()); |
210 | } |
211 | bool TraversePackIndexingType(PackIndexingType *E) override { |
212 | return DynamicRecursiveASTVisitor::TraverseStmt(S: E->getIndexExpr()); |
213 | } |
214 | bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) override { |
215 | return DynamicRecursiveASTVisitor::TraverseStmt(S: TL.getIndexExpr()); |
216 | } |
217 | |
218 | ///@} |
219 | |
220 | /// Suppress traversal of using-declaration pack expansion. |
221 | bool |
222 | TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) override { |
223 | if (D->isPackExpansion()) |
224 | return true; |
225 | |
226 | return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingValueDecl(D); |
227 | } |
228 | |
229 | /// Suppress traversal of using-declaration pack expansion. |
230 | bool TraverseUnresolvedUsingTypenameDecl( |
231 | UnresolvedUsingTypenameDecl *D) override { |
232 | if (D->isPackExpansion()) |
233 | return true; |
234 | |
235 | return DynamicRecursiveASTVisitor::TraverseUnresolvedUsingTypenameDecl(D); |
236 | } |
237 | |
238 | /// Suppress traversal of template argument pack expansions. |
239 | bool TraverseTemplateArgument(const TemplateArgument &Arg) override { |
240 | if (Arg.isPackExpansion()) |
241 | return true; |
242 | |
243 | return DynamicRecursiveASTVisitor::TraverseTemplateArgument(Arg); |
244 | } |
245 | |
246 | /// Suppress traversal of template argument pack expansions. |
247 | bool |
248 | TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) override { |
249 | if (ArgLoc.getArgument().isPackExpansion()) |
250 | return true; |
251 | |
252 | return DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc(ArgLoc); |
253 | } |
254 | |
255 | /// Suppress traversal of base specifier pack expansions. |
256 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) override { |
257 | if (Base.isPackExpansion()) |
258 | return true; |
259 | |
260 | return DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); |
261 | } |
262 | |
263 | /// Suppress traversal of mem-initializer pack expansions. |
264 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override { |
265 | if (Init->isPackExpansion()) |
266 | return true; |
267 | |
268 | return DynamicRecursiveASTVisitor::TraverseConstructorInitializer(Init); |
269 | } |
270 | |
271 | /// Note whether we're traversing a lambda containing an unexpanded |
272 | /// parameter pack. In this case, the unexpanded pack can occur anywhere, |
273 | /// including all the places where we normally wouldn't look. Within a |
274 | /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit |
275 | /// outside an expression. |
276 | bool TraverseLambdaExpr(LambdaExpr *Lambda) override { |
277 | // The ContainsUnexpandedParameterPack bit on a lambda is always correct, |
278 | // even if it's contained within another lambda. |
279 | if (!Lambda->containsUnexpandedParameterPack()) |
280 | return true; |
281 | |
282 | SaveAndRestore _(InLambdaOrBlock, true); |
283 | unsigned OldDepthLimit = DepthLimit; |
284 | |
285 | if (auto *TPL = Lambda->getTemplateParameterList()) |
286 | DepthLimit = TPL->getDepth(); |
287 | |
288 | DynamicRecursiveASTVisitor::TraverseLambdaExpr(S: Lambda); |
289 | |
290 | DepthLimit = OldDepthLimit; |
291 | return true; |
292 | } |
293 | |
294 | /// Analogously for blocks. |
295 | bool TraverseBlockExpr(BlockExpr *Block) override { |
296 | if (!Block->containsUnexpandedParameterPack()) |
297 | return true; |
298 | |
299 | SaveAndRestore _(InLambdaOrBlock, true); |
300 | DynamicRecursiveASTVisitor::TraverseBlockExpr(S: Block); |
301 | return true; |
302 | } |
303 | |
304 | /// Suppress traversal within pack expansions in lambda captures. |
305 | bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C, |
306 | Expr *Init) override { |
307 | if (C->isPackExpansion()) |
308 | return true; |
309 | |
310 | return DynamicRecursiveASTVisitor::TraverseLambdaCapture(LE: Lambda, C, Init); |
311 | } |
312 | |
313 | #ifndef NDEBUG |
314 | bool TraverseFunctionParmPackExpr(FunctionParmPackExpr *) override { |
315 | ContainsIntermediatePacks = true; |
316 | return true; |
317 | } |
318 | |
319 | bool TraverseSubstNonTypeTemplateParmPackExpr( |
320 | SubstNonTypeTemplateParmPackExpr *) override { |
321 | ContainsIntermediatePacks = true; |
322 | return true; |
323 | } |
324 | |
325 | bool VisitSubstTemplateTypeParmPackType( |
326 | SubstTemplateTypeParmPackType *) override { |
327 | ContainsIntermediatePacks = true; |
328 | return true; |
329 | } |
330 | |
331 | bool VisitSubstTemplateTypeParmPackTypeLoc( |
332 | SubstTemplateTypeParmPackTypeLoc) override { |
333 | ContainsIntermediatePacks = true; |
334 | return true; |
335 | } |
336 | |
337 | bool containsIntermediatePacks() const { return ContainsIntermediatePacks; } |
338 | #endif |
339 | }; |
340 | } |
341 | |
342 | /// Determine whether it's possible for an unexpanded parameter pack to |
343 | /// be valid in this location. This only happens when we're in a declaration |
344 | /// that is nested within an expression that could be expanded, such as a |
345 | /// lambda-expression within a function call. |
346 | /// |
347 | /// This is conservatively correct, but may claim that some unexpanded packs are |
348 | /// permitted when they are not. |
349 | bool Sema::isUnexpandedParameterPackPermitted() { |
350 | for (auto *SI : FunctionScopes) |
351 | if (isa<sema::LambdaScopeInfo>(Val: SI)) |
352 | return true; |
353 | return false; |
354 | } |
355 | |
356 | /// Diagnose all of the unexpanded parameter packs in the given |
357 | /// vector. |
358 | bool |
359 | Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, |
360 | UnexpandedParameterPackContext UPPC, |
361 | ArrayRef<UnexpandedParameterPack> Unexpanded) { |
362 | if (Unexpanded.empty()) |
363 | return false; |
364 | |
365 | // If we are within a lambda expression and referencing a pack that is not |
366 | // declared within the lambda itself, that lambda contains an unexpanded |
367 | // parameter pack, and we are done. Analogously for blocks. |
368 | // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it |
369 | // later. |
370 | SmallVector<UnexpandedParameterPack, 4> ParamPackReferences; |
371 | if (sema::CapturingScopeInfo *CSI = getEnclosingLambdaOrBlock()) { |
372 | for (auto &Pack : Unexpanded) { |
373 | auto DeclaresThisPack = [&](NamedDecl *LocalPack) { |
374 | if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) { |
375 | auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: LocalPack); |
376 | return TTPD && TTPD->getTypeForDecl() == TTPT; |
377 | } |
378 | return declaresSameEntity(D1: cast<NamedDecl *>(Val: Pack.first), D2: LocalPack); |
379 | }; |
380 | if (llvm::any_of(Range&: CSI->LocalPacks, P: DeclaresThisPack)) |
381 | ParamPackReferences.push_back(Elt: Pack); |
382 | } |
383 | |
384 | if (ParamPackReferences.empty()) { |
385 | // Construct in lambda only references packs declared outside the lambda. |
386 | // That's OK for now, but the lambda itself is considered to contain an |
387 | // unexpanded pack in this case, which will require expansion outside the |
388 | // lambda. |
389 | |
390 | // We do not permit pack expansion that would duplicate a statement |
391 | // expression, not even within a lambda. |
392 | // FIXME: We could probably support this for statement expressions that |
393 | // do not contain labels. |
394 | // FIXME: This is insufficient to detect this problem; consider |
395 | // f( ({ bad: 0; }) + pack ... ); |
396 | bool EnclosingStmtExpr = false; |
397 | for (unsigned N = FunctionScopes.size(); N; --N) { |
398 | sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; |
399 | if (llvm::any_of( |
400 | Range&: Func->CompoundScopes, |
401 | P: [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) { |
402 | EnclosingStmtExpr = true; |
403 | break; |
404 | } |
405 | // Coumpound-statements outside the lambda are OK for now; we'll check |
406 | // for those when we finish handling the lambda. |
407 | if (Func == CSI) |
408 | break; |
409 | } |
410 | |
411 | if (!EnclosingStmtExpr) { |
412 | CSI->ContainsUnexpandedParameterPack = true; |
413 | return false; |
414 | } |
415 | } else { |
416 | Unexpanded = ParamPackReferences; |
417 | } |
418 | } |
419 | |
420 | SmallVector<SourceLocation, 4> Locations; |
421 | SmallVector<IdentifierInfo *, 4> Names; |
422 | llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; |
423 | |
424 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { |
425 | IdentifierInfo *Name = nullptr; |
426 | if (const TemplateTypeParmType *TTP |
427 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) |
428 | Name = TTP->getIdentifier(); |
429 | else if (NamedDecl *ND = Unexpanded[I].first.dyn_cast<NamedDecl *>()) |
430 | Name = ND->getIdentifier(); |
431 | |
432 | if (Name && NamesKnown.insert(Ptr: Name).second) |
433 | Names.push_back(Elt: Name); |
434 | |
435 | if (Unexpanded[I].second.isValid()) |
436 | Locations.push_back(Elt: Unexpanded[I].second); |
437 | } |
438 | |
439 | auto DB = Diag(Loc, DiagID: diag::err_unexpanded_parameter_pack) |
440 | << (int)UPPC << (int)Names.size(); |
441 | for (size_t I = 0, E = std::min(a: Names.size(), b: (size_t)2); I != E; ++I) |
442 | DB << Names[I]; |
443 | |
444 | for (unsigned I = 0, N = Locations.size(); I != N; ++I) |
445 | DB << SourceRange(Locations[I]); |
446 | return true; |
447 | } |
448 | |
449 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
450 | TypeSourceInfo *T, |
451 | UnexpandedParameterPackContext UPPC) { |
452 | // C++0x [temp.variadic]p5: |
453 | // An appearance of a name of a parameter pack that is not expanded is |
454 | // ill-formed. |
455 | if (!T->getType()->containsUnexpandedParameterPack()) |
456 | return false; |
457 | |
458 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
459 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( |
460 | TL: T->getTypeLoc()); |
461 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
462 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); |
463 | } |
464 | |
465 | bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, |
466 | UnexpandedParameterPackContext UPPC) { |
467 | // C++0x [temp.variadic]p5: |
468 | // An appearance of a name of a parameter pack that is not expanded is |
469 | // ill-formed. |
470 | if (!E->containsUnexpandedParameterPack()) |
471 | return false; |
472 | |
473 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
474 | CollectUnexpandedParameterPacksVisitor Visitor(Unexpanded); |
475 | Visitor.TraverseStmt(S: E); |
476 | #ifndef NDEBUG |
477 | // The expression might contain a type/subexpression that has been substituted |
478 | // but has the expansion held off, e.g. a FunctionParmPackExpr which a larger |
479 | // CXXFoldExpr would expand. It's only possible when expanding a lambda as a |
480 | // pattern of a fold expression, so don't fire on an empty result in that |
481 | // case. |
482 | bool LambdaReferencingOuterPacks = |
483 | getEnclosingLambdaOrBlock() && Visitor.containsIntermediatePacks(); |
484 | assert((!Unexpanded.empty() || LambdaReferencingOuterPacks) && |
485 | "Unable to find unexpanded parameter packs" ); |
486 | #endif |
487 | return DiagnoseUnexpandedParameterPacks(Loc: E->getBeginLoc(), UPPC, Unexpanded); |
488 | } |
489 | |
490 | bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) { |
491 | if (!RE->containsUnexpandedParameterPack()) |
492 | return false; |
493 | |
494 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
495 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(S: RE); |
496 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
497 | |
498 | // We only care about unexpanded references to the RequiresExpr's own |
499 | // parameter packs. |
500 | auto Parms = RE->getLocalParameters(); |
501 | llvm::SmallPtrSet<NamedDecl *, 8> ParmSet(llvm::from_range, Parms); |
502 | SmallVector<UnexpandedParameterPack, 2> UnexpandedParms; |
503 | for (auto Parm : Unexpanded) |
504 | if (ParmSet.contains(Ptr: Parm.first.dyn_cast<NamedDecl *>())) |
505 | UnexpandedParms.push_back(Elt: Parm); |
506 | if (UnexpandedParms.empty()) |
507 | return false; |
508 | |
509 | return DiagnoseUnexpandedParameterPacks(Loc: RE->getBeginLoc(), UPPC: UPPC_Requirement, |
510 | Unexpanded: UnexpandedParms); |
511 | } |
512 | |
513 | bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, |
514 | UnexpandedParameterPackContext UPPC) { |
515 | // C++0x [temp.variadic]p5: |
516 | // An appearance of a name of a parameter pack that is not expanded is |
517 | // ill-formed. |
518 | if (!SS.getScopeRep() || |
519 | !SS.getScopeRep()->containsUnexpandedParameterPack()) |
520 | return false; |
521 | |
522 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
523 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
524 | .TraverseNestedNameSpecifier(NNS: SS.getScopeRep()); |
525 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
526 | return DiagnoseUnexpandedParameterPacks(Loc: SS.getRange().getBegin(), |
527 | UPPC, Unexpanded); |
528 | } |
529 | |
530 | bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, |
531 | UnexpandedParameterPackContext UPPC) { |
532 | // C++0x [temp.variadic]p5: |
533 | // An appearance of a name of a parameter pack that is not expanded is |
534 | // ill-formed. |
535 | switch (NameInfo.getName().getNameKind()) { |
536 | case DeclarationName::Identifier: |
537 | case DeclarationName::ObjCZeroArgSelector: |
538 | case DeclarationName::ObjCOneArgSelector: |
539 | case DeclarationName::ObjCMultiArgSelector: |
540 | case DeclarationName::CXXOperatorName: |
541 | case DeclarationName::CXXLiteralOperatorName: |
542 | case DeclarationName::CXXUsingDirective: |
543 | case DeclarationName::CXXDeductionGuideName: |
544 | return false; |
545 | |
546 | case DeclarationName::CXXConstructorName: |
547 | case DeclarationName::CXXDestructorName: |
548 | case DeclarationName::CXXConversionFunctionName: |
549 | // FIXME: We shouldn't need this null check! |
550 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) |
551 | return DiagnoseUnexpandedParameterPack(Loc: NameInfo.getLoc(), T: TSInfo, UPPC); |
552 | |
553 | if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) |
554 | return false; |
555 | |
556 | break; |
557 | } |
558 | |
559 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
560 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
561 | .TraverseType(T: NameInfo.getName().getCXXNameType()); |
562 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
563 | return DiagnoseUnexpandedParameterPacks(Loc: NameInfo.getLoc(), UPPC, Unexpanded); |
564 | } |
565 | |
566 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
567 | TemplateName Template, |
568 | UnexpandedParameterPackContext UPPC) { |
569 | |
570 | if (Template.isNull() || !Template.containsUnexpandedParameterPack()) |
571 | return false; |
572 | |
573 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
574 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
575 | .TraverseTemplateName(Template); |
576 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
577 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); |
578 | } |
579 | |
580 | bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, |
581 | UnexpandedParameterPackContext UPPC) { |
582 | if (Arg.getArgument().isNull() || |
583 | !Arg.getArgument().containsUnexpandedParameterPack()) |
584 | return false; |
585 | |
586 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
587 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
588 | .TraverseTemplateArgumentLoc(ArgLoc: Arg); |
589 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ); |
590 | return DiagnoseUnexpandedParameterPacks(Loc: Arg.getLocation(), UPPC, Unexpanded); |
591 | } |
592 | |
593 | void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, |
594 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
595 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
596 | .TraverseTemplateArgument(Arg); |
597 | } |
598 | |
599 | void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, |
600 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
601 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
602 | .TraverseTemplateArgumentLoc(ArgLoc: Arg); |
603 | } |
604 | |
605 | void Sema::collectUnexpandedParameterPacks(QualType T, |
606 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
607 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); |
608 | } |
609 | |
610 | void Sema::collectUnexpandedParameterPacks(TypeLoc TL, |
611 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
612 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); |
613 | } |
614 | |
615 | void Sema::collectUnexpandedParameterPacks( |
616 | NestedNameSpecifierLoc NNS, |
617 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
618 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
619 | .TraverseNestedNameSpecifierLoc(NNS); |
620 | } |
621 | |
622 | void Sema::collectUnexpandedParameterPacks( |
623 | const DeclarationNameInfo &NameInfo, |
624 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
625 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
626 | .TraverseDeclarationNameInfo(NameInfo); |
627 | } |
628 | |
629 | void Sema::collectUnexpandedParameterPacks( |
630 | Expr *E, SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
631 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(S: E); |
632 | } |
633 | |
634 | ParsedTemplateArgument |
635 | Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, |
636 | SourceLocation EllipsisLoc) { |
637 | if (Arg.isInvalid()) |
638 | return Arg; |
639 | |
640 | switch (Arg.getKind()) { |
641 | case ParsedTemplateArgument::Type: { |
642 | TypeResult Result = ActOnPackExpansion(Type: Arg.getAsType(), EllipsisLoc); |
643 | if (Result.isInvalid()) |
644 | return ParsedTemplateArgument(); |
645 | |
646 | return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), |
647 | Arg.getLocation()); |
648 | } |
649 | |
650 | case ParsedTemplateArgument::NonType: { |
651 | ExprResult Result = ActOnPackExpansion(Pattern: Arg.getAsExpr(), EllipsisLoc); |
652 | if (Result.isInvalid()) |
653 | return ParsedTemplateArgument(); |
654 | |
655 | return ParsedTemplateArgument(Arg.getKind(), Result.get(), |
656 | Arg.getLocation()); |
657 | } |
658 | |
659 | case ParsedTemplateArgument::Template: |
660 | if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) { |
661 | SourceRange R(Arg.getLocation()); |
662 | if (Arg.getScopeSpec().isValid()) |
663 | R.setBegin(Arg.getScopeSpec().getBeginLoc()); |
664 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_without_parameter_packs) |
665 | << R; |
666 | return ParsedTemplateArgument(); |
667 | } |
668 | |
669 | return Arg.getTemplatePackExpansion(EllipsisLoc); |
670 | } |
671 | llvm_unreachable("Unhandled template argument kind?" ); |
672 | } |
673 | |
674 | TypeResult Sema::ActOnPackExpansion(ParsedType Type, |
675 | SourceLocation EllipsisLoc) { |
676 | TypeSourceInfo *TSInfo; |
677 | GetTypeFromParser(Ty: Type, TInfo: &TSInfo); |
678 | if (!TSInfo) |
679 | return true; |
680 | |
681 | TypeSourceInfo *TSResult = |
682 | CheckPackExpansion(Pattern: TSInfo, EllipsisLoc, NumExpansions: std::nullopt); |
683 | if (!TSResult) |
684 | return true; |
685 | |
686 | return CreateParsedType(T: TSResult->getType(), TInfo: TSResult); |
687 | } |
688 | |
689 | TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, |
690 | SourceLocation EllipsisLoc, |
691 | UnsignedOrNone NumExpansions) { |
692 | // Create the pack expansion type and source-location information. |
693 | QualType Result = CheckPackExpansion(Pattern: Pattern->getType(), |
694 | PatternRange: Pattern->getTypeLoc().getSourceRange(), |
695 | EllipsisLoc, NumExpansions); |
696 | if (Result.isNull()) |
697 | return nullptr; |
698 | |
699 | TypeLocBuilder TLB; |
700 | TLB.pushFullCopy(L: Pattern->getTypeLoc()); |
701 | PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(T: Result); |
702 | TL.setEllipsisLoc(EllipsisLoc); |
703 | |
704 | return TLB.getTypeSourceInfo(Context, T: Result); |
705 | } |
706 | |
707 | QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, |
708 | SourceLocation EllipsisLoc, |
709 | UnsignedOrNone NumExpansions) { |
710 | // C++11 [temp.variadic]p5: |
711 | // The pattern of a pack expansion shall name one or more |
712 | // parameter packs that are not expanded by a nested pack |
713 | // expansion. |
714 | // |
715 | // A pattern containing a deduced type can't occur "naturally" but arises in |
716 | // the desugaring of an init-capture pack. |
717 | if (!Pattern->containsUnexpandedParameterPack() && |
718 | !Pattern->getContainedDeducedType()) { |
719 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_without_parameter_packs) |
720 | << PatternRange; |
721 | return QualType(); |
722 | } |
723 | |
724 | return Context.getPackExpansionType(Pattern, NumExpansions, |
725 | /*ExpectPackInType=*/false); |
726 | } |
727 | |
728 | ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { |
729 | return CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions: std::nullopt); |
730 | } |
731 | |
732 | ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, |
733 | UnsignedOrNone NumExpansions) { |
734 | if (!Pattern) |
735 | return ExprError(); |
736 | |
737 | // C++0x [temp.variadic]p5: |
738 | // The pattern of a pack expansion shall name one or more |
739 | // parameter packs that are not expanded by a nested pack |
740 | // expansion. |
741 | if (!Pattern->containsUnexpandedParameterPack()) { |
742 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_without_parameter_packs) |
743 | << Pattern->getSourceRange(); |
744 | return ExprError(); |
745 | } |
746 | |
747 | // Create the pack expansion expression and source-location information. |
748 | return new (Context) PackExpansionExpr(Pattern, EllipsisLoc, NumExpansions); |
749 | } |
750 | |
751 | bool Sema::CheckParameterPacksForExpansion( |
752 | SourceLocation EllipsisLoc, SourceRange PatternRange, |
753 | ArrayRef<UnexpandedParameterPack> Unexpanded, |
754 | const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, |
755 | bool &RetainExpansion, UnsignedOrNone &NumExpansions) { |
756 | ShouldExpand = true; |
757 | RetainExpansion = false; |
758 | IdentifierLoc FirstPack; |
759 | bool HaveFirstPack = false; |
760 | UnsignedOrNone NumPartialExpansions = std::nullopt; |
761 | SourceLocation PartiallySubstitutedPackLoc; |
762 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; |
763 | |
764 | for (UnexpandedParameterPack ParmPack : Unexpanded) { |
765 | // Compute the depth and index for this parameter pack. |
766 | unsigned Depth = 0, Index = 0; |
767 | IdentifierInfo *Name; |
768 | bool IsVarDeclPack = false; |
769 | FunctionParmPackExpr *BindingPack = nullptr; |
770 | |
771 | if (const TemplateTypeParmType *TTP = |
772 | ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) { |
773 | Depth = TTP->getDepth(); |
774 | Index = TTP->getIndex(); |
775 | Name = TTP->getIdentifier(); |
776 | } else { |
777 | NamedDecl *ND = cast<NamedDecl *>(Val&: ParmPack.first); |
778 | if (isa<VarDecl>(Val: ND)) |
779 | IsVarDeclPack = true; |
780 | else if (isa<BindingDecl>(Val: ND)) { |
781 | // Find the instantiated BindingDecl and check it for a resolved pack. |
782 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = |
783 | CurrentInstantiationScope->findInstantiationOf(D: ND); |
784 | Decl *B = cast<Decl *>(Val&: *Instantiation); |
785 | Expr *BindingExpr = cast<BindingDecl>(Val: B)->getBinding(); |
786 | BindingPack = cast_if_present<FunctionParmPackExpr>(Val: BindingExpr); |
787 | if (!BindingPack) { |
788 | ShouldExpand = false; |
789 | continue; |
790 | } |
791 | } else |
792 | std::tie(args&: Depth, args&: Index) = getDepthAndIndex(ND); |
793 | |
794 | Name = ND->getIdentifier(); |
795 | } |
796 | |
797 | // Determine the size of this argument pack. |
798 | unsigned NewPackSize, PendingPackExpansionSize = 0; |
799 | if (IsVarDeclPack) { |
800 | // Figure out whether we're instantiating to an argument pack or not. |
801 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = |
802 | CurrentInstantiationScope->findInstantiationOf( |
803 | D: cast<NamedDecl *>(Val&: ParmPack.first)); |
804 | if (isa<DeclArgumentPack *>(Val: *Instantiation)) { |
805 | // We could expand this function parameter pack. |
806 | NewPackSize = cast<DeclArgumentPack *>(Val&: *Instantiation)->size(); |
807 | } else { |
808 | // We can't expand this function parameter pack, so we can't expand |
809 | // the pack expansion. |
810 | ShouldExpand = false; |
811 | continue; |
812 | } |
813 | } else if (BindingPack) { |
814 | NewPackSize = BindingPack->getNumExpansions(); |
815 | } else { |
816 | // If we don't have a template argument at this depth/index, then we |
817 | // cannot expand the pack expansion. Make a note of this, but we still |
818 | // want to check any parameter packs we *do* have arguments for. |
819 | if (Depth >= TemplateArgs.getNumLevels() || |
820 | !TemplateArgs.hasTemplateArgument(Depth, Index)) { |
821 | ShouldExpand = false; |
822 | continue; |
823 | } |
824 | |
825 | // Determine the size of the argument pack. |
826 | ArrayRef<TemplateArgument> Pack = |
827 | TemplateArgs(Depth, Index).getPackAsArray(); |
828 | NewPackSize = Pack.size(); |
829 | PendingPackExpansionSize = |
830 | llvm::count_if(Range&: Pack, P: [](const TemplateArgument &TA) { |
831 | if (!TA.isPackExpansion()) |
832 | return false; |
833 | |
834 | if (TA.getKind() == TemplateArgument::Type) |
835 | return !TA.getAsType() |
836 | ->castAs<PackExpansionType>() |
837 | ->getNumExpansions(); |
838 | |
839 | if (TA.getKind() == TemplateArgument::Expression) |
840 | return !cast<PackExpansionExpr>(Val: TA.getAsExpr()) |
841 | ->getNumExpansions(); |
842 | |
843 | return !TA.getNumTemplateExpansions(); |
844 | }); |
845 | } |
846 | |
847 | // C++0x [temp.arg.explicit]p9: |
848 | // Template argument deduction can extend the sequence of template |
849 | // arguments corresponding to a template parameter pack, even when the |
850 | // sequence contains explicitly specified template arguments. |
851 | if (!IsVarDeclPack && CurrentInstantiationScope) { |
852 | if (NamedDecl *PartialPack = |
853 | CurrentInstantiationScope->getPartiallySubstitutedPack()) { |
854 | unsigned PartialDepth, PartialIndex; |
855 | std::tie(args&: PartialDepth, args&: PartialIndex) = getDepthAndIndex(ND: PartialPack); |
856 | if (PartialDepth == Depth && PartialIndex == Index) { |
857 | RetainExpansion = true; |
858 | // We don't actually know the new pack size yet. |
859 | NumPartialExpansions = NewPackSize; |
860 | PartiallySubstitutedPackLoc = ParmPack.second; |
861 | continue; |
862 | } |
863 | } |
864 | } |
865 | |
866 | if (!NumExpansions) { |
867 | // This is the first pack we've seen for which we have an argument. |
868 | // Record it. |
869 | NumExpansions = NewPackSize; |
870 | FirstPack = IdentifierLoc(ParmPack.second, Name); |
871 | HaveFirstPack = true; |
872 | continue; |
873 | } |
874 | |
875 | if (NewPackSize != *NumExpansions) { |
876 | // In some cases, we might be handling packs with unexpanded template |
877 | // arguments. For example, this can occur when substituting into a type |
878 | // alias declaration that uses its injected template parameters as |
879 | // arguments: |
880 | // |
881 | // template <class... Outer> struct S { |
882 | // template <class... Inner> using Alias = S<void(Outer, Inner)...>; |
883 | // }; |
884 | // |
885 | // Consider an instantiation attempt like 'S<int>::Alias<Pack...>', where |
886 | // Pack comes from another template parameter. 'S<int>' is first |
887 | // instantiated, expanding the outer pack 'Outer' to <int>. The alias |
888 | // declaration is accordingly substituted, leaving the template arguments |
889 | // as unexpanded |
890 | // '<Pack...>'. |
891 | // |
892 | // Since we have no idea of the size of '<Pack...>' until its expansion, |
893 | // we shouldn't assume its pack size for validation. However if we are |
894 | // certain that there are extra arguments beyond unexpanded packs, in |
895 | // which case the pack size is already larger than the previous expansion, |
896 | // we can complain that before instantiation. |
897 | unsigned LeastNewPackSize = NewPackSize - PendingPackExpansionSize; |
898 | if (PendingPackExpansionSize && LeastNewPackSize <= *NumExpansions) { |
899 | ShouldExpand = false; |
900 | continue; |
901 | } |
902 | // C++0x [temp.variadic]p5: |
903 | // All of the parameter packs expanded by a pack expansion shall have |
904 | // the same number of arguments specified. |
905 | if (HaveFirstPack) |
906 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_length_conflict) |
907 | << FirstPack.getIdentifierInfo() << Name << *NumExpansions |
908 | << (LeastNewPackSize != NewPackSize) << LeastNewPackSize |
909 | << SourceRange(FirstPack.getLoc()) << SourceRange(ParmPack.second); |
910 | else |
911 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_length_conflict_multilevel) |
912 | << Name << *NumExpansions << (LeastNewPackSize != NewPackSize) |
913 | << LeastNewPackSize << SourceRange(ParmPack.second); |
914 | return true; |
915 | } |
916 | } |
917 | |
918 | // If we're performing a partial expansion but we also have a full expansion, |
919 | // expand to the number of common arguments. For example, given: |
920 | // |
921 | // template<typename ...T> struct A { |
922 | // template<typename ...U> void f(pair<T, U>...); |
923 | // }; |
924 | // |
925 | // ... a call to 'A<int, int>().f<int>' should expand the pack once and |
926 | // retain an expansion. |
927 | if (NumPartialExpansions) { |
928 | if (NumExpansions && *NumExpansions < *NumPartialExpansions) { |
929 | NamedDecl *PartialPack = |
930 | CurrentInstantiationScope->getPartiallySubstitutedPack(); |
931 | Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_length_conflict_partial) |
932 | << PartialPack << *NumPartialExpansions << *NumExpansions |
933 | << SourceRange(PartiallySubstitutedPackLoc); |
934 | return true; |
935 | } |
936 | |
937 | NumExpansions = NumPartialExpansions; |
938 | } |
939 | |
940 | return false; |
941 | } |
942 | |
943 | UnsignedOrNone Sema::getNumArgumentsInExpansionFromUnexpanded( |
944 | llvm::ArrayRef<UnexpandedParameterPack> Unexpanded, |
945 | const MultiLevelTemplateArgumentList &TemplateArgs) { |
946 | UnsignedOrNone Result = std::nullopt; |
947 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { |
948 | // Compute the depth and index for this parameter pack. |
949 | unsigned Depth; |
950 | unsigned Index; |
951 | |
952 | if (const TemplateTypeParmType *TTP = |
953 | Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { |
954 | Depth = TTP->getDepth(); |
955 | Index = TTP->getIndex(); |
956 | } else { |
957 | NamedDecl *ND = cast<NamedDecl *>(Val: Unexpanded[I].first); |
958 | if (isa<VarDecl>(Val: ND)) { |
959 | // Function parameter pack or init-capture pack. |
960 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; |
961 | |
962 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = |
963 | CurrentInstantiationScope->findInstantiationOf( |
964 | D: cast<NamedDecl *>(Val: Unexpanded[I].first)); |
965 | if (isa<Decl *>(Val: *Instantiation)) |
966 | // The pattern refers to an unexpanded pack. We're not ready to expand |
967 | // this pack yet. |
968 | return std::nullopt; |
969 | |
970 | unsigned Size = cast<DeclArgumentPack *>(Val&: *Instantiation)->size(); |
971 | assert((!Result || *Result == Size) && "inconsistent pack sizes" ); |
972 | Result = Size; |
973 | continue; |
974 | } |
975 | |
976 | std::tie(args&: Depth, args&: Index) = getDepthAndIndex(ND); |
977 | } |
978 | if (Depth >= TemplateArgs.getNumLevels() || |
979 | !TemplateArgs.hasTemplateArgument(Depth, Index)) |
980 | // The pattern refers to an unknown template argument. We're not ready to |
981 | // expand this pack yet. |
982 | return std::nullopt; |
983 | |
984 | // Determine the size of the argument pack. |
985 | unsigned Size = TemplateArgs(Depth, Index).pack_size(); |
986 | assert((!Result || *Result == Size) && "inconsistent pack sizes" ); |
987 | Result = Size; |
988 | } |
989 | |
990 | return Result; |
991 | } |
992 | |
993 | UnsignedOrNone Sema::getNumArgumentsInExpansion( |
994 | QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) { |
995 | QualType Pattern = cast<PackExpansionType>(Val&: T)->getPattern(); |
996 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
997 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T: Pattern); |
998 | return getNumArgumentsInExpansionFromUnexpanded(Unexpanded, TemplateArgs); |
999 | } |
1000 | |
1001 | bool Sema::containsUnexpandedParameterPacks(Declarator &D) { |
1002 | const DeclSpec &DS = D.getDeclSpec(); |
1003 | switch (DS.getTypeSpecType()) { |
1004 | case TST_typename_pack_indexing: |
1005 | case TST_typename: |
1006 | case TST_typeof_unqualType: |
1007 | case TST_typeofType: |
1008 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: |
1009 | #include "clang/Basic/TransformTypeTraits.def" |
1010 | case TST_atomic: { |
1011 | QualType T = DS.getRepAsType().get(); |
1012 | if (!T.isNull() && T->containsUnexpandedParameterPack()) |
1013 | return true; |
1014 | break; |
1015 | } |
1016 | |
1017 | case TST_typeof_unqualExpr: |
1018 | case TST_typeofExpr: |
1019 | case TST_decltype: |
1020 | case TST_bitint: |
1021 | if (DS.getRepAsExpr() && |
1022 | DS.getRepAsExpr()->containsUnexpandedParameterPack()) |
1023 | return true; |
1024 | break; |
1025 | |
1026 | case TST_unspecified: |
1027 | case TST_void: |
1028 | case TST_char: |
1029 | case TST_wchar: |
1030 | case TST_char8: |
1031 | case TST_char16: |
1032 | case TST_char32: |
1033 | case TST_int: |
1034 | case TST_int128: |
1035 | case TST_half: |
1036 | case TST_float: |
1037 | case TST_double: |
1038 | case TST_Accum: |
1039 | case TST_Fract: |
1040 | case TST_Float16: |
1041 | case TST_float128: |
1042 | case TST_ibm128: |
1043 | case TST_bool: |
1044 | case TST_decimal32: |
1045 | case TST_decimal64: |
1046 | case TST_decimal128: |
1047 | case TST_enum: |
1048 | case TST_union: |
1049 | case TST_struct: |
1050 | case TST_interface: |
1051 | case TST_class: |
1052 | case TST_auto: |
1053 | case TST_auto_type: |
1054 | case TST_decltype_auto: |
1055 | case TST_BFloat16: |
1056 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: |
1057 | #include "clang/Basic/OpenCLImageTypes.def" |
1058 | #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case TST_##Name: |
1059 | #include "clang/Basic/HLSLIntangibleTypes.def" |
1060 | case TST_unknown_anytype: |
1061 | case TST_error: |
1062 | break; |
1063 | } |
1064 | |
1065 | for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { |
1066 | const DeclaratorChunk &Chunk = D.getTypeObject(i: I); |
1067 | switch (Chunk.Kind) { |
1068 | case DeclaratorChunk::Pointer: |
1069 | case DeclaratorChunk::Reference: |
1070 | case DeclaratorChunk::Paren: |
1071 | case DeclaratorChunk::Pipe: |
1072 | case DeclaratorChunk::BlockPointer: |
1073 | // These declarator chunks cannot contain any parameter packs. |
1074 | break; |
1075 | |
1076 | case DeclaratorChunk::Array: |
1077 | if (Chunk.Arr.NumElts && |
1078 | Chunk.Arr.NumElts->containsUnexpandedParameterPack()) |
1079 | return true; |
1080 | break; |
1081 | case DeclaratorChunk::Function: |
1082 | for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { |
1083 | ParmVarDecl *Param = cast<ParmVarDecl>(Val: Chunk.Fun.Params[i].Param); |
1084 | QualType ParamTy = Param->getType(); |
1085 | assert(!ParamTy.isNull() && "Couldn't parse type?" ); |
1086 | if (ParamTy->containsUnexpandedParameterPack()) return true; |
1087 | } |
1088 | |
1089 | if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { |
1090 | for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) { |
1091 | if (Chunk.Fun.Exceptions[i] |
1092 | .Ty.get() |
1093 | ->containsUnexpandedParameterPack()) |
1094 | return true; |
1095 | } |
1096 | } else if (isComputedNoexcept(ESpecType: Chunk.Fun.getExceptionSpecType()) && |
1097 | Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) |
1098 | return true; |
1099 | |
1100 | if (Chunk.Fun.hasTrailingReturnType()) { |
1101 | QualType T = Chunk.Fun.getTrailingReturnType().get(); |
1102 | if (!T.isNull() && T->containsUnexpandedParameterPack()) |
1103 | return true; |
1104 | } |
1105 | break; |
1106 | |
1107 | case DeclaratorChunk::MemberPointer: |
1108 | if (Chunk.Mem.Scope().getScopeRep() && |
1109 | Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) |
1110 | return true; |
1111 | break; |
1112 | } |
1113 | } |
1114 | |
1115 | if (Expr *TRC = D.getTrailingRequiresClause()) |
1116 | if (TRC->containsUnexpandedParameterPack()) |
1117 | return true; |
1118 | |
1119 | return false; |
1120 | } |
1121 | |
1122 | namespace { |
1123 | |
1124 | // Callback to only accept typo corrections that refer to parameter packs. |
1125 | class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { |
1126 | public: |
1127 | bool ValidateCandidate(const TypoCorrection &candidate) override { |
1128 | NamedDecl *ND = candidate.getCorrectionDecl(); |
1129 | return ND && ND->isParameterPack(); |
1130 | } |
1131 | |
1132 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
1133 | return std::make_unique<ParameterPackValidatorCCC>(args&: *this); |
1134 | } |
1135 | }; |
1136 | |
1137 | } |
1138 | |
1139 | ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, |
1140 | SourceLocation OpLoc, |
1141 | IdentifierInfo &Name, |
1142 | SourceLocation NameLoc, |
1143 | SourceLocation RParenLoc) { |
1144 | // C++0x [expr.sizeof]p5: |
1145 | // The identifier in a sizeof... expression shall name a parameter pack. |
1146 | LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); |
1147 | LookupName(R, S); |
1148 | |
1149 | NamedDecl *ParameterPack = nullptr; |
1150 | switch (R.getResultKind()) { |
1151 | case LookupResultKind::Found: |
1152 | ParameterPack = R.getFoundDecl(); |
1153 | break; |
1154 | |
1155 | case LookupResultKind::NotFound: |
1156 | case LookupResultKind::NotFoundInCurrentInstantiation: { |
1157 | ParameterPackValidatorCCC CCC{}; |
1158 | if (TypoCorrection Corrected = |
1159 | CorrectTypo(Typo: R.getLookupNameInfo(), LookupKind: R.getLookupKind(), S, SS: nullptr, |
1160 | CCC, Mode: CorrectTypoKind::ErrorRecovery)) { |
1161 | diagnoseTypo(Correction: Corrected, |
1162 | TypoDiag: PDiag(DiagID: diag::err_sizeof_pack_no_pack_name_suggest) << &Name, |
1163 | PrevNote: PDiag(DiagID: diag::note_parameter_pack_here)); |
1164 | ParameterPack = Corrected.getCorrectionDecl(); |
1165 | } |
1166 | break; |
1167 | } |
1168 | case LookupResultKind::FoundOverloaded: |
1169 | case LookupResultKind::FoundUnresolvedValue: |
1170 | break; |
1171 | |
1172 | case LookupResultKind::Ambiguous: |
1173 | DiagnoseAmbiguousLookup(Result&: R); |
1174 | return ExprError(); |
1175 | } |
1176 | |
1177 | if (!ParameterPack || !ParameterPack->isParameterPack()) { |
1178 | Diag(Loc: NameLoc, DiagID: diag::err_expected_name_of_pack) << &Name; |
1179 | return ExprError(); |
1180 | } |
1181 | |
1182 | MarkAnyDeclReferenced(Loc: OpLoc, D: ParameterPack, MightBeOdrUse: true); |
1183 | |
1184 | return SizeOfPackExpr::Create(Context, OperatorLoc: OpLoc, Pack: ParameterPack, PackLoc: NameLoc, |
1185 | RParenLoc); |
1186 | } |
1187 | |
1188 | static bool isParameterPack(Expr *PackExpression) { |
1189 | if (auto *D = dyn_cast<DeclRefExpr>(Val: PackExpression); D) { |
1190 | ValueDecl *VD = D->getDecl(); |
1191 | return VD->isParameterPack(); |
1192 | } |
1193 | return false; |
1194 | } |
1195 | |
1196 | ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression, |
1197 | SourceLocation EllipsisLoc, |
1198 | SourceLocation LSquareLoc, |
1199 | Expr *IndexExpr, |
1200 | SourceLocation RSquareLoc) { |
1201 | bool isParameterPack = ::isParameterPack(PackExpression); |
1202 | if (!isParameterPack) { |
1203 | if (!PackExpression->containsErrors()) |
1204 | Diag(Loc: PackExpression->getBeginLoc(), DiagID: diag::err_expected_name_of_pack) |
1205 | << PackExpression; |
1206 | return ExprError(); |
1207 | } |
1208 | ExprResult Res = |
1209 | BuildPackIndexingExpr(PackExpression, EllipsisLoc, IndexExpr, RSquareLoc); |
1210 | if (!Res.isInvalid()) |
1211 | Diag(Loc: Res.get()->getBeginLoc(), DiagID: getLangOpts().CPlusPlus26 |
1212 | ? diag::warn_cxx23_pack_indexing |
1213 | : diag::ext_pack_indexing); |
1214 | return Res; |
1215 | } |
1216 | |
1217 | ExprResult Sema::BuildPackIndexingExpr(Expr *PackExpression, |
1218 | SourceLocation EllipsisLoc, |
1219 | Expr *IndexExpr, |
1220 | SourceLocation RSquareLoc, |
1221 | ArrayRef<Expr *> ExpandedExprs, |
1222 | bool FullySubstituted) { |
1223 | |
1224 | std::optional<int64_t> Index; |
1225 | if (!IndexExpr->isInstantiationDependent()) { |
1226 | llvm::APSInt Value(Context.getIntWidth(T: Context.getSizeType())); |
1227 | |
1228 | ExprResult Res = CheckConvertedConstantExpression( |
1229 | From: IndexExpr, T: Context.getSizeType(), Value, CCE: CCEKind::ArrayBound); |
1230 | if (!Res.isUsable()) |
1231 | return ExprError(); |
1232 | Index = Value.getExtValue(); |
1233 | IndexExpr = Res.get(); |
1234 | } |
1235 | |
1236 | if (Index && FullySubstituted) { |
1237 | if (*Index < 0 || *Index >= int64_t(ExpandedExprs.size())) { |
1238 | Diag(Loc: PackExpression->getBeginLoc(), DiagID: diag::err_pack_index_out_of_bound) |
1239 | << *Index << PackExpression << ExpandedExprs.size(); |
1240 | return ExprError(); |
1241 | } |
1242 | } |
1243 | |
1244 | return PackIndexingExpr::Create(Context&: getASTContext(), EllipsisLoc, RSquareLoc, |
1245 | PackIdExpr: PackExpression, IndexExpr, Index, |
1246 | SubstitutedExprs: ExpandedExprs, FullySubstituted); |
1247 | } |
1248 | |
1249 | TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern( |
1250 | TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis, |
1251 | UnsignedOrNone &NumExpansions) const { |
1252 | const TemplateArgument &Argument = OrigLoc.getArgument(); |
1253 | assert(Argument.isPackExpansion()); |
1254 | switch (Argument.getKind()) { |
1255 | case TemplateArgument::Type: { |
1256 | // FIXME: We shouldn't ever have to worry about missing |
1257 | // type-source info! |
1258 | TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); |
1259 | if (!ExpansionTSInfo) |
1260 | ExpansionTSInfo = Context.getTrivialTypeSourceInfo(T: Argument.getAsType(), |
1261 | Loc: Ellipsis); |
1262 | PackExpansionTypeLoc Expansion = |
1263 | ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); |
1264 | Ellipsis = Expansion.getEllipsisLoc(); |
1265 | |
1266 | TypeLoc Pattern = Expansion.getPatternLoc(); |
1267 | NumExpansions = Expansion.getTypePtr()->getNumExpansions(); |
1268 | |
1269 | // We need to copy the TypeLoc because TemplateArgumentLocs store a |
1270 | // TypeSourceInfo. |
1271 | // FIXME: Find some way to avoid the copy? |
1272 | TypeLocBuilder TLB; |
1273 | TLB.pushFullCopy(L: Pattern); |
1274 | TypeSourceInfo *PatternTSInfo = |
1275 | TLB.getTypeSourceInfo(Context, T: Pattern.getType()); |
1276 | return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), |
1277 | PatternTSInfo); |
1278 | } |
1279 | |
1280 | case TemplateArgument::Expression: { |
1281 | PackExpansionExpr *Expansion |
1282 | = cast<PackExpansionExpr>(Val: Argument.getAsExpr()); |
1283 | Expr *Pattern = Expansion->getPattern(); |
1284 | Ellipsis = Expansion->getEllipsisLoc(); |
1285 | NumExpansions = Expansion->getNumExpansions(); |
1286 | return TemplateArgumentLoc( |
1287 | TemplateArgument(Pattern, Argument.isCanonicalExpr()), Pattern); |
1288 | } |
1289 | |
1290 | case TemplateArgument::TemplateExpansion: |
1291 | Ellipsis = OrigLoc.getTemplateEllipsisLoc(); |
1292 | NumExpansions = Argument.getNumTemplateExpansions(); |
1293 | return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), |
1294 | OrigLoc.getTemplateQualifierLoc(), |
1295 | OrigLoc.getTemplateNameLoc()); |
1296 | |
1297 | case TemplateArgument::Declaration: |
1298 | case TemplateArgument::NullPtr: |
1299 | case TemplateArgument::Template: |
1300 | case TemplateArgument::Integral: |
1301 | case TemplateArgument::StructuralValue: |
1302 | case TemplateArgument::Pack: |
1303 | case TemplateArgument::Null: |
1304 | return TemplateArgumentLoc(); |
1305 | } |
1306 | |
1307 | llvm_unreachable("Invalid TemplateArgument Kind!" ); |
1308 | } |
1309 | |
1310 | UnsignedOrNone Sema::getFullyPackExpandedSize(TemplateArgument Arg) { |
1311 | assert(Arg.containsUnexpandedParameterPack()); |
1312 | |
1313 | // If this is a substituted pack, grab that pack. If not, we don't know |
1314 | // the size yet. |
1315 | // FIXME: We could find a size in more cases by looking for a substituted |
1316 | // pack anywhere within this argument, but that's not necessary in the common |
1317 | // case for 'sizeof...(A)' handling. |
1318 | TemplateArgument Pack; |
1319 | switch (Arg.getKind()) { |
1320 | case TemplateArgument::Type: |
1321 | if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) |
1322 | Pack = Subst->getArgumentPack(); |
1323 | else |
1324 | return std::nullopt; |
1325 | break; |
1326 | |
1327 | case TemplateArgument::Expression: |
1328 | if (auto *Subst = |
1329 | dyn_cast<SubstNonTypeTemplateParmPackExpr>(Val: Arg.getAsExpr())) |
1330 | Pack = Subst->getArgumentPack(); |
1331 | else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Val: Arg.getAsExpr())) { |
1332 | for (ValueDecl *PD : *Subst) |
1333 | if (PD->isParameterPack()) |
1334 | return std::nullopt; |
1335 | return Subst->getNumExpansions(); |
1336 | } else |
1337 | return std::nullopt; |
1338 | break; |
1339 | |
1340 | case TemplateArgument::Template: |
1341 | if (SubstTemplateTemplateParmPackStorage *Subst = |
1342 | Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) |
1343 | Pack = Subst->getArgumentPack(); |
1344 | else |
1345 | return std::nullopt; |
1346 | break; |
1347 | |
1348 | case TemplateArgument::Declaration: |
1349 | case TemplateArgument::NullPtr: |
1350 | case TemplateArgument::TemplateExpansion: |
1351 | case TemplateArgument::Integral: |
1352 | case TemplateArgument::StructuralValue: |
1353 | case TemplateArgument::Pack: |
1354 | case TemplateArgument::Null: |
1355 | return std::nullopt; |
1356 | } |
1357 | |
1358 | // Check that no argument in the pack is itself a pack expansion. |
1359 | for (TemplateArgument Elem : Pack.pack_elements()) { |
1360 | // There's no point recursing in this case; we would have already |
1361 | // expanded this pack expansion into the enclosing pack if we could. |
1362 | if (Elem.isPackExpansion()) |
1363 | return std::nullopt; |
1364 | // Don't guess the size of unexpanded packs. The pack within a template |
1365 | // argument may have yet to be of a PackExpansion type before we see the |
1366 | // ellipsis in the annotation stage. |
1367 | // |
1368 | // This doesn't mean we would invalidate the optimization: Arg can be an |
1369 | // unexpanded pack regardless of Elem's dependence. For instance, |
1370 | // A TemplateArgument that contains either a SubstTemplateTypeParmPackType |
1371 | // or SubstNonTypeTemplateParmPackExpr is always considered Unexpanded, but |
1372 | // the underlying TemplateArgument thereof may not. |
1373 | if (Elem.containsUnexpandedParameterPack()) |
1374 | return std::nullopt; |
1375 | } |
1376 | return Pack.pack_size(); |
1377 | } |
1378 | |
1379 | static void CheckFoldOperand(Sema &S, Expr *E) { |
1380 | if (!E) |
1381 | return; |
1382 | |
1383 | E = E->IgnoreImpCasts(); |
1384 | auto *OCE = dyn_cast<CXXOperatorCallExpr>(Val: E); |
1385 | if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(Val: E) || |
1386 | isa<AbstractConditionalOperator>(Val: E)) { |
1387 | S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_fold_expression_bad_operand) |
1388 | << E->getSourceRange() |
1389 | << FixItHint::CreateInsertion(InsertionLoc: E->getBeginLoc(), Code: "(" ) |
1390 | << FixItHint::CreateInsertion(InsertionLoc: E->getEndLoc(), Code: ")" ); |
1391 | } |
1392 | } |
1393 | |
1394 | ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, |
1395 | tok::TokenKind Operator, |
1396 | SourceLocation EllipsisLoc, Expr *RHS, |
1397 | SourceLocation RParenLoc) { |
1398 | // LHS and RHS must be cast-expressions. We allow an arbitrary expression |
1399 | // in the parser and reduce down to just cast-expressions here. |
1400 | CheckFoldOperand(S&: *this, E: LHS); |
1401 | CheckFoldOperand(S&: *this, E: RHS); |
1402 | |
1403 | // [expr.prim.fold]p3: |
1404 | // In a binary fold, op1 and op2 shall be the same fold-operator, and |
1405 | // either e1 shall contain an unexpanded parameter pack or e2 shall contain |
1406 | // an unexpanded parameter pack, but not both. |
1407 | if (LHS && RHS && |
1408 | LHS->containsUnexpandedParameterPack() == |
1409 | RHS->containsUnexpandedParameterPack()) { |
1410 | return Diag(Loc: EllipsisLoc, |
1411 | DiagID: LHS->containsUnexpandedParameterPack() |
1412 | ? diag::err_fold_expression_packs_both_sides |
1413 | : diag::err_pack_expansion_without_parameter_packs) |
1414 | << LHS->getSourceRange() << RHS->getSourceRange(); |
1415 | } |
1416 | |
1417 | // [expr.prim.fold]p2: |
1418 | // In a unary fold, the cast-expression shall contain an unexpanded |
1419 | // parameter pack. |
1420 | if (!LHS || !RHS) { |
1421 | Expr *Pack = LHS ? LHS : RHS; |
1422 | assert(Pack && "fold expression with neither LHS nor RHS" ); |
1423 | if (!Pack->containsUnexpandedParameterPack()) { |
1424 | return Diag(Loc: EllipsisLoc, DiagID: diag::err_pack_expansion_without_parameter_packs) |
1425 | << Pack->getSourceRange(); |
1426 | } |
1427 | } |
1428 | |
1429 | BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind: Operator); |
1430 | |
1431 | // Perform first-phase name lookup now. |
1432 | UnresolvedLookupExpr *ULE = nullptr; |
1433 | { |
1434 | UnresolvedSet<16> Functions; |
1435 | LookupBinOp(S, OpLoc: EllipsisLoc, Opc, Functions); |
1436 | if (!Functions.empty()) { |
1437 | DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName( |
1438 | Op: BinaryOperator::getOverloadedOperator(Opc)); |
1439 | ExprResult Callee = CreateUnresolvedLookupExpr( |
1440 | /*NamingClass*/ nullptr, NNSLoc: NestedNameSpecifierLoc(), |
1441 | DNI: DeclarationNameInfo(OpName, EllipsisLoc), Fns: Functions); |
1442 | if (Callee.isInvalid()) |
1443 | return ExprError(); |
1444 | ULE = cast<UnresolvedLookupExpr>(Val: Callee.get()); |
1445 | } |
1446 | } |
1447 | |
1448 | return BuildCXXFoldExpr(Callee: ULE, LParenLoc, LHS, Operator: Opc, EllipsisLoc, RHS, RParenLoc, |
1449 | NumExpansions: std::nullopt); |
1450 | } |
1451 | |
1452 | ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, |
1453 | SourceLocation LParenLoc, Expr *LHS, |
1454 | BinaryOperatorKind Operator, |
1455 | SourceLocation EllipsisLoc, Expr *RHS, |
1456 | SourceLocation RParenLoc, |
1457 | UnsignedOrNone NumExpansions) { |
1458 | return new (Context) |
1459 | CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator, |
1460 | EllipsisLoc, RHS, RParenLoc, NumExpansions); |
1461 | } |
1462 | |
1463 | ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, |
1464 | BinaryOperatorKind Operator) { |
1465 | // [temp.variadic]p9: |
1466 | // If N is zero for a unary fold-expression, the value of the expression is |
1467 | // && -> true |
1468 | // || -> false |
1469 | // , -> void() |
1470 | // if the operator is not listed [above], the instantiation is ill-formed. |
1471 | // |
1472 | // Note that we need to use something like int() here, not merely 0, to |
1473 | // prevent the result from being a null pointer constant. |
1474 | QualType ScalarType; |
1475 | switch (Operator) { |
1476 | case BO_LOr: |
1477 | return ActOnCXXBoolLiteral(OpLoc: EllipsisLoc, Kind: tok::kw_false); |
1478 | case BO_LAnd: |
1479 | return ActOnCXXBoolLiteral(OpLoc: EllipsisLoc, Kind: tok::kw_true); |
1480 | case BO_Comma: |
1481 | ScalarType = Context.VoidTy; |
1482 | break; |
1483 | |
1484 | default: |
1485 | return Diag(Loc: EllipsisLoc, DiagID: diag::err_fold_expression_empty) |
1486 | << BinaryOperator::getOpcodeStr(Op: Operator); |
1487 | } |
1488 | |
1489 | return new (Context) CXXScalarValueInitExpr( |
1490 | ScalarType, Context.getTrivialTypeSourceInfo(T: ScalarType, Loc: EllipsisLoc), |
1491 | EllipsisLoc); |
1492 | } |
1493 | |