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