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
41 using 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.
printIntegral(const TemplateArgument & TemplArg,raw_ostream & Out,const PrintingPolicy & Policy,bool IncludeType)53 static 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 EnumType *ET = T->getAs<EnumType>()) {
60 for (const EnumConstantDecl *ECD : ET->getDecl()->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 }
88 CharacterLiteral::print(Val.getZExtValue(), CharacterLiteralKind::Ascii,
89 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.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
getArrayDepth(QualType type)136 static 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
needsAmpersandOnTemplateArg(QualType paramType,QualType argType)145 static 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
initFromType(QualType T,bool IsNullPtr,bool IsDefaulted)160 void 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
initFromDeclaration(ValueDecl * D,QualType QT,bool IsDefaulted)167 void 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
initFromIntegral(const ASTContext & Ctx,const llvm::APSInt & Value,QualType Type,bool IsDefaulted)176 void 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
initFromStructural(const ASTContext & Ctx,QualType Type,const APValue & V,bool IsDefaulted)197 void 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
TemplateArgument(const ASTContext & Ctx,const llvm::APSInt & Value,QualType Type,bool IsDefaulted)206 TemplateArgument::TemplateArgument(const ASTContext &Ctx,
207 const llvm::APSInt &Value, QualType Type,
208 bool IsDefaulted) {
209 initFromIntegral(Ctx, Value, Type, IsDefaulted);
210 }
211
getAsSimpleValueDeclRef(const ASTContext & Ctx,QualType T,const APValue & V)212 static 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
TemplateArgument(const ASTContext & Ctx,QualType Type,const APValue & V,bool IsDefaulted)238 TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
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
252 TemplateArgument
CreatePackCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)253 TemplateArgument::CreatePackCopy(ASTContext &Context,
254 ArrayRef<TemplateArgument> Args) {
255 if (Args.empty())
256 return getEmptyPack();
257
258 return TemplateArgument(Args.copy(Context));
259 }
260
getDependence() const261 TemplateArgumentDependence 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(getAsType()->getDependence());
269 if (isa<PackExpansionType>(getAsType()))
270 Deps |= TemplateArgumentDependence::Dependent;
271 return Deps;
272
273 case Template:
274 return toTemplateArgumentDependence(getAsTemplate().getDependence());
275
276 case TemplateExpansion:
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:
296 Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
297 if (isa<PackExpansionExpr>(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
isDependent() const310 bool TemplateArgument::isDependent() const {
311 return getDependence() & TemplateArgumentDependence::Dependent;
312 }
313
isInstantiationDependent() const314 bool TemplateArgument::isInstantiationDependent() const {
315 return getDependence() & TemplateArgumentDependence::Instantiation;
316 }
317
isPackExpansion() const318 bool 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>(getAsType());
334
335 case Expression:
336 return isa<PackExpansionExpr>(getAsExpr());
337 }
338
339 llvm_unreachable("Invalid TemplateArgument Kind!");
340 }
341
containsUnexpandedParameterPack() const342 bool TemplateArgument::containsUnexpandedParameterPack() const {
343 return getDependence() & TemplateArgumentDependence::UnexpandedPack;
344 }
345
getNumTemplateExpansions() const346 UnsignedOrNone TemplateArgument::getNumTemplateExpansions() const {
347 assert(getKind() == TemplateExpansion);
348 return TemplateArg.NumExpansions;
349 }
350
getNonTypeTemplateArgumentType() const351 QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
352 switch (getKind()) {
353 case TemplateArgument::Null:
354 case TemplateArgument::Type:
355 case TemplateArgument::Template:
356 case TemplateArgument::TemplateExpansion:
357 case TemplateArgument::Pack:
358 return QualType();
359
360 case TemplateArgument::Integral:
361 return getIntegralType();
362
363 case TemplateArgument::Expression:
364 return getAsExpr()->getType();
365
366 case TemplateArgument::Declaration:
367 return getParamTypeForDecl();
368
369 case TemplateArgument::NullPtr:
370 return getNullPtrType();
371
372 case TemplateArgument::StructuralValue:
373 return getStructuralValueType();
374 }
375
376 llvm_unreachable("Invalid TemplateArgument Kind!");
377 }
378
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & Context) const379 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
380 const ASTContext &Context) const {
381 ID.AddInteger(getKind());
382 switch (getKind()) {
383 case Null:
384 break;
385
386 case Type:
387 getAsType().Profile(ID);
388 break;
389
390 case NullPtr:
391 getNullPtrType().Profile(ID);
392 break;
393
394 case Declaration:
395 getParamTypeForDecl().Profile(ID);
396 ID.AddPointer(getAsDecl());
397 break;
398
399 case TemplateExpansion:
400 ID.AddInteger(TemplateArg.NumExpansions.toInternalRepresentation());
401 [[fallthrough]];
402 case Template:
403 ID.AddPointer(TemplateArg.Name);
404 break;
405
406 case Integral:
407 getIntegralType().Profile(ID);
408 getAsIntegral().Profile(ID);
409 break;
410
411 case StructuralValue:
412 getStructuralValueType().Profile(ID);
413 getAsStructuralValue().Profile(ID);
414 break;
415
416 case Expression: {
417 const Expr *E = getAsExpr();
418 bool IsCanonical = isCanonicalExpr();
419 ID.AddBoolean(IsCanonical);
420 if (IsCanonical)
421 E->Profile(ID, Context, true);
422 else
423 ID.AddPointer(E);
424 break;
425 }
426
427 case Pack:
428 ID.AddInteger(Args.NumArgs);
429 for (unsigned I = 0; I != Args.NumArgs; ++I)
430 Args.Args[I].Profile(ID, Context);
431 }
432 }
433
structurallyEquals(const TemplateArgument & Other) const434 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
435 if (getKind() != Other.getKind()) return false;
436
437 switch (getKind()) {
438 case Null:
439 case Type:
440 case NullPtr:
441 return TypeOrValue.V == Other.TypeOrValue.V;
442 case Expression:
443 return TypeOrValue.V == Other.TypeOrValue.V &&
444 TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr;
445
446 case Template:
447 case TemplateExpansion:
448 return TemplateArg.Name == Other.TemplateArg.Name &&
449 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
450
451 case Declaration:
452 return getAsDecl() == Other.getAsDecl() &&
453 getParamTypeForDecl() == Other.getParamTypeForDecl();
454
455 case Integral:
456 return getIntegralType() == Other.getIntegralType() &&
457 getAsIntegral() == Other.getAsIntegral();
458
459 case StructuralValue: {
460 if (getStructuralValueType().getCanonicalType() !=
461 Other.getStructuralValueType().getCanonicalType())
462 return false;
463
464 llvm::FoldingSetNodeID A, B;
465 getAsStructuralValue().Profile(A);
466 Other.getAsStructuralValue().Profile(B);
467 return A == B;
468 }
469
470 case Pack:
471 if (Args.NumArgs != Other.Args.NumArgs) return false;
472 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
473 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
474 return false;
475 return true;
476 }
477
478 llvm_unreachable("Invalid TemplateArgument Kind!");
479 }
480
getPackExpansionPattern() const481 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
482 assert(isPackExpansion());
483
484 switch (getKind()) {
485 case Type:
486 return getAsType()->castAs<PackExpansionType>()->getPattern();
487
488 case Expression:
489 return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(),
490 isCanonicalExpr());
491
492 case TemplateExpansion:
493 return TemplateArgument(getAsTemplateOrTemplatePattern());
494
495 case Declaration:
496 case Integral:
497 case StructuralValue:
498 case Pack:
499 case Null:
500 case Template:
501 case NullPtr:
502 return TemplateArgument();
503 }
504
505 llvm_unreachable("Invalid TemplateArgument Kind!");
506 }
507
print(const PrintingPolicy & Policy,raw_ostream & Out,bool IncludeType) const508 void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
509 bool IncludeType) const {
510
511 switch (getKind()) {
512 case Null:
513 Out << "(no value)";
514 break;
515
516 case Type: {
517 PrintingPolicy SubPolicy(Policy);
518 SubPolicy.SuppressStrongLifetime = true;
519 getAsType().print(Out, SubPolicy);
520 break;
521 }
522
523 case Declaration: {
524 ValueDecl *VD = getAsDecl();
525 if (getParamTypeForDecl()->isRecordType()) {
526 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(VD)) {
527 TPO->getType().getUnqualifiedType().print(Out, Policy);
528 TPO->printAsInit(Out, Policy);
529 break;
530 }
531 }
532 if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
533 Out << "&";
534 VD->printQualifiedName(Out);
535 break;
536 }
537
538 case StructuralValue:
539 getAsStructuralValue().printPretty(Out, Policy, getStructuralValueType());
540 break;
541
542 case NullPtr:
543 // FIXME: Include the type if it's not obvious from the context.
544 Out << "nullptr";
545 break;
546
547 case Template: {
548 getAsTemplate().print(Out, Policy);
549 break;
550 }
551
552 case TemplateExpansion:
553 getAsTemplateOrTemplatePattern().print(Out, Policy);
554 Out << "...";
555 break;
556
557 case Integral:
558 printIntegral(*this, Out, Policy, IncludeType);
559 break;
560
561 case Expression: {
562 PrintingPolicy ExprPolicy = Policy;
563 ExprPolicy.PrintAsCanonical = isCanonicalExpr();
564 getAsExpr()->printPretty(Out, nullptr, ExprPolicy);
565 break;
566 }
567
568 case Pack:
569 Out << "<";
570 bool First = true;
571 for (const auto &P : pack_elements()) {
572 if (First)
573 First = false;
574 else
575 Out << ", ";
576
577 P.print(Policy, Out, IncludeType);
578 }
579 Out << ">";
580 break;
581 }
582 }
583
584 //===----------------------------------------------------------------------===//
585 // TemplateArgumentLoc Implementation
586 //===----------------------------------------------------------------------===//
587
getSourceRange() const588 SourceRange TemplateArgumentLoc::getSourceRange() const {
589 switch (Argument.getKind()) {
590 case TemplateArgument::Expression:
591 return getSourceExpression()->getSourceRange();
592
593 case TemplateArgument::Declaration:
594 return getSourceDeclExpression()->getSourceRange();
595
596 case TemplateArgument::NullPtr:
597 return getSourceNullPtrExpression()->getSourceRange();
598
599 case TemplateArgument::Type:
600 if (TypeSourceInfo *TSI = getTypeSourceInfo())
601 return TSI->getTypeLoc().getSourceRange();
602 else
603 return SourceRange();
604
605 case TemplateArgument::Template:
606 if (getTemplateQualifierLoc())
607 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
608 getTemplateNameLoc());
609 return SourceRange(getTemplateNameLoc());
610
611 case TemplateArgument::TemplateExpansion:
612 if (getTemplateQualifierLoc())
613 return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
614 getTemplateEllipsisLoc());
615 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
616
617 case TemplateArgument::Integral:
618 return getSourceIntegralExpression()->getSourceRange();
619
620 case TemplateArgument::StructuralValue:
621 return getSourceStructuralValueExpression()->getSourceRange();
622
623 case TemplateArgument::Pack:
624 case TemplateArgument::Null:
625 return SourceRange();
626 }
627
628 llvm_unreachable("Invalid TemplateArgument Kind!");
629 }
630
631 template <typename T>
DiagTemplateArg(const T & DB,const TemplateArgument & Arg)632 static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
633 switch (Arg.getKind()) {
634 case TemplateArgument::Null:
635 // This is bad, but not as bad as crashing because of argument
636 // count mismatches.
637 return DB << "(null template argument)";
638
639 case TemplateArgument::Type:
640 return DB << Arg.getAsType();
641
642 case TemplateArgument::Declaration:
643 return DB << Arg.getAsDecl();
644
645 case TemplateArgument::NullPtr:
646 return DB << "nullptr";
647
648 case TemplateArgument::Integral:
649 return DB << toString(Arg.getAsIntegral(), 10);
650
651 case TemplateArgument::StructuralValue: {
652 // FIXME: We're guessing at LangOptions!
653 SmallString<32> Str;
654 llvm::raw_svector_ostream OS(Str);
655 LangOptions LangOpts;
656 LangOpts.CPlusPlus = true;
657 PrintingPolicy Policy(LangOpts);
658 Arg.getAsStructuralValue().printPretty(OS, Policy,
659 Arg.getStructuralValueType());
660 return DB << OS.str();
661 }
662
663 case TemplateArgument::Template:
664 return DB << Arg.getAsTemplate();
665
666 case TemplateArgument::TemplateExpansion:
667 return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
668
669 case TemplateArgument::Expression:
670 // FIXME: Support printing expressions as canonical
671 return DB << Arg.getAsExpr();
672
673 case TemplateArgument::Pack: {
674 // FIXME: We're guessing at LangOptions!
675 SmallString<32> Str;
676 llvm::raw_svector_ostream OS(Str);
677 LangOptions LangOpts;
678 LangOpts.CPlusPlus = true;
679 PrintingPolicy Policy(LangOpts);
680 Arg.print(Policy, OS, /*IncludeType*/ true);
681 return DB << OS.str();
682 }
683 }
684
685 llvm_unreachable("Invalid TemplateArgument Kind!");
686 }
687
operator <<(const StreamingDiagnostic & DB,const TemplateArgument & Arg)688 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
689 const TemplateArgument &Arg) {
690 return DiagTemplateArg(DB, Arg);
691 }
692
TemplateArgumentLocInfo(ASTContext & Ctx,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateNameLoc,SourceLocation EllipsisLoc)693 clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
694 ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
695 SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
696 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
697 Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
698 Template->QualifierLocData = QualifierLoc.getOpaqueData();
699 Template->TemplateNameLoc = TemplateNameLoc;
700 Template->EllipsisLoc = EllipsisLoc;
701 Pointer = Template;
702 }
703
704 const ASTTemplateArgumentListInfo *
Create(const ASTContext & C,const TemplateArgumentListInfo & List)705 ASTTemplateArgumentListInfo::Create(const ASTContext &C,
706 const TemplateArgumentListInfo &List) {
707 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
708 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
709 return new (Mem) ASTTemplateArgumentListInfo(List);
710 }
711
712 const ASTTemplateArgumentListInfo *
Create(const ASTContext & C,const ASTTemplateArgumentListInfo * List)713 ASTTemplateArgumentListInfo::Create(const ASTContext &C,
714 const ASTTemplateArgumentListInfo *List) {
715 if (!List)
716 return nullptr;
717 std::size_t size =
718 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
719 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
720 return new (Mem) ASTTemplateArgumentListInfo(List);
721 }
722
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo & Info)723 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
724 const TemplateArgumentListInfo &Info) {
725 LAngleLoc = Info.getLAngleLoc();
726 RAngleLoc = Info.getRAngleLoc();
727 NumTemplateArgs = Info.size();
728
729 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
730 for (unsigned i = 0; i != NumTemplateArgs; ++i)
731 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
732 }
733
ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo * Info)734 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
735 const ASTTemplateArgumentListInfo *Info) {
736 LAngleLoc = Info->getLAngleLoc();
737 RAngleLoc = Info->getRAngleLoc();
738 NumTemplateArgs = Info->getNumTemplateArgs();
739
740 TemplateArgumentLoc *ArgBuffer = getTrailingObjects();
741 for (unsigned i = 0; i != NumTemplateArgs; ++i)
742 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
743 }
744
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray)745 void ASTTemplateKWAndArgsInfo::initializeFrom(
746 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
747 TemplateArgumentLoc *OutArgArray) {
748 this->TemplateKWLoc = TemplateKWLoc;
749 LAngleLoc = Info.getLAngleLoc();
750 RAngleLoc = Info.getRAngleLoc();
751 NumTemplateArgs = Info.size();
752
753 for (unsigned i = 0; i != NumTemplateArgs; ++i)
754 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
755 }
756
initializeFrom(SourceLocation TemplateKWLoc)757 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
758 assert(TemplateKWLoc.isValid());
759 LAngleLoc = SourceLocation();
760 RAngleLoc = SourceLocation();
761 this->TemplateKWLoc = TemplateKWLoc;
762 NumTemplateArgs = 0;
763 }
764
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray,TemplateArgumentDependence & Deps)765 void ASTTemplateKWAndArgsInfo::initializeFrom(
766 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
767 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
768 this->TemplateKWLoc = TemplateKWLoc;
769 LAngleLoc = Info.getLAngleLoc();
770 RAngleLoc = Info.getRAngleLoc();
771 NumTemplateArgs = Info.size();
772
773 for (unsigned i = 0; i != NumTemplateArgs; ++i) {
774 Deps |= Info[i].getArgument().getDependence();
775
776 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
777 }
778 }
779
copyInto(const TemplateArgumentLoc * ArgArray,TemplateArgumentListInfo & Info) const780 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
781 TemplateArgumentListInfo &Info) const {
782 Info.setLAngleLoc(LAngleLoc);
783 Info.setRAngleLoc(RAngleLoc);
784 for (unsigned I = 0; I != NumTemplateArgs; ++I)
785 Info.addArgument(ArgArray[I]);
786 }
787