- //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file provides definitions which are common for all kinds of 
- //  template representation. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H 
- #define LLVM_CLANG_AST_TEMPLATEBASE_H 
-   
- #include "clang/AST/DependenceFlags.h" 
- #include "clang/AST/NestedNameSpecifier.h" 
- #include "clang/AST/TemplateName.h" 
- #include "clang/AST/Type.h" 
- #include "clang/Basic/LLVM.h" 
- #include "clang/Basic/SourceLocation.h" 
- #include "llvm/ADT/APInt.h" 
- #include "llvm/ADT/APSInt.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/SmallVector.h" 
- #include "llvm/Support/Compiler.h" 
- #include "llvm/Support/TrailingObjects.h" 
- #include <cassert> 
- #include <cstddef> 
- #include <cstdint> 
- #include <optional> 
-   
- namespace llvm { 
-   
- class FoldingSetNodeID; 
-   
- // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a 
- // full definition of Expr, but this file only sees a forward del because of 
- // the dependency. 
- template <> struct PointerLikeTypeTraits<clang::Expr *> { 
-   static inline void *getAsVoidPointer(clang::Expr *P) { return P; } 
-   static inline clang::Expr *getFromVoidPointer(void *P) { 
-     return static_cast<clang::Expr *>(P); 
-   } 
-   static constexpr int NumLowBitsAvailable = 2; 
- }; 
-   
- } // namespace llvm 
-   
- namespace clang { 
-   
- class ASTContext; 
- class Expr; 
- struct PrintingPolicy; 
- class TypeSourceInfo; 
- class ValueDecl; 
-   
- /// Represents a template argument. 
- class TemplateArgument { 
- public: 
-   /// The kind of template argument we're storing. 
-   enum ArgKind { 
-     /// Represents an empty template argument, e.g., one that has not 
-     /// been deduced. 
-     Null = 0, 
-   
-     /// The template argument is a type. 
-     Type, 
-   
-     /// The template argument is a declaration that was provided for a pointer, 
-     /// reference, or pointer to member non-type template parameter. 
-     Declaration, 
-   
-     /// The template argument is a null pointer or null pointer to member that 
-     /// was provided for a non-type template parameter. 
-     NullPtr, 
-   
-     /// The template argument is an integral value stored in an llvm::APSInt 
-     /// that was provided for an integral non-type template parameter. 
-     Integral, 
-   
-     /// The template argument is a template name that was provided for a 
-     /// template template parameter. 
-     Template, 
-   
-     /// The template argument is a pack expansion of a template name that was 
-     /// provided for a template template parameter. 
-     TemplateExpansion, 
-   
-     /// The template argument is an expression, and we've not resolved it to one 
-     /// of the other forms yet, either because it's dependent or because we're 
-     /// representing a non-canonical template argument (for instance, in a 
-     /// TemplateSpecializationType). 
-     Expression, 
-   
-     /// The template argument is actually a parameter pack. Arguments are stored 
-     /// in the Args struct. 
-     Pack 
-   }; 
-   
- private: 
-   /// The kind of template argument we're storing. 
-   
-   struct DA { 
-     unsigned Kind; 
-     void *QT; 
-     ValueDecl *D; 
-   }; 
-   struct I { 
-     unsigned Kind; 
-     // We store a decomposed APSInt with the data allocated by ASTContext if 
-     // BitWidth > 64. The memory may be shared between multiple 
-     // TemplateArgument instances. 
-     unsigned BitWidth : 31; 
-     unsigned IsUnsigned : 1; 
-     union { 
-       /// Used to store the <= 64 bits integer value. 
-       uint64_t VAL; 
-   
-       /// Used to store the >64 bits integer value. 
-       const uint64_t *pVal; 
-     }; 
-     void *Type; 
-   }; 
-   struct A { 
-     unsigned Kind; 
-     unsigned NumArgs; 
-     const TemplateArgument *Args; 
-   }; 
-   struct TA { 
-     unsigned Kind; 
-     unsigned NumExpansions; 
-     void *Name; 
-   }; 
-   struct TV { 
-     unsigned Kind; 
-     uintptr_t V; 
-   }; 
-   union { 
-     struct DA DeclArg; 
-     struct I Integer; 
-     struct A Args; 
-     struct TA TemplateArg; 
-     struct TV TypeOrValue; 
-   }; 
-   
- public: 
-   /// Construct an empty, invalid template argument. 
-   constexpr TemplateArgument() : TypeOrValue({Null, 0}) {} 
-   
-   /// Construct a template type argument. 
-   TemplateArgument(QualType T, bool isNullPtr = false) { 
-     TypeOrValue.Kind = isNullPtr ? NullPtr : Type; 
-     TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); 
-   } 
-   
-   /// Construct a template argument that refers to a 
-   /// declaration, which is either an external declaration or a 
-   /// template declaration. 
-   TemplateArgument(ValueDecl *D, QualType QT) { 
-     assert(D && "Expected decl"); 
-     DeclArg.Kind = Declaration; 
-     DeclArg.QT = QT.getAsOpaquePtr(); 
-     DeclArg.D = D; 
-   } 
-   
-   /// Construct an integral constant template argument. The memory to 
-   /// store the value is allocated with Ctx. 
-   TemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType Type); 
-   
-   /// Construct an integral constant template argument with the same 
-   /// value as Other but a different type. 
-   TemplateArgument(const TemplateArgument &Other, QualType Type) { 
-     Integer = Other.Integer; 
-     Integer.Type = Type.getAsOpaquePtr(); 
-   } 
-   
-   /// Construct a template argument that is a template. 
-   /// 
-   /// This form of template argument is generally used for template template 
-   /// parameters. However, the template name could be a dependent template 
-   /// name that ends up being instantiated to a function template whose address 
-   /// is taken. 
-   /// 
-   /// \param Name The template name. 
-   TemplateArgument(TemplateName Name) { 
-     TemplateArg.Kind = Template; 
-     TemplateArg.Name = Name.getAsVoidPointer(); 
-     TemplateArg.NumExpansions = 0; 
-   } 
-   
-   /// Construct a template argument that is a template pack expansion. 
-   /// 
-   /// This form of template argument is generally used for template template 
-   /// parameters. However, the template name could be a dependent template 
-   /// name that ends up being instantiated to a function template whose address 
-   /// is taken. 
-   /// 
-   /// \param Name The template name. 
-   /// 
-   /// \param NumExpansions The number of expansions that will be generated by 
-   /// instantiating 
-   TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions) { 
-     TemplateArg.Kind = TemplateExpansion; 
-     TemplateArg.Name = Name.getAsVoidPointer(); 
-     if (NumExpansions) 
-       TemplateArg.NumExpansions = *NumExpansions + 1; 
-     else 
-       TemplateArg.NumExpansions = 0; 
-   } 
-   
-   /// Construct a template argument that is an expression. 
-   /// 
-   /// This form of template argument only occurs in template argument 
-   /// lists used for dependent types and for expression; it will not 
-   /// occur in a non-dependent, canonical template argument list. 
-   TemplateArgument(Expr *E) { 
-     TypeOrValue.Kind = Expression; 
-     TypeOrValue.V = reinterpret_cast<uintptr_t>(E); 
-   } 
-   
-   /// Construct a template argument that is a template argument pack. 
-   /// 
-   /// We assume that storage for the template arguments provided 
-   /// outlives the TemplateArgument itself. 
-   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { 
-     this->Args.Kind = Pack; 
-     this->Args.Args = Args.data(); 
-     this->Args.NumArgs = Args.size(); 
-   } 
-   
-   TemplateArgument(TemplateName, bool) = delete; 
-   
-   static TemplateArgument getEmptyPack() { 
-     return TemplateArgument(std::nullopt); 
-   } 
-   
-   /// Create a new template argument pack by copying the given set of 
-   /// template arguments. 
-   static TemplateArgument CreatePackCopy(ASTContext &Context, 
-                                          ArrayRef<TemplateArgument> Args); 
-   
-   /// Return the kind of stored template argument. 
-   ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } 
-   
-   /// Determine whether this template argument has no value. 
-   bool isNull() const { return getKind() == Null; } 
-   
-   TemplateArgumentDependence getDependence() const; 
-   
-   /// Whether this template argument is dependent on a template 
-   /// parameter such that its result can change from one instantiation to 
-   /// another. 
-   bool isDependent() const; 
-   
-   /// Whether this template argument is dependent on a template 
-   /// parameter. 
-   bool isInstantiationDependent() const; 
-   
-   /// Whether this template argument contains an unexpanded 
-   /// parameter pack. 
-   bool containsUnexpandedParameterPack() const; 
-   
-   /// Determine whether this template argument is a pack expansion. 
-   bool isPackExpansion() const; 
-   
-   /// Retrieve the type for a type template argument. 
-   QualType getAsType() const { 
-     assert(getKind() == Type && "Unexpected kind"); 
-     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 
-   } 
-   
-   /// Retrieve the declaration for a declaration non-type 
-   /// template argument. 
-   ValueDecl *getAsDecl() const { 
-     assert(getKind() == Declaration && "Unexpected kind"); 
-     return DeclArg.D; 
-   } 
-   
-   QualType getParamTypeForDecl() const { 
-     assert(getKind() == Declaration && "Unexpected kind"); 
-     return QualType::getFromOpaquePtr(DeclArg.QT); 
-   } 
-   
-   /// Retrieve the type for null non-type template argument. 
-   QualType getNullPtrType() const { 
-     assert(getKind() == NullPtr && "Unexpected kind"); 
-     return QualType::getFromOpaquePtr(reinterpret_cast<void*>(TypeOrValue.V)); 
-   } 
-   
-   /// Retrieve the template name for a template name argument. 
-   TemplateName getAsTemplate() const { 
-     assert(getKind() == Template && "Unexpected kind"); 
-     return TemplateName::getFromVoidPointer(TemplateArg.Name); 
-   } 
-   
-   /// Retrieve the template argument as a template name; if the argument 
-   /// is a pack expansion, return the pattern as a template name. 
-   TemplateName getAsTemplateOrTemplatePattern() const { 
-     assert((getKind() == Template || getKind() == TemplateExpansion) && 
-            "Unexpected kind"); 
-   
-     return TemplateName::getFromVoidPointer(TemplateArg.Name); 
-   } 
-   
-   /// Retrieve the number of expansions that a template template argument 
-   /// expansion will produce, if known. 
-   std::optional<unsigned> getNumTemplateExpansions() const; 
-   
-   /// Retrieve the template argument as an integral value. 
-   // FIXME: Provide a way to read the integral data without copying the value. 
-   llvm::APSInt getAsIntegral() const { 
-     assert(getKind() == Integral && "Unexpected kind"); 
-   
-     using namespace llvm; 
-   
-     if (Integer.BitWidth <= 64) 
-       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned); 
-   
-     unsigned NumWords = APInt::getNumWords(Integer.BitWidth); 
-     return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)), 
-                   Integer.IsUnsigned); 
-   } 
-   
-   /// Retrieve the type of the integral value. 
-   QualType getIntegralType() const { 
-     assert(getKind() == Integral && "Unexpected kind"); 
-     return QualType::getFromOpaquePtr(Integer.Type); 
-   } 
-   
-   void setIntegralType(QualType T) { 
-     assert(getKind() == Integral && "Unexpected kind"); 
-     Integer.Type = T.getAsOpaquePtr(); 
-   } 
-   
-   /// If this is a non-type template argument, get its type. Otherwise, 
-   /// returns a null QualType. 
-   QualType getNonTypeTemplateArgumentType() const; 
-   
-   /// Retrieve the template argument as an expression. 
-   Expr *getAsExpr() const { 
-     assert(getKind() == Expression && "Unexpected kind"); 
-     return reinterpret_cast<Expr *>(TypeOrValue.V); 
-   } 
-   
-   /// Iterator that traverses the elements of a template argument pack. 
-   using pack_iterator = const TemplateArgument *; 
-   
-   /// Iterator referencing the first argument of a template argument 
-   /// pack. 
-   pack_iterator pack_begin() const { 
-     assert(getKind() == Pack); 
-     return Args.Args; 
-   } 
-   
-   /// Iterator referencing one past the last argument of a template 
-   /// argument pack. 
-   pack_iterator pack_end() const { 
-     assert(getKind() == Pack); 
-     return Args.Args + Args.NumArgs; 
-   } 
-   
-   /// Iterator range referencing all of the elements of a template 
-   /// argument pack. 
-   ArrayRef<TemplateArgument> pack_elements() const { 
-     return llvm::ArrayRef(pack_begin(), pack_end()); 
-   } 
-   
-   /// The number of template arguments in the given template argument 
-   /// pack. 
-   unsigned pack_size() const { 
-     assert(getKind() == Pack); 
-     return Args.NumArgs; 
-   } 
-   
-   /// Return the array of arguments in this template argument pack. 
-   ArrayRef<TemplateArgument> getPackAsArray() const { 
-     assert(getKind() == Pack); 
-     return llvm::ArrayRef(Args.Args, Args.NumArgs); 
-   } 
-   
-   /// Determines whether two template arguments are superficially the 
-   /// same. 
-   bool structurallyEquals(const TemplateArgument &Other) const; 
-   
-   /// When the template argument is a pack expansion, returns 
-   /// the pattern of the pack expansion. 
-   TemplateArgument getPackExpansionPattern() const; 
-   
-   /// Print this template argument to the given output stream. 
-   void print(const PrintingPolicy &Policy, raw_ostream &Out, 
-              bool IncludeType) const; 
-   
-   /// Debugging aid that dumps the template argument. 
-   void dump(raw_ostream &Out) const; 
-   
-   /// Debugging aid that dumps the template argument to standard error. 
-   void dump() const; 
-   
-   /// Used to insert TemplateArguments into FoldingSets. 
-   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; 
- }; 
-   
- /// Location information for a TemplateArgument. 
- struct TemplateArgumentLocInfo { 
- private: 
-   struct TemplateTemplateArgLocInfo { 
-     // FIXME: We'd like to just use the qualifier in the TemplateName, 
-     // but template arguments get canonicalized too quickly. 
-     NestedNameSpecifier *Qualifier; 
-     void *QualifierLocData; 
-     SourceLocation TemplateNameLoc; 
-     SourceLocation EllipsisLoc; 
-   }; 
-   
-   llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *> 
-       Pointer; 
-   
-   TemplateTemplateArgLocInfo *getTemplate() const { 
-     return Pointer.get<TemplateTemplateArgLocInfo *>(); 
-   } 
-   
- public: 
-   TemplateArgumentLocInfo() {} 
-   TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; } 
-   
-   TemplateArgumentLocInfo(Expr *E) { Pointer = E; } 
-   // Ctx is used for allocation -- this case is unusually large and also rare, 
-   // so we store the payload out-of-line. 
-   TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, 
-                           SourceLocation TemplateNameLoc, 
-                           SourceLocation EllipsisLoc); 
-   
-   TypeSourceInfo *getAsTypeSourceInfo() const { 
-     return Pointer.get<TypeSourceInfo *>(); 
-   } 
-   
-   Expr *getAsExpr() const { return Pointer.get<Expr *>(); } 
-   
-   NestedNameSpecifierLoc getTemplateQualifierLoc() const { 
-     const auto *Template = getTemplate(); 
-     return NestedNameSpecifierLoc(Template->Qualifier, 
-                                   Template->QualifierLocData); 
-   } 
-   
-   SourceLocation getTemplateNameLoc() const { 
-     return getTemplate()->TemplateNameLoc; 
-   } 
-   
-   SourceLocation getTemplateEllipsisLoc() const { 
-     return getTemplate()->EllipsisLoc; 
-   } 
- }; 
-   
- /// Location wrapper for a TemplateArgument.  TemplateArgument is to 
- /// TemplateArgumentLoc as Type is to TypeLoc. 
- class TemplateArgumentLoc { 
-   TemplateArgument Argument; 
-   TemplateArgumentLocInfo LocInfo; 
-   
- public: 
-   TemplateArgumentLoc() {} 
-   
-   TemplateArgumentLoc(const TemplateArgument &Argument, 
-                       TemplateArgumentLocInfo Opaque) 
-       : Argument(Argument), LocInfo(Opaque) {} 
-   
-   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo) 
-       : Argument(Argument), LocInfo(TInfo) { 
-     assert(Argument.getKind() == TemplateArgument::Type); 
-   } 
-   
-   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E) 
-       : Argument(Argument), LocInfo(E) { 
-   
-     // Permit any kind of template argument that can be represented with an 
-     // expression. 
-     assert(Argument.getKind() == TemplateArgument::NullPtr || 
-            Argument.getKind() == TemplateArgument::Integral || 
-            Argument.getKind() == TemplateArgument::Declaration || 
-            Argument.getKind() == TemplateArgument::Expression); 
-   } 
-   
-   TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument, 
-                       NestedNameSpecifierLoc QualifierLoc, 
-                       SourceLocation TemplateNameLoc, 
-                       SourceLocation EllipsisLoc = SourceLocation()) 
-       : Argument(Argument), 
-         LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) { 
-     assert(Argument.getKind() == TemplateArgument::Template || 
-            Argument.getKind() == TemplateArgument::TemplateExpansion); 
-   } 
-   
-   /// - Fetches the primary location of the argument. 
-   SourceLocation getLocation() const { 
-     if (Argument.getKind() == TemplateArgument::Template || 
-         Argument.getKind() == TemplateArgument::TemplateExpansion) 
-       return getTemplateNameLoc(); 
-   
-     return getSourceRange().getBegin(); 
-   } 
-   
-   /// - Fetches the full source range of the argument. 
-   SourceRange getSourceRange() const LLVM_READONLY; 
-   
-   const TemplateArgument &getArgument() const { 
-     return Argument; 
-   } 
-   
-   TemplateArgumentLocInfo getLocInfo() const { 
-     return LocInfo; 
-   } 
-   
-   TypeSourceInfo *getTypeSourceInfo() const { 
-     if (Argument.getKind() != TemplateArgument::Type) 
-       return nullptr; 
-     return LocInfo.getAsTypeSourceInfo(); 
-   } 
-   
-   Expr *getSourceExpression() const { 
-     assert(Argument.getKind() == TemplateArgument::Expression); 
-     return LocInfo.getAsExpr(); 
-   } 
-   
-   Expr *getSourceDeclExpression() const { 
-     assert(Argument.getKind() == TemplateArgument::Declaration); 
-     return LocInfo.getAsExpr(); 
-   } 
-   
-   Expr *getSourceNullPtrExpression() const { 
-     assert(Argument.getKind() == TemplateArgument::NullPtr); 
-     return LocInfo.getAsExpr(); 
-   } 
-   
-   Expr *getSourceIntegralExpression() const { 
-     assert(Argument.getKind() == TemplateArgument::Integral); 
-     return LocInfo.getAsExpr(); 
-   } 
-   
-   NestedNameSpecifierLoc getTemplateQualifierLoc() const { 
-     if (Argument.getKind() != TemplateArgument::Template && 
-         Argument.getKind() != TemplateArgument::TemplateExpansion) 
-       return NestedNameSpecifierLoc(); 
-     return LocInfo.getTemplateQualifierLoc(); 
-   } 
-   
-   SourceLocation getTemplateNameLoc() const { 
-     if (Argument.getKind() != TemplateArgument::Template && 
-         Argument.getKind() != TemplateArgument::TemplateExpansion) 
-       return SourceLocation(); 
-     return LocInfo.getTemplateNameLoc(); 
-   } 
-   
-   SourceLocation getTemplateEllipsisLoc() const { 
-     if (Argument.getKind() != TemplateArgument::TemplateExpansion) 
-       return SourceLocation(); 
-     return LocInfo.getTemplateEllipsisLoc(); 
-   } 
- }; 
-   
- /// A convenient class for passing around template argument 
- /// information.  Designed to be passed by reference. 
- class TemplateArgumentListInfo { 
-   SmallVector<TemplateArgumentLoc, 8> Arguments; 
-   SourceLocation LAngleLoc; 
-   SourceLocation RAngleLoc; 
-   
- public: 
-   TemplateArgumentListInfo() = default; 
-   
-   TemplateArgumentListInfo(SourceLocation LAngleLoc, 
-                            SourceLocation RAngleLoc) 
-       : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {} 
-   
-   // This can leak if used in an AST node, use ASTTemplateArgumentListInfo 
-   // instead. 
-   void *operator new(size_t bytes, ASTContext &C) = delete; 
-   
-   SourceLocation getLAngleLoc() const { return LAngleLoc; } 
-   SourceLocation getRAngleLoc() const { return RAngleLoc; } 
-   
-   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; } 
-   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; } 
-   
-   unsigned size() const { return Arguments.size(); } 
-   
-   const TemplateArgumentLoc *getArgumentArray() const { 
-     return Arguments.data(); 
-   } 
-   
-   llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 
-     return Arguments; 
-   } 
-   
-   const TemplateArgumentLoc &operator[](unsigned I) const { 
-     return Arguments[I]; 
-   } 
-   
-   TemplateArgumentLoc &operator[](unsigned I) { 
-     return Arguments[I]; 
-   } 
-   
-   void addArgument(const TemplateArgumentLoc &Loc) { 
-     Arguments.push_back(Loc); 
-   } 
- }; 
-   
- /// Represents an explicit template argument list in C++, e.g., 
- /// the "<int>" in "sort<int>". 
- /// This is safe to be used inside an AST node, in contrast with 
- /// TemplateArgumentListInfo. 
- struct ASTTemplateArgumentListInfo final 
-     : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, 
-                                     TemplateArgumentLoc> { 
- private: 
-   friend class ASTNodeImporter; 
-   friend TrailingObjects; 
-   
-   ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); 
-   
-   // FIXME: Is it ever necessary to copy to another context? 
-   ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List); 
-   
- public: 
-   /// The source location of the left angle bracket ('<'). 
-   SourceLocation LAngleLoc; 
-   
-   /// The source location of the right angle bracket ('>'). 
-   SourceLocation RAngleLoc; 
-   
-   /// The number of template arguments in TemplateArgs. 
-   unsigned NumTemplateArgs; 
-   
-   SourceLocation getLAngleLoc() const { return LAngleLoc; } 
-   SourceLocation getRAngleLoc() const { return RAngleLoc; } 
-   
-   /// Retrieve the template arguments 
-   const TemplateArgumentLoc *getTemplateArgs() const { 
-     return getTrailingObjects<TemplateArgumentLoc>(); 
-   } 
-   unsigned getNumTemplateArgs() const { return NumTemplateArgs; } 
-   
-   llvm::ArrayRef<TemplateArgumentLoc> arguments() const { 
-     return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs()); 
-   } 
-   
-   const TemplateArgumentLoc &operator[](unsigned I) const { 
-     return getTemplateArgs()[I]; 
-   } 
-   
-   static const ASTTemplateArgumentListInfo * 
-   Create(const ASTContext &C, const TemplateArgumentListInfo &List); 
-   
-   // FIXME: Is it ever necessary to copy to another context? 
-   static const ASTTemplateArgumentListInfo * 
-   Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List); 
- }; 
-   
- /// Represents an explicit template argument list in C++, e.g., 
- /// the "<int>" in "sort<int>". 
- /// 
- /// It is intended to be used as a trailing object on AST nodes, and 
- /// as such, doesn't contain the array of TemplateArgumentLoc itself, 
- /// but expects the containing object to also provide storage for 
- /// that. 
- struct alignas(void *) ASTTemplateKWAndArgsInfo { 
-   /// The source location of the left angle bracket ('<'). 
-   SourceLocation LAngleLoc; 
-   
-   /// The source location of the right angle bracket ('>'). 
-   SourceLocation RAngleLoc; 
-   
-   /// The source location of the template keyword; this is used 
-   /// as part of the representation of qualified identifiers, such as 
-   /// S<T>::template apply<T>.  Will be empty if this expression does 
-   /// not have a template keyword. 
-   SourceLocation TemplateKWLoc; 
-   
-   /// The number of template arguments in TemplateArgs. 
-   unsigned NumTemplateArgs; 
-   
-   void initializeFrom(SourceLocation TemplateKWLoc, 
-                       const TemplateArgumentListInfo &List, 
-                       TemplateArgumentLoc *OutArgArray); 
-   // FIXME: The parameter Deps is the result populated by this method, the 
-   // caller doesn't need it since it is populated by computeDependence. remove 
-   // it. 
-   void initializeFrom(SourceLocation TemplateKWLoc, 
-                       const TemplateArgumentListInfo &List, 
-                       TemplateArgumentLoc *OutArgArray, 
-                       TemplateArgumentDependence &Deps); 
-   void initializeFrom(SourceLocation TemplateKWLoc); 
-   
-   void copyInto(const TemplateArgumentLoc *ArgArray, 
-                 TemplateArgumentListInfo &List) const; 
- }; 
-   
- const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 
-                                       const TemplateArgument &Arg); 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_AST_TEMPLATEBASE_H 
-