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