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