clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaTemplateVariadic.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include/clang/Sema -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libclangSema/../include -I /usr/src/gnu/usr.bin/clang/libclangSema/obj -I /usr/src/gnu/usr.bin/clang/libclangSema/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libclangSema/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libclangSema/../../../llvm/clang/lib/Sema/SemaTemplateVariadic.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
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 | |
26 | |
27 | |
28 | namespace { |
29 | |
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 | |
44 | |
45 | |
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 | |
70 | |
71 | |
72 | |
73 | bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { |
74 | if (TL.getTypePtr()->isParameterPack()) |
75 | addUnexpanded(TL.getTypePtr(), TL.getNameLoc()); |
76 | return true; |
77 | } |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { |
85 | if (T->isParameterPack()) |
86 | addUnexpanded(T); |
87 | |
88 | return true; |
89 | } |
90 | |
91 | |
92 | |
93 | bool VisitDeclRefExpr(DeclRefExpr *E) { |
94 | if (E->getDecl()->isParameterPack()) |
95 | addUnexpanded(E->getDecl(), E->getLocation()); |
96 | |
97 | return true; |
98 | } |
99 | |
100 | |
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 | |
112 | |
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 | |
129 | |
130 | |
131 | |
132 | |
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 | |
142 | |
143 | bool TraverseType(QualType T) { |
144 | if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda) |
145 | return inherited::TraverseType(T); |
146 | |
147 | return true; |
148 | } |
149 | |
150 | |
151 | |
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 | |
162 | bool TraverseDecl(Decl *D) { |
163 | |
164 | |
165 | |
166 | if (D && D->isParameterPack()) |
167 | return true; |
168 | |
169 | return inherited::TraverseDecl(D); |
170 | } |
171 | |
172 | |
173 | bool TraverseAttr(Attr *A) { |
174 | if (A->isPackExpansion()) |
175 | return true; |
176 | |
177 | return inherited::TraverseAttr(A); |
178 | } |
179 | |
180 | |
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 | |
190 | bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { |
191 | if (D->isPackExpansion()) |
192 | return true; |
193 | |
194 | return inherited::TraverseUnresolvedUsingValueDecl(D); |
195 | } |
196 | |
197 | |
198 | bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { |
199 | if (D->isPackExpansion()) |
200 | return true; |
201 | |
202 | return inherited::TraverseUnresolvedUsingTypenameDecl(D); |
203 | } |
204 | |
205 | |
206 | bool TraverseTemplateArgument(const TemplateArgument &Arg) { |
207 | if (Arg.isPackExpansion()) |
208 | return true; |
209 | |
210 | return inherited::TraverseTemplateArgument(Arg); |
211 | } |
212 | |
213 | |
214 | bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) { |
215 | if (ArgLoc.getArgument().isPackExpansion()) |
216 | return true; |
217 | |
218 | return inherited::TraverseTemplateArgumentLoc(ArgLoc); |
219 | } |
220 | |
221 | |
222 | bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) { |
223 | if (Base.isPackExpansion()) |
224 | return true; |
225 | |
226 | return inherited::TraverseCXXBaseSpecifier(Base); |
227 | } |
228 | |
229 | |
230 | bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { |
231 | if (Init->isPackExpansion()) |
232 | return true; |
233 | |
234 | return inherited::TraverseConstructorInitializer(Init); |
235 | } |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | |
242 | bool TraverseLambdaExpr(LambdaExpr *Lambda) { |
243 | |
244 | |
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 | |
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 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | bool Sema::isUnexpandedParameterPackPermitted() { |
281 | for (auto *SI : FunctionScopes) |
282 | if (isa<sema::LambdaScopeInfo>(SI)) |
283 | return true; |
284 | return false; |
285 | } |
286 | |
287 | |
288 | |
289 | bool |
290 | Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, |
291 | UnexpandedParameterPackContext UPPC, |
292 | ArrayRef<UnexpandedParameterPack> Unexpanded) { |
293 | if (Unexpanded.empty()) |
294 | return false; |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
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 (std::find_if(LSI->LocalPacks.begin(), LSI->LocalPacks.end(), |
312 | DeclaresThisPack) != LSI->LocalPacks.end()) |
313 | LambdaParamPackReferences.push_back(Pack); |
314 | } |
315 | |
316 | if (LambdaParamPackReferences.empty()) { |
317 | |
318 | |
319 | |
320 | |
321 | |
322 | |
323 | |
324 | |
325 | |
326 | |
327 | |
328 | bool EnclosingStmtExpr = false; |
329 | for (unsigned N = FunctionScopes.size(); N; --N) { |
330 | sema::FunctionScopeInfo *Func = FunctionScopes[N-1]; |
331 | if (std::any_of( |
332 | Func->CompoundScopes.begin(), Func->CompoundScopes.end(), |
333 | [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) { |
334 | EnclosingStmtExpr = true; |
335 | break; |
336 | } |
337 | |
338 | |
339 | if (Func == LSI) |
340 | break; |
341 | } |
342 | |
343 | if (!EnclosingStmtExpr) { |
344 | LSI->ContainsUnexpandedParameterPack = true; |
345 | return false; |
346 | } |
347 | } else { |
348 | Unexpanded = LambdaParamPackReferences; |
349 | } |
350 | } |
351 | |
352 | SmallVector<SourceLocation, 4> Locations; |
353 | SmallVector<IdentifierInfo *, 4> Names; |
354 | llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; |
355 | |
356 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { |
357 | IdentifierInfo *Name = nullptr; |
358 | if (const TemplateTypeParmType *TTP |
359 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) |
360 | Name = TTP->getIdentifier(); |
361 | else |
362 | Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier(); |
363 | |
364 | if (Name && NamesKnown.insert(Name).second) |
365 | Names.push_back(Name); |
366 | |
367 | if (Unexpanded[I].second.isValid()) |
368 | Locations.push_back(Unexpanded[I].second); |
369 | } |
370 | |
371 | auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack) |
372 | << (int)UPPC << (int)Names.size(); |
373 | for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I) |
374 | DB << Names[I]; |
375 | |
376 | for (unsigned I = 0, N = Locations.size(); I != N; ++I) |
377 | DB << SourceRange(Locations[I]); |
378 | return true; |
379 | } |
380 | |
381 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
382 | TypeSourceInfo *T, |
383 | UnexpandedParameterPackContext UPPC) { |
384 | |
385 | |
386 | |
387 | if (!T->getType()->containsUnexpandedParameterPack()) |
388 | return false; |
389 | |
390 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
391 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( |
392 | T->getTypeLoc()); |
393 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
394 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); |
395 | } |
396 | |
397 | bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, |
398 | UnexpandedParameterPackContext UPPC) { |
399 | |
400 | |
401 | |
402 | if (!E->containsUnexpandedParameterPack()) |
403 | return false; |
404 | |
405 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
406 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E); |
407 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
408 | return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded); |
409 | } |
410 | |
411 | bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) { |
412 | if (!RE->containsUnexpandedParameterPack()) |
413 | return false; |
414 | |
415 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
416 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE); |
417 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
418 | |
419 | |
420 | |
421 | auto Parms = RE->getLocalParameters(); |
422 | llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end()); |
423 | SmallVector<UnexpandedParameterPack, 2> UnexpandedParms; |
424 | for (auto Parm : Unexpanded) |
425 | if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>())) |
426 | UnexpandedParms.push_back(Parm); |
427 | if (UnexpandedParms.empty()) |
428 | return false; |
429 | |
430 | return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement, |
431 | UnexpandedParms); |
432 | } |
433 | |
434 | bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, |
435 | UnexpandedParameterPackContext UPPC) { |
436 | |
437 | |
438 | |
439 | if (!SS.getScopeRep() || |
440 | !SS.getScopeRep()->containsUnexpandedParameterPack()) |
441 | return false; |
442 | |
443 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
444 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
445 | .TraverseNestedNameSpecifier(SS.getScopeRep()); |
446 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
447 | return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), |
448 | UPPC, Unexpanded); |
449 | } |
450 | |
451 | bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, |
452 | UnexpandedParameterPackContext UPPC) { |
453 | |
454 | |
455 | |
456 | switch (NameInfo.getName().getNameKind()) { |
457 | case DeclarationName::Identifier: |
458 | case DeclarationName::ObjCZeroArgSelector: |
459 | case DeclarationName::ObjCOneArgSelector: |
460 | case DeclarationName::ObjCMultiArgSelector: |
461 | case DeclarationName::CXXOperatorName: |
462 | case DeclarationName::CXXLiteralOperatorName: |
463 | case DeclarationName::CXXUsingDirective: |
464 | case DeclarationName::CXXDeductionGuideName: |
465 | return false; |
466 | |
467 | case DeclarationName::CXXConstructorName: |
468 | case DeclarationName::CXXDestructorName: |
469 | case DeclarationName::CXXConversionFunctionName: |
470 | |
471 | if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) |
472 | return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); |
473 | |
474 | if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) |
475 | return false; |
476 | |
477 | break; |
478 | } |
479 | |
480 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
481 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
482 | .TraverseType(NameInfo.getName().getCXXNameType()); |
483 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
484 | return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded); |
485 | } |
486 | |
487 | bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, |
488 | TemplateName Template, |
489 | UnexpandedParameterPackContext UPPC) { |
490 | |
491 | if (Template.isNull() || !Template.containsUnexpandedParameterPack()) |
492 | return false; |
493 | |
494 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
495 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
496 | .TraverseTemplateName(Template); |
497 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
498 | return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded); |
499 | } |
500 | |
501 | bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, |
502 | UnexpandedParameterPackContext UPPC) { |
503 | if (Arg.getArgument().isNull() || |
504 | !Arg.getArgument().containsUnexpandedParameterPack()) |
505 | return false; |
506 | |
507 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
508 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
509 | .TraverseTemplateArgumentLoc(Arg); |
510 | assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); |
511 | return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded); |
512 | } |
513 | |
514 | void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, |
515 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
516 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
517 | .TraverseTemplateArgument(Arg); |
518 | } |
519 | |
520 | void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, |
521 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
522 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
523 | .TraverseTemplateArgumentLoc(Arg); |
524 | } |
525 | |
526 | void Sema::collectUnexpandedParameterPacks(QualType T, |
527 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
528 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); |
529 | } |
530 | |
531 | void Sema::collectUnexpandedParameterPacks(TypeLoc TL, |
532 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
533 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); |
534 | } |
535 | |
536 | void Sema::collectUnexpandedParameterPacks( |
537 | NestedNameSpecifierLoc NNS, |
538 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
539 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
540 | .TraverseNestedNameSpecifierLoc(NNS); |
541 | } |
542 | |
543 | void Sema::collectUnexpandedParameterPacks( |
544 | const DeclarationNameInfo &NameInfo, |
545 | SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { |
546 | CollectUnexpandedParameterPacksVisitor(Unexpanded) |
547 | .TraverseDeclarationNameInfo(NameInfo); |
548 | } |
549 | |
550 | |
551 | ParsedTemplateArgument |
552 | Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, |
553 | SourceLocation EllipsisLoc) { |
554 | if (Arg.isInvalid()) |
555 | return Arg; |
556 | |
557 | switch (Arg.getKind()) { |
558 | case ParsedTemplateArgument::Type: { |
559 | TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc); |
560 | if (Result.isInvalid()) |
561 | return ParsedTemplateArgument(); |
562 | |
563 | return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), |
564 | Arg.getLocation()); |
565 | } |
566 | |
567 | case ParsedTemplateArgument::NonType: { |
568 | ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); |
569 | if (Result.isInvalid()) |
570 | return ParsedTemplateArgument(); |
571 | |
572 | return ParsedTemplateArgument(Arg.getKind(), Result.get(), |
573 | Arg.getLocation()); |
574 | } |
575 | |
576 | case ParsedTemplateArgument::Template: |
577 | if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) { |
578 | SourceRange R(Arg.getLocation()); |
579 | if (Arg.getScopeSpec().isValid()) |
580 | R.setBegin(Arg.getScopeSpec().getBeginLoc()); |
581 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
582 | << R; |
583 | return ParsedTemplateArgument(); |
584 | } |
585 | |
586 | return Arg.getTemplatePackExpansion(EllipsisLoc); |
587 | } |
588 | llvm_unreachable("Unhandled template argument kind?"); |
589 | } |
590 | |
591 | TypeResult Sema::ActOnPackExpansion(ParsedType Type, |
592 | SourceLocation EllipsisLoc) { |
593 | TypeSourceInfo *TSInfo; |
594 | GetTypeFromParser(Type, &TSInfo); |
595 | if (!TSInfo) |
596 | return true; |
597 | |
598 | TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None); |
599 | if (!TSResult) |
600 | return true; |
601 | |
602 | return CreateParsedType(TSResult->getType(), TSResult); |
603 | } |
604 | |
605 | TypeSourceInfo * |
606 | Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, |
607 | Optional<unsigned> NumExpansions) { |
608 | |
609 | QualType Result = CheckPackExpansion(Pattern->getType(), |
610 | Pattern->getTypeLoc().getSourceRange(), |
611 | EllipsisLoc, NumExpansions); |
612 | if (Result.isNull()) |
613 | return nullptr; |
614 | |
615 | TypeLocBuilder TLB; |
616 | TLB.pushFullCopy(Pattern->getTypeLoc()); |
617 | PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result); |
618 | TL.setEllipsisLoc(EllipsisLoc); |
619 | |
620 | return TLB.getTypeSourceInfo(Context, Result); |
621 | } |
622 | |
623 | QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, |
624 | SourceLocation EllipsisLoc, |
625 | Optional<unsigned> NumExpansions) { |
626 | |
627 | |
628 | |
629 | |
630 | |
631 | |
632 | |
633 | if (!Pattern->containsUnexpandedParameterPack() && |
634 | !Pattern->getContainedDeducedType()) { |
635 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
636 | << PatternRange; |
637 | return QualType(); |
638 | } |
639 | |
640 | return Context.getPackExpansionType(Pattern, NumExpansions, |
641 | false); |
642 | } |
643 | |
644 | ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { |
645 | return CheckPackExpansion(Pattern, EllipsisLoc, None); |
646 | } |
647 | |
648 | ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, |
649 | Optional<unsigned> NumExpansions) { |
650 | if (!Pattern) |
651 | return ExprError(); |
652 | |
653 | |
654 | |
655 | |
656 | |
657 | if (!Pattern->containsUnexpandedParameterPack()) { |
658 | Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
659 | << Pattern->getSourceRange(); |
660 | CorrectDelayedTyposInExpr(Pattern); |
661 | return ExprError(); |
662 | } |
663 | |
664 | |
665 | return new (Context) |
666 | PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions); |
667 | } |
668 | |
669 | bool Sema::CheckParameterPacksForExpansion( |
670 | SourceLocation EllipsisLoc, SourceRange PatternRange, |
671 | ArrayRef<UnexpandedParameterPack> Unexpanded, |
672 | const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, |
673 | bool &RetainExpansion, Optional<unsigned> &NumExpansions) { |
674 | ShouldExpand = true; |
675 | RetainExpansion = false; |
676 | std::pair<IdentifierInfo *, SourceLocation> FirstPack; |
677 | bool HaveFirstPack = false; |
678 | Optional<unsigned> NumPartialExpansions; |
679 | SourceLocation PartiallySubstitutedPackLoc; |
680 | |
681 | for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(), |
| 2 | | Loop condition is true. Entering loop body | |
|
| 27 | | Loop condition is true. Entering loop body | |
|
682 | end = Unexpanded.end(); |
683 | i != end; ++i) { |
| 1 | Assuming 'i' is not equal to 'end' | |
|
684 | |
685 | unsigned Depth = 0, Index = 0; |
686 | IdentifierInfo *Name; |
687 | bool IsVarDeclPack = false; |
688 | |
689 | if (const TemplateTypeParmType *TTP |
| |
| |
690 | = i->first.dyn_cast<const TemplateTypeParmType *>()) { |
| 28 | | Calling 'PointerUnion::dyn_cast' | |
|
| 35 | | Returning from 'PointerUnion::dyn_cast' | |
|
691 | Depth = TTP->getDepth(); |
692 | Index = TTP->getIndex(); |
693 | Name = TTP->getIdentifier(); |
694 | } else { |
695 | NamedDecl *ND = i->first.get<NamedDecl *>(); |
696 | if (isa<VarDecl>(ND)) |
| 4 | | Assuming 'ND' is not a 'VarDecl' | |
|
| |
| 37 | | Assuming 'ND' is a 'VarDecl' | |
|
| |
697 | IsVarDeclPack = true; |
698 | else |
699 | std::tie(Depth, Index) = getDepthAndIndex(ND); |
700 | |
701 | Name = ND->getIdentifier(); |
702 | } |
703 | |
704 | |
705 | unsigned NewPackSize; |
706 | if (IsVarDeclPack) { |
| |
| |
707 | |
708 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; |
709 | |
710 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation |
711 | = CurrentInstantiationScope->findInstantiationOf( |
| 40 | | Called C++ object pointer is null |
|
712 | i->first.get<NamedDecl *>()); |
713 | if (Instantiation->is<DeclArgumentPack *>()) { |
714 | |
715 | NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); |
716 | } else { |
717 | |
718 | |
719 | ShouldExpand = false; |
720 | continue; |
721 | } |
722 | } else { |
723 | |
724 | |
725 | |
726 | if (Depth >= TemplateArgs.getNumLevels() || |
| 7 | | Assuming the condition is false | |
|
| |
727 | !TemplateArgs.hasTemplateArgument(Depth, Index)) { |
| 8 | | Calling 'MultiLevelTemplateArgumentList::hasTemplateArgument' | |
|
| 18 | | Returning from 'MultiLevelTemplateArgumentList::hasTemplateArgument' | |
|
728 | ShouldExpand = false; |
729 | continue; |
730 | } |
731 | |
732 | |
733 | NewPackSize = TemplateArgs(Depth, Index).pack_size(); |
734 | } |
735 | |
736 | |
737 | |
738 | |
739 | |
740 | if (!IsVarDeclPack && CurrentInstantiationScope) { |
| 20 | | Assuming field 'CurrentInstantiationScope' is null | |
|
| 21 | | Assuming pointer value is null | |
|
| |
741 | if (NamedDecl *PartialPack |
742 | = CurrentInstantiationScope->getPartiallySubstitutedPack()){ |
743 | unsigned PartialDepth, PartialIndex; |
744 | std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); |
745 | if (PartialDepth == Depth && PartialIndex == Index) { |
746 | RetainExpansion = true; |
747 | |
748 | NumPartialExpansions = NewPackSize; |
749 | PartiallySubstitutedPackLoc = i->second; |
750 | continue; |
751 | } |
752 | } |
753 | } |
754 | |
755 | if (!NumExpansions) { |
| 23 | | Assuming the condition is false | |
|
| |
756 | |
757 | |
758 | NumExpansions = NewPackSize; |
759 | FirstPack.first = Name; |
760 | FirstPack.second = i->second; |
761 | HaveFirstPack = true; |
762 | continue; |
763 | } |
764 | |
765 | if (NewPackSize != *NumExpansions) { |
| 25 | | Assuming the condition is false | |
|
| |
766 | |
767 | |
768 | |
769 | if (HaveFirstPack) |
770 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) |
771 | << FirstPack.first << Name << *NumExpansions << NewPackSize |
772 | << SourceRange(FirstPack.second) << SourceRange(i->second); |
773 | else |
774 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) |
775 | << Name << *NumExpansions << NewPackSize |
776 | << SourceRange(i->second); |
777 | return true; |
778 | } |
779 | } |
780 | |
781 | |
782 | |
783 | |
784 | |
785 | |
786 | |
787 | |
788 | |
789 | |
790 | if (NumPartialExpansions) { |
791 | if (NumExpansions && *NumExpansions < *NumPartialExpansions) { |
792 | NamedDecl *PartialPack = |
793 | CurrentInstantiationScope->getPartiallySubstitutedPack(); |
794 | Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) |
795 | << PartialPack << *NumPartialExpansions << *NumExpansions |
796 | << SourceRange(PartiallySubstitutedPackLoc); |
797 | return true; |
798 | } |
799 | |
800 | NumExpansions = NumPartialExpansions; |
801 | } |
802 | |
803 | return false; |
804 | } |
805 | |
806 | Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, |
807 | const MultiLevelTemplateArgumentList &TemplateArgs) { |
808 | QualType Pattern = cast<PackExpansionType>(T)->getPattern(); |
809 | SmallVector<UnexpandedParameterPack, 2> Unexpanded; |
810 | CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); |
811 | |
812 | Optional<unsigned> Result; |
813 | for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { |
814 | |
815 | unsigned Depth; |
816 | unsigned Index; |
817 | |
818 | if (const TemplateTypeParmType *TTP |
819 | = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { |
820 | Depth = TTP->getDepth(); |
821 | Index = TTP->getIndex(); |
822 | } else { |
823 | NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); |
824 | if (isa<VarDecl>(ND)) { |
825 | |
826 | typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; |
827 | |
828 | llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation |
829 | = CurrentInstantiationScope->findInstantiationOf( |
830 | Unexpanded[I].first.get<NamedDecl *>()); |
831 | if (Instantiation->is<Decl*>()) |
832 | |
833 | |
834 | return None; |
835 | |
836 | unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); |
837 | assert((!Result || *Result == Size) && "inconsistent pack sizes"); |
838 | Result = Size; |
839 | continue; |
840 | } |
841 | |
842 | std::tie(Depth, Index) = getDepthAndIndex(ND); |
843 | } |
844 | if (Depth >= TemplateArgs.getNumLevels() || |
845 | !TemplateArgs.hasTemplateArgument(Depth, Index)) |
846 | |
847 | |
848 | return None; |
849 | |
850 | |
851 | unsigned Size = TemplateArgs(Depth, Index).pack_size(); |
852 | assert((!Result || *Result == Size) && "inconsistent pack sizes"); |
853 | Result = Size; |
854 | } |
855 | |
856 | return Result; |
857 | } |
858 | |
859 | bool Sema::containsUnexpandedParameterPacks(Declarator &D) { |
860 | const DeclSpec &DS = D.getDeclSpec(); |
861 | switch (DS.getTypeSpecType()) { |
862 | case TST_typename: |
863 | case TST_typeofType: |
864 | case TST_underlyingType: |
865 | case TST_atomic: { |
866 | QualType T = DS.getRepAsType().get(); |
867 | if (!T.isNull() && T->containsUnexpandedParameterPack()) |
868 | return true; |
869 | break; |
870 | } |
871 | |
872 | case TST_typeofExpr: |
873 | case TST_decltype: |
874 | case TST_extint: |
875 | if (DS.getRepAsExpr() && |
876 | DS.getRepAsExpr()->containsUnexpandedParameterPack()) |
877 | return true; |
878 | break; |
879 | |
880 | case TST_unspecified: |
881 | case TST_void: |
882 | case TST_char: |
883 | case TST_wchar: |
884 | case TST_char8: |
885 | case TST_char16: |
886 | case TST_char32: |
887 | case TST_int: |
888 | case TST_int128: |
889 | case TST_half: |
890 | case TST_float: |
891 | case TST_double: |
892 | case TST_Accum: |
893 | case TST_Fract: |
894 | case TST_Float16: |
895 | case TST_float128: |
896 | case TST_bool: |
897 | case TST_decimal32: |
898 | case TST_decimal64: |
899 | case TST_decimal128: |
900 | case TST_enum: |
901 | case TST_union: |
902 | case TST_struct: |
903 | case TST_interface: |
904 | case TST_class: |
905 | case TST_auto: |
906 | case TST_auto_type: |
907 | case TST_decltype_auto: |
908 | case TST_BFloat16: |
909 | #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: |
910 | #include "clang/Basic/OpenCLImageTypes.def" |
911 | case TST_unknown_anytype: |
912 | case TST_error: |
913 | break; |
914 | } |
915 | |
916 | for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { |
917 | const DeclaratorChunk &Chunk = D.getTypeObject(I); |
918 | switch (Chunk.Kind) { |
919 | case DeclaratorChunk::Pointer: |
920 | case DeclaratorChunk::Reference: |
921 | case DeclaratorChunk::Paren: |
922 | case DeclaratorChunk::Pipe: |
923 | case DeclaratorChunk::BlockPointer: |
924 | |
925 | break; |
926 | |
927 | case DeclaratorChunk::Array: |
928 | if (Chunk.Arr.NumElts && |
929 | Chunk.Arr.NumElts->containsUnexpandedParameterPack()) |
930 | return true; |
931 | break; |
932 | case DeclaratorChunk::Function: |
933 | for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { |
934 | ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); |
935 | QualType ParamTy = Param->getType(); |
936 | assert(!ParamTy.isNull() && "Couldn't parse type?"); |
937 | if (ParamTy->containsUnexpandedParameterPack()) return true; |
938 | } |
939 | |
940 | if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) { |
941 | for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) { |
942 | if (Chunk.Fun.Exceptions[i] |
943 | .Ty.get() |
944 | ->containsUnexpandedParameterPack()) |
945 | return true; |
946 | } |
947 | } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) && |
948 | Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack()) |
949 | return true; |
950 | |
951 | if (Chunk.Fun.hasTrailingReturnType()) { |
952 | QualType T = Chunk.Fun.getTrailingReturnType().get(); |
953 | if (!T.isNull() && T->containsUnexpandedParameterPack()) |
954 | return true; |
955 | } |
956 | break; |
957 | |
958 | case DeclaratorChunk::MemberPointer: |
959 | if (Chunk.Mem.Scope().getScopeRep() && |
960 | Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) |
961 | return true; |
962 | break; |
963 | } |
964 | } |
965 | |
966 | if (Expr *TRC = D.getTrailingRequiresClause()) |
967 | if (TRC->containsUnexpandedParameterPack()) |
968 | return true; |
969 | |
970 | return false; |
971 | } |
972 | |
973 | namespace { |
974 | |
975 | |
976 | class ParameterPackValidatorCCC final : public CorrectionCandidateCallback { |
977 | public: |
978 | bool ValidateCandidate(const TypoCorrection &candidate) override { |
979 | NamedDecl *ND = candidate.getCorrectionDecl(); |
980 | return ND && ND->isParameterPack(); |
981 | } |
982 | |
983 | std::unique_ptr<CorrectionCandidateCallback> clone() override { |
984 | return std::make_unique<ParameterPackValidatorCCC>(*this); |
985 | } |
986 | }; |
987 | |
988 | } |
989 | |
990 | |
991 | |
992 | |
993 | |
994 | |
995 | |
996 | |
997 | |
998 | |
999 | |
1000 | |
1001 | |
1002 | |
1003 | |
1004 | ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, |
1005 | SourceLocation OpLoc, |
1006 | IdentifierInfo &Name, |
1007 | SourceLocation NameLoc, |
1008 | SourceLocation RParenLoc) { |
1009 | |
1010 | |
1011 | LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); |
1012 | LookupName(R, S); |
1013 | |
1014 | NamedDecl *ParameterPack = nullptr; |
1015 | switch (R.getResultKind()) { |
1016 | case LookupResult::Found: |
1017 | ParameterPack = R.getFoundDecl(); |
1018 | break; |
1019 | |
1020 | case LookupResult::NotFound: |
1021 | case LookupResult::NotFoundInCurrentInstantiation: { |
1022 | ParameterPackValidatorCCC CCC{}; |
1023 | if (TypoCorrection Corrected = |
1024 | CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr, |
1025 | CCC, CTK_ErrorRecovery)) { |
1026 | diagnoseTypo(Corrected, |
1027 | PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, |
1028 | PDiag(diag::note_parameter_pack_here)); |
1029 | ParameterPack = Corrected.getCorrectionDecl(); |
1030 | } |
1031 | break; |
1032 | } |
1033 | case LookupResult::FoundOverloaded: |
1034 | case LookupResult::FoundUnresolvedValue: |
1035 | break; |
1036 | |
1037 | case LookupResult::Ambiguous: |
1038 | DiagnoseAmbiguousLookup(R); |
1039 | return ExprError(); |
1040 | } |
1041 | |
1042 | if (!ParameterPack || !ParameterPack->isParameterPack()) { |
1043 | Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) |
1044 | << &Name; |
1045 | return ExprError(); |
1046 | } |
1047 | |
1048 | MarkAnyDeclReferenced(OpLoc, ParameterPack, true); |
1049 | |
1050 | return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc, |
1051 | RParenLoc); |
1052 | } |
1053 | |
1054 | TemplateArgumentLoc |
1055 | Sema::getTemplateArgumentPackExpansionPattern( |
1056 | TemplateArgumentLoc OrigLoc, |
1057 | SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { |
1058 | const TemplateArgument &Argument = OrigLoc.getArgument(); |
1059 | assert(Argument.isPackExpansion()); |
1060 | switch (Argument.getKind()) { |
1061 | case TemplateArgument::Type: { |
1062 | |
1063 | |
1064 | TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo(); |
1065 | if (!ExpansionTSInfo) |
1066 | ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(), |
1067 | Ellipsis); |
1068 | PackExpansionTypeLoc Expansion = |
1069 | ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>(); |
1070 | Ellipsis = Expansion.getEllipsisLoc(); |
1071 | |
1072 | TypeLoc Pattern = Expansion.getPatternLoc(); |
1073 | NumExpansions = Expansion.getTypePtr()->getNumExpansions(); |
1074 | |
1075 | |
1076 | |
1077 | |
1078 | TypeLocBuilder TLB; |
1079 | TLB.pushFullCopy(Pattern); |
1080 | TypeSourceInfo *PatternTSInfo = |
1081 | TLB.getTypeSourceInfo(Context, Pattern.getType()); |
1082 | return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), |
1083 | PatternTSInfo); |
1084 | } |
1085 | |
1086 | case TemplateArgument::Expression: { |
1087 | PackExpansionExpr *Expansion |
1088 | = cast<PackExpansionExpr>(Argument.getAsExpr()); |
1089 | Expr *Pattern = Expansion->getPattern(); |
1090 | Ellipsis = Expansion->getEllipsisLoc(); |
1091 | NumExpansions = Expansion->getNumExpansions(); |
1092 | return TemplateArgumentLoc(Pattern, Pattern); |
1093 | } |
1094 | |
1095 | case TemplateArgument::TemplateExpansion: |
1096 | Ellipsis = OrigLoc.getTemplateEllipsisLoc(); |
1097 | NumExpansions = Argument.getNumTemplateExpansions(); |
1098 | return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(), |
1099 | OrigLoc.getTemplateQualifierLoc(), |
1100 | OrigLoc.getTemplateNameLoc()); |
1101 | |
1102 | case TemplateArgument::Declaration: |
1103 | case TemplateArgument::NullPtr: |
1104 | case TemplateArgument::Template: |
1105 | case TemplateArgument::Integral: |
1106 | case TemplateArgument::Pack: |
1107 | case TemplateArgument::Null: |
1108 | return TemplateArgumentLoc(); |
1109 | } |
1110 | |
1111 | llvm_unreachable("Invalid TemplateArgument Kind!"); |
1112 | } |
1113 | |
1114 | Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { |
1115 | assert(Arg.containsUnexpandedParameterPack()); |
1116 | |
1117 | |
1118 | |
1119 | |
1120 | |
1121 | |
1122 | TemplateArgument Pack; |
1123 | switch (Arg.getKind()) { |
1124 | case TemplateArgument::Type: |
1125 | if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>()) |
1126 | Pack = Subst->getArgumentPack(); |
1127 | else |
1128 | return None; |
1129 | break; |
1130 | |
1131 | case TemplateArgument::Expression: |
1132 | if (auto *Subst = |
1133 | dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr())) |
1134 | Pack = Subst->getArgumentPack(); |
1135 | else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) { |
1136 | for (VarDecl *PD : *Subst) |
1137 | if (PD->isParameterPack()) |
1138 | return None; |
1139 | return Subst->getNumExpansions(); |
1140 | } else |
1141 | return None; |
1142 | break; |
1143 | |
1144 | case TemplateArgument::Template: |
1145 | if (SubstTemplateTemplateParmPackStorage *Subst = |
1146 | Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack()) |
1147 | Pack = Subst->getArgumentPack(); |
1148 | else |
1149 | return None; |
1150 | break; |
1151 | |
1152 | case TemplateArgument::Declaration: |
1153 | case TemplateArgument::NullPtr: |
1154 | case TemplateArgument::TemplateExpansion: |
1155 | case TemplateArgument::Integral: |
1156 | case TemplateArgument::Pack: |
1157 | case TemplateArgument::Null: |
1158 | return None; |
1159 | } |
1160 | |
1161 | |
1162 | for (TemplateArgument Elem : Pack.pack_elements()) { |
1163 | |
1164 | |
1165 | if (Elem.isPackExpansion()) |
1166 | return None; |
1167 | } |
1168 | return Pack.pack_size(); |
1169 | } |
1170 | |
1171 | static void CheckFoldOperand(Sema &S, Expr *E) { |
1172 | if (!E) |
1173 | return; |
1174 | |
1175 | E = E->IgnoreImpCasts(); |
1176 | auto *OCE = dyn_cast<CXXOperatorCallExpr>(E); |
1177 | if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) || |
1178 | isa<AbstractConditionalOperator>(E)) { |
1179 | S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand) |
1180 | << E->getSourceRange() |
1181 | << FixItHint::CreateInsertion(E->getBeginLoc(), "(") |
1182 | << FixItHint::CreateInsertion(E->getEndLoc(), ")"); |
1183 | } |
1184 | } |
1185 | |
1186 | ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, |
1187 | tok::TokenKind Operator, |
1188 | SourceLocation EllipsisLoc, Expr *RHS, |
1189 | SourceLocation RParenLoc) { |
1190 | |
1191 | |
1192 | CheckFoldOperand(*this, LHS); |
1193 | CheckFoldOperand(*this, RHS); |
1194 | |
1195 | auto DiscardOperands = [&] { |
1196 | CorrectDelayedTyposInExpr(LHS); |
1197 | CorrectDelayedTyposInExpr(RHS); |
1198 | }; |
1199 | |
1200 | |
1201 | |
1202 | |
1203 | |
1204 | if (LHS && RHS && |
1205 | LHS->containsUnexpandedParameterPack() == |
1206 | RHS->containsUnexpandedParameterPack()) { |
1207 | DiscardOperands(); |
1208 | return Diag(EllipsisLoc, |
1209 | LHS->containsUnexpandedParameterPack() |
1210 | ? diag::err_fold_expression_packs_both_sides |
1211 | : diag::err_pack_expansion_without_parameter_packs) |
1212 | << LHS->getSourceRange() << RHS->getSourceRange(); |
1213 | } |
1214 | |
1215 | |
1216 | |
1217 | |
1218 | if (!LHS || !RHS) { |
1219 | Expr *Pack = LHS ? LHS : RHS; |
1220 | assert(Pack && "fold expression with neither LHS nor RHS"); |
1221 | DiscardOperands(); |
1222 | if (!Pack->containsUnexpandedParameterPack()) |
1223 | return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) |
1224 | << Pack->getSourceRange(); |
1225 | } |
1226 | |
1227 | BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator); |
1228 | |
1229 | |
1230 | UnresolvedLookupExpr *ULE = nullptr; |
1231 | { |
1232 | UnresolvedSet<16> Functions; |
1233 | LookupBinOp(S, EllipsisLoc, Opc, Functions); |
1234 | if (!Functions.empty()) { |
1235 | DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName( |
1236 | BinaryOperator::getOverloadedOperator(Opc)); |
1237 | ExprResult Callee = CreateUnresolvedLookupExpr( |
1238 | nullptr, NestedNameSpecifierLoc(), |
1239 | DeclarationNameInfo(OpName, EllipsisLoc), Functions); |
1240 | if (Callee.isInvalid()) |
1241 | return ExprError(); |
1242 | ULE = cast<UnresolvedLookupExpr>(Callee.get()); |
1243 | } |
1244 | } |
1245 | |
1246 | return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc, |
1247 | None); |
1248 | } |
1249 | |
1250 | ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, |
1251 | SourceLocation LParenLoc, Expr *LHS, |
1252 | BinaryOperatorKind Operator, |
1253 | SourceLocation EllipsisLoc, Expr *RHS, |
1254 | SourceLocation RParenLoc, |
1255 | Optional<unsigned> NumExpansions) { |
1256 | return new (Context) |
1257 | CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator, |
1258 | EllipsisLoc, RHS, RParenLoc, NumExpansions); |
1259 | } |
1260 | |
1261 | ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, |
1262 | BinaryOperatorKind Operator) { |
1263 | |
1264 | |
1265 | |
1266 | |
1267 | |
1268 | |
1269 | |
1270 | |
1271 | |
1272 | QualType ScalarType; |
1273 | switch (Operator) { |
1274 | case BO_LOr: |
1275 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false); |
1276 | case BO_LAnd: |
1277 | return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true); |
1278 | case BO_Comma: |
1279 | ScalarType = Context.VoidTy; |
1280 | break; |
1281 | |
1282 | default: |
1283 | return Diag(EllipsisLoc, diag::err_fold_expression_empty) |
1284 | << BinaryOperator::getOpcodeStr(Operator); |
1285 | } |
1286 | |
1287 | return new (Context) CXXScalarValueInitExpr( |
1288 | ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc), |
1289 | EllipsisLoc); |
1290 | } |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | #ifndef LLVM_CLANG_SEMA_TEMPLATE_H |
13 | #define LLVM_CLANG_SEMA_TEMPLATE_H |
14 | |
15 | #include "clang/AST/DeclTemplate.h" |
16 | #include "clang/AST/DeclVisitor.h" |
17 | #include "clang/AST/TemplateBase.h" |
18 | #include "clang/AST/Type.h" |
19 | #include "clang/Basic/LLVM.h" |
20 | #include "clang/Sema/Sema.h" |
21 | #include "llvm/ADT/ArrayRef.h" |
22 | #include "llvm/ADT/DenseMap.h" |
23 | #include "llvm/ADT/PointerUnion.h" |
24 | #include "llvm/ADT/SmallVector.h" |
25 | #include <cassert> |
26 | #include <utility> |
27 | |
28 | namespace clang { |
29 | |
30 | class ASTContext; |
31 | class BindingDecl; |
32 | class CXXMethodDecl; |
33 | class Decl; |
34 | class DeclaratorDecl; |
35 | class DeclContext; |
36 | class EnumDecl; |
37 | class FunctionDecl; |
38 | class NamedDecl; |
39 | class ParmVarDecl; |
40 | class TagDecl; |
41 | class TypedefNameDecl; |
42 | class TypeSourceInfo; |
43 | class VarDecl; |
44 | |
45 | |
46 | enum class TemplateSubstitutionKind : char { |
47 | |
48 | |
49 | Specialization, |
50 | |
51 | |
52 | |
53 | Rewrite, |
54 | }; |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | class MultiLevelTemplateArgumentList { |
76 | |
77 | using ArgList = ArrayRef<TemplateArgument>; |
78 | |
79 | |
80 | |
81 | SmallVector<ArgList, 4> TemplateArgumentLists; |
82 | |
83 | |
84 | |
85 | unsigned NumRetainedOuterLevels = 0; |
86 | |
87 | |
88 | TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; |
89 | |
90 | public: |
91 | |
92 | MultiLevelTemplateArgumentList() = default; |
93 | |
94 | |
95 | explicit |
96 | MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { |
97 | addOuterTemplateArguments(&TemplateArgs); |
98 | } |
99 | |
100 | void setKind(TemplateSubstitutionKind K) { Kind = K; } |
101 | |
102 | |
103 | TemplateSubstitutionKind getKind() const { return Kind; } |
104 | |
105 | |
106 | |
107 | |
108 | bool isRewrite() const { |
109 | return Kind == TemplateSubstitutionKind::Rewrite; |
110 | } |
111 | |
112 | |
113 | |
114 | unsigned getNumLevels() const { |
115 | return TemplateArgumentLists.size() + NumRetainedOuterLevels; |
116 | } |
117 | |
118 | |
119 | |
120 | unsigned getNumSubstitutedLevels() const { |
121 | return TemplateArgumentLists.size(); |
122 | } |
123 | |
124 | unsigned getNumRetainedOuterLevels() const { |
125 | return NumRetainedOuterLevels; |
126 | } |
127 | |
128 | |
129 | |
130 | unsigned getNewDepth(unsigned OldDepth) const { |
131 | if (OldDepth < NumRetainedOuterLevels) |
132 | return OldDepth; |
133 | if (OldDepth < getNumLevels()) |
134 | return NumRetainedOuterLevels; |
135 | return OldDepth - TemplateArgumentLists.size(); |
136 | } |
137 | |
138 | |
139 | const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { |
140 | assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); |
141 | assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); |
142 | return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; |
143 | } |
144 | |
145 | |
146 | |
147 | |
148 | |
149 | bool hasTemplateArgument(unsigned Depth, unsigned Index) const { |
150 | assert(Depth < getNumLevels()); |
151 | |
152 | if (Depth < NumRetainedOuterLevels) |
| 9 | | Assuming 'Depth' is >= field 'NumRetainedOuterLevels' | |
|
| |
153 | return false; |
154 | |
155 | if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) |
| 11 | | Assuming the condition is false | |
|
| |
156 | return false; |
157 | |
158 | return !(*this)(Depth, Index).isNull(); |
| 13 | | Calling 'TemplateArgument::isNull' | |
|
| 16 | | Returning from 'TemplateArgument::isNull' | |
|
| 17 | | Returning the value 1, which participates in a condition later | |
|
159 | } |
160 | |
161 | |
162 | void setArgument(unsigned Depth, unsigned Index, |
163 | TemplateArgument Arg) { |
164 | assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); |
165 | assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); |
166 | const_cast<TemplateArgument&>( |
167 | TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) |
168 | = Arg; |
169 | } |
170 | |
171 | |
172 | |
173 | void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { |
174 | addOuterTemplateArguments(ArgList(TemplateArgs->data(), |
175 | TemplateArgs->size())); |
176 | } |
177 | |
178 | |
179 | |
180 | void addOuterTemplateArguments(ArgList Args) { |
181 | assert(!NumRetainedOuterLevels && |
182 | "substituted args outside retained args?"); |
183 | TemplateArgumentLists.push_back(Args); |
184 | } |
185 | |
186 | |
187 | |
188 | |
189 | void addOuterRetainedLevel() { |
190 | ++NumRetainedOuterLevels; |
191 | } |
192 | void addOuterRetainedLevels(unsigned Num) { |
193 | NumRetainedOuterLevels += Num; |
194 | } |
195 | |
196 | |
197 | const ArgList &getInnermost() const { |
198 | return TemplateArgumentLists.front(); |
199 | } |
200 | }; |
201 | |
202 | |
203 | enum TPOC { |
204 | |
205 | TPOC_Call, |
206 | |
207 | |
208 | |
209 | TPOC_Conversion, |
210 | |
211 | |
212 | |
213 | |
214 | TPOC_Other |
215 | }; |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | class TemplatePartialOrderingContext { |
222 | TPOC Value; |
223 | |
224 | public: |
225 | TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} |
226 | |
227 | operator TPOC() const { return Value; } |
228 | }; |
229 | |
230 | |
231 | |
232 | class DeducedTemplateArgument : public TemplateArgument { |
233 | |
234 | |
235 | bool DeducedFromArrayBound = false; |
236 | |
237 | public: |
238 | DeducedTemplateArgument() = default; |
239 | |
240 | DeducedTemplateArgument(const TemplateArgument &Arg, |
241 | bool DeducedFromArrayBound = false) |
242 | : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} |
243 | |
244 | |
245 | |
246 | DeducedTemplateArgument(ASTContext &Ctx, |
247 | const llvm::APSInt &Value, |
248 | QualType ValueType, |
249 | bool DeducedFromArrayBound) |
250 | : TemplateArgument(Ctx, Value, ValueType), |
251 | DeducedFromArrayBound(DeducedFromArrayBound) {} |
252 | |
253 | |
254 | |
255 | bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } |
256 | |
257 | |
258 | |
259 | void setDeducedFromArrayBound(bool Deduced) { |
260 | DeducedFromArrayBound = Deduced; |
261 | } |
262 | }; |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | class LocalInstantiationScope { |
271 | public: |
272 | |
273 | using DeclArgumentPack = SmallVector<VarDecl *, 4>; |
274 | |
275 | private: |
276 | |
277 | |
278 | Sema &SemaRef; |
279 | |
280 | using LocalDeclsMap = |
281 | llvm::SmallDenseMap<const Decl *, |
282 | llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>; |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
301 | |
302 | LocalDeclsMap LocalDecls; |
303 | |
304 | |
305 | SmallVector<DeclArgumentPack *, 1> ArgumentPacks; |
306 | |
307 | |
308 | |
309 | |
310 | LocalInstantiationScope *Outer; |
311 | |
312 | |
313 | bool Exited = false; |
314 | |
315 | |
316 | |
317 | bool CombineWithOuterScope; |
318 | |
319 | |
320 | |
321 | NamedDecl *PartiallySubstitutedPack = nullptr; |
322 | |
323 | |
324 | |
325 | const TemplateArgument *ArgsInPartiallySubstitutedPack; |
326 | |
327 | |
328 | |
329 | |
330 | unsigned NumArgsInPartiallySubstitutedPack; |
331 | |
332 | public: |
333 | LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) |
334 | : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), |
335 | CombineWithOuterScope(CombineWithOuterScope) { |
336 | SemaRef.CurrentInstantiationScope = this; |
337 | } |
338 | |
339 | LocalInstantiationScope(const LocalInstantiationScope &) = delete; |
340 | LocalInstantiationScope & |
341 | operator=(const LocalInstantiationScope &) = delete; |
342 | |
343 | ~LocalInstantiationScope() { |
344 | Exit(); |
345 | } |
346 | |
347 | const Sema &getSema() const { return SemaRef; } |
348 | |
349 | |
350 | void Exit() { |
351 | if (Exited) |
352 | return; |
353 | |
354 | for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) |
355 | delete ArgumentPacks[I]; |
356 | |
357 | SemaRef.CurrentInstantiationScope = Outer; |
358 | Exited = true; |
359 | } |
360 | |
361 | |
362 | |
363 | LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { |
364 | if (this == Outermost) return this; |
365 | |
366 | |
367 | |
368 | LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; |
369 | |
370 | LocalInstantiationScope *newScope = |
371 | new LocalInstantiationScope(SemaRef, CombineWithOuterScope); |
372 | |
373 | newScope->Outer = nullptr; |
374 | if (Outer) |
375 | newScope->Outer = Outer->cloneScopes(Outermost); |
376 | |
377 | newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; |
378 | newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; |
379 | newScope->NumArgsInPartiallySubstitutedPack = |
380 | NumArgsInPartiallySubstitutedPack; |
381 | |
382 | for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); |
383 | I != E; ++I) { |
384 | const Decl *D = I->first; |
385 | llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = |
386 | newScope->LocalDecls[D]; |
387 | if (I->second.is<Decl *>()) { |
388 | Stored = I->second.get<Decl *>(); |
389 | } else { |
390 | DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); |
391 | DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); |
392 | Stored = NewPack; |
393 | newScope->ArgumentPacks.push_back(NewPack); |
394 | } |
395 | } |
396 | |
397 | SemaRef.CurrentInstantiationScope = oldScope; |
398 | return newScope; |
399 | } |
400 | |
401 | |
402 | |
403 | static void deleteScopes(LocalInstantiationScope *Scope, |
404 | LocalInstantiationScope *Outermost) { |
405 | while (Scope && Scope != Outermost) { |
406 | LocalInstantiationScope *Out = Scope->Outer; |
407 | delete Scope; |
408 | Scope = Out; |
409 | } |
410 | } |
411 | |
412 | |
413 | |
414 | |
415 | |
416 | |
417 | |
418 | |
419 | |
420 | llvm::PointerUnion<Decl *, DeclArgumentPack *> * |
421 | findInstantiationOf(const Decl *D); |
422 | |
423 | void InstantiatedLocal(const Decl *D, Decl *Inst); |
424 | void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); |
425 | void MakeInstantiatedLocalArgPack(const Decl *D); |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | void SetPartiallySubstitutedPack(NamedDecl *Pack, |
440 | const TemplateArgument *ExplicitArgs, |
441 | unsigned NumExplicitArgs); |
442 | |
443 | |
444 | |
445 | void ResetPartiallySubstitutedPack() { |
446 | assert(PartiallySubstitutedPack && "No partially-substituted pack"); |
447 | PartiallySubstitutedPack = nullptr; |
448 | ArgsInPartiallySubstitutedPack = nullptr; |
449 | NumArgsInPartiallySubstitutedPack = 0; |
450 | } |
451 | |
452 | |
453 | |
454 | |
455 | NamedDecl * |
456 | getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, |
457 | unsigned *NumExplicitArgs = nullptr) const; |
458 | |
459 | |
460 | bool isLocalPackExpansion(const Decl *D); |
461 | }; |
462 | |
463 | class TemplateDeclInstantiator |
464 | : public DeclVisitor<TemplateDeclInstantiator, Decl *> |
465 | { |
466 | Sema &SemaRef; |
467 | Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; |
468 | DeclContext *Owner; |
469 | const MultiLevelTemplateArgumentList &TemplateArgs; |
470 | Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; |
471 | LocalInstantiationScope *StartingScope = nullptr; |
472 | |
473 | |
474 | |
475 | |
476 | SmallVector<std::pair<ClassTemplateDecl *, |
477 | ClassTemplatePartialSpecializationDecl *>, 4> |
478 | OutOfLinePartialSpecs; |
479 | |
480 | |
481 | |
482 | |
483 | |
484 | SmallVector< |
485 | std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> |
486 | OutOfLineVarPartialSpecs; |
487 | |
488 | public: |
489 | TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, |
490 | const MultiLevelTemplateArgumentList &TemplateArgs) |
491 | : SemaRef(SemaRef), |
492 | SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), |
493 | Owner(Owner), TemplateArgs(TemplateArgs) {} |
494 | |
495 | |
496 | #define DECL(DERIVED, BASE) \ |
497 | Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); |
498 | #define ABSTRACT_DECL(DECL) |
499 | |
500 | |
501 | #define OBJCCONTAINER(DERIVED, BASE) |
502 | #define FILESCOPEASM(DERIVED, BASE) |
503 | #define IMPORT(DERIVED, BASE) |
504 | #define EXPORT(DERIVED, BASE) |
505 | #define LINKAGESPEC(DERIVED, BASE) |
506 | #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) |
507 | #define OBJCMETHOD(DERIVED, BASE) |
508 | #define OBJCTYPEPARAM(DERIVED, BASE) |
509 | #define OBJCIVAR(DERIVED, BASE) |
510 | #define OBJCPROPERTY(DERIVED, BASE) |
511 | #define OBJCPROPERTYIMPL(DERIVED, BASE) |
512 | #define EMPTY(DERIVED, BASE) |
513 | #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) |
514 | |
515 | |
516 | #define BLOCK(DERIVED, BASE) |
517 | #define CAPTURED(DERIVED, BASE) |
518 | #define IMPLICITPARAM(DERIVED, BASE) |
519 | |
520 | #include "clang/AST/DeclNodes.inc" |
521 | |
522 | enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; |
523 | |
524 | void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, |
525 | TypeSourceInfo *&TInfo, |
526 | DeclarationNameInfo &NameInfo); |
527 | |
528 | |
529 | Decl *VisitCXXMethodDecl(CXXMethodDecl *D, |
530 | TemplateParameterList *TemplateParams, |
531 | Optional<const ASTTemplateArgumentListInfo *> |
532 | ClassScopeSpecializationArgs = llvm::None, |
533 | RewriteKind RK = RewriteKind::None); |
534 | Decl *VisitFunctionDecl(FunctionDecl *D, |
535 | TemplateParameterList *TemplateParams, |
536 | RewriteKind RK = RewriteKind::None); |
537 | Decl *VisitDecl(Decl *D); |
538 | Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, |
539 | ArrayRef<BindingDecl *> *Bindings = nullptr); |
540 | Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, |
541 | LookupResult *Lookup); |
542 | |
543 | |
544 | |
545 | void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { |
546 | LateAttrs = LA; |
547 | StartingScope = SemaRef.CurrentInstantiationScope; |
548 | } |
549 | |
550 | |
551 | void disableLateAttributeInstantiation() { |
552 | LateAttrs = nullptr; |
553 | StartingScope = nullptr; |
554 | } |
555 | |
556 | LocalInstantiationScope *getStartingScope() const { return StartingScope; } |
557 | |
558 | using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< |
559 | ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; |
560 | |
561 | using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< |
562 | VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; |
563 | |
564 | |
565 | |
566 | |
567 | |
568 | delayed_partial_spec_iterator delayed_partial_spec_begin() { |
569 | return OutOfLinePartialSpecs.begin(); |
570 | } |
571 | |
572 | delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { |
573 | return OutOfLineVarPartialSpecs.begin(); |
574 | } |
575 | |
576 | |
577 | |
578 | |
579 | |
580 | delayed_partial_spec_iterator delayed_partial_spec_end() { |
581 | return OutOfLinePartialSpecs.end(); |
582 | } |
583 | |
584 | delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { |
585 | return OutOfLineVarPartialSpecs.end(); |
586 | } |
587 | |
588 | |
589 | TypeSourceInfo *SubstFunctionType(FunctionDecl *D, |
590 | SmallVectorImpl<ParmVarDecl *> &Params); |
591 | bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); |
592 | bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); |
593 | |
594 | bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); |
595 | |
596 | TemplateParameterList * |
597 | SubstTemplateParams(TemplateParameterList *List); |
598 | |
599 | bool SubstQualifier(const DeclaratorDecl *OldDecl, |
600 | DeclaratorDecl *NewDecl); |
601 | bool SubstQualifier(const TagDecl *OldDecl, |
602 | TagDecl *NewDecl); |
603 | |
604 | Decl *VisitVarTemplateSpecializationDecl( |
605 | VarTemplateDecl *VarTemplate, VarDecl *FromVar, |
606 | const TemplateArgumentListInfo &TemplateArgsInfo, |
607 | ArrayRef<TemplateArgument> Converted, |
608 | VarTemplateSpecializationDecl *PrevDecl = nullptr); |
609 | |
610 | Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); |
611 | ClassTemplatePartialSpecializationDecl * |
612 | InstantiateClassTemplatePartialSpecialization( |
613 | ClassTemplateDecl *ClassTemplate, |
614 | ClassTemplatePartialSpecializationDecl *PartialSpec); |
615 | VarTemplatePartialSpecializationDecl * |
616 | InstantiateVarTemplatePartialSpecialization( |
617 | VarTemplateDecl *VarTemplate, |
618 | VarTemplatePartialSpecializationDecl *PartialSpec); |
619 | void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); |
620 | |
621 | private: |
622 | template<typename T> |
623 | Decl *instantiateUnresolvedUsingDecl(T *D, |
624 | bool InstantiatingPackElement = false); |
625 | }; |
626 | |
627 | } |
628 | |
629 | #endif // LLVM_CLANG_SEMA_TEMPLATE_H |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H |
15 | #define LLVM_CLANG_AST_TEMPLATEBASE_H |
16 | |
17 | #include "clang/AST/DependenceFlags.h" |
18 | #include "clang/AST/NestedNameSpecifier.h" |
19 | #include "clang/AST/TemplateName.h" |
20 | #include "clang/AST/Type.h" |
21 | #include "clang/Basic/LLVM.h" |
22 | #include "clang/Basic/SourceLocation.h" |
23 | #include "llvm/ADT/APInt.h" |
24 | #include "llvm/ADT/APSInt.h" |
25 | #include "llvm/ADT/ArrayRef.h" |
26 | #include "llvm/ADT/None.h" |
27 | #include "llvm/ADT/Optional.h" |
28 | #include "llvm/ADT/SmallVector.h" |
29 | #include "llvm/Support/Compiler.h" |
30 | #include "llvm/Support/TrailingObjects.h" |
31 | #include <cassert> |
32 | #include <cstddef> |
33 | #include <cstdint> |
34 | |
35 | namespace llvm { |
36 | |
37 | class FoldingSetNodeID; |
38 | |
39 | |
40 | |
41 | |
42 | template <> struct PointerLikeTypeTraits<clang::Expr *> { |
43 | static inline void *getAsVoidPointer(clang::Expr *P) { return P; } |
44 | static inline clang::Expr *getFromVoidPointer(void *P) { |
45 | return static_cast<clang::Expr *>(P); |
46 | } |
47 | static constexpr int NumLowBitsAvailable = 2; |
48 | }; |
49 | |
50 | } |
51 | |
52 | namespace clang { |
53 | |
54 | class ASTContext; |
55 | class DiagnosticBuilder; |
56 | class Expr; |
57 | struct PrintingPolicy; |
58 | class TypeSourceInfo; |
59 | class ValueDecl; |
60 | |
61 | |
62 | class TemplateArgument { |
63 | public: |
64 | |
65 | enum ArgKind { |
66 | |
67 | |
68 | Null = 0, |
69 | |
70 | |
71 | Type, |
72 | |
73 | |
74 | |
75 | Declaration, |
76 | |
77 | |
78 | |
79 | NullPtr, |
80 | |
81 | |
82 | |
83 | Integral, |
84 | |
85 | |
86 | |
87 | Template, |
88 | |
89 | |
90 | |
91 | TemplateExpansion, |
92 | |
93 | |
94 | |
95 | |
96 | |
97 | Expression, |
98 | |
99 | |
100 | |
101 | Pack |
102 | }; |
103 | |
104 | private: |
105 | |
106 | |
107 | struct DA { |
108 | unsigned Kind; |
109 | void *QT; |
110 | ValueDecl *D; |
111 | }; |
112 | struct I { |
113 | unsigned Kind; |
114 | |
115 | |
116 | |
117 | unsigned BitWidth : 31; |
118 | unsigned IsUnsigned : 1; |
119 | union { |
120 | |
121 | uint64_t VAL; |
122 | |
123 | |
124 | const uint64_t *pVal; |
125 | }; |
126 | void *Type; |
127 | }; |
128 | struct A { |
129 | unsigned Kind; |
130 | unsigned NumArgs; |
131 | const TemplateArgument *Args; |
132 | }; |
133 | struct TA { |
134 | unsigned Kind; |
135 | unsigned NumExpansions; |
136 | void *Name; |
137 | }; |
138 | struct TV { |
139 | unsigned Kind; |
140 | uintptr_t V; |
141 | }; |
142 | union { |
143 | struct DA DeclArg; |
144 | struct I Integer; |
145 | struct A Args; |
146 | struct TA TemplateArg; |
147 | struct TV TypeOrValue; |
148 | }; |
149 | |
150 | public: |
151 | |
152 | constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} |
153 | |
154 | |
155 | TemplateArgument(QualType T, bool isNullPtr = false) { |
156 | TypeOrValue.Kind = isNullPtr ? NullPtr : Type; |
157 | TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); |
158 | } |
159 | |
160 | |
161 | |
162 | |
163 | TemplateArgument(ValueDecl *D, QualType QT) { |
164 | assert(D && "Expected decl"); |
165 | DeclArg.Kind = Declaration; |
166 | DeclArg.QT = QT.getAsOpaquePtr(); |
167 | DeclArg.D = D; |
168 | } |
169 | |
170 | |
171 | |
172 | TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); |
173 | |
174 | |
175 | |
176 | TemplateArgument(const TemplateArgument &Other, QualType Type) { |
177 | Integer = Other.Integer; |
178 | Integer.Type = Type.getAsOpaquePtr(); |
179 | } |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | TemplateArgument(TemplateName Name) { |
190 | TemplateArg.Kind = Template; |
191 | TemplateArg.Name = Name.getAsVoidPointer(); |
192 | TemplateArg.NumExpansions = 0; |
193 | } |
194 | |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | |
201 | |
202 | |
203 | |
204 | |
205 | |
206 | TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { |
207 | TemplateArg.Kind = TemplateExpansion; |
208 | TemplateArg.Name = Name.getAsVoidPointer(); |
209 | if (NumExpansions) |
210 | TemplateArg.NumExpansions = *NumExpansions + 1; |
211 | else |
212 | TemplateArg.NumExpansions = 0; |
213 | } |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | TemplateArgument(Expr *E) { |
221 | TypeOrValue.Kind = Expression; |
222 | TypeOrValue.V = reinterpret_cast<uintptr_t>(E); |
223 | } |
224 | |
225 | |
226 | |
227 | |
228 | |
229 | explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { |
230 | this->Args.Kind = Pack; |
231 | this->Args.Args = Args.data(); |
232 | this->Args.NumArgs = Args.size(); |
233 | } |
234 | |
235 | TemplateArgument(TemplateName, bool) = delete; |
236 | |
237 | static TemplateArgument getEmptyPack() { return TemplateArgument(None); } |
238 | |
239 | |
240 | |
241 | static TemplateArgument CreatePackCopy(ASTContext &Context, |
242 | ArrayRef<TemplateArgument> Args); |
243 | |
244 | |
245 | ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } |
246 | |
247 | |
248 | bool isNull() const { return getKind() == Null; } |
| 14 | | Assuming the condition is false | |
|
| 15 | | Returning zero, which participates in a condition later | |
|
249 | |
250 | TemplateArgumentDependence getDependence() const; |
251 | |
252 | |
253 | |
254 | |
255 | bool isDependent() const; |
256 | |
257 | |
258 | |
259 | bool isInstantiationDependent() const; |
260 | |
261 | |
262 | |
263 | bool containsUnexpandedParameterPack() const; |
264 | |
265 | |
266 | bool isPackExpansion() const; |
267 | |
268 | |
269 | QualType getAsType() const { |
270 | assert(getKind() == Type && "Unexpected kind"); |
271 | return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); |
272 | } |
273 | |
274 | |
275 | |
276 | ValueDecl *getAsDecl() const { |
277 | assert(getKind() == Declaration && "Unexpected kind"); |
278 | return DeclArg.D; |
279 | } |
280 | |
281 | QualType getParamTypeForDecl() const { |
282 | assert(getKind() == Declaration && "Unexpected kind"); |
283 | return QualType::getFromOpaquePtr(DeclArg.QT); |
284 | } |
285 | |
286 | |
287 | QualType getNullPtrType() const { |
288 | assert(getKind() == NullPtr && "Unexpected kind"); |
289 | return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); |
290 | } |
291 | |
292 | |
293 | TemplateName getAsTemplate() const { |
294 | assert(getKind() == Template && "Unexpected kind"); |
295 | return TemplateName::getFromVoidPointer(TemplateArg.Name); |
296 | } |
297 | |
298 | |
299 | |
300 | TemplateName getAsTemplateOrTemplatePattern() const { |
301 | assert((getKind() == Template || getKind() == TemplateExpansion) && |
302 | "Unexpected kind"); |
303 | |
304 | return TemplateName::getFromVoidPointer(TemplateArg.Name); |
305 | } |
306 | |
307 | |
308 | |
309 | Optional<unsigned> getNumTemplateExpansions() const; |
310 | |
311 | |
312 | |
313 | llvm::APSInt getAsIntegral() const { |
314 | assert(getKind() == Integral && "Unexpected kind"); |
315 | |
316 | using namespace llvm; |
317 | |
318 | if (Integer.BitWidth <= 64) |
319 | return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); |
320 | |
321 | unsigned NumWords = APInt::getNumWords(Integer.BitWidth); |
322 | return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), |
323 | Integer.IsUnsigned); |
324 | } |
325 | |
326 | |
327 | QualType getIntegralType() const { |
328 | assert(getKind() == Integral && "Unexpected kind"); |
329 | return QualType::getFromOpaquePtr(Integer.Type); |
330 | } |
331 | |
332 | void setIntegralType(QualType T) { |
333 | assert(getKind() == Integral && "Unexpected kind"); |
334 | Integer.Type = T.getAsOpaquePtr(); |
335 | } |
336 | |
337 | |
338 | |
339 | QualType getNonTypeTemplateArgumentType() const; |
340 | |
341 | |
342 | Expr *getAsExpr() const { |
343 | assert(getKind() == Expression && "Unexpected kind"); |
344 | return reinterpret_cast<Expr *>(TypeOrValue.V); |
345 | } |
346 | |
347 | |
348 | using pack_iterator = const TemplateArgument *; |
349 | |
350 | |
351 | |
352 | pack_iterator pack_begin() const { |
353 | assert(getKind() == Pack); |
354 | return Args.Args; |
355 | } |
356 | |
357 | |
358 | |
359 | pack_iterator pack_end() const { |
360 | assert(getKind() == Pack); |
361 | return Args.Args + Args.NumArgs; |
362 | } |
363 | |
364 | |
365 | |
366 | ArrayRef<TemplateArgument> pack_elements() const { |
367 | return llvm::makeArrayRef(pack_begin(), pack_end()); |
368 | } |
369 | |
370 | |
371 | |
372 | unsigned pack_size() const { |
373 | assert(getKind() == Pack); |
374 | return Args.NumArgs; |
375 | } |
376 | |
377 | |
378 | ArrayRef<TemplateArgument> getPackAsArray() const { |
379 | assert(getKind() == Pack); |
380 | return llvm::makeArrayRef(Args.Args, Args.NumArgs); |
381 | } |
382 | |
383 | |
384 | |
385 | bool structurallyEquals(const TemplateArgument &Other) const; |
386 | |
387 | |
388 | |
389 | TemplateArgument getPackExpansionPattern() const; |
390 | |
391 | |
392 | void print(const PrintingPolicy &Policy, raw_ostream &Out, |
393 | bool IncludeType) const; |
394 | |
395 | |
396 | void dump(raw_ostream &Out) const; |
397 | |
398 | |
399 | void dump() const; |
400 | |
401 | |
402 | void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; |
403 | }; |
404 | |
405 | |
406 | struct TemplateArgumentLocInfo { |
407 | private: |
408 | struct TemplateTemplateArgLocInfo { |
409 | |
410 | |
411 | NestedNameSpecifier *Qualifier; |
412 | void *QualifierLocData; |
413 | SourceLocation TemplateNameLoc; |
414 | SourceLocation EllipsisLoc; |
415 | }; |
416 | |
417 | llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *> |
418 | Pointer; |
419 | |
420 | TemplateTemplateArgLocInfo *getTemplate() const { |
421 | return Pointer.get<TemplateTemplateArgLocInfo *>(); |
422 | } |
423 | |
424 | public: |
425 | TemplateArgumentLocInfo() {} |
426 | TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; } |
427 | |
428 | TemplateArgumentLocInfo(Expr *E) { Pointer = E; } |
429 | |
430 | |
431 | TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, |
432 | SourceLocation TemplateNameLoc, |
433 | SourceLocation EllipsisLoc); |
434 | |
435 | TypeSourceInfo *getAsTypeSourceInfo() const { |
436 | return Pointer.get<TypeSourceInfo *>(); |
437 | } |
438 | |
439 | Expr *getAsExpr() const { return Pointer.get<Expr *>(); } |
440 | |
441 | NestedNameSpecifierLoc getTemplateQualifierLoc() const { |
442 | const auto *Template = getTemplate(); |
443 | return NestedNameSpecifierLoc(Template->Qualifier, |
444 | Template->QualifierLocData); |
445 | } |
446 | |
447 | SourceLocation getTemplateNameLoc() const { |
448 | return getTemplate()->TemplateNameLoc; |
449 | } |
450 | |
451 | SourceLocation getTemplateEllipsisLoc() const { |
452 | return getTemplate()->EllipsisLoc; |
453 | } |
454 | }; |
455 | |
456 | |
457 | |
458 | class TemplateArgumentLoc { |
459 | TemplateArgument Argument; |
460 | TemplateArgumentLocInfo LocInfo; |
461 | |
462 | public: |
463 | TemplateArgumentLoc() {} |
464 | |
465 | TemplateArgumentLoc(const TemplateArgument &Argument, |
466 | TemplateArgumentLocInfo Opaque) |
467 | : Argument(Argument), LocInfo(Opaque) {} |
468 | |
469 | TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) |
470 | : Argument(Argument), LocInfo(TInfo) { |
471 | assert(Argument.getKind() == TemplateArgument::Type); |
472 | } |
473 | |
474 | TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) |
475 | : Argument(Argument), LocInfo(E) { |
476 | |
477 | |
478 | |
479 | assert(Argument.getKind() == TemplateArgument::NullPtr || |
480 | Argument.getKind() == TemplateArgument::Integral || |
481 | Argument.getKind() == TemplateArgument::Declaration || |
482 | Argument.getKind() == TemplateArgument::Expression); |
483 | } |
484 | |
485 | TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument, |
486 | NestedNameSpecifierLoc QualifierLoc, |
487 | SourceLocation TemplateNameLoc, |
488 | SourceLocation EllipsisLoc = SourceLocation()) |
489 | : Argument(Argument), |
490 | LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) { |
491 | assert(Argument.getKind() == TemplateArgument::Template || |
492 | Argument.getKind() == TemplateArgument::TemplateExpansion); |
493 | } |
494 | |
495 | |
496 | SourceLocation getLocation() const { |
497 | if (Argument.getKind() == TemplateArgument::Template || |
498 | Argument.getKind() == TemplateArgument::TemplateExpansion) |
499 | return getTemplateNameLoc(); |
500 | |
501 | return getSourceRange().getBegin(); |
502 | } |
503 | |
504 | |
505 | SourceRange getSourceRange() const LLVM_READONLY; |
506 | |
507 | const TemplateArgument &getArgument() const { |
508 | return Argument; |
509 | } |
510 | |
511 | TemplateArgumentLocInfo getLocInfo() const { |
512 | return LocInfo; |
513 | } |
514 | |
515 | TypeSourceInfo *getTypeSourceInfo() const { |
516 | if (Argument.getKind() != TemplateArgument::Type) |
517 | return nullptr; |
518 | return LocInfo.getAsTypeSourceInfo(); |
519 | } |
520 | |
521 | Expr *getSourceExpression() const { |
522 | assert(Argument.getKind() == TemplateArgument::Expression); |
523 | return LocInfo.getAsExpr(); |
524 | } |
525 | |
526 | Expr *getSourceDeclExpression() const { |
527 | assert(Argument.getKind() == TemplateArgument::Declaration); |
528 | return LocInfo.getAsExpr(); |
529 | } |
530 | |
531 | Expr *getSourceNullPtrExpression() const { |
532 | assert(Argument.getKind() == TemplateArgument::NullPtr); |
533 | return LocInfo.getAsExpr(); |
534 | } |
535 | |
536 | Expr *getSourceIntegralExpression() const { |
537 | assert(Argument.getKind() == TemplateArgument::Integral); |
538 | return LocInfo.getAsExpr(); |
539 | } |
540 | |
541 | NestedNameSpecifierLoc getTemplateQualifierLoc() const { |
542 | if (Argument.getKind() != TemplateArgument::Template && |
543 | Argument.getKind() != TemplateArgument::TemplateExpansion) |
544 | return NestedNameSpecifierLoc(); |
545 | return LocInfo.getTemplateQualifierLoc(); |
546 | } |
547 | |
548 | SourceLocation getTemplateNameLoc() const { |
549 | if (Argument.getKind() != TemplateArgument::Template && |
550 | Argument.getKind() != TemplateArgument::TemplateExpansion) |
551 | return SourceLocation(); |
552 | return LocInfo.getTemplateNameLoc(); |
553 | } |
554 | |
555 | SourceLocation getTemplateEllipsisLoc() const { |
556 | if (Argument.getKind() != TemplateArgument::TemplateExpansion) |
557 | return SourceLocation(); |
558 | return LocInfo.getTemplateEllipsisLoc(); |
559 | } |
560 | }; |
561 | |
562 | |
563 | |
564 | class TemplateArgumentListInfo { |
565 | SmallVector<TemplateArgumentLoc, 8> Arguments; |
566 | SourceLocation LAngleLoc; |
567 | SourceLocation RAngleLoc; |
568 | |
569 | public: |
570 | TemplateArgumentListInfo() = default; |
571 | |
572 | TemplateArgumentListInfo(SourceLocation LAngleLoc, |
573 | SourceLocation RAngleLoc) |
574 | : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} |
575 | |
576 | |
577 | |
578 | void *operator new(size_t bytes, ASTContext &C) = delete; |
579 | |
580 | SourceLocation getLAngleLoc() const { return LAngleLoc; } |
581 | SourceLocation getRAngleLoc() const { return RAngleLoc; } |
582 | |
583 | void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } |
584 | void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } |
585 | |
586 | unsigned size() const { return Arguments.size(); } |
587 | |
588 | const TemplateArgumentLoc *getArgumentArray() const { |
589 | return Arguments.data(); |
590 | } |
591 | |
592 | llvm::ArrayRef<TemplateArgumentLoc> arguments() const { |
593 | return Arguments; |
594 | } |
595 | |
596 | const TemplateArgumentLoc &operator[](unsigned I) const { |
597 | return Arguments[I]; |
598 | } |
599 | |
600 | TemplateArgumentLoc &operator[](unsigned I) { |
601 | return Arguments[I]; |
602 | } |
603 | |
604 | void addArgument(const TemplateArgumentLoc &Loc) { |
605 | Arguments.push_back(Loc); |
606 | } |
607 | }; |
608 | |
609 | |
610 | |
611 | |
612 | |
613 | struct ASTTemplateArgumentListInfo final |
614 | : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, |
615 | TemplateArgumentLoc> { |
616 | private: |
617 | friend class ASTNodeImporter; |
618 | friend TrailingObjects; |
619 | |
620 | ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); |
621 | |
622 | public: |
623 | |
624 | SourceLocation LAngleLoc; |
625 | |
626 | |
627 | SourceLocation RAngleLoc; |
628 | |
629 | |
630 | unsigned NumTemplateArgs; |
631 | |
632 | SourceLocation getLAngleLoc() const { return LAngleLoc; } |
633 | SourceLocation getRAngleLoc() const { return RAngleLoc; } |
634 | |
635 | |
636 | const TemplateArgumentLoc *getTemplateArgs() const { |
637 | return getTrailingObjects<TemplateArgumentLoc>(); |
638 | } |
639 | unsigned getNumTemplateArgs() const { return NumTemplateArgs; } |
640 | |
641 | llvm::ArrayRef<TemplateArgumentLoc> arguments() const { |
642 | return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs()); |
643 | } |
644 | |
645 | const TemplateArgumentLoc &operator[](unsigned I) const { |
646 | return getTemplateArgs()[I]; |
647 | } |
648 | |
649 | static const ASTTemplateArgumentListInfo * |
650 | Create(const ASTContext &C, const TemplateArgumentListInfo &List); |
651 | }; |
652 | |
653 | |
654 | |
655 | |
656 | |
657 | |
658 | |
659 | |
660 | struct alignas(void *) ASTTemplateKWAndArgsInfo { |
661 | |
662 | SourceLocation LAngleLoc; |
663 | |
664 | |
665 | SourceLocation RAngleLoc; |
666 | |
667 | |
668 | |
669 | |
670 | |
671 | SourceLocation TemplateKWLoc; |
672 | |
673 | |
674 | unsigned NumTemplateArgs; |
675 | |
676 | void initializeFrom(SourceLocation TemplateKWLoc, |
677 | const TemplateArgumentListInfo &List, |
678 | TemplateArgumentLoc *OutArgArray); |
679 | |
680 | |
681 | |
682 | void initializeFrom(SourceLocation TemplateKWLoc, |
683 | const TemplateArgumentListInfo &List, |
684 | TemplateArgumentLoc *OutArgArray, |
685 | TemplateArgumentDependence &Deps); |
686 | void initializeFrom(SourceLocation TemplateKWLoc); |
687 | |
688 | void copyInto(const TemplateArgumentLoc *ArgArray, |
689 | TemplateArgumentListInfo &List) const; |
690 | }; |
691 | |
692 | const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, |
693 | const TemplateArgument &Arg); |
694 | |
695 | inline TemplateSpecializationType::iterator |
696 | TemplateSpecializationType::end() const { |
697 | return getArgs() + getNumArgs(); |
698 | } |
699 | |
700 | inline DependentTemplateSpecializationType::iterator |
701 | DependentTemplateSpecializationType::end() const { |
702 | return getArgs() + getNumArgs(); |
703 | } |
704 | |
705 | inline const TemplateArgument & |
706 | TemplateSpecializationType::getArg(unsigned Idx) const { |
707 | assert(Idx < getNumArgs() && "Template argument out of range"); |
708 | return getArgs()[Idx]; |
709 | } |
710 | |
711 | inline const TemplateArgument & |
712 | DependentTemplateSpecializationType::getArg(unsigned Idx) const { |
713 | assert(Idx < getNumArgs() && "Template argument out of range"); |
714 | return getArgs()[Idx]; |
715 | } |
716 | |
717 | inline const TemplateArgument &AutoType::getArg(unsigned Idx) const { |
718 | assert(Idx < getNumArgs() && "Template argument out of range"); |
719 | return getArgs()[Idx]; |
720 | } |
721 | |
722 | } |
723 | |
724 | #endif // LLVM_CLANG_AST_TEMPLATEBASE_H |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifndef LLVM_ADT_POINTERUNION_H |
15 | #define LLVM_ADT_POINTERUNION_H |
16 | |
17 | #include "llvm/ADT/DenseMapInfo.h" |
18 | #include "llvm/ADT/PointerIntPair.h" |
19 | #include "llvm/Support/PointerLikeTypeTraits.h" |
20 | #include <cassert> |
21 | #include <cstddef> |
22 | #include <cstdint> |
23 | |
24 | namespace llvm { |
25 | |
26 | template <typename T> struct PointerUnionTypeSelectorReturn { |
27 | using Return = T; |
28 | }; |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | template <typename T1, typename T2, typename RET_EQ, typename RET_NE> |
40 | struct PointerUnionTypeSelector { |
41 | using Return = typename PointerUnionTypeSelectorReturn<RET_NE>::Return; |
42 | }; |
43 | |
44 | template <typename T, typename RET_EQ, typename RET_NE> |
45 | struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> { |
46 | using Return = typename PointerUnionTypeSelectorReturn<RET_EQ>::Return; |
47 | }; |
48 | |
49 | template <typename T1, typename T2, typename RET_EQ, typename RET_NE> |
50 | struct PointerUnionTypeSelectorReturn< |
51 | PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>> { |
52 | using Return = |
53 | typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return; |
54 | }; |
55 | |
56 | namespace pointer_union_detail { |
57 | |
58 | |
59 | constexpr int bitsRequired(unsigned n) { |
60 | return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; |
61 | } |
62 | |
63 | template <typename... Ts> constexpr int lowBitsAvailable() { |
64 | return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}); |
65 | } |
66 | |
67 | |
68 | |
69 | |
70 | template <typename T, typename ...Us> struct TypeIndex; |
71 | template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> { |
72 | static constexpr int Index = 0; |
73 | }; |
74 | template <typename T, typename U, typename... Us> |
75 | struct TypeIndex<T, U, Us...> { |
76 | static constexpr int Index = 1 + TypeIndex<T, Us...>::Index; |
77 | }; |
78 | template <typename T> struct TypeIndex<T> { |
79 | static constexpr int Index = 0; |
80 | }; |
81 | |
82 | |
83 | template <typename T, typename...> struct GetFirstType { |
84 | using type = T; |
85 | }; |
86 | |
87 | |
88 | |
89 | template <typename ...PTs> class PointerUnionUIntTraits { |
90 | public: |
91 | static inline void *getAsVoidPointer(void *P) { return P; } |
92 | static inline void *getFromVoidPointer(void *P) { return P; } |
93 | static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>(); |
94 | }; |
95 | |
96 | template <typename Derived, typename ValTy, int I, typename ...Types> |
97 | class PointerUnionMembers; |
98 | |
99 | template <typename Derived, typename ValTy, int I> |
100 | class PointerUnionMembers<Derived, ValTy, I> { |
101 | protected: |
102 | ValTy Val; |
103 | PointerUnionMembers() = default; |
104 | PointerUnionMembers(ValTy Val) : Val(Val) {} |
105 | |
106 | friend struct PointerLikeTypeTraits<Derived>; |
107 | }; |
108 | |
109 | template <typename Derived, typename ValTy, int I, typename Type, |
110 | typename ...Types> |
111 | class PointerUnionMembers<Derived, ValTy, I, Type, Types...> |
112 | : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> { |
113 | using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>; |
114 | public: |
115 | using Base::Base; |
116 | PointerUnionMembers() = default; |
117 | PointerUnionMembers(Type V) |
118 | : Base(ValTy(const_cast<void *>( |
119 | PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
120 | I)) {} |
121 | |
122 | using Base::operator=; |
123 | Derived &operator=(Type V) { |
124 | this->Val = ValTy( |
125 | const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)), |
126 | I); |
127 | return static_cast<Derived &>(*this); |
128 | }; |
129 | }; |
130 | } |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | template <typename... PTs> |
149 | class PointerUnion |
150 | : public pointer_union_detail::PointerUnionMembers< |
151 | PointerUnion<PTs...>, |
152 | PointerIntPair< |
153 | void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, |
154 | pointer_union_detail::PointerUnionUIntTraits<PTs...>>, |
155 | 0, PTs...> { |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | using First = typename pointer_union_detail::GetFirstType<PTs...>::type; |
162 | using Base = typename PointerUnion::PointerUnionMembers; |
163 | |
164 | public: |
165 | PointerUnion() = default; |
166 | |
167 | PointerUnion(std::nullptr_t) : PointerUnion() {} |
168 | using Base::Base; |
169 | |
170 | |
171 | |
172 | bool isNull() const { return !this->Val.getPointer(); } |
173 | |
174 | explicit operator bool() const { return !isNull(); } |
175 | |
176 | |
177 | template <typename T> bool is() const { |
178 | constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index; |
179 | static_assert(Index < sizeof...(PTs), |
180 | "PointerUnion::is<T> given type not in the union"); |
181 | return this->Val.getInt() == Index; |
| 30 | | Assuming the condition is false | |
|
| 31 | | Returning zero, which participates in a condition later | |
|
182 | } |
183 | |
184 | |
185 | |
186 | |
187 | template <typename T> T get() const { |
188 | assert(is<T>() && "Invalid accessor called"); |
189 | return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer()); |
190 | } |
191 | |
192 | |
193 | |
194 | template <typename T> T dyn_cast() const { |
195 | if (is<T>()) |
| 29 | | Calling 'PointerUnion::is' | |
|
| 32 | | Returning from 'PointerUnion::is' | |
|
| |
196 | return get<T>(); |
197 | return T(); |
| 34 | | Returning null pointer, which participates in a condition later | |
|
198 | } |
199 | |
200 | |
201 | |
202 | First const *getAddrOfPtr1() const { |
203 | return const_cast<PointerUnion *>(this)->getAddrOfPtr1(); |
204 | } |
205 | |
206 | |
207 | |
208 | First *getAddrOfPtr1() { |
209 | assert(is<First>() && "Val is not the first pointer"); |
210 | assert( |
211 | PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == |
212 | this->Val.getPointer() && |
213 | "Can't get the address because PointerLikeTypeTraits changes the ptr"); |
214 | return const_cast<First *>( |
215 | reinterpret_cast<const First *>(this->Val.getAddrOfPointer())); |
216 | } |
217 | |
218 | |
219 | const PointerUnion &operator=(std::nullptr_t) { |
220 | this->Val.initWithPointer(nullptr); |
221 | return *this; |
222 | } |
223 | |
224 | |
225 | using Base::operator=; |
226 | |
227 | void *getOpaqueValue() const { return this->Val.getOpaqueValue(); } |
228 | static inline PointerUnion getFromOpaqueValue(void *VP) { |
229 | PointerUnion V; |
230 | V.Val = decltype(V.Val)::getFromOpaqueValue(VP); |
231 | return V; |
232 | } |
233 | }; |
234 | |
235 | template <typename ...PTs> |
236 | bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
237 | return lhs.getOpaqueValue() == rhs.getOpaqueValue(); |
238 | } |
239 | |
240 | template <typename ...PTs> |
241 | bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
242 | return lhs.getOpaqueValue() != rhs.getOpaqueValue(); |
243 | } |
244 | |
245 | template <typename ...PTs> |
246 | bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) { |
247 | return lhs.getOpaqueValue() < rhs.getOpaqueValue(); |
248 | } |
249 | |
250 | |
251 | |
252 | template <typename ...PTs> |
253 | struct PointerLikeTypeTraits<PointerUnion<PTs...>> { |
254 | static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) { |
255 | return P.getOpaqueValue(); |
256 | } |
257 | |
258 | static inline PointerUnion<PTs...> getFromVoidPointer(void *P) { |
259 | return PointerUnion<PTs...>::getFromOpaqueValue(P); |
260 | } |
261 | |
262 | |
263 | |
264 | static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype( |
265 | PointerUnion<PTs...>::Val)>::NumLowBitsAvailable; |
266 | }; |
267 | |
268 | |
269 | template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> { |
270 | using Union = PointerUnion<PTs...>; |
271 | using FirstInfo = |
272 | DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>; |
273 | |
274 | static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); } |
275 | |
276 | static inline Union getTombstoneKey() { |
277 | return Union(FirstInfo::getTombstoneKey()); |
278 | } |
279 | |
280 | static unsigned getHashValue(const Union &UnionVal) { |
281 | intptr_t key = (intptr_t)UnionVal.getOpaqueValue(); |
282 | return DenseMapInfo<intptr_t>::getHashValue(key); |
283 | } |
284 | |
285 | static bool isEqual(const Union &LHS, const Union &RHS) { |
286 | return LHS == RHS; |
287 | } |
288 | }; |
289 | |
290 | } |
291 | |
292 | #endif // LLVM_ADT_POINTERUNION_H |