Bug Summary

File:clang/lib/Sema/SemaTemplateVariadic.cpp
Warning:line 711, column 11
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/clang/lib/Sema -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D CLANG_ROUND_TRIP_CC1_ARGS=ON -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-08-28-193554-24367-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp

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
22using namespace clang;
23
24//----------------------------------------------------------------------------
25// Visitor that collects unexpanded parameter packs
26//----------------------------------------------------------------------------
27
28namespace {
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.
280bool 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.
289bool
290Sema::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 (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 // Construct in lambda only references packs declared outside the lambda.
318 // That's OK for now, but the lambda itself is considered to contain an
319 // unexpanded pack in this case, which will require expansion outside the
320 // lambda.
321
322 // We do not permit pack expansion that would duplicate a statement
323 // expression, not even within a lambda.
324 // FIXME: We could probably support this for statement expressions that
325 // do not contain labels.
326 // FIXME: This is insufficient to detect this problem; consider
327 // f( ({ bad: 0; }) + pack ... );
328 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 // Coumpound-statements outside the lambda are OK for now; we'll check
338 // for those when we finish handling the lambda.
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
381bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
382 TypeSourceInfo *T,
383 UnexpandedParameterPackContext UPPC) {
384 // C++0x [temp.variadic]p5:
385 // An appearance of a name of a parameter pack that is not expanded is
386 // ill-formed.
387 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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 393, __extension__ __PRETTY_FUNCTION__))
;
394 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
395}
396
397bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
398 UnexpandedParameterPackContext UPPC) {
399 // C++0x [temp.variadic]p5:
400 // An appearance of a name of a parameter pack that is not expanded is
401 // ill-formed.
402 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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 407, __extension__ __PRETTY_FUNCTION__))
;
408 return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
409}
410
411bool 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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 417, __extension__ __PRETTY_FUNCTION__))
;
418
419 // We only care about unexpanded references to the RequiresExpr's own
420 // parameter packs.
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
434bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
435 UnexpandedParameterPackContext UPPC) {
436 // C++0x [temp.variadic]p5:
437 // An appearance of a name of a parameter pack that is not expanded is
438 // ill-formed.
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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 446, __extension__ __PRETTY_FUNCTION__))
;
447 return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
448 UPPC, Unexpanded);
449}
450
451bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
452 UnexpandedParameterPackContext UPPC) {
453 // C++0x [temp.variadic]p5:
454 // An appearance of a name of a parameter pack that is not expanded is
455 // ill-formed.
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 // FIXME: We shouldn't need this null check!
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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 483, __extension__ __PRETTY_FUNCTION__))
;
484 return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
485}
486
487bool 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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 497, __extension__ __PRETTY_FUNCTION__))
;
498 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
499}
500
501bool 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")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 510, __extension__ __PRETTY_FUNCTION__))
;
511 return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
512}
513
514void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
515 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
516 CollectUnexpandedParameterPacksVisitor(Unexpanded)
517 .TraverseTemplateArgument(Arg);
518}
519
520void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
521 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
522 CollectUnexpandedParameterPacksVisitor(Unexpanded)
523 .TraverseTemplateArgumentLoc(Arg);
524}
525
526void Sema::collectUnexpandedParameterPacks(QualType T,
527 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
528 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
529}
530
531void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
532 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
533 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
534}
535
536void Sema::collectUnexpandedParameterPacks(
537 NestedNameSpecifierLoc NNS,
538 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
539 CollectUnexpandedParameterPacksVisitor(Unexpanded)
540 .TraverseNestedNameSpecifierLoc(NNS);
541}
542
543void Sema::collectUnexpandedParameterPacks(
544 const DeclarationNameInfo &NameInfo,
545 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
546 CollectUnexpandedParameterPacksVisitor(Unexpanded)
547 .TraverseDeclarationNameInfo(NameInfo);
548}
549
550
551ParsedTemplateArgument
552Sema::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?")::llvm::llvm_unreachable_internal("Unhandled template argument kind?"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 588)
;
589}
590
591TypeResult 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
605TypeSourceInfo *
606Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
607 Optional<unsigned> NumExpansions) {
608 // Create the pack expansion type and source-location information.
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
623QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
624 SourceLocation EllipsisLoc,
625 Optional<unsigned> NumExpansions) {
626 // C++11 [temp.variadic]p5:
627 // The pattern of a pack expansion shall name one or more
628 // parameter packs that are not expanded by a nested pack
629 // expansion.
630 //
631 // A pattern containing a deduced type can't occur "naturally" but arises in
632 // the desugaring of an init-capture pack.
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 /*ExpectPackInType=*/false);
642}
643
644ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
645 return CheckPackExpansion(Pattern, EllipsisLoc, None);
646}
647
648ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
649 Optional<unsigned> NumExpansions) {
650 if (!Pattern)
651 return ExprError();
652
653 // C++0x [temp.variadic]p5:
654 // The pattern of a pack expansion shall name one or more
655 // parameter packs that are not expanded by a nested pack
656 // expansion.
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 // Create the pack expansion expression and source-location information.
665 return new (Context)
666 PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
667}
668
669bool 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
26
Loop condition is true. Entering loop body
682 end = Unexpanded.end();
683 i != end; ++i) {
1
Assuming 'i' is not equal to 'end'
684 // Compute the depth and index for this parameter pack.
685 unsigned Depth = 0, Index = 0;
686 IdentifierInfo *Name;
687 bool IsVarDeclPack = false;
688
689 if (const TemplateTypeParmType *TTP
34.1
'TTP' is null
34.1
'TTP' is null
34.1
'TTP' is null
34.1
'TTP' is null
3
Assuming 'TTP' is non-null
4
Taking true branch
35
Taking false branch
690 = i->first.dyn_cast<const TemplateTypeParmType *>()) {
27
Calling 'PointerUnion::dyn_cast'
34
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))
36
Assuming 'ND' is a 'VarDecl'
37
Taking true branch
697 IsVarDeclPack = true; 698 else 699 std::tie(Depth, Index) = getDepthAndIndex(ND); 700 701 Name = ND->getIdentifier(); 702 } 703 704 // Determine the size of this argument pack. 705 unsigned NewPackSize; 706 if (IsVarDeclPack
4.1
'IsVarDeclPack' is false
37.1
'IsVarDeclPack' is true
4.1
'IsVarDeclPack' is false
37.1
'IsVarDeclPack' is true
4.1
'IsVarDeclPack' is false
37.1
'IsVarDeclPack' is true
4.1
'IsVarDeclPack' is false
37.1
'IsVarDeclPack' is true
) {
38
Taking true branch
707 // Figure out whether we're instantiating to an argument pack or not. 708 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; 709 710 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation 711 = CurrentInstantiationScope->findInstantiationOf(
39
Called C++ object pointer is null
712 i->first.get<NamedDecl *>()); 713 if (Instantiation->is<DeclArgumentPack *>()) { 714 // We could expand this function parameter pack. 715 NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); 716 } else { 717 // We can't expand this function parameter pack, so we can't expand 718 // the pack expansion. 719 ShouldExpand = false; 720 continue; 721 } 722 } else { 723 // If we don't have a template argument at this depth/index, then we 724 // cannot expand the pack expansion. Make a note of this, but we still 725 // want to check any parameter packs we *do* have arguments for. 726 if (Depth >= TemplateArgs.getNumLevels() ||
5
Assuming the condition is false
18
Taking false branch
727 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
6
Calling 'MultiLevelTemplateArgumentList::hasTemplateArgument'
17
Returning from 'MultiLevelTemplateArgumentList::hasTemplateArgument'
728 ShouldExpand = false; 729 continue; 730 } 731 732 // Determine the size of the argument pack. 733 NewPackSize = TemplateArgs(Depth, Index).pack_size(); 734 } 735 736 // C++0x [temp.arg.explicit]p9: 737 // Template argument deduction can extend the sequence of template 738 // arguments corresponding to a template parameter pack, even when the 739 // sequence contains explicitly specified template arguments. 740 if (!IsVarDeclPack
18.1
'IsVarDeclPack' is false
18.1
'IsVarDeclPack' is false
18.1
'IsVarDeclPack' is false
18.1
'IsVarDeclPack' is false
&& CurrentInstantiationScope
) {
19
Assuming field 'CurrentInstantiationScope' is null
20
Assuming pointer value is null
21
Taking false branch
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 // We don't actually know the new pack size yet. 748 NumPartialExpansions = NewPackSize; 749 PartiallySubstitutedPackLoc = i->second; 750 continue; 751 } 752 } 753 } 754 755 if (!NumExpansions) {
22
Assuming the condition is false
23
Taking false branch
756 // The is the first pack we've seen for which we have an argument. 757 // Record it. 758 NumExpansions = NewPackSize; 759 FirstPack.first = Name; 760 FirstPack.second = i->second; 761 HaveFirstPack = true; 762 continue; 763 } 764 765 if (NewPackSize != *NumExpansions) {
24
Assuming the condition is false
25
Taking false branch
766 // C++0x [temp.variadic]p5: 767 // All of the parameter packs expanded by a pack expansion shall have 768 // the same number of arguments specified. 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 // If we're performing a partial expansion but we also have a full expansion, 782 // expand to the number of common arguments. For example, given: 783 // 784 // template<typename ...T> struct A { 785 // template<typename ...U> void f(pair<T, U>...); 786 // }; 787 // 788 // ... a call to 'A<int, int>().f<int>' should expand the pack once and 789 // retain an expansion. 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 806Optional<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 // Compute the depth and index for this parameter pack. 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 // Function parameter pack or init-capture pack. 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 // The pattern refers to an unexpanded pack. We're not ready to expand 833 // this pack yet. 834 return None; 835 836 unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); 837 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 837, __extension__ __PRETTY_FUNCTION__))
; 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 // The pattern refers to an unknown template argument. We're not ready to 847 // expand this pack yet. 848 return None; 849 850 // Determine the size of the argument pack. 851 unsigned Size = TemplateArgs(Depth, Index).pack_size(); 852 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 852, __extension__ __PRETTY_FUNCTION__))
; 853 Result = Size; 854 } 855 856 return Result; 857} 858 859bool 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 // These declarator chunks cannot contain any parameter packs. 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?")(static_cast <bool> (!ParamTy.isNull() && "Couldn't parse type?"
) ? void (0) : __assert_fail ("!ParamTy.isNull() && \"Couldn't parse type?\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 936, __extension__ __PRETTY_FUNCTION__))
; 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 973namespace { 974 975// Callback to only accept typo corrections that refer to parameter packs. 976class 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/// Called when an expression computing the size of a parameter pack 991/// is parsed. 992/// 993/// \code 994/// template<typename ...Types> struct count { 995/// static const unsigned value = sizeof...(Types); 996/// }; 997/// \endcode 998/// 999// 1000/// \param OpLoc The location of the "sizeof" keyword. 1001/// \param Name The name of the parameter pack whose size will be determined. 1002/// \param NameLoc The source location of the name of the parameter pack. 1003/// \param RParenLoc The location of the closing parentheses. 1004ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, 1005 SourceLocation OpLoc, 1006 IdentifierInfo &Name, 1007 SourceLocation NameLoc, 1008 SourceLocation RParenLoc) { 1009 // C++0x [expr.sizeof]p5: 1010 // The identifier in a sizeof... expression shall name a parameter pack. 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 1054TemplateArgumentLoc 1055Sema::getTemplateArgumentPackExpansionPattern( 1056 TemplateArgumentLoc OrigLoc, 1057 SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const { 1058 const TemplateArgument &Argument = OrigLoc.getArgument(); 1059 assert(Argument.isPackExpansion())(static_cast <bool> (Argument.isPackExpansion()) ? void
(0) : __assert_fail ("Argument.isPackExpansion()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1059, __extension__ __PRETTY_FUNCTION__))
; 1060 switch (Argument.getKind()) { 1061 case TemplateArgument::Type: { 1062 // FIXME: We shouldn't ever have to worry about missing 1063 // type-source info! 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 // We need to copy the TypeLoc because TemplateArgumentLocs store a 1076 // TypeSourceInfo. 1077 // FIXME: Find some way to avoid the copy? 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!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1111)
; 1112} 1113 1114Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { 1115 assert(Arg.containsUnexpandedParameterPack())(static_cast <bool> (Arg.containsUnexpandedParameterPack
()) ? void (0) : __assert_fail ("Arg.containsUnexpandedParameterPack()"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1115, __extension__ __PRETTY_FUNCTION__))
; 1116 1117 // If this is a substituted pack, grab that pack. If not, we don't know 1118 // the size yet. 1119 // FIXME: We could find a size in more cases by looking for a substituted 1120 // pack anywhere within this argument, but that's not necessary in the common 1121 // case for 'sizeof...(A)' handling. 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 // Check that no argument in the pack is itself a pack expansion. 1162 for (TemplateArgument Elem : Pack.pack_elements()) { 1163 // There's no point recursing in this case; we would have already 1164 // expanded this pack expansion into the enclosing pack if we could. 1165 if (Elem.isPackExpansion()) 1166 return None; 1167 } 1168 return Pack.pack_size(); 1169} 1170 1171static 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 1186ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS, 1187 tok::TokenKind Operator, 1188 SourceLocation EllipsisLoc, Expr *RHS, 1189 SourceLocation RParenLoc) { 1190 // LHS and RHS must be cast-expressions. We allow an arbitrary expression 1191 // in the parser and reduce down to just cast-expressions here. 1192 CheckFoldOperand(*this, LHS); 1193 CheckFoldOperand(*this, RHS); 1194 1195 auto DiscardOperands = [&] { 1196 CorrectDelayedTyposInExpr(LHS); 1197 CorrectDelayedTyposInExpr(RHS); 1198 }; 1199 1200 // [expr.prim.fold]p3: 1201 // In a binary fold, op1 and op2 shall be the same fold-operator, and 1202 // either e1 shall contain an unexpanded parameter pack or e2 shall contain 1203 // an unexpanded parameter pack, but not both. 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 // [expr.prim.fold]p2: 1216 // In a unary fold, the cast-expression shall contain an unexpanded 1217 // parameter pack. 1218 if (!LHS || !RHS) { 1219 Expr *Pack = LHS ? LHS : RHS; 1220 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1220, __extension__ __PRETTY_FUNCTION__))
; 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 // Perform first-phase name lookup now. 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 /*NamingClass*/ 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 1250ExprResult 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 1261ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, 1262 BinaryOperatorKind Operator) { 1263 // [temp.variadic]p9: 1264 // If N is zero for a unary fold-expression, the value of the expression is 1265 // && -> true 1266 // || -> false 1267 // , -> void() 1268 // if the operator is not listed [above], the instantiation is ill-formed. 1269 // 1270 // Note that we need to use something like int() here, not merely 0, to 1271 // prevent the result from being a null pointer constant. 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}

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h

1//===- SemaTemplate.h - C++ Templates ---------------------------*- 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// This file provides types used in the semantic analysis of C++ templates.
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
28namespace clang {
29
30class ASTContext;
31class BindingDecl;
32class CXXMethodDecl;
33class Decl;
34class DeclaratorDecl;
35class DeclContext;
36class EnumDecl;
37class FunctionDecl;
38class NamedDecl;
39class ParmVarDecl;
40class TagDecl;
41class TypedefNameDecl;
42class TypeSourceInfo;
43class VarDecl;
44
45/// The kind of template substitution being performed.
46enum class TemplateSubstitutionKind : char {
47 /// We are substituting template parameters for template arguments in order
48 /// to form a template specialization.
49 Specialization,
50 /// We are substituting template parameters for (typically) other template
51 /// parameters in order to rewrite a declaration as a different declaration
52 /// (for example, when forming a deduction guide from a constructor).
53 Rewrite,
54};
55
56 /// Data structure that captures multiple levels of template argument
57 /// lists for use in template instantiation.
58 ///
59 /// Multiple levels of template arguments occur when instantiating the
60 /// definitions of member templates. For example:
61 ///
62 /// \code
63 /// template<typename T>
64 /// struct X {
65 /// template<T Value>
66 /// struct Y {
67 /// void f();
68 /// };
69 /// };
70 /// \endcode
71 ///
72 /// When instantiating X<int>::Y<17>::f, the multi-level template argument
73 /// list will contain a template argument list (int) at depth 0 and a
74 /// template argument list (17) at depth 1.
75 class MultiLevelTemplateArgumentList {
76 /// The template argument list at a certain template depth
77 using ArgList = ArrayRef<TemplateArgument>;
78
79 /// The template argument lists, stored from the innermost template
80 /// argument list (first) to the outermost template argument list (last).
81 SmallVector<ArgList, 4> TemplateArgumentLists;
82
83 /// The number of outer levels of template arguments that are not
84 /// being substituted.
85 unsigned NumRetainedOuterLevels = 0;
86
87 /// The kind of substitution described by this argument list.
88 TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization;
89
90 public:
91 /// Construct an empty set of template argument lists.
92 MultiLevelTemplateArgumentList() = default;
93
94 /// Construct a single-level template argument list.
95 explicit
96 MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
97 addOuterTemplateArguments(&TemplateArgs);
98 }
99
100 void setKind(TemplateSubstitutionKind K) { Kind = K; }
101
102 /// Determine the kind of template substitution being performed.
103 TemplateSubstitutionKind getKind() const { return Kind; }
104
105 /// Determine whether we are rewriting template parameters rather than
106 /// substituting for them. If so, we should not leave references to the
107 /// original template parameters behind.
108 bool isRewrite() const {
109 return Kind == TemplateSubstitutionKind::Rewrite;
110 }
111
112 /// Determine the number of levels in this template argument
113 /// list.
114 unsigned getNumLevels() const {
115 return TemplateArgumentLists.size() + NumRetainedOuterLevels;
116 }
117
118 /// Determine the number of substituted levels in this template
119 /// argument list.
120 unsigned getNumSubstitutedLevels() const {
121 return TemplateArgumentLists.size();
122 }
123
124 unsigned getNumRetainedOuterLevels() const {
125 return NumRetainedOuterLevels;
126 }
127
128 /// Determine how many of the \p OldDepth outermost template parameter
129 /// lists would be removed by substituting these arguments.
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 /// Retrieve the template argument at a given depth and index.
139 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
140 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels())(static_cast <bool> (NumRetainedOuterLevels <= Depth
&& Depth < getNumLevels()) ? void (0) : __assert_fail
("NumRetainedOuterLevels <= Depth && Depth < getNumLevels()"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 140, __extension__ __PRETTY_FUNCTION__))
;
141 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size())(static_cast <bool> (Index < TemplateArgumentLists[getNumLevels
() - Depth - 1].size()) ? void (0) : __assert_fail ("Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 141, __extension__ __PRETTY_FUNCTION__))
;
142 return TemplateArgumentLists[getNumLevels() - Depth - 1][Index];
143 }
144
145 /// Determine whether there is a non-NULL template argument at the
146 /// given depth and index.
147 ///
148 /// There must exist a template argument list at the given depth.
149 bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
150 assert(Depth < getNumLevels())(static_cast <bool> (Depth < getNumLevels()) ? void (
0) : __assert_fail ("Depth < getNumLevels()", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 150, __extension__ __PRETTY_FUNCTION__))
;
7
'?' condition is true
151
152 if (Depth < NumRetainedOuterLevels)
8
Assuming 'Depth' is >= field 'NumRetainedOuterLevels'
9
Taking false branch
153 return false;
154
155 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
10
Assuming the condition is false
11
Taking false branch
156 return false;
157
158 return !(*this)(Depth, Index).isNull();
12
Calling 'TemplateArgument::isNull'
15
Returning from 'TemplateArgument::isNull'
16
Returning the value 1, which participates in a condition later
159 }
160
161 /// Clear out a specific template argument.
162 void setArgument(unsigned Depth, unsigned Index,
163 TemplateArgument Arg) {
164 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels())(static_cast <bool> (NumRetainedOuterLevels <= Depth
&& Depth < getNumLevels()) ? void (0) : __assert_fail
("NumRetainedOuterLevels <= Depth && Depth < getNumLevels()"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 164, __extension__ __PRETTY_FUNCTION__))
;
165 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size())(static_cast <bool> (Index < TemplateArgumentLists[getNumLevels
() - Depth - 1].size()) ? void (0) : __assert_fail ("Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 165, __extension__ __PRETTY_FUNCTION__))
;
166 const_cast<TemplateArgument&>(
167 TemplateArgumentLists[getNumLevels() - Depth - 1][Index])
168 = Arg;
169 }
170
171 /// Add a new outermost level to the multi-level template argument
172 /// list.
173 void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
174 addOuterTemplateArguments(ArgList(TemplateArgs->data(),
175 TemplateArgs->size()));
176 }
177
178 /// Add a new outmost level to the multi-level template argument
179 /// list.
180 void addOuterTemplateArguments(ArgList Args) {
181 assert(!NumRetainedOuterLevels &&(static_cast <bool> (!NumRetainedOuterLevels &&
"substituted args outside retained args?") ? void (0) : __assert_fail
("!NumRetainedOuterLevels && \"substituted args outside retained args?\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 182, __extension__ __PRETTY_FUNCTION__))
182 "substituted args outside retained args?")(static_cast <bool> (!NumRetainedOuterLevels &&
"substituted args outside retained args?") ? void (0) : __assert_fail
("!NumRetainedOuterLevels && \"substituted args outside retained args?\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 182, __extension__ __PRETTY_FUNCTION__))
;
183 TemplateArgumentLists.push_back(Args);
184 }
185
186 /// Add an outermost level that we are not substituting. We have no
187 /// arguments at this level, and do not remove it from the depth of inner
188 /// template parameters that we instantiate.
189 void addOuterRetainedLevel() {
190 ++NumRetainedOuterLevels;
191 }
192 void addOuterRetainedLevels(unsigned Num) {
193 NumRetainedOuterLevels += Num;
194 }
195
196 /// Retrieve the innermost template argument list.
197 const ArgList &getInnermost() const {
198 return TemplateArgumentLists.front();
199 }
200 };
201
202 /// The context in which partial ordering of function templates occurs.
203 enum TPOC {
204 /// Partial ordering of function templates for a function call.
205 TPOC_Call,
206
207 /// Partial ordering of function templates for a call to a
208 /// conversion function.
209 TPOC_Conversion,
210
211 /// Partial ordering of function templates in other contexts, e.g.,
212 /// taking the address of a function template or matching a function
213 /// template specialization to a function template.
214 TPOC_Other
215 };
216
217 // This is lame but unavoidable in a world without forward
218 // declarations of enums. The alternatives are to either pollute
219 // Sema.h (by including this file) or sacrifice type safety (by
220 // making Sema.h declare things as enums).
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 /// Captures a template argument whose value has been deduced
231 /// via c++ template argument deduction.
232 class DeducedTemplateArgument : public TemplateArgument {
233 /// For a non-type template argument, whether the value was
234 /// deduced from an array bound.
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 /// Construct an integral non-type template argument that
245 /// has been deduced, possibly from an array bound.
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 /// For a non-type template argument, determine whether the
254 /// template argument was deduced from an array bound.
255 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
256
257 /// Specify whether the given non-type template argument
258 /// was deduced from an array bound.
259 void setDeducedFromArrayBound(bool Deduced) {
260 DeducedFromArrayBound = Deduced;
261 }
262 };
263
264 /// A stack-allocated class that identifies which local
265 /// variable declaration instantiations are present in this scope.
266 ///
267 /// A new instance of this class type will be created whenever we
268 /// instantiate a new function declaration, which will have its own
269 /// set of parameter declarations.
270 class LocalInstantiationScope {
271 public:
272 /// A set of declarations.
273 using DeclArgumentPack = SmallVector<VarDecl *, 4>;
274
275 private:
276 /// Reference to the semantic analysis that is performing
277 /// this template instantiation.
278 Sema &SemaRef;
279
280 using LocalDeclsMap =
281 llvm::SmallDenseMap<const Decl *,
282 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
283
284 /// A mapping from local declarations that occur
285 /// within a template to their instantiations.
286 ///
287 /// This mapping is used during instantiation to keep track of,
288 /// e.g., function parameter and variable declarations. For example,
289 /// given:
290 ///
291 /// \code
292 /// template<typename T> T add(T x, T y) { return x + y; }
293 /// \endcode
294 ///
295 /// when we instantiate add<int>, we will introduce a mapping from
296 /// the ParmVarDecl for 'x' that occurs in the template to the
297 /// instantiated ParmVarDecl for 'x'.
298 ///
299 /// For a parameter pack, the local instantiation scope may contain a
300 /// set of instantiated parameters. This is stored as a DeclArgumentPack
301 /// pointer.
302 LocalDeclsMap LocalDecls;
303
304 /// The set of argument packs we've allocated.
305 SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
306
307 /// The outer scope, which contains local variable
308 /// definitions from some other instantiation (that may not be
309 /// relevant to this particular scope).
310 LocalInstantiationScope *Outer;
311
312 /// Whether we have already exited this scope.
313 bool Exited = false;
314
315 /// Whether to combine this scope with the outer scope, such that
316 /// lookup will search our outer scope.
317 bool CombineWithOuterScope;
318
319 /// If non-NULL, the template parameter pack that has been
320 /// partially substituted per C++0x [temp.arg.explicit]p9.
321 NamedDecl *PartiallySubstitutedPack = nullptr;
322
323 /// If \c PartiallySubstitutedPack is non-null, the set of
324 /// explicitly-specified template arguments in that pack.
325 const TemplateArgument *ArgsInPartiallySubstitutedPack;
326
327 /// If \c PartiallySubstitutedPack, the number of
328 /// explicitly-specified template arguments in
329 /// ArgsInPartiallySubstitutedPack.
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 /// Exit this local instantiation scope early.
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 /// Clone this scope, and all outer scopes, down to the given
362 /// outermost scope.
363 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
364 if (this == Outermost) return this;
365
366 // Save the current scope from SemaRef since the LocalInstantiationScope
367 // will overwrite it on construction
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 // Restore the saved scope to SemaRef
397 SemaRef.CurrentInstantiationScope = oldScope;
398 return newScope;
399 }
400
401 /// deletes the given scope, and all otuer scopes, down to the
402 /// given outermost scope.
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 /// Find the instantiation of the declaration D within the current
413 /// instantiation scope.
414 ///
415 /// \param D The declaration whose instantiation we are searching for.
416 ///
417 /// \returns A pointer to the declaration or argument pack of declarations
418 /// to which the declaration \c D is instantiated, if found. Otherwise,
419 /// returns NULL.
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 /// Note that the given parameter pack has been partially substituted
428 /// via explicit specification of template arguments
429 /// (C++0x [temp.arg.explicit]p9).
430 ///
431 /// \param Pack The parameter pack, which will always be a template
432 /// parameter pack.
433 ///
434 /// \param ExplicitArgs The explicitly-specified template arguments provided
435 /// for this parameter pack.
436 ///
437 /// \param NumExplicitArgs The number of explicitly-specified template
438 /// arguments provided for this parameter pack.
439 void SetPartiallySubstitutedPack(NamedDecl *Pack,
440 const TemplateArgument *ExplicitArgs,
441 unsigned NumExplicitArgs);
442
443 /// Reset the partially-substituted pack when it is no longer of
444 /// interest.
445 void ResetPartiallySubstitutedPack() {
446 assert(PartiallySubstitutedPack && "No partially-substituted pack")(static_cast <bool> (PartiallySubstitutedPack &&
"No partially-substituted pack") ? void (0) : __assert_fail (
"PartiallySubstitutedPack && \"No partially-substituted pack\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/Sema/Template.h"
, 446, __extension__ __PRETTY_FUNCTION__))
;
447 PartiallySubstitutedPack = nullptr;
448 ArgsInPartiallySubstitutedPack = nullptr;
449 NumArgsInPartiallySubstitutedPack = 0;
450 }
451
452 /// Retrieve the partially-substitued template parameter pack.
453 ///
454 /// If there is no partially-substituted parameter pack, returns NULL.
455 NamedDecl *
456 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
457 unsigned *NumExplicitArgs = nullptr) const;
458
459 /// Determine whether D is a pack expansion created in this scope.
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 /// A list of out-of-line class template partial
474 /// specializations that will need to be instantiated after the
475 /// enclosing class's instantiation is complete.
476 SmallVector<std::pair<ClassTemplateDecl *,
477 ClassTemplatePartialSpecializationDecl *>, 4>
478 OutOfLinePartialSpecs;
479
480 /// A list of out-of-line variable template partial
481 /// specializations that will need to be instantiated after the
482 /// enclosing variable's instantiation is complete.
483 /// FIXME: Verify that this is needed.
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// Define all the decl visitors using DeclNodes.inc
496#define DECL(DERIVED, BASE) \
497 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
498#define ABSTRACT_DECL(DECL)
499
500// Decls which never appear inside a class or function.
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 // Decls which use special-case instantiation code.
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 // A few supplemental visitor functions.
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 // Enable late instantiation of attributes. Late instantiated attributes
544 // will be stored in LA.
545 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
546 LateAttrs = LA;
547 StartingScope = SemaRef.CurrentInstantiationScope;
548 }
549
550 // Disable late instantiation of attributes.
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 /// Return an iterator to the beginning of the set of
565 /// "delayed" partial specializations, which must be passed to
566 /// InstantiateClassTemplatePartialSpecialization once the class
567 /// definition has been completed.
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 /// Return an iterator to the end of the set of
577 /// "delayed" partial specializations, which must be passed to
578 /// InstantiateClassTemplatePartialSpecialization once the class
579 /// definition has been completed.
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 // Helper functions for instantiating methods.
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} // namespace clang
628
629#endif // LLVM_CLANG_SEMA_TEMPLATE_H

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h

1//===- TemplateBase.h - Core classes for C++ templates ----------*- 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 provides definitions which are common for all kinds of
10// template representation.
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
35namespace llvm {
36
37class FoldingSetNodeID;
38
39// Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
40// full definition of Expr, but this file only sees a forward del because of
41// the dependency.
42template <> 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} // namespace llvm
51
52namespace clang {
53
54class ASTContext;
55class DiagnosticBuilder;
56class Expr;
57struct PrintingPolicy;
58class TypeSourceInfo;
59class ValueDecl;
60
61/// Represents a template argument.
62class TemplateArgument {
63public:
64 /// The kind of template argument we're storing.
65 enum ArgKind {
66 /// Represents an empty template argument, e.g., one that has not
67 /// been deduced.
68 Null = 0,
69
70 /// The template argument is a type.
71 Type,
72
73 /// The template argument is a declaration that was provided for a pointer,
74 /// reference, or pointer to member non-type template parameter.
75 Declaration,
76
77 /// The template argument is a null pointer or null pointer to member that
78 /// was provided for a non-type template parameter.
79 NullPtr,
80
81 /// The template argument is an integral value stored in an llvm::APSInt
82 /// that was provided for an integral non-type template parameter.
83 Integral,
84
85 /// The template argument is a template name that was provided for a
86 /// template template parameter.
87 Template,
88
89 /// The template argument is a pack expansion of a template name that was
90 /// provided for a template template parameter.
91 TemplateExpansion,
92
93 /// The template argument is an expression, and we've not resolved it to one
94 /// of the other forms yet, either because it's dependent or because we're
95 /// representing a non-canonical template argument (for instance, in a
96 /// TemplateSpecializationType).
97 Expression,
98
99 /// The template argument is actually a parameter pack. Arguments are stored
100 /// in the Args struct.
101 Pack
102 };
103
104private:
105 /// The kind of template argument we're storing.
106
107 struct DA {
108 unsigned Kind;
109 void *QT;
110 ValueDecl *D;
111 };
112 struct I {
113 unsigned Kind;
114 // We store a decomposed APSInt with the data allocated by ASTContext if
115 // BitWidth > 64. The memory may be shared between multiple
116 // TemplateArgument instances.
117 unsigned BitWidth : 31;
118 unsigned IsUnsigned : 1;
119 union {
120 /// Used to store the <= 64 bits integer value.
121 uint64_t VAL;
122
123 /// Used to store the >64 bits integer value.
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
150public:
151 /// Construct an empty, invalid template argument.
152 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
153
154 /// Construct a template type argument.
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 /// Construct a template argument that refers to a
161 /// declaration, which is either an external declaration or a
162 /// template declaration.
163 TemplateArgument(ValueDecl *D, QualType QT) {
164 assert(D && "Expected decl")(static_cast <bool> (D && "Expected decl") ? void
(0) : __assert_fail ("D && \"Expected decl\"", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 164, __extension__ __PRETTY_FUNCTION__))
;
165 DeclArg.Kind = Declaration;
166 DeclArg.QT = QT.getAsOpaquePtr();
167 DeclArg.D = D;
168 }
169
170 /// Construct an integral constant template argument. The memory to
171 /// store the value is allocated with Ctx.
172 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
173
174 /// Construct an integral constant template argument with the same
175 /// value as Other but a different type.
176 TemplateArgument(const TemplateArgument &Other, QualType Type) {
177 Integer = Other.Integer;
178 Integer.Type = Type.getAsOpaquePtr();
179 }
180
181 /// Construct a template argument that is a template.
182 ///
183 /// This form of template argument is generally used for template template
184 /// parameters. However, the template name could be a dependent template
185 /// name that ends up being instantiated to a function template whose address
186 /// is taken.
187 ///
188 /// \param Name The template name.
189 TemplateArgument(TemplateName Name) {
190 TemplateArg.Kind = Template;
191 TemplateArg.Name = Name.getAsVoidPointer();
192 TemplateArg.NumExpansions = 0;
193 }
194
195 /// Construct a template argument that is a template pack expansion.
196 ///
197 /// This form of template argument is generally used for template template
198 /// parameters. However, the template name could be a dependent template
199 /// name that ends up being instantiated to a function template whose address
200 /// is taken.
201 ///
202 /// \param Name The template name.
203 ///
204 /// \param NumExpansions The number of expansions that will be generated by
205 /// instantiating
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 /// Construct a template argument that is an expression.
216 ///
217 /// This form of template argument only occurs in template argument
218 /// lists used for dependent types and for expression; it will not
219 /// occur in a non-dependent, canonical template argument list.
220 TemplateArgument(Expr *E) {
221 TypeOrValue.Kind = Expression;
222 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
223 }
224
225 /// Construct a template argument that is a template argument pack.
226 ///
227 /// We assume that storage for the template arguments provided
228 /// outlives the TemplateArgument itself.
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 /// Create a new template argument pack by copying the given set of
240 /// template arguments.
241 static TemplateArgument CreatePackCopy(ASTContext &Context,
242 ArrayRef<TemplateArgument> Args);
243
244 /// Return the kind of stored template argument.
245 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
246
247 /// Determine whether this template argument has no value.
248 bool isNull() const { return getKind() == Null; }
13
Assuming the condition is false
14
Returning zero, which participates in a condition later
249
250 TemplateArgumentDependence getDependence() const;
251
252 /// Whether this template argument is dependent on a template
253 /// parameter such that its result can change from one instantiation to
254 /// another.
255 bool isDependent() const;
256
257 /// Whether this template argument is dependent on a template
258 /// parameter.
259 bool isInstantiationDependent() const;
260
261 /// Whether this template argument contains an unexpanded
262 /// parameter pack.
263 bool containsUnexpandedParameterPack() const;
264
265 /// Determine whether this template argument is a pack expansion.
266 bool isPackExpansion() const;
267
268 /// Retrieve the type for a type template argument.
269 QualType getAsType() const {
270 assert(getKind() == Type && "Unexpected kind")(static_cast <bool> (getKind() == Type && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Type && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 270, __extension__ __PRETTY_FUNCTION__))
;
271 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
272 }
273
274 /// Retrieve the declaration for a declaration non-type
275 /// template argument.
276 ValueDecl *getAsDecl() const {
277 assert(getKind() == Declaration && "Unexpected kind")(static_cast <bool> (getKind() == Declaration &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 277, __extension__ __PRETTY_FUNCTION__))
;
278 return DeclArg.D;
279 }
280
281 QualType getParamTypeForDecl() const {
282 assert(getKind() == Declaration && "Unexpected kind")(static_cast <bool> (getKind() == Declaration &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 282, __extension__ __PRETTY_FUNCTION__))
;
283 return QualType::getFromOpaquePtr(DeclArg.QT);
284 }
285
286 /// Retrieve the type for null non-type template argument.
287 QualType getNullPtrType() const {
288 assert(getKind() == NullPtr && "Unexpected kind")(static_cast <bool> (getKind() == NullPtr && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == NullPtr && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 288, __extension__ __PRETTY_FUNCTION__))
;
289 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
290 }
291
292 /// Retrieve the template name for a template name argument.
293 TemplateName getAsTemplate() const {
294 assert(getKind() == Template && "Unexpected kind")(static_cast <bool> (getKind() == Template && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Template && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 294, __extension__ __PRETTY_FUNCTION__))
;
295 return TemplateName::getFromVoidPointer(TemplateArg.Name);
296 }
297
298 /// Retrieve the template argument as a template name; if the argument
299 /// is a pack expansion, return the pattern as a template name.
300 TemplateName getAsTemplateOrTemplatePattern() const {
301 assert((getKind() == Template || getKind() == TemplateExpansion) &&(static_cast <bool> ((getKind() == Template || getKind(
) == TemplateExpansion) && "Unexpected kind") ? void (
0) : __assert_fail ("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 302, __extension__ __PRETTY_FUNCTION__))
302 "Unexpected kind")(static_cast <bool> ((getKind() == Template || getKind(
) == TemplateExpansion) && "Unexpected kind") ? void (
0) : __assert_fail ("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 302, __extension__ __PRETTY_FUNCTION__))
;
303
304 return TemplateName::getFromVoidPointer(TemplateArg.Name);
305 }
306
307 /// Retrieve the number of expansions that a template template argument
308 /// expansion will produce, if known.
309 Optional<unsigned> getNumTemplateExpansions() const;
310
311 /// Retrieve the template argument as an integral value.
312 // FIXME: Provide a way to read the integral data without copying the value.
313 llvm::APSInt getAsIntegral() const {
314 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 314, __extension__ __PRETTY_FUNCTION__))
;
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 /// Retrieve the type of the integral value.
327 QualType getIntegralType() const {
328 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 328, __extension__ __PRETTY_FUNCTION__))
;
329 return QualType::getFromOpaquePtr(Integer.Type);
330 }
331
332 void setIntegralType(QualType T) {
333 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 333, __extension__ __PRETTY_FUNCTION__))
;
334 Integer.Type = T.getAsOpaquePtr();
335 }
336
337 /// If this is a non-type template argument, get its type. Otherwise,
338 /// returns a null QualType.
339 QualType getNonTypeTemplateArgumentType() const;
340
341 /// Retrieve the template argument as an expression.
342 Expr *getAsExpr() const {
343 assert(getKind() == Expression && "Unexpected kind")(static_cast <bool> (getKind() == Expression &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Expression && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 343, __extension__ __PRETTY_FUNCTION__))
;
344 return reinterpret_cast<Expr *>(TypeOrValue.V);
345 }
346
347 /// Iterator that traverses the elements of a template argument pack.
348 using pack_iterator = const TemplateArgument *;
349
350 /// Iterator referencing the first argument of a template argument
351 /// pack.
352 pack_iterator pack_begin() const {
353 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 353, __extension__ __PRETTY_FUNCTION__))
;
354 return Args.Args;
355 }
356
357 /// Iterator referencing one past the last argument of a template
358 /// argument pack.
359 pack_iterator pack_end() const {
360 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 360, __extension__ __PRETTY_FUNCTION__))
;
361 return Args.Args + Args.NumArgs;
362 }
363
364 /// Iterator range referencing all of the elements of a template
365 /// argument pack.
366 ArrayRef<TemplateArgument> pack_elements() const {
367 return llvm::makeArrayRef(pack_begin(), pack_end());
368 }
369
370 /// The number of template arguments in the given template argument
371 /// pack.
372 unsigned pack_size() const {
373 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 373, __extension__ __PRETTY_FUNCTION__))
;
374 return Args.NumArgs;
375 }
376
377 /// Return the array of arguments in this template argument pack.
378 ArrayRef<TemplateArgument> getPackAsArray() const {
379 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 379, __extension__ __PRETTY_FUNCTION__))
;
380 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
381 }
382
383 /// Determines whether two template arguments are superficially the
384 /// same.
385 bool structurallyEquals(const TemplateArgument &Other) const;
386
387 /// When the template argument is a pack expansion, returns
388 /// the pattern of the pack expansion.
389 TemplateArgument getPackExpansionPattern() const;
390
391 /// Print this template argument to the given output stream.
392 void print(const PrintingPolicy &Policy, raw_ostream &Out,
393 bool IncludeType) const;
394
395 /// Debugging aid that dumps the template argument.
396 void dump(raw_ostream &Out) const;
397
398 /// Debugging aid that dumps the template argument to standard error.
399 void dump() const;
400
401 /// Used to insert TemplateArguments into FoldingSets.
402 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
403};
404
405/// Location information for a TemplateArgument.
406struct TemplateArgumentLocInfo {
407private:
408 struct TemplateTemplateArgLocInfo {
409 // FIXME: We'd like to just use the qualifier in the TemplateName,
410 // but template arguments get canonicalized too quickly.
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
424public:
425 TemplateArgumentLocInfo() {}
426 TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
427
428 TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
429 // Ctx is used for allocation -- this case is unusually large and also rare,
430 // so we store the payload out-of-line.
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/// Location wrapper for a TemplateArgument. TemplateArgument is to
457/// TemplateArgumentLoc as Type is to TypeLoc.
458class TemplateArgumentLoc {
459 TemplateArgument Argument;
460 TemplateArgumentLocInfo LocInfo;
461
462public:
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)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Type) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 471, __extension__ __PRETTY_FUNCTION__))
;
472 }
473
474 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
475 : Argument(Argument), LocInfo(E) {
476
477 // Permit any kind of template argument that can be represented with an
478 // expression.
479 assert(Argument.getKind() == TemplateArgument::NullPtr ||(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr || Argument.getKind() == TemplateArgument::Integral
|| Argument.getKind() == TemplateArgument::Declaration || Argument
.getKind() == TemplateArgument::Expression) ? void (0) : __assert_fail
("Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 482, __extension__ __PRETTY_FUNCTION__))
480 Argument.getKind() == TemplateArgument::Integral ||(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr || Argument.getKind() == TemplateArgument::Integral
|| Argument.getKind() == TemplateArgument::Declaration || Argument
.getKind() == TemplateArgument::Expression) ? void (0) : __assert_fail
("Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 482, __extension__ __PRETTY_FUNCTION__))
481 Argument.getKind() == TemplateArgument::Declaration ||(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr || Argument.getKind() == TemplateArgument::Integral
|| Argument.getKind() == TemplateArgument::Declaration || Argument
.getKind() == TemplateArgument::Expression) ? void (0) : __assert_fail
("Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 482, __extension__ __PRETTY_FUNCTION__))
482 Argument.getKind() == TemplateArgument::Expression)(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr || Argument.getKind() == TemplateArgument::Integral
|| Argument.getKind() == TemplateArgument::Declaration || Argument
.getKind() == TemplateArgument::Expression) ? void (0) : __assert_fail
("Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 482, __extension__ __PRETTY_FUNCTION__))
;
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 ||(static_cast <bool> (Argument.getKind() == TemplateArgument
::Template || Argument.getKind() == TemplateArgument::TemplateExpansion
) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 492, __extension__ __PRETTY_FUNCTION__))
492 Argument.getKind() == TemplateArgument::TemplateExpansion)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Template || Argument.getKind() == TemplateArgument::TemplateExpansion
) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 492, __extension__ __PRETTY_FUNCTION__))
;
493 }
494
495 /// - Fetches the primary location of the argument.
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 /// - Fetches the full source range of the argument.
505 SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__));
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)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Expression) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 522, __extension__ __PRETTY_FUNCTION__))
;
523 return LocInfo.getAsExpr();
524 }
525
526 Expr *getSourceDeclExpression() const {
527 assert(Argument.getKind() == TemplateArgument::Declaration)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Declaration) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Declaration"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 527, __extension__ __PRETTY_FUNCTION__))
;
528 return LocInfo.getAsExpr();
529 }
530
531 Expr *getSourceNullPtrExpression() const {
532 assert(Argument.getKind() == TemplateArgument::NullPtr)(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::NullPtr"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 532, __extension__ __PRETTY_FUNCTION__))
;
533 return LocInfo.getAsExpr();
534 }
535
536 Expr *getSourceIntegralExpression() const {
537 assert(Argument.getKind() == TemplateArgument::Integral)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Integral) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Integral"
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 537, __extension__ __PRETTY_FUNCTION__))
;
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/// A convenient class for passing around template argument
563/// information. Designed to be passed by reference.
564class TemplateArgumentListInfo {
565 SmallVector<TemplateArgumentLoc, 8> Arguments;
566 SourceLocation LAngleLoc;
567 SourceLocation RAngleLoc;
568
569public:
570 TemplateArgumentListInfo() = default;
571
572 TemplateArgumentListInfo(SourceLocation LAngleLoc,
573 SourceLocation RAngleLoc)
574 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
575
576 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
577 // instead.
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/// Represents an explicit template argument list in C++, e.g.,
610/// the "<int>" in "sort<int>".
611/// This is safe to be used inside an AST node, in contrast with
612/// TemplateArgumentListInfo.
613struct ASTTemplateArgumentListInfo final
614 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
615 TemplateArgumentLoc> {
616private:
617 friend class ASTNodeImporter;
618 friend TrailingObjects;
619
620 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
621
622public:
623 /// The source location of the left angle bracket ('<').
624 SourceLocation LAngleLoc;
625
626 /// The source location of the right angle bracket ('>').
627 SourceLocation RAngleLoc;
628
629 /// The number of template arguments in TemplateArgs.
630 unsigned NumTemplateArgs;
631
632 SourceLocation getLAngleLoc() const { return LAngleLoc; }
633 SourceLocation getRAngleLoc() const { return RAngleLoc; }
634
635 /// Retrieve the template arguments
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/// Represents an explicit template argument list in C++, e.g.,
654/// the "<int>" in "sort<int>".
655///
656/// It is intended to be used as a trailing object on AST nodes, and
657/// as such, doesn't contain the array of TemplateArgumentLoc itself,
658/// but expects the containing object to also provide storage for
659/// that.
660struct alignas(void *) ASTTemplateKWAndArgsInfo {
661 /// The source location of the left angle bracket ('<').
662 SourceLocation LAngleLoc;
663
664 /// The source location of the right angle bracket ('>').
665 SourceLocation RAngleLoc;
666
667 /// The source location of the template keyword; this is used
668 /// as part of the representation of qualified identifiers, such as
669 /// S<T>::template apply<T>. Will be empty if this expression does
670 /// not have a template keyword.
671 SourceLocation TemplateKWLoc;
672
673 /// The number of template arguments in TemplateArgs.
674 unsigned NumTemplateArgs;
675
676 void initializeFrom(SourceLocation TemplateKWLoc,
677 const TemplateArgumentListInfo &List,
678 TemplateArgumentLoc *OutArgArray);
679 // FIXME: The parameter Deps is the result populated by this method, the
680 // caller doesn't need it since it is populated by computeDependence. remove
681 // it.
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
692const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
693 const TemplateArgument &Arg);
694
695inline TemplateSpecializationType::iterator
696 TemplateSpecializationType::end() const {
697 return getArgs() + getNumArgs();
698}
699
700inline DependentTemplateSpecializationType::iterator
701 DependentTemplateSpecializationType::end() const {
702 return getArgs() + getNumArgs();
703}
704
705inline const TemplateArgument &
706 TemplateSpecializationType::getArg(unsigned Idx) const {
707 assert(Idx < getNumArgs() && "Template argument out of range")(static_cast <bool> (Idx < getNumArgs() && "Template argument out of range"
) ? void (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 707, __extension__ __PRETTY_FUNCTION__))
;
708 return getArgs()[Idx];
709}
710
711inline const TemplateArgument &
712 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
713 assert(Idx < getNumArgs() && "Template argument out of range")(static_cast <bool> (Idx < getNumArgs() && "Template argument out of range"
) ? void (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 713, __extension__ __PRETTY_FUNCTION__))
;
714 return getArgs()[Idx];
715}
716
717inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
718 assert(Idx < getNumArgs() && "Template argument out of range")(static_cast <bool> (Idx < getNumArgs() && "Template argument out of range"
) ? void (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/clang/include/clang/AST/TemplateBase.h"
, 718, __extension__ __PRETTY_FUNCTION__))
;
719 return getArgs()[Idx];
720}
721
722} // namespace clang
723
724#endif // LLVM_CLANG_AST_TEMPLATEBASE_H

/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h

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// This file defines the PointerUnion class, which is a discriminated union of
10// pointer types.
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
24namespace llvm {
25
26namespace pointer_union_detail {
27 /// Determine the number of bits required to store integers with values < n.
28 /// This is ceil(log2(n)).
29 constexpr int bitsRequired(unsigned n) {
30 return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0;
31 }
32
33 template <typename... Ts> constexpr int lowBitsAvailable() {
34 return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...});
35 }
36
37 /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index
38 /// is the index of T in Us, or sizeof...(Us) if T does not appear in the
39 /// list.
40 template <typename T, typename ...Us> struct TypeIndex;
41 template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> {
42 static constexpr int Index = 0;
43 };
44 template <typename T, typename U, typename... Us>
45 struct TypeIndex<T, U, Us...> {
46 static constexpr int Index = 1 + TypeIndex<T, Us...>::Index;
47 };
48 template <typename T> struct TypeIndex<T> {
49 static constexpr int Index = 0;
50 };
51
52 /// Find the first type in a list of types.
53 template <typename T, typename...> struct GetFirstType {
54 using type = T;
55 };
56
57 /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
58 /// for the template arguments.
59 template <typename ...PTs> class PointerUnionUIntTraits {
60 public:
61 static inline void *getAsVoidPointer(void *P) { return P; }
62 static inline void *getFromVoidPointer(void *P) { return P; }
63 static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>();
64 };
65
66 template <typename Derived, typename ValTy, int I, typename ...Types>
67 class PointerUnionMembers;
68
69 template <typename Derived, typename ValTy, int I>
70 class PointerUnionMembers<Derived, ValTy, I> {
71 protected:
72 ValTy Val;
73 PointerUnionMembers() = default;
74 PointerUnionMembers(ValTy Val) : Val(Val) {}
75
76 friend struct PointerLikeTypeTraits<Derived>;
77 };
78
79 template <typename Derived, typename ValTy, int I, typename Type,
80 typename ...Types>
81 class PointerUnionMembers<Derived, ValTy, I, Type, Types...>
82 : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> {
83 using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>;
84 public:
85 using Base::Base;
86 PointerUnionMembers() = default;
87 PointerUnionMembers(Type V)
88 : Base(ValTy(const_cast<void *>(
89 PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
90 I)) {}
91
92 using Base::operator=;
93 Derived &operator=(Type V) {
94 this->Val = ValTy(
95 const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
96 I);
97 return static_cast<Derived &>(*this);
98 };
99 };
100}
101
102/// A discriminated union of two or more pointer types, with the discriminator
103/// in the low bit of the pointer.
104///
105/// This implementation is extremely efficient in space due to leveraging the
106/// low bits of the pointer, while exposing a natural and type-safe API.
107///
108/// Common use patterns would be something like this:
109/// PointerUnion<int*, float*> P;
110/// P = (int*)0;
111/// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
112/// X = P.get<int*>(); // ok.
113/// Y = P.get<float*>(); // runtime assertion failure.
114/// Z = P.get<double*>(); // compile time failure.
115/// P = (float*)0;
116/// Y = P.get<float*>(); // ok.
117/// X = P.get<int*>(); // runtime assertion failure.
118template <typename... PTs>
119class PointerUnion
120 : public pointer_union_detail::PointerUnionMembers<
121 PointerUnion<PTs...>,
122 PointerIntPair<
123 void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
124 pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
125 0, PTs...> {
126 // The first type is special because we want to directly cast a pointer to a
127 // default-initialized union to a pointer to the first type. But we don't
128 // want PointerUnion to be a 'template <typename First, typename ...Rest>'
129 // because it's much more convenient to have a name for the whole pack. So
130 // split off the first type here.
131 using First = typename pointer_union_detail::GetFirstType<PTs...>::type;
132 using Base = typename PointerUnion::PointerUnionMembers;
133
134public:
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 /// Test if the Union currently holds the type matching T.
147 template <typename T> bool is() const {
148 constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index;
149 static_assert(Index < sizeof...(PTs),
150 "PointerUnion::is<T> given type not in the union");
151 return this->Val.getInt() == Index;
29
Assuming the condition is false
30
Returning zero, which participates in a condition later
152 }
153
154 /// Returns the value of the specified pointer type.
155 ///
156 /// If the specified pointer type is incorrect, assert.
157 template <typename T> T get() const {
158 assert(is<T>() && "Invalid accessor called")(static_cast <bool> (is<T>() && "Invalid accessor called"
) ? void (0) : __assert_fail ("is<T>() && \"Invalid accessor called\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 158, __extension__ __PRETTY_FUNCTION__))
;
159 return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer());
160 }
161
162 /// Returns the current pointer if it is of the specified pointer type,
163 /// otherwise returns null.
164 template <typename T> T dyn_cast() const {
165 if (is<T>())
28
Calling 'PointerUnion::is'
31
Returning from 'PointerUnion::is'
32
Taking false branch
166 return get<T>();
167 return T();
33
Returning null pointer, which participates in a condition later
168 }
169
170 /// If the union is set to the first pointer type get an address pointing to
171 /// it.
172 First const *getAddrOfPtr1() const {
173 return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
174 }
175
176 /// If the union is set to the first pointer type get an address pointing to
177 /// it.
178 First *getAddrOfPtr1() {
179 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 179, __extension__ __PRETTY_FUNCTION__))
;
180 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 183, __extension__ __PRETTY_FUNCTION__))
181 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 183, __extension__ __PRETTY_FUNCTION__))
182 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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 183, __extension__ __PRETTY_FUNCTION__))
183 "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\""
, "/build/llvm-toolchain-snapshot-14~++20210828111110+16086d47c0d0/llvm/include/llvm/ADT/PointerUnion.h"
, 183, __extension__ __PRETTY_FUNCTION__))
;
184 return const_cast<First *>(
185 reinterpret_cast<const First *>(this->Val.getAddrOfPointer()));
186 }
187
188 /// Assignment from nullptr which just clears the union.
189 const PointerUnion &operator=(std::nullptr_t) {
190 this->Val.initWithPointer(nullptr);
191 return *this;
192 }
193
194 /// Assignment from elements of the union.
195 using Base::operator=;
196
197 void *getOpaqueValue() const { return this->Val.getOpaqueValue(); }
198 static inline PointerUnion getFromOpaqueValue(void *VP) {
199 PointerUnion V;
200 V.Val = decltype(V.Val)::getFromOpaqueValue(VP);
201 return V;
202 }
203};
204
205template <typename ...PTs>
206bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
207 return lhs.getOpaqueValue() == rhs.getOpaqueValue();
208}
209
210template <typename ...PTs>
211bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
212 return lhs.getOpaqueValue() != rhs.getOpaqueValue();
213}
214
215template <typename ...PTs>
216bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
217 return lhs.getOpaqueValue() < rhs.getOpaqueValue();
218}
219
220// Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
221// # low bits available = min(PT1bits,PT2bits)-1.
222template <typename ...PTs>
223struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
224 static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) {
225 return P.getOpaqueValue();
226 }
227
228 static inline PointerUnion<PTs...> getFromVoidPointer(void *P) {
229 return PointerUnion<PTs...>::getFromOpaqueValue(P);
230 }
231
232 // The number of bits available are the min of the pointer types minus the
233 // bits needed for the discriminator.
234 static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype(
235 PointerUnion<PTs...>::Val)>::NumLowBitsAvailable;
236};
237
238// Teach DenseMap how to use PointerUnions as keys.
239template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
240 using Union = PointerUnion<PTs...>;
241 using FirstInfo =
242 DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
243
244 static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
245
246 static inline Union getTombstoneKey() {
247 return Union(FirstInfo::getTombstoneKey());
248 }
249
250 static unsigned getHashValue(const Union &UnionVal) {
251 intptr_t key = (intptr_t)UnionVal.getOpaqueValue();
252 return DenseMapInfo<intptr_t>::getHashValue(key);
253 }
254
255 static bool isEqual(const Union &LHS, const Union &RHS) {
256 return LHS == RHS;
257 }
258};
259
260} // end namespace llvm
261
262#endif // LLVM_ADT_POINTERUNION_H