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