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