1327952Sdim//===- TemplateBase.cpp - Common template AST class implementation --------===//
2198893Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6198893Srdivacky//
7198893Srdivacky//===----------------------------------------------------------------------===//
8198893Srdivacky//
9198893Srdivacky// This file implements common classes used throughout C++ template
10198893Srdivacky// representations.
11198893Srdivacky//
12198893Srdivacky//===----------------------------------------------------------------------===//
13198893Srdivacky
14198893Srdivacky#include "clang/AST/TemplateBase.h"
15218893Sdim#include "clang/AST/ASTContext.h"
16327952Sdim#include "clang/AST/Decl.h"
17198893Srdivacky#include "clang/AST/DeclBase.h"
18199990Srdivacky#include "clang/AST/DeclTemplate.h"
19198893Srdivacky#include "clang/AST/Expr.h"
20218893Sdim#include "clang/AST/ExprCXX.h"
21327952Sdim#include "clang/AST/PrettyPrinter.h"
22327952Sdim#include "clang/AST/TemplateName.h"
23218893Sdim#include "clang/AST/Type.h"
24198893Srdivacky#include "clang/AST/TypeLoc.h"
25208600Srdivacky#include "clang/Basic/Diagnostic.h"
26327952Sdim#include "clang/Basic/LLVM.h"
27327952Sdim#include "clang/Basic/LangOptions.h"
28327952Sdim#include "clang/Basic/SourceLocation.h"
29327952Sdim#include "llvm/ADT/APSInt.h"
30218893Sdim#include "llvm/ADT/FoldingSet.h"
31327952Sdim#include "llvm/ADT/None.h"
32234353Sdim#include "llvm/ADT/SmallString.h"
33327952Sdim#include "llvm/ADT/StringRef.h"
34327952Sdim#include "llvm/Support/Casting.h"
35327952Sdim#include "llvm/Support/Compiler.h"
36327952Sdim#include "llvm/Support/ErrorHandling.h"
37249423Sdim#include "llvm/Support/raw_ostream.h"
38327952Sdim#include <cassert>
39327952Sdim#include <cstddef>
40327952Sdim#include <cstdint>
41327952Sdim#include <cstring>
42198893Srdivacky
43198893Srdivackyusing namespace clang;
44198893Srdivacky
45341825Sdim/// Print a template integral argument value.
46218893Sdim///
47218893Sdim/// \param TemplArg the TemplateArgument instance to print.
48218893Sdim///
49218893Sdim/// \param Out the raw_ostream instance to use for printing.
50280031Sdim///
51280031Sdim/// \param Policy the printing policy for EnumConstantDecl printing.
52218893Sdimstatic void printIntegral(const TemplateArgument &TemplArg,
53280031Sdim                          raw_ostream &Out, const PrintingPolicy& Policy) {
54327952Sdim  const Type *T = TemplArg.getIntegralType().getTypePtr();
55239462Sdim  const llvm::APSInt &Val = TemplArg.getAsIntegral();
56218893Sdim
57280031Sdim  if (const EnumType *ET = T->getAs<EnumType>()) {
58280031Sdim    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
59280031Sdim      // In Sema::CheckTemplateArugment, enum template arguments value are
60280031Sdim      // extended to the size of the integer underlying the enum type.  This
61280031Sdim      // may create a size difference between the enum value and template
62280031Sdim      // argument value, requiring isSameValue here instead of operator==.
63280031Sdim      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
64280031Sdim        ECD->printQualifiedName(Out, Policy);
65280031Sdim        return;
66280031Sdim      }
67280031Sdim    }
68280031Sdim  }
69280031Sdim
70296417Sdim  if (T->isBooleanType() && !Policy.MSVCFormatting) {
71239462Sdim    Out << (Val.getBoolValue() ? "true" : "false");
72218893Sdim  } else if (T->isCharType()) {
73239462Sdim    const char Ch = Val.getZExtValue();
74219077Sdim    Out << ((Ch == '\'') ? "'\\" : "'");
75234353Sdim    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
76219077Sdim    Out << "'";
77218893Sdim  } else {
78239462Sdim    Out << Val;
79218893Sdim  }
80218893Sdim}
81218893Sdim
82198893Srdivacky//===----------------------------------------------------------------------===//
83198893Srdivacky// TemplateArgument Implementation
84198893Srdivacky//===----------------------------------------------------------------------===//
85198893Srdivacky
86239462SdimTemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
87261991Sdim                                   QualType Type) {
88261991Sdim  Integer.Kind = Integral;
89239462Sdim  // Copy the APSInt value into our decomposed form.
90239462Sdim  Integer.BitWidth = Value.getBitWidth();
91239462Sdim  Integer.IsUnsigned = Value.isUnsigned();
92239462Sdim  // If the value is large, we have to get additional memory from the ASTContext
93239462Sdim  unsigned NumWords = Value.getNumWords();
94239462Sdim  if (NumWords > 1) {
95239462Sdim    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
96239462Sdim    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
97239462Sdim    Integer.pVal = static_cast<uint64_t *>(Mem);
98239462Sdim  } else {
99239462Sdim    Integer.VAL = Value.getZExtValue();
100239462Sdim  }
101239462Sdim
102239462Sdim  Integer.Type = Type.getAsOpaquePtr();
103239462Sdim}
104239462Sdim
105296417SdimTemplateArgument
106296417SdimTemplateArgument::CreatePackCopy(ASTContext &Context,
107296417Sdim                                 ArrayRef<TemplateArgument> Args) {
108296417Sdim  if (Args.empty())
109243830Sdim    return getEmptyPack();
110296417Sdim
111296417Sdim  return TemplateArgument(Args.copy(Context));
112218893Sdim}
113198893Srdivacky
114218893Sdimbool TemplateArgument::isDependent() const {
115218893Sdim  switch (getKind()) {
116218893Sdim  case Null:
117226633Sdim    llvm_unreachable("Should not have a NULL template argument");
118218893Sdim
119218893Sdim  case Type:
120280031Sdim    return getAsType()->isDependentType() ||
121280031Sdim           isa<PackExpansionType>(getAsType());
122218893Sdim
123218893Sdim  case Template:
124218893Sdim    return getAsTemplate().isDependent();
125218893Sdim
126218893Sdim  case TemplateExpansion:
127218893Sdim    return true;
128218893Sdim
129218893Sdim  case Declaration:
130243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
131243830Sdim      return DC->isDependentContext();
132243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
133243830Sdim
134243830Sdim  case NullPtr:
135234353Sdim    return false;
136218893Sdim
137218893Sdim  case Integral:
138218893Sdim    // Never dependent
139218893Sdim    return false;
140218893Sdim
141218893Sdim  case Expression:
142280031Sdim    return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
143280031Sdim            isa<PackExpansionExpr>(getAsExpr()));
144218893Sdim
145218893Sdim  case Pack:
146276479Sdim    for (const auto &P : pack_elements())
147276479Sdim      if (P.isDependent())
148218893Sdim        return true;
149218893Sdim    return false;
150198893Srdivacky  }
151198893Srdivacky
152234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
153198893Srdivacky}
154198893Srdivacky
155224145Sdimbool TemplateArgument::isInstantiationDependent() const {
156224145Sdim  switch (getKind()) {
157224145Sdim  case Null:
158226633Sdim    llvm_unreachable("Should not have a NULL template argument");
159341825Sdim
160224145Sdim  case Type:
161224145Sdim    return getAsType()->isInstantiationDependentType();
162341825Sdim
163224145Sdim  case Template:
164224145Sdim    return getAsTemplate().isInstantiationDependent();
165341825Sdim
166224145Sdim  case TemplateExpansion:
167224145Sdim    return true;
168341825Sdim
169224145Sdim  case Declaration:
170243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
171243830Sdim      return DC->isDependentContext();
172243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
173243830Sdim
174243830Sdim  case NullPtr:
175234353Sdim    return false;
176341825Sdim
177224145Sdim  case Integral:
178224145Sdim    // Never dependent
179224145Sdim    return false;
180341825Sdim
181224145Sdim  case Expression:
182224145Sdim    return getAsExpr()->isInstantiationDependent();
183341825Sdim
184224145Sdim  case Pack:
185276479Sdim    for (const auto &P : pack_elements())
186276479Sdim      if (P.isInstantiationDependent())
187224145Sdim        return true;
188224145Sdim    return false;
189224145Sdim  }
190234353Sdim
191234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
192224145Sdim}
193224145Sdim
194218893Sdimbool TemplateArgument::isPackExpansion() const {
195218893Sdim  switch (getKind()) {
196218893Sdim  case Null:
197218893Sdim  case Declaration:
198218893Sdim  case Integral:
199341825Sdim  case Pack:
200218893Sdim  case Template:
201243830Sdim  case NullPtr:
202218893Sdim    return false;
203341825Sdim
204218893Sdim  case TemplateExpansion:
205218893Sdim    return true;
206341825Sdim
207218893Sdim  case Type:
208218893Sdim    return isa<PackExpansionType>(getAsType());
209341825Sdim
210218893Sdim  case Expression:
211218893Sdim    return isa<PackExpansionExpr>(getAsExpr());
212218893Sdim  }
213234353Sdim
214234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
215218893Sdim}
216218893Sdim
217218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const {
218218893Sdim  switch (getKind()) {
219218893Sdim  case Null:
220218893Sdim  case Declaration:
221218893Sdim  case Integral:
222218893Sdim  case TemplateExpansion:
223243830Sdim  case NullPtr:
224218893Sdim    break;
225218893Sdim
226218893Sdim  case Type:
227218893Sdim    if (getAsType()->containsUnexpandedParameterPack())
228218893Sdim      return true;
229218893Sdim    break;
230218893Sdim
231218893Sdim  case Template:
232218893Sdim    if (getAsTemplate().containsUnexpandedParameterPack())
233218893Sdim      return true;
234218893Sdim    break;
235341825Sdim
236218893Sdim  case Expression:
237218893Sdim    if (getAsExpr()->containsUnexpandedParameterPack())
238218893Sdim      return true;
239218893Sdim    break;
240218893Sdim
241218893Sdim  case Pack:
242276479Sdim    for (const auto &P : pack_elements())
243276479Sdim      if (P.containsUnexpandedParameterPack())
244218893Sdim        return true;
245218893Sdim
246218893Sdim    break;
247218893Sdim  }
248218893Sdim
249218893Sdim  return false;
250218893Sdim}
251218893Sdim
252249423SdimOptional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
253261991Sdim  assert(getKind() == TemplateExpansion);
254218893Sdim  if (TemplateArg.NumExpansions)
255218893Sdim    return TemplateArg.NumExpansions - 1;
256341825Sdim
257341825Sdim  return None;
258218893Sdim}
259218893Sdim
260314564SdimQualType TemplateArgument::getNonTypeTemplateArgumentType() const {
261314564Sdim  switch (getKind()) {
262314564Sdim  case TemplateArgument::Null:
263314564Sdim  case TemplateArgument::Type:
264314564Sdim  case TemplateArgument::Template:
265314564Sdim  case TemplateArgument::TemplateExpansion:
266314564Sdim  case TemplateArgument::Pack:
267314564Sdim    return QualType();
268314564Sdim
269314564Sdim  case TemplateArgument::Integral:
270314564Sdim    return getIntegralType();
271314564Sdim
272314564Sdim  case TemplateArgument::Expression:
273314564Sdim    return getAsExpr()->getType();
274314564Sdim
275314564Sdim  case TemplateArgument::Declaration:
276314564Sdim    return getParamTypeForDecl();
277314564Sdim
278314564Sdim  case TemplateArgument::NullPtr:
279314564Sdim    return getNullPtrType();
280314564Sdim  }
281314564Sdim
282314564Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
283314564Sdim}
284314564Sdim
285198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
286218893Sdim                               const ASTContext &Context) const {
287261991Sdim  ID.AddInteger(getKind());
288261991Sdim  switch (getKind()) {
289198893Srdivacky  case Null:
290198893Srdivacky    break;
291198893Srdivacky
292198893Srdivacky  case Type:
293198893Srdivacky    getAsType().Profile(ID);
294198893Srdivacky    break;
295198893Srdivacky
296261991Sdim  case NullPtr:
297261991Sdim    getNullPtrType().Profile(ID);
298261991Sdim    break;
299261991Sdim
300198893Srdivacky  case Declaration:
301276479Sdim    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
302198893Srdivacky    break;
303198893Srdivacky
304199482Srdivacky  case Template:
305218893Sdim  case TemplateExpansion: {
306218893Sdim    TemplateName Template = getAsTemplateOrTemplatePattern();
307199990Srdivacky    if (TemplateTemplateParmDecl *TTP
308199990Srdivacky          = dyn_cast_or_null<TemplateTemplateParmDecl>(
309218893Sdim                                                Template.getAsTemplateDecl())) {
310199990Srdivacky      ID.AddBoolean(true);
311199990Srdivacky      ID.AddInteger(TTP->getDepth());
312199990Srdivacky      ID.AddInteger(TTP->getPosition());
313218893Sdim      ID.AddBoolean(TTP->isParameterPack());
314199990Srdivacky    } else {
315199990Srdivacky      ID.AddBoolean(false);
316218893Sdim      ID.AddPointer(Context.getCanonicalTemplateName(Template)
317218893Sdim                                                          .getAsVoidPointer());
318199990Srdivacky    }
319199482Srdivacky    break;
320218893Sdim  }
321341825Sdim
322198893Srdivacky  case Integral:
323239462Sdim    getAsIntegral().Profile(ID);
324198893Srdivacky    getIntegralType().Profile(ID);
325198893Srdivacky    break;
326198893Srdivacky
327198893Srdivacky  case Expression:
328198893Srdivacky    getAsExpr()->Profile(ID, Context, true);
329198893Srdivacky    break;
330198893Srdivacky
331198893Srdivacky  case Pack:
332198893Srdivacky    ID.AddInteger(Args.NumArgs);
333198893Srdivacky    for (unsigned I = 0; I != Args.NumArgs; ++I)
334198893Srdivacky      Args.Args[I].Profile(ID, Context);
335198893Srdivacky  }
336198893Srdivacky}
337198893Srdivacky
338210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
339210299Sed  if (getKind() != Other.getKind()) return false;
340210299Sed
341210299Sed  switch (getKind()) {
342210299Sed  case Null:
343210299Sed  case Type:
344341825Sdim  case Expression:
345210299Sed  case Template:
346218893Sdim  case TemplateExpansion:
347243830Sdim  case NullPtr:
348261991Sdim    return TypeOrValue.V == Other.TypeOrValue.V;
349210299Sed
350243830Sdim  case Declaration:
351280031Sdim    return getAsDecl() == Other.getAsDecl();
352243830Sdim
353210299Sed  case Integral:
354210299Sed    return getIntegralType() == Other.getIntegralType() &&
355239462Sdim           getAsIntegral() == Other.getAsIntegral();
356210299Sed
357210299Sed  case Pack:
358210299Sed    if (Args.NumArgs != Other.Args.NumArgs) return false;
359210299Sed    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
360210299Sed      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
361210299Sed        return false;
362210299Sed    return true;
363210299Sed  }
364210299Sed
365234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
366210299Sed}
367210299Sed
368218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const {
369218893Sdim  assert(isPackExpansion());
370341825Sdim
371218893Sdim  switch (getKind()) {
372218893Sdim  case Type:
373360784Sdim    return getAsType()->castAs<PackExpansionType>()->getPattern();
374341825Sdim
375218893Sdim  case Expression:
376218893Sdim    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
377341825Sdim
378218893Sdim  case TemplateExpansion:
379218893Sdim    return TemplateArgument(getAsTemplateOrTemplatePattern());
380243830Sdim
381218893Sdim  case Declaration:
382218893Sdim  case Integral:
383218893Sdim  case Pack:
384218893Sdim  case Null:
385218893Sdim  case Template:
386243830Sdim  case NullPtr:
387218893Sdim    return TemplateArgument();
388218893Sdim  }
389234353Sdim
390234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
391218893Sdim}
392218893Sdim
393341825Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy,
394226633Sdim                             raw_ostream &Out) const {
395218893Sdim  switch (getKind()) {
396218893Sdim  case Null:
397276479Sdim    Out << "(no value)";
398218893Sdim    break;
399341825Sdim
400218893Sdim  case Type: {
401224145Sdim    PrintingPolicy SubPolicy(Policy);
402224145Sdim    SubPolicy.SuppressStrongLifetime = true;
403249423Sdim    getAsType().print(Out, SubPolicy);
404218893Sdim    break;
405218893Sdim  }
406341825Sdim
407218893Sdim  case Declaration: {
408341825Sdim    NamedDecl *ND = getAsDecl();
409261991Sdim    Out << '&';
410243830Sdim    if (ND->getDeclName()) {
411243830Sdim      // FIXME: distinguish between pointer and reference args?
412261991Sdim      ND->printQualifiedName(Out);
413234353Sdim    } else {
414276479Sdim      Out << "(anonymous)";
415218893Sdim    }
416218893Sdim    break;
417218893Sdim  }
418243830Sdim
419243830Sdim  case NullPtr:
420243830Sdim    Out << "nullptr";
421243830Sdim    break;
422243830Sdim
423218893Sdim  case Template:
424218893Sdim    getAsTemplate().print(Out, Policy);
425218893Sdim    break;
426218893Sdim
427218893Sdim  case TemplateExpansion:
428218893Sdim    getAsTemplateOrTemplatePattern().print(Out, Policy);
429218893Sdim    Out << "...";
430218893Sdim    break;
431341825Sdim
432327952Sdim  case Integral:
433280031Sdim    printIntegral(*this, Out, Policy);
434218893Sdim    break;
435341825Sdim
436218893Sdim  case Expression:
437276479Sdim    getAsExpr()->printPretty(Out, nullptr, Policy);
438218893Sdim    break;
439341825Sdim
440218893Sdim  case Pack:
441218893Sdim    Out << "<";
442218893Sdim    bool First = true;
443276479Sdim    for (const auto &P : pack_elements()) {
444218893Sdim      if (First)
445218893Sdim        First = false;
446218893Sdim      else
447218893Sdim        Out << ", ";
448341825Sdim
449276479Sdim      P.print(Policy, Out);
450218893Sdim    }
451218893Sdim    Out << ">";
452341825Sdim    break;
453218893Sdim  }
454218893Sdim}
455218893Sdim
456309124Sdimvoid TemplateArgument::dump(raw_ostream &Out) const {
457309124Sdim  LangOptions LO; // FIXME! see also TemplateName::dump().
458309124Sdim  LO.CPlusPlus = true;
459309124Sdim  LO.Bool = true;
460309124Sdim  print(PrintingPolicy(LO), Out);
461309124Sdim}
462309124Sdim
463309124SdimLLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
464309124Sdim
465198893Srdivacky//===----------------------------------------------------------------------===//
466198893Srdivacky// TemplateArgumentLoc Implementation
467198893Srdivacky//===----------------------------------------------------------------------===//
468198893Srdivacky
469198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const {
470198893Srdivacky  switch (Argument.getKind()) {
471198893Srdivacky  case TemplateArgument::Expression:
472198893Srdivacky    return getSourceExpression()->getSourceRange();
473212904Sdim
474198893Srdivacky  case TemplateArgument::Declaration:
475198893Srdivacky    return getSourceDeclExpression()->getSourceRange();
476212904Sdim
477243830Sdim  case TemplateArgument::NullPtr:
478243830Sdim    return getSourceNullPtrExpression()->getSourceRange();
479243830Sdim
480198893Srdivacky  case TemplateArgument::Type:
481212904Sdim    if (TypeSourceInfo *TSI = getTypeSourceInfo())
482212904Sdim      return TSI->getTypeLoc().getSourceRange();
483212904Sdim    else
484212904Sdim      return SourceRange();
485212904Sdim
486199482Srdivacky  case TemplateArgument::Template:
487221345Sdim    if (getTemplateQualifierLoc())
488341825Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
489199482Srdivacky                         getTemplateNameLoc());
490199482Srdivacky    return SourceRange(getTemplateNameLoc());
491212904Sdim
492218893Sdim  case TemplateArgument::TemplateExpansion:
493221345Sdim    if (getTemplateQualifierLoc())
494341825Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
495218893Sdim                         getTemplateEllipsisLoc());
496218893Sdim    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
497218893Sdim
498198893Srdivacky  case TemplateArgument::Integral:
499243830Sdim    return getSourceIntegralExpression()->getSourceRange();
500243830Sdim
501198893Srdivacky  case TemplateArgument::Pack:
502198893Srdivacky  case TemplateArgument::Null:
503198893Srdivacky    return SourceRange();
504198893Srdivacky  }
505198893Srdivacky
506234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
507198893Srdivacky}
508208600Srdivacky
509208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
510208600Srdivacky                                           const TemplateArgument &Arg) {
511208600Srdivacky  switch (Arg.getKind()) {
512208600Srdivacky  case TemplateArgument::Null:
513212904Sdim    // This is bad, but not as bad as crashing because of argument
514212904Sdim    // count mismatches.
515212904Sdim    return DB << "(null template argument)";
516341825Sdim
517208600Srdivacky  case TemplateArgument::Type:
518208600Srdivacky    return DB << Arg.getAsType();
519341825Sdim
520208600Srdivacky  case TemplateArgument::Declaration:
521243830Sdim    return DB << Arg.getAsDecl();
522243830Sdim
523243830Sdim  case TemplateArgument::NullPtr:
524234353Sdim    return DB << "nullptr";
525341825Sdim
526208600Srdivacky  case TemplateArgument::Integral:
527239462Sdim    return DB << Arg.getAsIntegral().toString(10);
528341825Sdim
529208600Srdivacky  case TemplateArgument::Template:
530208600Srdivacky    return DB << Arg.getAsTemplate();
531218893Sdim
532218893Sdim  case TemplateArgument::TemplateExpansion:
533218893Sdim    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
534218893Sdim
535208600Srdivacky  case TemplateArgument::Expression: {
536208600Srdivacky    // This shouldn't actually ever happen, so it's okay that we're
537208600Srdivacky    // regurgitating an expression here.
538208600Srdivacky    // FIXME: We're guessing at LangOptions!
539234353Sdim    SmallString<32> Str;
540208600Srdivacky    llvm::raw_svector_ostream OS(Str);
541208600Srdivacky    LangOptions LangOpts;
542208600Srdivacky    LangOpts.CPlusPlus = true;
543208600Srdivacky    PrintingPolicy Policy(LangOpts);
544276479Sdim    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
545208600Srdivacky    return DB << OS.str();
546208600Srdivacky  }
547341825Sdim
548218893Sdim  case TemplateArgument::Pack: {
549218893Sdim    // FIXME: We're guessing at LangOptions!
550234353Sdim    SmallString<32> Str;
551218893Sdim    llvm::raw_svector_ostream OS(Str);
552218893Sdim    LangOptions LangOpts;
553218893Sdim    LangOpts.CPlusPlus = true;
554218893Sdim    PrintingPolicy Policy(LangOpts);
555218893Sdim    Arg.print(Policy, OS);
556218893Sdim    return DB << OS.str();
557208600Srdivacky  }
558218893Sdim  }
559234353Sdim
560234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
561208600Srdivacky}
562226633Sdim
563226633Sdimconst ASTTemplateArgumentListInfo *
564360784SdimASTTemplateArgumentListInfo::Create(const ASTContext &C,
565226633Sdim                                    const TemplateArgumentListInfo &List) {
566296417Sdim  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
567314564Sdim  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
568296417Sdim  return new (Mem) ASTTemplateArgumentListInfo(List);
569226633Sdim}
570226633Sdim
571296417SdimASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
572296417Sdim    const TemplateArgumentListInfo &Info) {
573226633Sdim  LAngleLoc = Info.getLAngleLoc();
574226633Sdim  RAngleLoc = Info.getRAngleLoc();
575226633Sdim  NumTemplateArgs = Info.size();
576226633Sdim
577296417Sdim  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
578226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
579226633Sdim    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
580226633Sdim}
581226633Sdim
582296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
583296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
584296417Sdim    TemplateArgumentLoc *OutArgArray) {
585296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
586226633Sdim  LAngleLoc = Info.getLAngleLoc();
587226633Sdim  RAngleLoc = Info.getRAngleLoc();
588226633Sdim  NumTemplateArgs = Info.size();
589226633Sdim
590296417Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
591296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
592296417Sdim}
593296417Sdim
594296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
595296417Sdim  assert(TemplateKWLoc.isValid());
596296417Sdim  LAngleLoc = SourceLocation();
597296417Sdim  RAngleLoc = SourceLocation();
598296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
599296417Sdim  NumTemplateArgs = 0;
600296417Sdim}
601296417Sdim
602296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
603296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
604296417Sdim    TemplateArgumentLoc *OutArgArray, bool &Dependent,
605296417Sdim    bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
606296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
607296417Sdim  LAngleLoc = Info.getLAngleLoc();
608296417Sdim  RAngleLoc = Info.getRAngleLoc();
609296417Sdim  NumTemplateArgs = Info.size();
610296417Sdim
611226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
612226633Sdim    Dependent = Dependent || Info[i].getArgument().isDependent();
613296417Sdim    InstantiationDependent = InstantiationDependent ||
614226633Sdim                             Info[i].getArgument().isInstantiationDependent();
615296417Sdim    ContainsUnexpandedParameterPack =
616296417Sdim        ContainsUnexpandedParameterPack ||
617226633Sdim        Info[i].getArgument().containsUnexpandedParameterPack();
618226633Sdim
619296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
620226633Sdim  }
621226633Sdim}
622226633Sdim
623296417Sdimvoid ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
624296417Sdim                                        TemplateArgumentListInfo &Info) const {
625226633Sdim  Info.setLAngleLoc(LAngleLoc);
626226633Sdim  Info.setRAngleLoc(RAngleLoc);
627226633Sdim  for (unsigned I = 0; I != NumTemplateArgs; ++I)
628296417Sdim    Info.addArgument(ArgArray[I]);
629226633Sdim}
630