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 // Dependent types are not supposed to be described as 226 // TemplateParamObjectDecls. 227 if (T->isDependentType() || T->isInstantiationDependentType()) 228 return nullptr; 229 return Ctx.getTemplateParamObjectDecl(T, V); 230 } 231 232 // Pointers and references with an empty path use the special 'Declaration' 233 // representation. 234 if (V.isLValue() && V.hasLValuePath() && V.getLValuePath().empty() && 235 !V.isLValueOnePastTheEnd()) 236 return V.getLValueBase().dyn_cast<const ValueDecl *>(); 237 238 // Everything else uses the 'structural' representation. 239 return nullptr; 240 } 241 242 TemplateArgument::TemplateArgument(const ASTContext &Ctx, QualType Type, 243 const APValue &V, bool IsDefaulted) { 244 if (Type->isIntegralOrEnumerationType() && V.isInt()) 245 initFromIntegral(Ctx, V.getInt(), Type, IsDefaulted); 246 else if ((V.isLValue() && V.isNullPointer()) || 247 (V.isMemberPointer() && !V.getMemberPointerDecl())) 248 initFromType(Type, /*isNullPtr=*/true, IsDefaulted); 249 else if (const ValueDecl *VD = getAsSimpleValueDeclRef(Ctx, Type, V)) 250 // FIXME: The Declaration form should expose a const ValueDecl*. 251 initFromDeclaration(const_cast<ValueDecl *>(VD), Type, IsDefaulted); 252 else 253 initFromStructural(Ctx, Type, V, IsDefaulted); 254 } 255 256 TemplateArgument 257 TemplateArgument::CreatePackCopy(ASTContext &Context, 258 ArrayRef<TemplateArgument> Args) { 259 if (Args.empty()) 260 return getEmptyPack(); 261 262 return TemplateArgument(Args.copy(Context)); 263 } 264 265 TemplateArgumentDependence TemplateArgument::getDependence() const { 266 auto Deps = TemplateArgumentDependence::None; 267 switch (getKind()) { 268 case Null: 269 llvm_unreachable("Should not have a NULL template argument"); 270 271 case Type: 272 Deps = toTemplateArgumentDependence(getAsType()->getDependence()); 273 if (isa<PackExpansionType>(getAsType())) 274 Deps |= TemplateArgumentDependence::Dependent; 275 return Deps; 276 277 case Template: 278 return toTemplateArgumentDependence(getAsTemplate().getDependence()); 279 280 case TemplateExpansion: 281 return TemplateArgumentDependence::Dependent | 282 TemplateArgumentDependence::Instantiation; 283 284 case Declaration: { 285 auto *DC = dyn_cast<DeclContext>(getAsDecl()); 286 if (!DC) 287 DC = getAsDecl()->getDeclContext(); 288 if (DC->isDependentContext()) 289 Deps = TemplateArgumentDependence::Dependent | 290 TemplateArgumentDependence::Instantiation; 291 return Deps; 292 } 293 294 case NullPtr: 295 case Integral: 296 case StructuralValue: 297 return TemplateArgumentDependence::None; 298 299 case Expression: 300 Deps = toTemplateArgumentDependence(getAsExpr()->getDependence()); 301 if (isa<PackExpansionExpr>(getAsExpr())) 302 Deps |= TemplateArgumentDependence::Dependent | 303 TemplateArgumentDependence::Instantiation; 304 return Deps; 305 306 case Pack: 307 for (const auto &P : pack_elements()) 308 Deps |= P.getDependence(); 309 return Deps; 310 } 311 llvm_unreachable("unhandled ArgKind"); 312 } 313 314 bool TemplateArgument::isDependent() const { 315 return getDependence() & TemplateArgumentDependence::Dependent; 316 } 317 318 bool TemplateArgument::isInstantiationDependent() const { 319 return getDependence() & TemplateArgumentDependence::Instantiation; 320 } 321 322 bool TemplateArgument::isPackExpansion() const { 323 switch (getKind()) { 324 case Null: 325 case Declaration: 326 case Integral: 327 case StructuralValue: 328 case Pack: 329 case Template: 330 case NullPtr: 331 return false; 332 333 case TemplateExpansion: 334 return true; 335 336 case Type: 337 return isa<PackExpansionType>(getAsType()); 338 339 case Expression: 340 return isa<PackExpansionExpr>(getAsExpr()); 341 } 342 343 llvm_unreachable("Invalid TemplateArgument Kind!"); 344 } 345 346 bool TemplateArgument::containsUnexpandedParameterPack() const { 347 return getDependence() & TemplateArgumentDependence::UnexpandedPack; 348 } 349 350 std::optional<unsigned> TemplateArgument::getNumTemplateExpansions() const { 351 assert(getKind() == TemplateExpansion); 352 if (TemplateArg.NumExpansions) 353 return TemplateArg.NumExpansions - 1; 354 355 return std::nullopt; 356 } 357 358 QualType TemplateArgument::getNonTypeTemplateArgumentType() const { 359 switch (getKind()) { 360 case TemplateArgument::Null: 361 case TemplateArgument::Type: 362 case TemplateArgument::Template: 363 case TemplateArgument::TemplateExpansion: 364 case TemplateArgument::Pack: 365 return QualType(); 366 367 case TemplateArgument::Integral: 368 return getIntegralType(); 369 370 case TemplateArgument::Expression: 371 return getAsExpr()->getType(); 372 373 case TemplateArgument::Declaration: 374 return getParamTypeForDecl(); 375 376 case TemplateArgument::NullPtr: 377 return getNullPtrType(); 378 379 case TemplateArgument::StructuralValue: 380 return getStructuralValueType(); 381 } 382 383 llvm_unreachable("Invalid TemplateArgument Kind!"); 384 } 385 386 void TemplateArgument::Profile(llvm::FoldingSetNodeID &ID, 387 const ASTContext &Context) const { 388 ID.AddInteger(getKind()); 389 switch (getKind()) { 390 case Null: 391 break; 392 393 case Type: 394 getAsType().Profile(ID); 395 break; 396 397 case NullPtr: 398 getNullPtrType().Profile(ID); 399 break; 400 401 case Declaration: 402 getParamTypeForDecl().Profile(ID); 403 ID.AddPointer(getAsDecl()); 404 break; 405 406 case TemplateExpansion: 407 ID.AddInteger(TemplateArg.NumExpansions); 408 [[fallthrough]]; 409 case Template: 410 ID.AddPointer(TemplateArg.Name); 411 break; 412 413 case Integral: 414 getIntegralType().Profile(ID); 415 getAsIntegral().Profile(ID); 416 break; 417 418 case StructuralValue: 419 getStructuralValueType().Profile(ID); 420 getAsStructuralValue().Profile(ID); 421 break; 422 423 case Expression: 424 getAsExpr()->Profile(ID, Context, true); 425 break; 426 427 case Pack: 428 ID.AddInteger(Args.NumArgs); 429 for (unsigned I = 0; I != Args.NumArgs; ++I) 430 Args.Args[I].Profile(ID, Context); 431 } 432 } 433 434 bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { 435 if (getKind() != Other.getKind()) return false; 436 437 switch (getKind()) { 438 case Null: 439 case Type: 440 case Expression: 441 case NullPtr: 442 return TypeOrValue.V == Other.TypeOrValue.V; 443 444 case Template: 445 case TemplateExpansion: 446 return TemplateArg.Name == Other.TemplateArg.Name && 447 TemplateArg.NumExpansions == Other.TemplateArg.NumExpansions; 448 449 case Declaration: 450 return getAsDecl() == Other.getAsDecl() && 451 getParamTypeForDecl() == Other.getParamTypeForDecl(); 452 453 case Integral: 454 return getIntegralType() == Other.getIntegralType() && 455 getAsIntegral() == Other.getAsIntegral(); 456 457 case StructuralValue: { 458 if (getStructuralValueType().getCanonicalType() != 459 Other.getStructuralValueType().getCanonicalType()) 460 return false; 461 462 llvm::FoldingSetNodeID A, B; 463 getAsStructuralValue().Profile(A); 464 Other.getAsStructuralValue().Profile(B); 465 return A == B; 466 } 467 468 case Pack: 469 if (Args.NumArgs != Other.Args.NumArgs) return false; 470 for (unsigned I = 0, E = Args.NumArgs; I != E; ++I) 471 if (!Args.Args[I].structurallyEquals(Other.Args.Args[I])) 472 return false; 473 return true; 474 } 475 476 llvm_unreachable("Invalid TemplateArgument Kind!"); 477 } 478 479 TemplateArgument TemplateArgument::getPackExpansionPattern() const { 480 assert(isPackExpansion()); 481 482 switch (getKind()) { 483 case Type: 484 return getAsType()->castAs<PackExpansionType>()->getPattern(); 485 486 case Expression: 487 return cast<PackExpansionExpr>(getAsExpr())->getPattern(); 488 489 case TemplateExpansion: 490 return TemplateArgument(getAsTemplateOrTemplatePattern()); 491 492 case Declaration: 493 case Integral: 494 case StructuralValue: 495 case Pack: 496 case Null: 497 case Template: 498 case NullPtr: 499 return TemplateArgument(); 500 } 501 502 llvm_unreachable("Invalid TemplateArgument Kind!"); 503 } 504 505 void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, 506 bool IncludeType) const { 507 508 switch (getKind()) { 509 case Null: 510 Out << "(no value)"; 511 break; 512 513 case Type: { 514 PrintingPolicy SubPolicy(Policy); 515 SubPolicy.SuppressStrongLifetime = true; 516 getAsType().print(Out, SubPolicy); 517 break; 518 } 519 520 case Declaration: { 521 NamedDecl *ND = getAsDecl(); 522 if (getParamTypeForDecl()->isRecordType()) { 523 if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) { 524 TPO->getType().getUnqualifiedType().print(Out, Policy); 525 TPO->printAsInit(Out, Policy); 526 break; 527 } 528 } 529 if (auto *VD = dyn_cast<ValueDecl>(ND)) { 530 if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType())) 531 Out << "&"; 532 } 533 ND->printQualifiedName(Out); 534 break; 535 } 536 537 case StructuralValue: 538 getAsStructuralValue().printPretty(Out, Policy, getStructuralValueType()); 539 break; 540 541 case NullPtr: 542 // FIXME: Include the type if it's not obvious from the context. 543 Out << "nullptr"; 544 break; 545 546 case Template: { 547 getAsTemplate().print(Out, Policy); 548 break; 549 } 550 551 case TemplateExpansion: 552 getAsTemplateOrTemplatePattern().print(Out, Policy); 553 Out << "..."; 554 break; 555 556 case Integral: 557 printIntegral(*this, Out, Policy, IncludeType); 558 break; 559 560 case Expression: 561 getAsExpr()->printPretty(Out, nullptr, Policy); 562 break; 563 564 case Pack: 565 Out << "<"; 566 bool First = true; 567 for (const auto &P : pack_elements()) { 568 if (First) 569 First = false; 570 else 571 Out << ", "; 572 573 P.print(Policy, Out, IncludeType); 574 } 575 Out << ">"; 576 break; 577 } 578 } 579 580 //===----------------------------------------------------------------------===// 581 // TemplateArgumentLoc Implementation 582 //===----------------------------------------------------------------------===// 583 584 SourceRange TemplateArgumentLoc::getSourceRange() const { 585 switch (Argument.getKind()) { 586 case TemplateArgument::Expression: 587 return getSourceExpression()->getSourceRange(); 588 589 case TemplateArgument::Declaration: 590 return getSourceDeclExpression()->getSourceRange(); 591 592 case TemplateArgument::NullPtr: 593 return getSourceNullPtrExpression()->getSourceRange(); 594 595 case TemplateArgument::Type: 596 if (TypeSourceInfo *TSI = getTypeSourceInfo()) 597 return TSI->getTypeLoc().getSourceRange(); 598 else 599 return SourceRange(); 600 601 case TemplateArgument::Template: 602 if (getTemplateQualifierLoc()) 603 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 604 getTemplateNameLoc()); 605 return SourceRange(getTemplateNameLoc()); 606 607 case TemplateArgument::TemplateExpansion: 608 if (getTemplateQualifierLoc()) 609 return SourceRange(getTemplateQualifierLoc().getBeginLoc(), 610 getTemplateEllipsisLoc()); 611 return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc()); 612 613 case TemplateArgument::Integral: 614 return getSourceIntegralExpression()->getSourceRange(); 615 616 case TemplateArgument::StructuralValue: 617 return getSourceStructuralValueExpression()->getSourceRange(); 618 619 case TemplateArgument::Pack: 620 case TemplateArgument::Null: 621 return SourceRange(); 622 } 623 624 llvm_unreachable("Invalid TemplateArgument Kind!"); 625 } 626 627 template <typename T> 628 static const T &DiagTemplateArg(const T &DB, const TemplateArgument &Arg) { 629 switch (Arg.getKind()) { 630 case TemplateArgument::Null: 631 // This is bad, but not as bad as crashing because of argument 632 // count mismatches. 633 return DB << "(null template argument)"; 634 635 case TemplateArgument::Type: 636 return DB << Arg.getAsType(); 637 638 case TemplateArgument::Declaration: 639 return DB << Arg.getAsDecl(); 640 641 case TemplateArgument::NullPtr: 642 return DB << "nullptr"; 643 644 case TemplateArgument::Integral: 645 return DB << toString(Arg.getAsIntegral(), 10); 646 647 case TemplateArgument::StructuralValue: { 648 // FIXME: We're guessing at LangOptions! 649 SmallString<32> Str; 650 llvm::raw_svector_ostream OS(Str); 651 LangOptions LangOpts; 652 LangOpts.CPlusPlus = true; 653 PrintingPolicy Policy(LangOpts); 654 Arg.getAsStructuralValue().printPretty(OS, Policy, 655 Arg.getStructuralValueType()); 656 return DB << OS.str(); 657 } 658 659 case TemplateArgument::Template: 660 return DB << Arg.getAsTemplate(); 661 662 case TemplateArgument::TemplateExpansion: 663 return DB << Arg.getAsTemplateOrTemplatePattern() << "..."; 664 665 case TemplateArgument::Expression: { 666 // This shouldn't actually ever happen, so it's okay that we're 667 // regurgitating an expression here. 668 // FIXME: We're guessing at LangOptions! 669 SmallString<32> Str; 670 llvm::raw_svector_ostream OS(Str); 671 LangOptions LangOpts; 672 LangOpts.CPlusPlus = true; 673 PrintingPolicy Policy(LangOpts); 674 Arg.getAsExpr()->printPretty(OS, nullptr, Policy); 675 return DB << OS.str(); 676 } 677 678 case TemplateArgument::Pack: { 679 // FIXME: We're guessing at LangOptions! 680 SmallString<32> Str; 681 llvm::raw_svector_ostream OS(Str); 682 LangOptions LangOpts; 683 LangOpts.CPlusPlus = true; 684 PrintingPolicy Policy(LangOpts); 685 Arg.print(Policy, OS, /*IncludeType*/ true); 686 return DB << OS.str(); 687 } 688 } 689 690 llvm_unreachable("Invalid TemplateArgument Kind!"); 691 } 692 693 const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB, 694 const TemplateArgument &Arg) { 695 return DiagTemplateArg(DB, Arg); 696 } 697 698 clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo( 699 ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, 700 SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) { 701 TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo; 702 Template->Qualifier = QualifierLoc.getNestedNameSpecifier(); 703 Template->QualifierLocData = QualifierLoc.getOpaqueData(); 704 Template->TemplateNameLoc = TemplateNameLoc; 705 Template->EllipsisLoc = EllipsisLoc; 706 Pointer = Template; 707 } 708 709 const ASTTemplateArgumentListInfo * 710 ASTTemplateArgumentListInfo::Create(const ASTContext &C, 711 const TemplateArgumentListInfo &List) { 712 std::size_t size = totalSizeToAlloc<TemplateArgumentLoc>(List.size()); 713 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 714 return new (Mem) ASTTemplateArgumentListInfo(List); 715 } 716 717 const ASTTemplateArgumentListInfo * 718 ASTTemplateArgumentListInfo::Create(const ASTContext &C, 719 const ASTTemplateArgumentListInfo *List) { 720 if (!List) 721 return nullptr; 722 std::size_t size = 723 totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs()); 724 void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo)); 725 return new (Mem) ASTTemplateArgumentListInfo(List); 726 } 727 728 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 729 const TemplateArgumentListInfo &Info) { 730 LAngleLoc = Info.getLAngleLoc(); 731 RAngleLoc = Info.getRAngleLoc(); 732 NumTemplateArgs = Info.size(); 733 734 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 735 for (unsigned i = 0; i != NumTemplateArgs; ++i) 736 new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]); 737 } 738 739 ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo( 740 const ASTTemplateArgumentListInfo *Info) { 741 LAngleLoc = Info->getLAngleLoc(); 742 RAngleLoc = Info->getRAngleLoc(); 743 NumTemplateArgs = Info->getNumTemplateArgs(); 744 745 TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>(); 746 for (unsigned i = 0; i != NumTemplateArgs; ++i) 747 new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]); 748 } 749 750 void ASTTemplateKWAndArgsInfo::initializeFrom( 751 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 752 TemplateArgumentLoc *OutArgArray) { 753 this->TemplateKWLoc = TemplateKWLoc; 754 LAngleLoc = Info.getLAngleLoc(); 755 RAngleLoc = Info.getRAngleLoc(); 756 NumTemplateArgs = Info.size(); 757 758 for (unsigned i = 0; i != NumTemplateArgs; ++i) 759 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 760 } 761 762 void ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation TemplateKWLoc) { 763 assert(TemplateKWLoc.isValid()); 764 LAngleLoc = SourceLocation(); 765 RAngleLoc = SourceLocation(); 766 this->TemplateKWLoc = TemplateKWLoc; 767 NumTemplateArgs = 0; 768 } 769 770 void ASTTemplateKWAndArgsInfo::initializeFrom( 771 SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, 772 TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence &Deps) { 773 this->TemplateKWLoc = TemplateKWLoc; 774 LAngleLoc = Info.getLAngleLoc(); 775 RAngleLoc = Info.getRAngleLoc(); 776 NumTemplateArgs = Info.size(); 777 778 for (unsigned i = 0; i != NumTemplateArgs; ++i) { 779 Deps |= Info[i].getArgument().getDependence(); 780 781 new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); 782 } 783 } 784 785 void ASTTemplateKWAndArgsInfo::copyInto(const TemplateArgumentLoc *ArgArray, 786 TemplateArgumentListInfo &Info) const { 787 Info.setLAngleLoc(LAngleLoc); 788 Info.setRAngleLoc(RAngleLoc); 789 for (unsigned I = 0; I != NumTemplateArgs; ++I) 790 Info.addArgument(ArgArray[I]); 791 } 792