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