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