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