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