Bug Summary

File:tools/clang/lib/AST/TemplateBase.cpp
Warning:line 373, column 12
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name TemplateBase.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.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-10~svn373517/build-llvm/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST -I /build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-10~svn373517/build-llvm/include -I /build/llvm-toolchain-snapshot-10~svn373517/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-10/lib/clang/10.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-10~svn373517/build-llvm/tools/clang/lib/AST -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~svn373517=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-10-02-234743-9763-1 -x c++ /build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp

/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp

1//===- TemplateBase.cpp - Common template AST class implementation --------===//
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 implements common classes used throughout C++ template
10// representations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/TemplateBase.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
21#include "clang/AST/PrettyPrinter.h"
22#include "clang/AST/TemplateName.h"
23#include "clang/AST/Type.h"
24#include "clang/AST/TypeLoc.h"
25#include "clang/Basic/Diagnostic.h"
26#include "clang/Basic/LLVM.h"
27#include "clang/Basic/LangOptions.h"
28#include "clang/Basic/SourceLocation.h"
29#include "llvm/ADT/APSInt.h"
30#include "llvm/ADT/FoldingSet.h"
31#include "llvm/ADT/None.h"
32#include "llvm/ADT/SmallString.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/Casting.h"
35#include "llvm/Support/Compiler.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/raw_ostream.h"
38#include <cassert>
39#include <cstddef>
40#include <cstdint>
41#include <cstring>
42
43using namespace clang;
44
45/// Print a template integral argument value.
46///
47/// \param TemplArg the TemplateArgument instance to print.
48///
49/// \param Out the raw_ostream instance to use for printing.
50///
51/// \param Policy the printing policy for EnumConstantDecl printing.
52static void printIntegral(const TemplateArgument &TemplArg,
53 raw_ostream &Out, const PrintingPolicy& Policy) {
54 const Type *T = TemplArg.getIntegralType().getTypePtr();
55 const llvm::APSInt &Val = TemplArg.getAsIntegral();
56
57 if (const EnumType *ET = T->getAs<EnumType>()) {
58 for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
59 // In Sema::CheckTemplateArugment, enum template arguments value are
60 // extended to the size of the integer underlying the enum type. This
61 // may create a size difference between the enum value and template
62 // argument value, requiring isSameValue here instead of operator==.
63 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
64 ECD->printQualifiedName(Out, Policy);
65 return;
66 }
67 }
68 }
69
70 if (T->isBooleanType() && !Policy.MSVCFormatting) {
71 Out << (Val.getBoolValue() ? "true" : "false");
72 } else if (T->isCharType()) {
73 const char Ch = Val.getZExtValue();
74 Out << ((Ch == '\'') ? "'\\" : "'");
75 Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
76 Out << "'";
77 } else {
78 Out << Val;
79 }
80}
81
82//===----------------------------------------------------------------------===//
83// TemplateArgument Implementation
84//===----------------------------------------------------------------------===//
85
86TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
87 QualType Type) {
88 Integer.Kind = Integral;
89 // Copy the APSInt value into our decomposed form.
90 Integer.BitWidth = Value.getBitWidth();
91 Integer.IsUnsigned = Value.isUnsigned();
92 // If the value is large, we have to get additional memory from the ASTContext
93 unsigned NumWords = Value.getNumWords();
94 if (NumWords > 1) {
95 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
96 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
97 Integer.pVal = static_cast<uint64_t *>(Mem);
98 } else {
99 Integer.VAL = Value.getZExtValue();
100 }
101
102 Integer.Type = Type.getAsOpaquePtr();
103}
104
105TemplateArgument
106TemplateArgument::CreatePackCopy(ASTContext &Context,
107 ArrayRef<TemplateArgument> Args) {
108 if (Args.empty())
109 return getEmptyPack();
110
111 return TemplateArgument(Args.copy(Context));
112}
113
114bool TemplateArgument::isDependent() const {
115 switch (getKind()) {
116 case Null:
117 llvm_unreachable("Should not have a NULL template argument")::llvm::llvm_unreachable_internal("Should not have a NULL template argument"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 117)
;
118
119 case Type:
120 return getAsType()->isDependentType() ||
121 isa<PackExpansionType>(getAsType());
122
123 case Template:
124 return getAsTemplate().isDependent();
125
126 case TemplateExpansion:
127 return true;
128
129 case Declaration:
130 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
131 return DC->isDependentContext();
132 return getAsDecl()->getDeclContext()->isDependentContext();
133
134 case NullPtr:
135 return false;
136
137 case Integral:
138 // Never dependent
139 return false;
140
141 case Expression:
142 return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
143 isa<PackExpansionExpr>(getAsExpr()));
144
145 case Pack:
146 for (const auto &P : pack_elements())
147 if (P.isDependent())
148 return true;
149 return false;
150 }
151
152 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 152)
;
153}
154
155bool TemplateArgument::isInstantiationDependent() const {
156 switch (getKind()) {
157 case Null:
158 llvm_unreachable("Should not have a NULL template argument")::llvm::llvm_unreachable_internal("Should not have a NULL template argument"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 158)
;
159
160 case Type:
161 return getAsType()->isInstantiationDependentType();
162
163 case Template:
164 return getAsTemplate().isInstantiationDependent();
165
166 case TemplateExpansion:
167 return true;
168
169 case Declaration:
170 if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
171 return DC->isDependentContext();
172 return getAsDecl()->getDeclContext()->isDependentContext();
173
174 case NullPtr:
175 return false;
176
177 case Integral:
178 // Never dependent
179 return false;
180
181 case Expression:
182 return getAsExpr()->isInstantiationDependent();
183
184 case Pack:
185 for (const auto &P : pack_elements())
186 if (P.isInstantiationDependent())
187 return true;
188 return false;
189 }
190
191 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 191)
;
192}
193
194bool TemplateArgument::isPackExpansion() const {
195 switch (getKind()) {
196 case Null:
197 case Declaration:
198 case Integral:
199 case Pack:
200 case Template:
201 case NullPtr:
202 return false;
203
204 case TemplateExpansion:
205 return true;
206
207 case Type:
208 return isa<PackExpansionType>(getAsType());
209
210 case Expression:
211 return isa<PackExpansionExpr>(getAsExpr());
212 }
213
214 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 214)
;
215}
216
217bool TemplateArgument::containsUnexpandedParameterPack() const {
218 switch (getKind()) {
219 case Null:
220 case Declaration:
221 case Integral:
222 case TemplateExpansion:
223 case NullPtr:
224 break;
225
226 case Type:
227 if (getAsType()->containsUnexpandedParameterPack())
228 return true;
229 break;
230
231 case Template:
232 if (getAsTemplate().containsUnexpandedParameterPack())
233 return true;
234 break;
235
236 case Expression:
237 if (getAsExpr()->containsUnexpandedParameterPack())
238 return true;
239 break;
240
241 case Pack:
242 for (const auto &P : pack_elements())
243 if (P.containsUnexpandedParameterPack())
244 return true;
245
246 break;
247 }
248
249 return false;
250}
251
252Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
253 assert(getKind() == TemplateExpansion)((getKind() == TemplateExpansion) ? static_cast<void> (
0) : __assert_fail ("getKind() == TemplateExpansion", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 253, __PRETTY_FUNCTION__))
;
254 if (TemplateArg.NumExpansions)
255 return TemplateArg.NumExpansions - 1;
256
257 return None;
258}
259
260QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
261 switch (getKind()) {
262 case TemplateArgument::Null:
263 case TemplateArgument::Type:
264 case TemplateArgument::Template:
265 case TemplateArgument::TemplateExpansion:
266 case TemplateArgument::Pack:
267 return QualType();
268
269 case TemplateArgument::Integral:
270 return getIntegralType();
271
272 case TemplateArgument::Expression:
273 return getAsExpr()->getType();
274
275 case TemplateArgument::Declaration:
276 return getParamTypeForDecl();
277
278 case TemplateArgument::NullPtr:
279 return getNullPtrType();
280 }
281
282 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 282)
;
283}
284
285void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
286 const ASTContext &Context) const {
287 ID.AddInteger(getKind());
288 switch (getKind()) {
289 case Null:
290 break;
291
292 case Type:
293 getAsType().Profile(ID);
294 break;
295
296 case NullPtr:
297 getNullPtrType().Profile(ID);
298 break;
299
300 case Declaration:
301 ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
302 break;
303
304 case Template:
305 case TemplateExpansion: {
306 TemplateName Template = getAsTemplateOrTemplatePattern();
307 if (TemplateTemplateParmDecl *TTP
308 = dyn_cast_or_null<TemplateTemplateParmDecl>(
309 Template.getAsTemplateDecl())) {
310 ID.AddBoolean(true);
311 ID.AddInteger(TTP->getDepth());
312 ID.AddInteger(TTP->getPosition());
313 ID.AddBoolean(TTP->isParameterPack());
314 } else {
315 ID.AddBoolean(false);
316 ID.AddPointer(Context.getCanonicalTemplateName(Template)
317 .getAsVoidPointer());
318 }
319 break;
320 }
321
322 case Integral:
323 getAsIntegral().Profile(ID);
324 getIntegralType().Profile(ID);
325 break;
326
327 case Expression:
328 getAsExpr()->Profile(ID, Context, true);
329 break;
330
331 case Pack:
332 ID.AddInteger(Args.NumArgs);
333 for (unsigned I = 0; I != Args.NumArgs; ++I)
334 Args.Args[I].Profile(ID, Context);
335 }
336}
337
338bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
339 if (getKind() != Other.getKind()) return false;
340
341 switch (getKind()) {
342 case Null:
343 case Type:
344 case Expression:
345 case Template:
346 case TemplateExpansion:
347 case NullPtr:
348 return TypeOrValue.V == Other.TypeOrValue.V;
349
350 case Declaration:
351 return getAsDecl() == Other.getAsDecl();
352
353 case Integral:
354 return getIntegralType() == Other.getIntegralType() &&
355 getAsIntegral() == Other.getAsIntegral();
356
357 case Pack:
358 if (Args.NumArgs != Other.Args.NumArgs) return false;
359 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
360 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
361 return false;
362 return true;
363 }
364
365 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 365)
;
366}
367
368TemplateArgument TemplateArgument::getPackExpansionPattern() const {
369 assert(isPackExpansion())((isPackExpansion()) ? static_cast<void> (0) : __assert_fail
("isPackExpansion()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 369, __PRETTY_FUNCTION__))
;
1
'?' condition is true
370
371 switch (getKind()) {
2
Calling 'TemplateArgument::getKind'
4
Returning from 'TemplateArgument::getKind'
5
Control jumps to 'case Type:' at line 372
372 case Type:
373 return getAsType()->getAs<PackExpansionType>()->getPattern();
6
Assuming the object is not a 'PackExpansionType'
7
Called C++ object pointer is null
374
375 case Expression:
376 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
377
378 case TemplateExpansion:
379 return TemplateArgument(getAsTemplateOrTemplatePattern());
380
381 case Declaration:
382 case Integral:
383 case Pack:
384 case Null:
385 case Template:
386 case NullPtr:
387 return TemplateArgument();
388 }
389
390 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 390)
;
391}
392
393void TemplateArgument::print(const PrintingPolicy &Policy,
394 raw_ostream &Out) const {
395 switch (getKind()) {
396 case Null:
397 Out << "(no value)";
398 break;
399
400 case Type: {
401 PrintingPolicy SubPolicy(Policy);
402 SubPolicy.SuppressStrongLifetime = true;
403 getAsType().print(Out, SubPolicy);
404 break;
405 }
406
407 case Declaration: {
408 NamedDecl *ND = getAsDecl();
409 Out << '&';
410 if (ND->getDeclName()) {
411 // FIXME: distinguish between pointer and reference args?
412 ND->printQualifiedName(Out);
413 } else {
414 Out << "(anonymous)";
415 }
416 break;
417 }
418
419 case NullPtr:
420 Out << "nullptr";
421 break;
422
423 case Template:
424 getAsTemplate().print(Out, Policy);
425 break;
426
427 case TemplateExpansion:
428 getAsTemplateOrTemplatePattern().print(Out, Policy);
429 Out << "...";
430 break;
431
432 case Integral:
433 printIntegral(*this, Out, Policy);
434 break;
435
436 case Expression:
437 getAsExpr()->printPretty(Out, nullptr, Policy);
438 break;
439
440 case Pack:
441 Out << "<";
442 bool First = true;
443 for (const auto &P : pack_elements()) {
444 if (First)
445 First = false;
446 else
447 Out << ", ";
448
449 P.print(Policy, Out);
450 }
451 Out << ">";
452 break;
453 }
454}
455
456void TemplateArgument::dump(raw_ostream &Out) const {
457 LangOptions LO; // FIXME! see also TemplateName::dump().
458 LO.CPlusPlus = true;
459 LO.Bool = true;
460 print(PrintingPolicy(LO), Out);
461}
462
463LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void TemplateArgument::dump() const { dump(llvm::errs()); }
464
465//===----------------------------------------------------------------------===//
466// TemplateArgumentLoc Implementation
467//===----------------------------------------------------------------------===//
468
469SourceRange TemplateArgumentLoc::getSourceRange() const {
470 switch (Argument.getKind()) {
471 case TemplateArgument::Expression:
472 return getSourceExpression()->getSourceRange();
473
474 case TemplateArgument::Declaration:
475 return getSourceDeclExpression()->getSourceRange();
476
477 case TemplateArgument::NullPtr:
478 return getSourceNullPtrExpression()->getSourceRange();
479
480 case TemplateArgument::Type:
481 if (TypeSourceInfo *TSI = getTypeSourceInfo())
482 return TSI->getTypeLoc().getSourceRange();
483 else
484 return SourceRange();
485
486 case TemplateArgument::Template:
487 if (getTemplateQualifierLoc())
488 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
489 getTemplateNameLoc());
490 return SourceRange(getTemplateNameLoc());
491
492 case TemplateArgument::TemplateExpansion:
493 if (getTemplateQualifierLoc())
494 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
495 getTemplateEllipsisLoc());
496 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
497
498 case TemplateArgument::Integral:
499 return getSourceIntegralExpression()->getSourceRange();
500
501 case TemplateArgument::Pack:
502 case TemplateArgument::Null:
503 return SourceRange();
504 }
505
506 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 506)
;
507}
508
509const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
510 const TemplateArgument &Arg) {
511 switch (Arg.getKind()) {
512 case TemplateArgument::Null:
513 // This is bad, but not as bad as crashing because of argument
514 // count mismatches.
515 return DB << "(null template argument)";
516
517 case TemplateArgument::Type:
518 return DB << Arg.getAsType();
519
520 case TemplateArgument::Declaration:
521 return DB << Arg.getAsDecl();
522
523 case TemplateArgument::NullPtr:
524 return DB << "nullptr";
525
526 case TemplateArgument::Integral:
527 return DB << Arg.getAsIntegral().toString(10);
528
529 case TemplateArgument::Template:
530 return DB << Arg.getAsTemplate();
531
532 case TemplateArgument::TemplateExpansion:
533 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
534
535 case TemplateArgument::Expression: {
536 // This shouldn't actually ever happen, so it's okay that we're
537 // regurgitating an expression here.
538 // FIXME: We're guessing at LangOptions!
539 SmallString<32> Str;
540 llvm::raw_svector_ostream OS(Str);
541 LangOptions LangOpts;
542 LangOpts.CPlusPlus = true;
543 PrintingPolicy Policy(LangOpts);
544 Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
545 return DB << OS.str();
546 }
547
548 case TemplateArgument::Pack: {
549 // FIXME: We're guessing at LangOptions!
550 SmallString<32> Str;
551 llvm::raw_svector_ostream OS(Str);
552 LangOptions LangOpts;
553 LangOpts.CPlusPlus = true;
554 PrintingPolicy Policy(LangOpts);
555 Arg.print(Policy, OS);
556 return DB << OS.str();
557 }
558 }
559
560 llvm_unreachable("Invalid TemplateArgument Kind!")::llvm::llvm_unreachable_internal("Invalid TemplateArgument Kind!"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 560)
;
561}
562
563const ASTTemplateArgumentListInfo *
564ASTTemplateArgumentListInfo::Create(ASTContext &C,
565 const TemplateArgumentListInfo &List) {
566 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
567 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
568 return new (Mem) ASTTemplateArgumentListInfo(List);
569}
570
571ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
572 const TemplateArgumentListInfo &Info) {
573 LAngleLoc = Info.getLAngleLoc();
574 RAngleLoc = Info.getRAngleLoc();
575 NumTemplateArgs = Info.size();
576
577 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
578 for (unsigned i = 0; i != NumTemplateArgs; ++i)
579 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
580}
581
582void ASTTemplateKWAndArgsInfo::initializeFrom(
583 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
584 TemplateArgumentLoc *OutArgArray) {
585 this->TemplateKWLoc = TemplateKWLoc;
586 LAngleLoc = Info.getLAngleLoc();
587 RAngleLoc = Info.getRAngleLoc();
588 NumTemplateArgs = Info.size();
589
590 for (unsigned i = 0; i != NumTemplateArgs; ++i)
591 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
592}
593
594void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
595 assert(TemplateKWLoc.isValid())((TemplateKWLoc.isValid()) ? static_cast<void> (0) : __assert_fail
("TemplateKWLoc.isValid()", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/lib/AST/TemplateBase.cpp"
, 595, __PRETTY_FUNCTION__))
;
596 LAngleLoc = SourceLocation();
597 RAngleLoc = SourceLocation();
598 this->TemplateKWLoc = TemplateKWLoc;
599 NumTemplateArgs = 0;
600}
601
602void ASTTemplateKWAndArgsInfo::initializeFrom(
603 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
604 TemplateArgumentLoc *OutArgArray, bool &Dependent,
605 bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
606 this->TemplateKWLoc = TemplateKWLoc;
607 LAngleLoc = Info.getLAngleLoc();
608 RAngleLoc = Info.getRAngleLoc();
609 NumTemplateArgs = Info.size();
610
611 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
612 Dependent = Dependent || Info[i].getArgument().isDependent();
613 InstantiationDependent = InstantiationDependent ||
614 Info[i].getArgument().isInstantiationDependent();
615 ContainsUnexpandedParameterPack =
616 ContainsUnexpandedParameterPack ||
617 Info[i].getArgument().containsUnexpandedParameterPack();
618
619 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
620 }
621}
622
623void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
624 TemplateArgumentListInfo &Info) const {
625 Info.setLAngleLoc(LAngleLoc);
626 Info.setRAngleLoc(RAngleLoc);
627 for (unsigned I = 0; I != NumTemplateArgs; ++I)
628 Info.addArgument(ArgArray[I]);
629}

/build/llvm-toolchain-snapshot-10~svn373517/tools/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/NestedNameSpecifier.h"
18#include "clang/AST/TemplateName.h"
19#include "clang/AST/Type.h"
20#include "clang/Basic/LLVM.h"
21#include "clang/Basic/SourceLocation.h"
22#include "llvm/ADT/APInt.h"
23#include "llvm/ADT/APSInt.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/None.h"
26#include "llvm/ADT/Optional.h"
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/Support/Compiler.h"
29#include "llvm/Support/TrailingObjects.h"
30#include <cassert>
31#include <cstddef>
32#include <cstdint>
33
34namespace llvm {
35
36class FoldingSetNodeID;
37
38} // namespace llvm
39
40namespace clang {
41
42class ASTContext;
43class DiagnosticBuilder;
44class Expr;
45struct PrintingPolicy;
46class TypeSourceInfo;
47class ValueDecl;
48
49/// Represents a template argument.
50class TemplateArgument {
51public:
52 /// The kind of template argument we're storing.
53 enum ArgKind {
54 /// Represents an empty template argument, e.g., one that has not
55 /// been deduced.
56 Null = 0,
57
58 /// The template argument is a type.
59 Type,
60
61 /// The template argument is a declaration that was provided for a pointer,
62 /// reference, or pointer to member non-type template parameter.
63 Declaration,
64
65 /// The template argument is a null pointer or null pointer to member that
66 /// was provided for a non-type template parameter.
67 NullPtr,
68
69 /// The template argument is an integral value stored in an llvm::APSInt
70 /// that was provided for an integral non-type template parameter.
71 Integral,
72
73 /// The template argument is a template name that was provided for a
74 /// template template parameter.
75 Template,
76
77 /// The template argument is a pack expansion of a template name that was
78 /// provided for a template template parameter.
79 TemplateExpansion,
80
81 /// The template argument is an expression, and we've not resolved it to one
82 /// of the other forms yet, either because it's dependent or because we're
83 /// representing a non-canonical template argument (for instance, in a
84 /// TemplateSpecializationType). Also used to represent a non-dependent
85 /// __uuidof expression (a Microsoft extension).
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-10~svn373517/tools/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; }
3
Returning the value 1, which participates in a condition later
235
236 /// Determine whether this template argument has no value.
237 bool isNull() const { return getKind() == Null; }
238
239 /// Whether this template argument is dependent on a template
240 /// parameter such that its result can change from one instantiation to
241 /// another.
242 bool isDependent() const;
243
244 /// Whether this template argument is dependent on a template
245 /// parameter.
246 bool isInstantiationDependent() const;
247
248 /// Whether this template argument contains an unexpanded
249 /// parameter pack.
250 bool containsUnexpandedParameterPack() const;
251
252 /// Determine whether this template argument is a pack expansion.
253 bool isPackExpansion() const;
254
255 /// Retrieve the type for a type template argument.
256 QualType getAsType() const {
257 assert(getKind() == Type && "Unexpected kind")((getKind() == Type && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Type && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 257, __PRETTY_FUNCTION__))
;
258 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
259 }
260
261 /// Retrieve the declaration for a declaration non-type
262 /// template argument.
263 ValueDecl *getAsDecl() const {
264 assert(getKind() == Declaration && "Unexpected kind")((getKind() == Declaration && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 264, __PRETTY_FUNCTION__))
;
265 return DeclArg.D;
266 }
267
268 QualType getParamTypeForDecl() const {
269 assert(getKind() == Declaration && "Unexpected kind")((getKind() == Declaration && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Declaration && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 269, __PRETTY_FUNCTION__))
;
270 return QualType::getFromOpaquePtr(DeclArg.QT);
271 }
272
273 /// Retrieve the type for null non-type template argument.
274 QualType getNullPtrType() const {
275 assert(getKind() == NullPtr && "Unexpected kind")((getKind() == NullPtr && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == NullPtr && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 275, __PRETTY_FUNCTION__))
;
276 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V));
277 }
278
279 /// Retrieve the template name for a template name argument.
280 TemplateName getAsTemplate() const {
281 assert(getKind() == Template && "Unexpected kind")((getKind() == Template && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Template && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 281, __PRETTY_FUNCTION__))
;
282 return TemplateName::getFromVoidPointer(TemplateArg.Name);
283 }
284
285 /// Retrieve the template argument as a template name; if the argument
286 /// is a pack expansion, return the pattern as a template name.
287 TemplateName getAsTemplateOrTemplatePattern() const {
288 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 289, __PRETTY_FUNCTION__))
289 "Unexpected kind")(((getKind() == Template || getKind() == TemplateExpansion) &&
"Unexpected kind") ? static_cast<void> (0) : __assert_fail
("(getKind() == Template || getKind() == TemplateExpansion) && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 289, __PRETTY_FUNCTION__))
;
290
291 return TemplateName::getFromVoidPointer(TemplateArg.Name);
292 }
293
294 /// Retrieve the number of expansions that a template template argument
295 /// expansion will produce, if known.
296 Optional<unsigned> getNumTemplateExpansions() const;
297
298 /// Retrieve the template argument as an integral value.
299 // FIXME: Provide a way to read the integral data without copying the value.
300 llvm::APSInt getAsIntegral() const {
301 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 301, __PRETTY_FUNCTION__))
;
302
303 using namespace llvm;
304
305 if (Integer.BitWidth <= 64)
306 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
307
308 unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
309 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)),
310 Integer.IsUnsigned);
311 }
312
313 /// Retrieve the type of the integral value.
314 QualType getIntegralType() const {
315 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 315, __PRETTY_FUNCTION__))
;
316 return QualType::getFromOpaquePtr(Integer.Type);
317 }
318
319 void setIntegralType(QualType T) {
320 assert(getKind() == Integral && "Unexpected kind")((getKind() == Integral && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Integral && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 320, __PRETTY_FUNCTION__))
;
321 Integer.Type = T.getAsOpaquePtr();
322 }
323
324 /// If this is a non-type template argument, get its type. Otherwise,
325 /// returns a null QualType.
326 QualType getNonTypeTemplateArgumentType() const;
327
328 /// Retrieve the template argument as an expression.
329 Expr *getAsExpr() const {
330 assert(getKind() == Expression && "Unexpected kind")((getKind() == Expression && "Unexpected kind") ? static_cast
<void> (0) : __assert_fail ("getKind() == Expression && \"Unexpected kind\""
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 330, __PRETTY_FUNCTION__))
;
331 return reinterpret_cast<Expr *>(TypeOrValue.V);
332 }
333
334 /// Iterator that traverses the elements of a template argument pack.
335 using pack_iterator = const TemplateArgument *;
336
337 /// Iterator referencing the first argument of a template argument
338 /// pack.
339 pack_iterator pack_begin() const {
340 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 340, __PRETTY_FUNCTION__))
;
341 return Args.Args;
342 }
343
344 /// Iterator referencing one past the last argument of a template
345 /// argument pack.
346 pack_iterator pack_end() const {
347 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 347, __PRETTY_FUNCTION__))
;
348 return Args.Args + Args.NumArgs;
349 }
350
351 /// Iterator range referencing all of the elements of a template
352 /// argument pack.
353 ArrayRef<TemplateArgument> pack_elements() const {
354 return llvm::makeArrayRef(pack_begin(), pack_end());
355 }
356
357 /// The number of template arguments in the given template argument
358 /// pack.
359 unsigned pack_size() const {
360 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 360, __PRETTY_FUNCTION__))
;
361 return Args.NumArgs;
362 }
363
364 /// Return the array of arguments in this template argument pack.
365 ArrayRef<TemplateArgument> getPackAsArray() const {
366 assert(getKind() == Pack)((getKind() == Pack) ? static_cast<void> (0) : __assert_fail
("getKind() == Pack", "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 366, __PRETTY_FUNCTION__))
;
367 return llvm::makeArrayRef(Args.Args, Args.NumArgs);
368 }
369
370 /// Determines whether two template arguments are superficially the
371 /// same.
372 bool structurallyEquals(const TemplateArgument &Other) const;
373
374 /// When the template argument is a pack expansion, returns
375 /// the pattern of the pack expansion.
376 TemplateArgument getPackExpansionPattern() const;
377
378 /// Print this template argument to the given output stream.
379 void print(const PrintingPolicy &Policy, raw_ostream &Out) const;
380
381 /// Debugging aid that dumps the template argument.
382 void dump(raw_ostream &Out) const;
383
384 /// Debugging aid that dumps the template argument to standard error.
385 void dump() const;
386
387 /// Used to insert TemplateArguments into FoldingSets.
388 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
389};
390
391/// Location information for a TemplateArgument.
392struct TemplateArgumentLocInfo {
393private:
394 struct T {
395 // FIXME: We'd like to just use the qualifier in the TemplateName,
396 // but template arguments get canonicalized too quickly.
397 NestedNameSpecifier *Qualifier;
398 void *QualifierLocData;
399 unsigned TemplateNameLoc;
400 unsigned EllipsisLoc;
401 };
402
403 union {
404 struct T Template;
405 Expr *Expression;
406 TypeSourceInfo *Declarator;
407 };
408
409public:
410 constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
411
412 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
413
414 TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
415
416 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
417 SourceLocation TemplateNameLoc,
418 SourceLocation EllipsisLoc) {
419 Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
420 Template.QualifierLocData = QualifierLoc.getOpaqueData();
421 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
422 Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
423 }
424
425 TypeSourceInfo *getAsTypeSourceInfo() const {
426 return Declarator;
427 }
428
429 Expr *getAsExpr() const {
430 return Expression;
431 }
432
433 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
434 return NestedNameSpecifierLoc(Template.Qualifier,
435 Template.QualifierLocData);
436 }
437
438 SourceLocation getTemplateNameLoc() const {
439 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
440 }
441
442 SourceLocation getTemplateEllipsisLoc() const {
443 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
444 }
445};
446
447/// Location wrapper for a TemplateArgument. TemplateArgument is to
448/// TemplateArgumentLoc as Type is to TypeLoc.
449class TemplateArgumentLoc {
450 TemplateArgument Argument;
451 TemplateArgumentLocInfo LocInfo;
452
453public:
454 constexpr TemplateArgumentLoc() {}
455
456 TemplateArgumentLoc(const TemplateArgument &Argument,
457 TemplateArgumentLocInfo Opaque)
458 : Argument(Argument), LocInfo(Opaque) {}
459
460 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
461 : Argument(Argument), LocInfo(TInfo) {
462 assert(Argument.getKind() == TemplateArgument::Type)((Argument.getKind() == TemplateArgument::Type) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 462, __PRETTY_FUNCTION__))
;
463 }
464
465 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
466 : Argument(Argument), LocInfo(E) {
467
468 // Permit any kind of template argument that can be represented with an
469 // expression.
470 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 473, __PRETTY_FUNCTION__))
471 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 473, __PRETTY_FUNCTION__))
472 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 473, __PRETTY_FUNCTION__))
473 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 473, __PRETTY_FUNCTION__))
;
474 }
475
476 TemplateArgumentLoc(const TemplateArgument &Argument,
477 NestedNameSpecifierLoc QualifierLoc,
478 SourceLocation TemplateNameLoc,
479 SourceLocation EllipsisLoc = SourceLocation())
480 : Argument(Argument),
481 LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
482 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 483, __PRETTY_FUNCTION__))
483 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 483, __PRETTY_FUNCTION__))
;
484 }
485
486 /// - Fetches the primary location of the argument.
487 SourceLocation getLocation() const {
488 if (Argument.getKind() == TemplateArgument::Template ||
489 Argument.getKind() == TemplateArgument::TemplateExpansion)
490 return getTemplateNameLoc();
491
492 return getSourceRange().getBegin();
493 }
494
495 /// - Fetches the full source range of the argument.
496 SourceRange getSourceRange() const LLVM_READONLY__attribute__((__pure__));
497
498 const TemplateArgument &getArgument() const {
499 return Argument;
500 }
501
502 TemplateArgumentLocInfo getLocInfo() const {
503 return LocInfo;
504 }
505
506 TypeSourceInfo *getTypeSourceInfo() const {
507 assert(Argument.getKind() == TemplateArgument::Type)((Argument.getKind() == TemplateArgument::Type) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Type"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 507, __PRETTY_FUNCTION__))
;
508 return LocInfo.getAsTypeSourceInfo();
509 }
510
511 Expr *getSourceExpression() const {
512 assert(Argument.getKind() == TemplateArgument::Expression)((Argument.getKind() == TemplateArgument::Expression) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Expression"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 512, __PRETTY_FUNCTION__))
;
513 return LocInfo.getAsExpr();
514 }
515
516 Expr *getSourceDeclExpression() const {
517 assert(Argument.getKind() == TemplateArgument::Declaration)((Argument.getKind() == TemplateArgument::Declaration) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Declaration"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 517, __PRETTY_FUNCTION__))
;
518 return LocInfo.getAsExpr();
519 }
520
521 Expr *getSourceNullPtrExpression() const {
522 assert(Argument.getKind() == TemplateArgument::NullPtr)((Argument.getKind() == TemplateArgument::NullPtr) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::NullPtr"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 522, __PRETTY_FUNCTION__))
;
523 return LocInfo.getAsExpr();
524 }
525
526 Expr *getSourceIntegralExpression() const {
527 assert(Argument.getKind() == TemplateArgument::Integral)((Argument.getKind() == TemplateArgument::Integral) ? static_cast
<void> (0) : __assert_fail ("Argument.getKind() == TemplateArgument::Integral"
, "/build/llvm-toolchain-snapshot-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 527, __PRETTY_FUNCTION__))
;
528 return LocInfo.getAsExpr();
529 }
530
531 NestedNameSpecifierLoc getTemplateQualifierLoc() const {
532 if (Argument.getKind() != TemplateArgument::Template &&
533 Argument.getKind() != TemplateArgument::TemplateExpansion)
534 return NestedNameSpecifierLoc();
535 return LocInfo.getTemplateQualifierLoc();
536 }
537
538 SourceLocation getTemplateNameLoc() const {
539 if (Argument.getKind() != TemplateArgument::Template &&
540 Argument.getKind() != TemplateArgument::TemplateExpansion)
541 return SourceLocation();
542 return LocInfo.getTemplateNameLoc();
543 }
544
545 SourceLocation getTemplateEllipsisLoc() const {
546 if (Argument.getKind() != TemplateArgument::TemplateExpansion)
547 return SourceLocation();
548 return LocInfo.getTemplateEllipsisLoc();
549 }
550};
551
552/// A convenient class for passing around template argument
553/// information. Designed to be passed by reference.
554class TemplateArgumentListInfo {
555 SmallVector<TemplateArgumentLoc, 8> Arguments;
556 SourceLocation LAngleLoc;
557 SourceLocation RAngleLoc;
558
559public:
560 TemplateArgumentListInfo() = default;
561
562 TemplateArgumentListInfo(SourceLocation LAngleLoc,
563 SourceLocation RAngleLoc)
564 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
565
566 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
567 // instead.
568 void *operator new(size_t bytes, ASTContext &C) = delete;
569
570 SourceLocation getLAngleLoc() const { return LAngleLoc; }
571 SourceLocation getRAngleLoc() const { return RAngleLoc; }
572
573 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
574 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
575
576 unsigned size() const { return Arguments.size(); }
577
578 const TemplateArgumentLoc *getArgumentArray() const {
579 return Arguments.data();
580 }
581
582 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
583 return Arguments;
584 }
585
586 const TemplateArgumentLoc &operator[](unsigned I) const {
587 return Arguments[I];
588 }
589
590 TemplateArgumentLoc &operator[](unsigned I) {
591 return Arguments[I];
592 }
593
594 void addArgument(const TemplateArgumentLoc &Loc) {
595 Arguments.push_back(Loc);
596 }
597};
598
599/// Represents an explicit template argument list in C++, e.g.,
600/// the "<int>" in "sort<int>".
601/// This is safe to be used inside an AST node, in contrast with
602/// TemplateArgumentListInfo.
603struct ASTTemplateArgumentListInfo final
604 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
605 TemplateArgumentLoc> {
606private:
607 friend class ASTNodeImporter;
608 friend TrailingObjects;
609
610 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
611
612public:
613 /// The source location of the left angle bracket ('<').
614 SourceLocation LAngleLoc;
615
616 /// The source location of the right angle bracket ('>').
617 SourceLocation RAngleLoc;
618
619 /// The number of template arguments in TemplateArgs.
620 unsigned NumTemplateArgs;
621
622 SourceLocation getLAngleLoc() const { return LAngleLoc; }
623 SourceLocation getRAngleLoc() const { return RAngleLoc; }
624
625 /// Retrieve the template arguments
626 const TemplateArgumentLoc *getTemplateArgs() const {
627 return getTrailingObjects<TemplateArgumentLoc>();
628 }
629 unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
630
631 llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
632 return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs());
633 }
634
635 const TemplateArgumentLoc &operator[](unsigned I) const {
636 return getTemplateArgs()[I];
637 }
638
639 static const ASTTemplateArgumentListInfo *
640 Create(ASTContext &C, const TemplateArgumentListInfo &List);
641};
642
643/// Represents an explicit template argument list in C++, e.g.,
644/// the "<int>" in "sort<int>".
645///
646/// It is intended to be used as a trailing object on AST nodes, and
647/// as such, doesn't contain the array of TemplateArgumentLoc itself,
648/// but expects the containing object to also provide storage for
649/// that.
650struct alignas(void *) ASTTemplateKWAndArgsInfo {
651 /// The source location of the left angle bracket ('<').
652 SourceLocation LAngleLoc;
653
654 /// The source location of the right angle bracket ('>').
655 SourceLocation RAngleLoc;
656
657 /// The source location of the template keyword; this is used
658 /// as part of the representation of qualified identifiers, such as
659 /// S<T>::template apply<T>. Will be empty if this expression does
660 /// not have a template keyword.
661 SourceLocation TemplateKWLoc;
662
663 /// The number of template arguments in TemplateArgs.
664 unsigned NumTemplateArgs;
665
666 void initializeFrom(SourceLocation TemplateKWLoc,
667 const TemplateArgumentListInfo &List,
668 TemplateArgumentLoc *OutArgArray);
669 void initializeFrom(SourceLocation TemplateKWLoc,
670 const TemplateArgumentListInfo &List,
671 TemplateArgumentLoc *OutArgArray, bool &Dependent,
672 bool &InstantiationDependent,
673 bool &ContainsUnexpandedParameterPack);
674 void initializeFrom(SourceLocation TemplateKWLoc);
675
676 void copyInto(const TemplateArgumentLoc *ArgArray,
677 TemplateArgumentListInfo &List) const;
678};
679
680const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
681 const TemplateArgument &Arg);
682
683inline TemplateSpecializationType::iterator
684 TemplateSpecializationType::end() const {
685 return getArgs() + getNumArgs();
686}
687
688inline DependentTemplateSpecializationType::iterator
689 DependentTemplateSpecializationType::end() const {
690 return getArgs() + getNumArgs();
691}
692
693inline const TemplateArgument &
694 TemplateSpecializationType::getArg(unsigned Idx) const {
695 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 695, __PRETTY_FUNCTION__))
;
696 return getArgs()[Idx];
697}
698
699inline const TemplateArgument &
700 DependentTemplateSpecializationType::getArg(unsigned Idx) const {
701 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-10~svn373517/tools/clang/include/clang/AST/TemplateBase.h"
, 701, __PRETTY_FUNCTION__))
;
702 return getArgs()[Idx];
703}
704
705} // namespace clang
706
707#endif // LLVM_CLANG_AST_TEMPLATEBASE_H