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; 107 void *QT; 108 ValueDecl *D; 109 }; 110 struct I { 111 unsigned Kind; 112 // We store a decomposed APSInt with the data allocated by ASTContext if 113 // BitWidth > 64. The memory may be shared between multiple 114 // TemplateArgument instances. 115 unsigned BitWidth : 31; 116 unsigned IsUnsigned : 1; 117 union { 118 /// Used to store the <= 64 bits integer value. 119 uint64_t VAL; 120 121 /// Used to store the >64 bits integer value. 122 const uint64_t *pVal; 123 }; 124 void *Type; 125 }; 126 struct A { 127 unsigned Kind; 128 unsigned NumArgs; 129 const TemplateArgument *Args; 130 }; 131 struct TA { 132 unsigned Kind; 133 unsigned NumExpansions; 134 void *Name; 135 }; 136 struct TV { 137 unsigned Kind; 138 uintptr_t V; 139 }; 140 union { 141 struct DA DeclArg; 142 struct I Integer; 143 struct A Args; 144 struct TA TemplateArg; 145 struct TV TypeOrValue; 146 }; 147 148 public: 149 /// Construct an empty, invalid template argument. 150 constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} 151 152 /// Construct a template type argument. 153 TemplateArgument(QualType T, bool isNullPtr = false) { 154 TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 155 TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 156 } 157 158 /// Construct a template argument that refers to a 159 /// declaration, which is either an external declaration or a 160 /// template declaration. 161 TemplateArgument(ValueDecl *D, QualType QT) { 162 assert(D && "Expected decl"); 163 DeclArg.Kind = Declaration; 164 DeclArg.QT = QT.getAsOpaquePtr(); 165 DeclArg.D = D; 166 } 167 168 /// Construct an integral constant template argument. The memory to 169 /// store the value is allocated with Ctx. 170 TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 171 172 /// Construct an integral constant template argument with the same 173 /// value as Other but a different type. 174 TemplateArgument(const TemplateArgument &Other, QualType Type) { 175 Integer = Other.Integer; 176 Integer.Type = Type.getAsOpaquePtr(); 177 } 178 179 /// Construct a template argument that is a template. 180 /// 181 /// This form of template argument is generally used for template template 182 /// parameters. However, the template name could be a dependent template 183 /// name that ends up being instantiated to a function template whose address 184 /// is taken. 185 /// 186 /// \param Name The template name. 187 TemplateArgument(TemplateName Name) { 188 TemplateArg.Kind = Template; 189 TemplateArg.Name = Name.getAsVoidPointer(); 190 TemplateArg.NumExpansions = 0; 191 } 192 193 /// Construct a template argument that is a template pack expansion. 194 /// 195 /// This form of template argument is generally used for template template 196 /// parameters. However, the template name could be a dependent template 197 /// name that ends up being instantiated to a function template whose address 198 /// is taken. 199 /// 200 /// \param Name The template name. 201 /// 202 /// \param NumExpansions The number of expansions that will be generated by 203 /// instantiating 204 TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions) { 205 TemplateArg.Kind = TemplateExpansion; 206 TemplateArg.Name = Name.getAsVoidPointer(); 207 if (NumExpansions) 208 TemplateArg.NumExpansions = *NumExpansions + 1; 209 else 210 TemplateArg.NumExpansions = 0; 211 } 212 213 /// Construct a template argument that is an expression. 214 /// 215 /// This form of template argument only occurs in template argument 216 /// lists used for dependent types and for expression; it will not 217 /// occur in a non-dependent, canonical template argument list. 218 TemplateArgument(Expr *E) { 219 TypeOrValue.Kind = Expression; 220 TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 221 } 222 223 /// Construct a template argument that is a template argument pack. 224 /// 225 /// We assume that storage for the template arguments provided 226 /// outlives the TemplateArgument itself. 227 explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { 228 this->Args.Kind = Pack; 229 this->Args.Args = Args.data(); 230 this->Args.NumArgs = Args.size(); 231 } 232 233 TemplateArgument(TemplateName, bool) = delete; 234 235 static TemplateArgument getEmptyPack() { 236 return TemplateArgument(std::nullopt); 237 } 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 std::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, ArrayRef(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::ArrayRef(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::ArrayRef(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, 393 bool IncludeType) const; 394 395 /// Debugging aid that dumps the template argument. 396 void dump(raw_ostream &Out) const; 397 398 /// Debugging aid that dumps the template argument to standard error. 399 void dump() const; 400 401 /// Used to insert TemplateArguments into FoldingSets. 402 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 403 }; 404 405 /// Location information for a TemplateArgument. 406 struct TemplateArgumentLocInfo { 407 private: 408 struct TemplateTemplateArgLocInfo { 409 // FIXME: We'd like to just use the qualifier in the TemplateName, 410 // but template arguments get canonicalized too quickly. 411 NestedNameSpecifier *Qualifier; 412 void *QualifierLocData; 413 SourceLocation TemplateNameLoc; 414 SourceLocation EllipsisLoc; 415 }; 416 417 llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *> 418 Pointer; 419 420 TemplateTemplateArgLocInfo *getTemplate() const { 421 return Pointer.get<TemplateTemplateArgLocInfo *>(); 422 } 423 424 public: 425 TemplateArgumentLocInfo() {} 426 TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; } 427 428 TemplateArgumentLocInfo(Expr *E) { Pointer = E; } 429 // Ctx is used for allocation -- this case is unusually large and also rare, 430 // so we store the payload out-of-line. 431 TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, 432 SourceLocation TemplateNameLoc, 433 SourceLocation EllipsisLoc); 434 435 TypeSourceInfo *getAsTypeSourceInfo() const { 436 return Pointer.get<TypeSourceInfo *>(); 437 } 438 439 Expr *getAsExpr() const { return Pointer.get<Expr *>(); } 440 441 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 442 const auto *Template = getTemplate(); 443 return NestedNameSpecifierLoc(Template->Qualifier, 444 Template->QualifierLocData); 445 } 446 447 SourceLocation getTemplateNameLoc() const { 448 return getTemplate()->TemplateNameLoc; 449 } 450 451 SourceLocation getTemplateEllipsisLoc() const { 452 return getTemplate()->EllipsisLoc; 453 } 454 }; 455 456 /// Location wrapper for a TemplateArgument. TemplateArgument is to 457 /// TemplateArgumentLoc as Type is to TypeLoc. 458 class TemplateArgumentLoc { 459 TemplateArgument Argument; 460 TemplateArgumentLocInfo LocInfo; 461 462 public: 463 TemplateArgumentLoc() {} 464 465 TemplateArgumentLoc(const TemplateArgument &Argument, 466 TemplateArgumentLocInfo Opaque) 467 : Argument(Argument), LocInfo(Opaque) {} 468 469 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 470 : Argument(Argument), LocInfo(TInfo) { 471 assert(Argument.getKind() == TemplateArgument::Type); 472 } 473 474 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 475 : Argument(Argument), LocInfo(E) { 476 477 // Permit any kind of template argument that can be represented with an 478 // expression. 479 assert(Argument.getKind() == TemplateArgument::NullPtr || 480 Argument.getKind() == TemplateArgument::Integral || 481 Argument.getKind() == TemplateArgument::Declaration || 482 Argument.getKind() == TemplateArgument::Expression); 483 } 484 485 TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument, 486 NestedNameSpecifierLoc QualifierLoc, 487 SourceLocation TemplateNameLoc, 488 SourceLocation EllipsisLoc = SourceLocation()) 489 : Argument(Argument), 490 LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) { 491 assert(Argument.getKind() == TemplateArgument::Template || 492 Argument.getKind() == TemplateArgument::TemplateExpansion); 493 } 494 495 /// - Fetches the primary location of the argument. 496 SourceLocation getLocation() const { 497 if (Argument.getKind() == TemplateArgument::Template || 498 Argument.getKind() == TemplateArgument::TemplateExpansion) 499 return getTemplateNameLoc(); 500 501 return getSourceRange().getBegin(); 502 } 503 504 /// - Fetches the full source range of the argument. 505 SourceRange getSourceRange() const LLVM_READONLY; 506 507 const TemplateArgument &getArgument() const { 508 return Argument; 509 } 510 511 TemplateArgumentLocInfo getLocInfo() const { 512 return LocInfo; 513 } 514 515 TypeSourceInfo *getTypeSourceInfo() const { 516 if (Argument.getKind() != TemplateArgument::Type) 517 return nullptr; 518 return LocInfo.getAsTypeSourceInfo(); 519 } 520 521 Expr *getSourceExpression() const { 522 assert(Argument.getKind() == TemplateArgument::Expression); 523 return LocInfo.getAsExpr(); 524 } 525 526 Expr *getSourceDeclExpression() const { 527 assert(Argument.getKind() == TemplateArgument::Declaration); 528 return LocInfo.getAsExpr(); 529 } 530 531 Expr *getSourceNullPtrExpression() const { 532 assert(Argument.getKind() == TemplateArgument::NullPtr); 533 return LocInfo.getAsExpr(); 534 } 535 536 Expr *getSourceIntegralExpression() const { 537 assert(Argument.getKind() == TemplateArgument::Integral); 538 return LocInfo.getAsExpr(); 539 } 540 541 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 542 if (Argument.getKind() != TemplateArgument::Template && 543 Argument.getKind() != TemplateArgument::TemplateExpansion) 544 return NestedNameSpecifierLoc(); 545 return LocInfo.getTemplateQualifierLoc(); 546 } 547 548 SourceLocation getTemplateNameLoc() const { 549 if (Argument.getKind() != TemplateArgument::Template && 550 Argument.getKind() != TemplateArgument::TemplateExpansion) 551 return SourceLocation(); 552 return LocInfo.getTemplateNameLoc(); 553 } 554 555 SourceLocation getTemplateEllipsisLoc() const { 556 if (Argument.getKind() != TemplateArgument::TemplateExpansion) 557 return SourceLocation(); 558 return LocInfo.getTemplateEllipsisLoc(); 559 } 560 }; 561 562 /// A convenient class for passing around template argument 563 /// information. Designed to be passed by reference. 564 class TemplateArgumentListInfo { 565 SmallVector<TemplateArgumentLoc, 8> Arguments; 566 SourceLocation LAngleLoc; 567 SourceLocation RAngleLoc; 568 569 public: 570 TemplateArgumentListInfo() = default; 571 572 TemplateArgumentListInfo(SourceLocation LAngleLoc, 573 SourceLocation RAngleLoc) 574 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 575 576 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 577 // instead. 578 void *operator new(size_t bytes, ASTContext &C) = delete; 579 580 SourceLocation getLAngleLoc() const { return LAngleLoc; } 581 SourceLocation getRAngleLoc() const { return RAngleLoc; } 582 583 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 584 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 585 586 unsigned size() const { return Arguments.size(); } 587 588 const TemplateArgumentLoc *getArgumentArray() const { 589 return Arguments.data(); 590 } 591 592 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 593 return Arguments; 594 } 595 596 const TemplateArgumentLoc &operator[](unsigned I) const { 597 return Arguments[I]; 598 } 599 600 TemplateArgumentLoc &operator[](unsigned I) { 601 return Arguments[I]; 602 } 603 604 void addArgument(const TemplateArgumentLoc &Loc) { 605 Arguments.push_back(Loc); 606 } 607 }; 608 609 /// Represents an explicit template argument list in C++, e.g., 610 /// the "<int>" in "sort<int>". 611 /// This is safe to be used inside an AST node, in contrast with 612 /// TemplateArgumentListInfo. 613 struct ASTTemplateArgumentListInfo final 614 : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, 615 TemplateArgumentLoc> { 616 private: 617 friend class ASTNodeImporter; 618 friend TrailingObjects; 619 620 ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); 621 622 // FIXME: Is it ever necessary to copy to another context? 623 ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List); 624 625 public: 626 /// The source location of the left angle bracket ('<'). 627 SourceLocation LAngleLoc; 628 629 /// The source location of the right angle bracket ('>'). 630 SourceLocation RAngleLoc; 631 632 /// The number of template arguments in TemplateArgs. 633 unsigned NumTemplateArgs; 634 635 SourceLocation getLAngleLoc() const { return LAngleLoc; } 636 SourceLocation getRAngleLoc() const { return RAngleLoc; } 637 638 /// Retrieve the template arguments 639 const TemplateArgumentLoc *getTemplateArgs() const { 640 return getTrailingObjects<TemplateArgumentLoc>(); 641 } 642 unsigned getNumTemplateArgs() const { return NumTemplateArgs; } 643 644 llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 645 return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs()); 646 } 647 648 const TemplateArgumentLoc &operator[](unsigned I) const { 649 return getTemplateArgs()[I]; 650 } 651 652 static const ASTTemplateArgumentListInfo * 653 Create(const ASTContext &C, const TemplateArgumentListInfo &List); 654 655 // FIXME: Is it ever necessary to copy to another context? 656 static const ASTTemplateArgumentListInfo * 657 Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List); 658 }; 659 660 /// Represents an explicit template argument list in C++, e.g., 661 /// the "<int>" in "sort<int>". 662 /// 663 /// It is intended to be used as a trailing object on AST nodes, and 664 /// as such, doesn't contain the array of TemplateArgumentLoc itself, 665 /// but expects the containing object to also provide storage for 666 /// that. 667 struct alignas(void *) ASTTemplateKWAndArgsInfo { 668 /// The source location of the left angle bracket ('<'). 669 SourceLocation LAngleLoc; 670 671 /// The source location of the right angle bracket ('>'). 672 SourceLocation RAngleLoc; 673 674 /// The source location of the template keyword; this is used 675 /// as part of the representation of qualified identifiers, such as 676 /// S<T>::template apply<T>. Will be empty if this expression does 677 /// not have a template keyword. 678 SourceLocation TemplateKWLoc; 679 680 /// The number of template arguments in TemplateArgs. 681 unsigned NumTemplateArgs; 682 683 void initializeFrom(SourceLocation TemplateKWLoc, 684 const TemplateArgumentListInfo &List, 685 TemplateArgumentLoc *OutArgArray); 686 // FIXME: The parameter Deps is the result populated by this method, the 687 // caller doesn't need it since it is populated by computeDependence. remove 688 // it. 689 void initializeFrom(SourceLocation TemplateKWLoc, 690 const TemplateArgumentListInfo &List, 691 TemplateArgumentLoc *OutArgArray, 692 TemplateArgumentDependence &Deps); 693 void initializeFrom(SourceLocation TemplateKWLoc); 694 695 void copyInto(const TemplateArgumentLoc *ArgArray, 696 TemplateArgumentListInfo &List) const; 697 }; 698 699 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 700 const TemplateArgument &Arg); 701 702 } // namespace clang 703 704 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H 705