clang 23.0.0git
TemplateBase.cpp
Go to the documentation of this file.
1//===- TemplateBase.cpp - Common template AST class implementation --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements common classes used throughout C++ template
10// representations.
11//
12//===----------------------------------------------------------------------===//
13
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
27#include "clang/Basic/LLVM.h"
30#include "llvm/ADT/APSInt.h"
31#include "llvm/ADT/FoldingSet.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/Compiler.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/raw_ostream.h"
36#include <cassert>
37#include <cstddef>
38#include <cstdint>
39#include <cstring>
40
41using namespace clang;
42
43/// Print a template integral argument value.
44///
45/// \param TemplArg the TemplateArgument instance to print.
46///
47/// \param Out the raw_ostream instance to use for printing.
48///
49/// \param Policy the printing policy for EnumConstantDecl printing.
50///
51/// \param IncludeType If set, ensure that the type of the expression printed
52/// matches the type of the template argument.
53static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
54 const PrintingPolicy &Policy, bool IncludeType) {
55 const Type *T = TemplArg.getIntegralType().getTypePtr();
56 const llvm::APSInt &Val = TemplArg.getAsIntegral();
57
58 if (Policy.UseEnumerators) {
59 if (const auto *ED = T->getAsEnumDecl()) {
60 for (const EnumConstantDecl *ECD : ED->enumerators()) {
61 // In Sema::CheckTemplateArugment, enum template arguments value are
62 // extended to the size of the integer underlying the enum type. This
63 // may create a size difference between the enum value and template
64 // argument value, requiring isSameValue here instead of operator==.
65 if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
66 ECD->printQualifiedName(Out, Policy);
67 return;
68 }
69 }
70 }
71 }
72
73 if (Policy.MSVCFormatting)
74 IncludeType = false;
75
76 if (T->isBooleanType()) {
77 if (!Policy.MSVCFormatting)
78 Out << (Val.getBoolValue() ? "true" : "false");
79 else
80 Out << Val;
81 } else if (T->isCharType()) {
82 if (IncludeType) {
83 if (T->isSpecificBuiltinType(BuiltinType::SChar))
84 Out << "(signed char)";
85 else if (T->isSpecificBuiltinType(BuiltinType::UChar))
86 Out << "(unsigned char)";
87 }
89 Out);
90 } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
92 if (T->isWideCharType())
94 else if (T->isChar8Type())
96 else if (T->isChar16Type())
98 else if (T->isChar32Type())
100 else
102 CharacterLiteral::print(Val.getExtValue(), Kind, Out);
103 } else if (IncludeType) {
104 if (const auto *BT = T->getAs<BuiltinType>()) {
105 switch (BT->getKind()) {
106 case BuiltinType::ULongLong:
107 Out << Val << "ULL";
108 break;
109 case BuiltinType::LongLong:
110 Out << Val << "LL";
111 break;
112 case BuiltinType::ULong:
113 Out << Val << "UL";
114 break;
115 case BuiltinType::Long:
116 Out << Val << "L";
117 break;
118 case BuiltinType::UInt:
119 Out << Val << "U";
120 break;
121 case BuiltinType::Int:
122 Out << Val;
123 break;
124 default:
125 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
126 << Val;
127 break;
128 }
129 } else
130 Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
131 << Val;
132 } else
133 Out << Val;
134}
135
136static unsigned getArrayDepth(QualType type) {
137 unsigned count = 0;
138 while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
139 count++;
140 type = arrayType->getElementType();
141 }
142 return count;
143}
144
145static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
146 // Generally, if the parameter type is a pointer, we must be taking the
147 // address of something and need a &. However, if the argument is an array,
148 // this could be implicit via array-to-pointer decay.
149 if (!paramType->isPointerType())
150 return paramType->isMemberPointerType();
151 if (argType->isArrayType())
152 return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
153 return true;
154}
155
156//===----------------------------------------------------------------------===//
157// TemplateArgument Implementation
158//===----------------------------------------------------------------------===//
159
160void TemplateArgument::initFromType(QualType T, bool IsNullPtr,
161 bool IsDefaulted) {
162 TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
163 TypeOrValue.IsDefaulted = IsDefaulted;
164 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
165}
166
167void TemplateArgument::initFromDeclaration(ValueDecl *D, QualType QT,
168 bool IsDefaulted) {
169 assert(D && "Expected decl");
170 DeclArg.Kind = Declaration;
171 DeclArg.IsDefaulted = IsDefaulted;
172 DeclArg.QT = QT.getAsOpaquePtr();
173 DeclArg.D = D;
174}
175
176void TemplateArgument::initFromIntegral(const ASTContext &Ctx,
177 const llvm::APSInt &Value,
178 QualType Type, bool IsDefaulted) {
179 Integer.Kind = Integral;
180 Integer.IsDefaulted = IsDefaulted;
181 // Copy the APSInt value into our decomposed form.
182 Integer.BitWidth = Value.getBitWidth();
183 Integer.IsUnsigned = Value.isUnsigned();
184 // If the value is large, we have to get additional memory from the ASTContext
185 unsigned NumWords = Value.getNumWords();
186 if (NumWords > 1) {
187 void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
188 std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
189 Integer.pVal = static_cast<uint64_t *>(Mem);
190 } else {
191 Integer.VAL = Value.getZExtValue();
192 }
193
194 Integer.Type = Type.getAsOpaquePtr();
195}
196
197void TemplateArgument::initFromStructural(const ASTContext &Ctx, QualType Type,
198 const APValue &V, bool IsDefaulted) {
199 Value.Kind = StructuralValue;
200 Value.IsDefaulted = IsDefaulted;
201 Value.Value = new (Ctx) APValue(V);
202 Ctx.addDestruction(Value.Value);
203 Value.Type = Type.getAsOpaquePtr();
204}
205
207 const llvm::APSInt &Value, QualType Type,
208 bool IsDefaulted) {
209 initFromIntegral(Ctx, Value, Type, IsDefaulted);
210}
211
213 QualType T, const APValue &V) {
214 // Pointers to members are relatively easy.
215 if (V.isMemberPointer() && V.getMemberPointerPath().empty())
216 return V.getMemberPointerDecl();
217
218 // We model class non-type template parameters as their template parameter
219 // object declaration.
220 if (V.isStruct() || V.isUnion()) {
221 // Dependent types are not supposed to be described as
222 // TemplateParamObjectDecls.
223 if (T->isDependentType() || T->isInstantiationDependentType())
224 return nullptr;
225 return Ctx.getTemplateParamObjectDecl(T, V);
226 }
227
228 // Pointers and references with an empty path use the special 'Declaration'
229 // representation.
230 if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&
231 !V.isLValueOnePastTheEnd())
232 return V.getLValueBase().dyn_cast<const ValueDecl *>();
233
234 // Everything else uses the 'structural' representation.
235 return nullptr;
236}
237
239 const APValue &V, bool IsDefaulted) {
240 if (Type->isIntegralOrEnumerationType() && V.isInt())
241 initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);
242 else if ((V.isLValue() && V.isNullPointer()) ||
243 (V.isMemberPointer() && !V.getMemberPointerDecl()))
244 initFromType(Type, /*isNullPtr=*/true, IsDefaulted);
245 else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
246 // FIXME: The Declaration form should expose a const ValueDecl*.
247 initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);
248 else
249 initFromStructural(Ctx, Type, V, IsDefaulted);
250}
251
255 if (Args.empty())
256 return getEmptyPack();
257
258 return TemplateArgument(Args.copy(Context));
259}
260
261TemplateArgumentDependence TemplateArgument::getDependence() const {
262 auto Deps = TemplateArgumentDependence::None;
263 switch (getKind()) {
264 case Null:
265 llvm_unreachable("Should not have a NULL template argument");
266
267 case Type:
270 Deps |= TemplateArgumentDependence::Dependent;
271 return Deps;
272
273 case Template:
275
277 return TemplateArgumentDependence::Dependent |
278 TemplateArgumentDependence::Instantiation;
279
280 case Declaration: {
281 auto *DC = dyn_cast<DeclContext>(getAsDecl());
282 if (!DC)
283 DC = getAsDecl()->getDeclContext();
284 if (DC->isDependentContext())
285 Deps = TemplateArgumentDependence::Dependent |
286 TemplateArgumentDependence::Instantiation;
287 return Deps;
288 }
289
290 case NullPtr:
291 case Integral:
292 case StructuralValue:
293 return TemplateArgumentDependence::None;
294
295 case Expression:
298 Deps |= TemplateArgumentDependence::Dependent |
299 TemplateArgumentDependence::Instantiation;
300 return Deps;
301
302 case Pack:
303 for (const auto &P : pack_elements())
304 Deps |= P.getDependence();
305 return Deps;
306 }
307 llvm_unreachable("unhandled ArgKind");
308}
309
311 return getDependence() & TemplateArgumentDependence::Dependent;
312}
313
315 return getDependence() & TemplateArgumentDependence::Instantiation;
316}
317
319 switch (getKind()) {
320 case Null:
321 case Declaration:
322 case Integral:
323 case StructuralValue:
324 case Pack:
325 case Template:
326 case NullPtr:
327 return false;
328
330 return true;
331
332 case Type:
334
335 case Expression:
337 }
338
339 llvm_unreachable("Invalid TemplateArgument Kind!");
340}
341
344 return false;
345
346 if (isa_and_nonnull<ConceptDecl>(getAsTemplate().getAsTemplateDecl()))
347 return true;
348 if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
349 getAsTemplate().getAsTemplateDecl()))
350 return TTP->templateParameterKind() == TNK_Concept_template;
351 return false;
352}
353
355 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
356}
357
359 assert(getKind() == TemplateExpansion);
360 return TemplateArg.NumExpansions;
361}
362
364 switch (getKind()) {
370 return QualType();
371
373 return getIntegralType();
374
376 return getAsExpr()->getType();
377
379 return getParamTypeForDecl();
380
382 return getNullPtrType();
383
385 return getStructuralValueType();
386 }
387
388 llvm_unreachable("Invalid TemplateArgument Kind!");
389}
390
391void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
392 const ASTContext &Context) const {
393 ID.AddInteger(getKind());
394 switch (getKind()) {
395 case Null:
396 break;
397
398 case Type:
399 getAsType().Profile(ID);
400 break;
401
402 case NullPtr:
404 break;
405
406 case Declaration:
408 ID.AddPointer(getAsDecl());
409 break;
410
412 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
413 [[fallthrough]];
414 case Template:
415 ID.AddPointer(TemplateArg.Name);
416 break;
417
418 case Integral:
420 getAsIntegral().Profile(ID);
421 break;
422
423 case StructuralValue:
426 break;
427
428 case Expression: {
429 const Expr *E = getAsExpr();
430 bool IsCanonical = isCanonicalExpr();
431 ID.AddBoolean(IsCanonical);
432 if (IsCanonical)
433 E->Profile(ID, Context, true);
434 else
435 ID.AddPointer(E);
436 break;
437 }
438
439 case Pack:
440 ID.AddInteger(Args.NumArgs);
441 for (unsigned I = 0; I != Args.NumArgs; ++I)
442 Args.Args[I].Profile(ID, Context);
443 }
444}
445
447 if (getKind() != Other.getKind()) return false;
448
449 switch (getKind()) {
450 case Null:
451 case Type:
452 case NullPtr:
453 return TypeOrValue.V == Other.TypeOrValue.V;
454 case Expression:
455 return TypeOrValue.V == Other.TypeOrValue.V &&
456 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
457
458 case Template:
460 return TemplateArg.Name == Other.TemplateArg.Name &&
461 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
462
463 case Declaration:
464 return getAsDecl() == Other.getAsDecl() &&
465 getParamTypeForDecl() == Other.getParamTypeForDecl();
466
467 case Integral:
468 return getIntegralType() == Other.getIntegralType() &&
469 getAsIntegral() == Other.getAsIntegral();
470
471 case StructuralValue: {
472 if (getStructuralValueType().getCanonicalType() !=
473 Other.getStructuralValueType().getCanonicalType())
474 return false;
475
476 llvm::FoldingSetNodeID A, B;
478 Other.getAsStructuralValue().Profile(B);
479 return A == B;
480 }
481
482 case Pack:
483 if (Args.NumArgs != Other.Args.NumArgs) return false;
484 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
485 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
486 return false;
487 return true;
488 }
489
490 llvm_unreachable("Invalid TemplateArgument Kind!");
491}
492
494 assert(isPackExpansion());
495
496 switch (getKind()) {
497 case Type:
498 return getAsType()->castAs<PackExpansionType>()->getPattern();
499
500 case Expression:
501 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
503
506
507 case Declaration:
508 case Integral:
509 case StructuralValue:
510 case Pack:
511 case Null:
512 case Template:
513 case NullPtr:
514 return TemplateArgument();
515 }
516
517 llvm_unreachable("Invalid TemplateArgument Kind!");
518}
519
520void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
521 bool IncludeType) const {
522
523 switch (getKind()) {
524 case Null:
525 Out << "(no value)";
526 break;
527
528 case Type: {
529 PrintingPolicy SubPolicy(Policy);
530 SubPolicy.SuppressStrongLifetime = true;
531 getAsType().print(Out, SubPolicy);
532 break;
533 }
534
535 case Declaration: {
536 ValueDecl *VD = getAsDecl();
538 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
539 TPO->getType().getUnqualifiedType().print(Out, Policy);
540 TPO->printAsInit(Out, Policy);
541 break;
542 }
543 }
545 Out << "&";
546 VD->printQualifiedName(Out);
547 break;
548 }
549
550 case StructuralValue:
552 break;
553
554 case NullPtr:
555 // FIXME: Include the type if it's not obvious from the context.
556 Out << "nullptr";
557 break;
558
559 case Template: {
560 getAsTemplate().print(Out, Policy);
561 break;
562 }
563
566 Out << "...";
567 break;
568
569 case Integral:
570 printIntegral(*this, Out, Policy, IncludeType);
571 break;
572
573 case Expression: {
574 PrintingPolicy ExprPolicy = Policy;
575 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
576 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
577 break;
578 }
579
580 case Pack:
581 Out << "<";
582 bool First = true;
583 for (const auto &P : pack_elements()) {
584 if (First)
585 First = false;
586 else
587 Out << ", ";
588
589 P.print(Policy, Out, IncludeType);
590 }
591 Out << ">";
592 break;
593 }
594}
595
596//===----------------------------------------------------------------------===//
597// TemplateArgumentLoc Implementation
598//===----------------------------------------------------------------------===//
599
601 const TemplateArgument &Argument,
602 SourceLocation TemplateKWLoc,
603 NestedNameSpecifierLoc QualifierLoc,
604 SourceLocation TemplateNameLoc,
605 SourceLocation EllipsisLoc)
606 : Argument(Argument),
607 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
608 assert(Argument.getKind() == TemplateArgument::Template ||
609 Argument.getKind() == TemplateArgument::TemplateExpansion);
610 assert(QualifierLoc.getNestedNameSpecifier() ==
611 Argument.getAsTemplateOrTemplatePattern().getQualifier());
612}
613
615 if (Argument.getKind() != TemplateArgument::Template &&
616 Argument.getKind() != TemplateArgument::TemplateExpansion)
617 return NestedNameSpecifierLoc();
619 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
620 LocInfo.getTemplate()->QualifierLocData);
621}
622
624 switch (Argument.getKind()) {
627
629 if (LocInfo.isTrivial())
630 return SourceRange(LocInfo.getTrivialLoc());
632
634 if (LocInfo.isTrivial())
635 return SourceRange(LocInfo.getTrivialLoc());
637
640 return TSI->getTypeLoc().getSourceRange();
641 else
642 return SourceRange();
643
646 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
649
652 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
655
657 if (LocInfo.isTrivial())
658 return SourceRange(LocInfo.getTrivialLoc());
660
662 if (LocInfo.isTrivial())
663 return SourceRange(LocInfo.getTrivialLoc());
665
667 return SourceRange(LocInfo.getTrivialLoc());
668
670 return SourceRange();
671 }
672
673 llvm_unreachable("Invalid TemplateArgument Kind!");
674}
675
676template <typename T>
677static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
678 switch (Arg.getKind()) {
680 // This is bad, but not as bad as crashing because of argument
681 // count mismatches.
682 return DB << "(null template argument)";
683
685 return DB << Arg.getAsType();
686
688 return DB << Arg.getAsDecl();
689
691 return DB << "nullptr";
692
694 return DB << toString(Arg.getAsIntegral(), 10);
695
697 // FIXME: We're guessing at LangOptions!
698 SmallString<32> Str;
699 llvm::raw_svector_ostream OS(Str);
700 LangOptions LangOpts;
701 LangOpts.CPlusPlus = true;
702 PrintingPolicy Policy(LangOpts);
703 Arg.getAsStructuralValue().printPretty(OS, Policy,
705 return DB << OS.str();
706 }
707
709 return DB << Arg.getAsTemplate();
710
712 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
713
715 // FIXME: Support printing expressions as canonical
716 return DB << Arg.getAsExpr();
717
719 // FIXME: We're guessing at LangOptions!
720 SmallString<32> Str;
721 llvm::raw_svector_ostream OS(Str);
722 LangOptions LangOpts;
723 LangOpts.CPlusPlus = true;
724 PrintingPolicy Policy(LangOpts);
725 Arg.print(Policy, OS, /*IncludeType*/ true);
726 return DB << OS.str();
727 }
728 }
729
730 llvm_unreachable("Invalid TemplateArgument Kind!");
731}
732
734 const TemplateArgument &Arg) {
735 return DiagTemplateArg(DB, Arg);
736}
737
739 ASTContext &Ctx, SourceLocation TemplateKWLoc,
740 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
741 SourceLocation EllipsisLoc) {
743 Template->TemplateKwLoc = TemplateKWLoc;
744 Template->QualifierLocData = QualifierLoc.getOpaqueData();
745 Template->TemplateNameLoc = TemplateNameLoc;
746 Template->EllipsisLoc = EllipsisLoc;
747 Pointer = Template;
748}
749
751 ASTContext &Ctx, SourceLocation TrivialLoc) {
752 if constexpr (EmbedLocInPointer)
753 Pointer = reinterpret_cast<LocOrPointer>(static_cast<uintptr_t>(
754 (TrivialLoc.getRawEncoding() + 1u) << LowBitsRequired));
755 else
756 Pointer = new (Ctx) SourceLocation(TrivialLoc);
757}
758
761 const TemplateArgumentListInfo &List) {
762 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
763 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
764 return new (Mem) ASTTemplateArgumentListInfo(List);
765}
766
769 const ASTTemplateArgumentListInfo *List) {
770 if (!List)
771 return nullptr;
772 std::size_t size =
773 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
774 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
775 return new (Mem) ASTTemplateArgumentListInfo(List);
776}
777
778ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
779 const TemplateArgumentListInfo &Info) {
780 LAngleLoc = Info.getLAngleLoc();
781 RAngleLoc = Info.getRAngleLoc();
782 NumTemplateArgs = Info.size();
783
784 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
785 for (unsigned i = 0; i != NumTemplateArgs; ++i)
786 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
787}
788
789ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
790 const ASTTemplateArgumentListInfo *Info) {
791 LAngleLoc = Info->getLAngleLoc();
792 RAngleLoc = Info->getRAngleLoc();
794
795 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
796 for (unsigned i = 0; i != NumTemplateArgs; ++i)
797 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
798}
799
802 TemplateArgumentLoc *OutArgArray) {
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 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
810}
811
819
822 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
823 this->TemplateKWLoc = TemplateKWLoc;
824 LAngleLoc = Info.getLAngleLoc();
825 RAngleLoc = Info.getRAngleLoc();
826 NumTemplateArgs = Info.size();
827
828 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
829 Deps |= Info[i].getArgument().getDependence();
830
831 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
832 }
833}
834
836 TemplateArgumentListInfo &Info) const {
839 for (unsigned I = 0; I != NumTemplateArgs; ++I)
840 Info.addArgument(ArgArray[I]);
841}
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:497
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const
Definition APValue.cpp:717
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
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:872
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:3214
static void print(unsigned val, CharacterLiteralKind Kind, raw_ostream &OS)
Definition Expr.cpp:1020
DeclContext * getDeclContext()
Definition DeclBase.h:448
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3438
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:1404
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8431
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.
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
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:8402
The base class of the type hierarchy.
Definition TypeBase.h:1866
bool isArrayType() const
Definition TypeBase.h:8767
bool isPointerType() const
Definition TypeBase.h:8668
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9328
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:754
bool isMemberPointerType() const
Definition TypeBase.h:8749
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
@ 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:1761
CharacterLiteralKind
Definition Expr.h:1606
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.