xref: /openbsd-src/gnu/llvm/clang/lib/AST/TemplateBase.cpp (revision e5dd70708596ae51455a0ffa086a00c5b29f8583)
1*e5dd7070Spatrick //===- TemplateBase.cpp - Common template AST class implementation --------===//
2*e5dd7070Spatrick //
3*e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e5dd7070Spatrick //
7*e5dd7070Spatrick //===----------------------------------------------------------------------===//
8*e5dd7070Spatrick //
9*e5dd7070Spatrick // This file implements common classes used throughout C++ template
10*e5dd7070Spatrick // representations.
11*e5dd7070Spatrick //
12*e5dd7070Spatrick //===----------------------------------------------------------------------===//
13*e5dd7070Spatrick 
14*e5dd7070Spatrick #include "clang/AST/TemplateBase.h"
15*e5dd7070Spatrick #include "clang/AST/ASTContext.h"
16*e5dd7070Spatrick #include "clang/AST/Decl.h"
17*e5dd7070Spatrick #include "clang/AST/DeclBase.h"
18*e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
19*e5dd7070Spatrick #include "clang/AST/Expr.h"
20*e5dd7070Spatrick #include "clang/AST/ExprCXX.h"
21*e5dd7070Spatrick #include "clang/AST/PrettyPrinter.h"
22*e5dd7070Spatrick #include "clang/AST/TemplateName.h"
23*e5dd7070Spatrick #include "clang/AST/Type.h"
24*e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
25*e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
26*e5dd7070Spatrick #include "clang/Basic/LLVM.h"
27*e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
28*e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
29*e5dd7070Spatrick #include "llvm/ADT/APSInt.h"
30*e5dd7070Spatrick #include "llvm/ADT/FoldingSet.h"
31*e5dd7070Spatrick #include "llvm/ADT/None.h"
32*e5dd7070Spatrick #include "llvm/ADT/SmallString.h"
33*e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
34*e5dd7070Spatrick #include "llvm/Support/Casting.h"
35*e5dd7070Spatrick #include "llvm/Support/Compiler.h"
36*e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
37*e5dd7070Spatrick #include "llvm/Support/raw_ostream.h"
38*e5dd7070Spatrick #include <cassert>
39*e5dd7070Spatrick #include <cstddef>
40*e5dd7070Spatrick #include <cstdint>
41*e5dd7070Spatrick #include <cstring>
42*e5dd7070Spatrick 
43*e5dd7070Spatrick using namespace clang;
44*e5dd7070Spatrick 
45*e5dd7070Spatrick /// Print a template integral argument value.
46*e5dd7070Spatrick ///
47*e5dd7070Spatrick /// \param TemplArg the TemplateArgument instance to print.
48*e5dd7070Spatrick ///
49*e5dd7070Spatrick /// \param Out the raw_ostream instance to use for printing.
50*e5dd7070Spatrick ///
51*e5dd7070Spatrick /// \param Policy the printing policy for EnumConstantDecl printing.
52*e5dd7070Spatrick static void printIntegral(const TemplateArgument &TemplArg,
53*e5dd7070Spatrick                           raw_ostream &Out, const PrintingPolicy& Policy) {
54*e5dd7070Spatrick   const Type *T = TemplArg.getIntegralType().getTypePtr();
55*e5dd7070Spatrick   const llvm::APSInt &Val = TemplArg.getAsIntegral();
56*e5dd7070Spatrick 
57*e5dd7070Spatrick   if (const EnumType *ET = T->getAs<EnumType>()) {
58*e5dd7070Spatrick     for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
59*e5dd7070Spatrick       // In Sema::CheckTemplateArugment, enum template arguments value are
60*e5dd7070Spatrick       // extended to the size of the integer underlying the enum type.  This
61*e5dd7070Spatrick       // may create a size difference between the enum value and template
62*e5dd7070Spatrick       // argument value, requiring isSameValue here instead of operator==.
63*e5dd7070Spatrick       if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
64*e5dd7070Spatrick         ECD->printQualifiedName(Out, Policy);
65*e5dd7070Spatrick         return;
66*e5dd7070Spatrick       }
67*e5dd7070Spatrick     }
68*e5dd7070Spatrick   }
69*e5dd7070Spatrick 
70*e5dd7070Spatrick   if (T->isBooleanType() && !Policy.MSVCFormatting) {
71*e5dd7070Spatrick     Out << (Val.getBoolValue() ? "true" : "false");
72*e5dd7070Spatrick   } else if (T->isCharType()) {
73*e5dd7070Spatrick     const char Ch = Val.getZExtValue();
74*e5dd7070Spatrick     Out << ((Ch == '\'') ? "'\\" : "'");
75*e5dd7070Spatrick     Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
76*e5dd7070Spatrick     Out << "'";
77*e5dd7070Spatrick   } else {
78*e5dd7070Spatrick     Out << Val;
79*e5dd7070Spatrick   }
80*e5dd7070Spatrick }
81*e5dd7070Spatrick 
82*e5dd7070Spatrick //===----------------------------------------------------------------------===//
83*e5dd7070Spatrick // TemplateArgument Implementation
84*e5dd7070Spatrick //===----------------------------------------------------------------------===//
85*e5dd7070Spatrick 
86*e5dd7070Spatrick TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
87*e5dd7070Spatrick                                    QualType Type) {
88*e5dd7070Spatrick   Integer.Kind = Integral;
89*e5dd7070Spatrick   // Copy the APSInt value into our decomposed form.
90*e5dd7070Spatrick   Integer.BitWidth = Value.getBitWidth();
91*e5dd7070Spatrick   Integer.IsUnsigned = Value.isUnsigned();
92*e5dd7070Spatrick   // If the value is large, we have to get additional memory from the ASTContext
93*e5dd7070Spatrick   unsigned NumWords = Value.getNumWords();
94*e5dd7070Spatrick   if (NumWords > 1) {
95*e5dd7070Spatrick     void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
96*e5dd7070Spatrick     std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
97*e5dd7070Spatrick     Integer.pVal = static_cast<uint64_t *>(Mem);
98*e5dd7070Spatrick   } else {
99*e5dd7070Spatrick     Integer.VAL = Value.getZExtValue();
100*e5dd7070Spatrick   }
101*e5dd7070Spatrick 
102*e5dd7070Spatrick   Integer.Type = Type.getAsOpaquePtr();
103*e5dd7070Spatrick }
104*e5dd7070Spatrick 
105*e5dd7070Spatrick TemplateArgument
106*e5dd7070Spatrick TemplateArgument::CreatePackCopy(ASTContext &Context,
107*e5dd7070Spatrick                                  ArrayRef<TemplateArgument> Args) {
108*e5dd7070Spatrick   if (Args.empty())
109*e5dd7070Spatrick     return getEmptyPack();
110*e5dd7070Spatrick 
111*e5dd7070Spatrick   return TemplateArgument(Args.copy(Context));
112*e5dd7070Spatrick }
113*e5dd7070Spatrick 
114*e5dd7070Spatrick bool TemplateArgument::isDependent() const {
115*e5dd7070Spatrick   switch (getKind()) {
116*e5dd7070Spatrick   case Null:
117*e5dd7070Spatrick     llvm_unreachable("Should not have a NULL template argument");
118*e5dd7070Spatrick 
119*e5dd7070Spatrick   case Type:
120*e5dd7070Spatrick     return getAsType()->isDependentType() ||
121*e5dd7070Spatrick            isa<PackExpansionType>(getAsType());
122*e5dd7070Spatrick 
123*e5dd7070Spatrick   case Template:
124*e5dd7070Spatrick     return getAsTemplate().isDependent();
125*e5dd7070Spatrick 
126*e5dd7070Spatrick   case TemplateExpansion:
127*e5dd7070Spatrick     return true;
128*e5dd7070Spatrick 
129*e5dd7070Spatrick   case Declaration:
130*e5dd7070Spatrick     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
131*e5dd7070Spatrick       return DC->isDependentContext();
132*e5dd7070Spatrick     return getAsDecl()->getDeclContext()->isDependentContext();
133*e5dd7070Spatrick 
134*e5dd7070Spatrick   case NullPtr:
135*e5dd7070Spatrick     return false;
136*e5dd7070Spatrick 
137*e5dd7070Spatrick   case Integral:
138*e5dd7070Spatrick     // Never dependent
139*e5dd7070Spatrick     return false;
140*e5dd7070Spatrick 
141*e5dd7070Spatrick   case Expression:
142*e5dd7070Spatrick     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
143*e5dd7070Spatrick             isa<PackExpansionExpr>(getAsExpr()));
144*e5dd7070Spatrick 
145*e5dd7070Spatrick   case Pack:
146*e5dd7070Spatrick     for (const auto &P : pack_elements())
147*e5dd7070Spatrick       if (P.isDependent())
148*e5dd7070Spatrick         return true;
149*e5dd7070Spatrick     return false;
150*e5dd7070Spatrick   }
151*e5dd7070Spatrick 
152*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
153*e5dd7070Spatrick }
154*e5dd7070Spatrick 
155*e5dd7070Spatrick bool TemplateArgument::isInstantiationDependent() const {
156*e5dd7070Spatrick   switch (getKind()) {
157*e5dd7070Spatrick   case Null:
158*e5dd7070Spatrick     llvm_unreachable("Should not have a NULL template argument");
159*e5dd7070Spatrick 
160*e5dd7070Spatrick   case Type:
161*e5dd7070Spatrick     return getAsType()->isInstantiationDependentType();
162*e5dd7070Spatrick 
163*e5dd7070Spatrick   case Template:
164*e5dd7070Spatrick     return getAsTemplate().isInstantiationDependent();
165*e5dd7070Spatrick 
166*e5dd7070Spatrick   case TemplateExpansion:
167*e5dd7070Spatrick     return true;
168*e5dd7070Spatrick 
169*e5dd7070Spatrick   case Declaration:
170*e5dd7070Spatrick     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
171*e5dd7070Spatrick       return DC->isDependentContext();
172*e5dd7070Spatrick     return getAsDecl()->getDeclContext()->isDependentContext();
173*e5dd7070Spatrick 
174*e5dd7070Spatrick   case NullPtr:
175*e5dd7070Spatrick     return false;
176*e5dd7070Spatrick 
177*e5dd7070Spatrick   case Integral:
178*e5dd7070Spatrick     // Never dependent
179*e5dd7070Spatrick     return false;
180*e5dd7070Spatrick 
181*e5dd7070Spatrick   case Expression:
182*e5dd7070Spatrick     return getAsExpr()->isInstantiationDependent();
183*e5dd7070Spatrick 
184*e5dd7070Spatrick   case Pack:
185*e5dd7070Spatrick     for (const auto &P : pack_elements())
186*e5dd7070Spatrick       if (P.isInstantiationDependent())
187*e5dd7070Spatrick         return true;
188*e5dd7070Spatrick     return false;
189*e5dd7070Spatrick   }
190*e5dd7070Spatrick 
191*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
192*e5dd7070Spatrick }
193*e5dd7070Spatrick 
194*e5dd7070Spatrick bool TemplateArgument::isPackExpansion() const {
195*e5dd7070Spatrick   switch (getKind()) {
196*e5dd7070Spatrick   case Null:
197*e5dd7070Spatrick   case Declaration:
198*e5dd7070Spatrick   case Integral:
199*e5dd7070Spatrick   case Pack:
200*e5dd7070Spatrick   case Template:
201*e5dd7070Spatrick   case NullPtr:
202*e5dd7070Spatrick     return false;
203*e5dd7070Spatrick 
204*e5dd7070Spatrick   case TemplateExpansion:
205*e5dd7070Spatrick     return true;
206*e5dd7070Spatrick 
207*e5dd7070Spatrick   case Type:
208*e5dd7070Spatrick     return isa<PackExpansionType>(getAsType());
209*e5dd7070Spatrick 
210*e5dd7070Spatrick   case Expression:
211*e5dd7070Spatrick     return isa<PackExpansionExpr>(getAsExpr());
212*e5dd7070Spatrick   }
213*e5dd7070Spatrick 
214*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
215*e5dd7070Spatrick }
216*e5dd7070Spatrick 
217*e5dd7070Spatrick bool TemplateArgument::containsUnexpandedParameterPack() const {
218*e5dd7070Spatrick   switch (getKind()) {
219*e5dd7070Spatrick   case Null:
220*e5dd7070Spatrick   case Declaration:
221*e5dd7070Spatrick   case Integral:
222*e5dd7070Spatrick   case TemplateExpansion:
223*e5dd7070Spatrick   case NullPtr:
224*e5dd7070Spatrick     break;
225*e5dd7070Spatrick 
226*e5dd7070Spatrick   case Type:
227*e5dd7070Spatrick     if (getAsType()->containsUnexpandedParameterPack())
228*e5dd7070Spatrick       return true;
229*e5dd7070Spatrick     break;
230*e5dd7070Spatrick 
231*e5dd7070Spatrick   case Template:
232*e5dd7070Spatrick     if (getAsTemplate().containsUnexpandedParameterPack())
233*e5dd7070Spatrick       return true;
234*e5dd7070Spatrick     break;
235*e5dd7070Spatrick 
236*e5dd7070Spatrick   case Expression:
237*e5dd7070Spatrick     if (getAsExpr()->containsUnexpandedParameterPack())
238*e5dd7070Spatrick       return true;
239*e5dd7070Spatrick     break;
240*e5dd7070Spatrick 
241*e5dd7070Spatrick   case Pack:
242*e5dd7070Spatrick     for (const auto &P : pack_elements())
243*e5dd7070Spatrick       if (P.containsUnexpandedParameterPack())
244*e5dd7070Spatrick         return true;
245*e5dd7070Spatrick 
246*e5dd7070Spatrick     break;
247*e5dd7070Spatrick   }
248*e5dd7070Spatrick 
249*e5dd7070Spatrick   return false;
250*e5dd7070Spatrick }
251*e5dd7070Spatrick 
252*e5dd7070Spatrick Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
253*e5dd7070Spatrick   assert(getKind() == TemplateExpansion);
254*e5dd7070Spatrick   if (TemplateArg.NumExpansions)
255*e5dd7070Spatrick     return TemplateArg.NumExpansions - 1;
256*e5dd7070Spatrick 
257*e5dd7070Spatrick   return None;
258*e5dd7070Spatrick }
259*e5dd7070Spatrick 
260*e5dd7070Spatrick QualType TemplateArgument::getNonTypeTemplateArgumentType() const {
261*e5dd7070Spatrick   switch (getKind()) {
262*e5dd7070Spatrick   case TemplateArgument::Null:
263*e5dd7070Spatrick   case TemplateArgument::Type:
264*e5dd7070Spatrick   case TemplateArgument::Template:
265*e5dd7070Spatrick   case TemplateArgument::TemplateExpansion:
266*e5dd7070Spatrick   case TemplateArgument::Pack:
267*e5dd7070Spatrick     return QualType();
268*e5dd7070Spatrick 
269*e5dd7070Spatrick   case TemplateArgument::Integral:
270*e5dd7070Spatrick     return getIntegralType();
271*e5dd7070Spatrick 
272*e5dd7070Spatrick   case TemplateArgument::Expression:
273*e5dd7070Spatrick     return getAsExpr()->getType();
274*e5dd7070Spatrick 
275*e5dd7070Spatrick   case TemplateArgument::Declaration:
276*e5dd7070Spatrick     return getParamTypeForDecl();
277*e5dd7070Spatrick 
278*e5dd7070Spatrick   case TemplateArgument::NullPtr:
279*e5dd7070Spatrick     return getNullPtrType();
280*e5dd7070Spatrick   }
281*e5dd7070Spatrick 
282*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
283*e5dd7070Spatrick }
284*e5dd7070Spatrick 
285*e5dd7070Spatrick void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
286*e5dd7070Spatrick                                const ASTContext &Context) const {
287*e5dd7070Spatrick   ID.AddInteger(getKind());
288*e5dd7070Spatrick   switch (getKind()) {
289*e5dd7070Spatrick   case Null:
290*e5dd7070Spatrick     break;
291*e5dd7070Spatrick 
292*e5dd7070Spatrick   case Type:
293*e5dd7070Spatrick     getAsType().Profile(ID);
294*e5dd7070Spatrick     break;
295*e5dd7070Spatrick 
296*e5dd7070Spatrick   case NullPtr:
297*e5dd7070Spatrick     getNullPtrType().Profile(ID);
298*e5dd7070Spatrick     break;
299*e5dd7070Spatrick 
300*e5dd7070Spatrick   case Declaration:
301*e5dd7070Spatrick     ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
302*e5dd7070Spatrick     break;
303*e5dd7070Spatrick 
304*e5dd7070Spatrick   case Template:
305*e5dd7070Spatrick   case TemplateExpansion: {
306*e5dd7070Spatrick     TemplateName Template = getAsTemplateOrTemplatePattern();
307*e5dd7070Spatrick     if (TemplateTemplateParmDecl *TTP
308*e5dd7070Spatrick           = dyn_cast_or_null<TemplateTemplateParmDecl>(
309*e5dd7070Spatrick                                                 Template.getAsTemplateDecl())) {
310*e5dd7070Spatrick       ID.AddBoolean(true);
311*e5dd7070Spatrick       ID.AddInteger(TTP->getDepth());
312*e5dd7070Spatrick       ID.AddInteger(TTP->getPosition());
313*e5dd7070Spatrick       ID.AddBoolean(TTP->isParameterPack());
314*e5dd7070Spatrick     } else {
315*e5dd7070Spatrick       ID.AddBoolean(false);
316*e5dd7070Spatrick       ID.AddPointer(Context.getCanonicalTemplateName(Template)
317*e5dd7070Spatrick                                                           .getAsVoidPointer());
318*e5dd7070Spatrick     }
319*e5dd7070Spatrick     break;
320*e5dd7070Spatrick   }
321*e5dd7070Spatrick 
322*e5dd7070Spatrick   case Integral:
323*e5dd7070Spatrick     getAsIntegral().Profile(ID);
324*e5dd7070Spatrick     getIntegralType().Profile(ID);
325*e5dd7070Spatrick     break;
326*e5dd7070Spatrick 
327*e5dd7070Spatrick   case Expression:
328*e5dd7070Spatrick     getAsExpr()->Profile(ID, Context, true);
329*e5dd7070Spatrick     break;
330*e5dd7070Spatrick 
331*e5dd7070Spatrick   case Pack:
332*e5dd7070Spatrick     ID.AddInteger(Args.NumArgs);
333*e5dd7070Spatrick     for (unsigned I = 0; I != Args.NumArgs; ++I)
334*e5dd7070Spatrick       Args.Args[I].Profile(ID, Context);
335*e5dd7070Spatrick   }
336*e5dd7070Spatrick }
337*e5dd7070Spatrick 
338*e5dd7070Spatrick bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
339*e5dd7070Spatrick   if (getKind() != Other.getKind()) return false;
340*e5dd7070Spatrick 
341*e5dd7070Spatrick   switch (getKind()) {
342*e5dd7070Spatrick   case Null:
343*e5dd7070Spatrick   case Type:
344*e5dd7070Spatrick   case Expression:
345*e5dd7070Spatrick   case Template:
346*e5dd7070Spatrick   case TemplateExpansion:
347*e5dd7070Spatrick   case NullPtr:
348*e5dd7070Spatrick     return TypeOrValue.V == Other.TypeOrValue.V;
349*e5dd7070Spatrick 
350*e5dd7070Spatrick   case Declaration:
351*e5dd7070Spatrick     return getAsDecl() == Other.getAsDecl();
352*e5dd7070Spatrick 
353*e5dd7070Spatrick   case Integral:
354*e5dd7070Spatrick     return getIntegralType() == Other.getIntegralType() &&
355*e5dd7070Spatrick            getAsIntegral() == Other.getAsIntegral();
356*e5dd7070Spatrick 
357*e5dd7070Spatrick   case Pack:
358*e5dd7070Spatrick     if (Args.NumArgs != Other.Args.NumArgs) return false;
359*e5dd7070Spatrick     for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
360*e5dd7070Spatrick       if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
361*e5dd7070Spatrick         return false;
362*e5dd7070Spatrick     return true;
363*e5dd7070Spatrick   }
364*e5dd7070Spatrick 
365*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
366*e5dd7070Spatrick }
367*e5dd7070Spatrick 
368*e5dd7070Spatrick TemplateArgument TemplateArgument::getPackExpansionPattern() const {
369*e5dd7070Spatrick   assert(isPackExpansion());
370*e5dd7070Spatrick 
371*e5dd7070Spatrick   switch (getKind()) {
372*e5dd7070Spatrick   case Type:
373*e5dd7070Spatrick     return getAsType()->castAs<PackExpansionType>()->getPattern();
374*e5dd7070Spatrick 
375*e5dd7070Spatrick   case Expression:
376*e5dd7070Spatrick     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
377*e5dd7070Spatrick 
378*e5dd7070Spatrick   case TemplateExpansion:
379*e5dd7070Spatrick     return TemplateArgument(getAsTemplateOrTemplatePattern());
380*e5dd7070Spatrick 
381*e5dd7070Spatrick   case Declaration:
382*e5dd7070Spatrick   case Integral:
383*e5dd7070Spatrick   case Pack:
384*e5dd7070Spatrick   case Null:
385*e5dd7070Spatrick   case Template:
386*e5dd7070Spatrick   case NullPtr:
387*e5dd7070Spatrick     return TemplateArgument();
388*e5dd7070Spatrick   }
389*e5dd7070Spatrick 
390*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
391*e5dd7070Spatrick }
392*e5dd7070Spatrick 
393*e5dd7070Spatrick void TemplateArgument::print(const PrintingPolicy &Policy,
394*e5dd7070Spatrick                              raw_ostream &Out) const {
395*e5dd7070Spatrick   switch (getKind()) {
396*e5dd7070Spatrick   case Null:
397*e5dd7070Spatrick     Out << "(no value)";
398*e5dd7070Spatrick     break;
399*e5dd7070Spatrick 
400*e5dd7070Spatrick   case Type: {
401*e5dd7070Spatrick     PrintingPolicy SubPolicy(Policy);
402*e5dd7070Spatrick     SubPolicy.SuppressStrongLifetime = true;
403*e5dd7070Spatrick     getAsType().print(Out, SubPolicy);
404*e5dd7070Spatrick     break;
405*e5dd7070Spatrick   }
406*e5dd7070Spatrick 
407*e5dd7070Spatrick   case Declaration: {
408*e5dd7070Spatrick     NamedDecl *ND = getAsDecl();
409*e5dd7070Spatrick     Out << '&';
410*e5dd7070Spatrick     if (ND->getDeclName()) {
411*e5dd7070Spatrick       // FIXME: distinguish between pointer and reference args?
412*e5dd7070Spatrick       ND->printQualifiedName(Out);
413*e5dd7070Spatrick     } else {
414*e5dd7070Spatrick       Out << "(anonymous)";
415*e5dd7070Spatrick     }
416*e5dd7070Spatrick     break;
417*e5dd7070Spatrick   }
418*e5dd7070Spatrick 
419*e5dd7070Spatrick   case NullPtr:
420*e5dd7070Spatrick     Out << "nullptr";
421*e5dd7070Spatrick     break;
422*e5dd7070Spatrick 
423*e5dd7070Spatrick   case Template:
424*e5dd7070Spatrick     getAsTemplate().print(Out, Policy);
425*e5dd7070Spatrick     break;
426*e5dd7070Spatrick 
427*e5dd7070Spatrick   case TemplateExpansion:
428*e5dd7070Spatrick     getAsTemplateOrTemplatePattern().print(Out, Policy);
429*e5dd7070Spatrick     Out << "...";
430*e5dd7070Spatrick     break;
431*e5dd7070Spatrick 
432*e5dd7070Spatrick   case Integral:
433*e5dd7070Spatrick     printIntegral(*this, Out, Policy);
434*e5dd7070Spatrick     break;
435*e5dd7070Spatrick 
436*e5dd7070Spatrick   case Expression:
437*e5dd7070Spatrick     getAsExpr()->printPretty(Out, nullptr, Policy);
438*e5dd7070Spatrick     break;
439*e5dd7070Spatrick 
440*e5dd7070Spatrick   case Pack:
441*e5dd7070Spatrick     Out << "<";
442*e5dd7070Spatrick     bool First = true;
443*e5dd7070Spatrick     for (const auto &P : pack_elements()) {
444*e5dd7070Spatrick       if (First)
445*e5dd7070Spatrick         First = false;
446*e5dd7070Spatrick       else
447*e5dd7070Spatrick         Out << ", ";
448*e5dd7070Spatrick 
449*e5dd7070Spatrick       P.print(Policy, Out);
450*e5dd7070Spatrick     }
451*e5dd7070Spatrick     Out << ">";
452*e5dd7070Spatrick     break;
453*e5dd7070Spatrick   }
454*e5dd7070Spatrick }
455*e5dd7070Spatrick 
456*e5dd7070Spatrick void TemplateArgument::dump(raw_ostream &Out) const {
457*e5dd7070Spatrick   LangOptions LO; // FIXME! see also TemplateName::dump().
458*e5dd7070Spatrick   LO.CPlusPlus = true;
459*e5dd7070Spatrick   LO.Bool = true;
460*e5dd7070Spatrick   print(PrintingPolicy(LO), Out);
461*e5dd7070Spatrick }
462*e5dd7070Spatrick 
463*e5dd7070Spatrick LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
464*e5dd7070Spatrick 
465*e5dd7070Spatrick //===----------------------------------------------------------------------===//
466*e5dd7070Spatrick // TemplateArgumentLoc Implementation
467*e5dd7070Spatrick //===----------------------------------------------------------------------===//
468*e5dd7070Spatrick 
469*e5dd7070Spatrick SourceRange TemplateArgumentLoc::getSourceRange() const {
470*e5dd7070Spatrick   switch (Argument.getKind()) {
471*e5dd7070Spatrick   case TemplateArgument::Expression:
472*e5dd7070Spatrick     return getSourceExpression()->getSourceRange();
473*e5dd7070Spatrick 
474*e5dd7070Spatrick   case TemplateArgument::Declaration:
475*e5dd7070Spatrick     return getSourceDeclExpression()->getSourceRange();
476*e5dd7070Spatrick 
477*e5dd7070Spatrick   case TemplateArgument::NullPtr:
478*e5dd7070Spatrick     return getSourceNullPtrExpression()->getSourceRange();
479*e5dd7070Spatrick 
480*e5dd7070Spatrick   case TemplateArgument::Type:
481*e5dd7070Spatrick     if (TypeSourceInfo *TSI = getTypeSourceInfo())
482*e5dd7070Spatrick       return TSI->getTypeLoc().getSourceRange();
483*e5dd7070Spatrick     else
484*e5dd7070Spatrick       return SourceRange();
485*e5dd7070Spatrick 
486*e5dd7070Spatrick   case TemplateArgument::Template:
487*e5dd7070Spatrick     if (getTemplateQualifierLoc())
488*e5dd7070Spatrick       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
489*e5dd7070Spatrick                          getTemplateNameLoc());
490*e5dd7070Spatrick     return SourceRange(getTemplateNameLoc());
491*e5dd7070Spatrick 
492*e5dd7070Spatrick   case TemplateArgument::TemplateExpansion:
493*e5dd7070Spatrick     if (getTemplateQualifierLoc())
494*e5dd7070Spatrick       return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
495*e5dd7070Spatrick                          getTemplateEllipsisLoc());
496*e5dd7070Spatrick     return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
497*e5dd7070Spatrick 
498*e5dd7070Spatrick   case TemplateArgument::Integral:
499*e5dd7070Spatrick     return getSourceIntegralExpression()->getSourceRange();
500*e5dd7070Spatrick 
501*e5dd7070Spatrick   case TemplateArgument::Pack:
502*e5dd7070Spatrick   case TemplateArgument::Null:
503*e5dd7070Spatrick     return SourceRange();
504*e5dd7070Spatrick   }
505*e5dd7070Spatrick 
506*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
507*e5dd7070Spatrick }
508*e5dd7070Spatrick 
509*e5dd7070Spatrick const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
510*e5dd7070Spatrick                                            const TemplateArgument &Arg) {
511*e5dd7070Spatrick   switch (Arg.getKind()) {
512*e5dd7070Spatrick   case TemplateArgument::Null:
513*e5dd7070Spatrick     // This is bad, but not as bad as crashing because of argument
514*e5dd7070Spatrick     // count mismatches.
515*e5dd7070Spatrick     return DB << "(null template argument)";
516*e5dd7070Spatrick 
517*e5dd7070Spatrick   case TemplateArgument::Type:
518*e5dd7070Spatrick     return DB << Arg.getAsType();
519*e5dd7070Spatrick 
520*e5dd7070Spatrick   case TemplateArgument::Declaration:
521*e5dd7070Spatrick     return DB << Arg.getAsDecl();
522*e5dd7070Spatrick 
523*e5dd7070Spatrick   case TemplateArgument::NullPtr:
524*e5dd7070Spatrick     return DB << "nullptr";
525*e5dd7070Spatrick 
526*e5dd7070Spatrick   case TemplateArgument::Integral:
527*e5dd7070Spatrick     return DB << Arg.getAsIntegral().toString(10);
528*e5dd7070Spatrick 
529*e5dd7070Spatrick   case TemplateArgument::Template:
530*e5dd7070Spatrick     return DB << Arg.getAsTemplate();
531*e5dd7070Spatrick 
532*e5dd7070Spatrick   case TemplateArgument::TemplateExpansion:
533*e5dd7070Spatrick     return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
534*e5dd7070Spatrick 
535*e5dd7070Spatrick   case TemplateArgument::Expression: {
536*e5dd7070Spatrick     // This shouldn't actually ever happen, so it's okay that we're
537*e5dd7070Spatrick     // regurgitating an expression here.
538*e5dd7070Spatrick     // FIXME: We're guessing at LangOptions!
539*e5dd7070Spatrick     SmallString<32> Str;
540*e5dd7070Spatrick     llvm::raw_svector_ostream OS(Str);
541*e5dd7070Spatrick     LangOptions LangOpts;
542*e5dd7070Spatrick     LangOpts.CPlusPlus = true;
543*e5dd7070Spatrick     PrintingPolicy Policy(LangOpts);
544*e5dd7070Spatrick     Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
545*e5dd7070Spatrick     return DB << OS.str();
546*e5dd7070Spatrick   }
547*e5dd7070Spatrick 
548*e5dd7070Spatrick   case TemplateArgument::Pack: {
549*e5dd7070Spatrick     // FIXME: We're guessing at LangOptions!
550*e5dd7070Spatrick     SmallString<32> Str;
551*e5dd7070Spatrick     llvm::raw_svector_ostream OS(Str);
552*e5dd7070Spatrick     LangOptions LangOpts;
553*e5dd7070Spatrick     LangOpts.CPlusPlus = true;
554*e5dd7070Spatrick     PrintingPolicy Policy(LangOpts);
555*e5dd7070Spatrick     Arg.print(Policy, OS);
556*e5dd7070Spatrick     return DB << OS.str();
557*e5dd7070Spatrick   }
558*e5dd7070Spatrick   }
559*e5dd7070Spatrick 
560*e5dd7070Spatrick   llvm_unreachable("Invalid TemplateArgument Kind!");
561*e5dd7070Spatrick }
562*e5dd7070Spatrick 
563*e5dd7070Spatrick const ASTTemplateArgumentListInfo *
564*e5dd7070Spatrick ASTTemplateArgumentListInfo::Create(const ASTContext &C,
565*e5dd7070Spatrick                                     const TemplateArgumentListInfo &List) {
566*e5dd7070Spatrick   std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
567*e5dd7070Spatrick   void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
568*e5dd7070Spatrick   return new (Mem) ASTTemplateArgumentListInfo(List);
569*e5dd7070Spatrick }
570*e5dd7070Spatrick 
571*e5dd7070Spatrick ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
572*e5dd7070Spatrick     const TemplateArgumentListInfo &Info) {
573*e5dd7070Spatrick   LAngleLoc = Info.getLAngleLoc();
574*e5dd7070Spatrick   RAngleLoc = Info.getRAngleLoc();
575*e5dd7070Spatrick   NumTemplateArgs = Info.size();
576*e5dd7070Spatrick 
577*e5dd7070Spatrick   TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
578*e5dd7070Spatrick   for (unsigned i = 0; i != NumTemplateArgs; ++i)
579*e5dd7070Spatrick     new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
580*e5dd7070Spatrick }
581*e5dd7070Spatrick 
582*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom(
583*e5dd7070Spatrick     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
584*e5dd7070Spatrick     TemplateArgumentLoc *OutArgArray) {
585*e5dd7070Spatrick   this->TemplateKWLoc = TemplateKWLoc;
586*e5dd7070Spatrick   LAngleLoc = Info.getLAngleLoc();
587*e5dd7070Spatrick   RAngleLoc = Info.getRAngleLoc();
588*e5dd7070Spatrick   NumTemplateArgs = Info.size();
589*e5dd7070Spatrick 
590*e5dd7070Spatrick   for (unsigned i = 0; i != NumTemplateArgs; ++i)
591*e5dd7070Spatrick     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
592*e5dd7070Spatrick }
593*e5dd7070Spatrick 
594*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
595*e5dd7070Spatrick   assert(TemplateKWLoc.isValid());
596*e5dd7070Spatrick   LAngleLoc = SourceLocation();
597*e5dd7070Spatrick   RAngleLoc = SourceLocation();
598*e5dd7070Spatrick   this->TemplateKWLoc = TemplateKWLoc;
599*e5dd7070Spatrick   NumTemplateArgs = 0;
600*e5dd7070Spatrick }
601*e5dd7070Spatrick 
602*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom(
603*e5dd7070Spatrick     SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
604*e5dd7070Spatrick     TemplateArgumentLoc *OutArgArray, bool &Dependent,
605*e5dd7070Spatrick     bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
606*e5dd7070Spatrick   this->TemplateKWLoc = TemplateKWLoc;
607*e5dd7070Spatrick   LAngleLoc = Info.getLAngleLoc();
608*e5dd7070Spatrick   RAngleLoc = Info.getRAngleLoc();
609*e5dd7070Spatrick   NumTemplateArgs = Info.size();
610*e5dd7070Spatrick 
611*e5dd7070Spatrick   for (unsigned i = 0; i != NumTemplateArgs; ++i) {
612*e5dd7070Spatrick     Dependent = Dependent || Info[i].getArgument().isDependent();
613*e5dd7070Spatrick     InstantiationDependent = InstantiationDependent ||
614*e5dd7070Spatrick                              Info[i].getArgument().isInstantiationDependent();
615*e5dd7070Spatrick     ContainsUnexpandedParameterPack =
616*e5dd7070Spatrick         ContainsUnexpandedParameterPack ||
617*e5dd7070Spatrick         Info[i].getArgument().containsUnexpandedParameterPack();
618*e5dd7070Spatrick 
619*e5dd7070Spatrick     new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
620*e5dd7070Spatrick   }
621*e5dd7070Spatrick }
622*e5dd7070Spatrick 
623*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
624*e5dd7070Spatrick                                         TemplateArgumentListInfo &Info) const {
625*e5dd7070Spatrick   Info.setLAngleLoc(LAngleLoc);
626*e5dd7070Spatrick   Info.setRAngleLoc(RAngleLoc);
627*e5dd7070Spatrick   for (unsigned I = 0; I != NumTemplateArgs; ++I)
628*e5dd7070Spatrick     Info.addArgument(ArgArray[I]);
629*e5dd7070Spatrick }
630