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