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