TemplateBase.cpp revision 235633
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" 26218893Sdim#include <algorithm> 27218893Sdim#include <cctype> 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(); 39218893Sdim const llvm::APSInt *Val = TemplArg.getAsIntegral(); 40218893Sdim 41218893Sdim if (T->isBooleanType()) { 42218893Sdim Out << (Val->getBoolValue() ? "true" : "false"); 43218893Sdim } else if (T->isCharType()) { 44235633Sdim const char Ch = Val->getZExtValue(); 45219077Sdim Out << ((Ch == '\'') ? "'\\" : "'"); 46235633Sdim Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); 47219077Sdim Out << "'"; 48218893Sdim } else { 49218893Sdim Out << Val->toString(10); 50218893Sdim } 51218893Sdim} 52218893Sdim 53198893Srdivacky//===----------------------------------------------------------------------===// 54198893Srdivacky// TemplateArgument Implementation 55198893Srdivacky//===----------------------------------------------------------------------===// 56198893Srdivacky 57218893SdimTemplateArgument TemplateArgument::CreatePackCopy(ASTContext &Context, 58218893Sdim const TemplateArgument *Args, 59218893Sdim unsigned NumArgs) { 60218893Sdim if (NumArgs == 0) 61218893Sdim return TemplateArgument(0, 0); 62218893Sdim 63218893Sdim TemplateArgument *Storage = new (Context) TemplateArgument [NumArgs]; 64218893Sdim std::copy(Args, Args + NumArgs, Storage); 65218893Sdim return TemplateArgument(Storage, NumArgs); 66218893Sdim} 67198893Srdivacky 68218893Sdimbool TemplateArgument::isDependent() const { 69218893Sdim switch (getKind()) { 70218893Sdim case Null: 71226890Sdim llvm_unreachable("Should not have a NULL template argument"); 72218893Sdim 73218893Sdim case Type: 74218893Sdim return getAsType()->isDependentType(); 75218893Sdim 76218893Sdim case Template: 77218893Sdim return getAsTemplate().isDependent(); 78218893Sdim 79218893Sdim case TemplateExpansion: 80218893Sdim return true; 81218893Sdim 82218893Sdim case Declaration: 83235633Sdim if (Decl *D = getAsDecl()) { 84235633Sdim if (DeclContext *DC = dyn_cast<DeclContext>(D)) 85235633Sdim return DC->isDependentContext(); 86235633Sdim return D->getDeclContext()->isDependentContext(); 87235633Sdim } 88235633Sdim 89235633Sdim return false; 90218893Sdim 91218893Sdim case Integral: 92218893Sdim // Never dependent 93218893Sdim return false; 94218893Sdim 95218893Sdim case Expression: 96218893Sdim return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent()); 97218893Sdim 98218893Sdim case Pack: 99218893Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 100218893Sdim if (P->isDependent()) 101218893Sdim return true; 102218893Sdim } 103218893Sdim 104218893Sdim return false; 105198893Srdivacky } 106198893Srdivacky 107235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 108198893Srdivacky} 109198893Srdivacky 110224145Sdimbool TemplateArgument::isInstantiationDependent() const { 111224145Sdim switch (getKind()) { 112224145Sdim case Null: 113226890Sdim llvm_unreachable("Should not have a NULL template argument"); 114224145Sdim 115224145Sdim case Type: 116224145Sdim return getAsType()->isInstantiationDependentType(); 117224145Sdim 118224145Sdim case Template: 119224145Sdim return getAsTemplate().isInstantiationDependent(); 120224145Sdim 121224145Sdim case TemplateExpansion: 122224145Sdim return true; 123224145Sdim 124224145Sdim case Declaration: 125235633Sdim if (Decl *D = getAsDecl()) { 126235633Sdim if (DeclContext *DC = dyn_cast<DeclContext>(D)) 127235633Sdim return DC->isDependentContext(); 128235633Sdim return D->getDeclContext()->isDependentContext(); 129235633Sdim } 130235633Sdim return false; 131235633Sdim 132224145Sdim case Integral: 133224145Sdim // Never dependent 134224145Sdim return false; 135224145Sdim 136224145Sdim case Expression: 137224145Sdim return getAsExpr()->isInstantiationDependent(); 138224145Sdim 139224145Sdim case Pack: 140224145Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { 141224145Sdim if (P->isInstantiationDependent()) 142224145Sdim return true; 143224145Sdim } 144224145Sdim 145224145Sdim return false; 146224145Sdim } 147235633Sdim 148235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 149224145Sdim} 150224145Sdim 151218893Sdimbool TemplateArgument::isPackExpansion() const { 152218893Sdim switch (getKind()) { 153218893Sdim case Null: 154218893Sdim case Declaration: 155218893Sdim case Integral: 156218893Sdim case Pack: 157218893Sdim case Template: 158218893Sdim return false; 159218893Sdim 160218893Sdim case TemplateExpansion: 161218893Sdim return true; 162218893Sdim 163218893Sdim case Type: 164218893Sdim return isa<PackExpansionType>(getAsType()); 165218893Sdim 166218893Sdim case Expression: 167218893Sdim return isa<PackExpansionExpr>(getAsExpr()); 168218893Sdim } 169235633Sdim 170235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 171218893Sdim} 172218893Sdim 173218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const { 174218893Sdim switch (getKind()) { 175218893Sdim case Null: 176218893Sdim case Declaration: 177218893Sdim case Integral: 178218893Sdim case TemplateExpansion: 179218893Sdim break; 180218893Sdim 181218893Sdim case Type: 182218893Sdim if (getAsType()->containsUnexpandedParameterPack()) 183218893Sdim return true; 184218893Sdim break; 185218893Sdim 186218893Sdim case Template: 187218893Sdim if (getAsTemplate().containsUnexpandedParameterPack()) 188218893Sdim return true; 189218893Sdim break; 190218893Sdim 191218893Sdim case Expression: 192218893Sdim if (getAsExpr()->containsUnexpandedParameterPack()) 193218893Sdim return true; 194218893Sdim break; 195218893Sdim 196218893Sdim case Pack: 197218893Sdim for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) 198218893Sdim if (P->containsUnexpandedParameterPack()) 199218893Sdim return true; 200218893Sdim 201218893Sdim break; 202218893Sdim } 203218893Sdim 204218893Sdim return false; 205218893Sdim} 206218893Sdim 207218893Sdimllvm::Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 208218893Sdim assert(Kind == TemplateExpansion); 209218893Sdim if (TemplateArg.NumExpansions) 210218893Sdim return TemplateArg.NumExpansions - 1; 211218893Sdim 212218893Sdim return llvm::Optional<unsigned>(); 213218893Sdim} 214218893Sdim 215198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 216218893Sdim const ASTContext &Context) const { 217198893Srdivacky ID.AddInteger(Kind); 218198893Srdivacky switch (Kind) { 219198893Srdivacky case Null: 220198893Srdivacky break; 221198893Srdivacky 222198893Srdivacky case Type: 223198893Srdivacky getAsType().Profile(ID); 224198893Srdivacky break; 225198893Srdivacky 226198893Srdivacky case Declaration: 227198893Srdivacky ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0); 228198893Srdivacky break; 229198893Srdivacky 230199482Srdivacky case Template: 231218893Sdim case TemplateExpansion: { 232218893Sdim TemplateName Template = getAsTemplateOrTemplatePattern(); 233199990Srdivacky if (TemplateTemplateParmDecl *TTP 234199990Srdivacky = dyn_cast_or_null<TemplateTemplateParmDecl>( 235218893Sdim Template.getAsTemplateDecl())) { 236199990Srdivacky ID.AddBoolean(true); 237199990Srdivacky ID.AddInteger(TTP->getDepth()); 238199990Srdivacky ID.AddInteger(TTP->getPosition()); 239218893Sdim ID.AddBoolean(TTP->isParameterPack()); 240199990Srdivacky } else { 241199990Srdivacky ID.AddBoolean(false); 242218893Sdim ID.AddPointer(Context.getCanonicalTemplateName(Template) 243218893Sdim .getAsVoidPointer()); 244199990Srdivacky } 245199482Srdivacky break; 246218893Sdim } 247199482Srdivacky 248198893Srdivacky case Integral: 249198893Srdivacky getAsIntegral()->Profile(ID); 250198893Srdivacky getIntegralType().Profile(ID); 251198893Srdivacky break; 252198893Srdivacky 253198893Srdivacky case Expression: 254198893Srdivacky getAsExpr()->Profile(ID, Context, true); 255198893Srdivacky break; 256198893Srdivacky 257198893Srdivacky case Pack: 258198893Srdivacky ID.AddInteger(Args.NumArgs); 259198893Srdivacky for (unsigned I = 0; I != Args.NumArgs; ++I) 260198893Srdivacky Args.Args[I].Profile(ID, Context); 261198893Srdivacky } 262198893Srdivacky} 263198893Srdivacky 264210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 265210299Sed if (getKind() != Other.getKind()) return false; 266210299Sed 267210299Sed switch (getKind()) { 268210299Sed case Null: 269210299Sed case Type: 270210299Sed case Declaration: 271218893Sdim case Expression: 272210299Sed case Template: 273218893Sdim case TemplateExpansion: 274210299Sed return TypeOrValue == Other.TypeOrValue; 275210299Sed 276210299Sed case Integral: 277210299Sed return getIntegralType() == Other.getIntegralType() && 278210299Sed *getAsIntegral() == *Other.getAsIntegral(); 279210299Sed 280210299Sed case Pack: 281210299Sed if (Args.NumArgs != Other.Args.NumArgs) return false; 282210299Sed for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 283210299Sed if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 284210299Sed return false; 285210299Sed return true; 286210299Sed } 287210299Sed 288235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 289210299Sed} 290210299Sed 291218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const { 292218893Sdim assert(isPackExpansion()); 293218893Sdim 294218893Sdim switch (getKind()) { 295218893Sdim case Type: 296218893Sdim return getAsType()->getAs<PackExpansionType>()->getPattern(); 297218893Sdim 298218893Sdim case Expression: 299218893Sdim return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 300218893Sdim 301218893Sdim case TemplateExpansion: 302218893Sdim return TemplateArgument(getAsTemplateOrTemplatePattern()); 303218893Sdim 304218893Sdim case Declaration: 305218893Sdim case Integral: 306218893Sdim case Pack: 307218893Sdim case Null: 308218893Sdim case Template: 309218893Sdim return TemplateArgument(); 310218893Sdim } 311235633Sdim 312235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 313218893Sdim} 314218893Sdim 315218893Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy, 316226890Sdim raw_ostream &Out) const { 317218893Sdim switch (getKind()) { 318218893Sdim case Null: 319218893Sdim Out << "<no value>"; 320218893Sdim break; 321218893Sdim 322218893Sdim case Type: { 323224145Sdim PrintingPolicy SubPolicy(Policy); 324224145Sdim SubPolicy.SuppressStrongLifetime = true; 325218893Sdim std::string TypeStr; 326224145Sdim getAsType().getAsStringInternal(TypeStr, SubPolicy); 327218893Sdim Out << TypeStr; 328218893Sdim break; 329218893Sdim } 330218893Sdim 331218893Sdim case Declaration: { 332218893Sdim if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getAsDecl())) { 333218893Sdim if (ND->getDeclName()) { 334235633Sdim Out << *ND; 335235633Sdim } else { 336235633Sdim Out << "<anonymous>"; 337218893Sdim } 338235633Sdim } else { 339235633Sdim Out << "nullptr"; 340218893Sdim } 341218893Sdim break; 342218893Sdim } 343218893Sdim 344218893Sdim case Template: 345218893Sdim getAsTemplate().print(Out, Policy); 346218893Sdim break; 347218893Sdim 348218893Sdim case TemplateExpansion: 349218893Sdim getAsTemplateOrTemplatePattern().print(Out, Policy); 350218893Sdim Out << "..."; 351218893Sdim break; 352218893Sdim 353218893Sdim case Integral: { 354218893Sdim printIntegral(*this, Out); 355218893Sdim break; 356218893Sdim } 357218893Sdim 358218893Sdim case Expression: 359218893Sdim getAsExpr()->printPretty(Out, 0, Policy); 360218893Sdim break; 361218893Sdim 362218893Sdim case Pack: 363218893Sdim Out << "<"; 364218893Sdim bool First = true; 365218893Sdim for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end(); 366218893Sdim P != PEnd; ++P) { 367218893Sdim if (First) 368218893Sdim First = false; 369218893Sdim else 370218893Sdim Out << ", "; 371218893Sdim 372218893Sdim P->print(Policy, Out); 373218893Sdim } 374218893Sdim Out << ">"; 375218893Sdim break; 376218893Sdim } 377218893Sdim} 378218893Sdim 379198893Srdivacky//===----------------------------------------------------------------------===// 380198893Srdivacky// TemplateArgumentLoc Implementation 381198893Srdivacky//===----------------------------------------------------------------------===// 382198893Srdivacky 383218893SdimTemplateArgumentLocInfo::TemplateArgumentLocInfo() { 384221345Sdim memset((void*)this, 0, sizeof(TemplateArgumentLocInfo)); 385218893Sdim} 386218893Sdim 387198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const { 388198893Srdivacky switch (Argument.getKind()) { 389198893Srdivacky case TemplateArgument::Expression: 390198893Srdivacky return getSourceExpression()->getSourceRange(); 391212904Sdim 392198893Srdivacky case TemplateArgument::Declaration: 393198893Srdivacky return getSourceDeclExpression()->getSourceRange(); 394212904Sdim 395198893Srdivacky case TemplateArgument::Type: 396212904Sdim if (TypeSourceInfo *TSI = getTypeSourceInfo()) 397212904Sdim return TSI->getTypeLoc().getSourceRange(); 398212904Sdim else 399212904Sdim return SourceRange(); 400212904Sdim 401199482Srdivacky case TemplateArgument::Template: 402221345Sdim if (getTemplateQualifierLoc()) 403221345Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 404199482Srdivacky getTemplateNameLoc()); 405199482Srdivacky return SourceRange(getTemplateNameLoc()); 406212904Sdim 407218893Sdim case TemplateArgument::TemplateExpansion: 408221345Sdim if (getTemplateQualifierLoc()) 409221345Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 410218893Sdim getTemplateEllipsisLoc()); 411218893Sdim return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 412218893Sdim 413198893Srdivacky case TemplateArgument::Integral: 414198893Srdivacky case TemplateArgument::Pack: 415198893Srdivacky case TemplateArgument::Null: 416198893Srdivacky return SourceRange(); 417198893Srdivacky } 418198893Srdivacky 419235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 420198893Srdivacky} 421208600Srdivacky 422218893SdimTemplateArgumentLoc 423218893SdimTemplateArgumentLoc::getPackExpansionPattern(SourceLocation &Ellipsis, 424218893Sdim llvm::Optional<unsigned> &NumExpansions, 425218893Sdim ASTContext &Context) const { 426218893Sdim assert(Argument.isPackExpansion()); 427218893Sdim 428218893Sdim switch (Argument.getKind()) { 429218893Sdim case TemplateArgument::Type: { 430218893Sdim // FIXME: We shouldn't ever have to worry about missing 431218893Sdim // type-source info! 432218893Sdim TypeSourceInfo *ExpansionTSInfo = getTypeSourceInfo(); 433218893Sdim if (!ExpansionTSInfo) 434218893Sdim ExpansionTSInfo = Context.getTrivialTypeSourceInfo( 435218893Sdim getArgument().getAsType(), 436218893Sdim Ellipsis); 437218893Sdim PackExpansionTypeLoc Expansion 438218893Sdim = cast<PackExpansionTypeLoc>(ExpansionTSInfo->getTypeLoc()); 439218893Sdim Ellipsis = Expansion.getEllipsisLoc(); 440218893Sdim 441218893Sdim TypeLoc Pattern = Expansion.getPatternLoc(); 442218893Sdim NumExpansions = Expansion.getTypePtr()->getNumExpansions(); 443218893Sdim 444218893Sdim // FIXME: This is horrible. We know where the source location data is for 445218893Sdim // the pattern, and we have the pattern's type, but we are forced to copy 446218893Sdim // them into an ASTContext because TypeSourceInfo bundles them together 447218893Sdim // and TemplateArgumentLoc traffics in TypeSourceInfo pointers. 448218893Sdim TypeSourceInfo *PatternTSInfo 449218893Sdim = Context.CreateTypeSourceInfo(Pattern.getType(), 450218893Sdim Pattern.getFullDataSize()); 451218893Sdim memcpy(PatternTSInfo->getTypeLoc().getOpaqueData(), 452218893Sdim Pattern.getOpaqueData(), Pattern.getFullDataSize()); 453218893Sdim return TemplateArgumentLoc(TemplateArgument(Pattern.getType()), 454218893Sdim PatternTSInfo); 455218893Sdim } 456218893Sdim 457218893Sdim case TemplateArgument::Expression: { 458218893Sdim PackExpansionExpr *Expansion 459218893Sdim = cast<PackExpansionExpr>(Argument.getAsExpr()); 460218893Sdim Expr *Pattern = Expansion->getPattern(); 461218893Sdim Ellipsis = Expansion->getEllipsisLoc(); 462218893Sdim NumExpansions = Expansion->getNumExpansions(); 463218893Sdim return TemplateArgumentLoc(Pattern, Pattern); 464218893Sdim } 465218893Sdim 466218893Sdim case TemplateArgument::TemplateExpansion: 467218893Sdim Ellipsis = getTemplateEllipsisLoc(); 468218893Sdim NumExpansions = Argument.getNumTemplateExpansions(); 469218893Sdim return TemplateArgumentLoc(Argument.getPackExpansionPattern(), 470221345Sdim getTemplateQualifierLoc(), 471218893Sdim getTemplateNameLoc()); 472218893Sdim 473218893Sdim case TemplateArgument::Declaration: 474218893Sdim case TemplateArgument::Template: 475218893Sdim case TemplateArgument::Integral: 476218893Sdim case TemplateArgument::Pack: 477218893Sdim case TemplateArgument::Null: 478218893Sdim return TemplateArgumentLoc(); 479218893Sdim } 480235633Sdim 481235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 482218893Sdim} 483218893Sdim 484208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 485208600Srdivacky const TemplateArgument &Arg) { 486208600Srdivacky switch (Arg.getKind()) { 487208600Srdivacky case TemplateArgument::Null: 488212904Sdim // This is bad, but not as bad as crashing because of argument 489212904Sdim // count mismatches. 490212904Sdim return DB << "(null template argument)"; 491208600Srdivacky 492208600Srdivacky case TemplateArgument::Type: 493208600Srdivacky return DB << Arg.getAsType(); 494208600Srdivacky 495208600Srdivacky case TemplateArgument::Declaration: 496235633Sdim if (Decl *D = Arg.getAsDecl()) 497235633Sdim return DB << D; 498235633Sdim return DB << "nullptr"; 499208600Srdivacky 500208600Srdivacky case TemplateArgument::Integral: 501208600Srdivacky return DB << Arg.getAsIntegral()->toString(10); 502208600Srdivacky 503208600Srdivacky case TemplateArgument::Template: 504208600Srdivacky return DB << Arg.getAsTemplate(); 505218893Sdim 506218893Sdim case TemplateArgument::TemplateExpansion: 507218893Sdim return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 508218893Sdim 509208600Srdivacky case TemplateArgument::Expression: { 510208600Srdivacky // This shouldn't actually ever happen, so it's okay that we're 511208600Srdivacky // regurgitating an expression here. 512208600Srdivacky // FIXME: We're guessing at LangOptions! 513235633Sdim SmallString<32> Str; 514208600Srdivacky llvm::raw_svector_ostream OS(Str); 515208600Srdivacky LangOptions LangOpts; 516208600Srdivacky LangOpts.CPlusPlus = true; 517208600Srdivacky PrintingPolicy Policy(LangOpts); 518208600Srdivacky Arg.getAsExpr()->printPretty(OS, 0, Policy); 519208600Srdivacky return DB << OS.str(); 520208600Srdivacky } 521208600Srdivacky 522218893Sdim case TemplateArgument::Pack: { 523218893Sdim // FIXME: We're guessing at LangOptions! 524235633Sdim SmallString<32> Str; 525218893Sdim llvm::raw_svector_ostream OS(Str); 526218893Sdim LangOptions LangOpts; 527218893Sdim LangOpts.CPlusPlus = true; 528218893Sdim PrintingPolicy Policy(LangOpts); 529218893Sdim Arg.print(Policy, OS); 530218893Sdim return DB << OS.str(); 531208600Srdivacky } 532218893Sdim } 533235633Sdim 534235633Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 535208600Srdivacky} 536226890Sdim 537226890Sdimconst ASTTemplateArgumentListInfo * 538226890SdimASTTemplateArgumentListInfo::Create(ASTContext &C, 539226890Sdim const TemplateArgumentListInfo &List) { 540226890Sdim std::size_t size = sizeof(CXXDependentScopeMemberExpr) + 541235633Sdim ASTTemplateArgumentListInfo::sizeFor(List.size()); 542226890Sdim void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>()); 543226890Sdim ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo(); 544226890Sdim TAI->initializeFrom(List); 545226890Sdim return TAI; 546226890Sdim} 547226890Sdim 548226890Sdimvoid ASTTemplateArgumentListInfo::initializeFrom( 549226890Sdim const TemplateArgumentListInfo &Info) { 550226890Sdim LAngleLoc = Info.getLAngleLoc(); 551226890Sdim RAngleLoc = Info.getRAngleLoc(); 552226890Sdim NumTemplateArgs = Info.size(); 553226890Sdim 554226890Sdim TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 555226890Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) 556226890Sdim new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 557226890Sdim} 558226890Sdim 559226890Sdimvoid ASTTemplateArgumentListInfo::initializeFrom( 560226890Sdim const TemplateArgumentListInfo &Info, 561226890Sdim bool &Dependent, 562226890Sdim bool &InstantiationDependent, 563226890Sdim bool &ContainsUnexpandedParameterPack) { 564226890Sdim LAngleLoc = Info.getLAngleLoc(); 565226890Sdim RAngleLoc = Info.getRAngleLoc(); 566226890Sdim NumTemplateArgs = Info.size(); 567226890Sdim 568226890Sdim TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 569226890Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) { 570226890Sdim Dependent = Dependent || Info[i].getArgument().isDependent(); 571226890Sdim InstantiationDependent = InstantiationDependent || 572226890Sdim Info[i].getArgument().isInstantiationDependent(); 573226890Sdim ContainsUnexpandedParameterPack 574226890Sdim = ContainsUnexpandedParameterPack || 575226890Sdim Info[i].getArgument().containsUnexpandedParameterPack(); 576226890Sdim 577226890Sdim new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 578226890Sdim } 579226890Sdim} 580226890Sdim 581226890Sdimvoid ASTTemplateArgumentListInfo::copyInto( 582226890Sdim TemplateArgumentListInfo &Info) const { 583226890Sdim Info.setLAngleLoc(LAngleLoc); 584226890Sdim Info.setRAngleLoc(RAngleLoc); 585226890Sdim for (unsigned I = 0; I != NumTemplateArgs; ++I) 586226890Sdim Info.addArgument(getTemplateArgs()[I]); 587226890Sdim} 588226890Sdim 589226890Sdimstd::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) { 590226890Sdim return sizeof(ASTTemplateArgumentListInfo) + 591226890Sdim sizeof(TemplateArgumentLoc) * NumTemplateArgs; 592226890Sdim} 593226890Sdim 594235633Sdimvoid 595235633SdimASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc, 596235633Sdim const TemplateArgumentListInfo &Info) { 597235633Sdim Base::initializeFrom(Info); 598235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 599226890Sdim} 600235633Sdim 601235633Sdimvoid 602235633SdimASTTemplateKWAndArgsInfo 603235633Sdim::initializeFrom(SourceLocation TemplateKWLoc, 604235633Sdim const TemplateArgumentListInfo &Info, 605235633Sdim bool &Dependent, 606235633Sdim bool &InstantiationDependent, 607235633Sdim bool &ContainsUnexpandedParameterPack) { 608235633Sdim Base::initializeFrom(Info, Dependent, InstantiationDependent, 609235633Sdim ContainsUnexpandedParameterPack); 610235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 611235633Sdim} 612235633Sdim 613235633Sdimvoid 614235633SdimASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 615235633Sdim // No explicit template arguments, but template keyword loc is valid. 616235633Sdim assert(TemplateKWLoc.isValid()); 617235633Sdim LAngleLoc = SourceLocation(); 618235633Sdim RAngleLoc = SourceLocation(); 619235633Sdim NumTemplateArgs = 0; 620235633Sdim setTemplateKeywordLoc(TemplateKWLoc); 621235633Sdim} 622235633Sdim 623235633Sdimstd::size_t 624235633SdimASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) { 625235633Sdim // Add space for the template keyword location. 626235633Sdim return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation); 627235633Sdim} 628235633Sdim 629