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