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