TemplateBase.cpp revision 341825
1327952Sdim//===- TemplateBase.cpp - Common template AST class implementation --------===//
2198893Srdivacky//
3198893Srdivacky//                     The LLVM Compiler Infrastructure
4198893Srdivacky//
5198893Srdivacky// This file is distributed under the University of Illinois Open Source
6198893Srdivacky// License. See LICENSE.TXT for details.
7198893Srdivacky//
8198893Srdivacky//===----------------------------------------------------------------------===//
9198893Srdivacky//
10198893Srdivacky// This file implements common classes used throughout C++ template
11198893Srdivacky// representations.
12198893Srdivacky//
13198893Srdivacky//===----------------------------------------------------------------------===//
14198893Srdivacky
15198893Srdivacky#include "clang/AST/TemplateBase.h"
16218893Sdim#include "clang/AST/ASTContext.h"
17327952Sdim#include "clang/AST/Decl.h"
18198893Srdivacky#include "clang/AST/DeclBase.h"
19199990Srdivacky#include "clang/AST/DeclTemplate.h"
20198893Srdivacky#include "clang/AST/Expr.h"
21218893Sdim#include "clang/AST/ExprCXX.h"
22327952Sdim#include "clang/AST/PrettyPrinter.h"
23327952Sdim#include "clang/AST/TemplateName.h"
24218893Sdim#include "clang/AST/Type.h"
25198893Srdivacky#include "clang/AST/TypeLoc.h"
26208600Srdivacky#include "clang/Basic/Diagnostic.h"
27327952Sdim#include "clang/Basic/LLVM.h"
28327952Sdim#include "clang/Basic/LangOptions.h"
29327952Sdim#include "clang/Basic/SourceLocation.h"
30327952Sdim#include "llvm/ADT/APSInt.h"
31218893Sdim#include "llvm/ADT/FoldingSet.h"
32327952Sdim#include "llvm/ADT/None.h"
33234353Sdim#include "llvm/ADT/SmallString.h"
34327952Sdim#include "llvm/ADT/StringRef.h"
35327952Sdim#include "llvm/Support/Casting.h"
36327952Sdim#include "llvm/Support/Compiler.h"
37327952Sdim#include "llvm/Support/ErrorHandling.h"
38249423Sdim#include "llvm/Support/raw_ostream.h"
39327952Sdim#include <cassert>
40327952Sdim#include <cstddef>
41327952Sdim#include <cstdint>
42327952Sdim#include <cstring>
43198893Srdivacky
44198893Srdivackyusing namespace clang;
45198893Srdivacky
46341825Sdim/// Print a template integral argument value.
47218893Sdim///
48218893Sdim/// \param TemplArg the TemplateArgument instance to print.
49218893Sdim///
50218893Sdim/// \param Out the raw_ostream instance to use for printing.
51280031Sdim///
52280031Sdim/// \param Policy the printing policy for EnumConstantDecl printing.
53218893Sdimstatic void printIntegral(const TemplateArgument &TemplArg,
54280031Sdim                          raw_ostream &Out, const PrintingPolicy& Policy) {
55327952Sdim  const Type *T = TemplArg.getIntegralType().getTypePtr();
56239462Sdim  const llvm::APSInt &Val = TemplArg.getAsIntegral();
57218893Sdim
58280031Sdim  if (const EnumType *ET = T->getAs<EnumType>()) {
59280031Sdim    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
60280031Sdim      // In Sema::CheckTemplateArugment, enum template arguments value are
61280031Sdim      // extended to the size of the integer underlying the enum type.  This
62280031Sdim      // may create a size difference between the enum value and template
63280031Sdim      // argument value, requiring isSameValue here instead of operator==.
64280031Sdim      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
65280031Sdim        ECD->printQualifiedName(Out, Policy);
66280031Sdim        return;
67280031Sdim      }
68280031Sdim    }
69280031Sdim  }
70280031Sdim
71296417Sdim  if (T->isBooleanType() && !Policy.MSVCFormatting) {
72239462Sdim    Out << (Val.getBoolValue() ? "true" : "false");
73218893Sdim  } else if (T->isCharType()) {
74239462Sdim    const char Ch = Val.getZExtValue();
75219077Sdim    Out << ((Ch == '\'') ? "'\\" : "'");
76234353Sdim    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
77219077Sdim    Out << "'";
78218893Sdim  } else {
79239462Sdim    Out << Val;
80218893Sdim  }
81218893Sdim}
82218893Sdim
83198893Srdivacky//===----------------------------------------------------------------------===//
84198893Srdivacky// TemplateArgument Implementation
85198893Srdivacky//===----------------------------------------------------------------------===//
86198893Srdivacky
87239462SdimTemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
88261991Sdim                                   QualType Type) {
89261991Sdim  Integer.Kind = Integral;
90239462Sdim  // Copy the APSInt value into our decomposed form.
91239462Sdim  Integer.BitWidth = Value.getBitWidth();
92239462Sdim  Integer.IsUnsigned = Value.isUnsigned();
93239462Sdim  // If the value is large, we have to get additional memory from the ASTContext
94239462Sdim  unsigned NumWords = Value.getNumWords();
95239462Sdim  if (NumWords > 1) {
96239462Sdim    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
97239462Sdim    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
98239462Sdim    Integer.pVal = static_cast<uint64_t *>(Mem);
99239462Sdim  } else {
100239462Sdim    Integer.VAL = Value.getZExtValue();
101239462Sdim  }
102239462Sdim
103239462Sdim  Integer.Type = Type.getAsOpaquePtr();
104239462Sdim}
105239462Sdim
106296417SdimTemplateArgument
107296417SdimTemplateArgument::CreatePackCopy(ASTContext &Context,
108296417Sdim                                 ArrayRef<TemplateArgument> Args) {
109296417Sdim  if (Args.empty())
110243830Sdim    return getEmptyPack();
111296417Sdim
112296417Sdim  return TemplateArgument(Args.copy(Context));
113218893Sdim}
114198893Srdivacky
115218893Sdimbool TemplateArgument::isDependent() const {
116218893Sdim  switch (getKind()) {
117218893Sdim  case Null:
118226633Sdim    llvm_unreachable("Should not have a NULL template argument");
119218893Sdim
120218893Sdim  case Type:
121280031Sdim    return getAsType()->isDependentType() ||
122280031Sdim           isa<PackExpansionType>(getAsType());
123218893Sdim
124218893Sdim  case Template:
125218893Sdim    return getAsTemplate().isDependent();
126218893Sdim
127218893Sdim  case TemplateExpansion:
128218893Sdim    return true;
129218893Sdim
130218893Sdim  case Declaration:
131243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
132243830Sdim      return DC->isDependentContext();
133243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
134243830Sdim
135243830Sdim  case NullPtr:
136234353Sdim    return false;
137218893Sdim
138218893Sdim  case Integral:
139218893Sdim    // Never dependent
140218893Sdim    return false;
141218893Sdim
142218893Sdim  case Expression:
143280031Sdim    return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
144280031Sdim            isa<PackExpansionExpr>(getAsExpr()));
145218893Sdim
146218893Sdim  case Pack:
147276479Sdim    for (const auto &P : pack_elements())
148276479Sdim      if (P.isDependent())
149218893Sdim        return true;
150218893Sdim    return false;
151198893Srdivacky  }
152198893Srdivacky
153234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
154198893Srdivacky}
155198893Srdivacky
156224145Sdimbool TemplateArgument::isInstantiationDependent() const {
157224145Sdim  switch (getKind()) {
158224145Sdim  case Null:
159226633Sdim    llvm_unreachable("Should not have a NULL template argument");
160341825Sdim
161224145Sdim  case Type:
162224145Sdim    return getAsType()->isInstantiationDependentType();
163341825Sdim
164224145Sdim  case Template:
165224145Sdim    return getAsTemplate().isInstantiationDependent();
166341825Sdim
167224145Sdim  case TemplateExpansion:
168224145Sdim    return true;
169341825Sdim
170224145Sdim  case Declaration:
171243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
172243830Sdim      return DC->isDependentContext();
173243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
174243830Sdim
175243830Sdim  case NullPtr:
176234353Sdim    return false;
177341825Sdim
178224145Sdim  case Integral:
179224145Sdim    // Never dependent
180224145Sdim    return false;
181341825Sdim
182224145Sdim  case Expression:
183224145Sdim    return getAsExpr()->isInstantiationDependent();
184341825Sdim
185224145Sdim  case Pack:
186276479Sdim    for (const auto &P : pack_elements())
187276479Sdim      if (P.isInstantiationDependent())
188224145Sdim        return true;
189224145Sdim    return false;
190224145Sdim  }
191234353Sdim
192234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
193224145Sdim}
194224145Sdim
195218893Sdimbool TemplateArgument::isPackExpansion() const {
196218893Sdim  switch (getKind()) {
197218893Sdim  case Null:
198218893Sdim  case Declaration:
199218893Sdim  case Integral:
200341825Sdim  case Pack:
201218893Sdim  case Template:
202243830Sdim  case NullPtr:
203218893Sdim    return false;
204341825Sdim
205218893Sdim  case TemplateExpansion:
206218893Sdim    return true;
207341825Sdim
208218893Sdim  case Type:
209218893Sdim    return isa<PackExpansionType>(getAsType());
210341825Sdim
211218893Sdim  case Expression:
212218893Sdim    return isa<PackExpansionExpr>(getAsExpr());
213218893Sdim  }
214234353Sdim
215234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
216218893Sdim}
217218893Sdim
218218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const {
219218893Sdim  switch (getKind()) {
220218893Sdim  case Null:
221218893Sdim  case Declaration:
222218893Sdim  case Integral:
223218893Sdim  case TemplateExpansion:
224243830Sdim  case NullPtr:
225218893Sdim    break;
226218893Sdim
227218893Sdim  case Type:
228218893Sdim    if (getAsType()->containsUnexpandedParameterPack())
229218893Sdim      return true;
230218893Sdim    break;
231218893Sdim
232218893Sdim  case Template:
233218893Sdim    if (getAsTemplate().containsUnexpandedParameterPack())
234218893Sdim      return true;
235218893Sdim    break;
236341825Sdim
237218893Sdim  case Expression:
238218893Sdim    if (getAsExpr()->containsUnexpandedParameterPack())
239218893Sdim      return true;
240218893Sdim    break;
241218893Sdim
242218893Sdim  case Pack:
243276479Sdim    for (const auto &P : pack_elements())
244276479Sdim      if (P.containsUnexpandedParameterPack())
245218893Sdim        return true;
246218893Sdim
247218893Sdim    break;
248218893Sdim  }
249218893Sdim
250218893Sdim  return false;
251218893Sdim}
252218893Sdim
253249423SdimOptional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
254261991Sdim  assert(getKind() == TemplateExpansion);
255218893Sdim  if (TemplateArg.NumExpansions)
256218893Sdim    return TemplateArg.NumExpansions - 1;
257341825Sdim
258341825Sdim  return None;
259218893Sdim}
260218893Sdim
261314564SdimQualType TemplateArgument::getNonTypeTemplateArgumentType() const {
262314564Sdim  switch (getKind()) {
263314564Sdim  case TemplateArgument::Null:
264314564Sdim  case TemplateArgument::Type:
265314564Sdim  case TemplateArgument::Template:
266314564Sdim  case TemplateArgument::TemplateExpansion:
267314564Sdim  case TemplateArgument::Pack:
268314564Sdim    return QualType();
269314564Sdim
270314564Sdim  case TemplateArgument::Integral:
271314564Sdim    return getIntegralType();
272314564Sdim
273314564Sdim  case TemplateArgument::Expression:
274314564Sdim    return getAsExpr()->getType();
275314564Sdim
276314564Sdim  case TemplateArgument::Declaration:
277314564Sdim    return getParamTypeForDecl();
278314564Sdim
279314564Sdim  case TemplateArgument::NullPtr:
280314564Sdim    return getNullPtrType();
281314564Sdim  }
282314564Sdim
283314564Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
284314564Sdim}
285314564Sdim
286198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
287218893Sdim                               const ASTContext &Context) const {
288261991Sdim  ID.AddInteger(getKind());
289261991Sdim  switch (getKind()) {
290198893Srdivacky  case Null:
291198893Srdivacky    break;
292198893Srdivacky
293198893Srdivacky  case Type:
294198893Srdivacky    getAsType().Profile(ID);
295198893Srdivacky    break;
296198893Srdivacky
297261991Sdim  case NullPtr:
298261991Sdim    getNullPtrType().Profile(ID);
299261991Sdim    break;
300261991Sdim
301198893Srdivacky  case Declaration:
302276479Sdim    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
303198893Srdivacky    break;
304198893Srdivacky
305199482Srdivacky  case Template:
306218893Sdim  case TemplateExpansion: {
307218893Sdim    TemplateName Template = getAsTemplateOrTemplatePattern();
308199990Srdivacky    if (TemplateTemplateParmDecl *TTP
309199990Srdivacky          = dyn_cast_or_null<TemplateTemplateParmDecl>(
310218893Sdim                                                Template.getAsTemplateDecl())) {
311199990Srdivacky      ID.AddBoolean(true);
312199990Srdivacky      ID.AddInteger(TTP->getDepth());
313199990Srdivacky      ID.AddInteger(TTP->getPosition());
314218893Sdim      ID.AddBoolean(TTP->isParameterPack());
315199990Srdivacky    } else {
316199990Srdivacky      ID.AddBoolean(false);
317218893Sdim      ID.AddPointer(Context.getCanonicalTemplateName(Template)
318218893Sdim                                                          .getAsVoidPointer());
319199990Srdivacky    }
320199482Srdivacky    break;
321218893Sdim  }
322341825Sdim
323198893Srdivacky  case Integral:
324239462Sdim    getAsIntegral().Profile(ID);
325198893Srdivacky    getIntegralType().Profile(ID);
326198893Srdivacky    break;
327198893Srdivacky
328198893Srdivacky  case Expression:
329198893Srdivacky    getAsExpr()->Profile(ID, Context, true);
330198893Srdivacky    break;
331198893Srdivacky
332198893Srdivacky  case Pack:
333198893Srdivacky    ID.AddInteger(Args.NumArgs);
334198893Srdivacky    for (unsigned I = 0; I != Args.NumArgs; ++I)
335198893Srdivacky      Args.Args[I].Profile(ID, Context);
336198893Srdivacky  }
337198893Srdivacky}
338198893Srdivacky
339210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
340210299Sed  if (getKind() != Other.getKind()) return false;
341210299Sed
342210299Sed  switch (getKind()) {
343210299Sed  case Null:
344210299Sed  case Type:
345341825Sdim  case Expression:
346210299Sed  case Template:
347218893Sdim  case TemplateExpansion:
348243830Sdim  case NullPtr:
349261991Sdim    return TypeOrValue.V == Other.TypeOrValue.V;
350210299Sed
351243830Sdim  case Declaration:
352280031Sdim    return getAsDecl() == Other.getAsDecl();
353243830Sdim
354210299Sed  case Integral:
355210299Sed    return getIntegralType() == Other.getIntegralType() &&
356239462Sdim           getAsIntegral() == Other.getAsIntegral();
357210299Sed
358210299Sed  case Pack:
359210299Sed    if (Args.NumArgs != Other.Args.NumArgs) return false;
360210299Sed    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
361210299Sed      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
362210299Sed        return false;
363210299Sed    return true;
364210299Sed  }
365210299Sed
366234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
367210299Sed}
368210299Sed
369218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const {
370218893Sdim  assert(isPackExpansion());
371341825Sdim
372218893Sdim  switch (getKind()) {
373218893Sdim  case Type:
374218893Sdim    return getAsType()->getAs<PackExpansionType>()->getPattern();
375341825Sdim
376218893Sdim  case Expression:
377218893Sdim    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
378341825Sdim
379218893Sdim  case TemplateExpansion:
380218893Sdim    return TemplateArgument(getAsTemplateOrTemplatePattern());
381243830Sdim
382218893Sdim  case Declaration:
383218893Sdim  case Integral:
384218893Sdim  case Pack:
385218893Sdim  case Null:
386218893Sdim  case Template:
387243830Sdim  case NullPtr:
388218893Sdim    return TemplateArgument();
389218893Sdim  }
390234353Sdim
391234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
392218893Sdim}
393218893Sdim
394341825Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy,
395226633Sdim                             raw_ostream &Out) const {
396218893Sdim  switch (getKind()) {
397218893Sdim  case Null:
398276479Sdim    Out << "(no value)";
399218893Sdim    break;
400341825Sdim
401218893Sdim  case Type: {
402224145Sdim    PrintingPolicy SubPolicy(Policy);
403224145Sdim    SubPolicy.SuppressStrongLifetime = true;
404249423Sdim    getAsType().print(Out, SubPolicy);
405218893Sdim    break;
406218893Sdim  }
407341825Sdim
408218893Sdim  case Declaration: {
409341825Sdim    NamedDecl *ND = getAsDecl();
410261991Sdim    Out << '&';
411243830Sdim    if (ND->getDeclName()) {
412243830Sdim      // FIXME: distinguish between pointer and reference args?
413261991Sdim      ND->printQualifiedName(Out);
414234353Sdim    } else {
415276479Sdim      Out << "(anonymous)";
416218893Sdim    }
417218893Sdim    break;
418218893Sdim  }
419243830Sdim
420243830Sdim  case NullPtr:
421243830Sdim    Out << "nullptr";
422243830Sdim    break;
423243830Sdim
424218893Sdim  case Template:
425218893Sdim    getAsTemplate().print(Out, Policy);
426218893Sdim    break;
427218893Sdim
428218893Sdim  case TemplateExpansion:
429218893Sdim    getAsTemplateOrTemplatePattern().print(Out, Policy);
430218893Sdim    Out << "...";
431218893Sdim    break;
432341825Sdim
433327952Sdim  case Integral:
434280031Sdim    printIntegral(*this, Out, Policy);
435218893Sdim    break;
436341825Sdim
437218893Sdim  case Expression:
438276479Sdim    getAsExpr()->printPretty(Out, nullptr, Policy);
439218893Sdim    break;
440341825Sdim
441218893Sdim  case Pack:
442218893Sdim    Out << "<";
443218893Sdim    bool First = true;
444276479Sdim    for (const auto &P : pack_elements()) {
445218893Sdim      if (First)
446218893Sdim        First = false;
447218893Sdim      else
448218893Sdim        Out << ", ";
449341825Sdim
450276479Sdim      P.print(Policy, Out);
451218893Sdim    }
452218893Sdim    Out << ">";
453341825Sdim    break;
454218893Sdim  }
455218893Sdim}
456218893Sdim
457309124Sdimvoid TemplateArgument::dump(raw_ostream &Out) const {
458309124Sdim  LangOptions LO; // FIXME! see also TemplateName::dump().
459309124Sdim  LO.CPlusPlus = true;
460309124Sdim  LO.Bool = true;
461309124Sdim  print(PrintingPolicy(LO), Out);
462309124Sdim}
463309124Sdim
464309124SdimLLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
465309124Sdim
466198893Srdivacky//===----------------------------------------------------------------------===//
467198893Srdivacky// TemplateArgumentLoc Implementation
468198893Srdivacky//===----------------------------------------------------------------------===//
469198893Srdivacky
470198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const {
471198893Srdivacky  switch (Argument.getKind()) {
472198893Srdivacky  case TemplateArgument::Expression:
473198893Srdivacky    return getSourceExpression()->getSourceRange();
474212904Sdim
475198893Srdivacky  case TemplateArgument::Declaration:
476198893Srdivacky    return getSourceDeclExpression()->getSourceRange();
477212904Sdim
478243830Sdim  case TemplateArgument::NullPtr:
479243830Sdim    return getSourceNullPtrExpression()->getSourceRange();
480243830Sdim
481198893Srdivacky  case TemplateArgument::Type:
482212904Sdim    if (TypeSourceInfo *TSI = getTypeSourceInfo())
483212904Sdim      return TSI->getTypeLoc().getSourceRange();
484212904Sdim    else
485212904Sdim      return SourceRange();
486212904Sdim
487199482Srdivacky  case TemplateArgument::Template:
488221345Sdim    if (getTemplateQualifierLoc())
489341825Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
490199482Srdivacky                         getTemplateNameLoc());
491199482Srdivacky    return SourceRange(getTemplateNameLoc());
492212904Sdim
493218893Sdim  case TemplateArgument::TemplateExpansion:
494221345Sdim    if (getTemplateQualifierLoc())
495341825Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
496218893Sdim                         getTemplateEllipsisLoc());
497218893Sdim    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
498218893Sdim
499198893Srdivacky  case TemplateArgument::Integral:
500243830Sdim    return getSourceIntegralExpression()->getSourceRange();
501243830Sdim
502198893Srdivacky  case TemplateArgument::Pack:
503198893Srdivacky  case TemplateArgument::Null:
504198893Srdivacky    return SourceRange();
505198893Srdivacky  }
506198893Srdivacky
507234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
508198893Srdivacky}
509208600Srdivacky
510208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
511208600Srdivacky                                           const TemplateArgument &Arg) {
512208600Srdivacky  switch (Arg.getKind()) {
513208600Srdivacky  case TemplateArgument::Null:
514212904Sdim    // This is bad, but not as bad as crashing because of argument
515212904Sdim    // count mismatches.
516212904Sdim    return DB << "(null template argument)";
517341825Sdim
518208600Srdivacky  case TemplateArgument::Type:
519208600Srdivacky    return DB << Arg.getAsType();
520341825Sdim
521208600Srdivacky  case TemplateArgument::Declaration:
522243830Sdim    return DB << Arg.getAsDecl();
523243830Sdim
524243830Sdim  case TemplateArgument::NullPtr:
525234353Sdim    return DB << "nullptr";
526341825Sdim
527208600Srdivacky  case TemplateArgument::Integral:
528239462Sdim    return DB << Arg.getAsIntegral().toString(10);
529341825Sdim
530208600Srdivacky  case TemplateArgument::Template:
531208600Srdivacky    return DB << Arg.getAsTemplate();
532218893Sdim
533218893Sdim  case TemplateArgument::TemplateExpansion:
534218893Sdim    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
535218893Sdim
536208600Srdivacky  case TemplateArgument::Expression: {
537208600Srdivacky    // This shouldn't actually ever happen, so it's okay that we're
538208600Srdivacky    // regurgitating an expression here.
539208600Srdivacky    // FIXME: We're guessing at LangOptions!
540234353Sdim    SmallString<32> Str;
541208600Srdivacky    llvm::raw_svector_ostream OS(Str);
542208600Srdivacky    LangOptions LangOpts;
543208600Srdivacky    LangOpts.CPlusPlus = true;
544208600Srdivacky    PrintingPolicy Policy(LangOpts);
545276479Sdim    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
546208600Srdivacky    return DB << OS.str();
547208600Srdivacky  }
548341825Sdim
549218893Sdim  case TemplateArgument::Pack: {
550218893Sdim    // FIXME: We're guessing at LangOptions!
551234353Sdim    SmallString<32> Str;
552218893Sdim    llvm::raw_svector_ostream OS(Str);
553218893Sdim    LangOptions LangOpts;
554218893Sdim    LangOpts.CPlusPlus = true;
555218893Sdim    PrintingPolicy Policy(LangOpts);
556218893Sdim    Arg.print(Policy, OS);
557218893Sdim    return DB << OS.str();
558208600Srdivacky  }
559218893Sdim  }
560234353Sdim
561234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
562208600Srdivacky}
563226633Sdim
564226633Sdimconst ASTTemplateArgumentListInfo *
565226633SdimASTTemplateArgumentListInfo::Create(ASTContext &C,
566226633Sdim                                    const TemplateArgumentListInfo &List) {
567296417Sdim  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
568314564Sdim  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
569296417Sdim  return new (Mem) ASTTemplateArgumentListInfo(List);
570226633Sdim}
571226633Sdim
572296417SdimASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
573296417Sdim    const TemplateArgumentListInfo &Info) {
574226633Sdim  LAngleLoc = Info.getLAngleLoc();
575226633Sdim  RAngleLoc = Info.getRAngleLoc();
576226633Sdim  NumTemplateArgs = Info.size();
577226633Sdim
578296417Sdim  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
579226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
580226633Sdim    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
581226633Sdim}
582226633Sdim
583296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
584296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
585296417Sdim    TemplateArgumentLoc *OutArgArray) {
586296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
587226633Sdim  LAngleLoc = Info.getLAngleLoc();
588226633Sdim  RAngleLoc = Info.getRAngleLoc();
589226633Sdim  NumTemplateArgs = Info.size();
590226633Sdim
591296417Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
592296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
593296417Sdim}
594296417Sdim
595296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
596296417Sdim  assert(TemplateKWLoc.isValid());
597296417Sdim  LAngleLoc = SourceLocation();
598296417Sdim  RAngleLoc = SourceLocation();
599296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
600296417Sdim  NumTemplateArgs = 0;
601296417Sdim}
602296417Sdim
603296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
604296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
605296417Sdim    TemplateArgumentLoc *OutArgArray, bool &Dependent,
606296417Sdim    bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
607296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
608296417Sdim  LAngleLoc = Info.getLAngleLoc();
609296417Sdim  RAngleLoc = Info.getRAngleLoc();
610296417Sdim  NumTemplateArgs = Info.size();
611296417Sdim
612226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
613226633Sdim    Dependent = Dependent || Info[i].getArgument().isDependent();
614296417Sdim    InstantiationDependent = InstantiationDependent ||
615226633Sdim                             Info[i].getArgument().isInstantiationDependent();
616296417Sdim    ContainsUnexpandedParameterPack =
617296417Sdim        ContainsUnexpandedParameterPack ||
618226633Sdim        Info[i].getArgument().containsUnexpandedParameterPack();
619226633Sdim
620296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
621226633Sdim  }
622226633Sdim}
623226633Sdim
624296417Sdimvoid ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
625296417Sdim                                        TemplateArgumentListInfo &Info) const {
626226633Sdim  Info.setLAngleLoc(LAngleLoc);
627226633Sdim  Info.setRAngleLoc(RAngleLoc);
628226633Sdim  for (unsigned I = 0; I != NumTemplateArgs; ++I)
629296417Sdim    Info.addArgument(ArgArray[I]);
630226633Sdim}
631