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