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