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
14#include "clang/AST/TemplateBase.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/AST/DependenceFlags.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
22#include "clang/AST/PrettyPrinter.h"
23#include "clang/AST/TemplateName.h"
24#include "clang/AST/Type.h"
25#include "clang/AST/TypeLoc.h"
26#include "clang/Basic/Diagnostic.h"
27#include "clang/Basic/LLVM.h"
28#include "clang/Basic/LangOptions.h"
29#include "clang/Basic/SourceLocation.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(I1: ECD->getInitVal(), I2: Val)) {
66 ECD->printQualifiedName(OS&: 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(K: BuiltinType::SChar))
84 Out << "(signed char)";
85 else if (T->isSpecificBuiltinType(K: BuiltinType::UChar))
86 Out << "(unsigned char)";
87 }
88 CharacterLiteral::print(val: Val.getZExtValue(), Kind: CharacterLiteralKind::Ascii,
89 OS&: Out);
90 } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
91 CharacterLiteralKind Kind;
92 if (T->isWideCharType())
93 Kind = CharacterLiteralKind::Wide;
94 else if (T->isChar8Type())
95 Kind = CharacterLiteralKind::UTF8;
96 else if (T->isChar16Type())
97 Kind = CharacterLiteralKind::UTF16;
98 else if (T->isChar32Type())
99 Kind = CharacterLiteralKind::UTF32;
100 else
101 Kind = CharacterLiteralKind::Ascii;
102 CharacterLiteral::print(val: Val.getExtValue(), Kind, OS&: 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(type: argType) == getArrayDepth(type: 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(Size: NumWords * sizeof(uint64_t));
188 std::memcpy(dest: Mem, src: Value.getRawData(), n: 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(Ptr: Value.Value);
203 Value.Type = Type.getAsOpaquePtr();
204}
205
206TemplateArgument::TemplateArgument(const ASTContext &Ctx,
207 const llvm::APSInt &Value, QualType Type,
208 bool IsDefaulted) {
209 initFromIntegral(Ctx, Value, Type, IsDefaulted);
210}
211
212static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
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
238TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
239 const APValue &V, bool IsDefaulted) {
240 if (Type->isIntegralOrEnumerationType() && V.isInt())
241 initFromIntegral(Ctx, Value: V.getInt(), Type, IsDefaulted);
242 else if ((V.isLValue() && V.isNullPointer()) ||
243 (V.isMemberPointer() && !V.getMemberPointerDecl()))
244 initFromType(T: Type, /*isNullPtr=*/IsNullPtr: true, IsDefaulted);
245 else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, T: Type, V))
246 // FIXME: The Declaration form should expose a const ValueDecl*.
247 initFromDeclaration(D: const_cast<ValueDecl *>(VD), QT: Type, IsDefaulted);
248 else
249 initFromStructural(Ctx, Type, V, IsDefaulted);
250}
251
252TemplateArgument
253TemplateArgument::CreatePackCopy(ASTContext &Context,
254 ArrayRef<TemplateArgument> Args) {
255 if (Args.empty())
256 return getEmptyPack();
257
258 return TemplateArgument(Args.copy(A&: Context));
259}
260
261StringRef TemplateArgument::getKindName() const {
262 switch (getKind()) {
263 case TemplateArgument::Null:
264 return "null";
265 case TemplateArgument::Type:
266 return "type";
267 case TemplateArgument::Declaration:
268 return "decl";
269 case TemplateArgument::NullPtr:
270 return "nullptr";
271 case TemplateArgument::Integral:
272 return "integral";
273 case TemplateArgument::Template:
274 return "template";
275 case TemplateArgument::TemplateExpansion:
276 return "template expansion";
277 case TemplateArgument::Expression:
278 return "expression";
279 case TemplateArgument::Pack:
280 return "pack";
281 case TemplateArgument::StructuralValue:
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:
294 Deps = toTemplateArgumentDependence(D: getAsType()->getDependence());
295 if (isa<PackExpansionType>(Val: getAsType()))
296 Deps |= TemplateArgumentDependence::Dependent;
297 return Deps;
298
299 case Template:
300 return toTemplateArgumentDependence(D: getAsTemplate().getDependence());
301
302 case TemplateExpansion:
303 return TemplateArgumentDependence::Dependent |
304 TemplateArgumentDependence::Instantiation;
305
306 case Declaration: {
307 auto *DC = dyn_cast<DeclContext>(Val: 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:
322 Deps = toTemplateArgumentDependence(D: getAsExpr()->getDependence());
323 if (isa<PackExpansionExpr>(Val: getAsExpr()))
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
336bool TemplateArgument::isDependent() const {
337 return getDependence() & TemplateArgumentDependence::Dependent;
338}
339
340bool TemplateArgument::isInstantiationDependent() const {
341 return getDependence() & TemplateArgumentDependence::Instantiation;
342}
343
344bool TemplateArgument::isPackExpansion() const {
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
355 case TemplateExpansion:
356 return true;
357
358 case Type:
359 return isa<PackExpansionType>(Val: getAsType());
360
361 case Expression:
362 return isa<PackExpansionExpr>(Val: getAsExpr());
363 }
364
365 llvm_unreachable("Invalid TemplateArgument Kind!");
366}
367
368bool TemplateArgument::isConceptOrConceptTemplateParameter() const {
369 return getKind() == TemplateArgument::Template &&
370 getAsTemplate().isConceptName();
371}
372
373bool TemplateArgument::containsUnexpandedParameterPack() const {
374 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
375}
376
377UnsignedOrNone TemplateArgument::getNumTemplateExpansions() const {
378 assert(getKind() == TemplateExpansion);
379 return TemplateArg.NumExpansions;
380}
381
382QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
383 switch (getKind()) {
384 case TemplateArgument::Null:
385 case TemplateArgument::Type:
386 case TemplateArgument::Template:
387 case TemplateArgument::TemplateExpansion:
388 case TemplateArgument::Pack:
389 return QualType();
390
391 case TemplateArgument::Integral:
392 return getIntegralType();
393
394 case TemplateArgument::Expression:
395 return getAsExpr()->getType();
396
397 case TemplateArgument::Declaration:
398 return getParamTypeForDecl();
399
400 case TemplateArgument::NullPtr:
401 return getNullPtrType();
402
403 case TemplateArgument::StructuralValue:
404 return getStructuralValueType();
405 }
406
407 llvm_unreachable("Invalid TemplateArgument Kind!");
408}
409
410void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
411 const ASTContext &Context) const {
412 ID.AddInteger(I: getKind());
413 switch (getKind()) {
414 case Null:
415 break;
416
417 case Type:
418 getAsType().Profile(ID);
419 break;
420
421 case NullPtr:
422 getNullPtrType().Profile(ID);
423 break;
424
425 case Declaration:
426 getParamTypeForDecl().Profile(ID);
427 ID.AddPointer(Ptr: getAsDecl());
428 break;
429
430 case TemplateExpansion:
431 ID.AddInteger(I: TemplateArg.NumExpansions.toInternalRepresentation());
432 [[fallthrough]];
433 case Template:
434 ID.AddPointer(Ptr: TemplateArg.Name);
435 break;
436
437 case Integral:
438 getIntegralType().Profile(ID);
439 getAsIntegral().Profile(ID);
440 break;
441
442 case StructuralValue:
443 getStructuralValueType().Profile(ID);
444 getAsStructuralValue().Profile(ID);
445 break;
446
447 case Expression: {
448 const Expr *E = getAsExpr();
449 bool IsCanonical = isCanonicalExpr();
450 ID.AddBoolean(B: IsCanonical);
451 if (IsCanonical)
452 E->Profile(ID, Context, Canonical: true);
453 else
454 ID.AddPointer(Ptr: E);
455 break;
456 }
457
458 case Pack:
459 ID.AddInteger(I: Args.NumArgs);
460 for (unsigned I = 0; I != Args.NumArgs; ++I)
461 Args.Args[I].Profile(ID, Context);
462 }
463}
464
465bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
466 if (getKind() != Other.getKind()) return false;
467
468 switch (getKind()) {
469 case Null:
470 case Type:
471 case NullPtr:
472 return TypeOrValue.V == Other.TypeOrValue.V;
473 case Expression:
474 return TypeOrValue.V == Other.TypeOrValue.V &&
475 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
476
477 case Template:
478 case TemplateExpansion:
479 return TemplateArg.Name == Other.TemplateArg.Name &&
480 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
481
482 case Declaration:
483 return getAsDecl() == Other.getAsDecl() &&
484 getParamTypeForDecl() == Other.getParamTypeForDecl();
485
486 case Integral:
487 return getIntegralType() == Other.getIntegralType() &&
488 getAsIntegral() == Other.getAsIntegral();
489
490 case StructuralValue: {
491 if (getStructuralValueType().getCanonicalType() !=
492 Other.getStructuralValueType().getCanonicalType())
493 return false;
494
495 llvm::FoldingSetNodeID A, B;
496 getAsStructuralValue().Profile(ID&: A);
497 Other.getAsStructuralValue().Profile(ID&: B);
498 return A == B;
499 }
500
501 case Pack:
502 if (Args.NumArgs != Other.Args.NumArgs) return false;
503 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
504 if (!Args.Args[I].structurallyEquals(Other: Other.Args.Args[I]))
505 return false;
506 return true;
507 }
508
509 llvm_unreachable("Invalid TemplateArgument Kind!");
510}
511
512TemplateArgument TemplateArgument::getPackExpansionPattern() const {
513 assert(isPackExpansion());
514
515 switch (getKind()) {
516 case Type:
517 return getAsType()->castAs<PackExpansionType>()->getPattern();
518
519 case Expression:
520 return TemplateArgument(cast<PackExpansionExpr>(Val: getAsExpr())->getPattern(),
521 isCanonicalExpr());
522
523 case TemplateExpansion:
524 return TemplateArgument(getAsTemplateOrTemplatePattern());
525
526 case Declaration:
527 case Integral:
528 case StructuralValue:
529 case Pack:
530 case Null:
531 case Template:
532 case NullPtr:
533 return TemplateArgument();
534 }
535
536 llvm_unreachable("Invalid TemplateArgument Kind!");
537}
538
539void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
540 bool IncludeType) const {
541
542 switch (getKind()) {
543 case Null:
544 Out << "(no value)";
545 break;
546
547 case Type: {
548 PrintingPolicy SubPolicy(Policy);
549 SubPolicy.SuppressStrongLifetime = true;
550 getAsType().print(OS&: Out, Policy: SubPolicy);
551 break;
552 }
553
554 case Declaration: {
555 ValueDecl *VD = getAsDecl();
556 if (getParamTypeForDecl()->isRecordType()) {
557 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(Val: VD)) {
558 TPO->getType().getUnqualifiedType().print(OS&: Out, Policy);
559 TPO->printAsInit(OS&: Out, Policy);
560 break;
561 }
562 }
563 if (needsAmpersandOnTemplateArg(paramType: getParamTypeForDecl(), argType: VD->getType()))
564 Out << "&";
565 VD->printQualifiedName(OS&: Out);
566 break;
567 }
568
569 case StructuralValue:
570 getAsStructuralValue().printPretty(OS&: Out, Policy, Ty: getStructuralValueType());
571 break;
572
573 case NullPtr:
574 // FIXME: Include the type if it's not obvious from the context.
575 Out << "nullptr";
576 break;
577
578 case Template: {
579 getAsTemplate().print(OS&: Out, Policy);
580 break;
581 }
582
583 case TemplateExpansion:
584 getAsTemplateOrTemplatePattern().print(OS&: Out, Policy);
585 Out << "...";
586 break;
587
588 case Integral:
589 printIntegral(TemplArg: *this, Out, Policy, IncludeType);
590 break;
591
592 case Expression: {
593 PrintingPolicy ExprPolicy = Policy;
594 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
595 getAsExpr()->printPretty(OS&: Out, Helper: nullptr, Policy: ExprPolicy);
596 break;
597 }
598
599 case Pack:
600 Out << "<";
601 bool First = true;
602 for (const auto &P : pack_elements()) {
603 if (First)
604 First = false;
605 else
606 Out << ", ";
607
608 P.print(Policy, Out, IncludeType);
609 }
610 Out << ">";
611 break;
612 }
613}
614
615//===----------------------------------------------------------------------===//
616// TemplateArgumentLoc Implementation
617//===----------------------------------------------------------------------===//
618
619TemplateArgumentLoc::TemplateArgumentLoc(ASTContext &Ctx,
620 const TemplateArgument &Argument,
621 SourceLocation TemplateKWLoc,
622 NestedNameSpecifierLoc QualifierLoc,
623 SourceLocation TemplateNameLoc,
624 SourceLocation EllipsisLoc)
625 : Argument(Argument),
626 LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
627 assert(Argument.getKind() == TemplateArgument::Template ||
628 Argument.getKind() == TemplateArgument::TemplateExpansion);
629 assert(QualifierLoc.getNestedNameSpecifier() ==
630 Argument.getAsTemplateOrTemplatePattern().getQualifier());
631}
632
633NestedNameSpecifierLoc TemplateArgumentLoc::getTemplateQualifierLoc() const {
634 if (Argument.getKind() != TemplateArgument::Template &&
635 Argument.getKind() != TemplateArgument::TemplateExpansion)
636 return NestedNameSpecifierLoc();
637 return NestedNameSpecifierLoc(
638 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
639 LocInfo.getTemplate()->QualifierLocData);
640}
641
642SourceRange TemplateArgumentLoc::getSourceRange() const {
643 switch (Argument.getKind()) {
644 case TemplateArgument::Expression:
645 return getSourceExpression()->getSourceRange();
646
647 case TemplateArgument::Declaration:
648 if (LocInfo.isTrivial())
649 return SourceRange(LocInfo.getTrivialLoc());
650 return getSourceDeclExpression()->getSourceRange();
651
652 case TemplateArgument::NullPtr:
653 if (LocInfo.isTrivial())
654 return SourceRange(LocInfo.getTrivialLoc());
655 return getSourceNullPtrExpression()->getSourceRange();
656
657 case TemplateArgument::Type:
658 if (TypeSourceInfo *TSI = getTypeSourceInfo())
659 return TSI->getTypeLoc().getSourceRange();
660 else
661 return SourceRange();
662
663 case TemplateArgument::Template:
664 if (getTemplateQualifierLoc())
665 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
666 getTemplateNameLoc());
667 return SourceRange(getTemplateNameLoc());
668
669 case TemplateArgument::TemplateExpansion:
670 if (getTemplateQualifierLoc())
671 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
672 getTemplateEllipsisLoc());
673 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
674
675 case TemplateArgument::Integral:
676 if (LocInfo.isTrivial())
677 return SourceRange(LocInfo.getTrivialLoc());
678 return getSourceIntegralExpression()->getSourceRange();
679
680 case TemplateArgument::StructuralValue:
681 if (LocInfo.isTrivial())
682 return SourceRange(LocInfo.getTrivialLoc());
683 return getSourceStructuralValueExpression()->getSourceRange();
684
685 case TemplateArgument::Pack:
686 return SourceRange(LocInfo.getTrivialLoc());
687
688 case TemplateArgument::Null:
689 return SourceRange();
690 }
691
692 llvm_unreachable("Invalid TemplateArgument Kind!");
693}
694
695template <typename T>
696static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
697 switch (Arg.getKind()) {
698 case TemplateArgument::Null:
699 // This is bad, but not as bad as crashing because of argument
700 // count mismatches.
701 return DB << "(null template argument)";
702
703 case TemplateArgument::Type:
704 return DB << Arg.getAsType();
705
706 case TemplateArgument::Declaration:
707 return DB << Arg.getAsDecl();
708
709 case TemplateArgument::NullPtr:
710 return DB << "nullptr";
711
712 case TemplateArgument::Integral:
713 return DB << toString(I: Arg.getAsIntegral(), Radix: 10);
714
715 case TemplateArgument::StructuralValue: {
716 // FIXME: We're guessing at LangOptions!
717 SmallString<32> Str;
718 llvm::raw_svector_ostream OS(Str);
719 LangOptions LangOpts;
720 LangOpts.CPlusPlus = true;
721 PrintingPolicy Policy(LangOpts);
722 Arg.getAsStructuralValue().printPretty(OS, Policy,
723 Ty: Arg.getStructuralValueType());
724 return DB << OS.str();
725 }
726
727 case TemplateArgument::Template:
728 return DB << Arg.getAsTemplate();
729
730 case TemplateArgument::TemplateExpansion:
731 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
732
733 case TemplateArgument::Expression:
734 // FIXME: Support printing expressions as canonical
735 return DB << Arg.getAsExpr();
736
737 case TemplateArgument::Pack: {
738 // FIXME: We're guessing at LangOptions!
739 SmallString<32> Str;
740 llvm::raw_svector_ostream OS(Str);
741 LangOptions LangOpts;
742 LangOpts.CPlusPlus = true;
743 PrintingPolicy Policy(LangOpts);
744 Arg.print(Policy, Out&: OS, /*IncludeType*/ true);
745 return DB << OS.str();
746 }
747 }
748
749 llvm_unreachable("Invalid TemplateArgument Kind!");
750}
751
752const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
753 const TemplateArgument &Arg) {
754 return DiagTemplateArg(DB, Arg);
755}
756
757clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
758 ASTContext &Ctx, SourceLocation TemplateKWLoc,
759 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
760 SourceLocation EllipsisLoc) {
761 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
762 Template->TemplateKwLoc = TemplateKWLoc;
763 Template->QualifierLocData = QualifierLoc.getOpaqueData();
764 Template->TemplateNameLoc = TemplateNameLoc;
765 Template->EllipsisLoc = EllipsisLoc;
766 Pointer = Template;
767}
768
769clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
770 ASTContext &Ctx, SourceLocation TrivialLoc) {
771 if constexpr (EmbedLocInPointer)
772 Pointer = reinterpret_cast<LocOrPointer>(static_cast<uintptr_t>(
773 (TrivialLoc.getRawEncoding() + 1u) << LowBitsRequired));
774 else
775 Pointer = new (Ctx) SourceLocation(TrivialLoc);
776}
777
778const ASTTemplateArgumentListInfo *
779ASTTemplateArgumentListInfo::Create(const ASTContext &C,
780 const TemplateArgumentListInfo &List) {
781 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(Counts: List.size());
782 void *Mem = C.Allocate(Size: size, Align: alignof(ASTTemplateArgumentListInfo));
783 return new (Mem) ASTTemplateArgumentListInfo(List);
784}
785
786ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
787 const TemplateArgumentListInfo &Info) {
788 LAngleLoc = Info.getLAngleLoc();
789 RAngleLoc = Info.getRAngleLoc();
790 NumTemplateArgs = Info.size();
791
792 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
793 for (unsigned i = 0; i != NumTemplateArgs; ++i)
794 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
795}
796
797void ASTTemplateKWAndArgsInfo::initializeFrom(
798 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
799 TemplateArgumentLoc *OutArgArray) {
800 this->TemplateKWLoc = TemplateKWLoc;
801 LAngleLoc = Info.getLAngleLoc();
802 RAngleLoc = Info.getRAngleLoc();
803 NumTemplateArgs = Info.size();
804
805 for (unsigned i = 0; i != NumTemplateArgs; ++i)
806 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
807}
808
809void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
810 assert(TemplateKWLoc.isValid());
811 LAngleLoc = SourceLocation();
812 RAngleLoc = SourceLocation();
813 this->TemplateKWLoc = TemplateKWLoc;
814 NumTemplateArgs = 0;
815}
816
817void ASTTemplateKWAndArgsInfo::initializeFrom(
818 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
819 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
820 this->TemplateKWLoc = TemplateKWLoc;
821 LAngleLoc = Info.getLAngleLoc();
822 RAngleLoc = Info.getRAngleLoc();
823 NumTemplateArgs = Info.size();
824
825 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
826 Deps |= Info[i].getArgument().getDependence();
827
828 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
829 }
830}
831
832void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
833 TemplateArgumentListInfo &Info) const {
834 Info.setLAngleLoc(LAngleLoc);
835 Info.setRAngleLoc(RAngleLoc);
836 for (unsigned I = 0; I != NumTemplateArgs; ++I)
837 Info.addArgument(Loc: ArgArray[I]);
838}
839