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" 25235633Sdim#include "llvm/ADT/SmallString.h" 26252723Sdim#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. 36218893Sdimstatic void printIntegral(const TemplateArgument &TemplArg, 37226890Sdim raw_ostream &Out) { 38218893Sdim const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr(); 39245431Sdim const llvm::APSInt &Val = TemplArg.getAsIntegral(); 40218893Sdim 41218893Sdim if (T->isBooleanType()) { 42245431Sdim Out << (Val.getBoolValue() ? "true" : "false"); 43218893Sdim } else if (T->isCharType()) { 44245431Sdim const char Ch = Val.getZExtValue(); 45219077Sdim Out << ((Ch == '\'') ? "'\\" : "'"); 46235633Sdim Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); 47219077Sdim Out << "'"; 48218893Sdim } else { 49245431Sdim Out << Val; 50218893Sdim } 51218893Sdim} 52218893Sdim 53198893Srdivacky//===----------------------------------------------------------------------===// 54198893Srdivacky// TemplateArgument Implementation 55198893Srdivacky//===----------------------------------------------------------------------===// 56198893Srdivacky 57245431SdimTemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, 58263509Sdim QualType Type) { 59263509Sdim Integer.Kind = Integral; 60245431Sdim // Copy the APSInt value into our decomposed form. 61245431Sdim Integer.BitWidth = Value.getBitWidth(); 62245431Sdim Integer.IsUnsigned = Value.isUnsigned(); 63245431Sdim // If the value is large, we have to get additional memory from the ASTContext 64245431Sdim unsigned NumWords = Value.getNumWords(); 65245431Sdim if (NumWords > 1) { 66245431Sdim void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); 67245431Sdim std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); 68245431Sdim Integer.pVal = static_cast<uint64_t *>(Mem); 69245431Sdim } else { 70245431Sdim Integer.VAL = Value.getZExtValue(); 71245431Sdim } 72245431Sdim 73245431Sdim Integer.Type = Type.getAsOpaquePtr(); 74245431Sdim} 75245431Sdim 76218893SdimTemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, 77218893Sdim const TemplateArgument *Args, 78218893Sdim unsigned NumArgs) { 79218893Sdim if (NumArgs == 0) 80245431Sdim return getEmptyPack(); 81218893Sdim 82218893Sdim TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs]; 83218893Sdim std::copy(Args, Args + NumArgs, Storage); 84218893Sdim return TemplateArgument(Storage, NumArgs); 85218893Sdim} 86198893Srdivacky 87218893Sdimbool TemplateArgument::isDependent() const { 88218893Sdim switch (getKind()) { 89218893Sdim case Null: 90226890Sdim llvm_unreachable("Should not have a NULL template argument"); 91218893Sdim 92218893Sdim case Type: 93218893Sdim return getAsType()->isDependentType(); 94218893Sdim 95218893Sdim case Template: 96218893Sdim return getAsTemplate().isDependent(); 97218893Sdim 98218893Sdim case TemplateExpansion: 99218893Sdim return true; 100218893Sdim 101218893Sdim case Declaration: 102245431Sdim if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 103245431Sdim return DC->isDependentContext(); 104245431Sdim return getAsDecl()->getDeclContext()->isDependentContext(); 105245431Sdim 106245431Sdim case NullPtr: 107235633Sdim return false; 108218893Sdim 109218893Sdim case Integral: 110218893Sdim // Never dependent 111218893Sdim return false; 112218893Sdim 113218893Sdim case Expression: 114218893Sdim return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent()); 115218893Sdim 116218893Sdim case Pack: 117218893Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 118218893Sdim if (P->isDependent()) 119218893Sdim return true; 120218893Sdim } 121218893Sdim 122218893Sdim return false; 123198893Srdivacky } 124198893Srdivacky 125235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 126198893Srdivacky} 127198893Srdivacky 128224145Sdimbool TemplateArgument::isInstantiationDependent() const { 129224145Sdim switch (getKind()) { 130224145Sdim case Null: 131226890Sdim llvm_unreachable("Should not have a NULL template argument"); 132224145Sdim 133224145Sdim case Type: 134224145Sdim return getAsType()->isInstantiationDependentType(); 135224145Sdim 136224145Sdim case Template: 137224145Sdim return getAsTemplate().isInstantiationDependent(); 138224145Sdim 139224145Sdim case TemplateExpansion: 140224145Sdim return true; 141224145Sdim 142224145Sdim case Declaration: 143245431Sdim if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 144245431Sdim return DC->isDependentContext(); 145245431Sdim return getAsDecl()->getDeclContext()->isDependentContext(); 146245431Sdim 147245431Sdim case NullPtr: 148235633Sdim return false; 149235633Sdim 150224145Sdim case Integral: 151224145Sdim // Never dependent 152224145Sdim return false; 153224145Sdim 154224145Sdim case Expression: 155224145Sdim return getAsExpr()->isInstantiationDependent(); 156224145Sdim 157224145Sdim case Pack: 158224145Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 159224145Sdim if (P->isInstantiationDependent()) 160224145Sdim return true; 161224145Sdim } 162224145Sdim 163224145Sdim return false; 164224145Sdim } 165235633Sdim 166235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 167224145Sdim} 168224145Sdim 169218893Sdimbool TemplateArgument::isPackExpansion() const { 170218893Sdim switch (getKind()) { 171218893Sdim case Null: 172218893Sdim case Declaration: 173218893Sdim case Integral: 174218893Sdim case Pack: 175218893Sdim case Template: 176245431Sdim case NullPtr: 177218893Sdim return false; 178218893Sdim 179218893Sdim case TemplateExpansion: 180218893Sdim return true; 181218893Sdim 182218893Sdim case Type: 183218893Sdim return isa<PackExpansionType>(getAsType()); 184218893Sdim 185218893Sdim case Expression: 186218893Sdim return isa<PackExpansionExpr>(getAsExpr()); 187218893Sdim } 188235633Sdim 189235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 190218893Sdim} 191218893Sdim 192218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const { 193218893Sdim switch (getKind()) { 194218893Sdim case Null: 195218893Sdim case Declaration: 196218893Sdim case Integral: 197218893Sdim case TemplateExpansion: 198245431Sdim case NullPtr: 199218893Sdim break; 200218893Sdim 201218893Sdim case Type: 202218893Sdim if (getAsType()->containsUnexpandedParameterPack()) 203218893Sdim return true; 204218893Sdim break; 205218893Sdim 206218893Sdim case Template: 207218893Sdim if (getAsTemplate().containsUnexpandedParameterPack()) 208218893Sdim return true; 209218893Sdim break; 210218893Sdim 211218893Sdim case Expression: 212218893Sdim if (getAsExpr()->containsUnexpandedParameterPack()) 213218893Sdim return true; 214218893Sdim break; 215218893Sdim 216218893Sdim case Pack: 217218893Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) 218218893Sdim if (P->containsUnexpandedParameterPack()) 219218893Sdim return true; 220218893Sdim 221218893Sdim break; 222218893Sdim } 223218893Sdim 224218893Sdim return false; 225218893Sdim} 226218893Sdim 227252723SdimOptional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 228263509Sdim assert(getKind() == TemplateExpansion); 229218893Sdim if (TemplateArg.NumExpansions) 230218893Sdim return TemplateArg.NumExpansions - 1; 231218893Sdim 232252723Sdim return None; 233218893Sdim} 234218893Sdim 235198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 236218893Sdim const ASTContext &Context) const { 237263509Sdim ID.AddInteger(getKind()); 238263509Sdim switch (getKind()) { 239198893Srdivacky case Null: 240198893Srdivacky break; 241198893Srdivacky 242198893Srdivacky case Type: 243198893Srdivacky getAsType().Profile(ID); 244198893Srdivacky break; 245198893Srdivacky 246263509Sdim case NullPtr: 247263509Sdim getNullPtrType().Profile(ID); 248263509Sdim break; 249263509Sdim 250198893Srdivacky case Declaration: 251198893Srdivacky ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0); 252198893Srdivacky break; 253198893Srdivacky 254199482Srdivacky case Template: 255218893Sdim case TemplateExpansion: { 256218893Sdim TemplateName Template = getAsTemplateOrTemplatePattern(); 257199990Srdivacky if (TemplateTemplateParmDecl *TTP 258199990Srdivacky = dyn_cast_or_null<TemplateTemplateParmDecl>( 259218893Sdim Template.getAsTemplateDecl())) { 260199990Srdivacky ID.AddBoolean(true); 261199990Srdivacky ID.AddInteger(TTP->getDepth()); 262199990Srdivacky ID.AddInteger(TTP->getPosition()); 263218893Sdim ID.AddBoolean(TTP->isParameterPack()); 264199990Srdivacky } else { 265199990Srdivacky ID.AddBoolean(false); 266218893Sdim ID.AddPointer(Context.getCanonicalTemplateName(Template) 267218893Sdim .getAsVoidPointer()); 268199990Srdivacky } 269199482Srdivacky break; 270218893Sdim } 271199482Srdivacky 272198893Srdivacky case Integral: 273245431Sdim getAsIntegral().Profile(ID); 274198893Srdivacky getIntegralType().Profile(ID); 275198893Srdivacky break; 276198893Srdivacky 277198893Srdivacky case Expression: 278198893Srdivacky getAsExpr()->Profile(ID, Context, true); 279198893Srdivacky break; 280198893Srdivacky 281198893Srdivacky case Pack: 282198893Srdivacky ID.AddInteger(Args.NumArgs); 283198893Srdivacky for (unsigned I = 0; I != Args.NumArgs; ++I) 284198893Srdivacky Args.Args[I].Profile(ID, Context); 285198893Srdivacky } 286198893Srdivacky} 287198893Srdivacky 288210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 289210299Sed if (getKind() != Other.getKind()) return false; 290210299Sed 291210299Sed switch (getKind()) { 292210299Sed case Null: 293210299Sed case Type: 294218893Sdim case Expression: 295210299Sed case Template: 296218893Sdim case TemplateExpansion: 297245431Sdim case NullPtr: 298263509Sdim return TypeOrValue.V == Other.TypeOrValue.V; 299210299Sed 300245431Sdim case Declaration: 301245431Sdim return getAsDecl() == Other.getAsDecl() && 302245431Sdim isDeclForReferenceParam() && Other.isDeclForReferenceParam(); 303245431Sdim 304210299Sed case Integral: 305210299Sed return getIntegralType() == Other.getIntegralType() && 306245431Sdim getAsIntegral() == Other.getAsIntegral(); 307210299Sed 308210299Sed case Pack: 309210299Sed if (Args.NumArgs != Other.Args.NumArgs) return false; 310210299Sed for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 311210299Sed if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 312210299Sed return false; 313210299Sed return true; 314210299Sed } 315210299Sed 316235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 317210299Sed} 318210299Sed 319218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const { 320218893Sdim assert(isPackExpansion()); 321218893Sdim 322218893Sdim switch (getKind()) { 323218893Sdim case Type: 324218893Sdim return getAsType()->getAs<PackExpansionType>()->getPattern(); 325218893Sdim 326218893Sdim case Expression: 327218893Sdim return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 328218893Sdim 329218893Sdim case TemplateExpansion: 330218893Sdim return TemplateArgument(getAsTemplateOrTemplatePattern()); 331245431Sdim 332218893Sdim case Declaration: 333218893Sdim case Integral: 334218893Sdim case Pack: 335218893Sdim case Null: 336218893Sdim case Template: 337245431Sdim case NullPtr: 338218893Sdim return TemplateArgument(); 339218893Sdim } 340235633Sdim 341235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 342218893Sdim} 343218893Sdim 344218893Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy, 345226890Sdim raw_ostream &Out) const { 346218893Sdim switch (getKind()) { 347218893Sdim case Null: 348218893Sdim Out << "<no value>"; 349218893Sdim break; 350218893Sdim 351218893Sdim case Type: { 352224145Sdim PrintingPolicy SubPolicy(Policy); 353224145Sdim SubPolicy.SuppressStrongLifetime = true; 354252723Sdim getAsType().print(Out, SubPolicy); 355218893Sdim break; 356218893Sdim } 357218893Sdim 358218893Sdim case Declaration: { 359245431Sdim NamedDecl *ND = cast<NamedDecl>(getAsDecl()); 360263509Sdim Out << '&'; 361245431Sdim if (ND->getDeclName()) { 362245431Sdim // FIXME: distinguish between pointer and reference args? 363263509Sdim ND->printQualifiedName(Out); 364235633Sdim } else { 365245431Sdim Out << "<anonymous>"; 366218893Sdim } 367218893Sdim break; 368218893Sdim } 369245431Sdim 370245431Sdim case NullPtr: 371245431Sdim Out << "nullptr"; 372245431Sdim break; 373245431Sdim 374218893Sdim case Template: 375218893Sdim getAsTemplate().print(Out, Policy); 376218893Sdim break; 377218893Sdim 378218893Sdim case TemplateExpansion: 379218893Sdim getAsTemplateOrTemplatePattern().print(Out, Policy); 380218893Sdim Out << "..."; 381218893Sdim break; 382218893Sdim 383218893Sdim case Integral: { 384218893Sdim printIntegral(*this, Out); 385218893Sdim break; 386218893Sdim } 387218893Sdim 388218893Sdim case Expression: 389218893Sdim getAsExpr()->printPretty(Out, 0, Policy); 390218893Sdim break; 391218893Sdim 392218893Sdim case Pack: 393218893Sdim Out << "<"; 394218893Sdim bool First = true; 395218893Sdim for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end(); 396218893Sdim P != PEnd; ++P) { 397218893Sdim if (First) 398218893Sdim First = false; 399218893Sdim else 400218893Sdim Out << ", "; 401218893Sdim 402218893Sdim P->print(Policy, Out); 403218893Sdim } 404218893Sdim Out << ">"; 405218893Sdim break; 406218893Sdim } 407218893Sdim} 408218893Sdim 409198893Srdivacky//===----------------------------------------------------------------------===// 410198893Srdivacky// TemplateArgumentLoc Implementation 411198893Srdivacky//===----------------------------------------------------------------------===// 412198893Srdivacky 413218893SdimTemplateArgumentLocInfo::TemplateArgumentLocInfo() { 414221345Sdim memset((void*)this, 0, sizeof(TemplateArgumentLocInfo)); 415218893Sdim} 416218893Sdim 417198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const { 418198893Srdivacky switch (Argument.getKind()) { 419198893Srdivacky case TemplateArgument::Expression: 420198893Srdivacky return getSourceExpression()->getSourceRange(); 421212904Sdim 422198893Srdivacky case TemplateArgument::Declaration: 423198893Srdivacky return getSourceDeclExpression()->getSourceRange(); 424212904Sdim 425245431Sdim case TemplateArgument::NullPtr: 426245431Sdim return getSourceNullPtrExpression()->getSourceRange(); 427245431Sdim 428198893Srdivacky case TemplateArgument::Type: 429212904Sdim if (TypeSourceInfo *TSI = getTypeSourceInfo()) 430212904Sdim return TSI->getTypeLoc().getSourceRange(); 431212904Sdim else 432212904Sdim return SourceRange(); 433212904Sdim 434199482Srdivacky case TemplateArgument::Template: 435221345Sdim if (getTemplateQualifierLoc()) 436221345Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 437199482Srdivacky getTemplateNameLoc()); 438199482Srdivacky return SourceRange(getTemplateNameLoc()); 439212904Sdim 440218893Sdim case TemplateArgument::TemplateExpansion: 441221345Sdim if (getTemplateQualifierLoc()) 442221345Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 443218893Sdim getTemplateEllipsisLoc()); 444218893Sdim return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 445218893Sdim 446198893Srdivacky case TemplateArgument::Integral: 447245431Sdim return getSourceIntegralExpression()->getSourceRange(); 448245431Sdim 449198893Srdivacky case TemplateArgument::Pack: 450198893Srdivacky case TemplateArgument::Null: 451198893Srdivacky return SourceRange(); 452198893Srdivacky } 453198893Srdivacky 454235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 455198893Srdivacky} 456208600Srdivacky 457208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 458208600Srdivacky const TemplateArgument &Arg) { 459208600Srdivacky switch (Arg.getKind()) { 460208600Srdivacky case TemplateArgument::Null: 461212904Sdim // This is bad, but not as bad as crashing because of argument 462212904Sdim // count mismatches. 463212904Sdim return DB << "(null template argument)"; 464208600Srdivacky 465208600Srdivacky case TemplateArgument::Type: 466208600Srdivacky return DB << Arg.getAsType(); 467208600Srdivacky 468208600Srdivacky case TemplateArgument::Declaration: 469245431Sdim return DB << Arg.getAsDecl(); 470245431Sdim 471245431Sdim case TemplateArgument::NullPtr: 472235633Sdim return DB << "nullptr"; 473208600Srdivacky 474208600Srdivacky case TemplateArgument::Integral: 475245431Sdim return DB << Arg.getAsIntegral().toString(10); 476208600Srdivacky 477208600Srdivacky case TemplateArgument::Template: 478208600Srdivacky return DB << Arg.getAsTemplate(); 479218893Sdim 480218893Sdim case TemplateArgument::TemplateExpansion: 481218893Sdim return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 482218893Sdim 483208600Srdivacky case TemplateArgument::Expression: { 484208600Srdivacky // This shouldn't actually ever happen, so it's okay that we're 485208600Srdivacky // regurgitating an expression here. 486208600Srdivacky // FIXME: We're guessing at LangOptions! 487235633Sdim SmallString<32> Str; 488208600Srdivacky llvm::raw_svector_ostream OS(Str); 489208600Srdivacky LangOptions LangOpts; 490208600Srdivacky LangOpts.CPlusPlus = true; 491208600Srdivacky PrintingPolicy Policy(LangOpts); 492208600Srdivacky Arg.getAsExpr()->printPretty(OS, 0, Policy); 493208600Srdivacky return DB << OS.str(); 494208600Srdivacky } 495208600Srdivacky 496218893Sdim case TemplateArgument::Pack: { 497218893Sdim // FIXME: We're guessing at LangOptions! 498235633Sdim SmallString<32> Str; 499218893Sdim llvm::raw_svector_ostream OS(Str); 500218893Sdim LangOptions LangOpts; 501218893Sdim LangOpts.CPlusPlus = true; 502218893Sdim PrintingPolicy Policy(LangOpts); 503218893Sdim Arg.print(Policy, OS); 504218893Sdim return DB << OS.str(); 505208600Srdivacky } 506218893Sdim } 507235633Sdim 508235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 509208600Srdivacky} 510226890Sdim 511226890Sdimconst ASTTemplateArgumentListInfo * 512226890SdimASTTemplateArgumentListInfo::Create(ASTContext &C, 513226890Sdim const TemplateArgumentListInfo &List) { 514245431Sdim std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size()); 515226890Sdim void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>()); 516226890Sdim ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo(); 517226890Sdim TAI->initializeFrom(List); 518226890Sdim return TAI; 519226890Sdim} 520226890Sdim 521226890Sdimvoid ASTTemplateArgumentListInfo::initializeFrom( 522226890Sdim const TemplateArgumentListInfo &Info) { 523226890Sdim LAngleLoc = Info.getLAngleLoc(); 524226890Sdim RAngleLoc = Info.getRAngleLoc(); 525226890Sdim NumTemplateArgs = Info.size(); 526226890Sdim 527226890Sdim TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 528226890Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) 529226890Sdim new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 530226890Sdim} 531226890Sdim 532226890Sdimvoid ASTTemplateArgumentListInfo::initializeFrom( 533226890Sdim const TemplateArgumentListInfo &Info, 534226890Sdim bool &Dependent, 535226890Sdim bool &InstantiationDependent, 536226890Sdim bool &ContainsUnexpandedParameterPack) { 537226890Sdim LAngleLoc = Info.getLAngleLoc(); 538226890Sdim RAngleLoc = Info.getRAngleLoc(); 539226890Sdim NumTemplateArgs = Info.size(); 540226890Sdim 541226890Sdim TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 542226890Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) { 543226890Sdim Dependent = Dependent || Info[i].getArgument().isDependent(); 544226890Sdim InstantiationDependent = InstantiationDependent || 545226890Sdim Info[i].getArgument().isInstantiationDependent(); 546226890Sdim ContainsUnexpandedParameterPack 547226890Sdim = ContainsUnexpandedParameterPack || 548226890Sdim Info[i].getArgument().containsUnexpandedParameterPack(); 549226890Sdim 550226890Sdim new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 551226890Sdim } 552226890Sdim} 553226890Sdim 554226890Sdimvoid ASTTemplateArgumentListInfo::copyInto( 555226890Sdim TemplateArgumentListInfo &Info) const { 556226890Sdim Info.setLAngleLoc(LAngleLoc); 557226890Sdim Info.setRAngleLoc(RAngleLoc); 558226890Sdim for (unsigned I = 0; I != NumTemplateArgs; ++I) 559226890Sdim Info.addArgument(getTemplateArgs()[I]); 560226890Sdim} 561226890Sdim 562226890Sdimstd::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) { 563226890Sdim return sizeof(ASTTemplateArgumentListInfo) + 564226890Sdim sizeof(TemplateArgumentLoc) * NumTemplateArgs; 565226890Sdim} 566226890Sdim 567235633Sdimvoid 568235633SdimASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc, 569235633Sdim const TemplateArgumentListInfo &Info) { 570235633Sdim Base::initializeFrom(Info); 571235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 572226890Sdim} 573235633Sdim 574235633Sdimvoid 575235633SdimASTTemplateKWAndArgsInfo 576235633Sdim::initializeFrom(SourceLocation TemplateKWLoc, 577235633Sdim const TemplateArgumentListInfo &Info, 578235633Sdim bool &Dependent, 579235633Sdim bool &InstantiationDependent, 580235633Sdim bool &ContainsUnexpandedParameterPack) { 581235633Sdim Base::initializeFrom(Info, Dependent, InstantiationDependent, 582235633Sdim ContainsUnexpandedParameterPack); 583235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 584235633Sdim} 585235633Sdim 586235633Sdimvoid 587235633SdimASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 588235633Sdim // No explicit template arguments, but template keyword loc is valid. 589235633Sdim assert(TemplateKWLoc.isValid()); 590235633Sdim LAngleLoc = SourceLocation(); 591235633Sdim RAngleLoc = SourceLocation(); 592235633Sdim NumTemplateArgs = 0; 593235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 594235633Sdim} 595235633Sdim 596235633Sdimstd::size_t 597235633SdimASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) { 598235633Sdim // Add space for the template keyword location. 599245431Sdim // FIXME: There's room for this in the padding before the template args in 600245431Sdim // 64-bit builds. 601235633Sdim return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation); 602235633Sdim} 603