clang 24.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
262 switch (getKind()) {
264 return "null";
266 return "type";
268 return "decl";
270 return "nullptr";
272 return "integral";
274 return "template";
276 return "template expansion";
278 return "expression";
280 return "pack";
282 return "structural value";
283 }
284 llvm_unreachable("unhandled ArgKind");
285}
286
287TemplateArgumentDependence TemplateArgument::getDependence() const {
288 auto Deps = TemplateArgumentDependence::None;
289 switch (getKind()) {
290 case Null:
291 llvm_unreachable("Should not have a NULL template argument");
292
293 case Type:
296 Deps |= TemplateArgumentDependence::Dependent;
297 return Deps;
298
299 case Template:
301
303 return TemplateArgumentDependence::Dependent |
304 TemplateArgumentDependence::Instantiation;
305
306 case Declaration: {
307 auto *DC = dyn_cast<DeclContext>(getAsDecl());
308 if (!DC)
309 DC = getAsDecl()->getDeclContext();
310 if (DC->isDependentContext())
311 Deps = TemplateArgumentDependence::Dependent |
312 TemplateArgumentDependence::Instantiation;
313 return Deps;
314 }
315
316 case NullPtr:
317 case Integral:
318 case StructuralValue:
319 return TemplateArgumentDependence::None;
320
321 case Expression:
324 Deps |= TemplateArgumentDependence::Dependent |
325 TemplateArgumentDependence::Instantiation;
326 return Deps;
327
328 case Pack:
329 for (const auto &P : pack_elements())
330 Deps |= P.getDependence();
331 return Deps;
332 }
333 llvm_unreachable("unhandled ArgKind");
334}
335
337 return getDependence() & TemplateArgumentDependence::Dependent;
338}
339
341 return getDependence() & TemplateArgumentDependence::Instantiation;
342}
343
345 switch (getKind()) {
346 case Null:
347 case Declaration:
348 case Integral:
349 case StructuralValue:
350 case Pack:
351 case Template:
352 case NullPtr:
353 return false;
354
356 return true;
357
358 case Type:
360
361 case Expression:
363 }
364
365 llvm_unreachable("Invalid TemplateArgument Kind!");
366}
367
372
374 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
375}
376
378 assert(getKind() == TemplateExpansion);
379 return TemplateArg.NumExpansions;
380}
381
383 switch (getKind()) {
389 return QualType();
390
392 return getIntegralType();
393
395 return getAsExpr()->getType();
396
398 return getParamTypeForDecl();
399
401 return getNullPtrType();
402
404 return getStructuralValueType();
405 }
406
407 llvm_unreachable("Invalid TemplateArgument Kind!");
408}
409
410void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
411 const ASTContext &Context) const {
412 ID.AddInteger(getKind());
413 switch (getKind()) {
414 case Null:
415 break;
416
417 case Type:
418 getAsType().Profile(ID);
419 break;
420
421 case NullPtr:
423 break;
424
425 case Declaration:
427 ID.AddPointer(getAsDecl());
428 break;
429
431 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
432 [[fallthrough]];
433 case Template:
434 ID.AddPointer(TemplateArg.Name);
435 break;
436
437 case Integral:
439 getAsIntegral().Profile(ID);
440 break;
441
442 case StructuralValue:
445 break;
446
447 case Expression: {
448 const Expr *E = getAsExpr();
449 bool IsCanonical = isCanonicalExpr();
450 ID.AddBoolean(IsCanonical);
451 if (IsCanonical)
452 E->Profile(ID, Context, true);
453 else
454 ID.AddPointer(E);
455 break;
456 }
457
458 case Pack:
459 ID.AddInteger(Args.NumArgs);
460 for (unsigned I = 0; I != Args.NumArgs; ++I)
461 Args.Args[I].Profile(ID, Context);
462 }
463}
464
466 if (getKind() != Other.getKind()) return false;
467
468 switch (getKind()) {
469 case Null:
470 case Type:
471 case NullPtr:
472 return TypeOrValue.V == Other.TypeOrValue.V;
473 case Expression:
474 return TypeOrValue.V == Other.TypeOrValue.V &&
475 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
476
477 case Template:
479 return TemplateArg.Name == Other.TemplateArg.Name &&
480 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
481
482 case Declaration:
483 return getAsDecl() == Other.getAsDecl() &&
484 getParamTypeForDecl() == Other.getParamTypeForDecl();
485
486 case Integral:
487 return getIntegralType() == Other.getIntegralType() &&
488 getAsIntegral() == Other.getAsIntegral();
489
490 case StructuralValue: {
491 if (getStructuralValueType().getCanonicalType() !=
492 Other.getStructuralValueType().getCanonicalType())
493 return false;
494
495 llvm::FoldingSetNodeID A, B;
497 Other.getAsStructuralValue().Profile(B);
498 return A == B;
499 }
500
501 case Pack:
502 if (Args.NumArgs != Other.Args.NumArgs) return false;
503 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
504 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
505 return false;
506 return true;
507 }
508
509 llvm_unreachable("Invalid TemplateArgument Kind!");
510}
511
513 assert(isPackExpansion());
514
515 switch (getKind()) {
516 case Type:
517 return getAsType()->castAs<PackExpansionType>()->getPattern();
518
519 case Expression:
520 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
522
525
526 case Declaration:
527 case Integral:
528 case StructuralValue:
529 case Pack:
530 case Null:
531 case Template:
532 case NullPtr:
533 return TemplateArgument();
534 }
535
536 llvm_unreachable("Invalid TemplateArgument Kind!");
537}
538
539void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
540 bool IncludeType) const {
541
542 switch (getKind()) {
543 case Null:
544 Out << "(no value)";
545 break;
546
547 case Type: {
548 PrintingPolicy SubPolicy(Policy);
549 SubPolicy.SuppressStrongLifetime = true;
550 getAsType().print(Out, SubPolicy);
551 break;
552 }
553
554 case Declaration: {
555 ValueDecl *VD = getAsDecl();
557 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
558 TPO->getType().getUnqualifiedType().print(Out, Policy);
559 TPO->printAsInit(Out, Policy);
560 break;
561 }
562 }
564 Out << "&";
565 VD->printQualifiedName(Out);
566 break;
567 }
568
569 case StructuralValue:
571 break;
572
573 case NullPtr:
574 // FIXME: Include the type if it's not obvious from the context.
575 Out << "nullptr";
576 break;
577
578 case Template: {
579 getAsTemplate().print(Out, Policy);
580 break;
581 }
582
585 Out << "...";
586 break;
587
588 case Integral:
589 printIntegral(*this, Out, Policy, IncludeType);
590 break;
591
592 case Expression: {
593 PrintingPolicy ExprPolicy = Policy;
594 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
595 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
596 break;
597 }
598
599 case Pack:
600 Out << "<";
601 bool First = true;
602 for (const auto &P : pack_elements()) {
603 if (First)
604 First = false;
605 else
606 Out << ", ";
607
608 P.print(Policy, Out, IncludeType);
609 }
610 Out << ">";
611 break;
612 }
613}
614
615//===----------------------------------------------------------------------===//
616// TemplateArgumentLoc Implementation
617//===----------------------------------------------------------------------===//
618
620 const TemplateArgument &Argument,
621 SourceLocation TemplateKWLoc,
622 NestedNameSpecifierLoc QualifierLoc,
623 SourceLocation TemplateNameLoc,
624 SourceLocation EllipsisLoc)
625 : Argument(Argument),
626 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
627 assert(Argument.getKind() == TemplateArgument::Template ||
628 Argument.getKind() == TemplateArgument::TemplateExpansion);
629 assert(QualifierLoc.getNestedNameSpecifier() ==
630 Argument.getAsTemplateOrTemplatePattern().getQualifier());
631}
632
634 if (Argument.getKind() != TemplateArgument::Template &&
635 Argument.getKind() != TemplateArgument::TemplateExpansion)
636 return NestedNameSpecifierLoc();
638 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
639 LocInfo.getTemplate()->QualifierLocData);
640}
641
643 switch (Argument.getKind()) {
646
648 if (LocInfo.isTrivial())
649 return SourceRange(LocInfo.getTrivialLoc());
651
653 if (LocInfo.isTrivial())
654 return SourceRange(LocInfo.getTrivialLoc());
656
659 return TSI->getTypeLoc().getSourceRange();
660 else
661 return SourceRange();
662
665 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
668
671 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
674
676 if (LocInfo.isTrivial())
677 return SourceRange(LocInfo.getTrivialLoc());
679
681 if (LocInfo.isTrivial())
682 return SourceRange(LocInfo.getTrivialLoc());
684
686 return SourceRange(LocInfo.getTrivialLoc());
687
689 return SourceRange();
690 }
691
692 llvm_unreachable("Invalid TemplateArgument Kind!");
693}
694
695template <typename T>
696static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
697 switch (Arg.getKind()) {
699 // This is bad, but not as bad as crashing because of argument
700 // count mismatches.
701 return DB << "(null template argument)";
702
704 return DB << Arg.getAsType();
705
707 return DB << Arg.getAsDecl();
708
710 return DB << "nullptr";
711
713 return DB << toString(Arg.getAsIntegral(), 10);
714
716 // FIXME: We're guessing at LangOptions!
717 SmallString<32> Str;
718 llvm::raw_svector_ostream OS(Str);
719 LangOptions LangOpts;
720 LangOpts.CPlusPlus = true;
721 PrintingPolicy Policy(LangOpts);
722 Arg.getAsStructuralValue().printPretty(OS, Policy,
724 return DB << OS.str();
725 }
726
728 return DB << Arg.getAsTemplate();
729
731 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
732
734 // FIXME: Support printing expressions as canonical
735 return DB << Arg.getAsExpr();
736
738 // FIXME: We're guessing at LangOptions!
739 SmallString<32> Str;
740 llvm::raw_svector_ostream OS(Str);
741 LangOptions LangOpts;
742 LangOpts.CPlusPlus = true;
743 PrintingPolicy Policy(LangOpts);
744 Arg.print(Policy, OS, /*IncludeType*/ true);
745 return DB << OS.str();
746 }
747 }
748
749 llvm_unreachable("Invalid TemplateArgument Kind!");
750}
751
753 const TemplateArgument &Arg) {
754 return DiagTemplateArg(DB, Arg);
755}
756
758 ASTContext &Ctx, SourceLocation TemplateKWLoc,
759 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
760 SourceLocation EllipsisLoc) {
762 Template->TemplateKwLoc = TemplateKWLoc;
763 Template->QualifierLocData = QualifierLoc.getOpaqueData();
764 Template->TemplateNameLoc = TemplateNameLoc;
765 Template->EllipsisLoc = EllipsisLoc;
766 Pointer = Template;
767}
768
770 ASTContext &Ctx, SourceLocation TrivialLoc) {
771 if constexpr (EmbedLocInPointer)
772 Pointer = reinterpret_cast<LocOrPointer>(static_cast<uintptr_t>(
773 (TrivialLoc.getRawEncoding() + 1u) << LowBitsRequired));
774 else
775 Pointer = new (Ctx) SourceLocation(TrivialLoc);
776}
777
780 const TemplateArgumentListInfo &List) {
781 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
782 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
783 return new (Mem) ASTTemplateArgumentListInfo(List);
784}
785
786ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
787 const TemplateArgumentListInfo &Info) {
788 LAngleLoc = Info.getLAngleLoc();
789 RAngleLoc = Info.getRAngleLoc();
790 NumTemplateArgs = Info.size();
791
792 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
793 for (unsigned i = 0; i != NumTemplateArgs; ++i)
794 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
795}
796
799 TemplateArgumentLoc *OutArgArray) {
800 this->TemplateKWLoc = TemplateKWLoc;
801 LAngleLoc = Info.getLAngleLoc();
802 RAngleLoc = Info.getRAngleLoc();
803 NumTemplateArgs = Info.size();
804
805 for (unsigned i = 0; i != NumTemplateArgs; ++i)
806 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
807}
808
816
819 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
820 this->TemplateKWLoc = TemplateKWLoc;
821 LAngleLoc = Info.getLAngleLoc();
822 RAngleLoc = Info.getRAngleLoc();
823 NumTemplateArgs = Info.size();
824
825 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
826 Deps |= Info[i].getArgument().getDependence();
827
828 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
829 }
830}
831
833 TemplateArgumentListInfo &Info) const {
836 for (unsigned I = 0; I != NumTemplateArgs; ++I)
837 Info.addArgument(ArgArray[I]);
838}
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:487
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition APValue.cpp:709
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
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:902
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:3241
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1026
DeclContext * getDeclContext()
Definition DeclBase.h:456
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3558
This represents one expression.
Definition Expr.h:113
QualType getType() const
Definition Expr.h:145
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:1691
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:938
void Profile(llvm::FoldingSetNodeID &ID) const
Definition TypeBase.h:1414
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8501
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void * getAsOpaquePtr() const
Definition TypeBase.h:985
Encodes a location in the source.
UIntTy getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it.
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:343
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
StringRef getKindName() 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.
bool isConceptName() const
Determines whether this template name denotes a concept, or a template template parameter denoting on...
A container of type source information.
Definition TypeBase.h:8472
The base class of the type hierarchy.
Definition TypeBase.h:1879
bool isArrayType() const
Definition TypeBase.h:8837
bool isPointerType() const
Definition TypeBase.h:8738
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9404
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:789
bool isMemberPointerType() const
Definition TypeBase.h:8819
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
QualType getType() const
Definition Decl.h:724
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
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:1775
CharacterLiteralKind
Definition Expr.h:1623
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 ('<').
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
unsigned NumTemplateArgs
The number of template arguments in TemplateArgs.
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.