LCOV - code coverage report
Current view: top level - clang/AST - TemplateBase.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 0 36 0.0 %
Date: 2016-01-31 12:01:00 Functions: 0 22 0.0 %

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

Generated by: LCOV version 1.11