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