1*e5dd7070Spatrick //===- TemplateBase.cpp - Common template AST class implementation --------===// 2*e5dd7070Spatrick // 3*e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*e5dd7070Spatrick // 7*e5dd7070Spatrick //===----------------------------------------------------------------------===// 8*e5dd7070Spatrick // 9*e5dd7070Spatrick // This file implements common classes used throughout C++ template 10*e5dd7070Spatrick // representations. 11*e5dd7070Spatrick // 12*e5dd7070Spatrick //===----------------------------------------------------------------------===// 13*e5dd7070Spatrick 14*e5dd7070Spatrick #include "clang/AST/TemplateBase.h" 15*e5dd7070Spatrick #include "clang/AST/ASTContext.h" 16*e5dd7070Spatrick #include "clang/AST/Decl.h" 17*e5dd7070Spatrick #include "clang/AST/DeclBase.h" 18*e5dd7070Spatrick #include "clang/AST/DeclTemplate.h" 19*e5dd7070Spatrick #include "clang/AST/Expr.h" 20*e5dd7070Spatrick #include "clang/AST/ExprCXX.h" 21*e5dd7070Spatrick #include "clang/AST/PrettyPrinter.h" 22*e5dd7070Spatrick #include "clang/AST/TemplateName.h" 23*e5dd7070Spatrick #include "clang/AST/Type.h" 24*e5dd7070Spatrick #include "clang/AST/TypeLoc.h" 25*e5dd7070Spatrick #include "clang/Basic/Diagnostic.h" 26*e5dd7070Spatrick #include "clang/Basic/LLVM.h" 27*e5dd7070Spatrick #include "clang/Basic/LangOptions.h" 28*e5dd7070Spatrick #include "clang/Basic/SourceLocation.h" 29*e5dd7070Spatrick #include "llvm/ADT/APSInt.h" 30*e5dd7070Spatrick #include "llvm/ADT/FoldingSet.h" 31*e5dd7070Spatrick #include "llvm/ADT/None.h" 32*e5dd7070Spatrick #include "llvm/ADT/SmallString.h" 33*e5dd7070Spatrick #include "llvm/ADT/StringRef.h" 34*e5dd7070Spatrick #include "llvm/Support/Casting.h" 35*e5dd7070Spatrick #include "llvm/Support/Compiler.h" 36*e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h" 37*e5dd7070Spatrick #include "llvm/Support/raw_ostream.h" 38*e5dd7070Spatrick #include <cassert> 39*e5dd7070Spatrick #include <cstddef> 40*e5dd7070Spatrick #include <cstdint> 41*e5dd7070Spatrick #include <cstring> 42*e5dd7070Spatrick 43*e5dd7070Spatrick using namespace clang; 44*e5dd7070Spatrick 45*e5dd7070Spatrick /// Print a template integral argument value. 46*e5dd7070Spatrick /// 47*e5dd7070Spatrick /// \param TemplArg the TemplateArgument instance to print. 48*e5dd7070Spatrick /// 49*e5dd7070Spatrick /// \param Out the raw_ostream instance to use for printing. 50*e5dd7070Spatrick /// 51*e5dd7070Spatrick /// \param Policy the printing policy for EnumConstantDecl printing. 52*e5dd7070Spatrick static void printIntegral(const TemplateArgument &TemplArg, 53*e5dd7070Spatrick raw_ostream &Out, const PrintingPolicy& Policy) { 54*e5dd7070Spatrick const Type *T = TemplArg.getIntegralType().getTypePtr(); 55*e5dd7070Spatrick const llvm::APSInt &Val = TemplArg.getAsIntegral(); 56*e5dd7070Spatrick 57*e5dd7070Spatrick if (const EnumType *ET = T->getAs<EnumType>()) { 58*e5dd7070Spatrick for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) { 59*e5dd7070Spatrick // In Sema::CheckTemplateArugment, enum template arguments value are 60*e5dd7070Spatrick // extended to the size of the integer underlying the enum type. This 61*e5dd7070Spatrick // may create a size difference between the enum value and template 62*e5dd7070Spatrick // argument value, requiring isSameValue here instead of operator==. 63*e5dd7070Spatrick if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) { 64*e5dd7070Spatrick ECD->printQualifiedName(Out, Policy); 65*e5dd7070Spatrick return; 66*e5dd7070Spatrick } 67*e5dd7070Spatrick } 68*e5dd7070Spatrick } 69*e5dd7070Spatrick 70*e5dd7070Spatrick if (T->isBooleanType() && !Policy.MSVCFormatting) { 71*e5dd7070Spatrick Out << (Val.getBoolValue() ? "true" : "false"); 72*e5dd7070Spatrick } else if (T->isCharType()) { 73*e5dd7070Spatrick const char Ch = Val.getZExtValue(); 74*e5dd7070Spatrick Out << ((Ch == '\'') ? "'\\" : "'"); 75*e5dd7070Spatrick Out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true); 76*e5dd7070Spatrick Out << "'"; 77*e5dd7070Spatrick } else { 78*e5dd7070Spatrick Out << Val; 79*e5dd7070Spatrick } 80*e5dd7070Spatrick } 81*e5dd7070Spatrick 82*e5dd7070Spatrick //===----------------------------------------------------------------------===// 83*e5dd7070Spatrick // TemplateArgument Implementation 84*e5dd7070Spatrick //===----------------------------------------------------------------------===// 85*e5dd7070Spatrick 86*e5dd7070Spatrick TemplateArgument::TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, 87*e5dd7070Spatrick QualType Type) { 88*e5dd7070Spatrick Integer.Kind = Integral; 89*e5dd7070Spatrick // Copy the APSInt value into our decomposed form. 90*e5dd7070Spatrick Integer.BitWidth = Value.getBitWidth(); 91*e5dd7070Spatrick Integer.IsUnsigned = Value.isUnsigned(); 92*e5dd7070Spatrick // If the value is large, we have to get additional memory from the ASTContext 93*e5dd7070Spatrick unsigned NumWords = Value.getNumWords(); 94*e5dd7070Spatrick if (NumWords > 1) { 95*e5dd7070Spatrick void *Mem = Ctx.Allocate(NumWords * sizeof(uint64_t)); 96*e5dd7070Spatrick std::memcpy(Mem, Value.getRawData(), NumWords * sizeof(uint64_t)); 97*e5dd7070Spatrick Integer.pVal = static_cast<uint64_t *>(Mem); 98*e5dd7070Spatrick } else { 99*e5dd7070Spatrick Integer.VAL = Value.getZExtValue(); 100*e5dd7070Spatrick } 101*e5dd7070Spatrick 102*e5dd7070Spatrick Integer.Type = Type.getAsOpaquePtr(); 103*e5dd7070Spatrick } 104*e5dd7070Spatrick 105*e5dd7070Spatrick TemplateArgument 106*e5dd7070Spatrick TemplateArgument::CreatePackCopy(ASTContext &Context, 107*e5dd7070Spatrick ArrayRef<TemplateArgument> Args) { 108*e5dd7070Spatrick if (Args.empty()) 109*e5dd7070Spatrick return getEmptyPack(); 110*e5dd7070Spatrick 111*e5dd7070Spatrick return TemplateArgument(Args.copy(Context)); 112*e5dd7070Spatrick } 113*e5dd7070Spatrick 114*e5dd7070Spatrick bool TemplateArgument::isDependent() const { 115*e5dd7070Spatrick switch (getKind()) { 116*e5dd7070Spatrick case Null: 117*e5dd7070Spatrick llvm_unreachable("Should not have a NULL template argument"); 118*e5dd7070Spatrick 119*e5dd7070Spatrick case Type: 120*e5dd7070Spatrick return getAsType()->isDependentType() || 121*e5dd7070Spatrick isa<PackExpansionType>(getAsType()); 122*e5dd7070Spatrick 123*e5dd7070Spatrick case Template: 124*e5dd7070Spatrick return getAsTemplate().isDependent(); 125*e5dd7070Spatrick 126*e5dd7070Spatrick case TemplateExpansion: 127*e5dd7070Spatrick return true; 128*e5dd7070Spatrick 129*e5dd7070Spatrick case Declaration: 130*e5dd7070Spatrick if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 131*e5dd7070Spatrick return DC->isDependentContext(); 132*e5dd7070Spatrick return getAsDecl()->getDeclContext()->isDependentContext(); 133*e5dd7070Spatrick 134*e5dd7070Spatrick case NullPtr: 135*e5dd7070Spatrick return false; 136*e5dd7070Spatrick 137*e5dd7070Spatrick case Integral: 138*e5dd7070Spatrick // Never dependent 139*e5dd7070Spatrick return false; 140*e5dd7070Spatrick 141*e5dd7070Spatrick case Expression: 142*e5dd7070Spatrick return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() || 143*e5dd7070Spatrick isa<PackExpansionExpr>(getAsExpr())); 144*e5dd7070Spatrick 145*e5dd7070Spatrick case Pack: 146*e5dd7070Spatrick for (const auto &P : pack_elements()) 147*e5dd7070Spatrick if (P.isDependent()) 148*e5dd7070Spatrick return true; 149*e5dd7070Spatrick return false; 150*e5dd7070Spatrick } 151*e5dd7070Spatrick 152*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 153*e5dd7070Spatrick } 154*e5dd7070Spatrick 155*e5dd7070Spatrick bool TemplateArgument::isInstantiationDependent() const { 156*e5dd7070Spatrick switch (getKind()) { 157*e5dd7070Spatrick case Null: 158*e5dd7070Spatrick llvm_unreachable("Should not have a NULL template argument"); 159*e5dd7070Spatrick 160*e5dd7070Spatrick case Type: 161*e5dd7070Spatrick return getAsType()->isInstantiationDependentType(); 162*e5dd7070Spatrick 163*e5dd7070Spatrick case Template: 164*e5dd7070Spatrick return getAsTemplate().isInstantiationDependent(); 165*e5dd7070Spatrick 166*e5dd7070Spatrick case TemplateExpansion: 167*e5dd7070Spatrick return true; 168*e5dd7070Spatrick 169*e5dd7070Spatrick case Declaration: 170*e5dd7070Spatrick if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) 171*e5dd7070Spatrick return DC->isDependentContext(); 172*e5dd7070Spatrick return getAsDecl()->getDeclContext()->isDependentContext(); 173*e5dd7070Spatrick 174*e5dd7070Spatrick case NullPtr: 175*e5dd7070Spatrick return false; 176*e5dd7070Spatrick 177*e5dd7070Spatrick case Integral: 178*e5dd7070Spatrick // Never dependent 179*e5dd7070Spatrick return false; 180*e5dd7070Spatrick 181*e5dd7070Spatrick case Expression: 182*e5dd7070Spatrick return getAsExpr()->isInstantiationDependent(); 183*e5dd7070Spatrick 184*e5dd7070Spatrick case Pack: 185*e5dd7070Spatrick for (const auto &P : pack_elements()) 186*e5dd7070Spatrick if (P.isInstantiationDependent()) 187*e5dd7070Spatrick return true; 188*e5dd7070Spatrick return false; 189*e5dd7070Spatrick } 190*e5dd7070Spatrick 191*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 192*e5dd7070Spatrick } 193*e5dd7070Spatrick 194*e5dd7070Spatrick bool TemplateArgument::isPackExpansion() const { 195*e5dd7070Spatrick switch (getKind()) { 196*e5dd7070Spatrick case Null: 197*e5dd7070Spatrick case Declaration: 198*e5dd7070Spatrick case Integral: 199*e5dd7070Spatrick case Pack: 200*e5dd7070Spatrick case Template: 201*e5dd7070Spatrick case NullPtr: 202*e5dd7070Spatrick return false; 203*e5dd7070Spatrick 204*e5dd7070Spatrick case TemplateExpansion: 205*e5dd7070Spatrick return true; 206*e5dd7070Spatrick 207*e5dd7070Spatrick case Type: 208*e5dd7070Spatrick return isa<PackExpansionType>(getAsType()); 209*e5dd7070Spatrick 210*e5dd7070Spatrick case Expression: 211*e5dd7070Spatrick return isa<PackExpansionExpr>(getAsExpr()); 212*e5dd7070Spatrick } 213*e5dd7070Spatrick 214*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 215*e5dd7070Spatrick } 216*e5dd7070Spatrick 217*e5dd7070Spatrick bool TemplateArgument::containsUnexpandedParameterPack() const { 218*e5dd7070Spatrick switch (getKind()) { 219*e5dd7070Spatrick case Null: 220*e5dd7070Spatrick case Declaration: 221*e5dd7070Spatrick case Integral: 222*e5dd7070Spatrick case TemplateExpansion: 223*e5dd7070Spatrick case NullPtr: 224*e5dd7070Spatrick break; 225*e5dd7070Spatrick 226*e5dd7070Spatrick case Type: 227*e5dd7070Spatrick if (getAsType()->containsUnexpandedParameterPack()) 228*e5dd7070Spatrick return true; 229*e5dd7070Spatrick break; 230*e5dd7070Spatrick 231*e5dd7070Spatrick case Template: 232*e5dd7070Spatrick if (getAsTemplate().containsUnexpandedParameterPack()) 233*e5dd7070Spatrick return true; 234*e5dd7070Spatrick break; 235*e5dd7070Spatrick 236*e5dd7070Spatrick case Expression: 237*e5dd7070Spatrick if (getAsExpr()->containsUnexpandedParameterPack()) 238*e5dd7070Spatrick return true; 239*e5dd7070Spatrick break; 240*e5dd7070Spatrick 241*e5dd7070Spatrick case Pack: 242*e5dd7070Spatrick for (const auto &P : pack_elements()) 243*e5dd7070Spatrick if (P.containsUnexpandedParameterPack()) 244*e5dd7070Spatrick return true; 245*e5dd7070Spatrick 246*e5dd7070Spatrick break; 247*e5dd7070Spatrick } 248*e5dd7070Spatrick 249*e5dd7070Spatrick return false; 250*e5dd7070Spatrick } 251*e5dd7070Spatrick 252*e5dd7070Spatrick Optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 253*e5dd7070Spatrick assert(getKind() == TemplateExpansion); 254*e5dd7070Spatrick if (TemplateArg.NumExpansions) 255*e5dd7070Spatrick return TemplateArg.NumExpansions - 1; 256*e5dd7070Spatrick 257*e5dd7070Spatrick return None; 258*e5dd7070Spatrick } 259*e5dd7070Spatrick 260*e5dd7070Spatrick QualType TemplateArgument::getNonTypeTemplateArgumentType() const { 261*e5dd7070Spatrick switch (getKind()) { 262*e5dd7070Spatrick case TemplateArgument::Null: 263*e5dd7070Spatrick case TemplateArgument::Type: 264*e5dd7070Spatrick case TemplateArgument::Template: 265*e5dd7070Spatrick case TemplateArgument::TemplateExpansion: 266*e5dd7070Spatrick case TemplateArgument::Pack: 267*e5dd7070Spatrick return QualType(); 268*e5dd7070Spatrick 269*e5dd7070Spatrick case TemplateArgument::Integral: 270*e5dd7070Spatrick return getIntegralType(); 271*e5dd7070Spatrick 272*e5dd7070Spatrick case TemplateArgument::Expression: 273*e5dd7070Spatrick return getAsExpr()->getType(); 274*e5dd7070Spatrick 275*e5dd7070Spatrick case TemplateArgument::Declaration: 276*e5dd7070Spatrick return getParamTypeForDecl(); 277*e5dd7070Spatrick 278*e5dd7070Spatrick case TemplateArgument::NullPtr: 279*e5dd7070Spatrick return getNullPtrType(); 280*e5dd7070Spatrick } 281*e5dd7070Spatrick 282*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 283*e5dd7070Spatrick } 284*e5dd7070Spatrick 285*e5dd7070Spatrick void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 286*e5dd7070Spatrick const ASTContext &Context) const { 287*e5dd7070Spatrick ID.AddInteger(getKind()); 288*e5dd7070Spatrick switch (getKind()) { 289*e5dd7070Spatrick case Null: 290*e5dd7070Spatrick break; 291*e5dd7070Spatrick 292*e5dd7070Spatrick case Type: 293*e5dd7070Spatrick getAsType().Profile(ID); 294*e5dd7070Spatrick break; 295*e5dd7070Spatrick 296*e5dd7070Spatrick case NullPtr: 297*e5dd7070Spatrick getNullPtrType().Profile(ID); 298*e5dd7070Spatrick break; 299*e5dd7070Spatrick 300*e5dd7070Spatrick case Declaration: 301*e5dd7070Spatrick ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr); 302*e5dd7070Spatrick break; 303*e5dd7070Spatrick 304*e5dd7070Spatrick case Template: 305*e5dd7070Spatrick case TemplateExpansion: { 306*e5dd7070Spatrick TemplateName Template = getAsTemplateOrTemplatePattern(); 307*e5dd7070Spatrick if (TemplateTemplateParmDecl *TTP 308*e5dd7070Spatrick = dyn_cast_or_null<TemplateTemplateParmDecl>( 309*e5dd7070Spatrick Template.getAsTemplateDecl())) { 310*e5dd7070Spatrick ID.AddBoolean(true); 311*e5dd7070Spatrick ID.AddInteger(TTP->getDepth()); 312*e5dd7070Spatrick ID.AddInteger(TTP->getPosition()); 313*e5dd7070Spatrick ID.AddBoolean(TTP->isParameterPack()); 314*e5dd7070Spatrick } else { 315*e5dd7070Spatrick ID.AddBoolean(false); 316*e5dd7070Spatrick ID.AddPointer(Context.getCanonicalTemplateName(Template) 317*e5dd7070Spatrick .getAsVoidPointer()); 318*e5dd7070Spatrick } 319*e5dd7070Spatrick break; 320*e5dd7070Spatrick } 321*e5dd7070Spatrick 322*e5dd7070Spatrick case Integral: 323*e5dd7070Spatrick getAsIntegral().Profile(ID); 324*e5dd7070Spatrick getIntegralType().Profile(ID); 325*e5dd7070Spatrick break; 326*e5dd7070Spatrick 327*e5dd7070Spatrick case Expression: 328*e5dd7070Spatrick getAsExpr()->Profile(ID, Context, true); 329*e5dd7070Spatrick break; 330*e5dd7070Spatrick 331*e5dd7070Spatrick case Pack: 332*e5dd7070Spatrick ID.AddInteger(Args.NumArgs); 333*e5dd7070Spatrick for (unsigned I = 0; I != Args.NumArgs; ++I) 334*e5dd7070Spatrick Args.Args[I].Profile(ID, Context); 335*e5dd7070Spatrick } 336*e5dd7070Spatrick } 337*e5dd7070Spatrick 338*e5dd7070Spatrick bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 339*e5dd7070Spatrick if (getKind() != Other.getKind()) return false; 340*e5dd7070Spatrick 341*e5dd7070Spatrick switch (getKind()) { 342*e5dd7070Spatrick case Null: 343*e5dd7070Spatrick case Type: 344*e5dd7070Spatrick case Expression: 345*e5dd7070Spatrick case Template: 346*e5dd7070Spatrick case TemplateExpansion: 347*e5dd7070Spatrick case NullPtr: 348*e5dd7070Spatrick return TypeOrValue.V == Other.TypeOrValue.V; 349*e5dd7070Spatrick 350*e5dd7070Spatrick case Declaration: 351*e5dd7070Spatrick return getAsDecl() == Other.getAsDecl(); 352*e5dd7070Spatrick 353*e5dd7070Spatrick case Integral: 354*e5dd7070Spatrick return getIntegralType() == Other.getIntegralType() && 355*e5dd7070Spatrick getAsIntegral() == Other.getAsIntegral(); 356*e5dd7070Spatrick 357*e5dd7070Spatrick case Pack: 358*e5dd7070Spatrick if (Args.NumArgs != Other.Args.NumArgs) return false; 359*e5dd7070Spatrick for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 360*e5dd7070Spatrick if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 361*e5dd7070Spatrick return false; 362*e5dd7070Spatrick return true; 363*e5dd7070Spatrick } 364*e5dd7070Spatrick 365*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 366*e5dd7070Spatrick } 367*e5dd7070Spatrick 368*e5dd7070Spatrick TemplateArgument TemplateArgument::getPackExpansionPattern() const { 369*e5dd7070Spatrick assert(isPackExpansion()); 370*e5dd7070Spatrick 371*e5dd7070Spatrick switch (getKind()) { 372*e5dd7070Spatrick case Type: 373*e5dd7070Spatrick return getAsType()->castAs<PackExpansionType>()->getPattern(); 374*e5dd7070Spatrick 375*e5dd7070Spatrick case Expression: 376*e5dd7070Spatrick return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 377*e5dd7070Spatrick 378*e5dd7070Spatrick case TemplateExpansion: 379*e5dd7070Spatrick return TemplateArgument(getAsTemplateOrTemplatePattern()); 380*e5dd7070Spatrick 381*e5dd7070Spatrick case Declaration: 382*e5dd7070Spatrick case Integral: 383*e5dd7070Spatrick case Pack: 384*e5dd7070Spatrick case Null: 385*e5dd7070Spatrick case Template: 386*e5dd7070Spatrick case NullPtr: 387*e5dd7070Spatrick return TemplateArgument(); 388*e5dd7070Spatrick } 389*e5dd7070Spatrick 390*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 391*e5dd7070Spatrick } 392*e5dd7070Spatrick 393*e5dd7070Spatrick void TemplateArgument::print(const PrintingPolicy &Policy, 394*e5dd7070Spatrick raw_ostream &Out) const { 395*e5dd7070Spatrick switch (getKind()) { 396*e5dd7070Spatrick case Null: 397*e5dd7070Spatrick Out << "(no value)"; 398*e5dd7070Spatrick break; 399*e5dd7070Spatrick 400*e5dd7070Spatrick case Type: { 401*e5dd7070Spatrick PrintingPolicy SubPolicy(Policy); 402*e5dd7070Spatrick SubPolicy.SuppressStrongLifetime = true; 403*e5dd7070Spatrick getAsType().print(Out, SubPolicy); 404*e5dd7070Spatrick break; 405*e5dd7070Spatrick } 406*e5dd7070Spatrick 407*e5dd7070Spatrick case Declaration: { 408*e5dd7070Spatrick NamedDecl *ND = getAsDecl(); 409*e5dd7070Spatrick Out << '&'; 410*e5dd7070Spatrick if (ND->getDeclName()) { 411*e5dd7070Spatrick // FIXME: distinguish between pointer and reference args? 412*e5dd7070Spatrick ND->printQualifiedName(Out); 413*e5dd7070Spatrick } else { 414*e5dd7070Spatrick Out << "(anonymous)"; 415*e5dd7070Spatrick } 416*e5dd7070Spatrick break; 417*e5dd7070Spatrick } 418*e5dd7070Spatrick 419*e5dd7070Spatrick case NullPtr: 420*e5dd7070Spatrick Out << "nullptr"; 421*e5dd7070Spatrick break; 422*e5dd7070Spatrick 423*e5dd7070Spatrick case Template: 424*e5dd7070Spatrick getAsTemplate().print(Out, Policy); 425*e5dd7070Spatrick break; 426*e5dd7070Spatrick 427*e5dd7070Spatrick case TemplateExpansion: 428*e5dd7070Spatrick getAsTemplateOrTemplatePattern().print(Out, Policy); 429*e5dd7070Spatrick Out << "..."; 430*e5dd7070Spatrick break; 431*e5dd7070Spatrick 432*e5dd7070Spatrick case Integral: 433*e5dd7070Spatrick printIntegral(*this, Out, Policy); 434*e5dd7070Spatrick break; 435*e5dd7070Spatrick 436*e5dd7070Spatrick case Expression: 437*e5dd7070Spatrick getAsExpr()->printPretty(Out, nullptr, Policy); 438*e5dd7070Spatrick break; 439*e5dd7070Spatrick 440*e5dd7070Spatrick case Pack: 441*e5dd7070Spatrick Out << "<"; 442*e5dd7070Spatrick bool First = true; 443*e5dd7070Spatrick for (const auto &P : pack_elements()) { 444*e5dd7070Spatrick if (First) 445*e5dd7070Spatrick First = false; 446*e5dd7070Spatrick else 447*e5dd7070Spatrick Out << ", "; 448*e5dd7070Spatrick 449*e5dd7070Spatrick P.print(Policy, Out); 450*e5dd7070Spatrick } 451*e5dd7070Spatrick Out << ">"; 452*e5dd7070Spatrick break; 453*e5dd7070Spatrick } 454*e5dd7070Spatrick } 455*e5dd7070Spatrick 456*e5dd7070Spatrick void TemplateArgument::dump(raw_ostream &Out) const { 457*e5dd7070Spatrick LangOptions LO; // FIXME! see also TemplateName::dump(). 458*e5dd7070Spatrick LO.CPlusPlus = true; 459*e5dd7070Spatrick LO.Bool = true; 460*e5dd7070Spatrick print(PrintingPolicy(LO), Out); 461*e5dd7070Spatrick } 462*e5dd7070Spatrick 463*e5dd7070Spatrick LLVM_DUMP_METHOD void TemplateArgument::dump() const { dump(llvm::errs()); } 464*e5dd7070Spatrick 465*e5dd7070Spatrick //===----------------------------------------------------------------------===// 466*e5dd7070Spatrick // TemplateArgumentLoc Implementation 467*e5dd7070Spatrick //===----------------------------------------------------------------------===// 468*e5dd7070Spatrick 469*e5dd7070Spatrick SourceRange TemplateArgumentLoc::getSourceRange() const { 470*e5dd7070Spatrick switch (Argument.getKind()) { 471*e5dd7070Spatrick case TemplateArgument::Expression: 472*e5dd7070Spatrick return getSourceExpression()->getSourceRange(); 473*e5dd7070Spatrick 474*e5dd7070Spatrick case TemplateArgument::Declaration: 475*e5dd7070Spatrick return getSourceDeclExpression()->getSourceRange(); 476*e5dd7070Spatrick 477*e5dd7070Spatrick case TemplateArgument::NullPtr: 478*e5dd7070Spatrick return getSourceNullPtrExpression()->getSourceRange(); 479*e5dd7070Spatrick 480*e5dd7070Spatrick case TemplateArgument::Type: 481*e5dd7070Spatrick if (TypeSourceInfo *TSI = getTypeSourceInfo()) 482*e5dd7070Spatrick return TSI->getTypeLoc().getSourceRange(); 483*e5dd7070Spatrick else 484*e5dd7070Spatrick return SourceRange(); 485*e5dd7070Spatrick 486*e5dd7070Spatrick case TemplateArgument::Template: 487*e5dd7070Spatrick if (getTemplateQualifierLoc()) 488*e5dd7070Spatrick return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 489*e5dd7070Spatrick getTemplateNameLoc()); 490*e5dd7070Spatrick return SourceRange(getTemplateNameLoc()); 491*e5dd7070Spatrick 492*e5dd7070Spatrick case TemplateArgument::TemplateExpansion: 493*e5dd7070Spatrick if (getTemplateQualifierLoc()) 494*e5dd7070Spatrick return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 495*e5dd7070Spatrick getTemplateEllipsisLoc()); 496*e5dd7070Spatrick return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 497*e5dd7070Spatrick 498*e5dd7070Spatrick case TemplateArgument::Integral: 499*e5dd7070Spatrick return getSourceIntegralExpression()->getSourceRange(); 500*e5dd7070Spatrick 501*e5dd7070Spatrick case TemplateArgument::Pack: 502*e5dd7070Spatrick case TemplateArgument::Null: 503*e5dd7070Spatrick return SourceRange(); 504*e5dd7070Spatrick } 505*e5dd7070Spatrick 506*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 507*e5dd7070Spatrick } 508*e5dd7070Spatrick 509*e5dd7070Spatrick const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, 510*e5dd7070Spatrick const TemplateArgument &Arg) { 511*e5dd7070Spatrick switch (Arg.getKind()) { 512*e5dd7070Spatrick case TemplateArgument::Null: 513*e5dd7070Spatrick // This is bad, but not as bad as crashing because of argument 514*e5dd7070Spatrick // count mismatches. 515*e5dd7070Spatrick return DB << "(null template argument)"; 516*e5dd7070Spatrick 517*e5dd7070Spatrick case TemplateArgument::Type: 518*e5dd7070Spatrick return DB << Arg.getAsType(); 519*e5dd7070Spatrick 520*e5dd7070Spatrick case TemplateArgument::Declaration: 521*e5dd7070Spatrick return DB << Arg.getAsDecl(); 522*e5dd7070Spatrick 523*e5dd7070Spatrick case TemplateArgument::NullPtr: 524*e5dd7070Spatrick return DB << "nullptr"; 525*e5dd7070Spatrick 526*e5dd7070Spatrick case TemplateArgument::Integral: 527*e5dd7070Spatrick return DB << Arg.getAsIntegral().toString(10); 528*e5dd7070Spatrick 529*e5dd7070Spatrick case TemplateArgument::Template: 530*e5dd7070Spatrick return DB << Arg.getAsTemplate(); 531*e5dd7070Spatrick 532*e5dd7070Spatrick case TemplateArgument::TemplateExpansion: 533*e5dd7070Spatrick return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 534*e5dd7070Spatrick 535*e5dd7070Spatrick case TemplateArgument::Expression: { 536*e5dd7070Spatrick // This shouldn't actually ever happen, so it's okay that we're 537*e5dd7070Spatrick // regurgitating an expression here. 538*e5dd7070Spatrick // FIXME: We're guessing at LangOptions! 539*e5dd7070Spatrick SmallString<32> Str; 540*e5dd7070Spatrick llvm::raw_svector_ostream OS(Str); 541*e5dd7070Spatrick LangOptions LangOpts; 542*e5dd7070Spatrick LangOpts.CPlusPlus = true; 543*e5dd7070Spatrick PrintingPolicy Policy(LangOpts); 544*e5dd7070Spatrick Arg.getAsExpr()->printPretty(OS, nullptr, Policy); 545*e5dd7070Spatrick return DB << OS.str(); 546*e5dd7070Spatrick } 547*e5dd7070Spatrick 548*e5dd7070Spatrick case TemplateArgument::Pack: { 549*e5dd7070Spatrick // FIXME: We're guessing at LangOptions! 550*e5dd7070Spatrick SmallString<32> Str; 551*e5dd7070Spatrick llvm::raw_svector_ostream OS(Str); 552*e5dd7070Spatrick LangOptions LangOpts; 553*e5dd7070Spatrick LangOpts.CPlusPlus = true; 554*e5dd7070Spatrick PrintingPolicy Policy(LangOpts); 555*e5dd7070Spatrick Arg.print(Policy, OS); 556*e5dd7070Spatrick return DB << OS.str(); 557*e5dd7070Spatrick } 558*e5dd7070Spatrick } 559*e5dd7070Spatrick 560*e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!"); 561*e5dd7070Spatrick } 562*e5dd7070Spatrick 563*e5dd7070Spatrick const ASTTemplateArgumentListInfo * 564*e5dd7070Spatrick ASTTemplateArgumentListInfo::Create(const ASTContext &C, 565*e5dd7070Spatrick const TemplateArgumentListInfo &List) { 566*e5dd7070Spatrick std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); 567*e5dd7070Spatrick void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 568*e5dd7070Spatrick return new (Mem) ASTTemplateArgumentListInfo(List); 569*e5dd7070Spatrick } 570*e5dd7070Spatrick 571*e5dd7070Spatrick ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 572*e5dd7070Spatrick const TemplateArgumentListInfo &Info) { 573*e5dd7070Spatrick LAngleLoc = Info.getLAngleLoc(); 574*e5dd7070Spatrick RAngleLoc = Info.getRAngleLoc(); 575*e5dd7070Spatrick NumTemplateArgs = Info.size(); 576*e5dd7070Spatrick 577*e5dd7070Spatrick TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 578*e5dd7070Spatrick for (unsigned i = 0; i != NumTemplateArgs; ++i) 579*e5dd7070Spatrick new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 580*e5dd7070Spatrick } 581*e5dd7070Spatrick 582*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom( 583*e5dd7070Spatrick SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 584*e5dd7070Spatrick TemplateArgumentLoc *OutArgArray) { 585*e5dd7070Spatrick this->TemplateKWLoc = TemplateKWLoc; 586*e5dd7070Spatrick LAngleLoc = Info.getLAngleLoc(); 587*e5dd7070Spatrick RAngleLoc = Info.getRAngleLoc(); 588*e5dd7070Spatrick NumTemplateArgs = Info.size(); 589*e5dd7070Spatrick 590*e5dd7070Spatrick for (unsigned i = 0; i != NumTemplateArgs; ++i) 591*e5dd7070Spatrick new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 592*e5dd7070Spatrick } 593*e5dd7070Spatrick 594*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 595*e5dd7070Spatrick assert(TemplateKWLoc.isValid()); 596*e5dd7070Spatrick LAngleLoc = SourceLocation(); 597*e5dd7070Spatrick RAngleLoc = SourceLocation(); 598*e5dd7070Spatrick this->TemplateKWLoc = TemplateKWLoc; 599*e5dd7070Spatrick NumTemplateArgs = 0; 600*e5dd7070Spatrick } 601*e5dd7070Spatrick 602*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::initializeFrom( 603*e5dd7070Spatrick SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 604*e5dd7070Spatrick TemplateArgumentLoc *OutArgArray, bool &Dependent, 605*e5dd7070Spatrick bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) { 606*e5dd7070Spatrick this->TemplateKWLoc = TemplateKWLoc; 607*e5dd7070Spatrick LAngleLoc = Info.getLAngleLoc(); 608*e5dd7070Spatrick RAngleLoc = Info.getRAngleLoc(); 609*e5dd7070Spatrick NumTemplateArgs = Info.size(); 610*e5dd7070Spatrick 611*e5dd7070Spatrick for (unsigned i = 0; i != NumTemplateArgs; ++i) { 612*e5dd7070Spatrick Dependent = Dependent || Info[i].getArgument().isDependent(); 613*e5dd7070Spatrick InstantiationDependent = InstantiationDependent || 614*e5dd7070Spatrick Info[i].getArgument().isInstantiationDependent(); 615*e5dd7070Spatrick ContainsUnexpandedParameterPack = 616*e5dd7070Spatrick ContainsUnexpandedParameterPack || 617*e5dd7070Spatrick Info[i].getArgument().containsUnexpandedParameterPack(); 618*e5dd7070Spatrick 619*e5dd7070Spatrick new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 620*e5dd7070Spatrick } 621*e5dd7070Spatrick } 622*e5dd7070Spatrick 623*e5dd7070Spatrick void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, 624*e5dd7070Spatrick TemplateArgumentListInfo &Info) const { 625*e5dd7070Spatrick Info.setLAngleLoc(LAngleLoc); 626*e5dd7070Spatrick Info.setRAngleLoc(RAngleLoc); 627*e5dd7070Spatrick for (unsigned I = 0; I != NumTemplateArgs; ++I) 628*e5dd7070Spatrick Info.addArgument(ArgArray[I]); 629*e5dd7070Spatrick } 630