1327952Sdim//===- TemplateBase.cpp - Common template AST class implementation --------===// 2198893Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6198893Srdivacky// 7198893Srdivacky//===----------------------------------------------------------------------===// 8198893Srdivacky// 9198893Srdivacky// This file implements common classes used throughout C++ template 10198893Srdivacky// representations. 11198893Srdivacky// 12198893Srdivacky//===----------------------------------------------------------------------===// 13198893Srdivacky 14198893Srdivacky#include "clang/AST/TemplateBase.h" 15218893Sdim#include "clang/AST/ASTContext.h" 16327952Sdim#include "clang/AST/Decl.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" 21327952Sdim#include "clang/AST/PrettyPrinter.h" 22327952Sdim#include "clang/AST/TemplateName.h" 23218893Sdim#include "clang/AST/Type.h" 24198893Srdivacky#include "clang/AST/TypeLoc.h" 25208600Srdivacky#include "clang/Basic/Diagnostic.h" 26327952Sdim#include "clang/Basic/LLVM.h" 27327952Sdim#include "clang/Basic/LangOptions.h" 28327952Sdim#include "clang/Basic/SourceLocation.h" 29327952Sdim#include "llvm/ADT/APSInt.h" 30218893Sdim#include "llvm/ADT/FoldingSet.h" 31327952Sdim#include "llvm/ADT/None.h" 32234353Sdim#include "llvm/ADT/SmallString.h" 33327952Sdim#include "llvm/ADT/StringRef.h" 34327952Sdim#include "llvm/Support/Casting.h" 35327952Sdim#include "llvm/Support/Compiler.h" 36327952Sdim#include "llvm/Support/ErrorHandling.h" 37249423Sdim#include "llvm/Support/raw_ostream.h" 38327952Sdim#include <cassert> 39327952Sdim#include <cstddef> 40327952Sdim#include <cstdint> 41327952Sdim#include <cstring> 42198893Srdivacky 43198893Srdivackyusing namespace clang; 44198893Srdivacky 45341825Sdim/// Print a template integral argument value. 46218893Sdim/// 47218893Sdim/// \param TemplArg the TemplateArgument instance to print. 48218893Sdim/// 49218893Sdim/// \param Out the raw_ostream instance to use for printing. 50280031Sdim/// 51280031Sdim/// \param Policy the printing policy for EnumConstantDecl printing. 52218893Sdimstatic void printIntegral(const TemplateArgument &TemplArg, 53280031Sdim raw_ostream &Out, const PrintingPolicy& Policy) { 54327952Sdim const Type *T = TemplArg.getIntegralType().getTypePtr(); 55239462Sdim const llvm::APSInt &Val = TemplArg.getAsIntegral(); 56218893Sdim 57280031Sdim if (const EnumType *ET = T->getAs<EnumType>()) { 58280031Sdim for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { 59280031Sdim // In Sema::CheckTemplateArugment, enum template arguments value are 60280031Sdim // extended to the size of the integer underlying the enum type. This 61280031Sdim // may create a size difference between the enum value and template 62280031Sdim // argument value, requiring isSameValue here instead of operator==. 63280031Sdim if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { 64280031Sdim ECD->printQualifiedName(Out, Policy); 65280031Sdim return; 66280031Sdim } 67280031Sdim } 68280031Sdim } 69280031Sdim 70296417Sdim if (T->isBooleanType() && !Policy.MSVCFormatting) { 71239462Sdim Out << (Val.getBoolValue() ? "true" : "false"); 72218893Sdim } else if (T->isCharType()) { 73239462Sdim const char Ch = Val.getZExtValue(); 74219077Sdim Out << ((Ch == '\'') ? "'\\" : "'"); 75234353Sdim Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); 76219077Sdim Out << "'"; 77218893Sdim } else { 78239462Sdim Out << Val; 79218893Sdim } 80218893Sdim} 81218893Sdim 82198893Srdivacky//===----------------------------------------------------------------------===// 83198893Srdivacky// TemplateArgument Implementation 84198893Srdivacky//===----------------------------------------------------------------------===// 85198893Srdivacky 86239462SdimTemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, 87261991Sdim QualType Type) { 88261991Sdim Integer.Kind = Integral; 89239462Sdim // Copy the APSInt value into our decomposed form. 90239462Sdim Integer.BitWidth = Value.getBitWidth(); 91239462Sdim Integer.IsUnsigned = Value.isUnsigned(); 92239462Sdim // If the value is large, we have to get additional memory from the ASTContext 93239462Sdim unsigned NumWords = Value.getNumWords(); 94239462Sdim if (NumWords > 1) { 95239462Sdim void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); 96239462Sdim std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); 97239462Sdim Integer.pVal = static_cast<uint64_t *>(Mem); 98239462Sdim } else { 99239462Sdim Integer.VAL = Value.getZExtValue(); 100239462Sdim } 101239462Sdim 102239462Sdim Integer.Type = Type.getAsOpaquePtr(); 103239462Sdim} 104239462Sdim 105296417SdimTemplateArgument 106296417SdimTemplateArgument::CreatePackCopy(ASTContext &Context, 107296417Sdim ArrayRef<TemplateArgument> Args) { 108296417Sdim if (Args.empty()) 109243830Sdim return getEmptyPack(); 110296417Sdim 111296417Sdim return TemplateArgument(Args.copy(Context)); 112218893Sdim} 113198893Srdivacky 114218893Sdimbool TemplateArgument::isDependent() const { 115218893Sdim switch (getKind()) { 116218893Sdim case Null: 117226633Sdim llvm_unreachable("Should not have a NULL template argument"); 118218893Sdim 119218893Sdim case Type: 120280031Sdim return getAsType()->isDependentType() || 121280031Sdim isa<PackExpansionType>(getAsType()); 122218893Sdim 123218893Sdim case Template: 124218893Sdim return getAsTemplate().isDependent(); 125218893Sdim 126218893Sdim case TemplateExpansion: 127218893Sdim return true; 128218893Sdim 129218893Sdim case Declaration: 130243830Sdim if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 131243830Sdim return DC->isDependentContext(); 132243830Sdim return getAsDecl()->getDeclContext()->isDependentContext(); 133243830Sdim 134243830Sdim case NullPtr: 135234353Sdim return false; 136218893Sdim 137218893Sdim case Integral: 138218893Sdim // Never dependent 139218893Sdim return false; 140218893Sdim 141218893Sdim case Expression: 142280031Sdim return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() || 143280031Sdim isa<PackExpansionExpr>(getAsExpr())); 144218893Sdim 145218893Sdim case Pack: 146276479Sdim for (const auto &P : pack_elements()) 147276479Sdim if (P.isDependent()) 148218893Sdim return true; 149218893Sdim return false; 150198893Srdivacky } 151198893Srdivacky 152234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 153198893Srdivacky} 154198893Srdivacky 155224145Sdimbool TemplateArgument::isInstantiationDependent() const { 156224145Sdim switch (getKind()) { 157224145Sdim case Null: 158226633Sdim llvm_unreachable("Should not have a NULL template argument"); 159341825Sdim 160224145Sdim case Type: 161224145Sdim return getAsType()->isInstantiationDependentType(); 162341825Sdim 163224145Sdim case Template: 164224145Sdim return getAsTemplate().isInstantiationDependent(); 165341825Sdim 166224145Sdim case TemplateExpansion: 167224145Sdim return true; 168341825Sdim 169224145Sdim case Declaration: 170243830Sdim if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 171243830Sdim return DC->isDependentContext(); 172243830Sdim return getAsDecl()->getDeclContext()->isDependentContext(); 173243830Sdim 174243830Sdim case NullPtr: 175234353Sdim return false; 176341825Sdim 177224145Sdim case Integral: 178224145Sdim // Never dependent 179224145Sdim return false; 180341825Sdim 181224145Sdim case Expression: 182224145Sdim return getAsExpr()->isInstantiationDependent(); 183341825Sdim 184224145Sdim case Pack: 185276479Sdim for (const auto &P : pack_elements()) 186276479Sdim if (P.isInstantiationDependent()) 187224145Sdim return true; 188224145Sdim return false; 189224145Sdim } 190234353Sdim 191234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 192224145Sdim} 193224145Sdim 194218893Sdimbool TemplateArgument::isPackExpansion() const { 195218893Sdim switch (getKind()) { 196218893Sdim case Null: 197218893Sdim case Declaration: 198218893Sdim case Integral: 199341825Sdim case Pack: 200218893Sdim case Template: 201243830Sdim case NullPtr: 202218893Sdim return false; 203341825Sdim 204218893Sdim case TemplateExpansion: 205218893Sdim return true; 206341825Sdim 207218893Sdim case Type: 208218893Sdim return isa<PackExpansionType>(getAsType()); 209341825Sdim 210218893Sdim case Expression: 211218893Sdim return isa<PackExpansionExpr>(getAsExpr()); 212218893Sdim } 213234353Sdim 214234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 215218893Sdim} 216218893Sdim 217218893Sdimbool TemplateArgument::containsUnexpandedParameterPack() const { 218218893Sdim switch (getKind()) { 219218893Sdim case Null: 220218893Sdim case Declaration: 221218893Sdim case Integral: 222218893Sdim case TemplateExpansion: 223243830Sdim case NullPtr: 224218893Sdim break; 225218893Sdim 226218893Sdim case Type: 227218893Sdim if (getAsType()->containsUnexpandedParameterPack()) 228218893Sdim return true; 229218893Sdim break; 230218893Sdim 231218893Sdim case Template: 232218893Sdim if (getAsTemplate().containsUnexpandedParameterPack()) 233218893Sdim return true; 234218893Sdim break; 235341825Sdim 236218893Sdim case Expression: 237218893Sdim if (getAsExpr()->containsUnexpandedParameterPack()) 238218893Sdim return true; 239218893Sdim break; 240218893Sdim 241218893Sdim case Pack: 242276479Sdim for (const auto &P : pack_elements()) 243276479Sdim if (P.containsUnexpandedParameterPack()) 244218893Sdim return true; 245218893Sdim 246218893Sdim break; 247218893Sdim } 248218893Sdim 249218893Sdim return false; 250218893Sdim} 251218893Sdim 252249423SdimOptional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 253261991Sdim assert(getKind() == TemplateExpansion); 254218893Sdim if (TemplateArg.NumExpansions) 255218893Sdim return TemplateArg.NumExpansions - 1; 256341825Sdim 257341825Sdim return None; 258218893Sdim} 259218893Sdim 260314564SdimQualType TemplateArgument::getNonTypeTemplateArgumentType() const { 261314564Sdim switch (getKind()) { 262314564Sdim case TemplateArgument::Null: 263314564Sdim case TemplateArgument::Type: 264314564Sdim case TemplateArgument::Template: 265314564Sdim case TemplateArgument::TemplateExpansion: 266314564Sdim case TemplateArgument::Pack: 267314564Sdim return QualType(); 268314564Sdim 269314564Sdim case TemplateArgument::Integral: 270314564Sdim return getIntegralType(); 271314564Sdim 272314564Sdim case TemplateArgument::Expression: 273314564Sdim return getAsExpr()->getType(); 274314564Sdim 275314564Sdim case TemplateArgument::Declaration: 276314564Sdim return getParamTypeForDecl(); 277314564Sdim 278314564Sdim case TemplateArgument::NullPtr: 279314564Sdim return getNullPtrType(); 280314564Sdim } 281314564Sdim 282314564Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 283314564Sdim} 284314564Sdim 285198893Srdivackyvoid TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 286218893Sdim const ASTContext &Context) const { 287261991Sdim ID.AddInteger(getKind()); 288261991Sdim switch (getKind()) { 289198893Srdivacky case Null: 290198893Srdivacky break; 291198893Srdivacky 292198893Srdivacky case Type: 293198893Srdivacky getAsType().Profile(ID); 294198893Srdivacky break; 295198893Srdivacky 296261991Sdim case NullPtr: 297261991Sdim getNullPtrType().Profile(ID); 298261991Sdim break; 299261991Sdim 300198893Srdivacky case Declaration: 301276479Sdim ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr); 302198893Srdivacky break; 303198893Srdivacky 304199482Srdivacky case Template: 305218893Sdim case TemplateExpansion: { 306218893Sdim TemplateName Template = getAsTemplateOrTemplatePattern(); 307199990Srdivacky if (TemplateTemplateParmDecl *TTP 308199990Srdivacky = dyn_cast_or_null<TemplateTemplateParmDecl>( 309218893Sdim Template.getAsTemplateDecl())) { 310199990Srdivacky ID.AddBoolean(true); 311199990Srdivacky ID.AddInteger(TTP->getDepth()); 312199990Srdivacky ID.AddInteger(TTP->getPosition()); 313218893Sdim ID.AddBoolean(TTP->isParameterPack()); 314199990Srdivacky } else { 315199990Srdivacky ID.AddBoolean(false); 316218893Sdim ID.AddPointer(Context.getCanonicalTemplateName(Template) 317218893Sdim .getAsVoidPointer()); 318199990Srdivacky } 319199482Srdivacky break; 320218893Sdim } 321341825Sdim 322198893Srdivacky case Integral: 323239462Sdim getAsIntegral().Profile(ID); 324198893Srdivacky getIntegralType().Profile(ID); 325198893Srdivacky break; 326198893Srdivacky 327198893Srdivacky case Expression: 328198893Srdivacky getAsExpr()->Profile(ID, Context, true); 329198893Srdivacky break; 330198893Srdivacky 331198893Srdivacky case Pack: 332198893Srdivacky ID.AddInteger(Args.NumArgs); 333198893Srdivacky for (unsigned I = 0; I != Args.NumArgs; ++I) 334198893Srdivacky Args.Args[I].Profile(ID, Context); 335198893Srdivacky } 336198893Srdivacky} 337198893Srdivacky 338210299Sedbool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 339210299Sed if (getKind() != Other.getKind()) return false; 340210299Sed 341210299Sed switch (getKind()) { 342210299Sed case Null: 343210299Sed case Type: 344341825Sdim case Expression: 345210299Sed case Template: 346218893Sdim case TemplateExpansion: 347243830Sdim case NullPtr: 348261991Sdim return TypeOrValue.V == Other.TypeOrValue.V; 349210299Sed 350243830Sdim case Declaration: 351280031Sdim return getAsDecl() == Other.getAsDecl(); 352243830Sdim 353210299Sed case Integral: 354210299Sed return getIntegralType() == Other.getIntegralType() && 355239462Sdim getAsIntegral() == Other.getAsIntegral(); 356210299Sed 357210299Sed case Pack: 358210299Sed if (Args.NumArgs != Other.Args.NumArgs) return false; 359210299Sed for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 360210299Sed if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 361210299Sed return false; 362210299Sed return true; 363210299Sed } 364210299Sed 365234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 366210299Sed} 367210299Sed 368218893SdimTemplateArgument TemplateArgument::getPackExpansionPattern() const { 369218893Sdim assert(isPackExpansion()); 370341825Sdim 371218893Sdim switch (getKind()) { 372218893Sdim case Type: 373360784Sdim return getAsType()->castAs<PackExpansionType>()->getPattern(); 374341825Sdim 375218893Sdim case Expression: 376218893Sdim return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 377341825Sdim 378218893Sdim case TemplateExpansion: 379218893Sdim return TemplateArgument(getAsTemplateOrTemplatePattern()); 380243830Sdim 381218893Sdim case Declaration: 382218893Sdim case Integral: 383218893Sdim case Pack: 384218893Sdim case Null: 385218893Sdim case Template: 386243830Sdim case NullPtr: 387218893Sdim return TemplateArgument(); 388218893Sdim } 389234353Sdim 390234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 391218893Sdim} 392218893Sdim 393341825Sdimvoid TemplateArgument::print(const PrintingPolicy &Policy, 394226633Sdim raw_ostream &Out) const { 395218893Sdim switch (getKind()) { 396218893Sdim case Null: 397276479Sdim Out << "(no value)"; 398218893Sdim break; 399341825Sdim 400218893Sdim case Type: { 401224145Sdim PrintingPolicy SubPolicy(Policy); 402224145Sdim SubPolicy.SuppressStrongLifetime = true; 403249423Sdim getAsType().print(Out, SubPolicy); 404218893Sdim break; 405218893Sdim } 406341825Sdim 407218893Sdim case Declaration: { 408341825Sdim NamedDecl *ND = getAsDecl(); 409261991Sdim Out << '&'; 410243830Sdim if (ND->getDeclName()) { 411243830Sdim // FIXME: distinguish between pointer and reference args? 412261991Sdim ND->printQualifiedName(Out); 413234353Sdim } else { 414276479Sdim Out << "(anonymous)"; 415218893Sdim } 416218893Sdim break; 417218893Sdim } 418243830Sdim 419243830Sdim case NullPtr: 420243830Sdim Out << "nullptr"; 421243830Sdim break; 422243830Sdim 423218893Sdim case Template: 424218893Sdim getAsTemplate().print(Out, Policy); 425218893Sdim break; 426218893Sdim 427218893Sdim case TemplateExpansion: 428218893Sdim getAsTemplateOrTemplatePattern().print(Out, Policy); 429218893Sdim Out << "..."; 430218893Sdim break; 431341825Sdim 432327952Sdim case Integral: 433280031Sdim printIntegral(*this, Out, Policy); 434218893Sdim break; 435341825Sdim 436218893Sdim case Expression: 437276479Sdim getAsExpr()->printPretty(Out, nullptr, Policy); 438218893Sdim break; 439341825Sdim 440218893Sdim case Pack: 441218893Sdim Out << "<"; 442218893Sdim bool First = true; 443276479Sdim for (const auto &P : pack_elements()) { 444218893Sdim if (First) 445218893Sdim First = false; 446218893Sdim else 447218893Sdim Out << ", "; 448341825Sdim 449276479Sdim P.print(Policy, Out); 450218893Sdim } 451218893Sdim Out << ">"; 452341825Sdim break; 453218893Sdim } 454218893Sdim} 455218893Sdim 456309124Sdimvoid TemplateArgument::dump(raw_ostream &Out) const { 457309124Sdim LangOptions LO; // FIXME! see also TemplateName::dump(). 458309124Sdim LO.CPlusPlus = true; 459309124Sdim LO.Bool = true; 460309124Sdim print(PrintingPolicy(LO), Out); 461309124Sdim} 462309124Sdim 463309124SdimLLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } 464309124Sdim 465198893Srdivacky//===----------------------------------------------------------------------===// 466198893Srdivacky// TemplateArgumentLoc Implementation 467198893Srdivacky//===----------------------------------------------------------------------===// 468198893Srdivacky 469198893SrdivackySourceRange TemplateArgumentLoc::getSourceRange() const { 470198893Srdivacky switch (Argument.getKind()) { 471198893Srdivacky case TemplateArgument::Expression: 472198893Srdivacky return getSourceExpression()->getSourceRange(); 473212904Sdim 474198893Srdivacky case TemplateArgument::Declaration: 475198893Srdivacky return getSourceDeclExpression()->getSourceRange(); 476212904Sdim 477243830Sdim case TemplateArgument::NullPtr: 478243830Sdim return getSourceNullPtrExpression()->getSourceRange(); 479243830Sdim 480198893Srdivacky case TemplateArgument::Type: 481212904Sdim if (TypeSourceInfo *TSI = getTypeSourceInfo()) 482212904Sdim return TSI->getTypeLoc().getSourceRange(); 483212904Sdim else 484212904Sdim return SourceRange(); 485212904Sdim 486199482Srdivacky case TemplateArgument::Template: 487221345Sdim if (getTemplateQualifierLoc()) 488341825Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 489199482Srdivacky getTemplateNameLoc()); 490199482Srdivacky return SourceRange(getTemplateNameLoc()); 491212904Sdim 492218893Sdim case TemplateArgument::TemplateExpansion: 493221345Sdim if (getTemplateQualifierLoc()) 494341825Sdim return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 495218893Sdim getTemplateEllipsisLoc()); 496218893Sdim return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 497218893Sdim 498198893Srdivacky case TemplateArgument::Integral: 499243830Sdim return getSourceIntegralExpression()->getSourceRange(); 500243830Sdim 501198893Srdivacky case TemplateArgument::Pack: 502198893Srdivacky case TemplateArgument::Null: 503198893Srdivacky return SourceRange(); 504198893Srdivacky } 505198893Srdivacky 506234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 507198893Srdivacky} 508208600Srdivacky 509208600Srdivackyconst DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 510208600Srdivacky const TemplateArgument &Arg) { 511208600Srdivacky switch (Arg.getKind()) { 512208600Srdivacky case TemplateArgument::Null: 513212904Sdim // This is bad, but not as bad as crashing because of argument 514212904Sdim // count mismatches. 515212904Sdim return DB << "(null template argument)"; 516341825Sdim 517208600Srdivacky case TemplateArgument::Type: 518208600Srdivacky return DB << Arg.getAsType(); 519341825Sdim 520208600Srdivacky case TemplateArgument::Declaration: 521243830Sdim return DB << Arg.getAsDecl(); 522243830Sdim 523243830Sdim case TemplateArgument::NullPtr: 524234353Sdim return DB << "nullptr"; 525341825Sdim 526208600Srdivacky case TemplateArgument::Integral: 527239462Sdim return DB << Arg.getAsIntegral().toString(10); 528341825Sdim 529208600Srdivacky case TemplateArgument::Template: 530208600Srdivacky return DB << Arg.getAsTemplate(); 531218893Sdim 532218893Sdim case TemplateArgument::TemplateExpansion: 533218893Sdim return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 534218893Sdim 535208600Srdivacky case TemplateArgument::Expression: { 536208600Srdivacky // This shouldn't actually ever happen, so it's okay that we're 537208600Srdivacky // regurgitating an expression here. 538208600Srdivacky // FIXME: We're guessing at LangOptions! 539234353Sdim SmallString<32> Str; 540208600Srdivacky llvm::raw_svector_ostream OS(Str); 541208600Srdivacky LangOptions LangOpts; 542208600Srdivacky LangOpts.CPlusPlus = true; 543208600Srdivacky PrintingPolicy Policy(LangOpts); 544276479Sdim Arg.getAsExpr()->printPretty(OS, nullptr, Policy); 545208600Srdivacky return DB << OS.str(); 546208600Srdivacky } 547341825Sdim 548218893Sdim case TemplateArgument::Pack: { 549218893Sdim // FIXME: We're guessing at LangOptions! 550234353Sdim SmallString<32> Str; 551218893Sdim llvm::raw_svector_ostream OS(Str); 552218893Sdim LangOptions LangOpts; 553218893Sdim LangOpts.CPlusPlus = true; 554218893Sdim PrintingPolicy Policy(LangOpts); 555218893Sdim Arg.print(Policy, OS); 556218893Sdim return DB << OS.str(); 557208600Srdivacky } 558218893Sdim } 559234353Sdim 560234353Sdim llvm_unreachable("Invalid TemplateArgument Kind!"); 561208600Srdivacky} 562226633Sdim 563226633Sdimconst ASTTemplateArgumentListInfo * 564360784SdimASTTemplateArgumentListInfo::Create(const ASTContext &C, 565226633Sdim const TemplateArgumentListInfo &List) { 566296417Sdim std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); 567314564Sdim void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 568296417Sdim return new (Mem) ASTTemplateArgumentListInfo(List); 569226633Sdim} 570226633Sdim 571296417SdimASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 572296417Sdim const TemplateArgumentListInfo &Info) { 573226633Sdim LAngleLoc = Info.getLAngleLoc(); 574226633Sdim RAngleLoc = Info.getRAngleLoc(); 575226633Sdim NumTemplateArgs = Info.size(); 576226633Sdim 577296417Sdim TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 578226633Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) 579226633Sdim new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 580226633Sdim} 581226633Sdim 582296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom( 583296417Sdim SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 584296417Sdim TemplateArgumentLoc *OutArgArray) { 585296417Sdim this->TemplateKWLoc = TemplateKWLoc; 586226633Sdim LAngleLoc = Info.getLAngleLoc(); 587226633Sdim RAngleLoc = Info.getRAngleLoc(); 588226633Sdim NumTemplateArgs = Info.size(); 589226633Sdim 590296417Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) 591296417Sdim new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 592296417Sdim} 593296417Sdim 594296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 595296417Sdim assert(TemplateKWLoc.isValid()); 596296417Sdim LAngleLoc = SourceLocation(); 597296417Sdim RAngleLoc = SourceLocation(); 598296417Sdim this->TemplateKWLoc = TemplateKWLoc; 599296417Sdim NumTemplateArgs = 0; 600296417Sdim} 601296417Sdim 602296417Sdimvoid ASTTemplateKWAndArgsInfo::initializeFrom( 603296417Sdim SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 604296417Sdim TemplateArgumentLoc *OutArgArray, bool &Dependent, 605296417Sdim bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) { 606296417Sdim this->TemplateKWLoc = TemplateKWLoc; 607296417Sdim LAngleLoc = Info.getLAngleLoc(); 608296417Sdim RAngleLoc = Info.getRAngleLoc(); 609296417Sdim NumTemplateArgs = Info.size(); 610296417Sdim 611226633Sdim for (unsigned i = 0; i != NumTemplateArgs; ++i) { 612226633Sdim Dependent = Dependent || Info[i].getArgument().isDependent(); 613296417Sdim InstantiationDependent = InstantiationDependent || 614226633Sdim Info[i].getArgument().isInstantiationDependent(); 615296417Sdim ContainsUnexpandedParameterPack = 616296417Sdim ContainsUnexpandedParameterPack || 617226633Sdim Info[i].getArgument().containsUnexpandedParameterPack(); 618226633Sdim 619296417Sdim new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 620226633Sdim } 621226633Sdim} 622226633Sdim 623296417Sdimvoid ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, 624296417Sdim TemplateArgumentListInfo &Info) const { 625226633Sdim Info.setLAngleLoc(LAngleLoc); 626226633Sdim Info.setRAngleLoc(RAngleLoc); 627226633Sdim for (unsigned I = 0; I != NumTemplateArgs; ++I) 628296417Sdim Info.addArgument(ArgArray[I]); 629226633Sdim} 630