1 //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===// 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 provides definitions which are common for all kinds of 10 // template representation. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 15 #define LLVM_CLANG_AST_TEMPLATEBASE_H 16 17 #include "clang/AST/DependenceFlags.h" 18 #include "clang/AST/NestedNameSpecifier.h" 19 #include "clang/AST/TemplateName.h" 20 #include "clang/AST/Type.h" 21 #include "clang/Basic/LLVM.h" 22 #include "clang/Basic/SourceLocation.h" 23 #include "llvm/ADT/APInt.h" 24 #include "llvm/ADT/APSInt.h" 25 #include "llvm/ADT/ArrayRef.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/Support/Compiler.h" 28 #include "llvm/Support/TrailingObjects.h" 29 #include <cassert> 30 #include <cstddef> 31 #include <cstdint> 32 #include <optional> 33 34 namespace llvm { 35 36 class FoldingSetNodeID; 37 38 // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a 39 // full definition of Expr, but this file only sees a forward del because of 40 // the dependency. 41 template <> struct PointerLikeTypeTraits<clang::Expr *> { 42 static inline void *getAsVoidPointer(clang::Expr *P) { return P; } 43 static inline clang::Expr *getFromVoidPointer(void *P) { 44 return static_cast<clang::Expr *>(P); 45 } 46 static constexpr int NumLowBitsAvailable = 2; 47 }; 48 49 } // namespace llvm 50 51 namespace clang { 52 53 class ASTContext; 54 class Expr; 55 struct PrintingPolicy; 56 class TypeSourceInfo; 57 class ValueDecl; 58 59 /// Represents a template argument. 60 class TemplateArgument { 61 public: 62 /// The kind of template argument we're storing. 63 enum ArgKind { 64 /// Represents an empty template argument, e.g., one that has not 65 /// been deduced. 66 Null = 0, 67 68 /// The template argument is a type. 69 Type, 70 71 /// The template argument is a declaration that was provided for a pointer, 72 /// reference, or pointer to member non-type template parameter. 73 Declaration, 74 75 /// The template argument is a null pointer or null pointer to member that 76 /// was provided for a non-type template parameter. 77 NullPtr, 78 79 /// The template argument is an integral value stored in an llvm::APSInt 80 /// that was provided for an integral non-type template parameter. 81 Integral, 82 83 /// The template argument is a template name that was provided for a 84 /// template template parameter. 85 Template, 86 87 /// The template argument is a pack expansion of a template name that was 88 /// provided for a template template parameter. 89 TemplateExpansion, 90 91 /// The template argument is an expression, and we've not resolved it to one 92 /// of the other forms yet, either because it's dependent or because we're 93 /// representing a non-canonical template argument (for instance, in a 94 /// TemplateSpecializationType). 95 Expression, 96 97 /// The template argument is actually a parameter pack. Arguments are stored 98 /// in the Args struct. 99 Pack 100 }; 101 102 private: 103 /// The kind of template argument we're storing. 104 105 struct DA { 106 unsigned Kind : 31; 107 unsigned IsDefaulted : 1; 108 void *QT; 109 ValueDecl *D; 110 }; 111 struct I { 112 unsigned Kind : 31; 113 unsigned IsDefaulted : 1; 114 // We store a decomposed APSInt with the data allocated by ASTContext if 115 // BitWidth > 64. The memory may be shared between multiple 116 // TemplateArgument instances. 117 unsigned BitWidth : 31; 118 unsigned IsUnsigned : 1; 119 union { 120 /// Used to store the <= 64 bits integer value. 121 uint64_t VAL; 122 123 /// Used to store the >64 bits integer value. 124 const uint64_t *pVal; 125 }; 126 void *Type; 127 }; 128 struct A { 129 unsigned Kind : 31; 130 unsigned IsDefaulted : 1; 131 unsigned NumArgs; 132 const TemplateArgument *Args; 133 }; 134 struct TA { 135 unsigned Kind : 31; 136 unsigned IsDefaulted : 1; 137 unsigned NumExpansions; 138 void *Name; 139 }; 140 struct TV { 141 unsigned Kind : 31; 142 unsigned IsDefaulted : 1; 143 uintptr_t V; 144 }; 145 union { 146 struct DA DeclArg; 147 struct I Integer; 148 struct A Args; 149 struct TA TemplateArg; 150 struct TV TypeOrValue; 151 }; 152 153 public: 154 /// Construct an empty, invalid template argument. 155 constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {} 156 157 /// Construct a template type argument. 158 TemplateArgument(QualType T, bool isNullPtr = false, 159 bool IsDefaulted = false) { 160 TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 161 TypeOrValue.IsDefaulted = IsDefaulted; 162 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 163 } 164 165 /// Construct a template argument that refers to a 166 /// declaration, which is either an external declaration or a 167 /// template declaration. 168 TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) { 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 /// Construct an integral constant template argument. The memory to 177 /// store the value is allocated with Ctx. 178 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type, 179 bool IsDefaulted = false); 180 181 /// Construct an integral constant template argument with the same 182 /// value as Other but a different type. 183 TemplateArgument(const TemplateArgument &Other, QualType Type) { 184 Integer = Other.Integer; 185 Integer.Type = Type.getAsOpaquePtr(); 186 } 187 188 /// Construct a template argument that is a template. 189 /// 190 /// This form of template argument is generally used for template template 191 /// parameters. However, the template name could be a dependent template 192 /// name that ends up being instantiated to a function template whose address 193 /// is taken. 194 /// 195 /// \param Name The template name. 196 /// 197 /// \param IsDefaulted If 'true', implies that this TemplateArgument 198 /// corresponds to a default template parameter 199 TemplateArgument(TemplateName Name, bool IsDefaulted = false) { 200 TemplateArg.Kind = Template; 201 TemplateArg.IsDefaulted = IsDefaulted; 202 TemplateArg.Name = Name.getAsVoidPointer(); 203 TemplateArg.NumExpansions = 0; 204 } 205 206 /// Construct a template argument that is a template pack expansion. 207 /// 208 /// This form of template argument is generally used for template template 209 /// parameters. However, the template name could be a dependent template 210 /// name that ends up being instantiated to a function template whose address 211 /// is taken. 212 /// 213 /// \param Name The template name. 214 /// 215 /// \param NumExpansions The number of expansions that will be generated by 216 /// instantiating 217 /// 218 /// \param IsDefaulted If 'true', implies that this TemplateArgument 219 /// corresponds to a default template parameter 220 TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions, 221 bool IsDefaulted = false) { 222 TemplateArg.Kind = TemplateExpansion; 223 TemplateArg.IsDefaulted = IsDefaulted; 224 TemplateArg.Name = Name.getAsVoidPointer(); 225 if (NumExpansions) 226 TemplateArg.NumExpansions = *NumExpansions + 1; 227 else 228 TemplateArg.NumExpansions = 0; 229 } 230 231 /// Construct a template argument that is an expression. 232 /// 233 /// This form of template argument only occurs in template argument 234 /// lists used for dependent types and for expression; it will not 235 /// occur in a non-dependent, canonical template argument list. 236 TemplateArgument(Expr *E, bool IsDefaulted = false) { 237 TypeOrValue.Kind = Expression; 238 TypeOrValue.IsDefaulted = IsDefaulted; 239 TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 240 } 241 242 /// Construct a template argument that is a template argument pack. 243 /// 244 /// We assume that storage for the template arguments provided 245 /// outlives the TemplateArgument itself. 246 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { 247 this->Args.Kind = Pack; 248 this->Args.IsDefaulted = false; 249 this->Args.Args = Args.data(); 250 this->Args.NumArgs = Args.size(); 251 } 252 253 static TemplateArgument getEmptyPack() { 254 return TemplateArgument(std::nullopt); 255 } 256 257 /// Create a new template argument pack by copying the given set of 258 /// template arguments. 259 static TemplateArgument CreatePackCopy(ASTContext &Context, 260 ArrayRef<TemplateArgument> Args); 261 262 /// Return the kind of stored template argument. 263 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } 264 265 /// Determine whether this template argument has no value. 266 bool isNull() const { return getKind() == Null; } 267 268 TemplateArgumentDependence getDependence() const; 269 270 /// Whether this template argument is dependent on a template 271 /// parameter such that its result can change from one instantiation to 272 /// another. 273 bool isDependent() const; 274 275 /// Whether this template argument is dependent on a template 276 /// parameter. 277 bool isInstantiationDependent() const; 278 279 /// Whether this template argument contains an unexpanded 280 /// parameter pack. 281 bool containsUnexpandedParameterPack() const; 282 283 /// Determine whether this template argument is a pack expansion. 284 bool isPackExpansion() const; 285 286 /// Retrieve the type for a type template argument. 287 QualType getAsType() const { 288 assert(getKind() == Type && "Unexpected kind"); 289 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 290 } 291 292 /// Retrieve the declaration for a declaration non-type 293 /// template argument. 294 ValueDecl *getAsDecl() const { 295 assert(getKind() == Declaration && "Unexpected kind"); 296 return DeclArg.D; 297 } 298 299 QualType getParamTypeForDecl() const { 300 assert(getKind() == Declaration && "Unexpected kind"); 301 return QualType::getFromOpaquePtr(DeclArg.QT); 302 } 303 304 /// Retrieve the type for null non-type template argument. 305 QualType getNullPtrType() const { 306 assert(getKind() == NullPtr && "Unexpected kind"); 307 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 308 } 309 310 /// Retrieve the template name for a template name argument. 311 TemplateName getAsTemplate() const { 312 assert(getKind() == Template && "Unexpected kind"); 313 return TemplateName::getFromVoidPointer(TemplateArg.Name); 314 } 315 316 /// Retrieve the template argument as a template name; if the argument 317 /// is a pack expansion, return the pattern as a template name. 318 TemplateName getAsTemplateOrTemplatePattern() const { 319 assert((getKind() == Template || getKind() == TemplateExpansion) && 320 "Unexpected kind"); 321 322 return TemplateName::getFromVoidPointer(TemplateArg.Name); 323 } 324 325 /// Retrieve the number of expansions that a template template argument 326 /// expansion will produce, if known. 327 std::optional<unsigned> getNumTemplateExpansions() const; 328 329 /// Retrieve the template argument as an integral value. 330 // FIXME: Provide a way to read the integral data without copying the value. 331 llvm::APSInt getAsIntegral() const { 332 assert(getKind() == Integral && "Unexpected kind"); 333 334 using namespace llvm; 335 336 if (Integer.BitWidth <= 64) 337 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 338 339 unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 340 return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)), 341 Integer.IsUnsigned); 342 } 343 344 /// Retrieve the type of the integral value. 345 QualType getIntegralType() const { 346 assert(getKind() == Integral && "Unexpected kind"); 347 return QualType::getFromOpaquePtr(Integer.Type); 348 } 349 350 void setIntegralType(QualType T) { 351 assert(getKind() == Integral && "Unexpected kind"); 352 Integer.Type = T.getAsOpaquePtr(); 353 } 354 355 /// Set to 'true' if this TemplateArgument corresponds to a 356 /// default template parameter. 357 void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; } 358 359 /// If returns 'true', this TemplateArgument corresponds to a 360 /// default template parameter. 361 bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; } 362 363 /// If this is a non-type template argument, get its type. Otherwise, 364 /// returns a null QualType. 365 QualType getNonTypeTemplateArgumentType() const; 366 367 /// Retrieve the template argument as an expression. 368 Expr *getAsExpr() const { 369 assert(getKind() == Expression && "Unexpected kind"); 370 return reinterpret_cast<Expr *>(TypeOrValue.V); 371 } 372 373 /// Iterator that traverses the elements of a template argument pack. 374 using pack_iterator = const TemplateArgument *; 375 376 /// Iterator referencing the first argument of a template argument 377 /// pack. 378 pack_iterator pack_begin() const { 379 assert(getKind() == Pack); 380 return Args.Args; 381 } 382 383 /// Iterator referencing one past the last argument of a template 384 /// argument pack. 385 pack_iterator pack_end() const { 386 assert(getKind() == Pack); 387 return Args.Args + Args.NumArgs; 388 } 389 390 /// Iterator range referencing all of the elements of a template 391 /// argument pack. 392 ArrayRef<TemplateArgument> pack_elements() const { 393 return llvm::ArrayRef(pack_begin(), pack_end()); 394 } 395 396 /// The number of template arguments in the given template argument 397 /// pack. 398 unsigned pack_size() const { 399 assert(getKind() == Pack); 400 return Args.NumArgs; 401 } 402 403 /// Return the array of arguments in this template argument pack. 404 ArrayRef<TemplateArgument> getPackAsArray() const { 405 assert(getKind() == Pack); 406 return llvm::ArrayRef(Args.Args, Args.NumArgs); 407 } 408 409 /// Determines whether two template arguments are superficially the 410 /// same. 411 bool structurallyEquals(const TemplateArgument &Other) const; 412 413 /// When the template argument is a pack expansion, returns 414 /// the pattern of the pack expansion. 415 TemplateArgument getPackExpansionPattern() const; 416 417 /// Print this template argument to the given output stream. 418 void print(const PrintingPolicy &Policy, raw_ostream &Out, 419 bool IncludeType) const; 420 421 /// Debugging aid that dumps the template argument. 422 void dump(raw_ostream &Out) const; 423 424 /// Debugging aid that dumps the template argument to standard error. 425 void dump() const; 426 427 /// Used to insert TemplateArguments into FoldingSets. 428 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 429 }; 430 431 /// Location information for a TemplateArgument. 432 struct TemplateArgumentLocInfo { 433 private: 434 struct TemplateTemplateArgLocInfo { 435 // FIXME: We'd like to just use the qualifier in the TemplateName, 436 // but template arguments get canonicalized too quickly. 437 NestedNameSpecifier *Qualifier; 438 void *QualifierLocData; 439 SourceLocation TemplateNameLoc; 440 SourceLocation EllipsisLoc; 441 }; 442 443 llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *> 444 Pointer; 445 446 TemplateTemplateArgLocInfo *getTemplate() const { 447 return Pointer.get<TemplateTemplateArgLocInfo *>(); 448 } 449 450 public: 451 TemplateArgumentLocInfo() {} 452 TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; } 453 454 TemplateArgumentLocInfo(Expr *E) { Pointer = E; } 455 // Ctx is used for allocation -- this case is unusually large and also rare, 456 // so we store the payload out-of-line. 457 TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, 458 SourceLocation TemplateNameLoc, 459 SourceLocation EllipsisLoc); 460 461 TypeSourceInfo *getAsTypeSourceInfo() const { 462 return Pointer.get<TypeSourceInfo *>(); 463 } 464 465 Expr *getAsExpr() const { return Pointer.get<Expr *>(); } 466 467 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 468 const auto *Template = getTemplate(); 469 return NestedNameSpecifierLoc(Template->Qualifier, 470 Template->QualifierLocData); 471 } 472 473 SourceLocation getTemplateNameLoc() const { 474 return getTemplate()->TemplateNameLoc; 475 } 476 477 SourceLocation getTemplateEllipsisLoc() const { 478 return getTemplate()->EllipsisLoc; 479 } 480 }; 481 482 /// Location wrapper for a TemplateArgument. TemplateArgument is to 483 /// TemplateArgumentLoc as Type is to TypeLoc. 484 class TemplateArgumentLoc { 485 TemplateArgument Argument; 486 TemplateArgumentLocInfo LocInfo; 487 488 public: 489 TemplateArgumentLoc() {} 490 491 TemplateArgumentLoc(const TemplateArgument &Argument, 492 TemplateArgumentLocInfo Opaque) 493 : Argument(Argument), LocInfo(Opaque) {} 494 495 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 496 : Argument(Argument), LocInfo(TInfo) { 497 assert(Argument.getKind() == TemplateArgument::Type); 498 } 499 500 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 501 : Argument(Argument), LocInfo(E) { 502 503 // Permit any kind of template argument that can be represented with an 504 // expression. 505 assert(Argument.getKind() == TemplateArgument::NullPtr || 506 Argument.getKind() == TemplateArgument::Integral || 507 Argument.getKind() == TemplateArgument::Declaration || 508 Argument.getKind() == TemplateArgument::Expression); 509 } 510 511 TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument, 512 NestedNameSpecifierLoc QualifierLoc, 513 SourceLocation TemplateNameLoc, 514 SourceLocation EllipsisLoc = SourceLocation()) 515 : Argument(Argument), 516 LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) { 517 assert(Argument.getKind() == TemplateArgument::Template || 518 Argument.getKind() == TemplateArgument::TemplateExpansion); 519 } 520 521 /// - Fetches the primary location of the argument. 522 SourceLocation getLocation() const { 523 if (Argument.getKind() == TemplateArgument::Template || 524 Argument.getKind() == TemplateArgument::TemplateExpansion) 525 return getTemplateNameLoc(); 526 527 return getSourceRange().getBegin(); 528 } 529 530 /// - Fetches the full source range of the argument. 531 SourceRange getSourceRange() const LLVM_READONLY; 532 533 const TemplateArgument &getArgument() const { 534 return Argument; 535 } 536 537 TemplateArgumentLocInfo getLocInfo() const { 538 return LocInfo; 539 } 540 541 TypeSourceInfo *getTypeSourceInfo() const { 542 if (Argument.getKind() != TemplateArgument::Type) 543 return nullptr; 544 return LocInfo.getAsTypeSourceInfo(); 545 } 546 547 Expr *getSourceExpression() const { 548 assert(Argument.getKind() == TemplateArgument::Expression); 549 return LocInfo.getAsExpr(); 550 } 551 552 Expr *getSourceDeclExpression() const { 553 assert(Argument.getKind() == TemplateArgument::Declaration); 554 return LocInfo.getAsExpr(); 555 } 556 557 Expr *getSourceNullPtrExpression() const { 558 assert(Argument.getKind() == TemplateArgument::NullPtr); 559 return LocInfo.getAsExpr(); 560 } 561 562 Expr *getSourceIntegralExpression() const { 563 assert(Argument.getKind() == TemplateArgument::Integral); 564 return LocInfo.getAsExpr(); 565 } 566 567 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 568 if (Argument.getKind() != TemplateArgument::Template && 569 Argument.getKind() != TemplateArgument::TemplateExpansion) 570 return NestedNameSpecifierLoc(); 571 return LocInfo.getTemplateQualifierLoc(); 572 } 573 574 SourceLocation getTemplateNameLoc() const { 575 if (Argument.getKind() != TemplateArgument::Template && 576 Argument.getKind() != TemplateArgument::TemplateExpansion) 577 return SourceLocation(); 578 return LocInfo.getTemplateNameLoc(); 579 } 580 581 SourceLocation getTemplateEllipsisLoc() const { 582 if (Argument.getKind() != TemplateArgument::TemplateExpansion) 583 return SourceLocation(); 584 return LocInfo.getTemplateEllipsisLoc(); 585 } 586 }; 587 588 /// A convenient class for passing around template argument 589 /// information. Designed to be passed by reference. 590 class TemplateArgumentListInfo { 591 SmallVector<TemplateArgumentLoc, 8> Arguments; 592 SourceLocation LAngleLoc; 593 SourceLocation RAngleLoc; 594 595 public: 596 TemplateArgumentListInfo() = default; 597 598 TemplateArgumentListInfo(SourceLocation LAngleLoc, 599 SourceLocation RAngleLoc) 600 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 601 602 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 603 // instead. 604 void *operator new(size_t bytes, ASTContext &C) = delete; 605 606 SourceLocation getLAngleLoc() const { return LAngleLoc; } 607 SourceLocation getRAngleLoc() const { return RAngleLoc; } 608 609 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 610 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 611 612 unsigned size() const { return Arguments.size(); } 613 614 const TemplateArgumentLoc *getArgumentArray() const { 615 return Arguments.data(); 616 } 617 618 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 619 return Arguments; 620 } 621 622 const TemplateArgumentLoc &operator[](unsigned I) const { 623 return Arguments[I]; 624 } 625 626 TemplateArgumentLoc &operator[](unsigned I) { 627 return Arguments[I]; 628 } 629 630 void addArgument(const TemplateArgumentLoc &Loc) { 631 Arguments.push_back(Loc); 632 } 633 }; 634 635 /// Represents an explicit template argument list in C++, e.g., 636 /// the "<int>" in "sort<int>". 637 /// This is safe to be used inside an AST node, in contrast with 638 /// TemplateArgumentListInfo. 639 struct ASTTemplateArgumentListInfo final 640 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, 641 TemplateArgumentLoc> { 642 private: 643 friend class ASTNodeImporter; 644 friend TrailingObjects; 645 646 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); 647 648 // FIXME: Is it ever necessary to copy to another context? 649 ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List); 650 651 public: 652 /// The source location of the left angle bracket ('<'). 653 SourceLocation LAngleLoc; 654 655 /// The source location of the right angle bracket ('>'). 656 SourceLocation RAngleLoc; 657 658 /// The number of template arguments in TemplateArgs. 659 unsigned NumTemplateArgs; 660 661 SourceLocation getLAngleLoc() const { return LAngleLoc; } 662 SourceLocation getRAngleLoc() const { return RAngleLoc; } 663 664 /// Retrieve the template arguments 665 const TemplateArgumentLoc *getTemplateArgs() const { 666 return getTrailingObjects<TemplateArgumentLoc>(); 667 } 668 unsigned getNumTemplateArgs() const { return NumTemplateArgs; } 669 670 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 671 return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs()); 672 } 673 674 const TemplateArgumentLoc &operator[](unsigned I) const { 675 return getTemplateArgs()[I]; 676 } 677 678 static const ASTTemplateArgumentListInfo * 679 Create(const ASTContext &C, const TemplateArgumentListInfo &List); 680 681 // FIXME: Is it ever necessary to copy to another context? 682 static const ASTTemplateArgumentListInfo * 683 Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List); 684 }; 685 686 /// Represents an explicit template argument list in C++, e.g., 687 /// the "<int>" in "sort<int>". 688 /// 689 /// It is intended to be used as a trailing object on AST nodes, and 690 /// as such, doesn't contain the array of TemplateArgumentLoc itself, 691 /// but expects the containing object to also provide storage for 692 /// that. 693 struct alignas(void *) ASTTemplateKWAndArgsInfo { 694 /// The source location of the left angle bracket ('<'). 695 SourceLocation LAngleLoc; 696 697 /// The source location of the right angle bracket ('>'). 698 SourceLocation RAngleLoc; 699 700 /// The source location of the template keyword; this is used 701 /// as part of the representation of qualified identifiers, such as 702 /// S<T>::template apply<T>. Will be empty if this expression does 703 /// not have a template keyword. 704 SourceLocation TemplateKWLoc; 705 706 /// The number of template arguments in TemplateArgs. 707 unsigned NumTemplateArgs; 708 709 void initializeFrom(SourceLocation TemplateKWLoc, 710 const TemplateArgumentListInfo &List, 711 TemplateArgumentLoc *OutArgArray); 712 // FIXME: The parameter Deps is the result populated by this method, the 713 // caller doesn't need it since it is populated by computeDependence. remove 714 // it. 715 void initializeFrom(SourceLocation TemplateKWLoc, 716 const TemplateArgumentListInfo &List, 717 TemplateArgumentLoc *OutArgArray, 718 TemplateArgumentDependence &Deps); 719 void initializeFrom(SourceLocation TemplateKWLoc); 720 721 void copyInto(const TemplateArgumentLoc *ArgArray, 722 TemplateArgumentListInfo &List) const; 723 }; 724 725 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 726 const TemplateArgument &Arg); 727 728 } // namespace clang 729 730 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H 731