TemplateBase.cpp revision 314564
1198893Srdivacky//===--- 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"
17198893Srdivacky#include "clang/AST/DeclBase.h"
18199990Srdivacky#include "clang/AST/DeclTemplate.h"
19198893Srdivacky#include "clang/AST/Expr.h"
20218893Sdim#include "clang/AST/ExprCXX.h"
21218893Sdim#include "clang/AST/Type.h"
22198893Srdivacky#include "clang/AST/TypeLoc.h"
23208600Srdivacky#include "clang/Basic/Diagnostic.h"
24218893Sdim#include "llvm/ADT/FoldingSet.h"
25234353Sdim#include "llvm/ADT/SmallString.h"
26249423Sdim#include "llvm/Support/raw_ostream.h"
27218893Sdim#include <algorithm>
28198893Srdivacky
29198893Srdivackyusing namespace clang;
30198893Srdivacky
31218893Sdim/// \brief Print a template integral argument value.
32218893Sdim///
33218893Sdim/// \param TemplArg the TemplateArgument instance to print.
34218893Sdim///
35218893Sdim/// \param Out the raw_ostream instance to use for printing.
36280031Sdim///
37280031Sdim/// \param Policy the printing policy for EnumConstantDecl printing.
38218893Sdimstatic void printIntegral(const TemplateArgument &TemplArg,
39280031Sdim                          raw_ostream &Out, const PrintingPolicy& Policy) {
40218893Sdim  const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
41239462Sdim  const llvm::APSInt &Val = TemplArg.getAsIntegral();
42218893Sdim
43280031Sdim  if (const EnumType *ET = T->getAs<EnumType>()) {
44280031Sdim    for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
45280031Sdim      // In Sema::CheckTemplateArugment, enum template arguments value are
46280031Sdim      // extended to the size of the integer underlying the enum type.  This
47280031Sdim      // may create a size difference between the enum value and template
48280031Sdim      // argument value, requiring isSameValue here instead of operator==.
49280031Sdim      if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
50280031Sdim        ECD->printQualifiedName(Out, Policy);
51280031Sdim        return;
52280031Sdim      }
53280031Sdim    }
54280031Sdim  }
55280031Sdim
56296417Sdim  if (T->isBooleanType() && !Policy.MSVCFormatting) {
57239462Sdim    Out << (Val.getBoolValue() ? "true" : "false");
58218893Sdim  } else if (T->isCharType()) {
59239462Sdim    const char Ch = Val.getZExtValue();
60219077Sdim    Out << ((Ch == '\'') ? "'\\" : "'");
61234353Sdim    Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
62219077Sdim    Out << "'";
63218893Sdim  } else {
64239462Sdim    Out << Val;
65218893Sdim  }
66218893Sdim}
67218893Sdim
68198893Srdivacky//===----------------------------------------------------------------------===//
69198893Srdivacky// TemplateArgument Implementation
70198893Srdivacky//===----------------------------------------------------------------------===//
71198893Srdivacky
72239462SdimTemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value,
73261991Sdim                                   QualType Type) {
74261991Sdim  Integer.Kind = Integral;
75239462Sdim  // Copy the APSInt value into our decomposed form.
76239462Sdim  Integer.BitWidth = Value.getBitWidth();
77239462Sdim  Integer.IsUnsigned = Value.isUnsigned();
78239462Sdim  // If the value is large, we have to get additional memory from the ASTContext
79239462Sdim  unsigned NumWords = Value.getNumWords();
80239462Sdim  if (NumWords > 1) {
81239462Sdim    void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t));
82239462Sdim    std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t));
83239462Sdim    Integer.pVal = static_cast<uint64_t *>(Mem);
84239462Sdim  } else {
85239462Sdim    Integer.VAL = Value.getZExtValue();
86239462Sdim  }
87239462Sdim
88239462Sdim  Integer.Type = Type.getAsOpaquePtr();
89239462Sdim}
90239462Sdim
91296417SdimTemplateArgument
92296417SdimTemplateArgument::CreatePackCopy(ASTContext &Context,
93296417Sdim                                 ArrayRef<TemplateArgument> Args) {
94296417Sdim  if (Args.empty())
95243830Sdim    return getEmptyPack();
96296417Sdim
97296417Sdim  return TemplateArgument(Args.copy(Context));
98218893Sdim}
99198893Srdivacky
100218893Sdimbool TemplateArgument::isDependent() const {
101218893Sdim  switch (getKind()) {
102218893Sdim  case Null:
103226633Sdim    llvm_unreachable("Should not have a NULL template argument");
104218893Sdim
105218893Sdim  case Type:
106280031Sdim    return getAsType()->isDependentType() ||
107280031Sdim           isa<PackExpansionType>(getAsType());
108218893Sdim
109218893Sdim  case Template:
110218893Sdim    return getAsTemplate().isDependent();
111218893Sdim
112218893Sdim  case TemplateExpansion:
113218893Sdim    return true;
114218893Sdim
115218893Sdim  case Declaration:
116243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
117243830Sdim      return DC->isDependentContext();
118243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
119243830Sdim
120243830Sdim  case NullPtr:
121234353Sdim    return false;
122218893Sdim
123218893Sdim  case Integral:
124218893Sdim    // Never dependent
125218893Sdim    return false;
126218893Sdim
127218893Sdim  case Expression:
128280031Sdim    return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() ||
129280031Sdim            isa<PackExpansionExpr>(getAsExpr()));
130218893Sdim
131218893Sdim  case Pack:
132276479Sdim    for (const auto &P : pack_elements())
133276479Sdim      if (P.isDependent())
134218893Sdim        return true;
135218893Sdim    return false;
136198893Srdivacky  }
137198893Srdivacky
138234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
139198893Srdivacky}
140198893Srdivacky
141224145Sdimbool TemplateArgument::isInstantiationDependent() const {
142224145Sdim  switch (getKind()) {
143224145Sdim  case Null:
144226633Sdim    llvm_unreachable("Should not have a NULL template argument");
145224145Sdim
146224145Sdim  case Type:
147224145Sdim    return getAsType()->isInstantiationDependentType();
148224145Sdim
149224145Sdim  case Template:
150224145Sdim    return getAsTemplate().isInstantiationDependent();
151224145Sdim
152224145Sdim  case TemplateExpansion:
153224145Sdim    return true;
154224145Sdim
155224145Sdim  case Declaration:
156243830Sdim    if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
157243830Sdim      return DC->isDependentContext();
158243830Sdim    return getAsDecl()->getDeclContext()->isDependentContext();
159243830Sdim
160243830Sdim  case NullPtr:
161234353Sdim    return false;
162234353Sdim
163224145Sdim  case Integral:
164224145Sdim    // Never dependent
165224145Sdim    return false;
166224145Sdim
167224145Sdim  case Expression:
168224145Sdim    return getAsExpr()->isInstantiationDependent();
169224145Sdim
170224145Sdim  case Pack:
171276479Sdim    for (const auto &P : pack_elements())
172276479Sdim      if (P.isInstantiationDependent())
173224145Sdim        return true;
174224145Sdim    return false;
175224145Sdim  }
176234353Sdim
177234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
178224145Sdim}
179224145Sdim
180218893Sdimbool TemplateArgument::isPackExpansion() const {
181218893Sdim  switch (getKind()) {
182218893Sdim  case Null:
183218893Sdim  case Declaration:
184218893Sdim  case Integral:
185218893Sdim  case Pack:
186218893Sdim  case Template:
187243830Sdim  case NullPtr:
188218893Sdim    return false;
189218893Sdim
190218893Sdim  case TemplateExpansion:
191218893Sdim    return true;
192218893Sdim
193218893Sdim  case Type:
194218893Sdim    return isa<PackExpansionType>(getAsType());
195218893Sdim
196218893Sdim  case Expression:
197218893Sdim    return isa<PackExpansionExpr>(getAsExpr());
198218893Sdim  }
199234353Sdim
200234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
201218893Sdim}
202218893Sdim
203218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const {
204218893Sdim  switch (getKind()) {
205218893Sdim  case Null:
206218893Sdim  case Declaration:
207218893Sdim  case Integral:
208218893Sdim  case TemplateExpansion:
209243830Sdim  case NullPtr:
210218893Sdim    break;
211218893Sdim
212218893Sdim  case Type:
213218893Sdim    if (getAsType()->containsUnexpandedParameterPack())
214218893Sdim      return true;
215218893Sdim    break;
216218893Sdim
217218893Sdim  case Template:
218218893Sdim    if (getAsTemplate().containsUnexpandedParameterPack())
219218893Sdim      return true;
220218893Sdim    break;
221218893Sdim
222218893Sdim  case Expression:
223218893Sdim    if (getAsExpr()->containsUnexpandedParameterPack())
224218893Sdim      return true;
225218893Sdim    break;
226218893Sdim
227218893Sdim  case Pack:
228276479Sdim    for (const auto &P : pack_elements())
229276479Sdim      if (P.containsUnexpandedParameterPack())
230218893Sdim        return true;
231218893Sdim
232218893Sdim    break;
233218893Sdim  }
234218893Sdim
235218893Sdim  return false;
236218893Sdim}
237218893Sdim
238249423SdimOptional<unsigned> TemplateArgument::getNumTemplateExpansions() const {
239261991Sdim  assert(getKind() == TemplateExpansion);
240218893Sdim  if (TemplateArg.NumExpansions)
241218893Sdim    return TemplateArg.NumExpansions - 1;
242218893Sdim
243249423Sdim  return None;
244218893Sdim}
245218893Sdim
246314564SdimQualType TemplateArgument::getNonTypeTemplateArgumentType() const {
247314564Sdim  switch (getKind()) {
248314564Sdim  case TemplateArgument::Null:
249314564Sdim  case TemplateArgument::Type:
250314564Sdim  case TemplateArgument::Template:
251314564Sdim  case TemplateArgument::TemplateExpansion:
252314564Sdim  case TemplateArgument::Pack:
253314564Sdim    return QualType();
254314564Sdim
255314564Sdim  case TemplateArgument::Integral:
256314564Sdim    return getIntegralType();
257314564Sdim
258314564Sdim  case TemplateArgument::Expression:
259314564Sdim    return getAsExpr()->getType();
260314564Sdim
261314564Sdim  case TemplateArgument::Declaration:
262314564Sdim    return getParamTypeForDecl();
263314564Sdim
264314564Sdim  case TemplateArgument::NullPtr:
265314564Sdim    return getNullPtrType();
266314564Sdim  }
267314564Sdim
268314564Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
269314564Sdim}
270314564Sdim
271198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID,
272218893Sdim                               const ASTContext &Context) const {
273261991Sdim  ID.AddInteger(getKind());
274261991Sdim  switch (getKind()) {
275198893Srdivacky  case Null:
276198893Srdivacky    break;
277198893Srdivacky
278198893Srdivacky  case Type:
279198893Srdivacky    getAsType().Profile(ID);
280198893Srdivacky    break;
281198893Srdivacky
282261991Sdim  case NullPtr:
283261991Sdim    getNullPtrType().Profile(ID);
284261991Sdim    break;
285261991Sdim
286198893Srdivacky  case Declaration:
287276479Sdim    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
288198893Srdivacky    break;
289198893Srdivacky
290199482Srdivacky  case Template:
291218893Sdim  case TemplateExpansion: {
292218893Sdim    TemplateName Template = getAsTemplateOrTemplatePattern();
293199990Srdivacky    if (TemplateTemplateParmDecl *TTP
294199990Srdivacky          = dyn_cast_or_null<TemplateTemplateParmDecl>(
295218893Sdim                                                Template.getAsTemplateDecl())) {
296199990Srdivacky      ID.AddBoolean(true);
297199990Srdivacky      ID.AddInteger(TTP->getDepth());
298199990Srdivacky      ID.AddInteger(TTP->getPosition());
299218893Sdim      ID.AddBoolean(TTP->isParameterPack());
300199990Srdivacky    } else {
301199990Srdivacky      ID.AddBoolean(false);
302218893Sdim      ID.AddPointer(Context.getCanonicalTemplateName(Template)
303218893Sdim                                                          .getAsVoidPointer());
304199990Srdivacky    }
305199482Srdivacky    break;
306218893Sdim  }
307199482Srdivacky
308198893Srdivacky  case Integral:
309239462Sdim    getAsIntegral().Profile(ID);
310198893Srdivacky    getIntegralType().Profile(ID);
311198893Srdivacky    break;
312198893Srdivacky
313198893Srdivacky  case Expression:
314198893Srdivacky    getAsExpr()->Profile(ID, Context, true);
315198893Srdivacky    break;
316198893Srdivacky
317198893Srdivacky  case Pack:
318198893Srdivacky    ID.AddInteger(Args.NumArgs);
319198893Srdivacky    for (unsigned I = 0; I != Args.NumArgs; ++I)
320198893Srdivacky      Args.Args[I].Profile(ID, Context);
321198893Srdivacky  }
322198893Srdivacky}
323198893Srdivacky
324210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
325210299Sed  if (getKind() != Other.getKind()) return false;
326210299Sed
327210299Sed  switch (getKind()) {
328210299Sed  case Null:
329210299Sed  case Type:
330218893Sdim  case Expression:
331210299Sed  case Template:
332218893Sdim  case TemplateExpansion:
333243830Sdim  case NullPtr:
334261991Sdim    return TypeOrValue.V == Other.TypeOrValue.V;
335210299Sed
336243830Sdim  case Declaration:
337280031Sdim    return getAsDecl() == Other.getAsDecl();
338243830Sdim
339210299Sed  case Integral:
340210299Sed    return getIntegralType() == Other.getIntegralType() &&
341239462Sdim           getAsIntegral() == Other.getAsIntegral();
342210299Sed
343210299Sed  case Pack:
344210299Sed    if (Args.NumArgs != Other.Args.NumArgs) return false;
345210299Sed    for (unsigned I = 0, E = Args.NumArgs; I != E; ++I)
346210299Sed      if (!Args.Args[I].structurallyEquals(Other.Args.Args[I]))
347210299Sed        return false;
348210299Sed    return true;
349210299Sed  }
350210299Sed
351234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
352210299Sed}
353210299Sed
354218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const {
355218893Sdim  assert(isPackExpansion());
356218893Sdim
357218893Sdim  switch (getKind()) {
358218893Sdim  case Type:
359218893Sdim    return getAsType()->getAs<PackExpansionType>()->getPattern();
360218893Sdim
361218893Sdim  case Expression:
362218893Sdim    return cast<PackExpansionExpr>(getAsExpr())->getPattern();
363218893Sdim
364218893Sdim  case TemplateExpansion:
365218893Sdim    return TemplateArgument(getAsTemplateOrTemplatePattern());
366243830Sdim
367218893Sdim  case Declaration:
368218893Sdim  case Integral:
369218893Sdim  case Pack:
370218893Sdim  case Null:
371218893Sdim  case Template:
372243830Sdim  case NullPtr:
373218893Sdim    return TemplateArgument();
374218893Sdim  }
375234353Sdim
376234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
377218893Sdim}
378218893Sdim
379218893Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy,
380226633Sdim                             raw_ostream &Out) const {
381218893Sdim  switch (getKind()) {
382218893Sdim  case Null:
383276479Sdim    Out << "(no value)";
384218893Sdim    break;
385218893Sdim
386218893Sdim  case Type: {
387224145Sdim    PrintingPolicy SubPolicy(Policy);
388224145Sdim    SubPolicy.SuppressStrongLifetime = true;
389249423Sdim    getAsType().print(Out, SubPolicy);
390218893Sdim    break;
391218893Sdim  }
392218893Sdim
393218893Sdim  case Declaration: {
394243830Sdim    NamedDecl *ND = cast<NamedDecl>(getAsDecl());
395261991Sdim    Out << '&';
396243830Sdim    if (ND->getDeclName()) {
397243830Sdim      // FIXME: distinguish between pointer and reference args?
398261991Sdim      ND->printQualifiedName(Out);
399234353Sdim    } else {
400276479Sdim      Out << "(anonymous)";
401218893Sdim    }
402218893Sdim    break;
403218893Sdim  }
404243830Sdim
405243830Sdim  case NullPtr:
406243830Sdim    Out << "nullptr";
407243830Sdim    break;
408243830Sdim
409218893Sdim  case Template:
410218893Sdim    getAsTemplate().print(Out, Policy);
411218893Sdim    break;
412218893Sdim
413218893Sdim  case TemplateExpansion:
414218893Sdim    getAsTemplateOrTemplatePattern().print(Out, Policy);
415218893Sdim    Out << "...";
416218893Sdim    break;
417218893Sdim
418218893Sdim  case Integral: {
419280031Sdim    printIntegral(*this, Out, Policy);
420218893Sdim    break;
421218893Sdim  }
422218893Sdim
423218893Sdim  case Expression:
424276479Sdim    getAsExpr()->printPretty(Out, nullptr, Policy);
425218893Sdim    break;
426218893Sdim
427218893Sdim  case Pack:
428218893Sdim    Out << "<";
429218893Sdim    bool First = true;
430276479Sdim    for (const auto &P : pack_elements()) {
431218893Sdim      if (First)
432218893Sdim        First = false;
433218893Sdim      else
434218893Sdim        Out << ", ";
435218893Sdim
436276479Sdim      P.print(Policy, Out);
437218893Sdim    }
438218893Sdim    Out << ">";
439218893Sdim    break;
440218893Sdim  }
441218893Sdim}
442218893Sdim
443309124Sdimvoid TemplateArgument::dump(raw_ostream &Out) const {
444309124Sdim  LangOptions LO; // FIXME! see also TemplateName::dump().
445309124Sdim  LO.CPlusPlus = true;
446309124Sdim  LO.Bool = true;
447309124Sdim  print(PrintingPolicy(LO), Out);
448309124Sdim}
449309124Sdim
450309124SdimLLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); }
451309124Sdim
452198893Srdivacky//===----------------------------------------------------------------------===//
453198893Srdivacky// TemplateArgumentLoc Implementation
454198893Srdivacky//===----------------------------------------------------------------------===//
455198893Srdivacky
456218893SdimTemplateArgumentLocInfo::TemplateArgumentLocInfo() {
457221345Sdim  memset((void*)this, 0, sizeof(TemplateArgumentLocInfo));
458218893Sdim}
459218893Sdim
460198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const {
461198893Srdivacky  switch (Argument.getKind()) {
462198893Srdivacky  case TemplateArgument::Expression:
463198893Srdivacky    return getSourceExpression()->getSourceRange();
464212904Sdim
465198893Srdivacky  case TemplateArgument::Declaration:
466198893Srdivacky    return getSourceDeclExpression()->getSourceRange();
467212904Sdim
468243830Sdim  case TemplateArgument::NullPtr:
469243830Sdim    return getSourceNullPtrExpression()->getSourceRange();
470243830Sdim
471198893Srdivacky  case TemplateArgument::Type:
472212904Sdim    if (TypeSourceInfo *TSI = getTypeSourceInfo())
473212904Sdim      return TSI->getTypeLoc().getSourceRange();
474212904Sdim    else
475212904Sdim      return SourceRange();
476212904Sdim
477199482Srdivacky  case TemplateArgument::Template:
478221345Sdim    if (getTemplateQualifierLoc())
479221345Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
480199482Srdivacky                         getTemplateNameLoc());
481199482Srdivacky    return SourceRange(getTemplateNameLoc());
482212904Sdim
483218893Sdim  case TemplateArgument::TemplateExpansion:
484221345Sdim    if (getTemplateQualifierLoc())
485221345Sdim      return SourceRange(getTemplateQualifierLoc().getBeginLoc(),
486218893Sdim                         getTemplateEllipsisLoc());
487218893Sdim    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
488218893Sdim
489198893Srdivacky  case TemplateArgument::Integral:
490243830Sdim    return getSourceIntegralExpression()->getSourceRange();
491243830Sdim
492198893Srdivacky  case TemplateArgument::Pack:
493198893Srdivacky  case TemplateArgument::Null:
494198893Srdivacky    return SourceRange();
495198893Srdivacky  }
496198893Srdivacky
497234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
498198893Srdivacky}
499208600Srdivacky
500208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
501208600Srdivacky                                           const TemplateArgument &Arg) {
502208600Srdivacky  switch (Arg.getKind()) {
503208600Srdivacky  case TemplateArgument::Null:
504212904Sdim    // This is bad, but not as bad as crashing because of argument
505212904Sdim    // count mismatches.
506212904Sdim    return DB << "(null template argument)";
507208600Srdivacky
508208600Srdivacky  case TemplateArgument::Type:
509208600Srdivacky    return DB << Arg.getAsType();
510208600Srdivacky
511208600Srdivacky  case TemplateArgument::Declaration:
512243830Sdim    return DB << Arg.getAsDecl();
513243830Sdim
514243830Sdim  case TemplateArgument::NullPtr:
515234353Sdim    return DB << "nullptr";
516208600Srdivacky
517208600Srdivacky  case TemplateArgument::Integral:
518239462Sdim    return DB << Arg.getAsIntegral().toString(10);
519208600Srdivacky
520208600Srdivacky  case TemplateArgument::Template:
521208600Srdivacky    return DB << Arg.getAsTemplate();
522218893Sdim
523218893Sdim  case TemplateArgument::TemplateExpansion:
524218893Sdim    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
525218893Sdim
526208600Srdivacky  case TemplateArgument::Expression: {
527208600Srdivacky    // This shouldn't actually ever happen, so it's okay that we're
528208600Srdivacky    // regurgitating an expression here.
529208600Srdivacky    // FIXME: We're guessing at LangOptions!
530234353Sdim    SmallString<32> Str;
531208600Srdivacky    llvm::raw_svector_ostream OS(Str);
532208600Srdivacky    LangOptions LangOpts;
533208600Srdivacky    LangOpts.CPlusPlus = true;
534208600Srdivacky    PrintingPolicy Policy(LangOpts);
535276479Sdim    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
536208600Srdivacky    return DB << OS.str();
537208600Srdivacky  }
538208600Srdivacky
539218893Sdim  case TemplateArgument::Pack: {
540218893Sdim    // FIXME: We're guessing at LangOptions!
541234353Sdim    SmallString<32> Str;
542218893Sdim    llvm::raw_svector_ostream OS(Str);
543218893Sdim    LangOptions LangOpts;
544218893Sdim    LangOpts.CPlusPlus = true;
545218893Sdim    PrintingPolicy Policy(LangOpts);
546218893Sdim    Arg.print(Policy, OS);
547218893Sdim    return DB << OS.str();
548208600Srdivacky  }
549218893Sdim  }
550234353Sdim
551234353Sdim  llvm_unreachable("Invalid TemplateArgument Kind!");
552208600Srdivacky}
553226633Sdim
554226633Sdimconst ASTTemplateArgumentListInfo *
555226633SdimASTTemplateArgumentListInfo::Create(ASTContext &C,
556226633Sdim                                    const TemplateArgumentListInfo &List) {
557296417Sdim  std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size());
558314564Sdim  void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
559296417Sdim  return new (Mem) ASTTemplateArgumentListInfo(List);
560226633Sdim}
561226633Sdim
562296417SdimASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
563296417Sdim    const TemplateArgumentListInfo &Info) {
564226633Sdim  LAngleLoc = Info.getLAngleLoc();
565226633Sdim  RAngleLoc = Info.getRAngleLoc();
566226633Sdim  NumTemplateArgs = Info.size();
567226633Sdim
568296417Sdim  TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
569226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
570226633Sdim    new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
571226633Sdim}
572226633Sdim
573296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
574296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
575296417Sdim    TemplateArgumentLoc *OutArgArray) {
576296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
577226633Sdim  LAngleLoc = Info.getLAngleLoc();
578226633Sdim  RAngleLoc = Info.getRAngleLoc();
579226633Sdim  NumTemplateArgs = Info.size();
580226633Sdim
581296417Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i)
582296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
583296417Sdim}
584296417Sdim
585296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) {
586296417Sdim  assert(TemplateKWLoc.isValid());
587296417Sdim  LAngleLoc = SourceLocation();
588296417Sdim  RAngleLoc = SourceLocation();
589296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
590296417Sdim  NumTemplateArgs = 0;
591296417Sdim}
592296417Sdim
593296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(
594296417Sdim    SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
595296417Sdim    TemplateArgumentLoc *OutArgArray, bool &Dependent,
596296417Sdim    bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) {
597296417Sdim  this->TemplateKWLoc = TemplateKWLoc;
598296417Sdim  LAngleLoc = Info.getLAngleLoc();
599296417Sdim  RAngleLoc = Info.getRAngleLoc();
600296417Sdim  NumTemplateArgs = Info.size();
601296417Sdim
602226633Sdim  for (unsigned i = 0; i != NumTemplateArgs; ++i) {
603226633Sdim    Dependent = Dependent || Info[i].getArgument().isDependent();
604296417Sdim    InstantiationDependent = InstantiationDependent ||
605226633Sdim                             Info[i].getArgument().isInstantiationDependent();
606296417Sdim    ContainsUnexpandedParameterPack =
607296417Sdim        ContainsUnexpandedParameterPack ||
608226633Sdim        Info[i].getArgument().containsUnexpandedParameterPack();
609226633Sdim
610296417Sdim    new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]);
611226633Sdim  }
612226633Sdim}
613226633Sdim
614296417Sdimvoid ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray,
615296417Sdim                                        TemplateArgumentListInfo &Info) const {
616226633Sdim  Info.setLAngleLoc(LAngleLoc);
617226633Sdim  Info.setRAngleLoc(RAngleLoc);
618226633Sdim  for (unsigned I = 0; I != NumTemplateArgs; ++I)
619296417Sdim    Info.addArgument(ArgArray[I]);
620226633Sdim}
621