Bug Summary

File:clang/lib/Sema/SemaTemplateVariadic.cpp
Warning:line 710, 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 -clear-ast-before-backend -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/clang/lib/Sema -I /build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/llvm/include -D _FORTIFY_SOURCE=2 -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 -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/= -O3 -Wno-unused-command-line-argument -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~++20220118101002+ec47dba1c8a2/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -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-2022-01-19-001817-16337-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/clang/lib/Sema/SemaTemplateVariadic.cpp

/build/llvm-toolchain-snapshot-14~++20220118101002+ec47dba1c8a2/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 (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
312 LambdaParamPackReferences.push_back(Pack);
313 }
314
315 if (LambdaParamPackReferences.empty()) {
316 // Construct in lambda only references packs declared outside the lambda.
317 // That's OK for now, but the lambda itself is considered to contain an
318 // unexpanded pack in this case, which will require expansion outside the
319 // lambda.
320
321 // We do not permit pack expansion that would duplicate a statement
322 // expression, not even within a lambda.
323 // FIXME: We could probably support this for statement expressions that
324 // do not contain labels.
325 // FIXME: This is insufficient to detect this problem; consider
326 // f( ({ bad: 0; }) + pack ... );
327 bool EnclosingStmtExpr = false;
328 for (unsigned N = FunctionScopes.size(); N; --N) {
329 sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
330 if (llvm::any_of(
331 Func->CompoundScopes,
332 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
333 EnclosingStmtExpr = true;
334 break;
335 }
336 // Coumpound-statements outside the lambda are OK for now; we'll check
337 // for those when we finish handling the lambda.
338 if (Func == LSI)
339 break;
340 }
341
342 if (!EnclosingStmtExpr) {
343 LSI->ContainsUnexpandedParameterPack = true;
344 return false;
345 }
346 } else {
347 Unexpanded = LambdaParamPackReferences;
348 }
349 }
350
351 SmallVector<SourceLocation, 4> Locations;
352 SmallVector<IdentifierInfo *, 4> Names;
353 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
354
355 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
356 IdentifierInfo *Name = nullptr;
357 if (const TemplateTypeParmType *TTP
358 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
359 Name = TTP->getIdentifier();
360 else
361 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
362
363 if (Name && NamesKnown.insert(Name).second)
364 Names.push_back(Name);
365
366 if (Unexpanded[I].second.isValid())
367 Locations.push_back(Unexpanded[I].second);
368 }
369
370 auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
371 << (int)UPPC << (int)Names.size();
372 for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
373 DB << Names[I];
374
375 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
376 DB << SourceRange(Locations[I]);
377 return true;
378}
379
380bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
381 TypeSourceInfo *T,
382 UnexpandedParameterPackContext UPPC) {
383 // C++0x [temp.variadic]p5:
384 // An appearance of a name of a parameter pack that is not expanded is
385 // ill-formed.
386 if (!T->getType()->containsUnexpandedParameterPack())
387 return false;
388
389 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
390 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
391 T->getTypeLoc());
392 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 392, __extension__
__PRETTY_FUNCTION__))
;
393 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
394}
395
396bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
397 UnexpandedParameterPackContext UPPC) {
398 // C++0x [temp.variadic]p5:
399 // An appearance of a name of a parameter pack that is not expanded is
400 // ill-formed.
401 if (!E->containsUnexpandedParameterPack())
402 return false;
403
404 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
405 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
406 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 406, __extension__
__PRETTY_FUNCTION__))
;
407 return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
408}
409
410bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
411 if (!RE->containsUnexpandedParameterPack())
412 return false;
413
414 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
415 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
416 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 416, __extension__
__PRETTY_FUNCTION__))
;
417
418 // We only care about unexpanded references to the RequiresExpr's own
419 // parameter packs.
420 auto Parms = RE->getLocalParameters();
421 llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
422 SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
423 for (auto Parm : Unexpanded)
424 if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>()))
425 UnexpandedParms.push_back(Parm);
426 if (UnexpandedParms.empty())
427 return false;
428
429 return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
430 UnexpandedParms);
431}
432
433bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
434 UnexpandedParameterPackContext UPPC) {
435 // C++0x [temp.variadic]p5:
436 // An appearance of a name of a parameter pack that is not expanded is
437 // ill-formed.
438 if (!SS.getScopeRep() ||
439 !SS.getScopeRep()->containsUnexpandedParameterPack())
440 return false;
441
442 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
443 CollectUnexpandedParameterPacksVisitor(Unexpanded)
444 .TraverseNestedNameSpecifier(SS.getScopeRep());
445 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 445, __extension__
__PRETTY_FUNCTION__))
;
446 return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
447 UPPC, Unexpanded);
448}
449
450bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
451 UnexpandedParameterPackContext UPPC) {
452 // C++0x [temp.variadic]p5:
453 // An appearance of a name of a parameter pack that is not expanded is
454 // ill-formed.
455 switch (NameInfo.getName().getNameKind()) {
456 case DeclarationName::Identifier:
457 case DeclarationName::ObjCZeroArgSelector:
458 case DeclarationName::ObjCOneArgSelector:
459 case DeclarationName::ObjCMultiArgSelector:
460 case DeclarationName::CXXOperatorName:
461 case DeclarationName::CXXLiteralOperatorName:
462 case DeclarationName::CXXUsingDirective:
463 case DeclarationName::CXXDeductionGuideName:
464 return false;
465
466 case DeclarationName::CXXConstructorName:
467 case DeclarationName::CXXDestructorName:
468 case DeclarationName::CXXConversionFunctionName:
469 // FIXME: We shouldn't need this null check!
470 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
471 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
472
473 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
474 return false;
475
476 break;
477 }
478
479 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
480 CollectUnexpandedParameterPacksVisitor(Unexpanded)
481 .TraverseType(NameInfo.getName().getCXXNameType());
482 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 482, __extension__
__PRETTY_FUNCTION__))
;
483 return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
484}
485
486bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
487 TemplateName Template,
488 UnexpandedParameterPackContext UPPC) {
489
490 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
491 return false;
492
493 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
494 CollectUnexpandedParameterPacksVisitor(Unexpanded)
495 .TraverseTemplateName(Template);
496 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 496, __extension__
__PRETTY_FUNCTION__))
;
497 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
498}
499
500bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
501 UnexpandedParameterPackContext UPPC) {
502 if (Arg.getArgument().isNull() ||
503 !Arg.getArgument().containsUnexpandedParameterPack())
504 return false;
505
506 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
507 CollectUnexpandedParameterPacksVisitor(Unexpanded)
508 .TraverseTemplateArgumentLoc(Arg);
509 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")(static_cast <bool> (!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? void (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 509, __extension__
__PRETTY_FUNCTION__))
;
510 return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
511}
512
513void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
514 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
515 CollectUnexpandedParameterPacksVisitor(Unexpanded)
516 .TraverseTemplateArgument(Arg);
517}
518
519void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
520 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
521 CollectUnexpandedParameterPacksVisitor(Unexpanded)
522 .TraverseTemplateArgumentLoc(Arg);
523}
524
525void Sema::collectUnexpandedParameterPacks(QualType T,
526 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
527 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
528}
529
530void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
531 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
532 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
533}
534
535void Sema::collectUnexpandedParameterPacks(
536 NestedNameSpecifierLoc NNS,
537 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
538 CollectUnexpandedParameterPacksVisitor(Unexpanded)
539 .TraverseNestedNameSpecifierLoc(NNS);
540}
541
542void Sema::collectUnexpandedParameterPacks(
543 const DeclarationNameInfo &NameInfo,
544 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
545 CollectUnexpandedParameterPacksVisitor(Unexpanded)
546 .TraverseDeclarationNameInfo(NameInfo);
547}
548
549
550ParsedTemplateArgument
551Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
552 SourceLocation EllipsisLoc) {
553 if (Arg.isInvalid())
554 return Arg;
555
556 switch (Arg.getKind()) {
557 case ParsedTemplateArgument::Type: {
558 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
559 if (Result.isInvalid())
560 return ParsedTemplateArgument();
561
562 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
563 Arg.getLocation());
564 }
565
566 case ParsedTemplateArgument::NonType: {
567 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
568 if (Result.isInvalid())
569 return ParsedTemplateArgument();
570
571 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
572 Arg.getLocation());
573 }
574
575 case ParsedTemplateArgument::Template:
576 if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
577 SourceRange R(Arg.getLocation());
578 if (Arg.getScopeSpec().isValid())
579 R.setBegin(Arg.getScopeSpec().getBeginLoc());
580 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
581 << R;
582 return ParsedTemplateArgument();
583 }
584
585 return Arg.getTemplatePackExpansion(EllipsisLoc);
586 }
587 llvm_unreachable("Unhandled template argument kind?")::llvm::llvm_unreachable_internal("Unhandled template argument kind?"
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 587)
;
588}
589
590TypeResult Sema::ActOnPackExpansion(ParsedType Type,
591 SourceLocation EllipsisLoc) {
592 TypeSourceInfo *TSInfo;
593 GetTypeFromParser(Type, &TSInfo);
594 if (!TSInfo)
595 return true;
596
597 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
598 if (!TSResult)
599 return true;
600
601 return CreateParsedType(TSResult->getType(), TSResult);
602}
603
604TypeSourceInfo *
605Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
606 Optional<unsigned> NumExpansions) {
607 // Create the pack expansion type and source-location information.
608 QualType Result = CheckPackExpansion(Pattern->getType(),
609 Pattern->getTypeLoc().getSourceRange(),
610 EllipsisLoc, NumExpansions);
611 if (Result.isNull())
612 return nullptr;
613
614 TypeLocBuilder TLB;
615 TLB.pushFullCopy(Pattern->getTypeLoc());
616 PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
617 TL.setEllipsisLoc(EllipsisLoc);
618
619 return TLB.getTypeSourceInfo(Context, Result);
620}
621
622QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
623 SourceLocation EllipsisLoc,
624 Optional<unsigned> NumExpansions) {
625 // C++11 [temp.variadic]p5:
626 // The pattern of a pack expansion shall name one or more
627 // parameter packs that are not expanded by a nested pack
628 // expansion.
629 //
630 // A pattern containing a deduced type can't occur "naturally" but arises in
631 // the desugaring of an init-capture pack.
632 if (!Pattern->containsUnexpandedParameterPack() &&
633 !Pattern->getContainedDeducedType()) {
634 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
635 << PatternRange;
636 return QualType();
637 }
638
639 return Context.getPackExpansionType(Pattern, NumExpansions,
640 /*ExpectPackInType=*/false);
641}
642
643ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
644 return CheckPackExpansion(Pattern, EllipsisLoc, None);
645}
646
647ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
648 Optional<unsigned> NumExpansions) {
649 if (!Pattern)
650 return ExprError();
651
652 // C++0x [temp.variadic]p5:
653 // The pattern of a pack expansion shall name one or more
654 // parameter packs that are not expanded by a nested pack
655 // expansion.
656 if (!Pattern->containsUnexpandedParameterPack()) {
657 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
658 << Pattern->getSourceRange();
659 CorrectDelayedTyposInExpr(Pattern);
660 return ExprError();
661 }
662
663 // Create the pack expansion expression and source-location information.
664 return new (Context)
665 PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
666}
667
668bool Sema::CheckParameterPacksForExpansion(
669 SourceLocation EllipsisLoc, SourceRange PatternRange,
670 ArrayRef<UnexpandedParameterPack> Unexpanded,
671 const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
672 bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
673 ShouldExpand = true;
674 RetainExpansion = false;
675 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
676 bool HaveFirstPack = false;
677 Optional<unsigned> NumPartialExpansions;
678 SourceLocation PartiallySubstitutedPackLoc;
679
680 for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
2
Loop condition is true. Entering loop body
26
Loop condition is true. Entering loop body
681 end = Unexpanded.end();
682 i != end; ++i) {
1
Assuming 'i' is not equal to 'end'
683 // Compute the depth and index for this parameter pack.
684 unsigned Depth = 0, Index = 0;
685 IdentifierInfo *Name;
686 bool IsVarDeclPack = false;
687
688 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
689 = i->first.dyn_cast<const TemplateTypeParmType *>()) {
27
Calling 'PointerUnion::dyn_cast'
34
Returning from 'PointerUnion::dyn_cast'
690 Depth = TTP->getDepth(); 691 Index = TTP->getIndex(); 692 Name = TTP->getIdentifier(); 693 } else { 694 NamedDecl *ND = i->first.get<NamedDecl *>(); 695 if (isa<VarDecl>(ND))
36
Assuming 'ND' is a 'VarDecl'
37
Taking true branch
696 IsVarDeclPack = true; 697 else 698 std::tie(Depth, Index) = getDepthAndIndex(ND); 699 700 Name = ND->getIdentifier(); 701 } 702 703 // Determine the size of this argument pack. 704 unsigned NewPackSize; 705 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
706 // Figure out whether we're instantiating to an argument pack or not. 707 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; 708 709 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation 710 = CurrentInstantiationScope->findInstantiationOf(
39
Called C++ object pointer is null
711 i->first.get<NamedDecl *>()); 712 if (Instantiation->is<DeclArgumentPack *>()) { 713 // We could expand this function parameter pack. 714 NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); 715 } else { 716 // We can't expand this function parameter pack, so we can't expand 717 // the pack expansion. 718 ShouldExpand = false; 719 continue; 720 } 721 } else { 722 // If we don't have a template argument at this depth/index, then we 723 // cannot expand the pack expansion. Make a note of this, but we still 724 // want to check any parameter packs we *do* have arguments for. 725 if (Depth >= TemplateArgs.getNumLevels() ||
5
Assuming the condition is false
18
Taking false branch
726 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
6
Calling 'MultiLevelTemplateArgumentList::hasTemplateArgument'
17
Returning from 'MultiLevelTemplateArgumentList::hasTemplateArgument'
727 ShouldExpand = false; 728 continue; 729 } 730 731 // Determine the size of the argument pack. 732 NewPackSize = TemplateArgs(Depth, Index).pack_size(); 733 } 734 735 // C++0x [temp.arg.explicit]p9: 736 // Template argument deduction can extend the sequence of template 737 // arguments corresponding to a template parameter pack, even when the 738 // sequence contains explicitly specified template arguments. 739 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
740 if (NamedDecl *PartialPack 741 = CurrentInstantiationScope->getPartiallySubstitutedPack()){ 742 unsigned PartialDepth, PartialIndex; 743 std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); 744 if (PartialDepth == Depth && PartialIndex == Index) { 745 RetainExpansion = true; 746 // We don't actually know the new pack size yet. 747 NumPartialExpansions = NewPackSize; 748 PartiallySubstitutedPackLoc = i->second; 749 continue; 750 } 751 } 752 } 753 754 if (!NumExpansions) {
22
Assuming the condition is false
23
Taking false branch
755 // The is the first pack we've seen for which we have an argument. 756 // Record it. 757 NumExpansions = NewPackSize; 758 FirstPack.first = Name; 759 FirstPack.second = i->second; 760 HaveFirstPack = true; 761 continue; 762 } 763 764 if (NewPackSize != *NumExpansions) {
24
Assuming the condition is false
25
Taking false branch
765 // C++0x [temp.variadic]p5: 766 // All of the parameter packs expanded by a pack expansion shall have 767 // the same number of arguments specified. 768 if (HaveFirstPack) 769 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) 770 << FirstPack.first << Name << *NumExpansions << NewPackSize 771 << SourceRange(FirstPack.second) << SourceRange(i->second); 772 else 773 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) 774 << Name << *NumExpansions << NewPackSize 775 << SourceRange(i->second); 776 return true; 777 } 778 } 779 780 // If we're performing a partial expansion but we also have a full expansion, 781 // expand to the number of common arguments. For example, given: 782 // 783 // template<typename ...T> struct A { 784 // template<typename ...U> void f(pair<T, U>...); 785 // }; 786 // 787 // ... a call to 'A<int, int>().f<int>' should expand the pack once and 788 // retain an expansion. 789 if (NumPartialExpansions) { 790 if (NumExpansions && *NumExpansions < *NumPartialExpansions) { 791 NamedDecl *PartialPack = 792 CurrentInstantiationScope->getPartiallySubstitutedPack(); 793 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) 794 << PartialPack << *NumPartialExpansions << *NumExpansions 795 << SourceRange(PartiallySubstitutedPackLoc); 796 return true; 797 } 798 799 NumExpansions = NumPartialExpansions; 800 } 801 802 return false; 803} 804 805Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, 806 const MultiLevelTemplateArgumentList &TemplateArgs) { 807 QualType Pattern = cast<PackExpansionType>(T)->getPattern(); 808 SmallVector<UnexpandedParameterPack, 2> Unexpanded; 809 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); 810 811 Optional<unsigned> Result; 812 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { 813 // Compute the depth and index for this parameter pack. 814 unsigned Depth; 815 unsigned Index; 816 817 if (const TemplateTypeParmType *TTP 818 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { 819 Depth = TTP->getDepth(); 820 Index = TTP->getIndex(); 821 } else { 822 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); 823 if (isa<VarDecl>(ND)) { 824 // Function parameter pack or init-capture pack. 825 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; 826 827 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation 828 = CurrentInstantiationScope->findInstantiationOf( 829 Unexpanded[I].first.get<NamedDecl *>()); 830 if (Instantiation->is<Decl*>()) 831 // The pattern refers to an unexpanded pack. We're not ready to expand 832 // this pack yet. 833 return None; 834 835 unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); 836 assert((!Result || *Result == Size) && "inconsistent pack sizes")(static_cast <bool> ((!Result || *Result == Size) &&
"inconsistent pack sizes") ? void (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 836, __extension__
__PRETTY_FUNCTION__))
; 837 Result = Size; 838 continue; 839 } 840 841 std::tie(Depth, Index) = getDepthAndIndex(ND); 842 } 843 if (Depth >= TemplateArgs.getNumLevels() || 844 !TemplateArgs.hasTemplateArgument(Depth, Index)) 845 // The pattern refers to an unknown template argument. We're not ready to 846 // expand this pack yet. 847 return None; 848 849 // Determine the size of the argument pack. 850 unsigned Size = TemplateArgs(Depth, Index).pack_size(); 851 assert((!Result || *Result == Size) && "inconsistent pack sizes")(static_cast <bool> ((!Result || *Result == Size) &&
"inconsistent pack sizes") ? void (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\""
, "clang/lib/Sema/SemaTemplateVariadic.cpp", 851, __extension__
__PRETTY_FUNCTION__))
; 852 Result = Size; 853 } 854 855 return Result; 856} 857 858bool Sema::containsUnexpandedParameterPacks(Declarator &D) { 859 const DeclSpec &DS = D.getDeclSpec(); 860 switch (DS.getTypeSpecType()) { 861 case TST_typename: 862 case TST_typeofType: 863 case TST_underlyingType: 864 case TST_atomic: { 865 QualType T = DS.getRepAsType().get(); 866 if (!T.isNull() && T->containsUnexpandedParameterPack()) 867 return true; 868 break; 869 } 870 871 case TST_typeofExpr: 872 case TST_decltype: 873 case TST_bitint: 874 if (DS.getRepAsExpr() && 875 DS.getRepAsExpr()->containsUnexpandedParameterPack()) 876 return true; 877 break; 878 879 case TST_unspecified: 880 case TST_void: 881 case TST_char: 882 case TST_wchar: 883 case TST_char8: 884 case TST_char16: 885 case TST_char32: 886 case TST_int: 887 case TST_int128: 888 case TST_half: 889 case TST_float: 890 case TST_double: 891 case TST_Accum: 892 case TST_Fract: 893 case TST_Float16: 894 case TST_float128: 895 case TST_ibm128: 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?\""
, "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()", "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!"
, "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()"
, "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\""
, "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~++20220118101002+ec47dba1c8a2/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()"
, "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()"
, "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()", "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()"
, "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()"
, "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?\""
, "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?\""
, "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\""
, "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~++20220118101002+ec47dba1c8a2/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 Expr;
56struct PrintingPolicy;
57class TypeSourceInfo;
58class ValueDecl;
59
60/// Represents a template argument.
61class TemplateArgument {
62public:
63 /// The kind of template argument we're storing.
64 enum ArgKind {
65 /// Represents an empty template argument, e.g., one that has not
66 /// been deduced.
67 Null = 0,
68
69 /// The template argument is a type.
70 Type,
71
72 /// The template argument is a declaration that was provided for a pointer,
73 /// reference, or pointer to member non-type template parameter.
74 Declaration,
75
76 /// The template argument is a null pointer or null pointer to member that
77 /// was provided for a non-type template parameter.
78 NullPtr,
79
80 /// The template argument is an integral value stored in an llvm::APSInt
81 /// that was provided for an integral non-type template parameter.
82 Integral,
83
84 /// The template argument is a template name that was provided for a
85 /// template template parameter.
86 Template,
87
88 /// The template argument is a pack expansion of a template name that was
89 /// provided for a template template parameter.
90 TemplateExpansion,
91
92 /// The template argument is an expression, and we've not resolved it to one
93 /// of the other forms yet, either because it's dependent or because we're
94 /// representing a non-canonical template argument (for instance, in a
95 /// TemplateSpecializationType).
96 Expression,
97
98 /// The template argument is actually a parameter pack. Arguments are stored
99 /// in the Args struct.
100 Pack
101 };
102
103private:
104 /// The kind of template argument we're storing.
105
106 struct DA {
107 unsigned Kind;
108 void *QT;
109 ValueDecl *D;
110 };
111 struct I {
112 unsigned Kind;
113 // We store a decomposed APSInt with the data allocated by ASTContext if
114 // BitWidth > 64. The memory may be shared between multiple
115 // TemplateArgument instances.
116 unsigned BitWidth : 31;
117 unsigned IsUnsigned : 1;
118 union {
119 /// Used to store the <= 64 bits integer value.
120 uint64_t VAL;
121
122 /// Used to store the >64 bits integer value.
123 const uint64_t *pVal;
124 };
125 void *Type;
126 };
127 struct A {
128 unsigned Kind;
129 unsigned NumArgs;
130 const TemplateArgument *Args;
131 };
132 struct TA {
133 unsigned Kind;
134 unsigned NumExpansions;
135 void *Name;
136 };
137 struct TV {
138 unsigned Kind;
139 uintptr_t V;
140 };
141 union {
142 struct DA DeclArg;
143 struct I Integer;
144 struct A Args;
145 struct TA TemplateArg;
146 struct TV TypeOrValue;
147 };
148
149public:
150 /// Construct an empty, invalid template argument.
151 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
152
153 /// Construct a template type argument.
154 TemplateArgument(QualType T, bool isNullPtr = false) {
155 TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
156 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
157 }
158
159 /// Construct a template argument that refers to a
160 /// declaration, which is either an external declaration or a
161 /// template declaration.
162 TemplateArgument(ValueDecl *D, QualType QT) {
163 assert(D && "Expected decl")(static_cast <bool> (D && "Expected decl") ? void
(0) : __assert_fail ("D && \"Expected decl\"", "clang/include/clang/AST/TemplateBase.h"
, 163, __extension__ __PRETTY_FUNCTION__))
;
164 DeclArg.Kind = Declaration;
165 DeclArg.QT = QT.getAsOpaquePtr();
166 DeclArg.D = D;
167 }
168
169 /// Construct an integral constant template argument. The memory to
170 /// store the value is allocated with Ctx.
171 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
172
173 /// Construct an integral constant template argument with the same
174 /// value as Other but a different type.
175 TemplateArgument(const TemplateArgument &Other, QualType Type) {
176 Integer = Other.Integer;
177 Integer.Type = Type.getAsOpaquePtr();
178 }
179
180 /// Construct a template argument that is a template.
181 ///
182 /// This form of template argument is generally used for template template
183 /// parameters. However, the template name could be a dependent template
184 /// name that ends up being instantiated to a function template whose address
185 /// is taken.
186 ///
187 /// \param Name The template name.
188 TemplateArgument(TemplateName Name) {
189 TemplateArg.Kind = Template;
190 TemplateArg.Name = Name.getAsVoidPointer();
191 TemplateArg.NumExpansions = 0;
192 }
193
194 /// Construct a template argument that is a template pack expansion.
195 ///
196 /// This form of template argument is generally used for template template
197 /// parameters. However, the template name could be a dependent template
198 /// name that ends up being instantiated to a function template whose address
199 /// is taken.
200 ///
201 /// \param Name The template name.
202 ///
203 /// \param NumExpansions The number of expansions that will be generated by
204 /// instantiating
205 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
206 TemplateArg.Kind = TemplateExpansion;
207 TemplateArg.Name = Name.getAsVoidPointer();
208 if (NumExpansions)
209 TemplateArg.NumExpansions = *NumExpansions + 1;
210 else
211 TemplateArg.NumExpansions = 0;
212 }
213
214 /// Construct a template argument that is an expression.
215 ///
216 /// This form of template argument only occurs in template argument
217 /// lists used for dependent types and for expression; it will not
218 /// occur in a non-dependent, canonical template argument list.
219 TemplateArgument(Expr *E) {
220 TypeOrValue.Kind = Expression;
221 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
222 }
223
224 /// Construct a template argument that is a template argument pack.
225 ///
226 /// We assume that storage for the template arguments provided
227 /// outlives the TemplateArgument itself.
228 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
229 this->Args.Kind = Pack;
230 this->Args.Args = Args.data();
231 this->Args.NumArgs = Args.size();
232 }
233
234 TemplateArgument(TemplateName, bool) = delete;
235
236 static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
237
238 /// Create a new template argument pack by copying the given set of
239 /// template arguments.
240 static TemplateArgument CreatePackCopy(ASTContext &Context,
241 ArrayRef<TemplateArgument> Args);
242
243 /// Return the kind of stored template argument.
244 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
245
246 /// Determine whether this template argument has no value.
247 bool isNull() const { return getKind() == Null; }
13
Assuming the condition is false
14
Returning zero, which participates in a condition later
248
249 TemplateArgumentDependence getDependence() const;
250
251 /// Whether this template argument is dependent on a template
252 /// parameter such that its result can change from one instantiation to
253 /// another.
254 bool isDependent() const;
255
256 /// Whether this template argument is dependent on a template
257 /// parameter.
258 bool isInstantiationDependent() const;
259
260 /// Whether this template argument contains an unexpanded
261 /// parameter pack.
262 bool containsUnexpandedParameterPack() const;
263
264 /// Determine whether this template argument is a pack expansion.
265 bool isPackExpansion() const;
266
267 /// Retrieve the type for a type template argument.
268 QualType getAsType() const {
269 assert(getKind() == Type && "Unexpected kind")(static_cast <bool> (getKind() == Type && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Type && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 269, __extension__
__PRETTY_FUNCTION__))
;
270 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
271 }
272
273 /// Retrieve the declaration for a declaration non-type
274 /// template argument.
275 ValueDecl *getAsDecl() const {
276 assert(getKind() == Declaration && "Unexpected kind")(static_cast <bool> (getKind() == Declaration &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 276, __extension__
__PRETTY_FUNCTION__))
;
277 return DeclArg.D;
278 }
279
280 QualType getParamTypeForDecl() const {
281 assert(getKind() == Declaration && "Unexpected kind")(static_cast <bool> (getKind() == Declaration &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 281, __extension__
__PRETTY_FUNCTION__))
;
282 return QualType::getFromOpaquePtr(DeclArg.QT);
283 }
284
285 /// Retrieve the type for null non-type template argument.
286 QualType getNullPtrType() const {
287 assert(getKind() == NullPtr && "Unexpected kind")(static_cast <bool> (getKind() == NullPtr && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == NullPtr && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 287, __extension__
__PRETTY_FUNCTION__))
;
288 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
289 }
290
291 /// Retrieve the template name for a template name argument.
292 TemplateName getAsTemplate() const {
293 assert(getKind() == Template && "Unexpected kind")(static_cast <bool> (getKind() == Template && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Template && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 293, __extension__
__PRETTY_FUNCTION__))
;
294 return TemplateName::getFromVoidPointer(TemplateArg.Name);
295 }
296
297 /// Retrieve the template argument as a template name; if the argument
298 /// is a pack expansion, return the pattern as a template name.
299 TemplateName getAsTemplateOrTemplatePattern() const {
300 assert((getKind() == Template || getKind() == TemplateExpansion) &&(static_cast <bool> ((getKind() == Template || getKind(
) == TemplateExpansion) && "Unexpected kind") ? void (
0) : __assert_fail ("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 301, __extension__
__PRETTY_FUNCTION__))
301 "Unexpected kind")(static_cast <bool> ((getKind() == Template || getKind(
) == TemplateExpansion) && "Unexpected kind") ? void (
0) : __assert_fail ("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 301, __extension__
__PRETTY_FUNCTION__))
;
302
303 return TemplateName::getFromVoidPointer(TemplateArg.Name);
304 }
305
306 /// Retrieve the number of expansions that a template template argument
307 /// expansion will produce, if known.
308 Optional<unsigned> getNumTemplateExpansions() const;
309
310 /// Retrieve the template argument as an integral value.
311 // FIXME: Provide a way to read the integral data without copying the value.
312 llvm::APSInt getAsIntegral() const {
313 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 313, __extension__
__PRETTY_FUNCTION__))
;
314
315 using namespace llvm;
316
317 if (Integer.BitWidth <= 64)
318 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
319
320 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
321 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
322 Integer.IsUnsigned);
323 }
324
325 /// Retrieve the type of the integral value.
326 QualType getIntegralType() const {
327 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 327, __extension__
__PRETTY_FUNCTION__))
;
328 return QualType::getFromOpaquePtr(Integer.Type);
329 }
330
331 void setIntegralType(QualType T) {
332 assert(getKind() == Integral && "Unexpected kind")(static_cast <bool> (getKind() == Integral && "Unexpected kind"
) ? void (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 332, __extension__
__PRETTY_FUNCTION__))
;
333 Integer.Type = T.getAsOpaquePtr();
334 }
335
336 /// If this is a non-type template argument, get its type. Otherwise,
337 /// returns a null QualType.
338 QualType getNonTypeTemplateArgumentType() const;
339
340 /// Retrieve the template argument as an expression.
341 Expr *getAsExpr() const {
342 assert(getKind() == Expression && "Unexpected kind")(static_cast <bool> (getKind() == Expression &&
"Unexpected kind") ? void (0) : __assert_fail ("getKind() == Expression && \"Unexpected kind\""
, "clang/include/clang/AST/TemplateBase.h", 342, __extension__
__PRETTY_FUNCTION__))
;
343 return reinterpret_cast<Expr *>(TypeOrValue.V);
344 }
345
346 /// Iterator that traverses the elements of a template argument pack.
347 using pack_iterator = const TemplateArgument *;
348
349 /// Iterator referencing the first argument of a template argument
350 /// pack.
351 pack_iterator pack_begin() const {
352 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "clang/include/clang/AST/TemplateBase.h"
, 352, __extension__ __PRETTY_FUNCTION__))
;
353 return Args.Args;
354 }
355
356 /// Iterator referencing one past the last argument of a template
357 /// argument pack.
358 pack_iterator pack_end() const {
359 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "clang/include/clang/AST/TemplateBase.h"
, 359, __extension__ __PRETTY_FUNCTION__))
;
360 return Args.Args + Args.NumArgs;
361 }
362
363 /// Iterator range referencing all of the elements of a template
364 /// argument pack.
365 ArrayRef<TemplateArgument> pack_elements() const {
366 return llvm::makeArrayRef(pack_begin(), pack_end());
367 }
368
369 /// The number of template arguments in the given template argument
370 /// pack.
371 unsigned pack_size() const {
372 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "clang/include/clang/AST/TemplateBase.h"
, 372, __extension__ __PRETTY_FUNCTION__))
;
373 return Args.NumArgs;
374 }
375
376 /// Return the array of arguments in this template argument pack.
377 ArrayRef<TemplateArgument> getPackAsArray() const {
378 assert(getKind() == Pack)(static_cast <bool> (getKind() == Pack) ? void (0) : __assert_fail
("getKind() == Pack", "clang/include/clang/AST/TemplateBase.h"
, 378, __extension__ __PRETTY_FUNCTION__))
;
379 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
380 }
381
382 /// Determines whether two template arguments are superficially the
383 /// same.
384 bool structurallyEquals(const TemplateArgument &Other) const;
385
386 /// When the template argument is a pack expansion, returns
387 /// the pattern of the pack expansion.
388 TemplateArgument getPackExpansionPattern() const;
389
390 /// Print this template argument to the given output stream.
391 void print(const PrintingPolicy &Policy, raw_ostream &Out,
392 bool IncludeType) const;
393
394 /// Debugging aid that dumps the template argument.
395 void dump(raw_ostream &Out) const;
396
397 /// Debugging aid that dumps the template argument to standard error.
398 void dump() const;
399
400 /// Used to insert TemplateArguments into FoldingSets.
401 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
402};
403
404/// Location information for a TemplateArgument.
405struct TemplateArgumentLocInfo {
406private:
407 struct TemplateTemplateArgLocInfo {
408 // FIXME: We'd like to just use the qualifier in the TemplateName,
409 // but template arguments get canonicalized too quickly.
410 NestedNameSpecifier *Qualifier;
411 void *QualifierLocData;
412 SourceLocation TemplateNameLoc;
413 SourceLocation EllipsisLoc;
414 };
415
416 llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
417 Pointer;
418
419 TemplateTemplateArgLocInfo *getTemplate() const {
420 return Pointer.get<TemplateTemplateArgLocInfo *>();
421 }
422
423public:
424 TemplateArgumentLocInfo() {}
425 TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
426
427 TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
428 // Ctx is used for allocation -- this case is unusually large and also rare,
429 // so we store the payload out-of-line.
430 TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
431 SourceLocation TemplateNameLoc,
432 SourceLocation EllipsisLoc);
433
434 TypeSourceInfo *getAsTypeSourceInfo() const {
435 return Pointer.get<TypeSourceInfo *>();
436 }
437
438 Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
439
440 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
441 const auto *Template = getTemplate();
442 return NestedNameSpecifierLoc(Template->Qualifier,
443 Template->QualifierLocData);
444 }
445
446 SourceLocation getTemplateNameLoc() const {
447 return getTemplate()->TemplateNameLoc;
448 }
449
450 SourceLocation getTemplateEllipsisLoc() const {
451 return getTemplate()->EllipsisLoc;
452 }
453};
454
455/// Location wrapper for a TemplateArgument. TemplateArgument is to
456/// TemplateArgumentLoc as Type is to TypeLoc.
457class TemplateArgumentLoc {
458 TemplateArgument Argument;
459 TemplateArgumentLocInfo LocInfo;
460
461public:
462 TemplateArgumentLoc() {}
463
464 TemplateArgumentLoc(const TemplateArgument &Argument,
465 TemplateArgumentLocInfo Opaque)
466 : Argument(Argument), LocInfo(Opaque) {}
467
468 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
469 : Argument(Argument), LocInfo(TInfo) {
470 assert(Argument.getKind() == TemplateArgument::Type)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Type) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "clang/include/clang/AST/TemplateBase.h", 470, __extension__
__PRETTY_FUNCTION__))
;
471 }
472
473 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
474 : Argument(Argument), LocInfo(E) {
475
476 // Permit any kind of template argument that can be represented with an
477 // expression.
478 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"
, "clang/include/clang/AST/TemplateBase.h", 481, __extension__
__PRETTY_FUNCTION__))
479 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"
, "clang/include/clang/AST/TemplateBase.h", 481, __extension__
__PRETTY_FUNCTION__))
480 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"
, "clang/include/clang/AST/TemplateBase.h", 481, __extension__
__PRETTY_FUNCTION__))
481 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"
, "clang/include/clang/AST/TemplateBase.h", 481, __extension__
__PRETTY_FUNCTION__))
;
482 }
483
484 TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
485 NestedNameSpecifierLoc QualifierLoc,
486 SourceLocation TemplateNameLoc,
487 SourceLocation EllipsisLoc = SourceLocation())
488 : Argument(Argument),
489 LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
490 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"
, "clang/include/clang/AST/TemplateBase.h", 491, __extension__
__PRETTY_FUNCTION__))
491 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"
, "clang/include/clang/AST/TemplateBase.h", 491, __extension__
__PRETTY_FUNCTION__))
;
492 }
493
494 /// - Fetches the primary location of the argument.
495 SourceLocation getLocation() const {
496 if (Argument.getKind() == TemplateArgument::Template ||
497 Argument.getKind() == TemplateArgument::TemplateExpansion)
498 return getTemplateNameLoc();
499
500 return getSourceRange().getBegin();
501 }
502
503 /// - Fetches the full source range of the argument.
504 SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__));
505
506 const TemplateArgument &getArgument() const {
507 return Argument;
508 }
509
510 TemplateArgumentLocInfo getLocInfo() const {
511 return LocInfo;
512 }
513
514 TypeSourceInfo *getTypeSourceInfo() const {
515 if (Argument.getKind() != TemplateArgument::Type)
516 return nullptr;
517 return LocInfo.getAsTypeSourceInfo();
518 }
519
520 Expr *getSourceExpression() const {
521 assert(Argument.getKind() == TemplateArgument::Expression)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Expression) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Expression"
, "clang/include/clang/AST/TemplateBase.h", 521, __extension__
__PRETTY_FUNCTION__))
;
522 return LocInfo.getAsExpr();
523 }
524
525 Expr *getSourceDeclExpression() const {
526 assert(Argument.getKind() == TemplateArgument::Declaration)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Declaration) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Declaration"
, "clang/include/clang/AST/TemplateBase.h", 526, __extension__
__PRETTY_FUNCTION__))
;
527 return LocInfo.getAsExpr();
528 }
529
530 Expr *getSourceNullPtrExpression() const {
531 assert(Argument.getKind() == TemplateArgument::NullPtr)(static_cast <bool> (Argument.getKind() == TemplateArgument
::NullPtr) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::NullPtr"
, "clang/include/clang/AST/TemplateBase.h", 531, __extension__
__PRETTY_FUNCTION__))
;
532 return LocInfo.getAsExpr();
533 }
534
535 Expr *getSourceIntegralExpression() const {
536 assert(Argument.getKind() == TemplateArgument::Integral)(static_cast <bool> (Argument.getKind() == TemplateArgument
::Integral) ? void (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Integral"
, "clang/include/clang/AST/TemplateBase.h", 536, __extension__
__PRETTY_FUNCTION__))
;
537 return LocInfo.getAsExpr();
538 }
539
540 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
541 if (Argument.getKind() != TemplateArgument::Template &&
542 Argument.getKind() != TemplateArgument::TemplateExpansion)
543 return NestedNameSpecifierLoc();
544 return LocInfo.getTemplateQualifierLoc();
545 }
546
547 SourceLocation getTemplateNameLoc() const {
548 if (Argument.getKind() != TemplateArgument::Template &&
549 Argument.getKind() != TemplateArgument::TemplateExpansion)
550 return SourceLocation();
551 return LocInfo.getTemplateNameLoc();
552 }
553
554 SourceLocation getTemplateEllipsisLoc() const {
555 if (Argument.getKind() != TemplateArgument::TemplateExpansion)
556 return SourceLocation();
557 return LocInfo.getTemplateEllipsisLoc();
558 }
559};
560
561/// A convenient class for passing around template argument
562/// information. Designed to be passed by reference.
563class TemplateArgumentListInfo {
564 SmallVector<TemplateArgumentLoc, 8> Arguments;
565 SourceLocation LAngleLoc;
566 SourceLocation RAngleLoc;
567
568public:
569 TemplateArgumentListInfo() = default;
570
571 TemplateArgumentListInfo(SourceLocation LAngleLoc,
572 SourceLocation RAngleLoc)
573 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
574
575 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
576 // instead.
577 void *operator new(size_t bytes, ASTContext &C) = delete;
578
579 SourceLocation getLAngleLoc() const { return LAngleLoc; }
580 SourceLocation getRAngleLoc() const { return RAngleLoc; }
581
582 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
583 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
584
585 unsigned size() const { return Arguments.size(); }
586
587 const TemplateArgumentLoc *getArgumentArray() const {
588 return Arguments.data();
589 }
590
591 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
592 return Arguments;
593 }
594
595 const TemplateArgumentLoc &operator[](unsigned I) const {
596 return Arguments[I];
597 }
598
599 TemplateArgumentLoc &operator[](unsigned I) {
600 return Arguments[I];
601 }
602
603 void addArgument(const TemplateArgumentLoc &Loc) {
604 Arguments.push_back(Loc);
605 }
606};
607
608/// Represents an explicit template argument list in C++, e.g.,
609/// the "<int>" in "sort<int>".
610/// This is safe to be used inside an AST node, in contrast with
611/// TemplateArgumentListInfo.
612struct ASTTemplateArgumentListInfo final
613 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
614 TemplateArgumentLoc> {
615private:
616 friend class ASTNodeImporter;
617 friend TrailingObjects;
618
619 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
620
621public:
622 /// The source location of the left angle bracket ('<').
623 SourceLocation LAngleLoc;
624
625 /// The source location of the right angle bracket ('>').
626 SourceLocation RAngleLoc;
627
628 /// The number of template arguments in TemplateArgs.
629 unsigned NumTemplateArgs;
630
631 SourceLocation getLAngleLoc() const { return LAngleLoc; }
632 SourceLocation getRAngleLoc() const { return RAngleLoc; }
633
634 /// Retrieve the template arguments
635 const TemplateArgumentLoc *getTemplateArgs() const {
636 return getTrailingObjects<TemplateArgumentLoc>();
637 }
638 unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
639
640 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
641 return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
642 }
643
644 const TemplateArgumentLoc &operator[](unsigned I) const {
645 return getTemplateArgs()[I];
646 }
647
648 static const ASTTemplateArgumentListInfo *
649 Create(const ASTContext &C, const TemplateArgumentListInfo &List);
650};
651
652/// Represents an explicit template argument list in C++, e.g.,
653/// the "<int>" in "sort<int>".
654///
655/// It is intended to be used as a trailing object on AST nodes, and
656/// as such, doesn't contain the array of TemplateArgumentLoc itself,
657/// but expects the containing object to also provide storage for
658/// that.
659struct alignas(void *) ASTTemplateKWAndArgsInfo {
660 /// The source location of the left angle bracket ('<').
661 SourceLocation LAngleLoc;
662
663 /// The source location of the right angle bracket ('>').
664 SourceLocation RAngleLoc;
665
666 /// The source location of the template keyword; this is used
667 /// as part of the representation of qualified identifiers, such as
668 /// S<T>::template apply<T>. Will be empty if this expression does
669 /// not have a template keyword.
670 SourceLocation TemplateKWLoc;
671
672 /// The number of template arguments in TemplateArgs.
673 unsigned NumTemplateArgs;
674
675 void initializeFrom(SourceLocation TemplateKWLoc,
676 const TemplateArgumentListInfo &List,
677 TemplateArgumentLoc *OutArgArray);
678 // FIXME: The parameter Deps is the result populated by this method, the
679 // caller doesn't need it since it is populated by computeDependence. remove
680 // it.
681 void initializeFrom(SourceLocation TemplateKWLoc,
682 const TemplateArgumentListInfo &List,
683 TemplateArgumentLoc *OutArgArray,
684 TemplateArgumentDependence &Deps);
685 void initializeFrom(SourceLocation TemplateKWLoc);
686
687 void copyInto(const TemplateArgumentLoc *ArgArray,
688 TemplateArgumentListInfo &List) const;
689};
690
691const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
692 const TemplateArgument &Arg);
693
694inline TemplateSpecializationType::iterator
695 TemplateSpecializationType::end() const {
696 return getArgs() + getNumArgs();
697}
698
699inline DependentTemplateSpecializationType::iterator
700 DependentTemplateSpecializationType::end() const {
701 return getArgs() + getNumArgs();
702}
703
704inline const TemplateArgument &
705 TemplateSpecializationType::getArg(unsigned Idx) const {
706 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\""
, "clang/include/clang/AST/TemplateBase.h", 706, __extension__
__PRETTY_FUNCTION__))
;
707 return getArgs()[Idx];
708}
709
710inline const TemplateArgument &
711 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
712 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\""
, "clang/include/clang/AST/TemplateBase.h", 712, __extension__
__PRETTY_FUNCTION__))
;
713 return getArgs()[Idx];
714}
715
716inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
717 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\""
, "clang/include/clang/AST/TemplateBase.h", 717, __extension__
__PRETTY_FUNCTION__))
;
718 return getArgs()[Idx];
719}
720
721} // namespace clang
722
723#endif // LLVM_CLANG_AST_TEMPLATEBASE_H

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