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