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