1 //===-- TemplateBase.h - Core classes for C++ templates ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides definitions which are common for all kinds of 11 // template representation. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 16 #define LLVM_CLANG_AST_TEMPLATEBASE_H 17 18 #include "clang/AST/Type.h" 19 #include "clang/AST/TemplateName.h" 20 #include "llvm/ADT/APSInt.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/Support/Compiler.h" 23 #include "llvm/Support/ErrorHandling.h" 24 25 namespace llvm { 26 class FoldingSetNodeID; 27 } 28 29 namespace clang { 30 31 class Decl; 32 class DiagnosticBuilder; 33 class Expr; 34 struct PrintingPolicy; 35 class TypeSourceInfo; 36 37 /// \brief Represents a template argument within a class template 38 /// specialization. 39 class TemplateArgument { 40 public: 41 /// \brief The kind of template argument we're storing. 42 enum ArgKind { 43 /// \brief Represents an empty template argument, e.g., one that has not 44 /// been deduced. 45 Null = 0, 46 /// The template argument is a type. Its value is stored in the 47 /// TypeOrValue field. 48 Type, 49 /// The template argument is a declaration that was provided for a pointer 50 /// or reference non-type template parameter. 51 Declaration, 52 /// The template argument is an integral value stored in an llvm::APSInt 53 /// that was provided for an integral non-type template parameter. 54 Integral, 55 /// The template argument is a template name that was provided for a 56 /// template template parameter. 57 Template, 58 /// The template argument is a pack expansion of a template name that was 59 /// provided for a template template parameter. 60 TemplateExpansion, 61 /// The template argument is a value- or type-dependent expression 62 /// stored in an Expr*. 63 Expression, 64 /// The template argument is actually a parameter pack. Arguments are stored 65 /// in the Args struct. 66 Pack 67 }; 68 69 private: 70 /// \brief The kind of template argument we're storing. 71 unsigned Kind; 72 73 union { 74 uintptr_t TypeOrValue; 75 struct { 76 char Value[sizeof(llvm::APSInt)]; 77 void *Type; 78 } Integer; 79 struct { 80 const TemplateArgument *Args; 81 unsigned NumArgs; 82 } Args; 83 struct { 84 void *Name; 85 unsigned NumExpansions; 86 } TemplateArg; 87 }; 88 89 TemplateArgument(TemplateName, bool); // DO NOT USE 90 91 public: 92 /// \brief Construct an empty, invalid template argument. TemplateArgument()93 TemplateArgument() : Kind(Null), TypeOrValue(0) { } 94 95 /// \brief Construct a template type argument. TemplateArgument(QualType T)96 TemplateArgument(QualType T) : Kind(Type) { 97 TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 98 } 99 100 /// \brief Construct a template argument that refers to a 101 /// declaration, which is either an external declaration or a 102 /// template declaration. TemplateArgument(Decl * D)103 TemplateArgument(Decl *D) : Kind(Declaration) { 104 TypeOrValue = reinterpret_cast<uintptr_t>(D); 105 } 106 107 /// \brief Construct an integral constant template argument. TemplateArgument(const llvm::APSInt & Value,QualType Type)108 TemplateArgument(const llvm::APSInt &Value, QualType Type) : Kind(Integral) { 109 // FIXME: Large integral values will get leaked. Do something 110 // similar to what we did with IntegerLiteral. 111 new (Integer.Value) llvm::APSInt(Value); 112 Integer.Type = Type.getAsOpaquePtr(); 113 } 114 115 /// \brief Construct a template argument that is a template. 116 /// 117 /// This form of template argument is generally used for template template 118 /// parameters. However, the template name could be a dependent template 119 /// name that ends up being instantiated to a function template whose address 120 /// is taken. 121 /// 122 /// \param Name The template name. TemplateArgument(TemplateName Name)123 TemplateArgument(TemplateName Name) : Kind(Template) 124 { 125 TemplateArg.Name = Name.getAsVoidPointer(); 126 TemplateArg.NumExpansions = 0; 127 } 128 129 /// \brief Construct a template argument that is a template pack expansion. 130 /// 131 /// This form of template argument is generally used for template template 132 /// parameters. However, the template name could be a dependent template 133 /// name that ends up being instantiated to a function template whose address 134 /// is taken. 135 /// 136 /// \param Name The template name. 137 /// 138 /// \param NumExpansions The number of expansions that will be generated by 139 /// instantiating TemplateArgument(TemplateName Name,llvm::Optional<unsigned> NumExpansions)140 TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions) 141 : Kind(TemplateExpansion) 142 { 143 TemplateArg.Name = Name.getAsVoidPointer(); 144 if (NumExpansions) 145 TemplateArg.NumExpansions = *NumExpansions + 1; 146 else 147 TemplateArg.NumExpansions = 0; 148 } 149 150 /// \brief Construct a template argument that is an expression. 151 /// 152 /// This form of template argument only occurs in template argument 153 /// lists used for dependent types and for expression; it will not 154 /// occur in a non-dependent, canonical template argument list. TemplateArgument(Expr * E)155 TemplateArgument(Expr *E) : Kind(Expression) { 156 TypeOrValue = reinterpret_cast<uintptr_t>(E); 157 } 158 159 /// \brief Construct a template argument that is a template argument pack. 160 /// 161 /// We assume that storage for the template arguments provided 162 /// outlives the TemplateArgument itself. TemplateArgument(const TemplateArgument * Args,unsigned NumArgs)163 TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) : Kind(Pack){ 164 this->Args.Args = Args; 165 this->Args.NumArgs = NumArgs; 166 } 167 168 /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument & Other)169 TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { 170 // FIXME: Large integral values will get leaked. Do something 171 // similar to what we did with IntegerLiteral. 172 if (Kind == Integral) { 173 new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); 174 Integer.Type = Other.Integer.Type; 175 } else if (Kind == Pack) { 176 Args.NumArgs = Other.Args.NumArgs; 177 Args.Args = Other.Args.Args; 178 } else if (Kind == Template || Kind == TemplateExpansion) { 179 TemplateArg.Name = Other.TemplateArg.Name; 180 TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions; 181 } else 182 TypeOrValue = Other.TypeOrValue; 183 } 184 185 TemplateArgument& operator=(const TemplateArgument& Other) { 186 using llvm::APSInt; 187 188 if (Kind == Other.Kind && Kind == Integral) { 189 // Copy integral values. 190 *this->getAsIntegral() = *Other.getAsIntegral(); 191 Integer.Type = Other.Integer.Type; 192 return *this; 193 } 194 195 // Destroy the current integral value, if that's what we're holding. 196 if (Kind == Integral) 197 getAsIntegral()->~APSInt(); 198 199 Kind = Other.Kind; 200 201 if (Other.Kind == Integral) { 202 new (Integer.Value) llvm::APSInt(*Other.getAsIntegral()); 203 Integer.Type = Other.Integer.Type; 204 } else if (Other.Kind == Pack) { 205 Args.NumArgs = Other.Args.NumArgs; 206 Args.Args = Other.Args.Args; 207 } else if (Kind == Template || Kind == TemplateExpansion) { 208 TemplateArg.Name = Other.TemplateArg.Name; 209 TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions; 210 } else { 211 TypeOrValue = Other.TypeOrValue; 212 } 213 214 return *this; 215 } 216 ~TemplateArgument()217 ~TemplateArgument() { 218 using llvm::APSInt; 219 220 if (Kind == Integral) 221 getAsIntegral()->~APSInt(); 222 } 223 224 /// \brief Create a new template argument pack by copying the given set of 225 /// template arguments. 226 static TemplateArgument CreatePackCopy(ASTContext &Context, 227 const TemplateArgument *Args, 228 unsigned NumArgs); 229 230 /// \brief Return the kind of stored template argument. getKind()231 ArgKind getKind() const { return (ArgKind)Kind; } 232 233 /// \brief Determine whether this template argument has no value. isNull()234 bool isNull() const { return Kind == Null; } 235 236 /// \brief Whether this template argument is dependent on a template 237 /// parameter such that its result can change from one instantiation to 238 /// another. 239 bool isDependent() const; 240 241 /// \brief Whether this template argument is dependent on a template 242 /// parameter. 243 bool isInstantiationDependent() const; 244 245 /// \brief Whether this template argument contains an unexpanded 246 /// parameter pack. 247 bool containsUnexpandedParameterPack() const; 248 249 /// \brief Determine whether this template argument is a pack expansion. 250 bool isPackExpansion() const; 251 252 /// \brief Retrieve the template argument as a type. getAsType()253 QualType getAsType() const { 254 if (Kind != Type) 255 return QualType(); 256 257 return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue)); 258 } 259 260 /// \brief Retrieve the template argument as a declaration. getAsDecl()261 Decl *getAsDecl() const { 262 if (Kind != Declaration) 263 return 0; 264 return reinterpret_cast<Decl *>(TypeOrValue); 265 } 266 267 /// \brief Retrieve the template argument as a template name. getAsTemplate()268 TemplateName getAsTemplate() const { 269 if (Kind != Template) 270 return TemplateName(); 271 272 return TemplateName::getFromVoidPointer(TemplateArg.Name); 273 } 274 275 /// \brief Retrieve the template argument as a template name; if the argument 276 /// is a pack expansion, return the pattern as a template name. getAsTemplateOrTemplatePattern()277 TemplateName getAsTemplateOrTemplatePattern() const { 278 if (Kind != Template && Kind != TemplateExpansion) 279 return TemplateName(); 280 281 return TemplateName::getFromVoidPointer(TemplateArg.Name); 282 } 283 284 /// \brief Retrieve the number of expansions that a template template argument 285 /// expansion will produce, if known. 286 llvm::Optional<unsigned> getNumTemplateExpansions() const; 287 288 /// \brief Retrieve the template argument as an integral value. getAsIntegral()289 llvm::APSInt *getAsIntegral() { 290 if (Kind != Integral) 291 return 0; 292 return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]); 293 } 294 getAsIntegral()295 const llvm::APSInt *getAsIntegral() const { 296 return const_cast<TemplateArgument*>(this)->getAsIntegral(); 297 } 298 299 /// \brief Retrieve the type of the integral value. getIntegralType()300 QualType getIntegralType() const { 301 if (Kind != Integral) 302 return QualType(); 303 304 return QualType::getFromOpaquePtr(Integer.Type); 305 } 306 setIntegralType(QualType T)307 void setIntegralType(QualType T) { 308 assert(Kind == Integral && 309 "Cannot set the integral type of a non-integral template argument"); 310 Integer.Type = T.getAsOpaquePtr(); 311 } 312 313 /// \brief Retrieve the template argument as an expression. getAsExpr()314 Expr *getAsExpr() const { 315 if (Kind != Expression) 316 return 0; 317 318 return reinterpret_cast<Expr *>(TypeOrValue); 319 } 320 321 /// \brief Iterator that traverses the elements of a template argument pack. 322 typedef const TemplateArgument * pack_iterator; 323 324 /// \brief Iterator referencing the first argument of a template argument 325 /// pack. pack_begin()326 pack_iterator pack_begin() const { 327 assert(Kind == Pack); 328 return Args.Args; 329 } 330 331 /// \brief Iterator referencing one past the last argument of a template 332 /// argument pack. pack_end()333 pack_iterator pack_end() const { 334 assert(Kind == Pack); 335 return Args.Args + Args.NumArgs; 336 } 337 338 /// \brief The number of template arguments in the given template argument 339 /// pack. pack_size()340 unsigned pack_size() const { 341 assert(Kind == Pack); 342 return Args.NumArgs; 343 } 344 345 /// Determines whether two template arguments are superficially the 346 /// same. 347 bool structurallyEquals(const TemplateArgument &Other) const; 348 349 /// \brief When the template argument is a pack expansion, returns 350 /// the pattern of the pack expansion. 351 /// 352 /// \param Ellipsis Will be set to the location of the ellipsis. 353 TemplateArgument getPackExpansionPattern() const; 354 355 /// \brief Print this template argument to the given output stream. 356 void print(const PrintingPolicy &Policy, raw_ostream &Out) const; 357 358 /// \brief Used to insert TemplateArguments into FoldingSets. 359 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 360 }; 361 362 /// Location information for a TemplateArgument. 363 struct TemplateArgumentLocInfo { 364 private: 365 union { 366 Expr *Expression; 367 TypeSourceInfo *Declarator; 368 struct { 369 // FIXME: We'd like to just use the qualifier in the TemplateName, 370 // but template arguments get canonicalized too quickly. 371 NestedNameSpecifier *Qualifier; 372 void *QualifierLocData; 373 unsigned TemplateNameLoc; 374 unsigned EllipsisLoc; 375 } Template; 376 }; 377 378 public: 379 TemplateArgumentLocInfo(); 380 TemplateArgumentLocInfoTemplateArgumentLocInfo381 TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {} 382 TemplateArgumentLocInfoTemplateArgumentLocInfo383 TemplateArgumentLocInfo(Expr *E) : Expression(E) {} 384 TemplateArgumentLocInfoTemplateArgumentLocInfo385 TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc, 386 SourceLocation TemplateNameLoc, 387 SourceLocation EllipsisLoc) 388 { 389 Template.Qualifier = QualifierLoc.getNestedNameSpecifier(); 390 Template.QualifierLocData = QualifierLoc.getOpaqueData(); 391 Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding(); 392 Template.EllipsisLoc = EllipsisLoc.getRawEncoding(); 393 } 394 getAsTypeSourceInfoTemplateArgumentLocInfo395 TypeSourceInfo *getAsTypeSourceInfo() const { 396 return Declarator; 397 } 398 getAsExprTemplateArgumentLocInfo399 Expr *getAsExpr() const { 400 return Expression; 401 } 402 getTemplateQualifierLocTemplateArgumentLocInfo403 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 404 return NestedNameSpecifierLoc(Template.Qualifier, 405 Template.QualifierLocData); 406 } 407 getTemplateNameLocTemplateArgumentLocInfo408 SourceLocation getTemplateNameLoc() const { 409 return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc); 410 } 411 getTemplateEllipsisLocTemplateArgumentLocInfo412 SourceLocation getTemplateEllipsisLoc() const { 413 return SourceLocation::getFromRawEncoding(Template.EllipsisLoc); 414 } 415 }; 416 417 /// Location wrapper for a TemplateArgument. TemplateArgument is to 418 /// TemplateArgumentLoc as Type is to TypeLoc. 419 class TemplateArgumentLoc { 420 TemplateArgument Argument; 421 TemplateArgumentLocInfo LocInfo; 422 423 public: TemplateArgumentLoc()424 TemplateArgumentLoc() {} 425 TemplateArgumentLoc(const TemplateArgument & Argument,TemplateArgumentLocInfo Opaque)426 TemplateArgumentLoc(const TemplateArgument &Argument, 427 TemplateArgumentLocInfo Opaque) 428 : Argument(Argument), LocInfo(Opaque) { 429 } 430 TemplateArgumentLoc(const TemplateArgument & Argument,TypeSourceInfo * TInfo)431 TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 432 : Argument(Argument), LocInfo(TInfo) { 433 assert(Argument.getKind() == TemplateArgument::Type); 434 } 435 TemplateArgumentLoc(const TemplateArgument & Argument,Expr * E)436 TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 437 : Argument(Argument), LocInfo(E) { 438 assert(Argument.getKind() == TemplateArgument::Expression); 439 } 440 441 TemplateArgumentLoc(const TemplateArgument &Argument, 442 NestedNameSpecifierLoc QualifierLoc, 443 SourceLocation TemplateNameLoc, 444 SourceLocation EllipsisLoc = SourceLocation()) Argument(Argument)445 : Argument(Argument), LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) { 446 assert(Argument.getKind() == TemplateArgument::Template || 447 Argument.getKind() == TemplateArgument::TemplateExpansion); 448 } 449 450 /// \brief - Fetches the primary location of the argument. getLocation()451 SourceLocation getLocation() const { 452 if (Argument.getKind() == TemplateArgument::Template || 453 Argument.getKind() == TemplateArgument::TemplateExpansion) 454 return getTemplateNameLoc(); 455 456 return getSourceRange().getBegin(); 457 } 458 459 /// \brief - Fetches the full source range of the argument. 460 SourceRange getSourceRange() const LLVM_READONLY; 461 getArgument()462 const TemplateArgument &getArgument() const { 463 return Argument; 464 } 465 getLocInfo()466 TemplateArgumentLocInfo getLocInfo() const { 467 return LocInfo; 468 } 469 getTypeSourceInfo()470 TypeSourceInfo *getTypeSourceInfo() const { 471 assert(Argument.getKind() == TemplateArgument::Type); 472 return LocInfo.getAsTypeSourceInfo(); 473 } 474 getSourceExpression()475 Expr *getSourceExpression() const { 476 assert(Argument.getKind() == TemplateArgument::Expression); 477 return LocInfo.getAsExpr(); 478 } 479 getSourceDeclExpression()480 Expr *getSourceDeclExpression() const { 481 assert(Argument.getKind() == TemplateArgument::Declaration); 482 return LocInfo.getAsExpr(); 483 } 484 getTemplateQualifierLoc()485 NestedNameSpecifierLoc getTemplateQualifierLoc() const { 486 assert(Argument.getKind() == TemplateArgument::Template || 487 Argument.getKind() == TemplateArgument::TemplateExpansion); 488 return LocInfo.getTemplateQualifierLoc(); 489 } 490 getTemplateNameLoc()491 SourceLocation getTemplateNameLoc() const { 492 assert(Argument.getKind() == TemplateArgument::Template || 493 Argument.getKind() == TemplateArgument::TemplateExpansion); 494 return LocInfo.getTemplateNameLoc(); 495 } 496 getTemplateEllipsisLoc()497 SourceLocation getTemplateEllipsisLoc() const { 498 assert(Argument.getKind() == TemplateArgument::TemplateExpansion); 499 return LocInfo.getTemplateEllipsisLoc(); 500 } 501 502 /// \brief When the template argument is a pack expansion, returns 503 /// the pattern of the pack expansion. 504 /// 505 /// \param Ellipsis Will be set to the location of the ellipsis. 506 /// 507 /// \param NumExpansions Will be set to the number of expansions that will 508 /// be generated from this pack expansion, if known a priori. 509 TemplateArgumentLoc getPackExpansionPattern(SourceLocation &Ellipsis, 510 llvm::Optional<unsigned> &NumExpansions, 511 ASTContext &Context) const; 512 }; 513 514 /// A convenient class for passing around template argument 515 /// information. Designed to be passed by reference. 516 class TemplateArgumentListInfo { 517 SmallVector<TemplateArgumentLoc, 8> Arguments; 518 SourceLocation LAngleLoc; 519 SourceLocation RAngleLoc; 520 521 // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 522 // instead. 523 void* operator new(size_t bytes, ASTContext& C); 524 525 public: TemplateArgumentListInfo()526 TemplateArgumentListInfo() {} 527 TemplateArgumentListInfo(SourceLocation LAngleLoc,SourceLocation RAngleLoc)528 TemplateArgumentListInfo(SourceLocation LAngleLoc, 529 SourceLocation RAngleLoc) 530 : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 531 getLAngleLoc()532 SourceLocation getLAngleLoc() const { return LAngleLoc; } getRAngleLoc()533 SourceLocation getRAngleLoc() const { return RAngleLoc; } 534 setLAngleLoc(SourceLocation Loc)535 void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } setRAngleLoc(SourceLocation Loc)536 void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 537 size()538 unsigned size() const { return Arguments.size(); } 539 getArgumentArray()540 const TemplateArgumentLoc *getArgumentArray() const { 541 return Arguments.data(); 542 } 543 544 const TemplateArgumentLoc &operator[](unsigned I) const { 545 return Arguments[I]; 546 } 547 addArgument(const TemplateArgumentLoc & Loc)548 void addArgument(const TemplateArgumentLoc &Loc) { 549 Arguments.push_back(Loc); 550 } 551 }; 552 553 /// \brief Represents an explicit template argument list in C++, e.g., 554 /// the "<int>" in "sort<int>". 555 /// This is safe to be used inside an AST node, in contrast with 556 /// TemplateArgumentListInfo. 557 struct ASTTemplateArgumentListInfo { 558 /// \brief The source location of the left angle bracket ('<'); 559 SourceLocation LAngleLoc; 560 561 /// \brief The source location of the right angle bracket ('>'); 562 SourceLocation RAngleLoc; 563 564 /// \brief The number of template arguments in TemplateArgs. 565 /// The actual template arguments (if any) are stored after the 566 /// ExplicitTemplateArgumentList structure. 567 unsigned NumTemplateArgs; 568 569 /// \brief Retrieve the template arguments getTemplateArgsASTTemplateArgumentListInfo570 TemplateArgumentLoc *getTemplateArgs() { 571 return reinterpret_cast<TemplateArgumentLoc *> (this + 1); 572 } 573 574 /// \brief Retrieve the template arguments getTemplateArgsASTTemplateArgumentListInfo575 const TemplateArgumentLoc *getTemplateArgs() const { 576 return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); 577 } 578 579 const TemplateArgumentLoc &operator[](unsigned I) const { 580 return getTemplateArgs()[I]; 581 } 582 583 static const ASTTemplateArgumentListInfo *Create(ASTContext &C, 584 const TemplateArgumentListInfo &List); 585 586 void initializeFrom(const TemplateArgumentListInfo &List); 587 void initializeFrom(const TemplateArgumentListInfo &List, 588 bool &Dependent, bool &InstantiationDependent, 589 bool &ContainsUnexpandedParameterPack); 590 void copyInto(TemplateArgumentListInfo &List) const; 591 static std::size_t sizeFor(unsigned NumTemplateArgs); 592 }; 593 594 /// \brief Extends ASTTemplateArgumentListInfo with the source location 595 /// information for the template keyword; this is used as part of the 596 /// representation of qualified identifiers, such as S<T>::template apply<T>. 597 struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { 598 typedef ASTTemplateArgumentListInfo Base; 599 600 // NOTE: the source location of the (optional) template keyword is 601 // stored after all template arguments. 602 603 /// \brief Get the source location of the template keyword. getTemplateKeywordLocASTTemplateKWAndArgsInfo604 SourceLocation getTemplateKeywordLoc() const { 605 return *reinterpret_cast<const SourceLocation*> 606 (getTemplateArgs() + NumTemplateArgs); 607 } 608 609 /// \brief Sets the source location of the template keyword. setTemplateKeywordLocASTTemplateKWAndArgsInfo610 void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { 611 *reinterpret_cast<SourceLocation*> 612 (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; 613 } 614 615 static const ASTTemplateKWAndArgsInfo* 616 Create(ASTContext &C, SourceLocation TemplateKWLoc, 617 const TemplateArgumentListInfo &List); 618 619 void initializeFrom(SourceLocation TemplateKWLoc, 620 const TemplateArgumentListInfo &List); 621 void initializeFrom(SourceLocation TemplateKWLoc, 622 const TemplateArgumentListInfo &List, 623 bool &Dependent, bool &InstantiationDependent, 624 bool &ContainsUnexpandedParameterPack); 625 void initializeFrom(SourceLocation TemplateKWLoc); 626 627 static std::size_t sizeFor(unsigned NumTemplateArgs); 628 }; 629 630 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, 631 const TemplateArgument &Arg); 632 633 inline TemplateSpecializationType::iterator end()634 TemplateSpecializationType::end() const { 635 return getArgs() + getNumArgs(); 636 } 637 638 inline DependentTemplateSpecializationType::iterator end()639 DependentTemplateSpecializationType::end() const { 640 return getArgs() + getNumArgs(); 641 } 642 643 inline const TemplateArgument & getArg(unsigned Idx)644 TemplateSpecializationType::getArg(unsigned Idx) const { 645 assert(Idx < getNumArgs() && "Template argument out of range"); 646 return getArgs()[Idx]; 647 } 648 649 inline const TemplateArgument & getArg(unsigned Idx)650 DependentTemplateSpecializationType::getArg(unsigned Idx) const { 651 assert(Idx < getNumArgs() && "Template argument out of range"); 652 return getArgs()[Idx]; 653 } 654 655 } // end namespace clang 656 657 #endif 658