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 DiagnosticBuilder; 56 class Expr; 57 struct PrintingPolicy; 58 class TypeSourceInfo; 59 class ValueDecl; 60 61 /// Represents a template argument. 62 class TemplateArgument { 63 public: 64 /// The kind of template argument we're storing. 65 enum ArgKind { 66 /// Represents an empty template argument, e.g., one that has not 67 /// been deduced. 68 Null = 0, 69 70 /// The template argument is a type. 71 Type, 72 73 /// The template argument is a declaration that was provided for a pointer, 74 /// reference, or pointer to member non-type template parameter. 75 Declaration, 76 77 /// The template argument is a null pointer or null pointer to member that 78 /// was provided for a non-type template parameter. 79 NullPtr, 80 81 /// The template argument is an integral value stored in an llvm::APSInt 82 /// that was provided for an integral non-type template parameter. 83 Integral, 84 85 /// The template argument is a template name that was provided for a 86 /// template template parameter. 87 Template, 88 89 /// The template argument is a pack expansion of a template name that was 90 /// provided for a template template parameter. 91 TemplateExpansion, 92 93 /// The template argument is an expression, and we've not resolved it to one 94 /// of the other forms yet, either because it's dependent or because we're 95 /// representing a non-canonical template argument (for instance, in a 96 /// TemplateSpecializationType). 97 Expression, 98 99 /// The template argument is actually a parameter pack. Arguments are stored 100 /// in the Args struct. 101 Pack 102 }; 103 104 private: 105 /// The kind of template argument we're storing. 106 107 struct DA { 108 unsigned Kind; 109 void *QT; 110 ValueDecl *D; 111 }; 112 struct I { 113 unsigned Kind; 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; 130 unsigned NumArgs; 131 const TemplateArgument *Args; 132 }; 133 struct TA { 134 unsigned Kind; 135 unsigned NumExpansions; 136 void *Name; 137 }; 138 struct TV { 139 unsigned Kind; 140 uintptr_t V; 141 }; 142 union { 143 struct DA DeclArg; 144 struct I Integer; 145 struct A Args; 146 struct TA TemplateArg; 147 struct TV TypeOrValue; 148 }; 149 150 public: 151 /// Construct an empty, invalid template argument. 152 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} 153 154 /// Construct a template type argument. 155 TemplateArgument(QualType T, bool isNullPtr = false) { 156 TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 157 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 158 } 159 160 /// Construct a template argument that refers to a 161 /// declaration, which is either an external declaration or a 162 /// template declaration. 163 TemplateArgument(ValueDecl *D, QualType QT) { 164 assert(D && "Expected decl"); 165 DeclArg.Kind = Declaration; 166 DeclArg.QT = QT.getAsOpaquePtr(); 167 DeclArg.D = D; 168 } 169 170 /// Construct an integral constant template argument. The memory to 171 /// store the value is allocated with Ctx. 172 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 173 174 /// Construct an integral constant template argument with the same 175 /// value as Other but a different type. 176 TemplateArgument(const TemplateArgument &Other, QualType Type) { 177 Integer = Other.Integer; 178 Integer.Type = Type.getAsOpaquePtr(); 179 } 180 181 /// Construct a template argument that is a template. 182 /// 183 /// This form of template argument is generally used for template template 184 /// parameters. However, the template name could be a dependent template 185 /// name that ends up being instantiated to a function template whose address 186 /// is taken. 187 /// 188 /// \param Name The template name. 189 TemplateArgument(TemplateName Name) { 190 TemplateArg.Kind = Template; 191 TemplateArg.Name = Name.getAsVoidPointer(); 192 TemplateArg.NumExpansions = 0; 193 } 194 195 /// Construct a template argument that is a template pack expansion. 196 /// 197 /// This form of template argument is generally used for template template 198 /// parameters. However, the template name could be a dependent template 199 /// name that ends up being instantiated to a function template whose address 200 /// is taken. 201 /// 202 /// \param Name The template name. 203 /// 204 /// \param NumExpansions The number of expansions that will be generated by 205 /// instantiating 206 TemplateArgument(TemplateName Name, Optional<unsigned> NumExpansions) { 207 TemplateArg.Kind = TemplateExpansion; 208 TemplateArg.Name = Name.getAsVoidPointer(); 209 if (NumExpansions) 210 TemplateArg.NumExpansions = *NumExpansions + 1; 211 else 212 TemplateArg.NumExpansions = 0; 213 } 214 215 /// Construct a template argument that is an expression. 216 /// 217 /// This form of template argument only occurs in template argument 218 /// lists used for dependent types and for expression; it will not 219 /// occur in a non-dependent, canonical template argument list. 220 TemplateArgument(Expr *E) { 221 TypeOrValue.Kind = Expression; 222 TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 223 } 224 225 /// Construct a template argument that is a template argument pack. 226 /// 227 /// We assume that storage for the template arguments provided 228 /// outlives the TemplateArgument itself. 229 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { 230 this->Args.Kind = Pack; 231 this->Args.Args = Args.data(); 232 this->Args.NumArgs = Args.size(); 233 } 234 235 TemplateArgument(TemplateName, bool) = delete; 236 237 static TemplateArgument getEmptyPack() { return TemplateArgument(None); } 238 239 /// Create a new template argument pack by copying the given set of 240 /// template arguments. 241 static TemplateArgument CreatePackCopy(ASTContext &Context, 242 ArrayRef<TemplateArgument> Args); 243 244 /// Return the kind of stored template argument. 245 ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } 246 247 /// Determine whether this template argument has no value. 248 bool isNull() const { return getKind() == Null; } 249 250 TemplateArgumentDependence getDependence() const; 251 252 /// Whether this template argument is dependent on a template 253 /// parameter such that its result can change from one instantiation to 254 /// another. 255 bool isDependent() const; 256 257 /// Whether this template argument is dependent on a template 258 /// parameter. 259 bool isInstantiationDependent() const; 260 261 /// Whether this template argument contains an unexpanded 262 /// parameter pack. 263 bool containsUnexpandedParameterPack() const; 264 265 /// Determine whether this template argument is a pack expansion. 266 bool isPackExpansion() const; 267 268 /// Retrieve the type for a type template argument. 269 QualType getAsType() const { 270 assert(getKind() == Type && "Unexpected kind"); 271 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 272 } 273 274 /// Retrieve the declaration for a declaration non-type 275 /// template argument. 276 ValueDecl *getAsDecl() const { 277 assert(getKind() == Declaration && "Unexpected kind"); 278 return DeclArg.D; 279 } 280 281 QualType getParamTypeForDecl() const { 282 assert(getKind() == Declaration && "Unexpected kind"); 283 return QualType::getFromOpaquePtr(DeclArg.QT); 284 } 285 286 /// Retrieve the type for null non-type template argument. 287 QualType getNullPtrType() const { 288 assert(getKind() == NullPtr && "Unexpected kind"); 289 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 290 } 291 292 /// Retrieve the template name for a template name argument. 293 TemplateName getAsTemplate() const { 294 assert(getKind() == Template && "Unexpected kind"); 295 return TemplateName::getFromVoidPointer(TemplateArg.Name); 296 } 297 298 /// Retrieve the template argument as a template name; if the argument 299 /// is a pack expansion, return the pattern as a template name. 300 TemplateName getAsTemplateOrTemplatePattern() const { 301 assert((getKind() == Template || getKind() == TemplateExpansion) && 302 "Unexpected kind"); 303 304 return TemplateName::getFromVoidPointer(TemplateArg.Name); 305 } 306 307 /// Retrieve the number of expansions that a template template argument 308 /// expansion will produce, if known. 309 Optional<unsigned> getNumTemplateExpansions() const; 310 311 /// Retrieve the template argument as an integral value. 312 // FIXME: Provide a way to read the integral data without copying the value. 313 llvm::APSInt getAsIntegral() const { 314 assert(getKind() == Integral && "Unexpected kind"); 315 316 using namespace llvm; 317 318 if (Integer.BitWidth <= 64) 319 return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 320 321 unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 322 return APSInt(APInt(Integer.BitWidth, makeArrayRef(Integer.pVal, NumWords)), 323 Integer.IsUnsigned); 324 } 325 326 /// Retrieve the type of the integral value. 327 QualType getIntegralType() const { 328 assert(getKind() == Integral && "Unexpected kind"); 329 return QualType::getFromOpaquePtr(Integer.Type); 330 } 331 332 void setIntegralType(QualType T) { 333 assert(getKind() == Integral && "Unexpected kind"); 334 Integer.Type = T.getAsOpaquePtr(); 335 } 336 337 /// If this is a non-type template argument, get its type. Otherwise, 338 /// returns a null QualType. 339 QualType getNonTypeTemplateArgumentType() const; 340 341 /// Retrieve the template argument as an expression. 342 Expr *getAsExpr() const { 343 assert(getKind() == Expression && "Unexpected kind"); 344 return reinterpret_cast<Expr *>(TypeOrValue.V); 345 } 346 347 /// Iterator that traverses the elements of a template argument pack. 348 using pack_iterator = const TemplateArgument *; 349 350 /// Iterator referencing the first argument of a template argument 351 /// pack. 352 pack_iterator pack_begin() const { 353 assert(getKind() == Pack); 354 return Args.Args; 355 } 356 357 /// Iterator referencing one past the last argument of a template 358 /// argument pack. 359 pack_iterator pack_end() const { 360 assert(getKind() == Pack); 361 return Args.Args + Args.NumArgs; 362 } 363 364 /// Iterator range referencing all of the elements of a template 365 /// argument pack. 366 ArrayRef<TemplateArgument> pack_elements() const { 367 return llvm::makeArrayRef(pack_begin(), pack_end()); 368 } 369 370 /// The number of template arguments in the given template argument 371 /// pack. 372 unsigned pack_size() const { 373 assert(getKind() == Pack); 374 return Args.NumArgs; 375 } 376 377 /// Return the array of arguments in this template argument pack. 378 ArrayRef<TemplateArgument> getPackAsArray() const { 379 assert(getKind() == Pack); 380 return llvm::makeArrayRef(Args.Args, Args.NumArgs); 381 } 382 383 /// Determines whether two template arguments are superficially the 384 /// same. 385 bool structurallyEquals(const TemplateArgument &Other) const; 386 387 /// When the template argument is a pack expansion, returns 388 /// the pattern of the pack expansion. 389 TemplateArgument getPackExpansionPattern() const; 390 391 /// Print this template argument to the given output stream. 392 void print(const PrintingPolicy &Policy, raw_ostream &Out) 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 assert(Argument.getKind() == TemplateArgument::Type); 516 return LocInfo.getAsTypeSourceInfo(); 517 } 518 519 Expr *getSourceExpression() const { 520 assert(Argument.getKind() == TemplateArgument::Expression); 521 return LocInfo.getAsExpr(); 522 } 523 524 Expr *getSourceDeclExpression() const { 525 assert(Argument.getKind() == TemplateArgument::Declaration); 526 return LocInfo.getAsExpr(); 527 } 528 529 Expr *getSourceNullPtrExpression() const { 530 assert(Argument.getKind() == TemplateArgument::NullPtr); 531 return LocInfo.getAsExpr(); 532 } 533 534 Expr *getSourceIntegralExpression() const { 535 assert(Argument.getKind() == TemplateArgument::Integral); 536 return LocInfo.getAsExpr(); 537 } 538 539 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 540 if (Argument.getKind() != TemplateArgument::Template && 541 Argument.getKind() != TemplateArgument::TemplateExpansion) 542 return NestedNameSpecifierLoc(); 543 return LocInfo.getTemplateQualifierLoc(); 544 } 545 546 SourceLocation getTemplateNameLoc() const { 547 if (Argument.getKind() != TemplateArgument::Template && 548 Argument.getKind() != TemplateArgument::TemplateExpansion) 549 return SourceLocation(); 550 return LocInfo.getTemplateNameLoc(); 551 } 552 553 SourceLocation getTemplateEllipsisLoc() const { 554 if (Argument.getKind() != TemplateArgument::TemplateExpansion) 555 return SourceLocation(); 556 return LocInfo.getTemplateEllipsisLoc(); 557 } 558 }; 559 560 /// A convenient class for passing around template argument 561 /// information. Designed to be passed by reference. 562 class TemplateArgumentListInfo { 563 SmallVector<TemplateArgumentLoc, 8> Arguments; 564 SourceLocation LAngleLoc; 565 SourceLocation RAngleLoc; 566 567 public: 568 TemplateArgumentListInfo() = default; 569 570 TemplateArgumentListInfo(SourceLocation LAngleLoc, 571 SourceLocation RAngleLoc) 572 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 573 574 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 575 // instead. 576 void *operator new(size_t bytes, ASTContext &C) = delete; 577 578 SourceLocation getLAngleLoc() const { return LAngleLoc; } 579 SourceLocation getRAngleLoc() const { return RAngleLoc; } 580 581 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 582 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 583 584 unsigned size() const { return Arguments.size(); } 585 586 const TemplateArgumentLoc *getArgumentArray() const { 587 return Arguments.data(); 588 } 589 590 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 591 return Arguments; 592 } 593 594 const TemplateArgumentLoc &operator[](unsigned I) const { 595 return Arguments[I]; 596 } 597 598 TemplateArgumentLoc &operator[](unsigned I) { 599 return Arguments[I]; 600 } 601 602 void addArgument(const TemplateArgumentLoc &Loc) { 603 Arguments.push_back(Loc); 604 } 605 }; 606 607 /// Represents an explicit template argument list in C++, e.g., 608 /// the "<int>" in "sort<int>". 609 /// This is safe to be used inside an AST node, in contrast with 610 /// TemplateArgumentListInfo. 611 struct ASTTemplateArgumentListInfo final 612 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, 613 TemplateArgumentLoc> { 614 private: 615 friend class ASTNodeImporter; 616 friend TrailingObjects; 617 618 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); 619 620 public: 621 /// The source location of the left angle bracket ('<'). 622 SourceLocation LAngleLoc; 623 624 /// The source location of the right angle bracket ('>'). 625 SourceLocation RAngleLoc; 626 627 /// The number of template arguments in TemplateArgs. 628 unsigned NumTemplateArgs; 629 630 SourceLocation getLAngleLoc() const { return LAngleLoc; } 631 SourceLocation getRAngleLoc() const { return RAngleLoc; } 632 633 /// Retrieve the template arguments 634 const TemplateArgumentLoc *getTemplateArgs() const { 635 return getTrailingObjects<TemplateArgumentLoc>(); 636 } 637 unsigned getNumTemplateArgs() const { return NumTemplateArgs; } 638 639 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 640 return llvm::makeArrayRef(getTemplateArgs(), getNumTemplateArgs()); 641 } 642 643 const TemplateArgumentLoc &operator[](unsigned I) const { 644 return getTemplateArgs()[I]; 645 } 646 647 static const ASTTemplateArgumentListInfo * 648 Create(const ASTContext &C, const TemplateArgumentListInfo &List); 649 }; 650 651 /// Represents an explicit template argument list in C++, e.g., 652 /// the "<int>" in "sort<int>". 653 /// 654 /// It is intended to be used as a trailing object on AST nodes, and 655 /// as such, doesn't contain the array of TemplateArgumentLoc itself, 656 /// but expects the containing object to also provide storage for 657 /// that. 658 struct alignas(void *) ASTTemplateKWAndArgsInfo { 659 /// The source location of the left angle bracket ('<'). 660 SourceLocation LAngleLoc; 661 662 /// The source location of the right angle bracket ('>'). 663 SourceLocation RAngleLoc; 664 665 /// The source location of the template keyword; this is used 666 /// as part of the representation of qualified identifiers, such as 667 /// S<T>::template apply<T>. Will be empty if this expression does 668 /// not have a template keyword. 669 SourceLocation TemplateKWLoc; 670 671 /// The number of template arguments in TemplateArgs. 672 unsigned NumTemplateArgs; 673 674 void initializeFrom(SourceLocation TemplateKWLoc, 675 const TemplateArgumentListInfo &List, 676 TemplateArgumentLoc *OutArgArray); 677 // FIXME: The parameter Deps is the result populated by this method, the 678 // caller doesn't need it since it is populated by computeDependence. remove 679 // it. 680 void initializeFrom(SourceLocation TemplateKWLoc, 681 const TemplateArgumentListInfo &List, 682 TemplateArgumentLoc *OutArgArray, 683 TemplateArgumentDependence &Deps); 684 void initializeFrom(SourceLocation TemplateKWLoc); 685 686 void copyInto(const TemplateArgumentLoc *ArgArray, 687 TemplateArgumentListInfo &List) const; 688 }; 689 690 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 691 const TemplateArgument &Arg); 692 693 inline TemplateSpecializationType::iterator 694 TemplateSpecializationType::end() const { 695 return getArgs() + getNumArgs(); 696 } 697 698 inline DependentTemplateSpecializationType::iterator 699 DependentTemplateSpecializationType::end() const { 700 return getArgs() + getNumArgs(); 701 } 702 703 inline const TemplateArgument & 704 TemplateSpecializationType::getArg(unsigned Idx) const { 705 assert(Idx < getNumArgs() && "Template argument out of range"); 706 return getArgs()[Idx]; 707 } 708 709 inline const TemplateArgument & 710 DependentTemplateSpecializationType::getArg(unsigned Idx) const { 711 assert(Idx < getNumArgs() && "Template argument out of range"); 712 return getArgs()[Idx]; 713 } 714 715 inline const TemplateArgument &AutoType::getArg(unsigned Idx) const { 716 assert(Idx < getNumArgs() && "Template argument out of range"); 717 return getArgs()[Idx]; 718 } 719 720 } // namespace clang 721 722 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H 723