File: | build/llvm-toolchain-snapshot-16~++20220828101037+f00f2b3e8d40/clang/lib/Sema/SemaTemplateVariadic.cpp |
Warning: | line 708, column 11 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||||||||||
22 | using namespace clang; | ||||||||||||
23 | |||||||||||||
24 | //---------------------------------------------------------------------------- | ||||||||||||
25 | // Visitor that collects unexpanded parameter packs | ||||||||||||
26 | //---------------------------------------------------------------------------- | ||||||||||||
27 | |||||||||||||
28 | namespace { | ||||||||||||
29 | /// A class that collects unexpanded parameter packs. | ||||||||||||
30 | class CollectUnexpandedParameterPacksVisitor : | ||||||||||||
31 | public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | ||||||||||||
32 | { | ||||||||||||
33 | typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor> | ||||||||||||
34 | inherited; | ||||||||||||
35 | |||||||||||||
36 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; | ||||||||||||
37 | |||||||||||||
38 | bool InLambda = false; | ||||||||||||
39 | unsigned DepthLimit = (unsigned)-1; | ||||||||||||
40 | |||||||||||||
41 | void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) { | ||||||||||||
42 | if (auto *VD = dyn_cast<VarDecl>(ND)) { | ||||||||||||
43 | // For now, the only problematic case is a generic lambda's templated | ||||||||||||
44 | // call operator, so we don't need to look for all the other ways we | ||||||||||||
45 | // could have reached a dependent parameter pack. | ||||||||||||
46 | auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext()); | ||||||||||||
47 | auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr; | ||||||||||||
48 | if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit) | ||||||||||||
49 | return; | ||||||||||||
50 | } else if (getDepthAndIndex(ND).first >= DepthLimit) | ||||||||||||
51 | return; | ||||||||||||
52 | |||||||||||||
53 | Unexpanded.push_back({ND, Loc}); | ||||||||||||
54 | } | ||||||||||||
55 | void addUnexpanded(const TemplateTypeParmType *T, | ||||||||||||
56 | SourceLocation Loc = SourceLocation()) { | ||||||||||||
57 | if (T->getDepth() < DepthLimit) | ||||||||||||
58 | Unexpanded.push_back({T, Loc}); | ||||||||||||
59 | } | ||||||||||||
60 | |||||||||||||
61 | public: | ||||||||||||
62 | explicit CollectUnexpandedParameterPacksVisitor( | ||||||||||||
63 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) | ||||||||||||
64 | : Unexpanded(Unexpanded) {} | ||||||||||||
65 | |||||||||||||
66 | bool shouldWalkTypesOfTypeLocs() const { return false; } | ||||||||||||
67 | |||||||||||||
68 | //------------------------------------------------------------------------ | ||||||||||||
69 | // Recording occurrences of (unexpanded) parameter packs. | ||||||||||||
70 | //------------------------------------------------------------------------ | ||||||||||||
71 | |||||||||||||
72 | /// Record occurrences of template type parameter packs. | ||||||||||||
73 | bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { | ||||||||||||
74 | if (TL.getTypePtr()->isParameterPack()) | ||||||||||||
75 | addUnexpanded(TL.getTypePtr(), TL.getNameLoc()); | ||||||||||||
76 | return true; | ||||||||||||
77 | } | ||||||||||||
78 | |||||||||||||
79 | /// Record occurrences of template type parameter packs | ||||||||||||
80 | /// when we don't have proper source-location information for | ||||||||||||
81 | /// them. | ||||||||||||
82 | /// | ||||||||||||
83 | /// Ideally, this routine would never be used. | ||||||||||||
84 | bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { | ||||||||||||
85 | if (T->isParameterPack()) | ||||||||||||
86 | addUnexpanded(T); | ||||||||||||
87 | |||||||||||||
88 | return true; | ||||||||||||
89 | } | ||||||||||||
90 | |||||||||||||
91 | /// Record occurrences of function and non-type template | ||||||||||||
92 | /// parameter packs in an expression. | ||||||||||||
93 | bool VisitDeclRefExpr(DeclRefExpr *E) { | ||||||||||||
94 | if (E->getDecl()->isParameterPack()) | ||||||||||||
95 | addUnexpanded(E->getDecl(), E->getLocation()); | ||||||||||||
96 | |||||||||||||
97 | return true; | ||||||||||||
98 | } | ||||||||||||
99 | |||||||||||||
100 | /// Record occurrences of template template parameter packs. | ||||||||||||
101 | bool TraverseTemplateName(TemplateName Template) { | ||||||||||||
102 | if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>( | ||||||||||||
103 | Template.getAsTemplateDecl())) { | ||||||||||||
104 | if (TTP->isParameterPack()) | ||||||||||||
105 | addUnexpanded(TTP); | ||||||||||||
106 | } | ||||||||||||
107 | |||||||||||||
108 | return inherited::TraverseTemplateName(Template); | ||||||||||||
109 | } | ||||||||||||
110 | |||||||||||||
111 | /// Suppress traversal into Objective-C container literal | ||||||||||||
112 | /// elements that are pack expansions. | ||||||||||||
113 | bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { | ||||||||||||
114 | if (!E->containsUnexpandedParameterPack()) | ||||||||||||
115 | return true; | ||||||||||||
116 | |||||||||||||
117 | for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { | ||||||||||||
118 | ObjCDictionaryElement Element = E->getKeyValueElement(I); | ||||||||||||
119 | if (Element.isPackExpansion()) | ||||||||||||
120 | continue; | ||||||||||||
121 | |||||||||||||
122 | TraverseStmt(Element.Key); | ||||||||||||
123 | TraverseStmt(Element.Value); | ||||||||||||
124 | } | ||||||||||||
125 | return true; | ||||||||||||
126 | } | ||||||||||||
127 | //------------------------------------------------------------------------ | ||||||||||||
128 | // Pruning the search for unexpanded parameter packs. | ||||||||||||
129 | //------------------------------------------------------------------------ | ||||||||||||
130 | |||||||||||||
131 | /// Suppress traversal into statements and expressions that | ||||||||||||
132 | /// do not contain unexpanded parameter packs. | ||||||||||||
133 | bool TraverseStmt(Stmt *S) { | ||||||||||||
134 | Expr *E = dyn_cast_or_null<Expr>(S); | ||||||||||||
135 | if ((E && E->containsUnexpandedParameterPack()) || InLambda) | ||||||||||||
136 | return inherited::TraverseStmt(S); | ||||||||||||
137 | |||||||||||||
138 | return true; | ||||||||||||
139 | } | ||||||||||||
140 | |||||||||||||
141 | /// Suppress traversal into types that do not contain | ||||||||||||
142 | /// unexpanded parameter packs. | ||||||||||||
143 | bool TraverseType(QualType T) { | ||||||||||||
144 | if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda) | ||||||||||||
145 | return inherited::TraverseType(T); | ||||||||||||
146 | |||||||||||||
147 | return true; | ||||||||||||
148 | } | ||||||||||||
149 | |||||||||||||
150 | /// Suppress traversal into types with location information | ||||||||||||
151 | /// that do not contain unexpanded parameter packs. | ||||||||||||
152 | bool TraverseTypeLoc(TypeLoc TL) { | ||||||||||||
153 | if ((!TL.getType().isNull() && | ||||||||||||
154 | TL.getType()->containsUnexpandedParameterPack()) || | ||||||||||||
155 | InLambda) | ||||||||||||
156 | return inherited::TraverseTypeLoc(TL); | ||||||||||||
157 | |||||||||||||
158 | return true; | ||||||||||||
159 | } | ||||||||||||
160 | |||||||||||||
161 | /// Suppress traversal of parameter packs. | ||||||||||||
162 | bool TraverseDecl(Decl *D) { | ||||||||||||
163 | // A function parameter pack is a pack expansion, so cannot contain | ||||||||||||
164 | // an unexpanded parameter pack. Likewise for a template parameter | ||||||||||||
165 | // pack that contains any references to other packs. | ||||||||||||
166 | if (D && D->isParameterPack()) | ||||||||||||
167 | return true; | ||||||||||||
168 | |||||||||||||
169 | return inherited::TraverseDecl(D); | ||||||||||||
170 | } | ||||||||||||
171 | |||||||||||||
172 | /// Suppress traversal of pack-expanded attributes. | ||||||||||||
173 | bool TraverseAttr(Attr *A) { | ||||||||||||
174 | if (A->isPackExpansion()) | ||||||||||||
175 | return true; | ||||||||||||
176 | |||||||||||||
177 | return inherited::TraverseAttr(A); | ||||||||||||
178 | } | ||||||||||||
179 | |||||||||||||
180 | /// Suppress traversal of pack expansion expressions and types. | ||||||||||||
181 | ///@{ | ||||||||||||
182 | bool TraversePackExpansionType(PackExpansionType *T) { return true; } | ||||||||||||
183 | bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; } | ||||||||||||
184 | bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; } | ||||||||||||
185 | bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; } | ||||||||||||
186 | |||||||||||||
187 | ///@} | ||||||||||||
188 | |||||||||||||
189 | /// Suppress traversal of using-declaration pack expansion. | ||||||||||||
190 | bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { | ||||||||||||
191 | if (D->isPackExpansion()) | ||||||||||||
192 | return true; | ||||||||||||
193 | |||||||||||||
194 | return inherited::TraverseUnresolvedUsingValueDecl(D); | ||||||||||||
195 | } | ||||||||||||
196 | |||||||||||||
197 | /// Suppress traversal of using-declaration pack expansion. | ||||||||||||
198 | bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { | ||||||||||||
199 | if (D->isPackExpansion()) | ||||||||||||
200 | return true; | ||||||||||||
201 | |||||||||||||
202 | return inherited::TraverseUnresolvedUsingTypenameDecl(D); | ||||||||||||
203 | } | ||||||||||||
204 | |||||||||||||
205 | /// Suppress traversal of template argument pack expansions. | ||||||||||||
206 | bool TraverseTemplateArgument(const TemplateArgument &Arg) { | ||||||||||||
207 | if (Arg.isPackExpansion()) | ||||||||||||
208 | return true; | ||||||||||||
209 | |||||||||||||
210 | return inherited::TraverseTemplateArgument(Arg); | ||||||||||||
211 | } | ||||||||||||
212 | |||||||||||||
213 | /// Suppress traversal of template argument pack expansions. | ||||||||||||
214 | bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { | ||||||||||||
215 | if (ArgLoc.getArgument().isPackExpansion()) | ||||||||||||
216 | return true; | ||||||||||||
217 | |||||||||||||
218 | return inherited::TraverseTemplateArgumentLoc(ArgLoc); | ||||||||||||
219 | } | ||||||||||||
220 | |||||||||||||
221 | /// Suppress traversal of base specifier pack expansions. | ||||||||||||
222 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { | ||||||||||||
223 | if (Base.isPackExpansion()) | ||||||||||||
224 | return true; | ||||||||||||
225 | |||||||||||||
226 | return inherited::TraverseCXXBaseSpecifier(Base); | ||||||||||||
227 | } | ||||||||||||
228 | |||||||||||||
229 | /// Suppress traversal of mem-initializer pack expansions. | ||||||||||||
230 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { | ||||||||||||
231 | if (Init->isPackExpansion()) | ||||||||||||
232 | return true; | ||||||||||||
233 | |||||||||||||
234 | return inherited::TraverseConstructorInitializer(Init); | ||||||||||||
235 | } | ||||||||||||
236 | |||||||||||||
237 | /// Note whether we're traversing a lambda containing an unexpanded | ||||||||||||
238 | /// parameter pack. In this case, the unexpanded pack can occur anywhere, | ||||||||||||
239 | /// including all the places where we normally wouldn't look. Within a | ||||||||||||
240 | /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit | ||||||||||||
241 | /// outside an expression. | ||||||||||||
242 | bool TraverseLambdaExpr(LambdaExpr *Lambda) { | ||||||||||||
243 | // The ContainsUnexpandedParameterPack bit on a lambda is always correct, | ||||||||||||
244 | // even if it's contained within another lambda. | ||||||||||||
245 | if (!Lambda->containsUnexpandedParameterPack()) | ||||||||||||
246 | return true; | ||||||||||||
247 | |||||||||||||
248 | bool WasInLambda = InLambda; | ||||||||||||
249 | unsigned OldDepthLimit = DepthLimit; | ||||||||||||
250 | |||||||||||||
251 | InLambda = true; | ||||||||||||
252 | if (auto *TPL = Lambda->getTemplateParameterList()) | ||||||||||||
253 | DepthLimit = TPL->getDepth(); | ||||||||||||
254 | |||||||||||||
255 | inherited::TraverseLambdaExpr(Lambda); | ||||||||||||
256 | |||||||||||||
257 | InLambda = WasInLambda; | ||||||||||||
258 | DepthLimit = OldDepthLimit; | ||||||||||||
259 | return true; | ||||||||||||
260 | } | ||||||||||||
261 | |||||||||||||
262 | /// Suppress traversal within pack expansions in lambda captures. | ||||||||||||
263 | bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C, | ||||||||||||
264 | Expr *Init) { | ||||||||||||
265 | if (C->isPackExpansion()) | ||||||||||||
266 | return true; | ||||||||||||
267 | |||||||||||||
268 | return inherited::TraverseLambdaCapture(Lambda, C, Init); | ||||||||||||
269 | } | ||||||||||||
270 | }; | ||||||||||||
271 | } | ||||||||||||
272 | |||||||||||||
273 | /// Determine whether it's possible for an unexpanded parameter pack to | ||||||||||||
274 | /// be valid in this location. This only happens when we're in a declaration | ||||||||||||
275 | /// that is nested within an expression that could be expanded, such as a | ||||||||||||
276 | /// lambda-expression within a function call. | ||||||||||||
277 | /// | ||||||||||||
278 | /// This is conservatively correct, but may claim that some unexpanded packs are | ||||||||||||
279 | /// permitted when they are not. | ||||||||||||
280 | bool Sema::isUnexpandedParameterPackPermitted() { | ||||||||||||
281 | for (auto *SI : FunctionScopes) | ||||||||||||
282 | if (isa<sema::LambdaScopeInfo>(SI)) | ||||||||||||
283 | return true; | ||||||||||||
284 | return false; | ||||||||||||
285 | } | ||||||||||||
286 | |||||||||||||
287 | /// Diagnose all of the unexpanded parameter packs in the given | ||||||||||||
288 | /// vector. | ||||||||||||
289 | bool | ||||||||||||
290 | Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, | ||||||||||||
291 | UnexpandedParameterPackContext UPPC, | ||||||||||||
292 | ArrayRef<UnexpandedParameterPack> Unexpanded) { | ||||||||||||
293 | if (Unexpanded.empty()) | ||||||||||||
294 | return false; | ||||||||||||
295 | |||||||||||||
296 | // If we are within a lambda expression and referencing a pack that is not | ||||||||||||
297 | // declared within the lambda itself, that lambda contains an unexpanded | ||||||||||||
298 | // parameter pack, and we are done. | ||||||||||||
299 | // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it | ||||||||||||
300 | // later. | ||||||||||||
301 | SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences; | ||||||||||||
302 | if (auto *LSI = getEnclosingLambda()) { | ||||||||||||
303 | for (auto &Pack : Unexpanded) { | ||||||||||||
304 | auto DeclaresThisPack = [&](NamedDecl *LocalPack) { | ||||||||||||
305 | if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||||||
306 | auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack); | ||||||||||||
307 | return TTPD && TTPD->getTypeForDecl() == TTPT; | ||||||||||||
308 | } | ||||||||||||
309 | return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack); | ||||||||||||
310 | }; | ||||||||||||
311 | if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack)) | ||||||||||||
312 | LambdaParamPackReferences.push_back(Pack); | ||||||||||||
313 | } | ||||||||||||
314 | |||||||||||||
315 | if (LambdaParamPackReferences.empty()) { | ||||||||||||
316 | // Construct in lambda only references packs declared outside the lambda. | ||||||||||||
317 | // That's OK for now, but the lambda itself is considered to contain an | ||||||||||||
318 | // unexpanded pack in this case, which will require expansion outside the | ||||||||||||
319 | // lambda. | ||||||||||||
320 | |||||||||||||
321 | // We do not permit pack expansion that would duplicate a statement | ||||||||||||
322 | // expression, not even within a lambda. | ||||||||||||
323 | // FIXME: We could probably support this for statement expressions that | ||||||||||||
324 | // do not contain labels. | ||||||||||||
325 | // FIXME: This is insufficient to detect this problem; consider | ||||||||||||
326 | // f( ({ bad: 0; }) + pack ... ); | ||||||||||||
327 | bool EnclosingStmtExpr = false; | ||||||||||||
328 | for (unsigned N = FunctionScopes.size(); N; --N) { | ||||||||||||
329 | sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; | ||||||||||||
330 | if (llvm::any_of( | ||||||||||||
331 | Func->CompoundScopes, | ||||||||||||
332 | [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) { | ||||||||||||
333 | EnclosingStmtExpr = true; | ||||||||||||
334 | break; | ||||||||||||
335 | } | ||||||||||||
336 | // Coumpound-statements outside the lambda are OK for now; we'll check | ||||||||||||
337 | // for those when we finish handling the lambda. | ||||||||||||
338 | if (Func == LSI) | ||||||||||||
339 | break; | ||||||||||||
340 | } | ||||||||||||
341 | |||||||||||||
342 | if (!EnclosingStmtExpr) { | ||||||||||||
343 | LSI->ContainsUnexpandedParameterPack = true; | ||||||||||||
344 | return false; | ||||||||||||
345 | } | ||||||||||||
346 | } else { | ||||||||||||
347 | Unexpanded = LambdaParamPackReferences; | ||||||||||||
348 | } | ||||||||||||
349 | } | ||||||||||||
350 | |||||||||||||
351 | SmallVector<SourceLocation, 4> Locations; | ||||||||||||
352 | SmallVector<IdentifierInfo *, 4> Names; | ||||||||||||
353 | llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; | ||||||||||||
354 | |||||||||||||
355 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { | ||||||||||||
356 | IdentifierInfo *Name = nullptr; | ||||||||||||
357 | if (const TemplateTypeParmType *TTP | ||||||||||||
358 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) | ||||||||||||
359 | Name = TTP->getIdentifier(); | ||||||||||||
360 | else | ||||||||||||
361 | Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier(); | ||||||||||||
362 | |||||||||||||
363 | if (Name && NamesKnown.insert(Name).second) | ||||||||||||
364 | Names.push_back(Name); | ||||||||||||
365 | |||||||||||||
366 | if (Unexpanded[I].second.isValid()) | ||||||||||||
367 | Locations.push_back(Unexpanded[I].second); | ||||||||||||
368 | } | ||||||||||||
369 | |||||||||||||
370 | auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack) | ||||||||||||
371 | << (int)UPPC << (int)Names.size(); | ||||||||||||
372 | for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I) | ||||||||||||
373 | DB << Names[I]; | ||||||||||||
374 | |||||||||||||
375 | for (unsigned I = 0, N = Locations.size(); I != N; ++I) | ||||||||||||
376 | DB << SourceRange(Locations[I]); | ||||||||||||
377 | return true; | ||||||||||||
378 | } | ||||||||||||
379 | |||||||||||||
380 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | ||||||||||||
381 | TypeSourceInfo *T, | ||||||||||||
382 | UnexpandedParameterPackContext UPPC) { | ||||||||||||
383 | // C++0x [temp.variadic]p5: | ||||||||||||
384 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||||||
385 | // ill-formed. | ||||||||||||
386 | if (!T->getType()->containsUnexpandedParameterPack()) | ||||||||||||
387 | return false; | ||||||||||||
388 | |||||||||||||
389 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
390 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( | ||||||||||||
391 | T->getTypeLoc()); | ||||||||||||
392 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 392, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
393 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | ||||||||||||
394 | } | ||||||||||||
395 | |||||||||||||
396 | bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, | ||||||||||||
397 | UnexpandedParameterPackContext UPPC) { | ||||||||||||
398 | // C++0x [temp.variadic]p5: | ||||||||||||
399 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||||||
400 | // ill-formed. | ||||||||||||
401 | if (!E->containsUnexpandedParameterPack()) | ||||||||||||
402 | return false; | ||||||||||||
403 | |||||||||||||
404 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
405 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E); | ||||||||||||
406 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 406, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
407 | return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded); | ||||||||||||
408 | } | ||||||||||||
409 | |||||||||||||
410 | bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) { | ||||||||||||
411 | if (!RE->containsUnexpandedParameterPack()) | ||||||||||||
412 | return false; | ||||||||||||
413 | |||||||||||||
414 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
415 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE); | ||||||||||||
416 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 416, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
417 | |||||||||||||
418 | // We only care about unexpanded references to the RequiresExpr's own | ||||||||||||
419 | // parameter packs. | ||||||||||||
420 | auto Parms = RE->getLocalParameters(); | ||||||||||||
421 | llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end()); | ||||||||||||
422 | SmallVector<UnexpandedParameterPack, 2> UnexpandedParms; | ||||||||||||
423 | for (auto Parm : Unexpanded) | ||||||||||||
424 | if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>())) | ||||||||||||
425 | UnexpandedParms.push_back(Parm); | ||||||||||||
426 | if (UnexpandedParms.empty()) | ||||||||||||
427 | return false; | ||||||||||||
428 | |||||||||||||
429 | return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement, | ||||||||||||
430 | UnexpandedParms); | ||||||||||||
431 | } | ||||||||||||
432 | |||||||||||||
433 | bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, | ||||||||||||
434 | UnexpandedParameterPackContext UPPC) { | ||||||||||||
435 | // C++0x [temp.variadic]p5: | ||||||||||||
436 | // An appearance of a name of a parameter pack that is not expanded is | ||||||||||||
437 | // ill-formed. | ||||||||||||
438 | if (!SS.getScopeRep() || | ||||||||||||
439 | !SS.getScopeRep()->containsUnexpandedParameterPack()) | ||||||||||||
440 | return false; | ||||||||||||
441 | |||||||||||||
442 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
443 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
444 | .TraverseNestedNameSpecifier(SS.getScopeRep()); | ||||||||||||
445 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 445, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
446 | return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), | ||||||||||||
447 | UPPC, Unexpanded); | ||||||||||||
448 | } | ||||||||||||
449 | |||||||||||||
450 | bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, | ||||||||||||
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 | switch (NameInfo.getName().getNameKind()) { | ||||||||||||
456 | case DeclarationName::Identifier: | ||||||||||||
457 | case DeclarationName::ObjCZeroArgSelector: | ||||||||||||
458 | case DeclarationName::ObjCOneArgSelector: | ||||||||||||
459 | case DeclarationName::ObjCMultiArgSelector: | ||||||||||||
460 | case DeclarationName::CXXOperatorName: | ||||||||||||
461 | case DeclarationName::CXXLiteralOperatorName: | ||||||||||||
462 | case DeclarationName::CXXUsingDirective: | ||||||||||||
463 | case DeclarationName::CXXDeductionGuideName: | ||||||||||||
464 | return false; | ||||||||||||
465 | |||||||||||||
466 | case DeclarationName::CXXConstructorName: | ||||||||||||
467 | case DeclarationName::CXXDestructorName: | ||||||||||||
468 | case DeclarationName::CXXConversionFunctionName: | ||||||||||||
469 | // FIXME: We shouldn't need this null check! | ||||||||||||
470 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) | ||||||||||||
471 | return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); | ||||||||||||
472 | |||||||||||||
473 | if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) | ||||||||||||
474 | return false; | ||||||||||||
475 | |||||||||||||
476 | break; | ||||||||||||
477 | } | ||||||||||||
478 | |||||||||||||
479 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
480 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
481 | .TraverseType(NameInfo.getName().getCXXNameType()); | ||||||||||||
482 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 482, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
483 | return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded); | ||||||||||||
484 | } | ||||||||||||
485 | |||||||||||||
486 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, | ||||||||||||
487 | TemplateName Template, | ||||||||||||
488 | UnexpandedParameterPackContext UPPC) { | ||||||||||||
489 | |||||||||||||
490 | if (Template.isNull() || !Template.containsUnexpandedParameterPack()) | ||||||||||||
491 | return false; | ||||||||||||
492 | |||||||||||||
493 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
494 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
495 | .TraverseTemplateName(Template); | ||||||||||||
496 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 496, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
497 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); | ||||||||||||
498 | } | ||||||||||||
499 | |||||||||||||
500 | bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, | ||||||||||||
501 | UnexpandedParameterPackContext UPPC) { | ||||||||||||
502 | if (Arg.getArgument().isNull() || | ||||||||||||
503 | !Arg.getArgument().containsUnexpandedParameterPack()) | ||||||||||||
504 | return false; | ||||||||||||
505 | |||||||||||||
506 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
507 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
508 | .TraverseTemplateArgumentLoc(Arg); | ||||||||||||
509 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs" ) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 509, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
510 | return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded); | ||||||||||||
511 | } | ||||||||||||
512 | |||||||||||||
513 | void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, | ||||||||||||
514 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
515 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
516 | .TraverseTemplateArgument(Arg); | ||||||||||||
517 | } | ||||||||||||
518 | |||||||||||||
519 | void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, | ||||||||||||
520 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
521 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
522 | .TraverseTemplateArgumentLoc(Arg); | ||||||||||||
523 | } | ||||||||||||
524 | |||||||||||||
525 | void Sema::collectUnexpandedParameterPacks(QualType T, | ||||||||||||
526 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
527 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); | ||||||||||||
528 | } | ||||||||||||
529 | |||||||||||||
530 | void Sema::collectUnexpandedParameterPacks(TypeLoc TL, | ||||||||||||
531 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
532 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); | ||||||||||||
533 | } | ||||||||||||
534 | |||||||||||||
535 | void Sema::collectUnexpandedParameterPacks( | ||||||||||||
536 | NestedNameSpecifierLoc NNS, | ||||||||||||
537 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
538 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
539 | .TraverseNestedNameSpecifierLoc(NNS); | ||||||||||||
540 | } | ||||||||||||
541 | |||||||||||||
542 | void Sema::collectUnexpandedParameterPacks( | ||||||||||||
543 | const DeclarationNameInfo &NameInfo, | ||||||||||||
544 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { | ||||||||||||
545 | CollectUnexpandedParameterPacksVisitor(Unexpanded) | ||||||||||||
546 | .TraverseDeclarationNameInfo(NameInfo); | ||||||||||||
547 | } | ||||||||||||
548 | |||||||||||||
549 | |||||||||||||
550 | ParsedTemplateArgument | ||||||||||||
551 | Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, | ||||||||||||
552 | SourceLocation EllipsisLoc) { | ||||||||||||
553 | if (Arg.isInvalid()) | ||||||||||||
554 | return Arg; | ||||||||||||
555 | |||||||||||||
556 | switch (Arg.getKind()) { | ||||||||||||
557 | case ParsedTemplateArgument::Type: { | ||||||||||||
558 | TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc); | ||||||||||||
559 | if (Result.isInvalid()) | ||||||||||||
560 | return ParsedTemplateArgument(); | ||||||||||||
561 | |||||||||||||
562 | return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), | ||||||||||||
563 | Arg.getLocation()); | ||||||||||||
564 | } | ||||||||||||
565 | |||||||||||||
566 | case ParsedTemplateArgument::NonType: { | ||||||||||||
567 | ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); | ||||||||||||
568 | if (Result.isInvalid()) | ||||||||||||
569 | return ParsedTemplateArgument(); | ||||||||||||
570 | |||||||||||||
571 | return ParsedTemplateArgument(Arg.getKind(), Result.get(), | ||||||||||||
572 | Arg.getLocation()); | ||||||||||||
573 | } | ||||||||||||
574 | |||||||||||||
575 | case ParsedTemplateArgument::Template: | ||||||||||||
576 | if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) { | ||||||||||||
577 | SourceRange R(Arg.getLocation()); | ||||||||||||
578 | if (Arg.getScopeSpec().isValid()) | ||||||||||||
579 | R.setBegin(Arg.getScopeSpec().getBeginLoc()); | ||||||||||||
580 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||||||
581 | << R; | ||||||||||||
582 | return ParsedTemplateArgument(); | ||||||||||||
583 | } | ||||||||||||
584 | |||||||||||||
585 | return Arg.getTemplatePackExpansion(EllipsisLoc); | ||||||||||||
586 | } | ||||||||||||
587 | llvm_unreachable("Unhandled template argument kind?")::llvm::llvm_unreachable_internal("Unhandled template argument kind?" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 587); | ||||||||||||
588 | } | ||||||||||||
589 | |||||||||||||
590 | TypeResult Sema::ActOnPackExpansion(ParsedType Type, | ||||||||||||
591 | SourceLocation EllipsisLoc) { | ||||||||||||
592 | TypeSourceInfo *TSInfo; | ||||||||||||
593 | GetTypeFromParser(Type, &TSInfo); | ||||||||||||
594 | if (!TSInfo) | ||||||||||||
595 | return true; | ||||||||||||
596 | |||||||||||||
597 | TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None); | ||||||||||||
598 | if (!TSResult) | ||||||||||||
599 | return true; | ||||||||||||
600 | |||||||||||||
601 | return CreateParsedType(TSResult->getType(), TSResult); | ||||||||||||
602 | } | ||||||||||||
603 | |||||||||||||
604 | TypeSourceInfo * | ||||||||||||
605 | Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, | ||||||||||||
606 | Optional<unsigned> NumExpansions) { | ||||||||||||
607 | // Create the pack expansion type and source-location information. | ||||||||||||
608 | QualType Result = CheckPackExpansion(Pattern->getType(), | ||||||||||||
609 | Pattern->getTypeLoc().getSourceRange(), | ||||||||||||
610 | EllipsisLoc, NumExpansions); | ||||||||||||
611 | if (Result.isNull()) | ||||||||||||
612 | return nullptr; | ||||||||||||
613 | |||||||||||||
614 | TypeLocBuilder TLB; | ||||||||||||
615 | TLB.pushFullCopy(Pattern->getTypeLoc()); | ||||||||||||
616 | PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result); | ||||||||||||
617 | TL.setEllipsisLoc(EllipsisLoc); | ||||||||||||
618 | |||||||||||||
619 | return TLB.getTypeSourceInfo(Context, Result); | ||||||||||||
620 | } | ||||||||||||
621 | |||||||||||||
622 | QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, | ||||||||||||
623 | SourceLocation EllipsisLoc, | ||||||||||||
624 | Optional<unsigned> NumExpansions) { | ||||||||||||
625 | // C++11 [temp.variadic]p5: | ||||||||||||
626 | // The pattern of a pack expansion shall name one or more | ||||||||||||
627 | // parameter packs that are not expanded by a nested pack | ||||||||||||
628 | // expansion. | ||||||||||||
629 | // | ||||||||||||
630 | // A pattern containing a deduced type can't occur "naturally" but arises in | ||||||||||||
631 | // the desugaring of an init-capture pack. | ||||||||||||
632 | if (!Pattern->containsUnexpandedParameterPack() && | ||||||||||||
633 | !Pattern->getContainedDeducedType()) { | ||||||||||||
634 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||||||
635 | << PatternRange; | ||||||||||||
636 | return QualType(); | ||||||||||||
637 | } | ||||||||||||
638 | |||||||||||||
639 | return Context.getPackExpansionType(Pattern, NumExpansions, | ||||||||||||
640 | /*ExpectPackInType=*/false); | ||||||||||||
641 | } | ||||||||||||
642 | |||||||||||||
643 | ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { | ||||||||||||
644 | return CheckPackExpansion(Pattern, EllipsisLoc, None); | ||||||||||||
645 | } | ||||||||||||
646 | |||||||||||||
647 | ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, | ||||||||||||
648 | Optional<unsigned> NumExpansions) { | ||||||||||||
649 | if (!Pattern) | ||||||||||||
650 | return ExprError(); | ||||||||||||
651 | |||||||||||||
652 | // C++0x [temp.variadic]p5: | ||||||||||||
653 | // The pattern of a pack expansion shall name one or more | ||||||||||||
654 | // parameter packs that are not expanded by a nested pack | ||||||||||||
655 | // expansion. | ||||||||||||
656 | if (!Pattern->containsUnexpandedParameterPack()) { | ||||||||||||
657 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||||||
658 | << Pattern->getSourceRange(); | ||||||||||||
659 | CorrectDelayedTyposInExpr(Pattern); | ||||||||||||
660 | return ExprError(); | ||||||||||||
661 | } | ||||||||||||
662 | |||||||||||||
663 | // Create the pack expansion expression and source-location information. | ||||||||||||
664 | return new (Context) | ||||||||||||
665 | PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions); | ||||||||||||
666 | } | ||||||||||||
667 | |||||||||||||
668 | bool Sema::CheckParameterPacksForExpansion( | ||||||||||||
669 | SourceLocation EllipsisLoc, SourceRange PatternRange, | ||||||||||||
670 | ArrayRef<UnexpandedParameterPack> Unexpanded, | ||||||||||||
671 | const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, | ||||||||||||
672 | bool &RetainExpansion, Optional<unsigned> &NumExpansions) { | ||||||||||||
673 | ShouldExpand = true; | ||||||||||||
674 | RetainExpansion = false; | ||||||||||||
675 | std::pair<IdentifierInfo *, SourceLocation> FirstPack; | ||||||||||||
676 | bool HaveFirstPack = false; | ||||||||||||
677 | Optional<unsigned> NumPartialExpansions; | ||||||||||||
678 | SourceLocation PartiallySubstitutedPackLoc; | ||||||||||||
679 | |||||||||||||
680 | for (UnexpandedParameterPack ParmPack : Unexpanded) { | ||||||||||||
| |||||||||||||
681 | // Compute the depth and index for this parameter pack. | ||||||||||||
682 | unsigned Depth = 0, Index = 0; | ||||||||||||
683 | IdentifierInfo *Name; | ||||||||||||
684 | bool IsVarDeclPack = false; | ||||||||||||
685 | |||||||||||||
686 | if (const TemplateTypeParmType *TTP
| ||||||||||||
687 | ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||||||
688 | Depth = TTP->getDepth(); | ||||||||||||
689 | Index = TTP->getIndex(); | ||||||||||||
690 | Name = TTP->getIdentifier(); | ||||||||||||
691 | } else { | ||||||||||||
692 | NamedDecl *ND = ParmPack.first.get<NamedDecl *>(); | ||||||||||||
693 | if (isa<VarDecl>(ND)) | ||||||||||||
694 | IsVarDeclPack = true; | ||||||||||||
695 | else | ||||||||||||
696 | std::tie(Depth, Index) = getDepthAndIndex(ND); | ||||||||||||
697 | |||||||||||||
698 | Name = ND->getIdentifier(); | ||||||||||||
699 | } | ||||||||||||
700 | |||||||||||||
701 | // Determine the size of this argument pack. | ||||||||||||
702 | unsigned NewPackSize; | ||||||||||||
703 | if (IsVarDeclPack
| ||||||||||||
704 | // Figure out whether we're instantiating to an argument pack or not. | ||||||||||||
705 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | ||||||||||||
706 | |||||||||||||
707 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation = | ||||||||||||
708 | CurrentInstantiationScope->findInstantiationOf( | ||||||||||||
| |||||||||||||
709 | ParmPack.first.get<NamedDecl *>()); | ||||||||||||
710 | if (Instantiation->is<DeclArgumentPack *>()) { | ||||||||||||
711 | // We could expand this function parameter pack. | ||||||||||||
712 | NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); | ||||||||||||
713 | } else { | ||||||||||||
714 | // We can't expand this function parameter pack, so we can't expand | ||||||||||||
715 | // the pack expansion. | ||||||||||||
716 | ShouldExpand = false; | ||||||||||||
717 | continue; | ||||||||||||
718 | } | ||||||||||||
719 | } else { | ||||||||||||
720 | // If we don't have a template argument at this depth/index, then we | ||||||||||||
721 | // cannot expand the pack expansion. Make a note of this, but we still | ||||||||||||
722 | // want to check any parameter packs we *do* have arguments for. | ||||||||||||
723 | if (Depth >= TemplateArgs.getNumLevels() || | ||||||||||||
724 | !TemplateArgs.hasTemplateArgument(Depth, Index)) { | ||||||||||||
725 | ShouldExpand = false; | ||||||||||||
726 | continue; | ||||||||||||
727 | } | ||||||||||||
728 | |||||||||||||
729 | // Determine the size of the argument pack. | ||||||||||||
730 | NewPackSize = TemplateArgs(Depth, Index).pack_size(); | ||||||||||||
731 | } | ||||||||||||
732 | |||||||||||||
733 | // C++0x [temp.arg.explicit]p9: | ||||||||||||
734 | // Template argument deduction can extend the sequence of template | ||||||||||||
735 | // arguments corresponding to a template parameter pack, even when the | ||||||||||||
736 | // sequence contains explicitly specified template arguments. | ||||||||||||
737 | if (!IsVarDeclPack
| ||||||||||||
738 | if (NamedDecl *PartialPack | ||||||||||||
739 | = CurrentInstantiationScope->getPartiallySubstitutedPack()){ | ||||||||||||
740 | unsigned PartialDepth, PartialIndex; | ||||||||||||
741 | std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); | ||||||||||||
742 | if (PartialDepth == Depth && PartialIndex == Index) { | ||||||||||||
743 | RetainExpansion = true; | ||||||||||||
744 | // We don't actually know the new pack size yet. | ||||||||||||
745 | NumPartialExpansions = NewPackSize; | ||||||||||||
746 | PartiallySubstitutedPackLoc = ParmPack.second; | ||||||||||||
747 | continue; | ||||||||||||
748 | } | ||||||||||||
749 | } | ||||||||||||
750 | } | ||||||||||||
751 | |||||||||||||
752 | if (!NumExpansions) { | ||||||||||||
753 | // The is the first pack we've seen for which we have an argument. | ||||||||||||
754 | // Record it. | ||||||||||||
755 | NumExpansions = NewPackSize; | ||||||||||||
756 | FirstPack.first = Name; | ||||||||||||
757 | FirstPack.second = ParmPack.second; | ||||||||||||
758 | HaveFirstPack = true; | ||||||||||||
759 | continue; | ||||||||||||
760 | } | ||||||||||||
761 | |||||||||||||
762 | if (NewPackSize != *NumExpansions) { | ||||||||||||
763 | // C++0x [temp.variadic]p5: | ||||||||||||
764 | // All of the parameter packs expanded by a pack expansion shall have | ||||||||||||
765 | // the same number of arguments specified. | ||||||||||||
766 | if (HaveFirstPack) | ||||||||||||
767 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) | ||||||||||||
768 | << FirstPack.first << Name << *NumExpansions << NewPackSize | ||||||||||||
769 | << SourceRange(FirstPack.second) << SourceRange(ParmPack.second); | ||||||||||||
770 | else | ||||||||||||
771 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) | ||||||||||||
772 | << Name << *NumExpansions << NewPackSize | ||||||||||||
773 | << SourceRange(ParmPack.second); | ||||||||||||
774 | return true; | ||||||||||||
775 | } | ||||||||||||
776 | } | ||||||||||||
777 | |||||||||||||
778 | // If we're performing a partial expansion but we also have a full expansion, | ||||||||||||
779 | // expand to the number of common arguments. For example, given: | ||||||||||||
780 | // | ||||||||||||
781 | // template<typename ...T> struct A { | ||||||||||||
782 | // template<typename ...U> void f(pair<T, U>...); | ||||||||||||
783 | // }; | ||||||||||||
784 | // | ||||||||||||
785 | // ... a call to 'A<int, int>().f<int>' should expand the pack once and | ||||||||||||
786 | // retain an expansion. | ||||||||||||
787 | if (NumPartialExpansions) { | ||||||||||||
788 | if (NumExpansions && *NumExpansions < *NumPartialExpansions) { | ||||||||||||
789 | NamedDecl *PartialPack = | ||||||||||||
790 | CurrentInstantiationScope->getPartiallySubstitutedPack(); | ||||||||||||
791 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) | ||||||||||||
792 | << PartialPack << *NumPartialExpansions << *NumExpansions | ||||||||||||
793 | << SourceRange(PartiallySubstitutedPackLoc); | ||||||||||||
794 | return true; | ||||||||||||
795 | } | ||||||||||||
796 | |||||||||||||
797 | NumExpansions = NumPartialExpansions; | ||||||||||||
798 | } | ||||||||||||
799 | |||||||||||||
800 | return false; | ||||||||||||
801 | } | ||||||||||||
802 | |||||||||||||
803 | Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, | ||||||||||||
804 | const MultiLevelTemplateArgumentList &TemplateArgs) { | ||||||||||||
805 | QualType Pattern = cast<PackExpansionType>(T)->getPattern(); | ||||||||||||
806 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; | ||||||||||||
807 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); | ||||||||||||
808 | |||||||||||||
809 | Optional<unsigned> Result; | ||||||||||||
810 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { | ||||||||||||
811 | // Compute the depth and index for this parameter pack. | ||||||||||||
812 | unsigned Depth; | ||||||||||||
813 | unsigned Index; | ||||||||||||
814 | |||||||||||||
815 | if (const TemplateTypeParmType *TTP | ||||||||||||
816 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { | ||||||||||||
817 | Depth = TTP->getDepth(); | ||||||||||||
818 | Index = TTP->getIndex(); | ||||||||||||
819 | } else { | ||||||||||||
820 | NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); | ||||||||||||
821 | if (isa<VarDecl>(ND)) { | ||||||||||||
822 | // Function parameter pack or init-capture pack. | ||||||||||||
823 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | ||||||||||||
824 | |||||||||||||
825 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation | ||||||||||||
826 | = CurrentInstantiationScope->findInstantiationOf( | ||||||||||||
827 | Unexpanded[I].first.get<NamedDecl *>()); | ||||||||||||
828 | if (Instantiation->is<Decl*>()) | ||||||||||||
829 | // The pattern refers to an unexpanded pack. We're not ready to expand | ||||||||||||
830 | // this pack yet. | ||||||||||||
831 | return None; | ||||||||||||
832 | |||||||||||||
833 | unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); | ||||||||||||
834 | assert((!Result || *Result == Size) && "inconsistent pack sizes")(static_cast <bool> ((!Result || *Result == Size) && "inconsistent pack sizes") ? void (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 834, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
835 | Result = Size; | ||||||||||||
836 | continue; | ||||||||||||
837 | } | ||||||||||||
838 | |||||||||||||
839 | std::tie(Depth, Index) = getDepthAndIndex(ND); | ||||||||||||
840 | } | ||||||||||||
841 | if (Depth >= TemplateArgs.getNumLevels() || | ||||||||||||
842 | !TemplateArgs.hasTemplateArgument(Depth, Index)) | ||||||||||||
843 | // The pattern refers to an unknown template argument. We're not ready to | ||||||||||||
844 | // expand this pack yet. | ||||||||||||
845 | return None; | ||||||||||||
846 | |||||||||||||
847 | // Determine the size of the argument pack. | ||||||||||||
848 | unsigned Size = TemplateArgs(Depth, Index).pack_size(); | ||||||||||||
849 | assert((!Result || *Result == Size) && "inconsistent pack sizes")(static_cast <bool> ((!Result || *Result == Size) && "inconsistent pack sizes") ? void (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 849, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
850 | Result = Size; | ||||||||||||
851 | } | ||||||||||||
852 | |||||||||||||
853 | return Result; | ||||||||||||
854 | } | ||||||||||||
855 | |||||||||||||
856 | bool Sema::containsUnexpandedParameterPacks(Declarator &D) { | ||||||||||||
857 | const DeclSpec &DS = D.getDeclSpec(); | ||||||||||||
858 | switch (DS.getTypeSpecType()) { | ||||||||||||
859 | case TST_typename: | ||||||||||||
860 | case TST_typeofType: | ||||||||||||
861 | #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: | ||||||||||||
862 | #include "clang/Basic/TransformTypeTraits.def" | ||||||||||||
863 | case TST_atomic: { | ||||||||||||
864 | QualType T = DS.getRepAsType().get(); | ||||||||||||
865 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | ||||||||||||
866 | return true; | ||||||||||||
867 | break; | ||||||||||||
868 | } | ||||||||||||
869 | |||||||||||||
870 | case TST_typeofExpr: | ||||||||||||
871 | case TST_decltype: | ||||||||||||
872 | case TST_bitint: | ||||||||||||
873 | if (DS.getRepAsExpr() && | ||||||||||||
874 | DS.getRepAsExpr()->containsUnexpandedParameterPack()) | ||||||||||||
875 | return true; | ||||||||||||
876 | break; | ||||||||||||
877 | |||||||||||||
878 | case TST_unspecified: | ||||||||||||
879 | case TST_void: | ||||||||||||
880 | case TST_char: | ||||||||||||
881 | case TST_wchar: | ||||||||||||
882 | case TST_char8: | ||||||||||||
883 | case TST_char16: | ||||||||||||
884 | case TST_char32: | ||||||||||||
885 | case TST_int: | ||||||||||||
886 | case TST_int128: | ||||||||||||
887 | case TST_half: | ||||||||||||
888 | case TST_float: | ||||||||||||
889 | case TST_double: | ||||||||||||
890 | case TST_Accum: | ||||||||||||
891 | case TST_Fract: | ||||||||||||
892 | case TST_Float16: | ||||||||||||
893 | case TST_float128: | ||||||||||||
894 | case TST_ibm128: | ||||||||||||
895 | case TST_bool: | ||||||||||||
896 | case TST_decimal32: | ||||||||||||
897 | case TST_decimal64: | ||||||||||||
898 | case TST_decimal128: | ||||||||||||
899 | case TST_enum: | ||||||||||||
900 | case TST_union: | ||||||||||||
901 | case TST_struct: | ||||||||||||
902 | case TST_interface: | ||||||||||||
903 | case TST_class: | ||||||||||||
904 | case TST_auto: | ||||||||||||
905 | case TST_auto_type: | ||||||||||||
906 | case TST_decltype_auto: | ||||||||||||
907 | case TST_BFloat16: | ||||||||||||
908 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: | ||||||||||||
909 | #include "clang/Basic/OpenCLImageTypes.def" | ||||||||||||
910 | case TST_unknown_anytype: | ||||||||||||
911 | case TST_error: | ||||||||||||
912 | break; | ||||||||||||
913 | } | ||||||||||||
914 | |||||||||||||
915 | for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { | ||||||||||||
916 | const DeclaratorChunk &Chunk = D.getTypeObject(I); | ||||||||||||
917 | switch (Chunk.Kind) { | ||||||||||||
918 | case DeclaratorChunk::Pointer: | ||||||||||||
919 | case DeclaratorChunk::Reference: | ||||||||||||
920 | case DeclaratorChunk::Paren: | ||||||||||||
921 | case DeclaratorChunk::Pipe: | ||||||||||||
922 | case DeclaratorChunk::BlockPointer: | ||||||||||||
923 | // These declarator chunks cannot contain any parameter packs. | ||||||||||||
924 | break; | ||||||||||||
925 | |||||||||||||
926 | case DeclaratorChunk::Array: | ||||||||||||
927 | if (Chunk.Arr.NumElts && | ||||||||||||
928 | Chunk.Arr.NumElts->containsUnexpandedParameterPack()) | ||||||||||||
929 | return true; | ||||||||||||
930 | break; | ||||||||||||
931 | case DeclaratorChunk::Function: | ||||||||||||
932 | for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { | ||||||||||||
933 | ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); | ||||||||||||
934 | QualType ParamTy = Param->getType(); | ||||||||||||
935 | assert(!ParamTy.isNull() && "Couldn't parse type?")(static_cast <bool> (!ParamTy.isNull() && "Couldn't parse type?" ) ? void (0) : __assert_fail ("!ParamTy.isNull() && \"Couldn't parse type?\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 935, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
936 | if (ParamTy->containsUnexpandedParameterPack()) return true; | ||||||||||||
937 | } | ||||||||||||
938 | |||||||||||||
939 | if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { | ||||||||||||
940 | for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) { | ||||||||||||
941 | if (Chunk.Fun.Exceptions[i] | ||||||||||||
942 | .Ty.get() | ||||||||||||
943 | ->containsUnexpandedParameterPack()) | ||||||||||||
944 | return true; | ||||||||||||
945 | } | ||||||||||||
946 | } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) && | ||||||||||||
947 | Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) | ||||||||||||
948 | return true; | ||||||||||||
949 | |||||||||||||
950 | if (Chunk.Fun.hasTrailingReturnType()) { | ||||||||||||
951 | QualType T = Chunk.Fun.getTrailingReturnType().get(); | ||||||||||||
952 | if (!T.isNull() && T->containsUnexpandedParameterPack()) | ||||||||||||
953 | return true; | ||||||||||||
954 | } | ||||||||||||
955 | break; | ||||||||||||
956 | |||||||||||||
957 | case DeclaratorChunk::MemberPointer: | ||||||||||||
958 | if (Chunk.Mem.Scope().getScopeRep() && | ||||||||||||
959 | Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) | ||||||||||||
960 | return true; | ||||||||||||
961 | break; | ||||||||||||
962 | } | ||||||||||||
963 | } | ||||||||||||
964 | |||||||||||||
965 | if (Expr *TRC = D.getTrailingRequiresClause()) | ||||||||||||
966 | if (TRC->containsUnexpandedParameterPack()) | ||||||||||||
967 | return true; | ||||||||||||
968 | |||||||||||||
969 | return false; | ||||||||||||
970 | } | ||||||||||||
971 | |||||||||||||
972 | namespace { | ||||||||||||
973 | |||||||||||||
974 | // Callback to only accept typo corrections that refer to parameter packs. | ||||||||||||
975 | class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { | ||||||||||||
976 | public: | ||||||||||||
977 | bool ValidateCandidate(const TypoCorrection &candidate) override { | ||||||||||||
978 | NamedDecl *ND = candidate.getCorrectionDecl(); | ||||||||||||
979 | return ND && ND->isParameterPack(); | ||||||||||||
980 | } | ||||||||||||
981 | |||||||||||||
982 | std::unique_ptr<CorrectionCandidateCallback> clone() override { | ||||||||||||
983 | return std::make_unique<ParameterPackValidatorCCC>(*this); | ||||||||||||
984 | } | ||||||||||||
985 | }; | ||||||||||||
986 | |||||||||||||
987 | } | ||||||||||||
988 | |||||||||||||
989 | /// Called when an expression computing the size of a parameter pack | ||||||||||||
990 | /// is parsed. | ||||||||||||
991 | /// | ||||||||||||
992 | /// \code | ||||||||||||
993 | /// template<typename ...Types> struct count { | ||||||||||||
994 | /// static const unsigned value = sizeof...(Types); | ||||||||||||
995 | /// }; | ||||||||||||
996 | /// \endcode | ||||||||||||
997 | /// | ||||||||||||
998 | // | ||||||||||||
999 | /// \param OpLoc The location of the "sizeof" keyword. | ||||||||||||
1000 | /// \param Name The name of the parameter pack whose size will be determined. | ||||||||||||
1001 | /// \param NameLoc The source location of the name of the parameter pack. | ||||||||||||
1002 | /// \param RParenLoc The location of the closing parentheses. | ||||||||||||
1003 | ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, | ||||||||||||
1004 | SourceLocation OpLoc, | ||||||||||||
1005 | IdentifierInfo &Name, | ||||||||||||
1006 | SourceLocation NameLoc, | ||||||||||||
1007 | SourceLocation RParenLoc) { | ||||||||||||
1008 | // C++0x [expr.sizeof]p5: | ||||||||||||
1009 | // The identifier in a sizeof... expression shall name a parameter pack. | ||||||||||||
1010 | LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); | ||||||||||||
1011 | LookupName(R, S); | ||||||||||||
1012 | |||||||||||||
1013 | NamedDecl *ParameterPack = nullptr; | ||||||||||||
1014 | switch (R.getResultKind()) { | ||||||||||||
1015 | case LookupResult::Found: | ||||||||||||
1016 | ParameterPack = R.getFoundDecl(); | ||||||||||||
1017 | break; | ||||||||||||
1018 | |||||||||||||
1019 | case LookupResult::NotFound: | ||||||||||||
1020 | case LookupResult::NotFoundInCurrentInstantiation: { | ||||||||||||
1021 | ParameterPackValidatorCCC CCC{}; | ||||||||||||
1022 | if (TypoCorrection Corrected = | ||||||||||||
1023 | CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, | ||||||||||||
1024 | CCC, CTK_ErrorRecovery)) { | ||||||||||||
1025 | diagnoseTypo(Corrected, | ||||||||||||
1026 | PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, | ||||||||||||
1027 | PDiag(diag::note_parameter_pack_here)); | ||||||||||||
1028 | ParameterPack = Corrected.getCorrectionDecl(); | ||||||||||||
1029 | } | ||||||||||||
1030 | break; | ||||||||||||
1031 | } | ||||||||||||
1032 | case LookupResult::FoundOverloaded: | ||||||||||||
1033 | case LookupResult::FoundUnresolvedValue: | ||||||||||||
1034 | break; | ||||||||||||
1035 | |||||||||||||
1036 | case LookupResult::Ambiguous: | ||||||||||||
1037 | DiagnoseAmbiguousLookup(R); | ||||||||||||
1038 | return ExprError(); | ||||||||||||
1039 | } | ||||||||||||
1040 | |||||||||||||
1041 | if (!ParameterPack || !ParameterPack->isParameterPack()) { | ||||||||||||
1042 | Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) | ||||||||||||
1043 | << &Name; | ||||||||||||
1044 | return ExprError(); | ||||||||||||
1045 | } | ||||||||||||
1046 | |||||||||||||
1047 | MarkAnyDeclReferenced(OpLoc, ParameterPack, true); | ||||||||||||
1048 | |||||||||||||
1049 | return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc, | ||||||||||||
1050 | RParenLoc); | ||||||||||||
1051 | } | ||||||||||||
1052 | |||||||||||||
1053 | TemplateArgumentLoc | ||||||||||||
1054 | Sema::getTemplateArgumentPackExpansionPattern( | ||||||||||||
1055 | TemplateArgumentLoc OrigLoc, | ||||||||||||
1056 | SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { | ||||||||||||
1057 | const TemplateArgument &Argument = OrigLoc.getArgument(); | ||||||||||||
1058 | assert(Argument.isPackExpansion())(static_cast <bool> (Argument.isPackExpansion()) ? void (0) : __assert_fail ("Argument.isPackExpansion()", "clang/lib/Sema/SemaTemplateVariadic.cpp" , 1058, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1059 | switch (Argument.getKind()) { | ||||||||||||
1060 | case TemplateArgument::Type: { | ||||||||||||
1061 | // FIXME: We shouldn't ever have to worry about missing | ||||||||||||
1062 | // type-source info! | ||||||||||||
1063 | TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); | ||||||||||||
1064 | if (!ExpansionTSInfo) | ||||||||||||
1065 | ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), | ||||||||||||
1066 | Ellipsis); | ||||||||||||
1067 | PackExpansionTypeLoc Expansion = | ||||||||||||
1068 | ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); | ||||||||||||
1069 | Ellipsis = Expansion.getEllipsisLoc(); | ||||||||||||
1070 | |||||||||||||
1071 | TypeLoc Pattern = Expansion.getPatternLoc(); | ||||||||||||
1072 | NumExpansions = Expansion.getTypePtr()->getNumExpansions(); | ||||||||||||
1073 | |||||||||||||
1074 | // We need to copy the TypeLoc because TemplateArgumentLocs store a | ||||||||||||
1075 | // TypeSourceInfo. | ||||||||||||
1076 | // FIXME: Find some way to avoid the copy? | ||||||||||||
1077 | TypeLocBuilder TLB; | ||||||||||||
1078 | TLB.pushFullCopy(Pattern); | ||||||||||||
1079 | TypeSourceInfo *PatternTSInfo = | ||||||||||||
1080 | TLB.getTypeSourceInfo(Context, Pattern.getType()); | ||||||||||||
1081 | return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), | ||||||||||||
1082 | PatternTSInfo); | ||||||||||||
1083 | } | ||||||||||||
1084 | |||||||||||||
1085 | case TemplateArgument::Expression: { | ||||||||||||
1086 | PackExpansionExpr *Expansion | ||||||||||||
1087 | = cast<PackExpansionExpr>(Argument.getAsExpr()); | ||||||||||||
1088 | Expr *Pattern = Expansion->getPattern(); | ||||||||||||
1089 | Ellipsis = Expansion->getEllipsisLoc(); | ||||||||||||
1090 | NumExpansions = Expansion->getNumExpansions(); | ||||||||||||
1091 | return TemplateArgumentLoc(Pattern, Pattern); | ||||||||||||
1092 | } | ||||||||||||
1093 | |||||||||||||
1094 | case TemplateArgument::TemplateExpansion: | ||||||||||||
1095 | Ellipsis = OrigLoc.getTemplateEllipsisLoc(); | ||||||||||||
1096 | NumExpansions = Argument.getNumTemplateExpansions(); | ||||||||||||
1097 | return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), | ||||||||||||
1098 | OrigLoc.getTemplateQualifierLoc(), | ||||||||||||
1099 | OrigLoc.getTemplateNameLoc()); | ||||||||||||
1100 | |||||||||||||
1101 | case TemplateArgument::Declaration: | ||||||||||||
1102 | case TemplateArgument::NullPtr: | ||||||||||||
1103 | case TemplateArgument::Template: | ||||||||||||
1104 | case TemplateArgument::Integral: | ||||||||||||
1105 | case TemplateArgument::Pack: | ||||||||||||
1106 | case TemplateArgument::Null: | ||||||||||||
1107 | return TemplateArgumentLoc(); | ||||||||||||
1108 | } | ||||||||||||
1109 | |||||||||||||
1110 | llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1110); | ||||||||||||
1111 | } | ||||||||||||
1112 | |||||||||||||
1113 | Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { | ||||||||||||
1114 | assert(Arg.containsUnexpandedParameterPack())(static_cast <bool> (Arg.containsUnexpandedParameterPack ()) ? void (0) : __assert_fail ("Arg.containsUnexpandedParameterPack()" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1114, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1115 | |||||||||||||
1116 | // If this is a substituted pack, grab that pack. If not, we don't know | ||||||||||||
1117 | // the size yet. | ||||||||||||
1118 | // FIXME: We could find a size in more cases by looking for a substituted | ||||||||||||
1119 | // pack anywhere within this argument, but that's not necessary in the common | ||||||||||||
1120 | // case for 'sizeof...(A)' handling. | ||||||||||||
1121 | TemplateArgument Pack; | ||||||||||||
1122 | switch (Arg.getKind()) { | ||||||||||||
1123 | case TemplateArgument::Type: | ||||||||||||
1124 | if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) | ||||||||||||
1125 | Pack = Subst->getArgumentPack(); | ||||||||||||
1126 | else | ||||||||||||
1127 | return None; | ||||||||||||
1128 | break; | ||||||||||||
1129 | |||||||||||||
1130 | case TemplateArgument::Expression: | ||||||||||||
1131 | if (auto *Subst = | ||||||||||||
1132 | dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) | ||||||||||||
1133 | Pack = Subst->getArgumentPack(); | ||||||||||||
1134 | else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) { | ||||||||||||
1135 | for (VarDecl *PD : *Subst) | ||||||||||||
1136 | if (PD->isParameterPack()) | ||||||||||||
1137 | return None; | ||||||||||||
1138 | return Subst->getNumExpansions(); | ||||||||||||
1139 | } else | ||||||||||||
1140 | return None; | ||||||||||||
1141 | break; | ||||||||||||
1142 | |||||||||||||
1143 | case TemplateArgument::Template: | ||||||||||||
1144 | if (SubstTemplateTemplateParmPackStorage *Subst = | ||||||||||||
1145 | Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) | ||||||||||||
1146 | Pack = Subst->getArgumentPack(); | ||||||||||||
1147 | else | ||||||||||||
1148 | return None; | ||||||||||||
1149 | break; | ||||||||||||
1150 | |||||||||||||
1151 | case TemplateArgument::Declaration: | ||||||||||||
1152 | case TemplateArgument::NullPtr: | ||||||||||||
1153 | case TemplateArgument::TemplateExpansion: | ||||||||||||
1154 | case TemplateArgument::Integral: | ||||||||||||
1155 | case TemplateArgument::Pack: | ||||||||||||
1156 | case TemplateArgument::Null: | ||||||||||||
1157 | return None; | ||||||||||||
1158 | } | ||||||||||||
1159 | |||||||||||||
1160 | // Check that no argument in the pack is itself a pack expansion. | ||||||||||||
1161 | for (TemplateArgument Elem : Pack.pack_elements()) { | ||||||||||||
1162 | // There's no point recursing in this case; we would have already | ||||||||||||
1163 | // expanded this pack expansion into the enclosing pack if we could. | ||||||||||||
1164 | if (Elem.isPackExpansion()) | ||||||||||||
1165 | return None; | ||||||||||||
1166 | } | ||||||||||||
1167 | return Pack.pack_size(); | ||||||||||||
1168 | } | ||||||||||||
1169 | |||||||||||||
1170 | static void CheckFoldOperand(Sema &S, Expr *E) { | ||||||||||||
1171 | if (!E) | ||||||||||||
1172 | return; | ||||||||||||
1173 | |||||||||||||
1174 | E = E->IgnoreImpCasts(); | ||||||||||||
1175 | auto *OCE = dyn_cast<CXXOperatorCallExpr>(E); | ||||||||||||
1176 | if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) || | ||||||||||||
1177 | isa<AbstractConditionalOperator>(E)) { | ||||||||||||
1178 | S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand) | ||||||||||||
1179 | << E->getSourceRange() | ||||||||||||
1180 | << FixItHint::CreateInsertion(E->getBeginLoc(), "(") | ||||||||||||
1181 | << FixItHint::CreateInsertion(E->getEndLoc(), ")"); | ||||||||||||
1182 | } | ||||||||||||
1183 | } | ||||||||||||
1184 | |||||||||||||
1185 | ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, | ||||||||||||
1186 | tok::TokenKind Operator, | ||||||||||||
1187 | SourceLocation EllipsisLoc, Expr *RHS, | ||||||||||||
1188 | SourceLocation RParenLoc) { | ||||||||||||
1189 | // LHS and RHS must be cast-expressions. We allow an arbitrary expression | ||||||||||||
1190 | // in the parser and reduce down to just cast-expressions here. | ||||||||||||
1191 | CheckFoldOperand(*this, LHS); | ||||||||||||
1192 | CheckFoldOperand(*this, RHS); | ||||||||||||
1193 | |||||||||||||
1194 | auto DiscardOperands = [&] { | ||||||||||||
1195 | CorrectDelayedTyposInExpr(LHS); | ||||||||||||
1196 | CorrectDelayedTyposInExpr(RHS); | ||||||||||||
1197 | }; | ||||||||||||
1198 | |||||||||||||
1199 | // [expr.prim.fold]p3: | ||||||||||||
1200 | // In a binary fold, op1 and op2 shall be the same fold-operator, and | ||||||||||||
1201 | // either e1 shall contain an unexpanded parameter pack or e2 shall contain | ||||||||||||
1202 | // an unexpanded parameter pack, but not both. | ||||||||||||
1203 | if (LHS && RHS && | ||||||||||||
1204 | LHS->containsUnexpandedParameterPack() == | ||||||||||||
1205 | RHS->containsUnexpandedParameterPack()) { | ||||||||||||
1206 | DiscardOperands(); | ||||||||||||
1207 | return Diag(EllipsisLoc, | ||||||||||||
1208 | LHS->containsUnexpandedParameterPack() | ||||||||||||
1209 | ? diag::err_fold_expression_packs_both_sides | ||||||||||||
1210 | : diag::err_pack_expansion_without_parameter_packs) | ||||||||||||
1211 | << LHS->getSourceRange() << RHS->getSourceRange(); | ||||||||||||
1212 | } | ||||||||||||
1213 | |||||||||||||
1214 | // [expr.prim.fold]p2: | ||||||||||||
1215 | // In a unary fold, the cast-expression shall contain an unexpanded | ||||||||||||
1216 | // parameter pack. | ||||||||||||
1217 | if (!LHS || !RHS) { | ||||||||||||
1218 | Expr *Pack = LHS ? LHS : RHS; | ||||||||||||
1219 | assert(Pack && "fold expression with neither LHS nor RHS")(static_cast <bool> (Pack && "fold expression with neither LHS nor RHS" ) ? void (0) : __assert_fail ("Pack && \"fold expression with neither LHS nor RHS\"" , "clang/lib/Sema/SemaTemplateVariadic.cpp", 1219, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
1220 | DiscardOperands(); | ||||||||||||
1221 | if (!Pack->containsUnexpandedParameterPack()) | ||||||||||||
1222 | return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) | ||||||||||||
1223 | << Pack->getSourceRange(); | ||||||||||||
1224 | } | ||||||||||||
1225 | |||||||||||||
1226 | BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator); | ||||||||||||
1227 | |||||||||||||
1228 | // Perform first-phase name lookup now. | ||||||||||||
1229 | UnresolvedLookupExpr *ULE = nullptr; | ||||||||||||
1230 | { | ||||||||||||
1231 | UnresolvedSet<16> Functions; | ||||||||||||
1232 | LookupBinOp(S, EllipsisLoc, Opc, Functions); | ||||||||||||
1233 | if (!Functions.empty()) { | ||||||||||||
1234 | DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName( | ||||||||||||
1235 | BinaryOperator::getOverloadedOperator(Opc)); | ||||||||||||
1236 | ExprResult Callee = CreateUnresolvedLookupExpr( | ||||||||||||
1237 | /*NamingClass*/ nullptr, NestedNameSpecifierLoc(), | ||||||||||||
1238 | DeclarationNameInfo(OpName, EllipsisLoc), Functions); | ||||||||||||
1239 | if (Callee.isInvalid()) | ||||||||||||
1240 | return ExprError(); | ||||||||||||
1241 | ULE = cast<UnresolvedLookupExpr>(Callee.get()); | ||||||||||||
1242 | } | ||||||||||||
1243 | } | ||||||||||||
1244 | |||||||||||||
1245 | return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc, | ||||||||||||
1246 | None); | ||||||||||||
1247 | } | ||||||||||||
1248 | |||||||||||||
1249 | ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, | ||||||||||||
1250 | SourceLocation LParenLoc, Expr *LHS, | ||||||||||||
1251 | BinaryOperatorKind Operator, | ||||||||||||
1252 | SourceLocation EllipsisLoc, Expr *RHS, | ||||||||||||
1253 | SourceLocation RParenLoc, | ||||||||||||
1254 | Optional<unsigned> NumExpansions) { | ||||||||||||
1255 | return new (Context) | ||||||||||||
1256 | CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator, | ||||||||||||
1257 | EllipsisLoc, RHS, RParenLoc, NumExpansions); | ||||||||||||
1258 | } | ||||||||||||
1259 | |||||||||||||
1260 | ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, | ||||||||||||
1261 | BinaryOperatorKind Operator) { | ||||||||||||
1262 | // [temp.variadic]p9: | ||||||||||||
1263 | // If N is zero for a unary fold-expression, the value of the expression is | ||||||||||||
1264 | // && -> true | ||||||||||||
1265 | // || -> false | ||||||||||||
1266 | // , -> void() | ||||||||||||
1267 | // if the operator is not listed [above], the instantiation is ill-formed. | ||||||||||||
1268 | // | ||||||||||||
1269 | // Note that we need to use something like int() here, not merely 0, to | ||||||||||||
1270 | // prevent the result from being a null pointer constant. | ||||||||||||
1271 | QualType ScalarType; | ||||||||||||
1272 | switch (Operator) { | ||||||||||||
1273 | case BO_LOr: | ||||||||||||
1274 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false); | ||||||||||||
1275 | case BO_LAnd: | ||||||||||||
1276 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true); | ||||||||||||
1277 | case BO_Comma: | ||||||||||||
1278 | ScalarType = Context.VoidTy; | ||||||||||||
1279 | break; | ||||||||||||
1280 | |||||||||||||
1281 | default: | ||||||||||||
1282 | return Diag(EllipsisLoc, diag::err_fold_expression_empty) | ||||||||||||
1283 | << BinaryOperator::getOpcodeStr(Operator); | ||||||||||||
1284 | } | ||||||||||||
1285 | |||||||||||||
1286 | return new (Context) CXXScalarValueInitExpr( | ||||||||||||
1287 | ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc), | ||||||||||||
1288 | EllipsisLoc); | ||||||||||||
1289 | } |
1 | //===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===// |
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 | /// |
9 | /// \file |
10 | /// This file defines the PointerUnion class, which is a discriminated union of |
11 | /// pointer types. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_ADT_POINTERUNION_H |
16 | #define LLVM_ADT_POINTERUNION_H |
17 | |
18 | #include "llvm/ADT/DenseMapInfo.h" |
19 | #include "llvm/ADT/PointerIntPair.h" |
20 | #include "llvm/ADT/STLExtras.h" |
21 | #include "llvm/Support/Casting.h" |
22 | #include "llvm/Support/PointerLikeTypeTraits.h" |
23 | #include <algorithm> |
24 | #include <cassert> |
25 | #include <cstddef> |
26 | #include <cstdint> |
27 | |
28 | namespace llvm { |
29 | |
30 | namespace pointer_union_detail { |
31 | /// Determine the number of bits required to store integers with values < n. |
32 | /// This is ceil(log2(n)). |
33 | constexpr int bitsRequired(unsigned n) { |
34 | return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; |
35 | } |
36 | |
37 | template <typename... Ts> constexpr int lowBitsAvailable() { |
38 | return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}); |
39 | } |
40 | |
41 | /// Find the first type in a list of types. |
42 | template <typename T, typename...> struct GetFirstType { |
43 | using type = T; |
44 | }; |
45 | |
46 | /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion |
47 | /// for the template arguments. |
48 | template <typename ...PTs> class PointerUnionUIntTraits { |
49 | public: |
50 | static inline void *getAsVoidPointer(void *P) { return P; } |
51 | static inline void *getFromVoidPointer(void *P) { return P; } |
52 | static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>(); |
53 | }; |
54 | |
55 | template <typename Derived, typename ValTy, int I, typename ...Types> |
56 | class PointerUnionMembers; |
57 | |
58 | template <typename Derived, typename ValTy, int I> |
59 | class PointerUnionMembers<Derived, ValTy, I> { |
60 | protected: |
61 | ValTy Val; |
62 | PointerUnionMembers() = default; |
63 | PointerUnionMembers(ValTy Val) : Val(Val) {} |
64 | |
65 | friend struct PointerLikeTypeTraits<Derived>; |
66 | }; |
67 | |
68 | template <typename Derived, typename ValTy, int I, typename Type, |
69 | typename ...Types> |
70 | class PointerUnionMembers<Derived, ValTy, I, Type, Types...> |
71 | : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> { |
72 | using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>; |
73 | public: |
74 | using Base::Base; |
75 | PointerUnionMembers() = default; |
76 | PointerUnionMembers(Type V) |
77 | : Base(ValTy(const_cast<void *>( |
78 | PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
79 | I)) {} |
80 | |
81 | using Base::operator=; |
82 | Derived &operator=(Type V) { |
83 | this->Val = ValTy( |
84 | const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
85 | I); |
86 | return static_cast<Derived &>(*this); |
87 | }; |
88 | }; |
89 | } |
90 | |
91 | // This is a forward declaration of CastInfoPointerUnionImpl |
92 | // Refer to its definition below for further details |
93 | template <typename... PTs> struct CastInfoPointerUnionImpl; |
94 | /// A discriminated union of two or more pointer types, with the discriminator |
95 | /// in the low bit of the pointer. |
96 | /// |
97 | /// This implementation is extremely efficient in space due to leveraging the |
98 | /// low bits of the pointer, while exposing a natural and type-safe API. |
99 | /// |
100 | /// Common use patterns would be something like this: |
101 | /// PointerUnion<int*, float*> P; |
102 | /// P = (int*)0; |
103 | /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0" |
104 | /// X = P.get<int*>(); // ok. |
105 | /// Y = P.get<float*>(); // runtime assertion failure. |
106 | /// Z = P.get<double*>(); // compile time failure. |
107 | /// P = (float*)0; |
108 | /// Y = P.get<float*>(); // ok. |
109 | /// X = P.get<int*>(); // runtime assertion failure. |
110 | /// PointerUnion<int*, int*> Q; // compile time failure. |
111 | template <typename... PTs> |
112 | class PointerUnion |
113 | : public pointer_union_detail::PointerUnionMembers< |
114 | PointerUnion<PTs...>, |
115 | PointerIntPair< |
116 | void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, |
117 | pointer_union_detail::PointerUnionUIntTraits<PTs...>>, |
118 | 0, PTs...> { |
119 | static_assert(TypesAreDistinct<PTs...>::value, |
120 | "PointerUnion alternative types cannot be repeated"); |
121 | // The first type is special because we want to directly cast a pointer to a |
122 | // default-initialized union to a pointer to the first type. But we don't |
123 | // want PointerUnion to be a 'template <typename First, typename ...Rest>' |
124 | // because it's much more convenient to have a name for the whole pack. So |
125 | // split off the first type here. |
126 | using First = TypeAtIndex<0, PTs...>; |
127 | using Base = typename PointerUnion::PointerUnionMembers; |
128 | |
129 | /// This is needed to give the CastInfo implementation below access |
130 | /// to protected members. |
131 | /// Refer to its definition for further details. |
132 | friend struct CastInfoPointerUnionImpl<PTs...>; |
133 | |
134 | public: |
135 | PointerUnion() = default; |
136 | |
137 | PointerUnion(std::nullptr_t) : PointerUnion() {} |
138 | using Base::Base; |
139 | |
140 | /// Test if the pointer held in the union is null, regardless of |
141 | /// which type it is. |
142 | bool isNull() const { return !this->Val.getPointer(); } |
143 | |
144 | explicit operator bool() const { return !isNull(); } |
145 | |
146 | // FIXME: Replace the uses of is(), get() and dyn_cast() with |
147 | // isa<T>, cast<T> and the llvm::dyn_cast<T> |
148 | |
149 | /// Test if the Union currently holds the type matching T. |
150 | template <typename T> inline bool is() const { return isa<T>(*this); } |
151 | |
152 | /// Returns the value of the specified pointer type. |
153 | /// |
154 | /// If the specified pointer type is incorrect, assert. |
155 | template <typename T> inline T get() const { |
156 | assert(isa<T>(*this) && "Invalid accessor called")(static_cast <bool> (isa<T>(*this) && "Invalid accessor called" ) ? void (0) : __assert_fail ("isa<T>(*this) && \"Invalid accessor called\"" , "llvm/include/llvm/ADT/PointerUnion.h", 156, __extension__ __PRETTY_FUNCTION__ )); |
157 | return cast<T>(*this); |
158 | } |
159 | |
160 | /// Returns the current pointer if it is of the specified pointer type, |
161 | /// otherwise returns null. |
162 | template <typename T> inline T dyn_cast() const { |
163 | return llvm::dyn_cast<T>(*this); |
164 | } |
165 | |
166 | /// If the union is set to the first pointer type get an address pointing to |
167 | /// it. |
168 | First const *getAddrOfPtr1() const { |
169 | return const_cast<PointerUnion *>(this)->getAddrOfPtr1(); |
170 | } |
171 | |
172 | /// If the union is set to the first pointer type get an address pointing to |
173 | /// it. |
174 | First *getAddrOfPtr1() { |
175 | assert(is<First>() && "Val is not the first pointer")(static_cast <bool> (is<First>() && "Val is not the first pointer" ) ? void (0) : __assert_fail ("is<First>() && \"Val is not the first pointer\"" , "llvm/include/llvm/ADT/PointerUnion.h", 175, __extension__ __PRETTY_FUNCTION__ )); |
176 | assert((static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
177 | PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) ==(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
178 | this->Val.getPointer() &&(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )) |
179 | "Can't get the address because PointerLikeTypeTraits changes the ptr")(static_cast <bool> (PointerLikeTypeTraits<First> ::getAsVoidPointer(get<First>()) == this->Val.getPointer () && "Can't get the address because PointerLikeTypeTraits changes the ptr" ) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\"" , "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__ )); |
180 | return const_cast<First *>( |
181 | reinterpret_cast<const First *>(this->Val.getAddrOfPointer())); |
182 | } |
183 | |
184 | /// Assignment from nullptr which just clears the union. |
185 | const PointerUnion &operator=(std::nullptr_t) { |
186 | this->Val.initWithPointer(nullptr); |
187 | return *this; |
188 | } |
189 | |
190 | /// Assignment from elements of the union. |
191 | using Base::operator=; |
192 | |
193 | void *getOpaqueValue() const { return this->Val.getOpaqueValue(); } |
194 | static inline PointerUnion getFromOpaqueValue(void *VP) { |
195 | PointerUnion V; |
196 | V.Val = decltype(V.Val)::getFromOpaqueValue(VP); |
197 | return V; |
198 | } |
199 | }; |
200 | |
201 | template <typename ...PTs> |
202 | bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
203 | return lhs.getOpaqueValue() == rhs.getOpaqueValue(); |
204 | } |
205 | |
206 | template <typename ...PTs> |
207 | bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
208 | return lhs.getOpaqueValue() != rhs.getOpaqueValue(); |
209 | } |
210 | |
211 | template <typename ...PTs> |
212 | bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
213 | return lhs.getOpaqueValue() < rhs.getOpaqueValue(); |
214 | } |
215 | |
216 | /// We can't (at least, at this moment with C++14) declare CastInfo |
217 | /// as a friend of PointerUnion like this: |
218 | /// ``` |
219 | /// template<typename To> |
220 | /// friend struct CastInfo<To, PointerUnion<PTs...>>; |
221 | /// ``` |
222 | /// The compiler complains 'Partial specialization cannot be declared as a |
223 | /// friend'. |
224 | /// So we define this struct to be a bridge between CastInfo and |
225 | /// PointerUnion. |
226 | template <typename... PTs> struct CastInfoPointerUnionImpl { |
227 | using From = PointerUnion<PTs...>; |
228 | |
229 | template <typename To> static inline bool isPossible(From &F) { |
230 | return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value; |
231 | } |
232 | |
233 | template <typename To> static To doCast(From &F) { |
234 | assert(isPossible<To>(F) && "cast to an incompatible type !")(static_cast <bool> (isPossible<To>(F) && "cast to an incompatible type !") ? void (0) : __assert_fail ("isPossible<To>(F) && \"cast to an incompatible type !\"" , "llvm/include/llvm/ADT/PointerUnion.h", 234, __extension__ __PRETTY_FUNCTION__ )); |
235 | return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer()); |
236 | } |
237 | }; |
238 | |
239 | // Specialization of CastInfo for PointerUnion |
240 | template <typename To, typename... PTs> |
241 | struct CastInfo<To, PointerUnion<PTs...>> |
242 | : public DefaultDoCastIfPossible<To, PointerUnion<PTs...>, |
243 | CastInfo<To, PointerUnion<PTs...>>> { |
244 | using From = PointerUnion<PTs...>; |
245 | using Impl = CastInfoPointerUnionImpl<PTs...>; |
246 | |
247 | static inline bool isPossible(From &f) { |
248 | return Impl::template isPossible<To>(f); |
249 | } |
250 | |
251 | static To doCast(From &f) { return Impl::template doCast<To>(f); } |
252 | |
253 | static inline To castFailed() { return To(); } |
254 | }; |
255 | |
256 | template <typename To, typename... PTs> |
257 | struct CastInfo<To, const PointerUnion<PTs...>> |
258 | : public ConstStrippingForwardingCast<To, const PointerUnion<PTs...>, |
259 | CastInfo<To, PointerUnion<PTs...>>> { |
260 | }; |
261 | |
262 | // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has |
263 | // # low bits available = min(PT1bits,PT2bits)-1. |
264 | template <typename ...PTs> |
265 | struct PointerLikeTypeTraits<PointerUnion<PTs...>> { |
266 | static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) { |
267 | return P.getOpaqueValue(); |
268 | } |
269 | |
270 | static inline PointerUnion<PTs...> getFromVoidPointer(void *P) { |
271 | return PointerUnion<PTs...>::getFromOpaqueValue(P); |
272 | } |
273 | |
274 | // The number of bits available are the min of the pointer types minus the |
275 | // bits needed for the discriminator. |
276 | static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype( |
277 | PointerUnion<PTs...>::Val)>::NumLowBitsAvailable; |
278 | }; |
279 | |
280 | // Teach DenseMap how to use PointerUnions as keys. |
281 | template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { |
282 | using Union = PointerUnion<PTs...>; |
283 | using FirstInfo = |
284 | DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; |
285 | |
286 | static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } |
287 | |
288 | static inline Union getTombstoneKey() { |
289 | return Union(FirstInfo::getTombstoneKey()); |
290 | } |
291 | |
292 | static unsigned getHashValue(const Union &UnionVal) { |
293 | intptr_t key = (intptr_t)UnionVal.getOpaqueValue(); |
294 | return DenseMapInfo<intptr_t>::getHashValue(key); |
295 | } |
296 | |
297 | static bool isEqual(const Union &LHS, const Union &RHS) { |
298 | return LHS == RHS; |
299 | } |
300 | }; |
301 | |
302 | } // end namespace llvm |
303 | |
304 | #endif // LLVM_ADT_POINTERUNION_H |
1 | //===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- C++ -*-===// |
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 | // |
9 | // This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), |
10 | // cast_if_present<X>(), and dyn_cast_if_present<X>() templates. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_CASTING_H |
15 | #define LLVM_SUPPORT_CASTING_H |
16 | |
17 | #include "llvm/ADT/Optional.h" |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/type_traits.h" |
20 | #include <cassert> |
21 | #include <memory> |
22 | #include <type_traits> |
23 | |
24 | namespace llvm { |
25 | |
26 | //===----------------------------------------------------------------------===// |
27 | // simplify_type |
28 | //===----------------------------------------------------------------------===// |
29 | |
30 | /// Define a template that can be specialized by smart pointers to reflect the |
31 | /// fact that they are automatically dereferenced, and are not involved with the |
32 | /// template selection process... the default implementation is a noop. |
33 | // TODO: rename this and/or replace it with other cast traits. |
34 | template <typename From> struct simplify_type { |
35 | using SimpleType = From; // The real type this represents... |
36 | |
37 | // An accessor to get the real value... |
38 | static SimpleType &getSimplifiedValue(From &Val) { return Val; } |
39 | }; |
40 | |
41 | template <typename From> struct simplify_type<const From> { |
42 | using NonConstSimpleType = typename simplify_type<From>::SimpleType; |
43 | using SimpleType = typename add_const_past_pointer<NonConstSimpleType>::type; |
44 | using RetType = |
45 | typename add_lvalue_reference_if_not_pointer<SimpleType>::type; |
46 | |
47 | static RetType getSimplifiedValue(const From &Val) { |
48 | return simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val)); |
49 | } |
50 | }; |
51 | |
52 | // TODO: add this namespace once everyone is switched to using the new |
53 | // interface. |
54 | // namespace detail { |
55 | |
56 | //===----------------------------------------------------------------------===// |
57 | // isa_impl |
58 | //===----------------------------------------------------------------------===// |
59 | |
60 | // The core of the implementation of isa<X> is here; To and From should be |
61 | // the names of classes. This template can be specialized to customize the |
62 | // implementation of isa<> without rewriting it from scratch. |
63 | template <typename To, typename From, typename Enabler = void> struct isa_impl { |
64 | static inline bool doit(const From &Val) { return To::classof(&Val); } |
65 | }; |
66 | |
67 | // Always allow upcasts, and perform no dynamic check for them. |
68 | template <typename To, typename From> |
69 | struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> { |
70 | static inline bool doit(const From &) { return true; } |
71 | }; |
72 | |
73 | template <typename To, typename From> struct isa_impl_cl { |
74 | static inline bool doit(const From &Val) { |
75 | return isa_impl<To, From>::doit(Val); |
76 | } |
77 | }; |
78 | |
79 | template <typename To, typename From> struct isa_impl_cl<To, const From> { |
80 | static inline bool doit(const From &Val) { |
81 | return isa_impl<To, From>::doit(Val); |
82 | } |
83 | }; |
84 | |
85 | template <typename To, typename From> |
86 | struct isa_impl_cl<To, const std::unique_ptr<From>> { |
87 | static inline bool doit(const std::unique_ptr<From> &Val) { |
88 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 88, __extension__ __PRETTY_FUNCTION__ )); |
89 | return isa_impl_cl<To, From>::doit(*Val); |
90 | } |
91 | }; |
92 | |
93 | template <typename To, typename From> struct isa_impl_cl<To, From *> { |
94 | static inline bool doit(const From *Val) { |
95 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 95, __extension__ __PRETTY_FUNCTION__ )); |
96 | return isa_impl<To, From>::doit(*Val); |
97 | } |
98 | }; |
99 | |
100 | template <typename To, typename From> struct isa_impl_cl<To, From *const> { |
101 | static inline bool doit(const From *Val) { |
102 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 102, __extension__ __PRETTY_FUNCTION__ )); |
103 | return isa_impl<To, From>::doit(*Val); |
104 | } |
105 | }; |
106 | |
107 | template <typename To, typename From> struct isa_impl_cl<To, const From *> { |
108 | static inline bool doit(const From *Val) { |
109 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 109, __extension__ __PRETTY_FUNCTION__ )); |
110 | return isa_impl<To, From>::doit(*Val); |
111 | } |
112 | }; |
113 | |
114 | template <typename To, typename From> |
115 | struct isa_impl_cl<To, const From *const> { |
116 | static inline bool doit(const From *Val) { |
117 | assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer" ) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\"" , "llvm/include/llvm/Support/Casting.h", 117, __extension__ __PRETTY_FUNCTION__ )); |
118 | return isa_impl<To, From>::doit(*Val); |
119 | } |
120 | }; |
121 | |
122 | template <typename To, typename From, typename SimpleFrom> |
123 | struct isa_impl_wrap { |
124 | // When From != SimplifiedType, we can simplify the type some more by using |
125 | // the simplify_type template. |
126 | static bool doit(const From &Val) { |
127 | return isa_impl_wrap<To, SimpleFrom, |
128 | typename simplify_type<SimpleFrom>::SimpleType>:: |
129 | doit(simplify_type<const From>::getSimplifiedValue(Val)); |
130 | } |
131 | }; |
132 | |
133 | template <typename To, typename FromTy> |
134 | struct isa_impl_wrap<To, FromTy, FromTy> { |
135 | // When From == SimpleType, we are as simple as we are going to get. |
136 | static bool doit(const FromTy &Val) { |
137 | return isa_impl_cl<To, FromTy>::doit(Val); |
138 | } |
139 | }; |
140 | |
141 | //===----------------------------------------------------------------------===// |
142 | // cast_retty + cast_retty_impl |
143 | //===----------------------------------------------------------------------===// |
144 | |
145 | template <class To, class From> struct cast_retty; |
146 | |
147 | // Calculate what type the 'cast' function should return, based on a requested |
148 | // type of To and a source type of From. |
149 | template <class To, class From> struct cast_retty_impl { |
150 | using ret_type = To &; // Normal case, return Ty& |
151 | }; |
152 | template <class To, class From> struct cast_retty_impl<To, const From> { |
153 | using ret_type = const To &; // Normal case, return Ty& |
154 | }; |
155 | |
156 | template <class To, class From> struct cast_retty_impl<To, From *> { |
157 | using ret_type = To *; // Pointer arg case, return Ty* |
158 | }; |
159 | |
160 | template <class To, class From> struct cast_retty_impl<To, const From *> { |
161 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
162 | }; |
163 | |
164 | template <class To, class From> struct cast_retty_impl<To, const From *const> { |
165 | using ret_type = const To *; // Constant pointer arg case, return const Ty* |
166 | }; |
167 | |
168 | template <class To, class From> |
169 | struct cast_retty_impl<To, std::unique_ptr<From>> { |
170 | private: |
171 | using PointerType = typename cast_retty_impl<To, From *>::ret_type; |
172 | using ResultType = std::remove_pointer_t<PointerType>; |
173 | |
174 | public: |
175 | using ret_type = std::unique_ptr<ResultType>; |
176 | }; |
177 | |
178 | template <class To, class From, class SimpleFrom> struct cast_retty_wrap { |
179 | // When the simplified type and the from type are not the same, use the type |
180 | // simplifier to reduce the type, then reuse cast_retty_impl to get the |
181 | // resultant type. |
182 | using ret_type = typename cast_retty<To, SimpleFrom>::ret_type; |
183 | }; |
184 | |
185 | template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> { |
186 | // When the simplified type is equal to the from type, use it directly. |
187 | using ret_type = typename cast_retty_impl<To, FromTy>::ret_type; |
188 | }; |
189 | |
190 | template <class To, class From> struct cast_retty { |
191 | using ret_type = typename cast_retty_wrap< |
192 | To, From, typename simplify_type<From>::SimpleType>::ret_type; |
193 | }; |
194 | |
195 | //===----------------------------------------------------------------------===// |
196 | // cast_convert_val |
197 | //===----------------------------------------------------------------------===// |
198 | |
199 | // Ensure the non-simple values are converted using the simplify_type template |
200 | // that may be specialized by smart pointers... |
201 | // |
202 | template <class To, class From, class SimpleFrom> struct cast_convert_val { |
203 | // This is not a simple type, use the template to simplify it... |
204 | static typename cast_retty<To, From>::ret_type doit(const From &Val) { |
205 | return cast_convert_val<To, SimpleFrom, |
206 | typename simplify_type<SimpleFrom>::SimpleType>:: |
207 | doit(simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val))); |
208 | } |
209 | }; |
210 | |
211 | template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> { |
212 | // If it's a reference, switch to a pointer to do the cast and then deref it. |
213 | static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) { |
214 | return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type> |
215 | *)&const_cast<FromTy &>(Val); |
216 | } |
217 | }; |
218 | |
219 | template <class To, class FromTy> |
220 | struct cast_convert_val<To, FromTy *, FromTy *> { |
221 | // If it's a pointer, we can use c-style casting directly. |
222 | static typename cast_retty<To, FromTy *>::ret_type doit(const FromTy *Val) { |
223 | return (typename cast_retty<To, FromTy *>::ret_type) const_cast<FromTy *>( |
224 | Val); |
225 | } |
226 | }; |
227 | |
228 | //===----------------------------------------------------------------------===// |
229 | // is_simple_type |
230 | //===----------------------------------------------------------------------===// |
231 | |
232 | template <class X> struct is_simple_type { |
233 | static const bool value = |
234 | std::is_same<X, typename simplify_type<X>::SimpleType>::value; |
235 | }; |
236 | |
237 | // } // namespace detail |
238 | |
239 | //===----------------------------------------------------------------------===// |
240 | // CastIsPossible |
241 | //===----------------------------------------------------------------------===// |
242 | |
243 | /// This struct provides a way to check if a given cast is possible. It provides |
244 | /// a static function called isPossible that is used to check if a cast can be |
245 | /// performed. It should be overridden like this: |
246 | /// |
247 | /// template<> struct CastIsPossible<foo, bar> { |
248 | /// static inline bool isPossible(const bar &b) { |
249 | /// return bar.isFoo(); |
250 | /// } |
251 | /// }; |
252 | template <typename To, typename From, typename Enable = void> |
253 | struct CastIsPossible { |
254 | static inline bool isPossible(const From &f) { |
255 | return isa_impl_wrap< |
256 | To, const From, |
257 | typename simplify_type<const From>::SimpleType>::doit(f); |
258 | } |
259 | }; |
260 | |
261 | // Needed for optional unwrapping. This could be implemented with isa_impl, but |
262 | // we want to implement things in the new method and move old implementations |
263 | // over. In fact, some of the isa_impl templates should be moved over to |
264 | // CastIsPossible. |
265 | template <typename To, typename From> |
266 | struct CastIsPossible<To, Optional<From>> { |
267 | static inline bool isPossible(const Optional<From> &f) { |
268 | assert(f && "CastIsPossible::isPossible called on a nullopt!")(static_cast <bool> (f && "CastIsPossible::isPossible called on a nullopt!" ) ? void (0) : __assert_fail ("f && \"CastIsPossible::isPossible called on a nullopt!\"" , "llvm/include/llvm/Support/Casting.h", 268, __extension__ __PRETTY_FUNCTION__ )); |
269 | return isa_impl_wrap< |
270 | To, const From, |
271 | typename simplify_type<const From>::SimpleType>::doit(*f); |
272 | } |
273 | }; |
274 | |
275 | /// Upcasting (from derived to base) and casting from a type to itself should |
276 | /// always be possible. |
277 | template <typename To, typename From> |
278 | struct CastIsPossible<To, From, |
279 | std::enable_if_t<std::is_base_of<To, From>::value>> { |
280 | static inline bool isPossible(const From &f) { return true; } |
281 | }; |
282 | |
283 | //===----------------------------------------------------------------------===// |
284 | // Cast traits |
285 | //===----------------------------------------------------------------------===// |
286 | |
287 | /// All of these cast traits are meant to be implementations for useful casts |
288 | /// that users may want to use that are outside the standard behavior. An |
289 | /// example of how to use a special cast called `CastTrait` is: |
290 | /// |
291 | /// template<> struct CastInfo<foo, bar> : public CastTrait<foo, bar> {}; |
292 | /// |
293 | /// Essentially, if your use case falls directly into one of the use cases |
294 | /// supported by a given cast trait, simply inherit your special CastInfo |
295 | /// directly from one of these to avoid having to reimplement the boilerplate |
296 | /// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also |
297 | /// provide a subset of those functions. |
298 | |
299 | /// This cast trait just provides castFailed for the specified `To` type to make |
300 | /// CastInfo specializations more declarative. In order to use this, the target |
301 | /// result type must be `To` and `To` must be constructible from `nullptr`. |
302 | template <typename To> struct NullableValueCastFailed { |
303 | static To castFailed() { return To(nullptr); } |
304 | }; |
305 | |
306 | /// This cast trait just provides the default implementation of doCastIfPossible |
307 | /// to make CastInfo specializations more declarative. The `Derived` template |
308 | /// parameter *must* be provided for forwarding castFailed and doCast. |
309 | template <typename To, typename From, typename Derived> |
310 | struct DefaultDoCastIfPossible { |
311 | static To doCastIfPossible(From f) { |
312 | if (!Derived::isPossible(f)) |
313 | return Derived::castFailed(); |
314 | return Derived::doCast(f); |
315 | } |
316 | }; |
317 | |
318 | namespace detail { |
319 | /// A helper to derive the type to use with `Self` for cast traits, when the |
320 | /// provided CRTP derived type is allowed to be void. |
321 | template <typename OptionalDerived, typename Default> |
322 | using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value, |
323 | Default, OptionalDerived>; |
324 | } // namespace detail |
325 | |
326 | /// This cast trait provides casting for the specific case of casting to a |
327 | /// value-typed object from a pointer-typed object. Note that `To` must be |
328 | /// nullable/constructible from a pointer to `From` to use this cast. |
329 | template <typename To, typename From, typename Derived = void> |
330 | struct ValueFromPointerCast |
331 | : public CastIsPossible<To, From *>, |
332 | public NullableValueCastFailed<To>, |
333 | public DefaultDoCastIfPossible< |
334 | To, From *, |
335 | detail::SelfType<Derived, ValueFromPointerCast<To, From>>> { |
336 | static inline To doCast(From *f) { return To(f); } |
337 | }; |
338 | |
339 | /// This cast trait provides std::unique_ptr casting. It has the semantics of |
340 | /// moving the contents of the input unique_ptr into the output unique_ptr |
341 | /// during the cast. It's also a good example of how to implement a move-only |
342 | /// cast. |
343 | template <typename To, typename From, typename Derived = void> |
344 | struct UniquePtrCast : public CastIsPossible<To, From *> { |
345 | using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>; |
346 | using CastResultType = std::unique_ptr< |
347 | std::remove_reference_t<typename cast_retty<To, From>::ret_type>>; |
348 | |
349 | static inline CastResultType doCast(std::unique_ptr<From> &&f) { |
350 | return CastResultType((typename CastResultType::element_type *)f.release()); |
351 | } |
352 | |
353 | static inline CastResultType castFailed() { return CastResultType(nullptr); } |
354 | |
355 | static inline CastResultType doCastIfPossible(std::unique_ptr<From> &&f) { |
356 | if (!Self::isPossible(f)) |
357 | return castFailed(); |
358 | return doCast(f); |
359 | } |
360 | }; |
361 | |
362 | /// This cast trait provides Optional<T> casting. This means that if you have a |
363 | /// value type, you can cast it to another value type and have dyn_cast return |
364 | /// an Optional<T>. |
365 | template <typename To, typename From, typename Derived = void> |
366 | struct OptionalValueCast |
367 | : public CastIsPossible<To, From>, |
368 | public DefaultDoCastIfPossible< |
369 | Optional<To>, From, |
370 | detail::SelfType<Derived, OptionalValueCast<To, From>>> { |
371 | static inline Optional<To> castFailed() { return Optional<To>{}; } |
372 | |
373 | static inline Optional<To> doCast(const From &f) { return To(f); } |
374 | }; |
375 | |
376 | /// Provides a cast trait that strips `const` from types to make it easier to |
377 | /// implement a const-version of a non-const cast. It just removes boilerplate |
378 | /// and reduces the amount of code you as the user need to implement. You can |
379 | /// use it like this: |
380 | /// |
381 | /// template<> struct CastInfo<foo, bar> { |
382 | /// ...verbose implementation... |
383 | /// }; |
384 | /// |
385 | /// template<> struct CastInfo<foo, const bar> : public |
386 | /// ConstStrippingForwardingCast<foo, const bar, CastInfo<foo, bar>> {}; |
387 | /// |
388 | template <typename To, typename From, typename ForwardTo> |
389 | struct ConstStrippingForwardingCast { |
390 | // Remove the pointer if it exists, then we can get rid of consts/volatiles. |
391 | using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>; |
392 | // Now if it's a pointer, add it back. Otherwise, we want a ref. |
393 | using NonConstFrom = std::conditional_t<std::is_pointer<From>::value, |
394 | DecayedFrom *, DecayedFrom &>; |
395 | |
396 | static inline bool isPossible(const From &f) { |
397 | return ForwardTo::isPossible(const_cast<NonConstFrom>(f)); |
398 | } |
399 | |
400 | static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); } |
401 | |
402 | static inline decltype(auto) doCast(const From &f) { |
403 | return ForwardTo::doCast(const_cast<NonConstFrom>(f)); |
404 | } |
405 | |
406 | static inline decltype(auto) doCastIfPossible(const From &f) { |
407 | return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f)); |
408 | } |
409 | }; |
410 | |
411 | /// Provides a cast trait that uses a defined pointer to pointer cast as a base |
412 | /// for reference-to-reference casts. Note that it does not provide castFailed |
413 | /// and doCastIfPossible because a pointer-to-pointer cast would likely just |
414 | /// return `nullptr` which could cause nullptr dereference. You can use it like |
415 | /// this: |
416 | /// |
417 | /// template <> struct CastInfo<foo, bar *> { ... verbose implementation... }; |
418 | /// |
419 | /// template <> |
420 | /// struct CastInfo<foo, bar> |
421 | /// : public ForwardToPointerCast<foo, bar, CastInfo<foo, bar *>> {}; |
422 | /// |
423 | template <typename To, typename From, typename ForwardTo> |
424 | struct ForwardToPointerCast { |
425 | static inline bool isPossible(const From &f) { |
426 | return ForwardTo::isPossible(&f); |
427 | } |
428 | |
429 | static inline decltype(auto) doCast(const From &f) { |
430 | return *ForwardTo::doCast(&f); |
431 | } |
432 | }; |
433 | |
434 | //===----------------------------------------------------------------------===// |
435 | // CastInfo |
436 | //===----------------------------------------------------------------------===// |
437 | |
438 | /// This struct provides a method for customizing the way a cast is performed. |
439 | /// It inherits from CastIsPossible, to support the case of declaring many |
440 | /// CastIsPossible specializations without having to specialize the full |
441 | /// CastInfo. |
442 | /// |
443 | /// In order to specialize different behaviors, specify different functions in |
444 | /// your CastInfo specialization. |
445 | /// For isa<> customization, provide: |
446 | /// |
447 | /// `static bool isPossible(const From &f)` |
448 | /// |
449 | /// For cast<> customization, provide: |
450 | /// |
451 | /// `static To doCast(const From &f)` |
452 | /// |
453 | /// For dyn_cast<> and the *_if_present<> variants' customization, provide: |
454 | /// |
455 | /// `static To castFailed()` and `static To doCastIfPossible(const From &f)` |
456 | /// |
457 | /// Your specialization might look something like this: |
458 | /// |
459 | /// template<> struct CastInfo<foo, bar> : public CastIsPossible<foo, bar> { |
460 | /// static inline foo doCast(const bar &b) { |
461 | /// return foo(const_cast<bar &>(b)); |
462 | /// } |
463 | /// static inline foo castFailed() { return foo(); } |
464 | /// static inline foo doCastIfPossible(const bar &b) { |
465 | /// if (!CastInfo<foo, bar>::isPossible(b)) |
466 | /// return castFailed(); |
467 | /// return doCast(b); |
468 | /// } |
469 | /// }; |
470 | |
471 | // The default implementations of CastInfo don't use cast traits for now because |
472 | // we need to specify types all over the place due to the current expected |
473 | // casting behavior and the way cast_retty works. New use cases can and should |
474 | // take advantage of the cast traits whenever possible! |
475 | |
476 | template <typename To, typename From, typename Enable = void> |
477 | struct CastInfo : public CastIsPossible<To, From> { |
478 | using Self = CastInfo<To, From, Enable>; |
479 | |
480 | using CastReturnType = typename cast_retty<To, From>::ret_type; |
481 | |
482 | static inline CastReturnType doCast(const From &f) { |
483 | return cast_convert_val< |
484 | To, From, |
485 | typename simplify_type<From>::SimpleType>::doit(const_cast<From &>(f)); |
486 | } |
487 | |
488 | // This assumes that you can construct the cast return type from `nullptr`. |
489 | // This is largely to support legacy use cases - if you don't want this |
490 | // behavior you should specialize CastInfo for your use case. |
491 | static inline CastReturnType castFailed() { return CastReturnType(nullptr); } |
492 | |
493 | static inline CastReturnType doCastIfPossible(const From &f) { |
494 | if (!Self::isPossible(f)) |
495 | return castFailed(); |
496 | return doCast(f); |
497 | } |
498 | }; |
499 | |
500 | /// This struct provides an overload for CastInfo where From has simplify_type |
501 | /// defined. This simply forwards to the appropriate CastInfo with the |
502 | /// simplified type/value, so you don't have to implement both. |
503 | template <typename To, typename From> |
504 | struct CastInfo<To, From, std::enable_if_t<!is_simple_type<From>::value>> { |
505 | using Self = CastInfo<To, From>; |
506 | using SimpleFrom = typename simplify_type<From>::SimpleType; |
507 | using SimplifiedSelf = CastInfo<To, SimpleFrom>; |
508 | |
509 | static inline bool isPossible(From &f) { |
510 | return SimplifiedSelf::isPossible( |
511 | simplify_type<From>::getSimplifiedValue(f)); |
512 | } |
513 | |
514 | static inline decltype(auto) doCast(From &f) { |
515 | return SimplifiedSelf::doCast(simplify_type<From>::getSimplifiedValue(f)); |
516 | } |
517 | |
518 | static inline decltype(auto) castFailed() { |
519 | return SimplifiedSelf::castFailed(); |
520 | } |
521 | |
522 | static inline decltype(auto) doCastIfPossible(From &f) { |
523 | return SimplifiedSelf::doCastIfPossible( |
524 | simplify_type<From>::getSimplifiedValue(f)); |
525 | } |
526 | }; |
527 | |
528 | //===----------------------------------------------------------------------===// |
529 | // Pre-specialized CastInfo |
530 | //===----------------------------------------------------------------------===// |
531 | |
532 | /// Provide a CastInfo specialized for std::unique_ptr. |
533 | template <typename To, typename From> |
534 | struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {}; |
535 | |
536 | /// Provide a CastInfo specialized for Optional<From>. It's assumed that if the |
537 | /// input is Optional<From> that the output can be Optional<To>. If that's not |
538 | /// the case, specialize CastInfo for your use case. |
539 | template <typename To, typename From> |
540 | struct CastInfo<To, Optional<From>> : public OptionalValueCast<To, From> {}; |
541 | |
542 | /// isa<X> - Return true if the parameter to the template is an instance of one |
543 | /// of the template type arguments. Used like this: |
544 | /// |
545 | /// if (isa<Type>(myVal)) { ... } |
546 | /// if (isa<Type0, Type1, Type2>(myVal)) { ... } |
547 | template <typename To, typename From> |
548 | [[nodiscard]] inline bool isa(const From &Val) { |
549 | return CastInfo<To, const From>::isPossible(Val); |
550 | } |
551 | |
552 | template <typename First, typename Second, typename... Rest, typename From> |
553 | [[nodiscard]] inline bool isa(const From &Val) { |
554 | return isa<First>(Val) || isa<Second, Rest...>(Val); |
555 | } |
556 | |
557 | /// cast<X> - Return the argument parameter cast to the specified type. This |
558 | /// casting operator asserts that the type is correct, so it does not return |
559 | /// null on failure. It does not allow a null argument (use cast_if_present for |
560 | /// that). It is typically used like this: |
561 | /// |
562 | /// cast<Instruction>(myVal)->getParent() |
563 | |
564 | template <typename To, typename From> |
565 | [[nodiscard]] inline decltype(auto) cast(const From &Val) { |
566 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 566, __extension__ __PRETTY_FUNCTION__ )); |
567 | return CastInfo<To, const From>::doCast(Val); |
568 | } |
569 | |
570 | template <typename To, typename From> |
571 | [[nodiscard]] inline decltype(auto) cast(From &Val) { |
572 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 572, __extension__ __PRETTY_FUNCTION__ )); |
573 | return CastInfo<To, From>::doCast(Val); |
574 | } |
575 | |
576 | template <typename To, typename From> |
577 | [[nodiscard]] inline decltype(auto) cast(From *Val) { |
578 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 578, __extension__ __PRETTY_FUNCTION__ )); |
579 | return CastInfo<To, From *>::doCast(Val); |
580 | } |
581 | |
582 | template <typename To, typename From> |
583 | [[nodiscard]] inline decltype(auto) cast(std::unique_ptr<From> &&Val) { |
584 | assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 584, __extension__ __PRETTY_FUNCTION__ )); |
585 | return CastInfo<To, std::unique_ptr<From>>::doCast(std::move(Val)); |
586 | } |
587 | |
588 | /// dyn_cast<X> - Return the argument parameter cast to the specified type. This |
589 | /// casting operator returns null if the argument is of the wrong type, so it |
590 | /// can be used to test for a type as well as cast if successful. The value |
591 | /// passed in must be present, if not, use dyn_cast_if_present. This should be |
592 | /// used in the context of an if statement like this: |
593 | /// |
594 | /// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... } |
595 | |
596 | template <typename To, typename From> |
597 | [[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) { |
598 | return CastInfo<To, const From>::doCastIfPossible(Val); |
599 | } |
600 | |
601 | template <typename To, typename From> |
602 | [[nodiscard]] inline decltype(auto) dyn_cast(From &Val) { |
603 | return CastInfo<To, From>::doCastIfPossible(Val); |
604 | } |
605 | |
606 | template <typename To, typename From> |
607 | [[nodiscard]] inline decltype(auto) dyn_cast(From *Val) { |
608 | return CastInfo<To, From *>::doCastIfPossible(Val); |
609 | } |
610 | |
611 | template <typename To, typename From> |
612 | [[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) { |
613 | return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible(std::move(Val)); |
614 | } |
615 | |
616 | //===----------------------------------------------------------------------===// |
617 | // ValueIsPresent |
618 | //===----------------------------------------------------------------------===// |
619 | |
620 | template <typename T> |
621 | constexpr bool IsNullable = std::is_pointer<T>::value || |
622 | std::is_constructible<T, std::nullptr_t>::value; |
623 | |
624 | /// ValueIsPresent provides a way to check if a value is, well, present. For |
625 | /// pointers, this is the equivalent of checking against nullptr, for |
626 | /// Optionals this is the equivalent of checking hasValue(). It also |
627 | /// provides a method for unwrapping a value (think dereferencing a |
628 | /// pointer). |
629 | |
630 | // Generic values can't *not* be present. |
631 | template <typename T, typename Enable = void> struct ValueIsPresent { |
632 | using UnwrappedType = T; |
633 | static inline bool isPresent(const T &t) { return true; } |
634 | static inline decltype(auto) unwrapValue(T &t) { return t; } |
635 | }; |
636 | |
637 | // Optional provides its own way to check if something is present. |
638 | template <typename T> struct ValueIsPresent<Optional<T>> { |
639 | using UnwrappedType = T; |
640 | static inline bool isPresent(const Optional<T> &t) { return t.has_value(); } |
641 | static inline decltype(auto) unwrapValue(Optional<T> &t) { return t.value(); } |
642 | }; |
643 | |
644 | // If something is "nullable" then we just compare it to nullptr to see if it |
645 | // exists. |
646 | template <typename T> |
647 | struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> { |
648 | using UnwrappedType = T; |
649 | static inline bool isPresent(const T &t) { return t != nullptr; } |
650 | static inline decltype(auto) unwrapValue(T &t) { return t; } |
651 | }; |
652 | |
653 | namespace detail { |
654 | // Convenience function we can use to check if a value is present. Because of |
655 | // simplify_type, we have to call it on the simplified type for now. |
656 | template <typename T> inline bool isPresent(const T &t) { |
657 | return ValueIsPresent<typename simplify_type<T>::SimpleType>::isPresent( |
658 | simplify_type<T>::getSimplifiedValue(const_cast<T &>(t))); |
659 | } |
660 | |
661 | // Convenience function we can use to unwrap a value. |
662 | template <typename T> inline decltype(auto) unwrapValue(T &t) { |
663 | return ValueIsPresent<T>::unwrapValue(t); |
664 | } |
665 | } // namespace detail |
666 | |
667 | /// isa_and_present<X> - Functionally identical to isa, except that a null value |
668 | /// is accepted. |
669 | template <typename... X, class Y> |
670 | [[nodiscard]] inline bool isa_and_present(const Y &Val) { |
671 | if (!detail::isPresent(Val)) |
672 | return false; |
673 | return isa<X...>(Val); |
674 | } |
675 | |
676 | template <typename... X, class Y> |
677 | [[nodiscard]] inline bool isa_and_nonnull(const Y &Val) { |
678 | return isa_and_present<X...>(Val); |
679 | } |
680 | |
681 | /// cast_if_present<X> - Functionally identical to cast, except that a null |
682 | /// value is accepted. |
683 | template <class X, class Y> |
684 | [[nodiscard]] inline auto cast_if_present(const Y &Val) { |
685 | if (!detail::isPresent(Val)) |
686 | return CastInfo<X, const Y>::castFailed(); |
687 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 687, __extension__ __PRETTY_FUNCTION__ )); |
688 | return cast<X>(detail::unwrapValue(Val)); |
689 | } |
690 | |
691 | template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) { |
692 | if (!detail::isPresent(Val)) |
693 | return CastInfo<X, Y>::castFailed(); |
694 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 694, __extension__ __PRETTY_FUNCTION__ )); |
695 | return cast<X>(detail::unwrapValue(Val)); |
696 | } |
697 | |
698 | template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) { |
699 | if (!detail::isPresent(Val)) |
700 | return CastInfo<X, Y *>::castFailed(); |
701 | assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!" ) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\"" , "llvm/include/llvm/Support/Casting.h", 701, __extension__ __PRETTY_FUNCTION__ )); |
702 | return cast<X>(detail::unwrapValue(Val)); |
703 | } |
704 | |
705 | template <class X, class Y> |
706 | [[nodiscard]] inline auto cast_if_present(std::unique_ptr<Y> &&Val) { |
707 | if (!detail::isPresent(Val)) |
708 | return UniquePtrCast<X, Y>::castFailed(); |
709 | return UniquePtrCast<X, Y>::doCast(std::move(Val)); |
710 | } |
711 | |
712 | // Provide a forwarding from cast_or_null to cast_if_present for current |
713 | // users. This is deprecated and will be removed in a future patch, use |
714 | // cast_if_present instead. |
715 | template <class X, class Y> auto cast_or_null(const Y &Val) { |
716 | return cast_if_present<X>(Val); |
717 | } |
718 | |
719 | template <class X, class Y> auto cast_or_null(Y &Val) { |
720 | return cast_if_present<X>(Val); |
721 | } |
722 | |
723 | template <class X, class Y> auto cast_or_null(Y *Val) { |
724 | return cast_if_present<X>(Val); |
725 | } |
726 | |
727 | template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) { |
728 | return cast_if_present<X>(std::move(Val)); |
729 | } |
730 | |
731 | /// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a |
732 | /// null (or none in the case of optionals) value is accepted. |
733 | template <class X, class Y> auto dyn_cast_if_present(const Y &Val) { |
734 | if (!detail::isPresent(Val)) |
735 | return CastInfo<X, const Y>::castFailed(); |
736 | return CastInfo<X, const Y>::doCastIfPossible(detail::unwrapValue(Val)); |
737 | } |
738 | |
739 | template <class X, class Y> auto dyn_cast_if_present(Y &Val) { |
740 | if (!detail::isPresent(Val)) |
741 | return CastInfo<X, Y>::castFailed(); |
742 | return CastInfo<X, Y>::doCastIfPossible(detail::unwrapValue(Val)); |
743 | } |
744 | |
745 | template <class X, class Y> auto dyn_cast_if_present(Y *Val) { |
746 | if (!detail::isPresent(Val)) |
747 | return CastInfo<X, Y *>::castFailed(); |
748 | return CastInfo<X, Y *>::doCastIfPossible(detail::unwrapValue(Val)); |
749 | } |
750 | |
751 | // Forwards to dyn_cast_if_present to avoid breaking current users. This is |
752 | // deprecated and will be removed in a future patch, use |
753 | // cast_if_present instead. |
754 | template <class X, class Y> auto dyn_cast_or_null(const Y &Val) { |
755 | return dyn_cast_if_present<X>(Val); |
756 | } |
757 | |
758 | template <class X, class Y> auto dyn_cast_or_null(Y &Val) { |
759 | return dyn_cast_if_present<X>(Val); |
760 | } |
761 | |
762 | template <class X, class Y> auto dyn_cast_or_null(Y *Val) { |
763 | return dyn_cast_if_present<X>(Val); |
764 | } |
765 | |
766 | /// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>, |
767 | /// taking ownership of the input pointer iff isa<X>(Val) is true. If the |
768 | /// cast is successful, From refers to nullptr on exit and the casted value |
769 | /// is returned. If the cast is unsuccessful, the function returns nullptr |
770 | /// and From is unchanged. |
771 | template <class X, class Y> |
772 | [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType |
773 | unique_dyn_cast(std::unique_ptr<Y> &Val) { |
774 | if (!isa<X>(Val)) |
775 | return nullptr; |
776 | return cast<X>(std::move(Val)); |
777 | } |
778 | |
779 | template <class X, class Y> |
780 | [[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) { |
781 | return unique_dyn_cast<X, Y>(Val); |
782 | } |
783 | |
784 | // unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast, |
785 | // except that a null value is accepted. |
786 | template <class X, class Y> |
787 | [[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType |
788 | unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) { |
789 | if (!Val) |
790 | return nullptr; |
791 | return unique_dyn_cast<X, Y>(Val); |
792 | } |
793 | |
794 | template <class X, class Y> |
795 | [[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) { |
796 | return unique_dyn_cast_or_null<X, Y>(Val); |
797 | } |
798 | |
799 | } // end namespace llvm |
800 | |
801 | #endif // LLVM_SUPPORT_CASTING_H |