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