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 if (isa<ConceptDecl>(getAsTemplate().getAsTemplateDecl()))
345 return true;
346 else if (auto *TTP = dyn_cast_if_present<TemplateTemplateParmDecl>(
347 getAsTemplate().getAsTemplateDecl()))
348 return TTP->templateParameterKind() == TNK_Concept_template;
349 }
350 return false;
351}
352
354 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
355}
356
358 assert(getKind() == TemplateExpansion);
359 return TemplateArg.NumExpansions;
360}
361
363 switch (getKind()) {
369 return QualType();
370
372 return getIntegralType();
373
375 return getAsExpr()->getType();
376
378 return getParamTypeForDecl();
379
381 return getNullPtrType();
382
384 return getStructuralValueType();
385 }
386
387 llvm_unreachable("Invalid TemplateArgument Kind!");
388}
389
390void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
391 const ASTContext &Context) const {
392 ID.AddInteger(getKind());
393 switch (getKind()) {
394 case Null:
395 break;
396
397 case Type:
398 getAsType().Profile(ID);
399 break;
400
401 case NullPtr:
403 break;
404
405 case Declaration:
407 ID.AddPointer(getAsDecl());
408 break;
409
411 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
412 [[fallthrough]];
413 case Template:
414 ID.AddPointer(TemplateArg.Name);
415 break;
416
417 case Integral:
419 getAsIntegral().Profile(ID);
420 break;
421
422 case StructuralValue:
425 break;
426
427 case Expression: {
428 const Expr *E = getAsExpr();
429 bool IsCanonical = isCanonicalExpr();
430 ID.AddBoolean(IsCanonical);
431 if (IsCanonical)
432 E->Profile(ID, Context, true);
433 else
434 ID.AddPointer(E);
435 break;
436 }
437
438 case Pack:
439 ID.AddInteger(Args.NumArgs);
440 for (unsigned I = 0; I != Args.NumArgs; ++I)
441 Args.Args[I].Profile(ID, Context);
442 }
443}
444
446 if (getKind() != Other.getKind()) return false;
447
448 switch (getKind()) {
449 case Null:
450 case Type:
451 case NullPtr:
452 return TypeOrValue.V == Other.TypeOrValue.V;
453 case Expression:
454 return TypeOrValue.V == Other.TypeOrValue.V &&
455 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
456
457 case Template:
459 return TemplateArg.Name == Other.TemplateArg.Name &&
460 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
461
462 case Declaration:
463 return getAsDecl() == Other.getAsDecl() &&
464 getParamTypeForDecl() == Other.getParamTypeForDecl();
465
466 case Integral:
467 return getIntegralType() == Other.getIntegralType() &&
468 getAsIntegral() == Other.getAsIntegral();
469
470 case StructuralValue: {
471 if (getStructuralValueType().getCanonicalType() !=
472 Other.getStructuralValueType().getCanonicalType())
473 return false;
474
475 llvm::FoldingSetNodeID A, B;
477 Other.getAsStructuralValue().Profile(B);
478 return A == B;
479 }
480
481 case Pack:
482 if (Args.NumArgs != Other.Args.NumArgs) return false;
483 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
484 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
485 return false;
486 return true;
487 }
488
489 llvm_unreachable("Invalid TemplateArgument Kind!");
490}
491
493 assert(isPackExpansion());
494
495 switch (getKind()) {
496 case Type:
497 return getAsType()->castAs<PackExpansionType>()->getPattern();
498
499 case Expression:
500 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
502
505
506 case Declaration:
507 case Integral:
508 case StructuralValue:
509 case Pack:
510 case Null:
511 case Template:
512 case NullPtr:
513 return TemplateArgument();
514 }
515
516 llvm_unreachable("Invalid TemplateArgument Kind!");
517}
518
519void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
520 bool IncludeType) const {
521
522 switch (getKind()) {
523 case Null:
524 Out << "(no value)";
525 break;
526
527 case Type: {
528 PrintingPolicy SubPolicy(Policy);
529 SubPolicy.SuppressStrongLifetime = true;
530 getAsType().print(Out, SubPolicy);
531 break;
532 }
533
534 case Declaration: {
535 ValueDecl *VD = getAsDecl();
537 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
538 TPO->getType().getUnqualifiedType().print(Out, Policy);
539 TPO->printAsInit(Out, Policy);
540 break;
541 }
542 }
544 Out << "&";
545 VD->printQualifiedName(Out);
546 break;
547 }
548
549 case StructuralValue:
551 break;
552
553 case NullPtr:
554 // FIXME: Include the type if it's not obvious from the context.
555 Out << "nullptr";
556 break;
557
558 case Template: {
559 getAsTemplate().print(Out, Policy);
560 break;
561 }
562
565 Out << "...";
566 break;
567
568 case Integral:
569 printIntegral(*this, Out, Policy, IncludeType);
570 break;
571
572 case Expression: {
573 PrintingPolicy ExprPolicy = Policy;
574 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
575 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
576 break;
577 }
578
579 case Pack:
580 Out << "<";
581 bool First = true;
582 for (const auto &P : pack_elements()) {
583 if (First)
584 First = false;
585 else
586 Out << ", ";
587
588 P.print(Policy, Out, IncludeType);
589 }
590 Out << ">";
591 break;
592 }
593}
594
595//===----------------------------------------------------------------------===//
596// TemplateArgumentLoc Implementation
597//===----------------------------------------------------------------------===//
598
600 const TemplateArgument &Argument,
601 SourceLocation TemplateKWLoc,
602 NestedNameSpecifierLoc QualifierLoc,
603 SourceLocation TemplateNameLoc,
604 SourceLocation EllipsisLoc)
605 : Argument(Argument),
606 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
607 assert(Argument.getKind() == TemplateArgument::Template ||
608 Argument.getKind() == TemplateArgument::TemplateExpansion);
609 assert(QualifierLoc.getNestedNameSpecifier() ==
610 Argument.getAsTemplateOrTemplatePattern().getQualifier());
611}
612
614 if (Argument.getKind() != TemplateArgument::Template &&
615 Argument.getKind() != TemplateArgument::TemplateExpansion)
616 return NestedNameSpecifierLoc();
618 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
619 LocInfo.getTemplate()->QualifierLocData);
620}
621
623 switch (Argument.getKind()) {
626
629
632
635 return TSI->getTypeLoc().getSourceRange();
636 else
637 return SourceRange();
638
641 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
644
647 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
650
653
656
659 return SourceRange();
660 }
661
662 llvm_unreachable("Invalid TemplateArgument Kind!");
663}
664
665template <typename T>
666static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
667 switch (Arg.getKind()) {
669 // This is bad, but not as bad as crashing because of argument
670 // count mismatches.
671 return DB << "(null template argument)";
672
674 return DB << Arg.getAsType();
675
677 return DB << Arg.getAsDecl();
678
680 return DB << "nullptr";
681
683 return DB << toString(Arg.getAsIntegral(), 10);
684
686 // FIXME: We're guessing at LangOptions!
687 SmallString<32> Str;
688 llvm::raw_svector_ostream OS(Str);
689 LangOptions LangOpts;
690 LangOpts.CPlusPlus = true;
691 PrintingPolicy Policy(LangOpts);
692 Arg.getAsStructuralValue().printPretty(OS, Policy,
694 return DB << OS.str();
695 }
696
698 return DB << Arg.getAsTemplate();
699
701 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
702
704 // FIXME: Support printing expressions as canonical
705 return DB << Arg.getAsExpr();
706
708 // FIXME: We're guessing at LangOptions!
709 SmallString<32> Str;
710 llvm::raw_svector_ostream OS(Str);
711 LangOptions LangOpts;
712 LangOpts.CPlusPlus = true;
713 PrintingPolicy Policy(LangOpts);
714 Arg.print(Policy, OS, /*IncludeType*/ true);
715 return DB << OS.str();
716 }
717 }
718
719 llvm_unreachable("Invalid TemplateArgument Kind!");
720}
721
723 const TemplateArgument &Arg) {
724 return DiagTemplateArg(DB, Arg);
725}
726
728 ASTContext &Ctx, SourceLocation TemplateKWLoc,
729 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
730 SourceLocation EllipsisLoc) {
732 Template->TemplateKwLoc = TemplateKWLoc;
733 Template->QualifierLocData = QualifierLoc.getOpaqueData();
734 Template->TemplateNameLoc = TemplateNameLoc;
735 Template->EllipsisLoc = EllipsisLoc;
736 Pointer = Template;
737}
738
741 const TemplateArgumentListInfo &List) {
742 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
743 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
744 return new (Mem) ASTTemplateArgumentListInfo(List);
745}
746
749 const ASTTemplateArgumentListInfo *List) {
750 if (!List)
751 return nullptr;
752 std::size_t size =
753 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
754 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
755 return new (Mem) ASTTemplateArgumentListInfo(List);
756}
757
758ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
759 const TemplateArgumentListInfo &Info) {
760 LAngleLoc = Info.getLAngleLoc();
761 RAngleLoc = Info.getRAngleLoc();
762 NumTemplateArgs = Info.size();
763
764 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
765 for (unsigned i = 0; i != NumTemplateArgs; ++i)
766 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
767}
768
769ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
770 const ASTTemplateArgumentListInfo *Info) {
771 LAngleLoc = Info->getLAngleLoc();
772 RAngleLoc = Info->getRAngleLoc();
774
775 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
776 for (unsigned i = 0; i != NumTemplateArgs; ++i)
777 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
778}
779
782 TemplateArgumentLoc *OutArgArray) {
783 this->TemplateKWLoc = TemplateKWLoc;
784 LAngleLoc = Info.getLAngleLoc();
785 RAngleLoc = Info.getRAngleLoc();
786 NumTemplateArgs = Info.size();
787
788 for (unsigned i = 0; i != NumTemplateArgs; ++i)
789 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
790}
791
799
802 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
803 this->TemplateKWLoc = TemplateKWLoc;
804 LAngleLoc = Info.getLAngleLoc();
805 RAngleLoc = Info.getRAngleLoc();
806 NumTemplateArgs = Info.size();
807
808 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
809 Deps |= Info[i].getArgument().getDependence();
810
811 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
812 }
813}
814
816 TemplateArgumentListInfo &Info) const {
819 for (unsigned I = 0; I != NumTemplateArgs; ++I)
820 Info.addArgument(ArgArray[I]);
821}
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:188
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:811
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:3420
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:8285
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:334
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:8256
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isArrayType() const
Definition TypeBase.h:8621
bool isPointerType() const
Definition TypeBase.h:8522
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9168
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:8603
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:711
QualType getType() const
Definition Decl.h:722
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 StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
Definition Parser.h:81
@ TNK_Concept_template
The name refers to a concept.
TemplateArgumentDependence toTemplateArgumentDependence(TypeDependence D)
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1745
CharacterLiteralKind
Definition Expr.h:1605
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.