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