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