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/SmallString.h"
33 #include "llvm/ADT/StringExtras.h"
34 #include "llvm/ADT/StringRef.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/Compiler.h"
37 #include "llvm/Support/ErrorHandling.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <cassert>
40 #include <cstddef>
41 #include <cstdint>
42 #include <cstring>
43 #include <optional>
44 
45 using namespace clang;
46 
47 /// Print a template integral argument value.
48 ///
49 /// \param TemplArg the TemplateArgument instance to print.
50 ///
51 /// \param Out the raw_ostream instance to use for printing.
52 ///
53 /// \param Policy the printing policy for EnumConstantDecl printing.
54 ///
55 /// \param IncludeType If set, ensure that the type of the expression printed
56 /// matches the type of the template argument.
printIntegral(const TemplateArgument & TemplArg,raw_ostream & Out,const PrintingPolicy & Policy,bool IncludeType)57 static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
58                           const PrintingPolicy &Policy, bool IncludeType) {
59   const Type *T = TemplArg.getIntegralType().getTypePtr();
60   const llvm::APSInt &Val = TemplArg.getAsIntegral();
61 
62   if (Policy.UseEnumerators) {
63     if (const EnumType *ET = T->getAs<EnumType>()) {
64       for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {
65         // In Sema::CheckTemplateArugment, enum template arguments value are
66         // extended to the size of the integer underlying the enum type.  This
67         // may create a size difference between the enum value and template
68         // argument value, requiring isSameValue here instead of operator==.
69         if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
70           ECD->printQualifiedName(Out, Policy);
71           return;
72         }
73       }
74     }
75   }
76 
77   if (Policy.MSVCFormatting)
78     IncludeType = false;
79 
80   if (T->isBooleanType()) {
81     if (!Policy.MSVCFormatting)
82       Out << (Val.getBoolValue() ? "true" : "false");
83     else
84       Out << Val;
85   } else if (T->isCharType()) {
86     if (IncludeType) {
87       if (T->isSpecificBuiltinType(BuiltinType::SChar))
88         Out << "(signed char)";
89       else if (T->isSpecificBuiltinType(BuiltinType::UChar))
90         Out << "(unsigned char)";
91     }
92     CharacterLiteral::print(Val.getZExtValue(), CharacterLiteralKind::Ascii,
93                             Out);
94   } else if (T->isAnyCharacterType() && !Policy.MSVCFormatting) {
95     CharacterLiteralKind Kind;
96     if (T->isWideCharType())
97       Kind = CharacterLiteralKind::Wide;
98     else if (T->isChar8Type())
99       Kind = CharacterLiteralKind::UTF8;
100     else if (T->isChar16Type())
101       Kind = CharacterLiteralKind::UTF16;
102     else if (T->isChar32Type())
103       Kind = CharacterLiteralKind::UTF32;
104     else
105       Kind = CharacterLiteralKind::Ascii;
106     CharacterLiteral::print(Val.getExtValue(), Kind, Out);
107   } else if (IncludeType) {
108     if (const auto *BT = T->getAs<BuiltinType>()) {
109       switch (BT->getKind()) {
110       case BuiltinType::ULongLong:
111         Out << Val << "ULL";
112         break;
113       case BuiltinType::LongLong:
114         Out << Val << "LL";
115         break;
116       case BuiltinType::ULong:
117         Out << Val << "UL";
118         break;
119       case BuiltinType::Long:
120         Out << Val << "L";
121         break;
122       case BuiltinType::UInt:
123         Out << Val << "U";
124         break;
125       case BuiltinType::Int:
126         Out << Val;
127         break;
128       default:
129         Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
130             << Val;
131         break;
132       }
133     } else
134       Out << "(" << T->getCanonicalTypeInternal().getAsString(Policy) << ")"
135           << Val;
136   } else
137     Out << Val;
138 }
139 
getArrayDepth(QualType type)140 static unsigned getArrayDepth(QualType type) {
141   unsigned count = 0;
142   while (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
143     count++;
144     type = arrayType->getElementType();
145   }
146   return count;
147 }
148 
needsAmpersandOnTemplateArg(QualType paramType,QualType argType)149 static bool needsAmpersandOnTemplateArg(QualType paramType, QualType argType) {
150   // Generally, if the parameter type is a pointer, we must be taking the
151   // address of something and need a &.  However, if the argument is an array,
152   // this could be implicit via array-to-pointer decay.
153   if (!paramType->isPointerType())
154     return paramType->isMemberPointerType();
155   if (argType->isArrayType())
156     return getArrayDepth(argType) == getArrayDepth(paramType->getPointeeType());
157   return true;
158 }
159 
160 //===----------------------------------------------------------------------===//
161 // TemplateArgument Implementation
162 //===----------------------------------------------------------------------===//
163 
initFromType(QualType T,bool IsNullPtr,bool IsDefaulted)164 void TemplateArgument::initFromType(QualType T, bool IsNullPtr,
165                                     bool IsDefaulted) {
166   TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
167   TypeOrValue.IsDefaulted = IsDefaulted;
168   TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
169 }
170 
initFromDeclaration(ValueDecl * D,QualType QT,bool IsDefaulted)171 void TemplateArgument::initFromDeclaration(ValueDecl *D, QualType QT,
172                                            bool IsDefaulted) {
173   assert(D && "Expected decl");
174   DeclArg.Kind = Declaration;
175   DeclArg.IsDefaulted = IsDefaulted;
176   DeclArg.QT = QT.getAsOpaquePtr();
177   DeclArg.D = D;
178 }
179 
initFromIntegral(const ASTContext & Ctx,const llvm::APSInt & Value,QualType Type,bool IsDefaulted)180 void TemplateArgument::initFromIntegral(const ASTContext &Ctx,
181                                         const llvm::APSInt &Value,
182                                         QualType Type, bool IsDefaulted) {
183   Integer.Kind = Integral;
184   Integer.IsDefaulted = IsDefaulted;
185   // Copy the APSInt value into our decomposed form.
186   Integer.BitWidth = Value.getBitWidth();
187   Integer.IsUnsigned = Value.isUnsigned();
188   // If the value is large, we have to get additional memory from the ASTContext
189   unsigned NumWords = Value.getNumWords();
190   if (NumWords > 1) {
191     void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
192     std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
193     Integer.pVal = static_cast<uint64_t *>(Mem);
194   } else {
195     Integer.VAL = Value.getZExtValue();
196   }
197 
198   Integer.Type = Type.getAsOpaquePtr();
199 }
200 
initFromStructural(const ASTContext & Ctx,QualType Type,const APValue & V,bool IsDefaulted)201 void TemplateArgument::initFromStructural(const ASTContext &Ctx, QualType Type,
202                                           const APValue &V, bool IsDefaulted) {
203   Value.Kind = StructuralValue;
204   Value.IsDefaulted = IsDefaulted;
205   Value.Value = new (Ctx) APValue(V);
206   Ctx.addDestruction(Value.Value);
207   Value.Type = Type.getAsOpaquePtr();
208 }
209 
TemplateArgument(const ASTContext & Ctx,const llvm::APSInt & Value,QualType Type,bool IsDefaulted)210 TemplateArgument::TemplateArgument(const ASTContext &Ctx,
211                                    const llvm::APSInt &Value, QualType Type,
212                                    bool IsDefaulted) {
213   initFromIntegral(Ctx, Value, Type, IsDefaulted);
214 }
215 
getAsSimpleValueDeclRef(const ASTContext & Ctx,QualType T,const APValue & V)216 static const ValueDecl *getAsSimpleValueDeclRef(const ASTContext &Ctx,
217                                                 QualType T, const APValue &V) {
218   // Pointers to members are relatively easy.
219   if (V.isMemberPointer() && V.getMemberPointerPath().empty())
220     return V.getMemberPointerDecl();
221 
222   // We model class non-type template parameters as their template parameter
223   // object declaration.
224   if (V.isStruct() || V.isUnion())
225     return Ctx.getTemplateParamObjectDecl(T, V);
226 
227   // Pointers and references with an empty path use the special 'Declaration'
228   // representation.
229   if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() &&
230       !V.isLValueOnePastTheEnd())
231     return V.getLValueBase().dyn_cast<const ValueDecl *>();
232 
233   // Everything else uses the 'structural' representation.
234   return nullptr;
235 }
236 
TemplateArgument(const ASTContext & Ctx,QualType Type,const APValue & V,bool IsDefaulted)237 TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type,
238                                    const APValue &V, bool IsDefaulted) {
239   if (Type->isIntegralOrEnumerationType() && V.isInt())
240     initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted);
241   else if ((V.isLValue() && V.isNullPointer()) ||
242            (V.isMemberPointer() && !V.getMemberPointerDecl()))
243     initFromType(Type, /*isNullPtr=*/true, IsDefaulted);
244   else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V))
245     // FIXME: The Declaration form should expose a const ValueDecl*.
246     initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted);
247   else
248     initFromStructural(Ctx, Type, V, IsDefaulted);
249 }
250 
251 TemplateArgument
CreatePackCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)252 TemplateArgument::CreatePackCopy(ASTContext &Context,
253                                  ArrayRef<TemplateArgument> Args) {
254   if (Args.empty())
255     return getEmptyPack();
256 
257   return TemplateArgument(Args.copy(Context));
258 }
259 
getDependence() const260 TemplateArgumentDependence TemplateArgument::getDependence() const {
261   auto Deps = TemplateArgumentDependence::None;
262   switch (getKind()) {
263   case Null:
264     llvm_unreachable("Should not have a NULL template argument");
265 
266   case Type:
267     Deps = toTemplateArgumentDependence(getAsType()->getDependence());
268     if (isa<PackExpansionType>(getAsType()))
269       Deps |= TemplateArgumentDependence::Dependent;
270     return Deps;
271 
272   case Template:
273     return toTemplateArgumentDependence(getAsTemplate().getDependence());
274 
275   case TemplateExpansion:
276     return TemplateArgumentDependence::Dependent |
277            TemplateArgumentDependence::Instantiation;
278 
279   case Declaration: {
280     auto *DC = dyn_cast<DeclContext>(getAsDecl());
281     if (!DC)
282       DC = getAsDecl()->getDeclContext();
283     if (DC->isDependentContext())
284       Deps = TemplateArgumentDependence::Dependent |
285              TemplateArgumentDependence::Instantiation;
286     return Deps;
287   }
288 
289   case NullPtr:
290   case Integral:
291   case StructuralValue:
292     return TemplateArgumentDependence::None;
293 
294   case Expression:
295     Deps = toTemplateArgumentDependence(getAsExpr()->getDependence());
296     if (isa<PackExpansionExpr>(getAsExpr()))
297       Deps |= TemplateArgumentDependence::Dependent |
298               TemplateArgumentDependence::Instantiation;
299     return Deps;
300 
301   case Pack:
302     for (const auto &P : pack_elements())
303       Deps |= P.getDependence();
304     return Deps;
305   }
306   llvm_unreachable("unhandled ArgKind");
307 }
308 
isDependent() const309 bool TemplateArgument::isDependent() const {
310   return getDependence() & TemplateArgumentDependence::Dependent;
311 }
312 
isInstantiationDependent() const313 bool TemplateArgument::isInstantiationDependent() const {
314   return getDependence() & TemplateArgumentDependence::Instantiation;
315 }
316 
isPackExpansion() const317 bool TemplateArgument::isPackExpansion() const {
318   switch (getKind()) {
319   case Null:
320   case Declaration:
321   case Integral:
322   case StructuralValue:
323   case Pack:
324   case Template:
325   case NullPtr:
326     return false;
327 
328   case TemplateExpansion:
329     return true;
330 
331   case Type:
332     return isa<PackExpansionType>(getAsType());
333 
334   case Expression:
335     return isa<PackExpansionExpr>(getAsExpr());
336   }
337 
338   llvm_unreachable("Invalid TemplateArgument Kind!");
339 }
340 
containsUnexpandedParameterPack() const341 bool TemplateArgument::containsUnexpandedParameterPack() const {
342   return getDependence() & TemplateArgumentDependence::UnexpandedPack;
343 }
344 
getNumTemplateExpansions() const345 std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
346   assert(getKind() == TemplateExpansion);
347   if (TemplateArg.NumExpansions)
348     return TemplateArg.NumExpansions - 1;
349 
350   return std::nullopt;
351 }
352 
getNonTypeTemplateArgumentType() const353 QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
354   switch (getKind()) {
355   case TemplateArgument::Null:
356   case TemplateArgument::Type:
357   case TemplateArgument::Template:
358   case TemplateArgument::TemplateExpansion:
359   case TemplateArgument::Pack:
360     return QualType();
361 
362   case TemplateArgument::Integral:
363     return getIntegralType();
364 
365   case TemplateArgument::Expression:
366     return getAsExpr()->getType();
367 
368   case TemplateArgument::Declaration:
369     return getParamTypeForDecl();
370 
371   case TemplateArgument::NullPtr:
372     return getNullPtrType();
373 
374   case TemplateArgument::StructuralValue:
375     return getStructuralValueType();
376   }
377 
378   llvm_unreachable("Invalid TemplateArgument Kind!");
379 }
380 
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & Context) const381 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
382                                const ASTContext &Context) const {
383   ID.AddInteger(getKind());
384   switch (getKind()) {
385   case Null:
386     break;
387 
388   case Type:
389     getAsType().Profile(ID);
390     break;
391 
392   case NullPtr:
393     getNullPtrType().Profile(ID);
394     break;
395 
396   case Declaration:
397     getParamTypeForDecl().Profile(ID);
398     ID.AddPointer(getAsDecl());
399     break;
400 
401   case TemplateExpansion:
402     ID.AddInteger(TemplateArg.NumExpansions);
403     [[fallthrough]];
404   case Template:
405     ID.AddPointer(TemplateArg.Name);
406     break;
407 
408   case Integral:
409     getIntegralType().Profile(ID);
410     getAsIntegral().Profile(ID);
411     break;
412 
413   case StructuralValue:
414     getStructuralValueType().Profile(ID);
415     getAsStructuralValue().Profile(ID);
416     break;
417 
418   case Expression:
419     getAsExpr()->Profile(ID, Context, true);
420     break;
421 
422   case Pack:
423     ID.AddInteger(Args.NumArgs);
424     for (unsigned I = 0; I != Args.NumArgs; ++I)
425       Args.Args[I].Profile(ID, Context);
426   }
427 }
428 
structurallyEquals(const TemplateArgument & Other) const429 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
430   if (getKind() != Other.getKind()) return false;
431 
432   switch (getKind()) {
433   case Null:
434   case Type:
435   case Expression:
436   case NullPtr:
437     return TypeOrValue.V == Other.TypeOrValue.V;
438 
439   case Template:
440   case TemplateExpansion:
441     return TemplateArg.Name == Other.TemplateArg.Name &&
442            TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions;
443 
444   case Declaration:
445     return getAsDecl() == Other.getAsDecl() &&
446            getParamTypeForDecl() == Other.getParamTypeForDecl();
447 
448   case Integral:
449     return getIntegralType() == Other.getIntegralType() &&
450            getAsIntegral() == Other.getAsIntegral();
451 
452   case StructuralValue: {
453     if (getStructuralValueType().getCanonicalType() !=
454         Other.getStructuralValueType().getCanonicalType())
455       return false;
456 
457     llvm::FoldingSetNodeID A, B;
458     getAsStructuralValue().Profile(A);
459     Other.getAsStructuralValue().Profile(B);
460     return A == B;
461   }
462 
463   case Pack:
464     if (Args.NumArgs != Other.Args.NumArgs) return false;
465     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
466       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
467         return false;
468     return true;
469   }
470 
471   llvm_unreachable("Invalid TemplateArgument Kind!");
472 }
473 
getPackExpansionPattern() const474 TemplateArgument TemplateArgument::getPackExpansionPattern() const {
475   assert(isPackExpansion());
476 
477   switch (getKind()) {
478   case Type:
479     return getAsType()->castAs<PackExpansionType>()->getPattern();
480 
481   case Expression:
482     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
483 
484   case TemplateExpansion:
485     return TemplateArgument(getAsTemplateOrTemplatePattern());
486 
487   case Declaration:
488   case Integral:
489   case StructuralValue:
490   case Pack:
491   case Null:
492   case Template:
493   case NullPtr:
494     return TemplateArgument();
495   }
496 
497   llvm_unreachable("Invalid TemplateArgument Kind!");
498 }
499 
print(const PrintingPolicy & Policy,raw_ostream & Out,bool IncludeType) const500 void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
501                              bool IncludeType) const {
502 
503   switch (getKind()) {
504   case Null:
505     Out << "(no value)";
506     break;
507 
508   case Type: {
509     PrintingPolicy SubPolicy(Policy);
510     SubPolicy.SuppressStrongLifetime = true;
511     getAsType().print(Out, SubPolicy);
512     break;
513   }
514 
515   case Declaration: {
516     NamedDecl *ND = getAsDecl();
517     if (getParamTypeForDecl()->isRecordType()) {
518       if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
519         TPO->getType().getUnqualifiedType().print(Out, Policy);
520         TPO->printAsInit(Out, Policy);
521         break;
522       }
523     }
524     if (auto *VD = dyn_cast<ValueDecl>(ND)) {
525       if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType()))
526         Out << "&";
527     }
528     ND->printQualifiedName(Out);
529     break;
530   }
531 
532   case StructuralValue:
533     getAsStructuralValue().printPretty(Out, Policy, getStructuralValueType());
534     break;
535 
536   case NullPtr:
537     // FIXME: Include the type if it's not obvious from the context.
538     Out << "nullptr";
539     break;
540 
541   case Template:
542     getAsTemplate().print(Out, Policy, TemplateName::Qualified::Fully);
543     break;
544 
545   case TemplateExpansion:
546     getAsTemplateOrTemplatePattern().print(Out, Policy);
547     Out << "...";
548     break;
549 
550   case Integral:
551     printIntegral(*this, Out, Policy, IncludeType);
552     break;
553 
554   case Expression:
555     getAsExpr()->printPretty(Out, nullptr, Policy);
556     break;
557 
558   case Pack:
559     Out << "<";
560     bool First = true;
561     for (const auto &P : pack_elements()) {
562       if (First)
563         First = false;
564       else
565         Out << ", ";
566 
567       P.print(Policy, Out, IncludeType);
568     }
569     Out << ">";
570     break;
571   }
572 }
573 
dump(raw_ostream & Out) const574 void TemplateArgument::dump(raw_ostream &Out) const {
575   LangOptions LO; // FIXME! see also TemplateName::dump().
576   LO.CPlusPlus = true;
577   LO.Bool = true;
578   print(PrintingPolicy(LO), Out, /*IncludeType*/ true);
579 }
580 
dump() const581 LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
582 
583 //===----------------------------------------------------------------------===//
584 // TemplateArgumentLoc Implementation
585 //===----------------------------------------------------------------------===//
586 
getSourceRange() const587 SourceRange TemplateArgumentLoc::getSourceRange() const {
588   switch (Argument.getKind()) {
589   case TemplateArgument::Expression:
590     return getSourceExpression()->getSourceRange();
591 
592   case TemplateArgument::Declaration:
593     return getSourceDeclExpression()->getSourceRange();
594 
595   case TemplateArgument::NullPtr:
596     return getSourceNullPtrExpression()->getSourceRange();
597 
598   case TemplateArgument::Type:
599     if (TypeSourceInfo *TSI = getTypeSourceInfo())
600       return TSI->getTypeLoc().getSourceRange();
601     else
602       return SourceRange();
603 
604   case TemplateArgument::Template:
605     if (getTemplateQualifierLoc())
606       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
607                          getTemplateNameLoc());
608     return SourceRange(getTemplateNameLoc());
609 
610   case TemplateArgument::TemplateExpansion:
611     if (getTemplateQualifierLoc())
612       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
613                          getTemplateEllipsisLoc());
614     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
615 
616   case TemplateArgument::Integral:
617     return getSourceIntegralExpression()->getSourceRange();
618 
619   case TemplateArgument::StructuralValue:
620     return getSourceStructuralValueExpression()->getSourceRange();
621 
622   case TemplateArgument::Pack:
623   case TemplateArgument::Null:
624     return SourceRange();
625   }
626 
627   llvm_unreachable("Invalid TemplateArgument Kind!");
628 }
629 
630 template <typename T>
DiagTemplateArg(const T & DB,const TemplateArgument & Arg)631 static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) {
632   switch (Arg.getKind()) {
633   case TemplateArgument::Null:
634     // This is bad, but not as bad as crashing because of argument
635     // count mismatches.
636     return DB << "(null template argument)";
637 
638   case TemplateArgument::Type:
639     return DB << Arg.getAsType();
640 
641   case TemplateArgument::Declaration:
642     return DB << Arg.getAsDecl();
643 
644   case TemplateArgument::NullPtr:
645     return DB << "nullptr";
646 
647   case TemplateArgument::Integral:
648     return DB << toString(Arg.getAsIntegral(), 10);
649 
650   case TemplateArgument::StructuralValue: {
651     // FIXME: We're guessing at LangOptions!
652     SmallString<32> Str;
653     llvm::raw_svector_ostream OS(Str);
654     LangOptions LangOpts;
655     LangOpts.CPlusPlus = true;
656     PrintingPolicy Policy(LangOpts);
657     Arg.getAsStructuralValue().printPretty(OS, Policy,
658                                            Arg.getStructuralValueType());
659     return DB << OS.str();
660   }
661 
662   case TemplateArgument::Template:
663     return DB << Arg.getAsTemplate();
664 
665   case TemplateArgument::TemplateExpansion:
666     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
667 
668   case TemplateArgument::Expression: {
669     // This shouldn't actually ever happen, so it's okay that we're
670     // regurgitating an expression here.
671     // FIXME: We're guessing at LangOptions!
672     SmallString<32> Str;
673     llvm::raw_svector_ostream OS(Str);
674     LangOptions LangOpts;
675     LangOpts.CPlusPlus = true;
676     PrintingPolicy Policy(LangOpts);
677     Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
678     return DB << OS.str();
679   }
680 
681   case TemplateArgument::Pack: {
682     // FIXME: We're guessing at LangOptions!
683     SmallString<32> Str;
684     llvm::raw_svector_ostream OS(Str);
685     LangOptions LangOpts;
686     LangOpts.CPlusPlus = true;
687     PrintingPolicy Policy(LangOpts);
688     Arg.print(Policy, OS, /*IncludeType*/ true);
689     return DB << OS.str();
690   }
691   }
692 
693   llvm_unreachable("Invalid TemplateArgument Kind!");
694 }
695 
operator <<(const StreamingDiagnostic & DB,const TemplateArgument & Arg)696 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
697                                              const TemplateArgument &Arg) {
698   return DiagTemplateArg(DB, Arg);
699 }
700 
TemplateArgumentLocInfo(ASTContext & Ctx,NestedNameSpecifierLoc QualifierLoc,SourceLocation TemplateNameLoc,SourceLocation EllipsisLoc)701 clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
702     ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
703     SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
704   TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
705   Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
706   Template->QualifierLocData = QualifierLoc.getOpaqueData();
707   Template->TemplateNameLoc = TemplateNameLoc;
708   Template->EllipsisLoc = EllipsisLoc;
709   Pointer = Template;
710 }
711 
712 const ASTTemplateArgumentListInfo *
Create(const ASTContext & C,const TemplateArgumentListInfo & List)713 ASTTemplateArgumentListInfo::Create(const ASTContext &C,
714                                     const TemplateArgumentListInfo &List) {
715   std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
716   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
717   return new (Mem) ASTTemplateArgumentListInfo(List);
718 }
719 
720 const ASTTemplateArgumentListInfo *
Create(const ASTContext & C,const ASTTemplateArgumentListInfo * List)721 ASTTemplateArgumentListInfo::Create(const ASTContext &C,
722                                     const ASTTemplateArgumentListInfo *List) {
723   if (!List)
724     return nullptr;
725   std::size_t size =
726       totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
727   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
728   return new (Mem) ASTTemplateArgumentListInfo(List);
729 }
730 
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo & Info)731 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
732     const TemplateArgumentListInfo &Info) {
733   LAngleLoc = Info.getLAngleLoc();
734   RAngleLoc = Info.getRAngleLoc();
735   NumTemplateArgs = Info.size();
736 
737   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
738   for (unsigned i = 0; i != NumTemplateArgs; ++i)
739     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
740 }
741 
ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo * Info)742 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
743     const ASTTemplateArgumentListInfo *Info) {
744   LAngleLoc = Info->getLAngleLoc();
745   RAngleLoc = Info->getRAngleLoc();
746   NumTemplateArgs = Info->getNumTemplateArgs();
747 
748   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
749   for (unsigned i = 0; i != NumTemplateArgs; ++i)
750     new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
751 }
752 
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray)753 void ASTTemplateKWAndArgsInfo::initializeFrom(
754     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
755     TemplateArgumentLoc *OutArgArray) {
756   this->TemplateKWLoc = TemplateKWLoc;
757   LAngleLoc = Info.getLAngleLoc();
758   RAngleLoc = Info.getRAngleLoc();
759   NumTemplateArgs = Info.size();
760 
761   for (unsigned i = 0; i != NumTemplateArgs; ++i)
762     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
763 }
764 
initializeFrom(SourceLocation TemplateKWLoc)765 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
766   assert(TemplateKWLoc.isValid());
767   LAngleLoc = SourceLocation();
768   RAngleLoc = SourceLocation();
769   this->TemplateKWLoc = TemplateKWLoc;
770   NumTemplateArgs = 0;
771 }
772 
initializeFrom(SourceLocation TemplateKWLoc,const TemplateArgumentListInfo & Info,TemplateArgumentLoc * OutArgArray,TemplateArgumentDependence & Deps)773 void ASTTemplateKWAndArgsInfo::initializeFrom(
774     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
775     TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) {
776   this->TemplateKWLoc = TemplateKWLoc;
777   LAngleLoc = Info.getLAngleLoc();
778   RAngleLoc = Info.getRAngleLoc();
779   NumTemplateArgs = Info.size();
780 
781   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
782     Deps |= Info[i].getArgument().getDependence();
783 
784     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
785   }
786 }
787 
copyInto(const TemplateArgumentLoc * ArgArray,TemplateArgumentListInfo & Info) const788 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
789                                         TemplateArgumentListInfo &Info) const {
790   Info.setLAngleLoc(LAngleLoc);
791   Info.setRAngleLoc(RAngleLoc);
792   for (unsigned I = 0; I != NumTemplateArgs; ++I)
793     Info.addArgument(ArgArray[I]);
794 }
795