clang 18.0.0git
TemplateBase.cpp
Go to the documentation of this file.
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
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/LLVM.h"
30#include "llvm/ADT/APSInt.h"
31#include "llvm/ADT/FoldingSet.h"
32#include "llvm/ADT/SmallString.h"
33#include "llvm/ADT/StringExtras.h"
34#include "llvm/ADT/StringRef.h"
35#include "llvm/Support/Casting.h"
36#include "llvm/Support/Compiler.h"
37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/raw_ostream.h"
39#include <cassert>
40#include <cstddef>
41#include <cstdint>
42#include <cstring>
43#include <optional>
44
45using namespace clang;
46
47/// Print a template integral argument value.
48///
49/// \param TemplArg the TemplateArgument instance to print.
50///
51/// \param Out the raw_ostream instance to use for printing.
52///
53/// \param Policy the printing policy for EnumConstantDecl printing.
54///
55/// \param IncludeType If set, ensure that the type of the expression printed
56/// matches the type of the template argument.
57static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
58 const PrintingPolicy &Policy, bool IncludeType) {
59 const Type *T = TemplArg.getIntegralType().getTypePtr();
60 const llvm::APSInt &Val = TemplArg.getAsIntegral();
61
62 if (Policy.UseEnumerators) {
63 if (const EnumType *ET = T->getAs<EnumType>()) {
64 for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {
65 // In Sema::CheckTemplateArugment, enum template arguments value are
66 // extended to the size of the integer underlying the enum type. This
67 // may create a size difference between the enum value and template
68 // argument value, requiring isSameValue here instead of operator==.
69 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
70 ECD->printQualifiedName(Out, Policy);
71 return;
72 }
73 }
74 }
75 }
76
77 if (Policy.MSVCFormatting)
78 IncludeType = false;
79
80 if (T->isBooleanType()) {
81 if (!Policy.MSVCFormatting)
82 Out << (Val.getBoolValue() ? "true" : "false");
83 else
84 Out << Val;
85 } else if (T->isCharType()) {
86 if (IncludeType) {
87 if (T->isSpecificBuiltinType(BuiltinType::SChar))
88 Out << "(signed char)";
89 else if (T->isSpecificBuiltinType(BuiltinType::UChar))
90 Out << "(unsigned char)";
91 }
92 CharacterLiteral::print(Val.getZExtValue(), CharacterLiteral::Ascii, Out);
93 } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
95 if (T->isWideCharType())
97 else if (T->isChar8Type())
99 else if (T->isChar16Type())
101 else if (T->isChar32Type())
103 else
105 CharacterLiteral::print(Val.getExtValue(), Kind, Out);
106 } else if (IncludeType) {
107 if (const auto *BT = T->getAs<BuiltinType>()) {
108 switch (BT->getKind()) {
109 case BuiltinType::ULongLong:
110 Out << Val << "ULL";
111 break;
112 case BuiltinType::LongLong:
113 Out << Val << "LL";
114 break;
115 case BuiltinType::ULong:
116 Out << Val << "UL";
117 break;
118 case BuiltinType::Long:
119 Out << Val << "L";
120 break;
121 case BuiltinType::UInt:
122 Out << Val << "U";
123 break;
124 case BuiltinType::Int:
125 Out << Val;
126 break;
127 default:
128 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
129 << Val;
130 break;
131 }
132 } else
133 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
134 << Val;
135 } else
136 Out << Val;
137}
138
139static unsigned getArrayDepth(QualType type) {
140 unsigned count = 0;
141 while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
142 count++;
143 type = arrayType->getElementType();
144 }
145 return count;
146}
147
148static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
149 // Generally, if the parameter type is a pointer, we must be taking the
150 // address of something and need a &. However, if the argument is an array,
151 // this could be implicit via array-to-pointer decay.
152 if (!paramType->isPointerType())
153 return paramType->isMemberPointerType();
154 if (argType->isArrayType())
155 return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
156 return true;
157}
158
159//===----------------------------------------------------------------------===//
160// TemplateArgument Implementation
161//===----------------------------------------------------------------------===//
162
164 QualType Type, bool IsDefaulted) {
165 Integer.Kind = Integral;
166 Integer.IsDefaulted = IsDefaulted;
167 // Copy the APSInt value into our decomposed form.
168 Integer.BitWidth = Value.getBitWidth();
169 Integer.IsUnsigned = Value.isUnsigned();
170 // If the value is large, we have to get additional memory from the ASTContext
171 unsigned NumWords = Value.getNumWords();
172 if (NumWords > 1) {
173 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
174 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
175 Integer.pVal = static_cast<uint64_t *>(Mem);
176 } else {
177 Integer.VAL = Value.getZExtValue();
178 }
179
180 Integer.Type = Type.getAsOpaquePtr();
181}
182
186 if (Args.empty())
187 return getEmptyPack();
188
189 return TemplateArgument(Args.copy(Context));
190}
191
192TemplateArgumentDependence TemplateArgument::getDependence() const {
193 auto Deps = TemplateArgumentDependence::None;
194 switch (getKind()) {
195 case Null:
196 llvm_unreachable("Should not have a NULL template argument");
197
198 case Type:
200 if (isa<PackExpansionType>(getAsType()))
201 Deps |= TemplateArgumentDependence::Dependent;
202 return Deps;
203
204 case Template:
206
208 return TemplateArgumentDependence::Dependent |
209 TemplateArgumentDependence::Instantiation;
210
211 case Declaration: {
212 auto *DC = dyn_cast<DeclContext>(getAsDecl());
213 if (!DC)
214 DC = getAsDecl()->getDeclContext();
215 if (DC->isDependentContext())
216 Deps = TemplateArgumentDependence::Dependent |
217 TemplateArgumentDependence::Instantiation;
218 return Deps;
219 }
220
221 case NullPtr:
222 case Integral:
223 return TemplateArgumentDependence::None;
224
225 case Expression:
227 if (isa<PackExpansionExpr>(getAsExpr()))
228 Deps |= TemplateArgumentDependence::Dependent |
229 TemplateArgumentDependence::Instantiation;
230 return Deps;
231
232 case Pack:
233 for (const auto &P : pack_elements())
234 Deps |= P.getDependence();
235 return Deps;
236 }
237 llvm_unreachable("unhandled ArgKind");
238}
239
241 return getDependence() & TemplateArgumentDependence::Dependent;
242}
243
245 return getDependence() & TemplateArgumentDependence::Instantiation;
246}
247
249 switch (getKind()) {
250 case Null:
251 case Declaration:
252 case Integral:
253 case Pack:
254 case Template:
255 case NullPtr:
256 return false;
257
259 return true;
260
261 case Type:
262 return isa<PackExpansionType>(getAsType());
263
264 case Expression:
265 return isa<PackExpansionExpr>(getAsExpr());
266 }
267
268 llvm_unreachable("Invalid TemplateArgument Kind!");
269}
270
272 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
273}
274
275std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
276 assert(getKind() == TemplateExpansion);
277 if (TemplateArg.NumExpansions)
278 return TemplateArg.NumExpansions - 1;
279
280 return std::nullopt;
281}
282
284 switch (getKind()) {
290 return QualType();
291
293 return getIntegralType();
294
296 return getAsExpr()->getType();
297
299 return getParamTypeForDecl();
300
302 return getNullPtrType();
303 }
304
305 llvm_unreachable("Invalid TemplateArgument Kind!");
306}
307
308void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
309 const ASTContext &Context) const {
310 ID.AddInteger(getKind());
311 switch (getKind()) {
312 case Null:
313 break;
314
315 case Type:
316 getAsType().Profile(ID);
317 break;
318
319 case NullPtr:
321 break;
322
323 case Declaration:
325 ID.AddPointer(getAsDecl());
326 break;
327
329 ID.AddInteger(TemplateArg.NumExpansions);
330 [[fallthrough]];
331 case Template:
332 ID.AddPointer(TemplateArg.Name);
333 break;
334
335 case Integral:
336 getAsIntegral().Profile(ID);
338 break;
339
340 case Expression:
341 getAsExpr()->Profile(ID, Context, true);
342 break;
343
344 case Pack:
345 ID.AddInteger(Args.NumArgs);
346 for (unsigned I = 0; I != Args.NumArgs; ++I)
347 Args.Args[I].Profile(ID, Context);
348 }
349}
350
352 if (getKind() != Other.getKind()) return false;
353
354 switch (getKind()) {
355 case Null:
356 case Type:
357 case Expression:
358 case NullPtr:
359 return TypeOrValue.V == Other.TypeOrValue.V;
360
361 case Template:
363 return TemplateArg.Name == Other.TemplateArg.Name &&
364 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
365
366 case Declaration:
367 return getAsDecl() == Other.getAsDecl() &&
368 getParamTypeForDecl() == Other.getParamTypeForDecl();
369
370 case Integral:
371 return getIntegralType() == Other.getIntegralType() &&
372 getAsIntegral() == Other.getAsIntegral();
373
374 case Pack:
375 if (Args.NumArgs != Other.Args.NumArgs) return false;
376 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
377 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
378 return false;
379 return true;
380 }
381
382 llvm_unreachable("Invalid TemplateArgument Kind!");
383}
384
386 assert(isPackExpansion());
387
388 switch (getKind()) {
389 case Type:
390 return getAsType()->castAs<PackExpansionType>()->getPattern();
391
392 case Expression:
393 return cast<PackExpansionExpr>(getAsExpr())->getPattern();
394
397
398 case Declaration:
399 case Integral:
400 case Pack:
401 case Null:
402 case Template:
403 case NullPtr:
404 return TemplateArgument();
405 }
406
407 llvm_unreachable("Invalid TemplateArgument Kind!");
408}
409
410void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
411 bool IncludeType) const {
412
413 switch (getKind()) {
414 case Null:
415 Out << "(no value)";
416 break;
417
418 case Type: {
419 PrintingPolicy SubPolicy(Policy);
420 SubPolicy.SuppressStrongLifetime = true;
421 getAsType().print(Out, SubPolicy);
422 break;
423 }
424
425 case Declaration: {
426 NamedDecl *ND = getAsDecl();
428 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
429 TPO->getType().getUnqualifiedType().print(Out, Policy);
430 TPO->printAsInit(Out, Policy);
431 break;
432 }
433 }
434 if (auto *VD = dyn_cast<ValueDecl>(ND)) {
436 Out << "&";
437 }
438 ND->printQualifiedName(Out);
439 break;
440 }
441
442 case NullPtr:
443 // FIXME: Include the type if it's not obvious from the context.
444 Out << "nullptr";
445 break;
446
447 case Template:
449 break;
450
453 Out << "...";
454 break;
455
456 case Integral:
457 printIntegral(*this, Out, Policy, IncludeType);
458 break;
459
460 case Expression:
461 getAsExpr()->printPretty(Out, nullptr, Policy);
462 break;
463
464 case Pack:
465 Out << "<";
466 bool First = true;
467 for (const auto &P : pack_elements()) {
468 if (First)
469 First = false;
470 else
471 Out << ", ";
472
473 P.print(Policy, Out, IncludeType);
474 }
475 Out << ">";
476 break;
477 }
478}
479
480void TemplateArgument::dump(raw_ostream &Out) const {
481 LangOptions LO; // FIXME! see also TemplateName::dump().
482 LO.CPlusPlus = true;
483 LO.Bool = true;
484 print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
485}
486
487LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
488
489//===----------------------------------------------------------------------===//
490// TemplateArgumentLoc Implementation
491//===----------------------------------------------------------------------===//
492
494 switch (Argument.getKind()) {
497
500
503
506 return TSI->getTypeLoc().getSourceRange();
507 else
508 return SourceRange();
509
512 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
515
518 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
521
524
527 return SourceRange();
528 }
529
530 llvm_unreachable("Invalid TemplateArgument Kind!");
531}
532
533template <typename T>
534static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
535 switch (Arg.getKind()) {
537 // This is bad, but not as bad as crashing because of argument
538 // count mismatches.
539 return DB << "(null template argument)";
540
542 return DB << Arg.getAsType();
543
545 return DB << Arg.getAsDecl();
546
548 return DB << "nullptr";
549
551 return DB << toString(Arg.getAsIntegral(), 10);
552
554 return DB << Arg.getAsTemplate();
555
557 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
558
560 // This shouldn't actually ever happen, so it's okay that we're
561 // regurgitating an expression here.
562 // FIXME: We're guessing at LangOptions!
563 SmallString<32> Str;
564 llvm::raw_svector_ostream OS(Str);
565 LangOptions LangOpts;
566 LangOpts.CPlusPlus = true;
567 PrintingPolicy Policy(LangOpts);
568 Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
569 return DB << OS.str();
570 }
571
573 // FIXME: We're guessing at LangOptions!
574 SmallString<32> Str;
575 llvm::raw_svector_ostream OS(Str);
576 LangOptions LangOpts;
577 LangOpts.CPlusPlus = true;
578 PrintingPolicy Policy(LangOpts);
579 Arg.print(Policy, OS, /*IncludeType*/ true);
580 return DB << OS.str();
581 }
582 }
583
584 llvm_unreachable("Invalid TemplateArgument Kind!");
585}
586
588 const TemplateArgument &Arg) {
589 return DiagTemplateArg(DB, Arg);
590}
591
593 ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
594 SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
595 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
596 Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
597 Template->QualifierLocData = QualifierLoc.getOpaqueData();
598 Template->TemplateNameLoc = TemplateNameLoc;
599 Template->EllipsisLoc = EllipsisLoc;
600 Pointer = Template;
601}
602
605 const TemplateArgumentListInfo &List) {
606 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
607 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
608 return new (Mem) ASTTemplateArgumentListInfo(List);
609}
610
613 const ASTTemplateArgumentListInfo *List) {
614 if (!List)
615 return nullptr;
616 std::size_t size =
617 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
618 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
619 return new (Mem) ASTTemplateArgumentListInfo(List);
620}
621
622ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
623 const TemplateArgumentListInfo &Info) {
624 LAngleLoc = Info.getLAngleLoc();
625 RAngleLoc = Info.getRAngleLoc();
626 NumTemplateArgs = Info.size();
627
628 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
629 for (unsigned i = 0; i != NumTemplateArgs; ++i)
630 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
631}
632
633ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
634 const ASTTemplateArgumentListInfo *Info) {
635 LAngleLoc = Info->getLAngleLoc();
636 RAngleLoc = Info->getRAngleLoc();
638
639 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
640 for (unsigned i = 0; i != NumTemplateArgs; ++i)
641 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
642}
643
645 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
646 TemplateArgumentLoc *OutArgArray) {
647 this->TemplateKWLoc = TemplateKWLoc;
648 LAngleLoc = Info.getLAngleLoc();
649 RAngleLoc = Info.getRAngleLoc();
650 NumTemplateArgs = Info.size();
651
652 for (unsigned i = 0; i != NumTemplateArgs; ++i)
653 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
654}
655
657 assert(TemplateKWLoc.isValid());
660 this->TemplateKWLoc = TemplateKWLoc;
661 NumTemplateArgs = 0;
662}
663
665 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
666 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
667 this->TemplateKWLoc = TemplateKWLoc;
668 LAngleLoc = Info.getLAngleLoc();
669 RAngleLoc = Info.getRAngleLoc();
670 NumTemplateArgs = Info.size();
671
672 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
673 Deps |= Info[i].getArgument().getDependence();
674
675 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
676 }
677}
678
680 TemplateArgumentListInfo &Info) const {
683 for (unsigned I = 0; I != NumTemplateArgs; ++I)
684 Info.addArgument(ArgArray[I]);
685}
Defines the clang::ASTContext interface.
StringRef P
Defines the Diagnostic-related interfaces.
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static bool isRecordType(QualType T)
Defines the clang::SourceLocation class and associated facilities.
static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out, const PrintingPolicy &Policy, bool IncludeType)
Print a template integral argument value.
static unsigned getArrayDepth(QualType type)
static const T & DiagTemplateArg(const T &DB, const TemplateArgument &Arg)
static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType)
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:704
This class is used for builtin types like 'int'.
Definition: Type.h:2682
static void print(unsigned val, CharacterKind Kind, raw_ostream &OS)
Definition: Expr.cpp:1045
DeclContext * getDeclContext()
Definition: DeclBase.h:441
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3197
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:4959
QualType getType() const
Definition: Expr.h:142
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:83
This represents a decl that may have a name.
Definition: Decl.h:247
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition: Decl.cpp:1687
A C++ nested-name-specifier augmented with source location information.
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a pack expansion of types.
Definition: Type.h:5956
A (possibly-)qualified type.
Definition: Type.h:736
void Profile(llvm::FoldingSetNodeID &ID) const
Definition: Type.h:1186
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6747
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1120
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:325
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1110
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
SourceLocation getRAngleLoc() const
Definition: TemplateBase.h:607
void setLAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:609
void setRAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:610
void addArgument(const TemplateArgumentLoc &Loc)
Definition: TemplateBase.h:630
SourceLocation getLAngleLoc() const
Definition: TemplateBase.h:606
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
SourceLocation getTemplateEllipsisLoc() const
Definition: TemplateBase.h:581
Expr * getSourceIntegralExpression() const
Definition: TemplateBase.h:562
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:541
Expr * getSourceNullPtrExpression() const
Definition: TemplateBase.h:557
SourceRange getSourceRange() const LLVM_READONLY
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:567
Expr * getSourceDeclExpression() const
Definition: TemplateBase.h:552
Expr * getSourceExpression() const
Definition: TemplateBase.h:547
Represents a template argument.
Definition: TemplateBase.h:60
QualType getParamTypeForDecl() const
Definition: TemplateBase.h:299
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:368
bool isDependent() const
Whether this template argument is dependent on a template parameter such that its result can change f...
std::optional< unsigned > getNumTemplateExpansions() const
Retrieve the number of expansions that a template template argument expansion will produce,...
bool isInstantiationDependent() const
Whether this template argument is dependent on a template parameter.
constexpr TemplateArgument()
Construct an empty, invalid template argument.
Definition: TemplateBase.h:155
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
void dump() const
Debugging aid that dumps the template argument to standard error.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:287
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:331
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
Definition: TemplateBase.h:305
static TemplateArgument CreatePackCopy(ASTContext &Context, ArrayRef< TemplateArgument > Args)
Create a new template argument pack by copying the given set of template arguments.
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:311
bool containsUnexpandedParameterPack() const
Whether this template argument contains an unexpanded parameter pack.
TemplateArgument getPackExpansionPattern() const
When the template argument is a pack expansion, returns the pattern of the pack expansion.
static TemplateArgument getEmptyPack()
Definition: TemplateBase.h:253
bool structurallyEquals(const TemplateArgument &Other) const
Determines whether two template arguments are superficially the same.
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
QualType getIntegralType() const
Retrieve the type of the integral value.
Definition: TemplateBase.h:345
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:294
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:392
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:73
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:85
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:99
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:89
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:77
@ Type
The template argument is a type.
Definition: TemplateBase.h:69
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:66
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:81
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:95
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:263
TemplateArgumentDependence getDependence() const
bool isPackExpansion() const
Determine whether this template argument is a pack expansion.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:318
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
A container of type source information.
Definition: Type.h:6718
The base class of the type hierarchy.
Definition: Type.h:1597
bool isBooleanType() const
Definition: Type.h:7433
bool isArrayType() const
Definition: Type.h:7065
bool isCharType() const
Definition: Type.cpp:2030
bool isPointerType() const
Definition: Type.h:6999
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7590
bool isChar8Type() const
Definition: Type.cpp:2046
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:655
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition: Type.cpp:2066
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: Type.h:7286
bool isChar16Type() const
Definition: Type.cpp:2052
QualType getCanonicalTypeInternal() const
Definition: Type.h:2645
bool isMemberPointerType() const
Definition: Type.h:7047
bool isChar32Type() const
Definition: Type.cpp:2058
bool isWideCharType() const
Definition: Type.cpp:2039
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7523
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
@ C
Languages that the frontend can parse and compile.
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:641
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
Definition: TemplateBase.h:656
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
Definition: TemplateBase.h:653
SourceLocation getLAngleLoc() const
Definition: TemplateBase.h:661
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
Definition: TemplateBase.h:659
SourceLocation getRAngleLoc() const
Definition: TemplateBase.h:662
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
Definition: TemplateBase.h:695
void copyInto(const TemplateArgumentLoc *ArgArray, TemplateArgumentListInfo &List) const
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
Definition: TemplateBase.h:707
void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, TemplateArgumentLoc *OutArgArray)
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
Definition: TemplateBase.h:698
SourceLocation TemplateKWLoc
The source location of the template keyword; this is used as part of the representation of qualified ...
Definition: TemplateBase.h:704
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
unsigned MSVCFormatting
Use whitespace and punctuation like MSVC does.
unsigned SuppressStrongLifetime
When true, suppress printing of the __strong lifetime qualifier in ARC.
unsigned UseEnumerators
Whether to print enumerator non-type template parameters with a matching enumerator name or via cast ...