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
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:
268 Deps = toTemplateArgumentDependence(D: getAsType()->getDependence());
269 if (isa<PackExpansionType>(Val: getAsType()))
270 Deps |= TemplateArgumentDependence::Dependent;
271 return Deps;
272
273 case Template:
274 return toTemplateArgumentDependence(D: getAsTemplate().getDependence());
275
276 case TemplateExpansion:
277 return TemplateArgumentDependence::Dependent |
278 TemplateArgumentDependence::Instantiation;
279
280 case Declaration: {
281 auto *DC = dyn_cast<DeclContext>(Val: 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:
296 Deps = toTemplateArgumentDependence(D: getAsExpr()->getDependence());
297 if (isa<PackExpansionExpr>(Val: getAsExpr()))
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
310bool TemplateArgument::isDependent() const {
311 return getDependence() & TemplateArgumentDependence::Dependent;
312}
313
314bool TemplateArgument::isInstantiationDependent() const {
315 return getDependence() & TemplateArgumentDependence::Instantiation;
316}
317
318bool TemplateArgument::isPackExpansion() const {
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
329 case TemplateExpansion:
330 return true;
331
332 case Type:
333 return isa<PackExpansionType>(Val: getAsType());
334
335 case Expression:
336 return isa<PackExpansionExpr>(Val: getAsExpr());
337 }
338
339 llvm_unreachable("Invalid TemplateArgument Kind!");
340}
341
342bool TemplateArgument::isConceptOrConceptTemplateParameter() const {
343 if (getKind() != TemplateArgument::Template)
344 return false;
345
346 if (isa_and_nonnull<ConceptDecl>(Val: getAsTemplate().getAsTemplateDecl()))
347 return true;
348 if (auto *TTP = llvm::dyn_cast_or_null<TemplateTemplateParmDecl>(
349 Val: getAsTemplate().getAsTemplateDecl()))
350 return TTP->templateParameterKind() == TNK_Concept_template;
351 return false;
352}
353
354bool TemplateArgument::containsUnexpandedParameterPack() const {
355 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
356}
357
358UnsignedOrNone TemplateArgument::getNumTemplateExpansions() const {
359 assert(getKind() == TemplateExpansion);
360 return TemplateArg.NumExpansions;
361}
362
363QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
364 switch (getKind()) {
365 case TemplateArgument::Null:
366 case TemplateArgument::Type:
367 case TemplateArgument::Template:
368 case TemplateArgument::TemplateExpansion:
369 case TemplateArgument::Pack:
370 return QualType();
371
372 case TemplateArgument::Integral:
373 return getIntegralType();
374
375 case TemplateArgument::Expression:
376 return getAsExpr()->getType();
377
378 case TemplateArgument::Declaration:
379 return getParamTypeForDecl();
380
381 case TemplateArgument::NullPtr:
382 return getNullPtrType();
383
384 case TemplateArgument::StructuralValue:
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(I: getKind());
394 switch (getKind()) {
395 case Null:
396 break;
397
398 case Type:
399 getAsType().Profile(ID);
400 break;
401
402 case NullPtr:
403 getNullPtrType().Profile(ID);
404 break;
405
406 case Declaration:
407 getParamTypeForDecl().Profile(ID);
408 ID.AddPointer(Ptr: getAsDecl());
409 break;
410
411 case TemplateExpansion:
412 ID.AddInteger(I: TemplateArg.NumExpansions.toInternalRepresentation());
413 [[fallthrough]];
414 case Template:
415 ID.AddPointer(Ptr: TemplateArg.Name);
416 break;
417
418 case Integral:
419 getIntegralType().Profile(ID);
420 getAsIntegral().Profile(ID);
421 break;
422
423 case StructuralValue:
424 getStructuralValueType().Profile(ID);
425 getAsStructuralValue().Profile(ID);
426 break;
427
428 case Expression: {
429 const Expr *E = getAsExpr();
430 bool IsCanonical = isCanonicalExpr();
431 ID.AddBoolean(B: IsCanonical);
432 if (IsCanonical)
433 E->Profile(ID, Context, Canonical: true);
434 else
435 ID.AddPointer(Ptr: E);
436 break;
437 }
438
439 case Pack:
440 ID.AddInteger(I: Args.NumArgs);
441 for (unsigned I = 0; I != Args.NumArgs; ++I)
442 Args.Args[I].Profile(ID, Context);
443 }
444}
445
446bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
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:
459 case TemplateExpansion:
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;
477 getAsStructuralValue().Profile(ID&: A);
478 Other.getAsStructuralValue().Profile(ID&: 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: Other.Args.Args[I]))
486 return false;
487 return true;
488 }
489
490 llvm_unreachable("Invalid TemplateArgument Kind!");
491}
492
493TemplateArgument TemplateArgument::getPackExpansionPattern() const {
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>(Val: getAsExpr())->getPattern(),
502 isCanonicalExpr());
503
504 case TemplateExpansion:
505 return TemplateArgument(getAsTemplateOrTemplatePattern());
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(OS&: Out, Policy: SubPolicy);
532 break;
533 }
534
535 case Declaration: {
536 ValueDecl *VD = getAsDecl();
537 if (getParamTypeForDecl()->isRecordType()) {
538 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(Val: VD)) {
539 TPO->getType().getUnqualifiedType().print(OS&: Out, Policy);
540 TPO->printAsInit(OS&: Out, Policy);
541 break;
542 }
543 }
544 if (needsAmpersandOnTemplateArg(paramType: getParamTypeForDecl(), argType: VD->getType()))
545 Out << "&";
546 VD->printQualifiedName(OS&: Out);
547 break;
548 }
549
550 case StructuralValue:
551 getAsStructuralValue().printPretty(OS&: Out, Policy, Ty: getStructuralValueType());
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(OS&: Out, Policy);
561 break;
562 }
563
564 case TemplateExpansion:
565 getAsTemplateOrTemplatePattern().print(OS&: Out, Policy);
566 Out << "...";
567 break;
568
569 case Integral:
570 printIntegral(TemplArg: *this, Out, Policy, IncludeType);
571 break;
572
573 case Expression: {
574 PrintingPolicy ExprPolicy = Policy;
575 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
576 getAsExpr()->printPretty(OS&: Out, Helper: nullptr, Policy: 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
600TemplateArgumentLoc::TemplateArgumentLoc(ASTContext &Ctx,
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
614NestedNameSpecifierLoc TemplateArgumentLoc::getTemplateQualifierLoc() const {
615 if (Argument.getKind() != TemplateArgument::Template &&
616 Argument.getKind() != TemplateArgument::TemplateExpansion)
617 return NestedNameSpecifierLoc();
618 return NestedNameSpecifierLoc(
619 Argument.getAsTemplateOrTemplatePattern().getQualifier(),
620 LocInfo.getTemplate()->QualifierLocData);
621}
622
623SourceRange TemplateArgumentLoc::getSourceRange() const {
624 switch (Argument.getKind()) {
625 case TemplateArgument::Expression:
626 return getSourceExpression()->getSourceRange();
627
628 case TemplateArgument::Declaration:
629 return getSourceDeclExpression()->getSourceRange();
630
631 case TemplateArgument::NullPtr:
632 return getSourceNullPtrExpression()->getSourceRange();
633
634 case TemplateArgument::Type:
635 if (TypeSourceInfo *TSI = getTypeSourceInfo())
636 return TSI->getTypeLoc().getSourceRange();
637 else
638 return SourceRange();
639
640 case TemplateArgument::Template:
641 if (getTemplateQualifierLoc())
642 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
643 getTemplateNameLoc());
644 return SourceRange(getTemplateNameLoc());
645
646 case TemplateArgument::TemplateExpansion:
647 if (getTemplateQualifierLoc())
648 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
649 getTemplateEllipsisLoc());
650 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
651
652 case TemplateArgument::Integral:
653 return getSourceIntegralExpression()->getSourceRange();
654
655 case TemplateArgument::StructuralValue:
656 return getSourceStructuralValueExpression()->getSourceRange();
657
658 case TemplateArgument::Pack:
659 case TemplateArgument::Null:
660 return SourceRange();
661 }
662
663 llvm_unreachable("Invalid TemplateArgument Kind!");
664}
665
666template <typename T>
667static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
668 switch (Arg.getKind()) {
669 case TemplateArgument::Null:
670 // This is bad, but not as bad as crashing because of argument
671 // count mismatches.
672 return DB << "(null template argument)";
673
674 case TemplateArgument::Type:
675 return DB << Arg.getAsType();
676
677 case TemplateArgument::Declaration:
678 return DB << Arg.getAsDecl();
679
680 case TemplateArgument::NullPtr:
681 return DB << "nullptr";
682
683 case TemplateArgument::Integral:
684 return DB << toString(I: Arg.getAsIntegral(), Radix: 10);
685
686 case TemplateArgument::StructuralValue: {
687 // FIXME: We're guessing at LangOptions!
688 SmallString<32> Str;
689 llvm::raw_svector_ostream OS(Str);
690 LangOptions LangOpts;
691 LangOpts.CPlusPlus = true;
692 PrintingPolicy Policy(LangOpts);
693 Arg.getAsStructuralValue().printPretty(OS, Policy,
694 Ty: Arg.getStructuralValueType());
695 return DB << OS.str();
696 }
697
698 case TemplateArgument::Template:
699 return DB << Arg.getAsTemplate();
700
701 case TemplateArgument::TemplateExpansion:
702 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
703
704 case TemplateArgument::Expression:
705 // FIXME: Support printing expressions as canonical
706 return DB << Arg.getAsExpr();
707
708 case TemplateArgument::Pack: {
709 // FIXME: We're guessing at LangOptions!
710 SmallString<32> Str;
711 llvm::raw_svector_ostream OS(Str);
712 LangOptions LangOpts;
713 LangOpts.CPlusPlus = true;
714 PrintingPolicy Policy(LangOpts);
715 Arg.print(Policy, Out&: OS, /*IncludeType*/ true);
716 return DB << OS.str();
717 }
718 }
719
720 llvm_unreachable("Invalid TemplateArgument Kind!");
721}
722
723const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
724 const TemplateArgument &Arg) {
725 return DiagTemplateArg(DB, Arg);
726}
727
728clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
729 ASTContext &Ctx, SourceLocation TemplateKWLoc,
730 NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
731 SourceLocation EllipsisLoc) {
732 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
733 Template->TemplateKwLoc = TemplateKWLoc;
734 Template->QualifierLocData = QualifierLoc.getOpaqueData();
735 Template->TemplateNameLoc = TemplateNameLoc;
736 Template->EllipsisLoc = EllipsisLoc;
737 Pointer = Template;
738}
739
740const ASTTemplateArgumentListInfo *
741ASTTemplateArgumentListInfo::Create(const ASTContext &C,
742 const TemplateArgumentListInfo &List) {
743 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(Counts: List.size());
744 void *Mem = C.Allocate(Size: size, Align: alignof(ASTTemplateArgumentListInfo));
745 return new (Mem) ASTTemplateArgumentListInfo(List);
746}
747
748const ASTTemplateArgumentListInfo *
749ASTTemplateArgumentListInfo::Create(const ASTContext &C,
750 const ASTTemplateArgumentListInfo *List) {
751 if (!List)
752 return nullptr;
753 std::size_t size =
754 totalSizeToAlloc<TemplateArgumentLoc>(Counts: List->getNumTemplateArgs());
755 void *Mem = C.Allocate(Size: size, Align: alignof(ASTTemplateArgumentListInfo));
756 return new (Mem) ASTTemplateArgumentListInfo(List);
757}
758
759ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
760 const TemplateArgumentListInfo &Info) {
761 LAngleLoc = Info.getLAngleLoc();
762 RAngleLoc = Info.getRAngleLoc();
763 NumTemplateArgs = Info.size();
764
765 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
766 for (unsigned i = 0; i != NumTemplateArgs; ++i)
767 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
768}
769
770ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
771 const ASTTemplateArgumentListInfo *Info) {
772 LAngleLoc = Info->getLAngleLoc();
773 RAngleLoc = Info->getRAngleLoc();
774 NumTemplateArgs = Info->getNumTemplateArgs();
775
776 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
777 for (unsigned i = 0; i != NumTemplateArgs; ++i)
778 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
779}
780
781void ASTTemplateKWAndArgsInfo::initializeFrom(
782 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
783 TemplateArgumentLoc *OutArgArray) {
784 this->TemplateKWLoc = TemplateKWLoc;
785 LAngleLoc = Info.getLAngleLoc();
786 RAngleLoc = Info.getRAngleLoc();
787 NumTemplateArgs = Info.size();
788
789 for (unsigned i = 0; i != NumTemplateArgs; ++i)
790 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
791}
792
793void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
794 assert(TemplateKWLoc.isValid());
795 LAngleLoc = SourceLocation();
796 RAngleLoc = SourceLocation();
797 this->TemplateKWLoc = TemplateKWLoc;
798 NumTemplateArgs = 0;
799}
800
801void ASTTemplateKWAndArgsInfo::initializeFrom(
802 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
803 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
804 this->TemplateKWLoc = TemplateKWLoc;
805 LAngleLoc = Info.getLAngleLoc();
806 RAngleLoc = Info.getRAngleLoc();
807 NumTemplateArgs = Info.size();
808
809 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
810 Deps |= Info[i].getArgument().getDependence();
811
812 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
813 }
814}
815
816void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
817 TemplateArgumentListInfo &Info) const {
818 Info.setLAngleLoc(LAngleLoc);
819 Info.setRAngleLoc(RAngleLoc);
820 for (unsigned I = 0; I != NumTemplateArgs; ++I)
821 Info.addArgument(Loc: ArgArray[I]);
822}
823