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