Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:43

0001 //===- TemplateBase.h - Core classes for C++ templates ----------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file provides definitions which are common for all kinds of
0010 //  template representation.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
0015 #define LLVM_CLANG_AST_TEMPLATEBASE_H
0016 
0017 #include "clang/AST/DependenceFlags.h"
0018 #include "clang/AST/NestedNameSpecifier.h"
0019 #include "clang/AST/TemplateName.h"
0020 #include "clang/AST/Type.h"
0021 #include "clang/Basic/LLVM.h"
0022 #include "clang/Basic/SourceLocation.h"
0023 #include "llvm/ADT/APInt.h"
0024 #include "llvm/ADT/APSInt.h"
0025 #include "llvm/ADT/ArrayRef.h"
0026 #include "llvm/ADT/SmallVector.h"
0027 #include "llvm/Support/Compiler.h"
0028 #include "llvm/Support/TrailingObjects.h"
0029 #include <cassert>
0030 #include <cstddef>
0031 #include <cstdint>
0032 #include <optional>
0033 
0034 namespace llvm {
0035 
0036 class FoldingSetNodeID;
0037 
0038 // Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
0039 // full definition of Expr, but this file only sees a forward del because of
0040 // the dependency.
0041 template <> struct PointerLikeTypeTraits<clang::Expr *> {
0042   static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
0043   static inline clang::Expr *getFromVoidPointer(void *P) {
0044     return static_cast<clang::Expr *>(P);
0045   }
0046   static constexpr int NumLowBitsAvailable = 2;
0047 };
0048 
0049 } // namespace llvm
0050 
0051 namespace clang {
0052 
0053 class APValue;
0054 class ASTContext;
0055 class Expr;
0056 struct PrintingPolicy;
0057 class TypeSourceInfo;
0058 class ValueDecl;
0059 
0060 /// Represents a template argument.
0061 class TemplateArgument {
0062 public:
0063   /// The kind of template argument we're storing.
0064   enum ArgKind {
0065     /// Represents an empty template argument, e.g., one that has not
0066     /// been deduced.
0067     Null = 0,
0068 
0069     /// The template argument is a type.
0070     Type,
0071 
0072     /// The template argument is a declaration that was provided for a pointer,
0073     /// reference, or pointer to member non-type template parameter.
0074     Declaration,
0075 
0076     /// The template argument is a null pointer or null pointer to member that
0077     /// was provided for a non-type template parameter.
0078     NullPtr,
0079 
0080     /// The template argument is an integral value stored in an llvm::APSInt
0081     /// that was provided for an integral non-type template parameter.
0082     Integral,
0083 
0084     /// The template argument is a non-type template argument that can't be
0085     /// represented by the special-case Declaration, NullPtr, or Integral
0086     /// forms. These values are only ever produced by constant evaluation,
0087     /// so cannot be dependent.
0088     /// TODO: merge Declaration, NullPtr and Integral into this?
0089     StructuralValue,
0090 
0091     /// The template argument is a template name that was provided for a
0092     /// template template parameter.
0093     Template,
0094 
0095     /// The template argument is a pack expansion of a template name that was
0096     /// provided for a template template parameter.
0097     TemplateExpansion,
0098 
0099     /// The template argument is an expression, and we've not resolved it to one
0100     /// of the other forms yet, either because it's dependent or because we're
0101     /// representing a non-canonical template argument (for instance, in a
0102     /// TemplateSpecializationType).
0103     Expression,
0104 
0105     /// The template argument is actually a parameter pack. Arguments are stored
0106     /// in the Args struct.
0107     Pack
0108   };
0109 
0110 private:
0111   /// The kind of template argument we're storing.
0112 
0113   struct DA {
0114     LLVM_PREFERRED_TYPE(ArgKind)
0115     unsigned Kind : 31;
0116     LLVM_PREFERRED_TYPE(bool)
0117     unsigned IsDefaulted : 1;
0118     void *QT;
0119     ValueDecl *D;
0120   };
0121   struct I {
0122     LLVM_PREFERRED_TYPE(ArgKind)
0123     unsigned Kind : 31;
0124     LLVM_PREFERRED_TYPE(bool)
0125     unsigned IsDefaulted : 1;
0126     // We store a decomposed APSInt with the data allocated by ASTContext if
0127     // BitWidth > 64. The memory may be shared between multiple
0128     // TemplateArgument instances.
0129     unsigned BitWidth : 31;
0130     LLVM_PREFERRED_TYPE(bool)
0131     unsigned IsUnsigned : 1;
0132     union {
0133       /// Used to store the <= 64 bits integer value.
0134       uint64_t VAL;
0135 
0136       /// Used to store the >64 bits integer value.
0137       const uint64_t *pVal;
0138     };
0139     void *Type;
0140   };
0141   struct V {
0142     LLVM_PREFERRED_TYPE(ArgKind)
0143     unsigned Kind : 31;
0144     LLVM_PREFERRED_TYPE(bool)
0145     unsigned IsDefaulted : 1;
0146     APValue *Value;
0147     void *Type;
0148   };
0149   struct A {
0150     LLVM_PREFERRED_TYPE(ArgKind)
0151     unsigned Kind : 31;
0152     LLVM_PREFERRED_TYPE(bool)
0153     unsigned IsDefaulted : 1;
0154     unsigned NumArgs;
0155     const TemplateArgument *Args;
0156   };
0157   struct TA {
0158     LLVM_PREFERRED_TYPE(ArgKind)
0159     unsigned Kind : 31;
0160     LLVM_PREFERRED_TYPE(bool)
0161     unsigned IsDefaulted : 1;
0162     unsigned NumExpansions;
0163     void *Name;
0164   };
0165   struct TV {
0166     LLVM_PREFERRED_TYPE(ArgKind)
0167     unsigned Kind : 31;
0168     LLVM_PREFERRED_TYPE(bool)
0169     unsigned IsDefaulted : 1;
0170     uintptr_t V;
0171   };
0172   union {
0173     struct DA DeclArg;
0174     struct I Integer;
0175     struct V Value;
0176     struct A Args;
0177     struct TA TemplateArg;
0178     struct TV TypeOrValue;
0179   };
0180 
0181   void initFromType(QualType T, bool IsNullPtr, bool IsDefaulted);
0182   void initFromDeclaration(ValueDecl *D, QualType QT, bool IsDefaulted);
0183   void initFromIntegral(const ASTContext &Ctx, const llvm::APSInt &Value,
0184                         QualType Type, bool IsDefaulted);
0185   void initFromStructural(const ASTContext &Ctx, QualType Type,
0186                           const APValue &V, bool IsDefaulted);
0187 
0188 public:
0189   /// Construct an empty, invalid template argument.
0190   constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {}
0191 
0192   /// Construct a template type argument.
0193   TemplateArgument(QualType T, bool isNullPtr = false,
0194                    bool IsDefaulted = false) {
0195     initFromType(T, isNullPtr, IsDefaulted);
0196   }
0197 
0198   /// Construct a template argument that refers to a (non-dependent)
0199   /// declaration.
0200   TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) {
0201     initFromDeclaration(D, QT, IsDefaulted);
0202   }
0203 
0204   /// Construct an integral constant template argument. The memory to
0205   /// store the value is allocated with Ctx.
0206   TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
0207                    QualType Type, bool IsDefaulted = false);
0208 
0209   /// Construct a template argument from an arbitrary constant value.
0210   TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value,
0211                    bool IsDefaulted = false);
0212 
0213   /// Construct an integral constant template argument with the same
0214   /// value as Other but a different type.
0215   TemplateArgument(const TemplateArgument &Other, QualType Type) {
0216     Integer = Other.Integer;
0217     Integer.Type = Type.getAsOpaquePtr();
0218   }
0219 
0220   /// Construct a template argument that is a template.
0221   ///
0222   /// This form of template argument is generally used for template template
0223   /// parameters. However, the template name could be a dependent template
0224   /// name that ends up being instantiated to a function template whose address
0225   /// is taken.
0226   ///
0227   /// \param Name The template name.
0228   ///
0229   /// \param IsDefaulted If 'true', implies that this TemplateArgument
0230   /// corresponds to a default template parameter
0231   TemplateArgument(TemplateName Name, bool IsDefaulted = false) {
0232     TemplateArg.Kind = Template;
0233     TemplateArg.IsDefaulted = IsDefaulted;
0234     TemplateArg.Name = Name.getAsVoidPointer();
0235     TemplateArg.NumExpansions = 0;
0236   }
0237 
0238   /// Construct a template argument that is a template pack expansion.
0239   ///
0240   /// This form of template argument is generally used for template template
0241   /// parameters. However, the template name could be a dependent template
0242   /// name that ends up being instantiated to a function template whose address
0243   /// is taken.
0244   ///
0245   /// \param Name The template name.
0246   ///
0247   /// \param NumExpansions The number of expansions that will be generated by
0248   /// instantiating
0249   ///
0250   /// \param IsDefaulted If 'true', implies that this TemplateArgument
0251   /// corresponds to a default template parameter
0252   TemplateArgument(TemplateName Name, std::optional<unsigned> NumExpansions,
0253                    bool IsDefaulted = false) {
0254     TemplateArg.Kind = TemplateExpansion;
0255     TemplateArg.IsDefaulted = IsDefaulted;
0256     TemplateArg.Name = Name.getAsVoidPointer();
0257     if (NumExpansions)
0258       TemplateArg.NumExpansions = *NumExpansions + 1;
0259     else
0260       TemplateArg.NumExpansions = 0;
0261   }
0262 
0263   /// Construct a template argument that is an expression.
0264   ///
0265   /// This form of template argument only occurs in template argument
0266   /// lists used for dependent types and for expression; it will not
0267   /// occur in a non-dependent, canonical template argument list.
0268   TemplateArgument(Expr *E, bool IsDefaulted = false) {
0269     TypeOrValue.Kind = Expression;
0270     TypeOrValue.IsDefaulted = IsDefaulted;
0271     TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
0272   }
0273 
0274   /// Construct a template argument that is a template argument pack.
0275   ///
0276   /// We assume that storage for the template arguments provided
0277   /// outlives the TemplateArgument itself.
0278   explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
0279     this->Args.Kind = Pack;
0280     this->Args.IsDefaulted = false;
0281     this->Args.Args = Args.data();
0282     this->Args.NumArgs = Args.size();
0283   }
0284 
0285   static TemplateArgument getEmptyPack() {
0286     return TemplateArgument(ArrayRef<TemplateArgument>());
0287   }
0288 
0289   /// Create a new template argument pack by copying the given set of
0290   /// template arguments.
0291   static TemplateArgument CreatePackCopy(ASTContext &Context,
0292                                          ArrayRef<TemplateArgument> Args);
0293 
0294   /// Return the kind of stored template argument.
0295   ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; }
0296 
0297   /// Determine whether this template argument has no value.
0298   bool isNull() const { return getKind() == Null; }
0299 
0300   TemplateArgumentDependence getDependence() const;
0301 
0302   /// Whether this template argument is dependent on a template
0303   /// parameter such that its result can change from one instantiation to
0304   /// another.
0305   bool isDependent() const;
0306 
0307   /// Whether this template argument is dependent on a template
0308   /// parameter.
0309   bool isInstantiationDependent() const;
0310 
0311   /// Whether this template argument contains an unexpanded
0312   /// parameter pack.
0313   bool containsUnexpandedParameterPack() const;
0314 
0315   /// Determine whether this template argument is a pack expansion.
0316   bool isPackExpansion() const;
0317 
0318   /// Retrieve the type for a type template argument.
0319   QualType getAsType() const {
0320     assert(getKind() == Type && "Unexpected kind");
0321     return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
0322   }
0323 
0324   /// Retrieve the declaration for a declaration non-type
0325   /// template argument.
0326   ValueDecl *getAsDecl() const {
0327     assert(getKind() == Declaration && "Unexpected kind");
0328     return DeclArg.D;
0329   }
0330 
0331   QualType getParamTypeForDecl() const {
0332     assert(getKind() == Declaration && "Unexpected kind");
0333     return QualType::getFromOpaquePtr(DeclArg.QT);
0334   }
0335 
0336   /// Retrieve the type for null non-type template argument.
0337   QualType getNullPtrType() const {
0338     assert(getKind() == NullPtr && "Unexpected kind");
0339     return QualType::getFromOpaquePtr(reinterpret_cast<void *>(TypeOrValue.V));
0340   }
0341 
0342   /// Retrieve the template name for a template name argument.
0343   TemplateName getAsTemplate() const {
0344     assert(getKind() == Template && "Unexpected kind");
0345     return TemplateName::getFromVoidPointer(TemplateArg.Name);
0346   }
0347 
0348   /// Retrieve the template argument as a template name; if the argument
0349   /// is a pack expansion, return the pattern as a template name.
0350   TemplateName getAsTemplateOrTemplatePattern() const {
0351     assert((getKind() == Template || getKind() == TemplateExpansion) &&
0352            "Unexpected kind");
0353 
0354     return TemplateName::getFromVoidPointer(TemplateArg.Name);
0355   }
0356 
0357   /// Retrieve the number of expansions that a template template argument
0358   /// expansion will produce, if known.
0359   std::optional<unsigned> getNumTemplateExpansions() const;
0360 
0361   /// Retrieve the template argument as an integral value.
0362   // FIXME: Provide a way to read the integral data without copying the value.
0363   llvm::APSInt getAsIntegral() const {
0364     assert(getKind() == Integral && "Unexpected kind");
0365 
0366     using namespace llvm;
0367 
0368     if (Integer.BitWidth <= 64)
0369       return APSInt(APInt(Integer.BitWidth, Integer.VAL), Integer.IsUnsigned);
0370 
0371     unsigned NumWords = APInt::getNumWords(Integer.BitWidth);
0372     return APSInt(APInt(Integer.BitWidth, ArrayRef(Integer.pVal, NumWords)),
0373                   Integer.IsUnsigned);
0374   }
0375 
0376   /// Retrieve the type of the integral value.
0377   QualType getIntegralType() const {
0378     assert(getKind() == Integral && "Unexpected kind");
0379     return QualType::getFromOpaquePtr(Integer.Type);
0380   }
0381 
0382   void setIntegralType(QualType T) {
0383     assert(getKind() == Integral && "Unexpected kind");
0384     Integer.Type = T.getAsOpaquePtr();
0385   }
0386 
0387   /// Set to 'true' if this TemplateArgument corresponds to a
0388   /// default template parameter.
0389   void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; }
0390 
0391   /// If returns 'true', this TemplateArgument corresponds to a
0392   /// default template parameter.
0393   bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
0394 
0395   /// Get the value of a StructuralValue.
0396   const APValue &getAsStructuralValue() const { return *Value.Value; }
0397 
0398   /// Get the type of a StructuralValue.
0399   QualType getStructuralValueType() const {
0400     return QualType::getFromOpaquePtr(Value.Type);
0401   }
0402 
0403   /// If this is a non-type template argument, get its type. Otherwise,
0404   /// returns a null QualType.
0405   QualType getNonTypeTemplateArgumentType() const;
0406 
0407   /// Retrieve the template argument as an expression.
0408   Expr *getAsExpr() const {
0409     assert(getKind() == Expression && "Unexpected kind");
0410     return reinterpret_cast<Expr *>(TypeOrValue.V);
0411   }
0412 
0413   /// Iterator that traverses the elements of a template argument pack.
0414   using pack_iterator = const TemplateArgument *;
0415 
0416   /// Iterator referencing the first argument of a template argument
0417   /// pack.
0418   pack_iterator pack_begin() const {
0419     assert(getKind() == Pack);
0420     return Args.Args;
0421   }
0422 
0423   /// Iterator referencing one past the last argument of a template
0424   /// argument pack.
0425   pack_iterator pack_end() const {
0426     assert(getKind() == Pack);
0427     return Args.Args + Args.NumArgs;
0428   }
0429 
0430   /// Iterator range referencing all of the elements of a template
0431   /// argument pack.
0432   ArrayRef<TemplateArgument> pack_elements() const {
0433     return llvm::ArrayRef(pack_begin(), pack_end());
0434   }
0435 
0436   /// The number of template arguments in the given template argument
0437   /// pack.
0438   unsigned pack_size() const {
0439     assert(getKind() == Pack);
0440     return Args.NumArgs;
0441   }
0442 
0443   /// Return the array of arguments in this template argument pack.
0444   ArrayRef<TemplateArgument> getPackAsArray() const {
0445     assert(getKind() == Pack);
0446     return llvm::ArrayRef(Args.Args, Args.NumArgs);
0447   }
0448 
0449   /// Determines whether two template arguments are superficially the
0450   /// same.
0451   bool structurallyEquals(const TemplateArgument &Other) const;
0452 
0453   /// When the template argument is a pack expansion, returns
0454   /// the pattern of the pack expansion.
0455   TemplateArgument getPackExpansionPattern() const;
0456 
0457   /// Print this template argument to the given output stream.
0458   void print(const PrintingPolicy &Policy, raw_ostream &Out,
0459              bool IncludeType) const;
0460 
0461   /// Debugging aid that dumps the template argument.
0462   void dump(raw_ostream &Out, const ASTContext &Context) const;
0463 
0464   /// Debugging aid that dumps the template argument to standard error.
0465   void dump() const;
0466 
0467   /// Used to insert TemplateArguments into FoldingSets.
0468   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const;
0469 };
0470 
0471 /// Location information for a TemplateArgument.
0472 struct TemplateArgumentLocInfo {
0473 private:
0474   struct TemplateTemplateArgLocInfo {
0475     // FIXME: We'd like to just use the qualifier in the TemplateName,
0476     // but template arguments get canonicalized too quickly.
0477     NestedNameSpecifier *Qualifier;
0478     void *QualifierLocData;
0479     SourceLocation TemplateNameLoc;
0480     SourceLocation EllipsisLoc;
0481   };
0482 
0483   llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
0484       Pointer;
0485 
0486   TemplateTemplateArgLocInfo *getTemplate() const {
0487     return cast<TemplateTemplateArgLocInfo *>(Pointer);
0488   }
0489 
0490 public:
0491   TemplateArgumentLocInfo() {}
0492   TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
0493 
0494   TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
0495   // Ctx is used for allocation -- this case is unusually large and also rare,
0496   // so we store the payload out-of-line.
0497   TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
0498                           SourceLocation TemplateNameLoc,
0499                           SourceLocation EllipsisLoc);
0500 
0501   TypeSourceInfo *getAsTypeSourceInfo() const {
0502     return cast<TypeSourceInfo *>(Pointer);
0503   }
0504 
0505   Expr *getAsExpr() const { return cast<Expr *>(Pointer); }
0506 
0507   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
0508     const auto *Template = getTemplate();
0509     return NestedNameSpecifierLoc(Template->Qualifier,
0510                                   Template->QualifierLocData);
0511   }
0512 
0513   SourceLocation getTemplateNameLoc() const {
0514     return getTemplate()->TemplateNameLoc;
0515   }
0516 
0517   SourceLocation getTemplateEllipsisLoc() const {
0518     return getTemplate()->EllipsisLoc;
0519   }
0520 };
0521 
0522 /// Location wrapper for a TemplateArgument.  TemplateArgument is to
0523 /// TemplateArgumentLoc as Type is to TypeLoc.
0524 class TemplateArgumentLoc {
0525   TemplateArgument Argument;
0526   TemplateArgumentLocInfo LocInfo;
0527 
0528 public:
0529   TemplateArgumentLoc() {}
0530 
0531   TemplateArgumentLoc(const TemplateArgument &Argument,
0532                       TemplateArgumentLocInfo Opaque)
0533       : Argument(Argument), LocInfo(Opaque) {}
0534 
0535   TemplateArgumentLoc(const TemplateArgument &Argument, TypeSourceInfo *TInfo)
0536       : Argument(Argument), LocInfo(TInfo) {
0537     assert(Argument.getKind() == TemplateArgument::Type);
0538   }
0539 
0540   TemplateArgumentLoc(const TemplateArgument &Argument, Expr *E)
0541       : Argument(Argument), LocInfo(E) {
0542 
0543     // Permit any kind of template argument that can be represented with an
0544     // expression.
0545     assert(Argument.getKind() == TemplateArgument::NullPtr ||
0546            Argument.getKind() == TemplateArgument::Integral ||
0547            Argument.getKind() == TemplateArgument::Declaration ||
0548            Argument.getKind() == TemplateArgument::StructuralValue ||
0549            Argument.getKind() == TemplateArgument::Expression);
0550   }
0551 
0552   TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
0553                       NestedNameSpecifierLoc QualifierLoc,
0554                       SourceLocation TemplateNameLoc,
0555                       SourceLocation EllipsisLoc = SourceLocation())
0556       : Argument(Argument),
0557         LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
0558     assert(Argument.getKind() == TemplateArgument::Template ||
0559            Argument.getKind() == TemplateArgument::TemplateExpansion);
0560   }
0561 
0562   /// - Fetches the primary location of the argument.
0563   SourceLocation getLocation() const {
0564     if (Argument.getKind() == TemplateArgument::Template ||
0565         Argument.getKind() == TemplateArgument::TemplateExpansion)
0566       return getTemplateNameLoc();
0567 
0568     return getSourceRange().getBegin();
0569   }
0570 
0571   /// - Fetches the full source range of the argument.
0572   SourceRange getSourceRange() const LLVM_READONLY;
0573 
0574   const TemplateArgument &getArgument() const { return Argument; }
0575 
0576   TemplateArgumentLocInfo getLocInfo() const { return LocInfo; }
0577 
0578   TypeSourceInfo *getTypeSourceInfo() const {
0579     if (Argument.getKind() != TemplateArgument::Type)
0580       return nullptr;
0581     return LocInfo.getAsTypeSourceInfo();
0582   }
0583 
0584   Expr *getSourceExpression() const {
0585     assert(Argument.getKind() == TemplateArgument::Expression);
0586     return LocInfo.getAsExpr();
0587   }
0588 
0589   Expr *getSourceDeclExpression() const {
0590     assert(Argument.getKind() == TemplateArgument::Declaration);
0591     return LocInfo.getAsExpr();
0592   }
0593 
0594   Expr *getSourceNullPtrExpression() const {
0595     assert(Argument.getKind() == TemplateArgument::NullPtr);
0596     return LocInfo.getAsExpr();
0597   }
0598 
0599   Expr *getSourceIntegralExpression() const {
0600     assert(Argument.getKind() == TemplateArgument::Integral);
0601     return LocInfo.getAsExpr();
0602   }
0603 
0604   Expr *getSourceStructuralValueExpression() const {
0605     assert(Argument.getKind() == TemplateArgument::StructuralValue);
0606     return LocInfo.getAsExpr();
0607   }
0608 
0609   NestedNameSpecifierLoc getTemplateQualifierLoc() const {
0610     if (Argument.getKind() != TemplateArgument::Template &&
0611         Argument.getKind() != TemplateArgument::TemplateExpansion)
0612       return NestedNameSpecifierLoc();
0613     return LocInfo.getTemplateQualifierLoc();
0614   }
0615 
0616   SourceLocation getTemplateNameLoc() const {
0617     if (Argument.getKind() != TemplateArgument::Template &&
0618         Argument.getKind() != TemplateArgument::TemplateExpansion)
0619       return SourceLocation();
0620     return LocInfo.getTemplateNameLoc();
0621   }
0622 
0623   SourceLocation getTemplateEllipsisLoc() const {
0624     if (Argument.getKind() != TemplateArgument::TemplateExpansion)
0625       return SourceLocation();
0626     return LocInfo.getTemplateEllipsisLoc();
0627   }
0628 };
0629 
0630 /// A convenient class for passing around template argument
0631 /// information.  Designed to be passed by reference.
0632 class TemplateArgumentListInfo {
0633   SmallVector<TemplateArgumentLoc, 8> Arguments;
0634   SourceLocation LAngleLoc;
0635   SourceLocation RAngleLoc;
0636 
0637 public:
0638   TemplateArgumentListInfo() = default;
0639 
0640   TemplateArgumentListInfo(SourceLocation LAngleLoc, SourceLocation RAngleLoc)
0641       : LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc) {}
0642 
0643   // This can leak if used in an AST node, use ASTTemplateArgumentListInfo
0644   // instead.
0645   void *operator new(size_t bytes, ASTContext &C) = delete;
0646 
0647   SourceLocation getLAngleLoc() const { return LAngleLoc; }
0648   SourceLocation getRAngleLoc() const { return RAngleLoc; }
0649 
0650   void setLAngleLoc(SourceLocation Loc) { LAngleLoc = Loc; }
0651   void setRAngleLoc(SourceLocation Loc) { RAngleLoc = Loc; }
0652 
0653   unsigned size() const { return Arguments.size(); }
0654 
0655   const TemplateArgumentLoc *getArgumentArray() const {
0656     return Arguments.data();
0657   }
0658 
0659   llvm::ArrayRef<TemplateArgumentLoc> arguments() const { return Arguments; }
0660 
0661   const TemplateArgumentLoc &operator[](unsigned I) const {
0662     return Arguments[I];
0663   }
0664 
0665   TemplateArgumentLoc &operator[](unsigned I) { return Arguments[I]; }
0666 
0667   void addArgument(const TemplateArgumentLoc &Loc) { Arguments.push_back(Loc); }
0668 };
0669 
0670 /// Represents an explicit template argument list in C++, e.g.,
0671 /// the "<int>" in "sort<int>".
0672 /// This is safe to be used inside an AST node, in contrast with
0673 /// TemplateArgumentListInfo.
0674 struct ASTTemplateArgumentListInfo final
0675     : private llvm::TrailingObjects<ASTTemplateArgumentListInfo,
0676                                     TemplateArgumentLoc> {
0677 private:
0678   friend class ASTNodeImporter;
0679   friend TrailingObjects;
0680 
0681   ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
0682 
0683   // FIXME: Is it ever necessary to copy to another context?
0684   ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
0685 
0686 public:
0687   /// The source location of the left angle bracket ('<').
0688   SourceLocation LAngleLoc;
0689 
0690   /// The source location of the right angle bracket ('>').
0691   SourceLocation RAngleLoc;
0692 
0693   /// The number of template arguments in TemplateArgs.
0694   unsigned NumTemplateArgs;
0695 
0696   SourceLocation getLAngleLoc() const { return LAngleLoc; }
0697   SourceLocation getRAngleLoc() const { return RAngleLoc; }
0698 
0699   /// Retrieve the template arguments
0700   const TemplateArgumentLoc *getTemplateArgs() const {
0701     return getTrailingObjects<TemplateArgumentLoc>();
0702   }
0703   unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
0704 
0705   llvm::ArrayRef<TemplateArgumentLoc> arguments() const {
0706     return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs());
0707   }
0708 
0709   const TemplateArgumentLoc &operator[](unsigned I) const {
0710     return getTemplateArgs()[I];
0711   }
0712 
0713   static const ASTTemplateArgumentListInfo *
0714   Create(const ASTContext &C, const TemplateArgumentListInfo &List);
0715 
0716   // FIXME: Is it ever necessary to copy to another context?
0717   static const ASTTemplateArgumentListInfo *
0718   Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
0719 };
0720 
0721 /// Represents an explicit template argument list in C++, e.g.,
0722 /// the "<int>" in "sort<int>".
0723 ///
0724 /// It is intended to be used as a trailing object on AST nodes, and
0725 /// as such, doesn't contain the array of TemplateArgumentLoc itself,
0726 /// but expects the containing object to also provide storage for
0727 /// that.
0728 struct alignas(void *) ASTTemplateKWAndArgsInfo {
0729   /// The source location of the left angle bracket ('<').
0730   SourceLocation LAngleLoc;
0731 
0732   /// The source location of the right angle bracket ('>').
0733   SourceLocation RAngleLoc;
0734 
0735   /// The source location of the template keyword; this is used
0736   /// as part of the representation of qualified identifiers, such as
0737   /// S<T>::template apply<T>.  Will be empty if this expression does
0738   /// not have a template keyword.
0739   SourceLocation TemplateKWLoc;
0740 
0741   /// The number of template arguments in TemplateArgs.
0742   unsigned NumTemplateArgs;
0743 
0744   void initializeFrom(SourceLocation TemplateKWLoc,
0745                       const TemplateArgumentListInfo &List,
0746                       TemplateArgumentLoc *OutArgArray);
0747   // FIXME: The parameter Deps is the result populated by this method, the
0748   // caller doesn't need it since it is populated by computeDependence. remove
0749   // it.
0750   void initializeFrom(SourceLocation TemplateKWLoc,
0751                       const TemplateArgumentListInfo &List,
0752                       TemplateArgumentLoc *OutArgArray,
0753                       TemplateArgumentDependence &Deps);
0754   void initializeFrom(SourceLocation TemplateKWLoc);
0755 
0756   void copyInto(const TemplateArgumentLoc *ArgArray,
0757                 TemplateArgumentListInfo &List) const;
0758 };
0759 
0760 const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
0761                                       const TemplateArgument &Arg);
0762 
0763 } // namespace clang
0764 
0765 #endif // LLVM_CLANG_AST_TEMPLATEBASE_H