Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaTemplateVariadic.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-09-17-195756-12974-1 -x c++ /build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp

/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp

1//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===/
7//
8// This file implements semantic analysis for C++0x variadic templates.
9//===----------------------------------------------------------------------===/
10
11#include "clang/Sema/Sema.h"
12#include "TypeLocBuilder.h"
13#include "clang/AST/Expr.h"
14#include "clang/AST/RecursiveASTVisitor.h"
15#include "clang/AST/TypeLoc.h"
16#include "clang/Sema/Lookup.h"
17#include "clang/Sema/ParsedTemplate.h"
18#include "clang/Sema/ScopeInfo.h"
19#include "clang/Sema/SemaInternal.h"
20#include "clang/Sema/Template.h"
21
22using namespace clang;
23
24//----------------------------------------------------------------------------
25// Visitor that collects unexpanded parameter packs
26//----------------------------------------------------------------------------
27
28namespace {
29 /// A class that collects unexpanded parameter packs.
30 class CollectUnexpandedParameterPacksVisitor :
31 public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
32 {
33 typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
34 inherited;
35
36 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
37
38 bool InLambda = false;
39 unsigned DepthLimit = (unsigned)-1;
40
41 void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
42 if (auto *VD = dyn_cast<VarDecl>(ND)) {
43 // For now, the only problematic case is a generic lambda's templated
44 // call operator, so we don't need to look for all the other ways we
45 // could have reached a dependent parameter pack.
46 auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
47 auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
48 if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
49 return;
50 } else if (getDepthAndIndex(ND).first >= DepthLimit)
51 return;
52
53 Unexpanded.push_back({ND, Loc});
54 }
55 void addUnexpanded(const TemplateTypeParmType *T,
56 SourceLocation Loc = SourceLocation()) {
57 if (T->getDepth() < DepthLimit)
58 Unexpanded.push_back({T, Loc});
59 }
60
61 public:
62 explicit CollectUnexpandedParameterPacksVisitor(
63 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
64 : Unexpanded(Unexpanded) {}
65
66 bool shouldWalkTypesOfTypeLocs() const { return false; }
67
68 //------------------------------------------------------------------------
69 // Recording occurrences of (unexpanded) parameter packs.
70 //------------------------------------------------------------------------
71
72 /// Record occurrences of template type parameter packs.
73 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
74 if (TL.getTypePtr()->isParameterPack())
75 addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
76 return true;
77 }
78
79 /// Record occurrences of template type parameter packs
80 /// when we don't have proper source-location information for
81 /// them.
82 ///
83 /// Ideally, this routine would never be used.
84 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
85 if (T->isParameterPack())
86 addUnexpanded(T);
87
88 return true;
89 }
90
91 /// Record occurrences of function and non-type template
92 /// parameter packs in an expression.
93 bool VisitDeclRefExpr(DeclRefExpr *E) {
94 if (E->getDecl()->isParameterPack())
95 addUnexpanded(E->getDecl(), E->getLocation());
96
97 return true;
98 }
99
100 /// Record occurrences of template template parameter packs.
101 bool TraverseTemplateName(TemplateName Template) {
102 if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
103 Template.getAsTemplateDecl())) {
104 if (TTP->isParameterPack())
105 addUnexpanded(TTP);
106 }
107
108 return inherited::TraverseTemplateName(Template);
109 }
110
111 /// Suppress traversal into Objective-C container literal
112 /// elements that are pack expansions.
113 bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
114 if (!E->containsUnexpandedParameterPack())
115 return true;
116
117 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
118 ObjCDictionaryElement Element = E->getKeyValueElement(I);
119 if (Element.isPackExpansion())
120 continue;
121
122 TraverseStmt(Element.Key);
123 TraverseStmt(Element.Value);
124 }
125 return true;
126 }
127 //------------------------------------------------------------------------
128 // Pruning the search for unexpanded parameter packs.
129 //------------------------------------------------------------------------
130
131 /// Suppress traversal into statements and expressions that
132 /// do not contain unexpanded parameter packs.
133 bool TraverseStmt(Stmt *S) {
134 Expr *E = dyn_cast_or_null<Expr>(S);
135 if ((E && E->containsUnexpandedParameterPack()) || InLambda)
136 return inherited::TraverseStmt(S);
137
138 return true;
139 }
140
141 /// Suppress traversal into types that do not contain
142 /// unexpanded parameter packs.
143 bool TraverseType(QualType T) {
144 if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
145 return inherited::TraverseType(T);
146
147 return true;
148 }
149
150 /// Suppress traversal into types with location information
151 /// that do not contain unexpanded parameter packs.
152 bool TraverseTypeLoc(TypeLoc TL) {
153 if ((!TL.getType().isNull() &&
154 TL.getType()->containsUnexpandedParameterPack()) ||
155 InLambda)
156 return inherited::TraverseTypeLoc(TL);
157
158 return true;
159 }
160
161 /// Suppress traversal of parameter packs.
162 bool TraverseDecl(Decl *D) {
163 // A function parameter pack is a pack expansion, so cannot contain
164 // an unexpanded parameter pack. Likewise for a template parameter
165 // pack that contains any references to other packs.
166 if (D && D->isParameterPack())
167 return true;
168
169 return inherited::TraverseDecl(D);
170 }
171
172 /// Suppress traversal of pack-expanded attributes.
173 bool TraverseAttr(Attr *A) {
174 if (A->isPackExpansion())
175 return true;
176
177 return inherited::TraverseAttr(A);
178 }
179
180 /// Suppress traversal of pack expansion expressions and types.
181 ///@{
182 bool TraversePackExpansionType(PackExpansionType *T) { return true; }
183 bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
184 bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
185 bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
186
187 ///@}
188
189 /// Suppress traversal of using-declaration pack expansion.
190 bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
191 if (D->isPackExpansion())
192 return true;
193
194 return inherited::TraverseUnresolvedUsingValueDecl(D);
195 }
196
197 /// Suppress traversal of using-declaration pack expansion.
198 bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
199 if (D->isPackExpansion())
200 return true;
201
202 return inherited::TraverseUnresolvedUsingTypenameDecl(D);
203 }
204
205 /// Suppress traversal of template argument pack expansions.
206 bool TraverseTemplateArgument(const TemplateArgument &Arg) {
207 if (Arg.isPackExpansion())
208 return true;
209
210 return inherited::TraverseTemplateArgument(Arg);
211 }
212
213 /// Suppress traversal of template argument pack expansions.
214 bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
215 if (ArgLoc.getArgument().isPackExpansion())
216 return true;
217
218 return inherited::TraverseTemplateArgumentLoc(ArgLoc);
219 }
220
221 /// Suppress traversal of base specifier pack expansions.
222 bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
223 if (Base.isPackExpansion())
224 return true;
225
226 return inherited::TraverseCXXBaseSpecifier(Base);
227 }
228
229 /// Suppress traversal of mem-initializer pack expansions.
230 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
231 if (Init->isPackExpansion())
232 return true;
233
234 return inherited::TraverseConstructorInitializer(Init);
235 }
236
237 /// Note whether we're traversing a lambda containing an unexpanded
238 /// parameter pack. In this case, the unexpanded pack can occur anywhere,
239 /// including all the places where we normally wouldn't look. Within a
240 /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
241 /// outside an expression.
242 bool TraverseLambdaExpr(LambdaExpr *Lambda) {
243 // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
244 // even if it's contained within another lambda.
245 if (!Lambda->containsUnexpandedParameterPack())
246 return true;
247
248 bool WasInLambda = InLambda;
249 unsigned OldDepthLimit = DepthLimit;
250
251 InLambda = true;
252 if (auto *TPL = Lambda->getTemplateParameterList())
253 DepthLimit = TPL->getDepth();
254
255 inherited::TraverseLambdaExpr(Lambda);
256
257 InLambda = WasInLambda;
258 DepthLimit = OldDepthLimit;
259 return true;
260 }
261
262 /// Suppress traversal within pack expansions in lambda captures.
263 bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
264 Expr *Init) {
265 if (C->isPackExpansion())
266 return true;
267
268 return inherited::TraverseLambdaCapture(Lambda, C, Init);
269 }
270 };
271}
272
273/// Determine whether it's possible for an unexpanded parameter pack to
274/// be valid in this location. This only happens when we're in a declaration
275/// that is nested within an expression that could be expanded, such as a
276/// lambda-expression within a function call.
277///
278/// This is conservatively correct, but may claim that some unexpanded packs are
279/// permitted when they are not.
280bool Sema::isUnexpandedParameterPackPermitted() {
281 for (auto *SI : FunctionScopes)
282 if (isa<sema::LambdaScopeInfo>(SI))
283 return true;
284 return false;
285}
286
287/// Diagnose all of the unexpanded parameter packs in the given
288/// vector.
289bool
290Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
291 UnexpandedParameterPackContext UPPC,
292 ArrayRef<UnexpandedParameterPack> Unexpanded) {
293 if (Unexpanded.empty())
294 return false;
295
296 // If we are within a lambda expression and referencing a pack that is not
297 // declared within the lambda itself, that lambda contains an unexpanded
298 // parameter pack, and we are done.
299 // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
300 // later.
301 SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
302 if (auto *LSI = getEnclosingLambda()) {
303 for (auto &Pack : Unexpanded) {
304 auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
305 if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
306 auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
307 return TTPD && TTPD->getTypeForDecl() == TTPT;
308 }
309 return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
310 };
311 if (std::find_if(LSI->LocalPacks.begin(), LSI->LocalPacks.end(),
312 DeclaresThisPack) != LSI->LocalPacks.end())
313 LambdaParamPackReferences.push_back(Pack);
314 }
315
316 if (LambdaParamPackReferences.empty()) {
317 // Construct in lambda only references packs declared outside the lambda.
318 // That's OK for now, but the lambda itself is considered to contain an
319 // unexpanded pack in this case, which will require expansion outside the
320 // lambda.
321
322 // We do not permit pack expansion that would duplicate a statement
323 // expression, not even within a lambda.
324 // FIXME: We could probably support this for statement expressions that
325 // do not contain labels.
326 // FIXME: This is insufficient to detect this problem; consider
327 // f( ({ bad: 0; }) + pack ... );
328 bool EnclosingStmtExpr = false;
329 for (unsigned N = FunctionScopes.size(); N; --N) {
330 sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
331 if (std::any_of(
332 Func->CompoundScopes.begin(), Func->CompoundScopes.end(),
333 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
334 EnclosingStmtExpr = true;
335 break;
336 }
337 // Coumpound-statements outside the lambda are OK for now; we'll check
338 // for those when we finish handling the lambda.
339 if (Func == LSI)
340 break;
341 }
342
343 if (!EnclosingStmtExpr) {
344 LSI->ContainsUnexpandedParameterPack = true;
345 return false;
346 }
347 } else {
348 Unexpanded = LambdaParamPackReferences;
349 }
350 }
351
352 SmallVector<SourceLocation, 4> Locations;
353 SmallVector<IdentifierInfo *, 4> Names;
354 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
355
356 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
357 IdentifierInfo *Name = nullptr;
358 if (const TemplateTypeParmType *TTP
359 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
360 Name = TTP->getIdentifier();
361 else
362 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
363
364 if (Name && NamesKnown.insert(Name).second)
365 Names.push_back(Name);
366
367 if (Unexpanded[I].second.isValid())
368 Locations.push_back(Unexpanded[I].second);
369 }
370
371 DiagnosticBuilder DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
372 << (int)UPPC << (int)Names.size();
373 for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
374 DB << Names[I];
375
376 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
377 DB << SourceRange(Locations[I]);
378 return true;
379}
380
381bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
382 TypeSourceInfo *T,
383 UnexpandedParameterPackContext UPPC) {
384 // C++0x [temp.variadic]p5:
385 // An appearance of a name of a parameter pack that is not expanded is
386 // ill-formed.
387 if (!T->getType()->containsUnexpandedParameterPack())
388 return false;
389
390 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
391 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
392 T->getTypeLoc());
393 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 393, __PRETTY_FUNCTION__))
;
394 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
395}
396
397bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
398 UnexpandedParameterPackContext UPPC) {
399 // C++0x [temp.variadic]p5:
400 // An appearance of a name of a parameter pack that is not expanded is
401 // ill-formed.
402 if (!E->containsUnexpandedParameterPack())
403 return false;
404
405 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
406 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
407 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 407, __PRETTY_FUNCTION__))
;
408 return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
409}
410
411bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
412 if (!RE->containsUnexpandedParameterPack())
413 return false;
414
415 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
416 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
417 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 417, __PRETTY_FUNCTION__))
;
418
419 // We only care about unexpanded references to the RequiresExpr's own
420 // parameter packs.
421 auto Parms = RE->getLocalParameters();
422 llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
423 SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
424 for (auto Parm : Unexpanded)
425 if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>()))
426 UnexpandedParms.push_back(Parm);
427 if (UnexpandedParms.empty())
428 return false;
429
430 return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
431 UnexpandedParms);
432}
433
434bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
435 UnexpandedParameterPackContext UPPC) {
436 // C++0x [temp.variadic]p5:
437 // An appearance of a name of a parameter pack that is not expanded is
438 // ill-formed.
439 if (!SS.getScopeRep() ||
440 !SS.getScopeRep()->containsUnexpandedParameterPack())
441 return false;
442
443 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
444 CollectUnexpandedParameterPacksVisitor(Unexpanded)
445 .TraverseNestedNameSpecifier(SS.getScopeRep());
446 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 446, __PRETTY_FUNCTION__))
;
447 return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
448 UPPC, Unexpanded);
449}
450
451bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
452 UnexpandedParameterPackContext UPPC) {
453 // C++0x [temp.variadic]p5:
454 // An appearance of a name of a parameter pack that is not expanded is
455 // ill-formed.
456 switch (NameInfo.getName().getNameKind()) {
457 case DeclarationName::Identifier:
458 case DeclarationName::ObjCZeroArgSelector:
459 case DeclarationName::ObjCOneArgSelector:
460 case DeclarationName::ObjCMultiArgSelector:
461 case DeclarationName::CXXOperatorName:
462 case DeclarationName::CXXLiteralOperatorName:
463 case DeclarationName::CXXUsingDirective:
464 case DeclarationName::CXXDeductionGuideName:
465 return false;
466
467 case DeclarationName::CXXConstructorName:
468 case DeclarationName::CXXDestructorName:
469 case DeclarationName::CXXConversionFunctionName:
470 // FIXME: We shouldn't need this null check!
471 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
472 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
473
474 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
475 return false;
476
477 break;
478 }
479
480 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
481 CollectUnexpandedParameterPacksVisitor(Unexpanded)
482 .TraverseType(NameInfo.getName().getCXXNameType());
483 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 483, __PRETTY_FUNCTION__))
;
484 return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
485}
486
487bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
488 TemplateName Template,
489 UnexpandedParameterPackContext UPPC) {
490
491 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
492 return false;
493
494 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
495 CollectUnexpandedParameterPacksVisitor(Unexpanded)
496 .TraverseTemplateName(Template);
497 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 497, __PRETTY_FUNCTION__))
;
498 return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
499}
500
501bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
502 UnexpandedParameterPackContext UPPC) {
503 if (Arg.getArgument().isNull() ||
504 !Arg.getArgument().containsUnexpandedParameterPack())
505 return false;
506
507 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
508 CollectUnexpandedParameterPacksVisitor(Unexpanded)
509 .TraverseTemplateArgumentLoc(Arg);
510 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs")((!Unexpanded.empty() && "Unable to find unexpanded parameter packs"
) ? static_cast<void> (0) : __assert_fail ("!Unexpanded.empty() && \"Unable to find unexpanded parameter packs\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 510, __PRETTY_FUNCTION__))
;
511 return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
512}
513
514void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
515 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
516 CollectUnexpandedParameterPacksVisitor(Unexpanded)
517 .TraverseTemplateArgument(Arg);
518}
519
520void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
521 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
522 CollectUnexpandedParameterPacksVisitor(Unexpanded)
523 .TraverseTemplateArgumentLoc(Arg);
524}
525
526void Sema::collectUnexpandedParameterPacks(QualType T,
527 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
528 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
529}
530
531void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
532 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
533 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
534}
535
536void Sema::collectUnexpandedParameterPacks(
537 NestedNameSpecifierLoc NNS,
538 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
539 CollectUnexpandedParameterPacksVisitor(Unexpanded)
540 .TraverseNestedNameSpecifierLoc(NNS);
541}
542
543void Sema::collectUnexpandedParameterPacks(
544 const DeclarationNameInfo &NameInfo,
545 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
546 CollectUnexpandedParameterPacksVisitor(Unexpanded)
547 .TraverseDeclarationNameInfo(NameInfo);
548}
549
550
551ParsedTemplateArgument
552Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
553 SourceLocation EllipsisLoc) {
554 if (Arg.isInvalid())
555 return Arg;
556
557 switch (Arg.getKind()) {
558 case ParsedTemplateArgument::Type: {
559 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
560 if (Result.isInvalid())
561 return ParsedTemplateArgument();
562
563 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
564 Arg.getLocation());
565 }
566
567 case ParsedTemplateArgument::NonType: {
568 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
569 if (Result.isInvalid())
570 return ParsedTemplateArgument();
571
572 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
573 Arg.getLocation());
574 }
575
576 case ParsedTemplateArgument::Template:
577 if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
578 SourceRange R(Arg.getLocation());
579 if (Arg.getScopeSpec().isValid())
580 R.setBegin(Arg.getScopeSpec().getBeginLoc());
581 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
582 << R;
583 return ParsedTemplateArgument();
584 }
585
586 return Arg.getTemplatePackExpansion(EllipsisLoc);
587 }
588 llvm_unreachable("Unhandled template argument kind?")::llvm::llvm_unreachable_internal("Unhandled template argument kind?"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 588)
;
589}
590
591TypeResult Sema::ActOnPackExpansion(ParsedType Type,
592 SourceLocation EllipsisLoc) {
593 TypeSourceInfo *TSInfo;
594 GetTypeFromParser(Type, &TSInfo);
595 if (!TSInfo)
596 return true;
597
598 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
599 if (!TSResult)
600 return true;
601
602 return CreateParsedType(TSResult->getType(), TSResult);
603}
604
605TypeSourceInfo *
606Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
607 Optional<unsigned> NumExpansions) {
608 // Create the pack expansion type and source-location information.
609 QualType Result = CheckPackExpansion(Pattern->getType(),
610 Pattern->getTypeLoc().getSourceRange(),
611 EllipsisLoc, NumExpansions);
612 if (Result.isNull())
613 return nullptr;
614
615 TypeLocBuilder TLB;
616 TLB.pushFullCopy(Pattern->getTypeLoc());
617 PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
618 TL.setEllipsisLoc(EllipsisLoc);
619
620 return TLB.getTypeSourceInfo(Context, Result);
621}
622
623QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
624 SourceLocation EllipsisLoc,
625 Optional<unsigned> NumExpansions) {
626 // C++11 [temp.variadic]p5:
627 // The pattern of a pack expansion shall name one or more
628 // parameter packs that are not expanded by a nested pack
629 // expansion.
630 //
631 // A pattern containing a deduced type can't occur "naturally" but arises in
632 // the desugaring of an init-capture pack.
633 if (!Pattern->containsUnexpandedParameterPack() &&
634 !Pattern->getContainedDeducedType()) {
635 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
636 << PatternRange;
637 return QualType();
638 }
639
640 return Context.getPackExpansionType(Pattern, NumExpansions,
641 /*ExpectPackInType=*/false);
642}
643
644ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
645 return CheckPackExpansion(Pattern, EllipsisLoc, None);
646}
647
648ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
649 Optional<unsigned> NumExpansions) {
650 if (!Pattern)
651 return ExprError();
652
653 // C++0x [temp.variadic]p5:
654 // The pattern of a pack expansion shall name one or more
655 // parameter packs that are not expanded by a nested pack
656 // expansion.
657 if (!Pattern->containsUnexpandedParameterPack()) {
658 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
659 << Pattern->getSourceRange();
660 CorrectDelayedTyposInExpr(Pattern);
661 return ExprError();
662 }
663
664 // Create the pack expansion expression and source-location information.
665 return new (Context)
666 PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
667}
668
669bool Sema::CheckParameterPacksForExpansion(
670 SourceLocation EllipsisLoc, SourceRange PatternRange,
671 ArrayRef<UnexpandedParameterPack> Unexpanded,
672 const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
673 bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
674 ShouldExpand = true;
675 RetainExpansion = false;
676 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
677 bool HaveFirstPack = false;
678 Optional<unsigned> NumPartialExpansions;
679 SourceLocation PartiallySubstitutedPackLoc;
680
681 for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
2
Loop condition is true. Entering loop body
28
Loop condition is true. Entering loop body
682 end = Unexpanded.end();
683 i != end; ++i) {
1
Assuming 'i' is not equal to 'end'
684 // Compute the depth and index for this parameter pack.
685 unsigned Depth = 0, Index = 0;
686 IdentifierInfo *Name;
687 bool IsVarDeclPack = false;
688
689 if (const TemplateTypeParmType *TTP
2.1
'TTP' is null
36.1
'TTP' is null
2.1
'TTP' is null
36.1
'TTP' is null
2.1
'TTP' is null
36.1
'TTP' is null
2.1
'TTP' is null
36.1
'TTP' is null
3
Taking false branch
37
Taking false branch
690 = i->first.dyn_cast<const TemplateTypeParmType *>()) {
29
Calling 'PointerUnion::dyn_cast'
36
Returning from 'PointerUnion::dyn_cast'
691 Depth = TTP->getDepth(); 692 Index = TTP->getIndex(); 693 Name = TTP->getIdentifier(); 694 } else { 695 NamedDecl *ND = i->first.get<NamedDecl *>(); 696 if (isa<VarDecl>(ND))
4
Assuming 'ND' is not a 'VarDecl'
5
Taking false branch
38
Assuming 'ND' is a 'VarDecl'
39
Taking true branch
697 IsVarDeclPack = true; 698 else 699 std::tie(Depth, Index) = getDepthAndIndex(ND); 700 701 Name = ND->getIdentifier(); 702 } 703 704 // Determine the size of this argument pack. 705 unsigned NewPackSize; 706 if (IsVarDeclPack
5.1
'IsVarDeclPack' is false
39.1
'IsVarDeclPack' is true
5.1
'IsVarDeclPack' is false
39.1
'IsVarDeclPack' is true
5.1
'IsVarDeclPack' is false
39.1
'IsVarDeclPack' is true
5.1
'IsVarDeclPack' is false
39.1
'IsVarDeclPack' is true
) {
6
Taking false branch
40
Taking true branch
707 // Figure out whether we're instantiating to an argument pack or not. 708 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; 709 710 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation 711 = CurrentInstantiationScope->findInstantiationOf(
41
Called C++ object pointer is null
712 i->first.get<NamedDecl *>()); 713 if (Instantiation->is<DeclArgumentPack *>()) { 714 // We could expand this function parameter pack. 715 NewPackSize = Instantiation->get<DeclArgumentPack *>()->size(); 716 } else { 717 // We can't expand this function parameter pack, so we can't expand 718 // the pack expansion. 719 ShouldExpand = false; 720 continue; 721 } 722 } else { 723 // If we don't have a template argument at this depth/index, then we 724 // cannot expand the pack expansion. Make a note of this, but we still 725 // want to check any parameter packs we *do* have arguments for. 726 if (Depth >= TemplateArgs.getNumLevels() ||
7
Assuming the condition is false
20
Taking false branch
727 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
8
Calling 'MultiLevelTemplateArgumentList::hasTemplateArgument'
19
Returning from 'MultiLevelTemplateArgumentList::hasTemplateArgument'
728 ShouldExpand = false; 729 continue; 730 } 731 732 // Determine the size of the argument pack. 733 NewPackSize = TemplateArgs(Depth, Index).pack_size(); 734 } 735 736 // C++0x [temp.arg.explicit]p9: 737 // Template argument deduction can extend the sequence of template 738 // arguments corresponding to a template parameter pack, even when the 739 // sequence contains explicitly specified template arguments. 740 if (!IsVarDeclPack
20.1
'IsVarDeclPack' is false
20.1
'IsVarDeclPack' is false
20.1
'IsVarDeclPack' is false
20.1
'IsVarDeclPack' is false
&& CurrentInstantiationScope
) {
21
Assuming field 'CurrentInstantiationScope' is null
22
Assuming pointer value is null
23
Taking false branch
741 if (NamedDecl *PartialPack 742 = CurrentInstantiationScope->getPartiallySubstitutedPack()){ 743 unsigned PartialDepth, PartialIndex; 744 std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack); 745 if (PartialDepth == Depth && PartialIndex == Index) { 746 RetainExpansion = true; 747 // We don't actually know the new pack size yet. 748 NumPartialExpansions = NewPackSize; 749 PartiallySubstitutedPackLoc = i->second; 750 continue; 751 } 752 } 753 } 754 755 if (!NumExpansions) {
24
Assuming the condition is false
25
Taking false branch
756 // The is the first pack we've seen for which we have an argument. 757 // Record it. 758 NumExpansions = NewPackSize; 759 FirstPack.first = Name; 760 FirstPack.second = i->second; 761 HaveFirstPack = true; 762 continue; 763 } 764 765 if (NewPackSize != *NumExpansions) {
26
Assuming the condition is false
27
Taking false branch
766 // C++0x [temp.variadic]p5: 767 // All of the parameter packs expanded by a pack expansion shall have 768 // the same number of arguments specified. 769 if (HaveFirstPack) 770 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) 771 << FirstPack.first << Name << *NumExpansions << NewPackSize 772 << SourceRange(FirstPack.second) << SourceRange(i->second); 773 else 774 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) 775 << Name << *NumExpansions << NewPackSize 776 << SourceRange(i->second); 777 return true; 778 } 779 } 780 781 // If we're performing a partial expansion but we also have a full expansion, 782 // expand to the number of common arguments. For example, given: 783 // 784 // template<typename ...T> struct A { 785 // template<typename ...U> void f(pair<T, U>...); 786 // }; 787 // 788 // ... a call to 'A<int, int>().f<int>' should expand the pack once and 789 // retain an expansion. 790 if (NumPartialExpansions) { 791 if (NumExpansions && *NumExpansions < *NumPartialExpansions) { 792 NamedDecl *PartialPack = 793 CurrentInstantiationScope->getPartiallySubstitutedPack(); 794 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial) 795 << PartialPack << *NumPartialExpansions << *NumExpansions 796 << SourceRange(PartiallySubstitutedPackLoc); 797 return true; 798 } 799 800 NumExpansions = NumPartialExpansions; 801 } 802 803 return false; 804} 805 806Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T, 807 const MultiLevelTemplateArgumentList &TemplateArgs) { 808 QualType Pattern = cast<PackExpansionType>(T)->getPattern(); 809 SmallVector<UnexpandedParameterPack, 2> Unexpanded; 810 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern); 811 812 Optional<unsigned> Result; 813 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { 814 // Compute the depth and index for this parameter pack. 815 unsigned Depth; 816 unsigned Index; 817 818 if (const TemplateTypeParmType *TTP 819 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { 820 Depth = TTP->getDepth(); 821 Index = TTP->getIndex(); 822 } else { 823 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); 824 if (isa<VarDecl>(ND)) { 825 // Function parameter pack or init-capture pack. 826 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; 827 828 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation 829 = CurrentInstantiationScope->findInstantiationOf( 830 Unexpanded[I].first.get<NamedDecl *>()); 831 if (Instantiation->is<Decl*>()) 832 // The pattern refers to an unexpanded pack. We're not ready to expand 833 // this pack yet. 834 return None; 835 836 unsigned Size = Instantiation->get<DeclArgumentPack *>()->size(); 837 assert((!Result || *Result == Size) && "inconsistent pack sizes")(((!Result || *Result == Size) && "inconsistent pack sizes"
) ? static_cast<void> (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 837, __PRETTY_FUNCTION__))
; 838 Result = Size; 839 continue; 840 } 841 842 std::tie(Depth, Index) = getDepthAndIndex(ND); 843 } 844 if (Depth >= TemplateArgs.getNumLevels() || 845 !TemplateArgs.hasTemplateArgument(Depth, Index)) 846 // The pattern refers to an unknown template argument. We're not ready to 847 // expand this pack yet. 848 return None; 849 850 // Determine the size of the argument pack. 851 unsigned Size = TemplateArgs(Depth, Index).pack_size(); 852 assert((!Result || *Result == Size) && "inconsistent pack sizes")(((!Result || *Result == Size) && "inconsistent pack sizes"
) ? static_cast<void> (0) : __assert_fail ("(!Result || *Result == Size) && \"inconsistent pack sizes\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 852, __PRETTY_FUNCTION__))
; 853 Result = Size; 854 } 855 856 return Result; 857} 858 859bool Sema::containsUnexpandedParameterPacks(Declarator &D) { 860 const DeclSpec &DS = D.getDeclSpec(); 861 switch (DS.getTypeSpecType()) { 862 case TST_typename: 863 case TST_typeofType: 864 case TST_underlyingType: 865 case TST_atomic: { 866 QualType T = DS.getRepAsType().get(); 867 if (!T.isNull() && T->containsUnexpandedParameterPack()) 868 return true; 869 break; 870 } 871 872 case TST_typeofExpr: 873 case TST_decltype: 874 case TST_extint: 875 if (DS.getRepAsExpr() && 876 DS.getRepAsExpr()->containsUnexpandedParameterPack()) 877 return true; 878 break; 879 880 case TST_unspecified: 881 case TST_void: 882 case TST_char: 883 case TST_wchar: 884 case TST_char8: 885 case TST_char16: 886 case TST_char32: 887 case TST_int: 888 case TST_int128: 889 case TST_half: 890 case TST_float: 891 case TST_double: 892 case TST_Accum: 893 case TST_Fract: 894 case TST_Float16: 895 case TST_float128: 896 case TST_bool: 897 case TST_decimal32: 898 case TST_decimal64: 899 case TST_decimal128: 900 case TST_enum: 901 case TST_union: 902 case TST_struct: 903 case TST_interface: 904 case TST_class: 905 case TST_auto: 906 case TST_auto_type: 907 case TST_decltype_auto: 908 case TST_BFloat16: 909#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: 910#include "clang/Basic/OpenCLImageTypes.def" 911 case TST_unknown_anytype: 912 case TST_error: 913 break; 914 } 915 916 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { 917 const DeclaratorChunk &Chunk = D.getTypeObject(I); 918 switch (Chunk.Kind) { 919 case DeclaratorChunk::Pointer: 920 case DeclaratorChunk::Reference: 921 case DeclaratorChunk::Paren: 922 case DeclaratorChunk::Pipe: 923 case DeclaratorChunk::BlockPointer: 924 // These declarator chunks cannot contain any parameter packs. 925 break; 926 927 case DeclaratorChunk::Array: 928 if (Chunk.Arr.NumElts && 929 Chunk.Arr.NumElts->containsUnexpandedParameterPack()) 930 return true; 931 break; 932 case DeclaratorChunk::Function: 933 for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) { 934 ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param); 935 QualType ParamTy = Param->getType(); 936 assert(!ParamTy.isNull() && "Couldn't parse type?")((!ParamTy.isNull() && "Couldn't parse type?") ? static_cast
<void> (0) : __assert_fail ("!ParamTy.isNull() && \"Couldn't parse type?\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 936, __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())((Argument.isPackExpansion()) ? static_cast<void> (0) :
__assert_fail ("Argument.isPackExpansion()", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1059, __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(Argument.getPackExpansionPattern(), 1099 OrigLoc.getTemplateQualifierLoc(), 1100 OrigLoc.getTemplateNameLoc()); 1101 1102 case TemplateArgument::Declaration: 1103 case TemplateArgument::NullPtr: 1104 case TemplateArgument::Template: 1105 case TemplateArgument::Integral: 1106 case TemplateArgument::Pack: 1107 case TemplateArgument::Null: 1108 return TemplateArgumentLoc(); 1109 } 1110 1111 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1111)
; 1112} 1113 1114Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) { 1115 assert(Arg.containsUnexpandedParameterPack())((Arg.containsUnexpandedParameterPack()) ? static_cast<void
> (0) : __assert_fail ("Arg.containsUnexpandedParameterPack()"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1115, __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")((Pack && "fold expression with neither LHS nor RHS")
? static_cast<void> (0) : __assert_fail ("Pack && \"fold expression with neither LHS nor RHS\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/lib/Sema/SemaTemplateVariadic.cpp"
, 1220, __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-12~++20200917111122+b03c2b8395b/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())((NumRetainedOuterLevels <= Depth && Depth < getNumLevels
()) ? static_cast<void> (0) : __assert_fail ("NumRetainedOuterLevels <= Depth && Depth < getNumLevels()"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 140, __PRETTY_FUNCTION__))
;
141 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size())((Index < TemplateArgumentLists[getNumLevels() - Depth - 1
].size()) ? static_cast<void> (0) : __assert_fail ("Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 141, __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())((Depth < getNumLevels()) ? static_cast<void> (0) : __assert_fail
("Depth < getNumLevels()", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 150, __PRETTY_FUNCTION__))
;
9
'?' condition is true
151
152 if (Depth < NumRetainedOuterLevels)
10
Assuming 'Depth' is >= field 'NumRetainedOuterLevels'
11
Taking false branch
153 return false;
154
155 if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size())
12
Assuming the condition is false
13
Taking false branch
156 return false;
157
158 return !(*this)(Depth, Index).isNull();
14
Calling 'TemplateArgument::isNull'
17
Returning from 'TemplateArgument::isNull'
18
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())((NumRetainedOuterLevels <= Depth && Depth < getNumLevels
()) ? static_cast<void> (0) : __assert_fail ("NumRetainedOuterLevels <= Depth && Depth < getNumLevels()"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 164, __PRETTY_FUNCTION__))
;
165 assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size())((Index < TemplateArgumentLists[getNumLevels() - Depth - 1
].size()) ? static_cast<void> (0) : __assert_fail ("Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 165, __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 &&((!NumRetainedOuterLevels && "substituted args outside retained args?"
) ? static_cast<void> (0) : __assert_fail ("!NumRetainedOuterLevels && \"substituted args outside retained args?\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 182, __PRETTY_FUNCTION__))
182 "substituted args outside retained args?")((!NumRetainedOuterLevels && "substituted args outside retained args?"
) ? static_cast<void> (0) : __assert_fail ("!NumRetainedOuterLevels && \"substituted args outside retained args?\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 182, __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")((PartiallySubstitutedPack && "No partially-substituted pack"
) ? static_cast<void> (0) : __assert_fail ("PartiallySubstitutedPack && \"No partially-substituted pack\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/Sema/Template.h"
, 446, __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
541 // Enable late instantiation of attributes. Late instantiated attributes
542 // will be stored in LA.
543 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
544 LateAttrs = LA;
545 StartingScope = SemaRef.CurrentInstantiationScope;
546 }
547
548 // Disable late instantiation of attributes.
549 void disableLateAttributeInstantiation() {
550 LateAttrs = nullptr;
551 StartingScope = nullptr;
552 }
553
554 LocalInstantiationScope *getStartingScope() const { return StartingScope; }
555
556 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
557 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
558
559 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
560 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
561
562 /// Return an iterator to the beginning of the set of
563 /// "delayed" partial specializations, which must be passed to
564 /// InstantiateClassTemplatePartialSpecialization once the class
565 /// definition has been completed.
566 delayed_partial_spec_iterator delayed_partial_spec_begin() {
567 return OutOfLinePartialSpecs.begin();
568 }
569
570 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
571 return OutOfLineVarPartialSpecs.begin();
572 }
573
574 /// Return an iterator to the end of the set of
575 /// "delayed" partial specializations, which must be passed to
576 /// InstantiateClassTemplatePartialSpecialization once the class
577 /// definition has been completed.
578 delayed_partial_spec_iterator delayed_partial_spec_end() {
579 return OutOfLinePartialSpecs.end();
580 }
581
582 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
583 return OutOfLineVarPartialSpecs.end();
584 }
585
586 // Helper functions for instantiating methods.
587 TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
588 SmallVectorImpl<ParmVarDecl *> &Params);
589 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
590 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
591
592 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl);
593
594 TemplateParameterList *
595 SubstTemplateParams(TemplateParameterList *List);
596
597 bool SubstQualifier(const DeclaratorDecl *OldDecl,
598 DeclaratorDecl *NewDecl);
599 bool SubstQualifier(const TagDecl *OldDecl,
600 TagDecl *NewDecl);
601
602 Decl *VisitVarTemplateSpecializationDecl(
603 VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
604 const TemplateArgumentListInfo &TemplateArgsInfo,
605 ArrayRef<TemplateArgument> Converted,
606 VarTemplateSpecializationDecl *PrevDecl = nullptr);
607
608 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
609 ClassTemplatePartialSpecializationDecl *
610 InstantiateClassTemplatePartialSpecialization(
611 ClassTemplateDecl *ClassTemplate,
612 ClassTemplatePartialSpecializationDecl *PartialSpec);
613 VarTemplatePartialSpecializationDecl *
614 InstantiateVarTemplatePartialSpecialization(
615 VarTemplateDecl *VarTemplate,
616 VarTemplatePartialSpecializationDecl *PartialSpec);
617 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
618
619 private:
620 template<typename T>
621 Decl *instantiateUnresolvedUsingDecl(T *D,
622 bool InstantiatingPackElement = false);
623 };
624
625} // namespace clang
626
627#endif // LLVM_CLANG_SEMA_TEMPLATE_H

/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/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} // namespace llvm
40
41namespace clang {
42
43class ASTContext;
44class DiagnosticBuilder;
45class Expr;
46struct PrintingPolicy;
47class TypeSourceInfo;
48class ValueDecl;
49
50/// Represents a template argument.
51class TemplateArgument {
52public:
53 /// The kind of template argument we're storing.
54 enum ArgKind {
55 /// Represents an empty template argument, e.g., one that has not
56 /// been deduced.
57 Null = 0,
58
59 /// The template argument is a type.
60 Type,
61
62 /// The template argument is a declaration that was provided for a pointer,
63 /// reference, or pointer to member non-type template parameter.
64 Declaration,
65
66 /// The template argument is a null pointer or null pointer to member that
67 /// was provided for a non-type template parameter.
68 NullPtr,
69
70 /// The template argument is an integral value stored in an llvm::APSInt
71 /// that was provided for an integral non-type template parameter.
72 Integral,
73
74 /// The template argument is a template name that was provided for a
75 /// template template parameter.
76 Template,
77
78 /// The template argument is a pack expansion of a template name that was
79 /// provided for a template template parameter.
80 TemplateExpansion,
81
82 /// The template argument is an expression, and we've not resolved it to one
83 /// of the other forms yet, either because it's dependent or because we're
84 /// representing a non-canonical template argument (for instance, in a
85 /// TemplateSpecializationType).
86 Expression,
87
88 /// The template argument is actually a parameter pack. Arguments are stored
89 /// in the Args struct.
90 Pack
91 };
92
93private:
94 /// The kind of template argument we're storing.
95
96 struct DA {
97 unsigned Kind;
98 void *QT;
99 ValueDecl *D;
100 };
101 struct I {
102 unsigned Kind;
103 // We store a decomposed APSInt with the data allocated by ASTContext if
104 // BitWidth > 64. The memory may be shared between multiple
105 // TemplateArgument instances.
106 unsigned BitWidth : 31;
107 unsigned IsUnsigned : 1;
108 union {
109 /// Used to store the <= 64 bits integer value.
110 uint64_t VAL;
111
112 /// Used to store the >64 bits integer value.
113 const uint64_t *pVal;
114 };
115 void *Type;
116 };
117 struct A {
118 unsigned Kind;
119 unsigned NumArgs;
120 const TemplateArgument *Args;
121 };
122 struct TA {
123 unsigned Kind;
124 unsigned NumExpansions;
125 void *Name;
126 };
127 struct TV {
128 unsigned Kind;
129 uintptr_t V;
130 };
131 union {
132 struct DA DeclArg;
133 struct I Integer;
134 struct A Args;
135 struct TA TemplateArg;
136 struct TV TypeOrValue;
137 };
138
139public:
140 /// Construct an empty, invalid template argument.
141 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {}
142
143 /// Construct a template type argument.
144 TemplateArgument(QualType T, bool isNullPtr = false) {
145 TypeOrValue.Kind = isNullPtr ? NullPtr : Type;
146 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
147 }
148
149 /// Construct a template argument that refers to a
150 /// declaration, which is either an external declaration or a
151 /// template declaration.
152 TemplateArgument(ValueDecl *D, QualType QT) {
153 assert(D && "Expected decl")((D && "Expected decl") ? static_cast<void> (0)
: __assert_fail ("D && \"Expected decl\"", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 153, __PRETTY_FUNCTION__))
;
154 DeclArg.Kind = Declaration;
155 DeclArg.QT = QT.getAsOpaquePtr();
156 DeclArg.D = D;
157 }
158
159 /// Construct an integral constant template argument. The memory to
160 /// store the value is allocated with Ctx.
161 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type);
162
163 /// Construct an integral constant template argument with the same
164 /// value as Other but a different type.
165 TemplateArgument(const TemplateArgument &Other, QualType Type) {
166 Integer = Other.Integer;
167 Integer.Type = Type.getAsOpaquePtr();
168 }
169
170 /// Construct a template argument that is a template.
171 ///
172 /// This form of template argument is generally used for template template
173 /// parameters. However, the template name could be a dependent template
174 /// name that ends up being instantiated to a function template whose address
175 /// is taken.
176 ///
177 /// \param Name The template name.
178 TemplateArgument(TemplateName Name) {
179 TemplateArg.Kind = Template;
180 TemplateArg.Name = Name.getAsVoidPointer();
181 TemplateArg.NumExpansions = 0;
182 }
183
184 /// Construct a template argument that is a template pack expansion.
185 ///
186 /// This form of template argument is generally used for template template
187 /// parameters. However, the template name could be a dependent template
188 /// name that ends up being instantiated to a function template whose address
189 /// is taken.
190 ///
191 /// \param Name The template name.
192 ///
193 /// \param NumExpansions The number of expansions that will be generated by
194 /// instantiating
195 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) {
196 TemplateArg.Kind = TemplateExpansion;
197 TemplateArg.Name = Name.getAsVoidPointer();
198 if (NumExpansions)
199 TemplateArg.NumExpansions = *NumExpansions + 1;
200 else
201 TemplateArg.NumExpansions = 0;
202 }
203
204 /// Construct a template argument that is an expression.
205 ///
206 /// This form of template argument only occurs in template argument
207 /// lists used for dependent types and for expression; it will not
208 /// occur in a non-dependent, canonical template argument list.
209 TemplateArgument(Expr *E) {
210 TypeOrValue.Kind = Expression;
211 TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
212 }
213
214 /// Construct a template argument that is a template argument pack.
215 ///
216 /// We assume that storage for the template arguments provided
217 /// outlives the TemplateArgument itself.
218 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
219 this->Args.Kind = Pack;
220 this->Args.Args = Args.data();
221 this->Args.NumArgs = Args.size();
222 }
223
224 TemplateArgument(TemplateName, bool) = delete;
225
226 static TemplateArgument getEmptyPack() { return TemplateArgument(None); }
227
228 /// Create a new template argument pack by copying the given set of
229 /// template arguments.
230 static TemplateArgument CreatePackCopy(ASTContext &Context,
231 ArrayRef<TemplateArgument> Args);
232
233 /// Return the kind of stored template argument.
234 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
235
236 /// Determine whether this template argument has no value.
237 bool isNull() const { return getKind() == Null; }
15
Assuming the condition is false
16
Returning zero, which participates in a condition later
238
239 TemplateArgumentDependence getDependence() const;
240
241 /// Whether this template argument is dependent on a template
242 /// parameter such that its result can change from one instantiation to
243 /// another.
244 bool isDependent() const;
245
246 /// Whether this template argument is dependent on a template
247 /// parameter.
248 bool isInstantiationDependent() const;
249
250 /// Whether this template argument contains an unexpanded
251 /// parameter pack.
252 bool containsUnexpandedParameterPack() const;
253
254 /// Determine whether this template argument is a pack expansion.
255 bool isPackExpansion() const;
256
257 /// Retrieve the type for a type template argument.
258 QualType getAsType() const {
259 assert(getKind() == Type && "Unexpected kind")((getKind() == Type && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Type && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 259, __PRETTY_FUNCTION__))
;
260 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
261 }
262
263 /// Retrieve the declaration for a declaration non-type
264 /// template argument.
265 ValueDecl *getAsDecl() const {
266 assert(getKind() == Declaration && "Unexpected kind")((getKind() == Declaration && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 266, __PRETTY_FUNCTION__))
;
267 return DeclArg.D;
268 }
269
270 QualType getParamTypeForDecl() const {
271 assert(getKind() == Declaration && "Unexpected kind")((getKind() == Declaration && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 271, __PRETTY_FUNCTION__))
;
272 return QualType::getFromOpaquePtr(DeclArg.QT);
273 }
274
275 /// Retrieve the type for null non-type template argument.
276 QualType getNullPtrType() const {
277 assert(getKind() == NullPtr && "Unexpected kind")((getKind() == NullPtr && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == NullPtr && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 277, __PRETTY_FUNCTION__))
;
278 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
279 }
280
281 /// Retrieve the template name for a template name argument.
282 TemplateName getAsTemplate() const {
283 assert(getKind() == Template && "Unexpected kind")((getKind() == Template && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Template && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 283, __PRETTY_FUNCTION__))
;
284 return TemplateName::getFromVoidPointer(TemplateArg.Name);
285 }
286
287 /// Retrieve the template argument as a template name; if the argument
288 /// is a pack expansion, return the pattern as a template name.
289 TemplateName getAsTemplateOrTemplatePattern() const {
290 assert((getKind() == Template || getKind() == TemplateExpansion) &&(((getKind() == Template || getKind() == TemplateExpansion) &&
"Unexpected kind") ? static_cast<void> (0) : __assert_fail
("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 291, __PRETTY_FUNCTION__))
291 "Unexpected kind")(((getKind() == Template || getKind() == TemplateExpansion) &&
"Unexpected kind") ? static_cast<void> (0) : __assert_fail
("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 291, __PRETTY_FUNCTION__))
;
292
293 return TemplateName::getFromVoidPointer(TemplateArg.Name);
294 }
295
296 /// Retrieve the number of expansions that a template template argument
297 /// expansion will produce, if known.
298 Optional<unsigned> getNumTemplateExpansions() const;
299
300 /// Retrieve the template argument as an integral value.
301 // FIXME: Provide a way to read the integral data without copying the value.
302 llvm::APSInt getAsIntegral() const {
303 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 303, __PRETTY_FUNCTION__))
;
304
305 using namespace llvm;
306
307 if (Integer.BitWidth <= 64)
308 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
309
310 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
311 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
312 Integer.IsUnsigned);
313 }
314
315 /// Retrieve the type of the integral value.
316 QualType getIntegralType() const {
317 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 317, __PRETTY_FUNCTION__))
;
318 return QualType::getFromOpaquePtr(Integer.Type);
319 }
320
321 void setIntegralType(QualType T) {
322 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 322, __PRETTY_FUNCTION__))
;
323 Integer.Type = T.getAsOpaquePtr();
324 }
325
326 /// If this is a non-type template argument, get its type. Otherwise,
327 /// returns a null QualType.
328 QualType getNonTypeTemplateArgumentType() const;
329
330 /// Retrieve the template argument as an expression.
331 Expr *getAsExpr() const {
332 assert(getKind() == Expression && "Unexpected kind")((getKind() == Expression && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Expression && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 332, __PRETTY_FUNCTION__))
;
333 return reinterpret_cast<Expr *>(TypeOrValue.V);
334 }
335
336 /// Iterator that traverses the elements of a template argument pack.
337 using pack_iterator = const TemplateArgument *;
338
339 /// Iterator referencing the first argument of a template argument
340 /// pack.
341 pack_iterator pack_begin() const {
342 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 342, __PRETTY_FUNCTION__))
;
343 return Args.Args;
344 }
345
346 /// Iterator referencing one past the last argument of a template
347 /// argument pack.
348 pack_iterator pack_end() const {
349 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 349, __PRETTY_FUNCTION__))
;
350 return Args.Args + Args.NumArgs;
351 }
352
353 /// Iterator range referencing all of the elements of a template
354 /// argument pack.
355 ArrayRef<TemplateArgument> pack_elements() const {
356 return llvm::makeArrayRef(pack_begin(), pack_end());
357 }
358
359 /// The number of template arguments in the given template argument
360 /// pack.
361 unsigned pack_size() const {
362 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 362, __PRETTY_FUNCTION__))
;
363 return Args.NumArgs;
364 }
365
366 /// Return the array of arguments in this template argument pack.
367 ArrayRef<TemplateArgument> getPackAsArray() const {
368 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 368, __PRETTY_FUNCTION__))
;
369 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
370 }
371
372 /// Determines whether two template arguments are superficially the
373 /// same.
374 bool structurallyEquals(const TemplateArgument &Other) const;
375
376 /// When the template argument is a pack expansion, returns
377 /// the pattern of the pack expansion.
378 TemplateArgument getPackExpansionPattern() const;
379
380 /// Print this template argument to the given output stream.
381 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
382
383 /// Debugging aid that dumps the template argument.
384 void dump(raw_ostream &Out) const;
385
386 /// Debugging aid that dumps the template argument to standard error.
387 void dump() const;
388
389 /// Used to insert TemplateArguments into FoldingSets.
390 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
391};
392
393/// Location information for a TemplateArgument.
394struct TemplateArgumentLocInfo {
395private:
396 struct T {
397 // FIXME: We'd like to just use the qualifier in the TemplateName,
398 // but template arguments get canonicalized too quickly.
399 NestedNameSpecifier *Qualifier;
400 void *QualifierLocData;
401 unsigned TemplateNameLoc;
402 unsigned EllipsisLoc;
403 };
404
405 union {
406 struct T Template;
407 Expr *Expression;
408 TypeSourceInfo *Declarator;
409 };
410
411public:
412 constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
413
414 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
415
416 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
417
418 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
419 SourceLocation TemplateNameLoc,
420 SourceLocation EllipsisLoc) {
421 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
422 Template.QualifierLocData = QualifierLoc.getOpaqueData();
423 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
424 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
425 }
426
427 TypeSourceInfo *getAsTypeSourceInfo() const {
428 return Declarator;
429 }
430
431 Expr *getAsExpr() const {
432 return Expression;
433 }
434
435 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
436 return NestedNameSpecifierLoc(Template.Qualifier,
437 Template.QualifierLocData);
438 }
439
440 SourceLocation getTemplateNameLoc() const {
441 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
442 }
443
444 SourceLocation getTemplateEllipsisLoc() const {
445 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
446 }
447};
448
449/// Location wrapper for a TemplateArgument. TemplateArgument is to
450/// TemplateArgumentLoc as Type is to TypeLoc.
451class TemplateArgumentLoc {
452 TemplateArgument Argument;
453 TemplateArgumentLocInfo LocInfo;
454
455public:
456 constexpr TemplateArgumentLoc() {}
457
458 TemplateArgumentLoc(const TemplateArgument &Argument,
459 TemplateArgumentLocInfo Opaque)
460 : Argument(Argument), LocInfo(Opaque) {}
461
462 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
463 : Argument(Argument), LocInfo(TInfo) {
464 assert(Argument.getKind() == TemplateArgument::Type)((Argument.getKind() == TemplateArgument::Type) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 464, __PRETTY_FUNCTION__))
;
465 }
466
467 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
468 : Argument(Argument), LocInfo(E) {
469
470 // Permit any kind of template argument that can be represented with an
471 // expression.
472 assert(Argument.getKind() == TemplateArgument::NullPtr ||((Argument.getKind() == TemplateArgument::NullPtr || Argument
.getKind() == TemplateArgument::Integral || Argument.getKind(
) == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument
::Expression) ? static_cast<void> (0) : __assert_fail (
"Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 475, __PRETTY_FUNCTION__))
473 Argument.getKind() == TemplateArgument::Integral ||((Argument.getKind() == TemplateArgument::NullPtr || Argument
.getKind() == TemplateArgument::Integral || Argument.getKind(
) == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument
::Expression) ? static_cast<void> (0) : __assert_fail (
"Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 475, __PRETTY_FUNCTION__))
474 Argument.getKind() == TemplateArgument::Declaration ||((Argument.getKind() == TemplateArgument::NullPtr || Argument
.getKind() == TemplateArgument::Integral || Argument.getKind(
) == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument
::Expression) ? static_cast<void> (0) : __assert_fail (
"Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 475, __PRETTY_FUNCTION__))
475 Argument.getKind() == TemplateArgument::Expression)((Argument.getKind() == TemplateArgument::NullPtr || Argument
.getKind() == TemplateArgument::Integral || Argument.getKind(
) == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument
::Expression) ? static_cast<void> (0) : __assert_fail (
"Argument.getKind() == TemplateArgument::NullPtr || Argument.getKind() == TemplateArgument::Integral || Argument.getKind() == TemplateArgument::Declaration || Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 475, __PRETTY_FUNCTION__))
;
476 }
477
478 TemplateArgumentLoc(const TemplateArgument &Argument,
479 NestedNameSpecifierLoc QualifierLoc,
480 SourceLocation TemplateNameLoc,
481 SourceLocation EllipsisLoc = SourceLocation())
482 : Argument(Argument),
483 LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
484 assert(Argument.getKind() == TemplateArgument::Template ||((Argument.getKind() == TemplateArgument::Template || Argument
.getKind() == TemplateArgument::TemplateExpansion) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 485, __PRETTY_FUNCTION__))
485 Argument.getKind() == TemplateArgument::TemplateExpansion)((Argument.getKind() == TemplateArgument::Template || Argument
.getKind() == TemplateArgument::TemplateExpansion) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Template || Argument.getKind() == TemplateArgument::TemplateExpansion"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 485, __PRETTY_FUNCTION__))
;
486 }
487
488 /// - Fetches the primary location of the argument.
489 SourceLocation getLocation() const {
490 if (Argument.getKind() == TemplateArgument::Template ||
491 Argument.getKind() == TemplateArgument::TemplateExpansion)
492 return getTemplateNameLoc();
493
494 return getSourceRange().getBegin();
495 }
496
497 /// - Fetches the full source range of the argument.
498 SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__));
499
500 const TemplateArgument &getArgument() const {
501 return Argument;
502 }
503
504 TemplateArgumentLocInfo getLocInfo() const {
505 return LocInfo;
506 }
507
508 TypeSourceInfo *getTypeSourceInfo() const {
509 assert(Argument.getKind() == TemplateArgument::Type)((Argument.getKind() == TemplateArgument::Type) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 509, __PRETTY_FUNCTION__))
;
510 return LocInfo.getAsTypeSourceInfo();
511 }
512
513 Expr *getSourceExpression() const {
514 assert(Argument.getKind() == TemplateArgument::Expression)((Argument.getKind() == TemplateArgument::Expression) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 514, __PRETTY_FUNCTION__))
;
515 return LocInfo.getAsExpr();
516 }
517
518 Expr *getSourceDeclExpression() const {
519 assert(Argument.getKind() == TemplateArgument::Declaration)((Argument.getKind() == TemplateArgument::Declaration) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Declaration"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 519, __PRETTY_FUNCTION__))
;
520 return LocInfo.getAsExpr();
521 }
522
523 Expr *getSourceNullPtrExpression() const {
524 assert(Argument.getKind() == TemplateArgument::NullPtr)((Argument.getKind() == TemplateArgument::NullPtr) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::NullPtr"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 524, __PRETTY_FUNCTION__))
;
525 return LocInfo.getAsExpr();
526 }
527
528 Expr *getSourceIntegralExpression() const {
529 assert(Argument.getKind() == TemplateArgument::Integral)((Argument.getKind() == TemplateArgument::Integral) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Integral"
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 529, __PRETTY_FUNCTION__))
;
530 return LocInfo.getAsExpr();
531 }
532
533 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
534 if (Argument.getKind() != TemplateArgument::Template &&
535 Argument.getKind() != TemplateArgument::TemplateExpansion)
536 return NestedNameSpecifierLoc();
537 return LocInfo.getTemplateQualifierLoc();
538 }
539
540 SourceLocation getTemplateNameLoc() const {
541 if (Argument.getKind() != TemplateArgument::Template &&
542 Argument.getKind() != TemplateArgument::TemplateExpansion)
543 return SourceLocation();
544 return LocInfo.getTemplateNameLoc();
545 }
546
547 SourceLocation getTemplateEllipsisLoc() const {
548 if (Argument.getKind() != TemplateArgument::TemplateExpansion)
549 return SourceLocation();
550 return LocInfo.getTemplateEllipsisLoc();
551 }
552};
553
554/// A convenient class for passing around template argument
555/// information. Designed to be passed by reference.
556class TemplateArgumentListInfo {
557 SmallVector<TemplateArgumentLoc, 8> Arguments;
558 SourceLocation LAngleLoc;
559 SourceLocation RAngleLoc;
560
561public:
562 TemplateArgumentListInfo() = default;
563
564 TemplateArgumentListInfo(SourceLocation LAngleLoc,
565 SourceLocation RAngleLoc)
566 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
567
568 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
569 // instead.
570 void *operator new(size_t bytes, ASTContext &C) = delete;
571
572 SourceLocation getLAngleLoc() const { return LAngleLoc; }
573 SourceLocation getRAngleLoc() const { return RAngleLoc; }
574
575 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
576 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
577
578 unsigned size() const { return Arguments.size(); }
579
580 const TemplateArgumentLoc *getArgumentArray() const {
581 return Arguments.data();
582 }
583
584 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
585 return Arguments;
586 }
587
588 const TemplateArgumentLoc &operator[](unsigned I) const {
589 return Arguments[I];
590 }
591
592 TemplateArgumentLoc &operator[](unsigned I) {
593 return Arguments[I];
594 }
595
596 void addArgument(const TemplateArgumentLoc &Loc) {
597 Arguments.push_back(Loc);
598 }
599};
600
601/// Represents an explicit template argument list in C++, e.g.,
602/// the "<int>" in "sort<int>".
603/// This is safe to be used inside an AST node, in contrast with
604/// TemplateArgumentListInfo.
605struct ASTTemplateArgumentListInfo final
606 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
607 TemplateArgumentLoc> {
608private:
609 friend class ASTNodeImporter;
610 friend TrailingObjects;
611
612 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
613
614public:
615 /// The source location of the left angle bracket ('<').
616 SourceLocation LAngleLoc;
617
618 /// The source location of the right angle bracket ('>').
619 SourceLocation RAngleLoc;
620
621 /// The number of template arguments in TemplateArgs.
622 unsigned NumTemplateArgs;
623
624 SourceLocation getLAngleLoc() const { return LAngleLoc; }
625 SourceLocation getRAngleLoc() const { return RAngleLoc; }
626
627 /// Retrieve the template arguments
628 const TemplateArgumentLoc *getTemplateArgs() const {
629 return getTrailingObjects<TemplateArgumentLoc>();
630 }
631 unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
632
633 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
634 return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
635 }
636
637 const TemplateArgumentLoc &operator[](unsigned I) const {
638 return getTemplateArgs()[I];
639 }
640
641 static const ASTTemplateArgumentListInfo *
642 Create(const ASTContext &C, const TemplateArgumentListInfo &List);
643};
644
645/// Represents an explicit template argument list in C++, e.g.,
646/// the "<int>" in "sort<int>".
647///
648/// It is intended to be used as a trailing object on AST nodes, and
649/// as such, doesn't contain the array of TemplateArgumentLoc itself,
650/// but expects the containing object to also provide storage for
651/// that.
652struct alignas(void *) ASTTemplateKWAndArgsInfo {
653 /// The source location of the left angle bracket ('<').
654 SourceLocation LAngleLoc;
655
656 /// The source location of the right angle bracket ('>').
657 SourceLocation RAngleLoc;
658
659 /// The source location of the template keyword; this is used
660 /// as part of the representation of qualified identifiers, such as
661 /// S<T>::template apply<T>. Will be empty if this expression does
662 /// not have a template keyword.
663 SourceLocation TemplateKWLoc;
664
665 /// The number of template arguments in TemplateArgs.
666 unsigned NumTemplateArgs;
667
668 void initializeFrom(SourceLocation TemplateKWLoc,
669 const TemplateArgumentListInfo &List,
670 TemplateArgumentLoc *OutArgArray);
671 // FIXME: The parameter Deps is the result populated by this method, the
672 // caller doesn't need it since it is populated by computeDependence. remove
673 // it.
674 void initializeFrom(SourceLocation TemplateKWLoc,
675 const TemplateArgumentListInfo &List,
676 TemplateArgumentLoc *OutArgArray,
677 TemplateArgumentDependence &Deps);
678 void initializeFrom(SourceLocation TemplateKWLoc);
679
680 void copyInto(const TemplateArgumentLoc *ArgArray,
681 TemplateArgumentListInfo &List) const;
682};
683
684const StreamableDiagnosticBase &operator<<(const StreamableDiagnosticBase &DB,
685 const TemplateArgument &Arg);
686
687inline TemplateSpecializationType::iterator
688 TemplateSpecializationType::end() const {
689 return getArgs() + getNumArgs();
690}
691
692inline DependentTemplateSpecializationType::iterator
693 DependentTemplateSpecializationType::end() const {
694 return getArgs() + getNumArgs();
695}
696
697inline const TemplateArgument &
698 TemplateSpecializationType::getArg(unsigned Idx) const {
699 assert(Idx < getNumArgs() && "Template argument out of range")((Idx < getNumArgs() && "Template argument out of range"
) ? static_cast<void> (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 699, __PRETTY_FUNCTION__))
;
700 return getArgs()[Idx];
701}
702
703inline const TemplateArgument &
704 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
705 assert(Idx < getNumArgs() && "Template argument out of range")((Idx < getNumArgs() && "Template argument out of range"
) ? static_cast<void> (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 705, __PRETTY_FUNCTION__))
;
706 return getArgs()[Idx];
707}
708
709inline const TemplateArgument &AutoType::getArg(unsigned Idx) const {
710 assert(Idx < getNumArgs() && "Template argument out of range")((Idx < getNumArgs() && "Template argument out of range"
) ? static_cast<void> (0) : __assert_fail ("Idx < getNumArgs() && \"Template argument out of range\""
, "/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/clang/include/clang/AST/TemplateBase.h"
, 710, __PRETTY_FUNCTION__))
;
711 return getArgs()[Idx];
712}
713
714} // namespace clang
715
716#endif // LLVM_CLANG_AST_TEMPLATEBASE_H

/build/llvm-toolchain-snapshot-12~++20200917111122+b03c2b8395b/llvm/include/llvm/ADT/PointerUnion.h

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