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
370 return false;
371
372 if (isa_and_nonnull<ConceptDecl>(getAsTemplate().getAsTemplateDecl()))
373 return true;
374 if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
375 getAsTemplate().getAsTemplateDecl()))
376 return TTP->templateParameterKind() == TNK_Concept_template;
377 return false;
378}
379
381 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
382}
383
385 assert(getKind() == TemplateExpansion);
386 return TemplateArg.NumExpansions;
387}
388
390 switch (getKind()) {
396 return QualType();
397
399 return getIntegralType();
400
402 return getAsExpr()->getType();
403
405 return getParamTypeForDecl();
406
408 return getNullPtrType();
409
411 return getStructuralValueType();
412 }
413
414 llvm_unreachable("Invalid TemplateArgument Kind!");
415}
416
417void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
418 const ASTContext &Context) const {
419 ID.AddInteger(getKind());
420 switch (getKind()) {
421 case Null:
422 break;
423
424 case Type:
425 getAsType().Profile(ID);
426 break;
427
428 case NullPtr:
430 break;
431
432 case Declaration:
434 ID.AddPointer(getAsDecl());
435 break;
436
438 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
439 [[fallthrough]];
440 case Template:
441 ID.AddPointer(TemplateArg.Name);
442 break;
443
444 case Integral:
446 getAsIntegral().Profile(ID);
447 break;
448
449 case StructuralValue:
452 break;
453
454 case Expression: {
455 const Expr *E = getAsExpr();
456 bool IsCanonical = isCanonicalExpr();
457 ID.AddBoolean(IsCanonical);
458 if (IsCanonical)
459 E->Profile(ID, Context, true);
460 else
461 ID.AddPointer(E);
462 break;
463 }
464
465 case Pack:
466 ID.AddInteger(Args.NumArgs);
467 for (unsigned I = 0; I != Args.NumArgs; ++I)
468 Args.Args[I].Profile(ID, Context);
469 }
470}
471
473 if (getKind() != Other.getKind()) return false;
474
475 switch (getKind()) {
476 case Null:
477 case Type:
478 case NullPtr:
479 return TypeOrValue.V == Other.TypeOrValue.V;
480 case Expression:
481 return TypeOrValue.V == Other.TypeOrValue.V &&
482 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
483
484 case Template:
486 return TemplateArg.Name == Other.TemplateArg.Name &&
487 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
488
489 case Declaration:
490 return getAsDecl() == Other.getAsDecl() &&
491 getParamTypeForDecl() == Other.getParamTypeForDecl();
492
493 case Integral:
494 return getIntegralType() == Other.getIntegralType() &&
495 getAsIntegral() == Other.getAsIntegral();
496
497 case StructuralValue: {
498 if (getStructuralValueType().getCanonicalType() !=
499 Other.getStructuralValueType().getCanonicalType())
500 return false;
501
502 llvm::FoldingSetNodeID A, B;
504 Other.getAsStructuralValue().Profile(B);
505 return A == B;
506 }
507
508 case Pack:
509 if (Args.NumArgs != Other.Args.NumArgs) return false;
510 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
511 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
512 return false;
513 return true;
514 }
515
516 llvm_unreachable("Invalid TemplateArgument Kind!");
517}
518
520 assert(isPackExpansion());
521
522 switch (getKind()) {
523 case Type:
524 return getAsType()->castAs<PackExpansionType>()->getPattern();
525
526 case Expression:
527 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
529
532
533 case Declaration:
534 case Integral:
535 case StructuralValue:
536 case Pack:
537 case Null:
538 case Template:
539 case NullPtr:
540 return TemplateArgument();
541 }
542
543 llvm_unreachable("Invalid TemplateArgument Kind!");
544}
545
546void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
547 bool IncludeType) const {
548
549 switch (getKind()) {
550 case Null:
551 Out << "(no value)";
552 break;
553
554 case Type: {
555 PrintingPolicy SubPolicy(Policy);
556 SubPolicy.SuppressStrongLifetime = true;
557 getAsType().print(Out, SubPolicy);
558 break;
559 }
560
561 case Declaration: {
562 ValueDecl *VD = getAsDecl();
564 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
565 TPO->getType().getUnqualifiedType().print(Out, Policy);
566 TPO->printAsInit(Out, Policy);
567 break;
568 }
569 }
571 Out << "&";
572 VD->printQualifiedName(Out);
573 break;
574 }
575
576 case StructuralValue:
578 break;
579
580 case NullPtr:
581 // FIXME: Include the type if it's not obvious from the context.
582 Out << "nullptr";
583 break;
584
585 case Template: {
586 getAsTemplate().print(Out, Policy);
587 break;
588 }
589
592 Out << "...";
593 break;
594
595 case Integral:
596 printIntegral(*this, Out, Policy, IncludeType);
597 break;
598
599 case Expression: {
600 PrintingPolicy ExprPolicy = Policy;
601 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
602 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
603 break;
604 }
605
606 case Pack:
607 Out << "<";
608 bool First = true;
609 for (const auto &P : pack_elements()) {
610 if (First)
611 First = false;
612 else
613 Out << ", ";
614
615 P.print(Policy, Out, IncludeType);
616 }
617 Out << ">";
618 break;
619 }
620}
621
622//===----------------------------------------------------------------------===//
623// TemplateArgumentLoc Implementation
624//===----------------------------------------------------------------------===//
625
627 const TemplateArgument &Argument,
628 SourceLocation TemplateKWLoc,
629 NestedNameSpecifierLoc QualifierLoc,
630 SourceLocation TemplateNameLoc,
631 SourceLocation EllipsisLoc)
632 : Argument(Argument),
633 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
634 assert(Argument.getKind() == TemplateArgument::Template ||
635 Argument.getKind() == TemplateArgument::TemplateExpansion);
636 assert(QualifierLoc.getNestedNameSpecifier() ==
637 Argument.getAsTemplateOrTemplatePattern().getQualifier());
638}
639
641 if (Argument.getKind() != TemplateArgument::Template &&
642 Argument.getKind() != TemplateArgument::TemplateExpansion)
643 return NestedNameSpecifierLoc();
645 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
646 LocInfo.getTemplate()->QualifierLocData);
647}
648
650 switch (Argument.getKind()) {
653
655 if (LocInfo.isTrivial())
656 return SourceRange(LocInfo.getTrivialLoc());
658
660 if (LocInfo.isTrivial())
661 return SourceRange(LocInfo.getTrivialLoc());
663
666 return TSI->getTypeLoc().getSourceRange();
667 else
668 return SourceRange();
669
672 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
675
678 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
681
683 if (LocInfo.isTrivial())
684 return SourceRange(LocInfo.getTrivialLoc());
686
688 if (LocInfo.isTrivial())
689 return SourceRange(LocInfo.getTrivialLoc());
691
693 return SourceRange(LocInfo.getTrivialLoc());
694
696 return SourceRange();
697 }
698
699 llvm_unreachable("Invalid TemplateArgument Kind!");
700}
701
702template <typename T>
703static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
704 switch (Arg.getKind()) {
706 // This is bad, but not as bad as crashing because of argument
707 // count mismatches.
708 return DB << "(null template argument)";
709
711 return DB << Arg.getAsType();
712
714 return DB << Arg.getAsDecl();
715
717 return DB << "nullptr";
718
720 return DB << toString(Arg.getAsIntegral(), 10);
721
723 // FIXME: We're guessing at LangOptions!
724 SmallString<32> Str;
725 llvm::raw_svector_ostream OS(Str);
726 LangOptions LangOpts;
727 LangOpts.CPlusPlus = true;
728 PrintingPolicy Policy(LangOpts);
729 Arg.getAsStructuralValue().printPretty(OS, Policy,
731 return DB << OS.str();
732 }
733
735 return DB << Arg.getAsTemplate();
736
738 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
739
741 // FIXME: Support printing expressions as canonical
742 return DB << Arg.getAsExpr();
743
745 // FIXME: We're guessing at LangOptions!
746 SmallString<32> Str;
747 llvm::raw_svector_ostream OS(Str);
748 LangOptions LangOpts;
749 LangOpts.CPlusPlus = true;
750 PrintingPolicy Policy(LangOpts);
751 Arg.print(Policy, OS, /*IncludeType*/ true);
752 return DB << OS.str();
753 }
754 }
755
756 llvm_unreachable("Invalid TemplateArgument Kind!");
757}
758
760 const TemplateArgument &Arg) {
761 return DiagTemplateArg(DB, Arg);
762}
763
765 ASTContext &Ctx, SourceLocation TemplateKWLoc,
766 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
767 SourceLocation EllipsisLoc) {
769 Template->TemplateKwLoc = TemplateKWLoc;
770 Template->QualifierLocData = QualifierLoc.getOpaqueData();
771 Template->TemplateNameLoc = TemplateNameLoc;
772 Template->EllipsisLoc = EllipsisLoc;
773 Pointer = Template;
774}
775
777 ASTContext &Ctx, SourceLocation TrivialLoc) {
778 if constexpr (EmbedLocInPointer)
779 Pointer = reinterpret_cast<LocOrPointer>(static_cast<uintptr_t>(
780 (TrivialLoc.getRawEncoding() + 1u) << LowBitsRequired));
781 else
782 Pointer = new (Ctx) SourceLocation(TrivialLoc);
783}
784
787 const TemplateArgumentListInfo &List) {
788 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
789 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
790 return new (Mem) ASTTemplateArgumentListInfo(List);
791}
792
795 const ASTTemplateArgumentListInfo *List) {
796 if (!List)
797 return nullptr;
798 std::size_t size =
799 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
800 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
801 return new (Mem) ASTTemplateArgumentListInfo(List);
802}
803
804ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
805 const TemplateArgumentListInfo &Info) {
806 LAngleLoc = Info.getLAngleLoc();
807 RAngleLoc = Info.getRAngleLoc();
808 NumTemplateArgs = Info.size();
809
810 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
811 for (unsigned i = 0; i != NumTemplateArgs; ++i)
812 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
813}
814
815ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
816 const ASTTemplateArgumentListInfo *Info) {
817 LAngleLoc = Info->getLAngleLoc();
818 RAngleLoc = Info->getRAngleLoc();
820
821 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
822 for (unsigned i = 0; i != NumTemplateArgs; ++i)
823 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
824}
825
828 TemplateArgumentLoc *OutArgArray) {
829 this->TemplateKWLoc = TemplateKWLoc;
830 LAngleLoc = Info.getLAngleLoc();
831 RAngleLoc = Info.getRAngleLoc();
832 NumTemplateArgs = Info.size();
833
834 for (unsigned i = 0; i != NumTemplateArgs; ++i)
835 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
836}
837
845
848 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
849 this->TemplateKWLoc = TemplateKWLoc;
850 LAngleLoc = Info.getLAngleLoc();
851 RAngleLoc = Info.getRAngleLoc();
852 NumTemplateArgs = Info.size();
853
854 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
855 Deps |= Info[i].getArgument().getDependence();
856
857 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
858 }
859}
860
862 TemplateArgumentListInfo &Info) const {
865 for (unsigned I = 0; I != NumTemplateArgs; ++I)
866 Info.addArgument(ArgArray[I]);
867}
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:711
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:882
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:3235
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:3467
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:1690
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:8495
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.
A container of type source information.
Definition TypeBase.h:8466
The base class of the type hierarchy.
Definition TypeBase.h:1876
bool isArrayType() const
Definition TypeBase.h:8831
bool isPointerType() const
Definition TypeBase.h:8732
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9392
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:8813
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
OptionalUnsigned< unsigned > UnsignedOrNone
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:1774
CharacterLiteralKind
Definition Expr.h:1609
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.