clang 22.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/StringExtras.h"
33#include "llvm/Support/Compiler.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/raw_ostream.h"
36#include <cassert>
37#include <cstddef>
38#include <cstdint>
39#include <cstring>
40
41using namespace clang;
42
43/// Print a template integral argument value.
44///
45/// \param TemplArg the TemplateArgument instance to print.
46///
47/// \param Out the raw_ostream instance to use for printing.
48///
49/// \param Policy the printing policy for EnumConstantDecl printing.
50///
51/// \param IncludeType If set, ensure that the type of the expression printed
52/// matches the type of the template argument.
53static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
54 const PrintingPolicy &Policy, bool IncludeType) {
55 const Type *T = TemplArg.getIntegralType().getTypePtr();
56 const llvm::APSInt &Val = TemplArg.getAsIntegral();
57
58 if (Policy.UseEnumerators) {
59 if (const auto *ED = T->getAsEnumDecl()) {
60 for (const EnumConstantDecl *ECD : ED->enumerators()) {
61 // In Sema::CheckTemplateArugment, enum template arguments value are
62 // extended to the size of the integer underlying the enum type. This
63 // may create a size difference between the enum value and template
64 // argument value, requiring isSameValue here instead of operator==.
65 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
66 ECD->printQualifiedName(Out, Policy);
67 return;
68 }
69 }
70 }
71 }
72
73 if (Policy.MSVCFormatting)
74 IncludeType = false;
75
76 if (T->isBooleanType()) {
77 if (!Policy.MSVCFormatting)
78 Out << (Val.getBoolValue() ? "true" : "false");
79 else
80 Out << Val;
81 } else if (T->isCharType()) {
82 if (IncludeType) {
83 if (T->isSpecificBuiltinType(BuiltinType::SChar))
84 Out << "(signed char)";
85 else if (T->isSpecificBuiltinType(BuiltinType::UChar))
86 Out << "(unsigned char)";
87 }
89 Out);
90 } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
92 if (T->isWideCharType())
94 else if (T->isChar8Type())
96 else if (T->isChar16Type())
98 else if (T->isChar32Type())
100 else
102 CharacterLiteral::print(Val.getExtValue(), Kind, Out);
103 } else if (IncludeType) {
104 if (const auto *BT = T->getAs<BuiltinType>()) {
105 switch (BT->getKind()) {
106 case BuiltinType::ULongLong:
107 Out << Val << "ULL";
108 break;
109 case BuiltinType::LongLong:
110 Out << Val << "LL";
111 break;
112 case BuiltinType::ULong:
113 Out << Val << "UL";
114 break;
115 case BuiltinType::Long:
116 Out << Val << "L";
117 break;
118 case BuiltinType::UInt:
119 Out << Val << "U";
120 break;
121 case BuiltinType::Int:
122 Out << Val;
123 break;
124 default:
125 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
126 << Val;
127 break;
128 }
129 } else
130 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
131 << Val;
132 } else
133 Out << Val;
134}
135
136static unsigned getArrayDepth(QualType type) {
137 unsigned count = 0;
138 while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
139 count++;
140 type = arrayType->getElementType();
141 }
142 return count;
143}
144
145static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
146 // Generally, if the parameter type is a pointer, we must be taking the
147 // address of something and need a &. However, if the argument is an array,
148 // this could be implicit via array-to-pointer decay.
149 if (!paramType->isPointerType())
150 return paramType->isMemberPointerType();
151 if (argType->isArrayType())
152 return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
153 return true;
154}
155
156//===----------------------------------------------------------------------===//
157// TemplateArgument Implementation
158//===----------------------------------------------------------------------===//
159
160void TemplateArgument::initFromType(QualType T, bool IsNullPtr,
161 bool IsDefaulted) {
162 TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
163 TypeOrValue.IsDefaulted = IsDefaulted;
164 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
165}
166
167void TemplateArgument::initFromDeclaration(ValueDecl *D, QualType QT,
168 bool IsDefaulted) {
169 assert(D && "Expected decl");
170 DeclArg.Kind = Declaration;
171 DeclArg.IsDefaulted = IsDefaulted;
172 DeclArg.QT = QT.getAsOpaquePtr();
173 DeclArg.D = D;
174}
175
176void TemplateArgument::initFromIntegral(const ASTContext &Ctx,
177 const llvm::APSInt &Value,
178 QualType Type, bool IsDefaulted) {
179 Integer.Kind = Integral;
180 Integer.IsDefaulted = IsDefaulted;
181 // Copy the APSInt value into our decomposed form.
182 Integer.BitWidth = Value.getBitWidth();
183 Integer.IsUnsigned = Value.isUnsigned();
184 // If the value is large, we have to get additional memory from the ASTContext
185 unsigned NumWords = Value.getNumWords();
186 if (NumWords > 1) {
187 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
188 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
189 Integer.pVal = static_cast<uint64_t *>(Mem);
190 } else {
191 Integer.VAL = Value.getZExtValue();
192 }
193
194 Integer.Type = Type.getAsOpaquePtr();
195}
196
197void TemplateArgument::initFromStructural(const ASTContext &Ctx, QualType Type,
198 const APValue &V, bool IsDefaulted) {
199 Value.Kind = StructuralValue;
200 Value.IsDefaulted = IsDefaulted;
201 Value.Value = new (Ctx) APValue(V);
202 Ctx.addDestruction(Value.Value);
203 Value.Type = Type.getAsOpaquePtr();
204}
205
207 const llvm::APSInt &Value, QualType Type,
208 bool IsDefaulted) {
209 initFromIntegral(Ctx, Value, Type, IsDefaulted);
210}
211
213 QualType T, const APValue &V) {
214 // Pointers to members are relatively easy.
215 if (V.isMemberPointer() && V.getMemberPointerPath().empty())
216 return V.getMemberPointerDecl();
217
218 // We model class non-type template parameters as their template parameter
219 // object declaration.
220 if (V.isStruct() || V.isUnion()) {
221 // Dependent types are not supposed to be described as
222 // TemplateParamObjectDecls.
223 if (T->isDependentType() || T->isInstantiationDependentType())
224 return nullptr;
225 return Ctx.getTemplateParamObjectDecl(T, V);
226 }
227
228 // Pointers and references with an empty path use the special 'Declaration'
229 // representation.
230 if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&
231 !V.isLValueOnePastTheEnd())
232 return V.getLValueBase().dyn_cast<const ValueDecl *>();
233
234 // Everything else uses the 'structural' representation.
235 return nullptr;
236}
237
239 const APValue &V, bool IsDefaulted) {
240 if (Type->isIntegralOrEnumerationType() && V.isInt())
241 initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);
242 else if ((V.isLValue() && V.isNullPointer()) ||
243 (V.isMemberPointer() && !V.getMemberPointerDecl()))
244 initFromType(Type, /*isNullPtr=*/true, IsDefaulted);
245 else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
246 // FIXME: The Declaration form should expose a const ValueDecl*.
247 initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);
248 else
249 initFromStructural(Ctx, Type, V, IsDefaulted);
250}
251
255 if (Args.empty())
256 return getEmptyPack();
257
258 return TemplateArgument(Args.copy(Context));
259}
260
261TemplateArgumentDependence TemplateArgument::getDependence() const {
262 auto Deps = TemplateArgumentDependence::None;
263 switch (getKind()) {
264 case Null:
265 llvm_unreachable("Should not have a NULL template argument");
266
267 case Type:
270 Deps |= TemplateArgumentDependence::Dependent;
271 return Deps;
272
273 case Template:
275
277 return TemplateArgumentDependence::Dependent |
278 TemplateArgumentDependence::Instantiation;
279
280 case Declaration: {
281 auto *DC = dyn_cast<DeclContext>(getAsDecl());
282 if (!DC)
283 DC = getAsDecl()->getDeclContext();
284 if (DC->isDependentContext())
285 Deps = TemplateArgumentDependence::Dependent |
286 TemplateArgumentDependence::Instantiation;
287 return Deps;
288 }
289
290 case NullPtr:
291 case Integral:
292 case StructuralValue:
293 return TemplateArgumentDependence::None;
294
295 case Expression:
298 Deps |= TemplateArgumentDependence::Dependent |
299 TemplateArgumentDependence::Instantiation;
300 return Deps;
301
302 case Pack:
303 for (const auto &P : pack_elements())
304 Deps |= P.getDependence();
305 return Deps;
306 }
307 llvm_unreachable("unhandled ArgKind");
308}
309
311 return getDependence() & TemplateArgumentDependence::Dependent;
312}
313
315 return getDependence() & TemplateArgumentDependence::Instantiation;
316}
317
319 switch (getKind()) {
320 case Null:
321 case Declaration:
322 case Integral:
323 case StructuralValue:
324 case Pack:
325 case Template:
326 case NullPtr:
327 return false;
328
330 return true;
331
332 case Type:
334
335 case Expression:
337 }
338
339 llvm_unreachable("Invalid TemplateArgument Kind!");
340}
341
344 return false;
345
346 if (isa_and_nonnull<ConceptDecl>(getAsTemplate().getAsTemplateDecl()))
347 return true;
348 if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
349 getAsTemplate().getAsTemplateDecl()))
350 return TTP->templateParameterKind() == TNK_Concept_template;
351 return false;
352}
353
355 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
356}
357
359 assert(getKind() == TemplateExpansion);
360 return TemplateArg.NumExpansions;
361}
362
364 switch (getKind()) {
370 return QualType();
371
373 return getIntegralType();
374
376 return getAsExpr()->getType();
377
379 return getParamTypeForDecl();
380
382 return getNullPtrType();
383
385 return getStructuralValueType();
386 }
387
388 llvm_unreachable("Invalid TemplateArgument Kind!");
389}
390
391void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
392 const ASTContext &Context) const {
393 ID.AddInteger(getKind());
394 switch (getKind()) {
395 case Null:
396 break;
397
398 case Type:
399 getAsType().Profile(ID);
400 break;
401
402 case NullPtr:
404 break;
405
406 case Declaration:
408 ID.AddPointer(getAsDecl());
409 break;
410
412 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
413 [[fallthrough]];
414 case Template:
415 ID.AddPointer(TemplateArg.Name);
416 break;
417
418 case Integral:
420 getAsIntegral().Profile(ID);
421 break;
422
423 case StructuralValue:
426 break;
427
428 case Expression: {
429 const Expr *E = getAsExpr();
430 bool IsCanonical = isCanonicalExpr();
431 ID.AddBoolean(IsCanonical);
432 if (IsCanonical)
433 E->Profile(ID, Context, true);
434 else
435 ID.AddPointer(E);
436 break;
437 }
438
439 case Pack:
440 ID.AddInteger(Args.NumArgs);
441 for (unsigned I = 0; I != Args.NumArgs; ++I)
442 Args.Args[I].Profile(ID, Context);
443 }
444}
445
447 if (getKind() != Other.getKind()) return false;
448
449 switch (getKind()) {
450 case Null:
451 case Type:
452 case NullPtr:
453 return TypeOrValue.V == Other.TypeOrValue.V;
454 case Expression:
455 return TypeOrValue.V == Other.TypeOrValue.V &&
456 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
457
458 case Template:
460 return TemplateArg.Name == Other.TemplateArg.Name &&
461 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
462
463 case Declaration:
464 return getAsDecl() == Other.getAsDecl() &&
465 getParamTypeForDecl() == Other.getParamTypeForDecl();
466
467 case Integral:
468 return getIntegralType() == Other.getIntegralType() &&
469 getAsIntegral() == Other.getAsIntegral();
470
471 case StructuralValue: {
472 if (getStructuralValueType().getCanonicalType() !=
473 Other.getStructuralValueType().getCanonicalType())
474 return false;
475
476 llvm::FoldingSetNodeID A, B;
478 Other.getAsStructuralValue().Profile(B);
479 return A == B;
480 }
481
482 case Pack:
483 if (Args.NumArgs != Other.Args.NumArgs) return false;
484 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
485 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
486 return false;
487 return true;
488 }
489
490 llvm_unreachable("Invalid TemplateArgument Kind!");
491}
492
494 assert(isPackExpansion());
495
496 switch (getKind()) {
497 case Type:
498 return getAsType()->castAs<PackExpansionType>()->getPattern();
499
500 case Expression:
501 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
503
506
507 case Declaration:
508 case Integral:
509 case StructuralValue:
510 case Pack:
511 case Null:
512 case Template:
513 case NullPtr:
514 return TemplateArgument();
515 }
516
517 llvm_unreachable("Invalid TemplateArgument Kind!");
518}
519
520void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
521 bool IncludeType) const {
522
523 switch (getKind()) {
524 case Null:
525 Out << "(no value)";
526 break;
527
528 case Type: {
529 PrintingPolicy SubPolicy(Policy);
530 SubPolicy.SuppressStrongLifetime = true;
531 getAsType().print(Out, SubPolicy);
532 break;
533 }
534
535 case Declaration: {
536 ValueDecl *VD = getAsDecl();
538 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
539 TPO->getType().getUnqualifiedType().print(Out, Policy);
540 TPO->printAsInit(Out, Policy);
541 break;
542 }
543 }
545 Out << "&";
546 VD->printQualifiedName(Out);
547 break;
548 }
549
550 case StructuralValue:
552 break;
553
554 case NullPtr:
555 // FIXME: Include the type if it's not obvious from the context.
556 Out << "nullptr";
557 break;
558
559 case Template: {
560 getAsTemplate().print(Out, Policy);
561 break;
562 }
563
566 Out << "...";
567 break;
568
569 case Integral:
570 printIntegral(*this, Out, Policy, IncludeType);
571 break;
572
573 case Expression: {
574 PrintingPolicy ExprPolicy = Policy;
575 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
576 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
577 break;
578 }
579
580 case Pack:
581 Out << "<";
582 bool First = true;
583 for (const auto &P : pack_elements()) {
584 if (First)
585 First = false;
586 else
587 Out << ", ";
588
589 P.print(Policy, Out, IncludeType);
590 }
591 Out << ">";
592 break;
593 }
594}
595
596//===----------------------------------------------------------------------===//
597// TemplateArgumentLoc Implementation
598//===----------------------------------------------------------------------===//
599
601 const TemplateArgument &Argument,
602 SourceLocation TemplateKWLoc,
603 NestedNameSpecifierLoc QualifierLoc,
604 SourceLocation TemplateNameLoc,
605 SourceLocation EllipsisLoc)
606 : Argument(Argument),
607 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
608 assert(Argument.getKind() == TemplateArgument::Template ||
609 Argument.getKind() == TemplateArgument::TemplateExpansion);
610 assert(QualifierLoc.getNestedNameSpecifier() ==
611 Argument.getAsTemplateOrTemplatePattern().getQualifier());
612}
613
615 if (Argument.getKind() != TemplateArgument::Template &&
616 Argument.getKind() != TemplateArgument::TemplateExpansion)
617 return NestedNameSpecifierLoc();
619 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
620 LocInfo.getTemplate()->QualifierLocData);
621}
622
624 switch (Argument.getKind()) {
627
630
633
636 return TSI->getTypeLoc().getSourceRange();
637 else
638 return SourceRange();
639
642 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
645
648 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
651
654
657
660 return SourceRange();
661 }
662
663 llvm_unreachable("Invalid TemplateArgument Kind!");
664}
665
666template <typename T>
667static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
668 switch (Arg.getKind()) {
670 // This is bad, but not as bad as crashing because of argument
671 // count mismatches.
672 return DB << "(null template argument)";
673
675 return DB << Arg.getAsType();
676
678 return DB << Arg.getAsDecl();
679
681 return DB << "nullptr";
682
684 return DB << toString(Arg.getAsIntegral(), 10);
685
687 // FIXME: We're guessing at LangOptions!
688 SmallString<32> Str;
689 llvm::raw_svector_ostream OS(Str);
690 LangOptions LangOpts;
691 LangOpts.CPlusPlus = true;
692 PrintingPolicy Policy(LangOpts);
693 Arg.getAsStructuralValue().printPretty(OS, Policy,
695 return DB << OS.str();
696 }
697
699 return DB << Arg.getAsTemplate();
700
702 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
703
705 // FIXME: Support printing expressions as canonical
706 return DB << Arg.getAsExpr();
707
709 // FIXME: We're guessing at LangOptions!
710 SmallString<32> Str;
711 llvm::raw_svector_ostream OS(Str);
712 LangOptions LangOpts;
713 LangOpts.CPlusPlus = true;
714 PrintingPolicy Policy(LangOpts);
715 Arg.print(Policy, OS, /*IncludeType*/ true);
716 return DB << OS.str();
717 }
718 }
719
720 llvm_unreachable("Invalid TemplateArgument Kind!");
721}
722
724 const TemplateArgument &Arg) {
725 return DiagTemplateArg(DB, Arg);
726}
727
729 ASTContext &Ctx, SourceLocation TemplateKWLoc,
730 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
731 SourceLocation EllipsisLoc) {
733 Template->TemplateKwLoc = TemplateKWLoc;
734 Template->QualifierLocData = QualifierLoc.getOpaqueData();
735 Template->TemplateNameLoc = TemplateNameLoc;
736 Template->EllipsisLoc = EllipsisLoc;
737 Pointer = Template;
738}
739
742 const TemplateArgumentListInfo &List) {
743 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
744 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
745 return new (Mem) ASTTemplateArgumentListInfo(List);
746}
747
750 const ASTTemplateArgumentListInfo *List) {
751 if (!List)
752 return nullptr;
753 std::size_t size =
754 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
755 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
756 return new (Mem) ASTTemplateArgumentListInfo(List);
757}
758
759ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
760 const TemplateArgumentListInfo &Info) {
761 LAngleLoc = Info.getLAngleLoc();
762 RAngleLoc = Info.getRAngleLoc();
763 NumTemplateArgs = Info.size();
764
765 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
766 for (unsigned i = 0; i != NumTemplateArgs; ++i)
767 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
768}
769
770ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
771 const ASTTemplateArgumentListInfo *Info) {
772 LAngleLoc = Info->getLAngleLoc();
773 RAngleLoc = Info->getRAngleLoc();
775
776 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
777 for (unsigned i = 0; i != NumTemplateArgs; ++i)
778 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
779}
780
783 TemplateArgumentLoc *OutArgArray) {
784 this->TemplateKWLoc = TemplateKWLoc;
785 LAngleLoc = Info.getLAngleLoc();
786 RAngleLoc = Info.getRAngleLoc();
787 NumTemplateArgs = Info.size();
788
789 for (unsigned i = 0; i != NumTemplateArgs; ++i)
790 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
791}
792
800
803 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
804 this->TemplateKWLoc = TemplateKWLoc;
805 LAngleLoc = Info.getLAngleLoc();
806 RAngleLoc = Info.getRAngleLoc();
807 NumTemplateArgs = Info.size();
808
809 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
810 Deps |= Info[i].getArgument().getDependence();
811
812 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
813 }
814}
815
817 TemplateArgumentListInfo &Info) const {
820 for (unsigned I = 0; I != NumTemplateArgs; ++I)
821 Info.addArgument(ArgArray[I]);
822}
Defines the clang::ASTContext interface.
#define V(N, I)
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 const ValueDecl * getAsSimpleValueDeclRef(const ASTContext &Ctx, QualType T, const APValue &V)
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.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
void Profile(llvm::FoldingSetNodeID &ID) const
profile this value.
Definition APValue.cpp:489
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition APValue.cpp:703
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:220
TemplateParamObjectDecl * getTemplateParamObjectDecl(QualType T, const APValue &V) const
Return the template parameter object of the given type with the given value.
void * Allocate(size_t Size, unsigned Align=8) const
Definition ASTContext.h:846
void addDestruction(T *Ptr) const
If T isn't trivially destructible, calls AddDeallocation to register it for destruction.
This class is used for builtin types like 'int'.
Definition TypeBase.h:3164
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1016
DeclContext * getDeclContext()
Definition DeclBase.h:448
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3423
This represents one expression.
Definition Expr.h:112
QualType getType() const
Definition Expr.h:144
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
A (possibly-)qualified type.
Definition TypeBase.h:937
void Profile(llvm::FoldingSetNodeID &ID) const
Definition TypeBase.h:1398
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8278
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
Definition TypeBase.h:984
Encodes a location in the source.
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:338
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.
A convenient class for passing around template argument information.
SourceLocation getRAngleLoc() const
void setLAngleLoc(SourceLocation Loc)
void setRAngleLoc(SourceLocation Loc)
void addArgument(const TemplateArgumentLoc &Loc)
SourceLocation getLAngleLoc() const
Location wrapper for a TemplateArgument.
SourceLocation getTemplateEllipsisLoc() const
Expr * getSourceStructuralValueExpression() const
Expr * getSourceIntegralExpression() const
SourceLocation getTemplateNameLoc() const
TypeSourceInfo * getTypeSourceInfo() const
Expr * getSourceNullPtrExpression() const
SourceRange getSourceRange() const LLVM_READONLY
Expr * getSourceDeclExpression() const
Expr * getSourceExpression() const
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Represents a template argument.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getParamTypeForDecl() const
Expr * getAsExpr() const
Retrieve the template argument as an expression.
bool isDependent() const
Whether this template argument is dependent on a template parameter such that its result can change f...
bool isInstantiationDependent() const
Whether this template argument is dependent on a template parameter.
constexpr TemplateArgument()
Construct an empty, invalid template argument.
UnsignedOrNone getNumTemplateExpansions() const
Retrieve the number of expansions that a template template argument expansion will produce,...
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
bool isConceptOrConceptTemplateParameter() const
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.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
QualType getNullPtrType() const
Retrieve the type for null non-type template argument.
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.
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()
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.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateArgumentDependence getDependence() const
bool isCanonicalExpr() 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,...
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
A container of type source information.
Definition TypeBase.h:8249
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isArrayType() const
Definition TypeBase.h:8614
bool isPointerType() const
Definition TypeBase.h:8515
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9158
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:752
bool isMemberPointerType() const
Definition TypeBase.h:8596
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ TNK_Concept_template
The name refers to a concept.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1746
CharacterLiteralKind
Definition Expr.h:1603
unsigned long uint64_t
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
SourceLocation getLAngleLoc() const
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
SourceLocation getRAngleLoc() const
SourceLocation LAngleLoc
The source location of the left angle bracket ('<').
void copyInto(const TemplateArgumentLoc *ArgArray, TemplateArgumentListInfo &List) const
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, TemplateArgumentLoc *OutArgArray)
SourceLocation RAngleLoc
The source location of the right angle bracket ('>').
SourceLocation TemplateKWLoc
The source location of the template keyword; this is used as part of the representation of qualified ...
Describes how types, statements, expressions, and declarations should be printed.
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 ...
unsigned PrintAsCanonical
Whether to print entities as written or canonically.