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