Home | History | Annotate | Download | only in Sema
      1 //===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
      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 data structures that store the parsed representation of
     11 //  templates.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
     15 #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
     16 
     17 #include "clang/Sema/DeclSpec.h"
     18 #include "clang/Sema/Ownership.h"
     19 #include <cassert>
     20 
     21 namespace clang {
     22   /// \brief Represents the parsed form of a C++ template argument.
     23   class ParsedTemplateArgument {
     24   public:
     25     /// \brief Describes the kind of template argument that was parsed.
     26     enum KindType {
     27       /// \brief A template type parameter, stored as a type.
     28       Type,
     29       /// \brief A non-type template parameter, stored as an expression.
     30       NonType,
     31       /// \brief A template template argument, stored as a template name.
     32       Template
     33     };
     34 
     35     /// \brief Build an empty template argument.
     36     ///
     37     /// This template argument is invalid.
     38     ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
     39 
     40     /// \brief Create a template type argument or non-type template argument.
     41     ///
     42     /// \param Arg the template type argument or non-type template argument.
     43     /// \param Loc the location of the type.
     44     ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
     45       : Kind(Kind), Arg(Arg), Loc(Loc) { }
     46 
     47     /// \brief Create a template template argument.
     48     ///
     49     /// \param SS the C++ scope specifier that precedes the template name, if
     50     /// any.
     51     ///
     52     /// \param Template the template to which this template template
     53     /// argument refers.
     54     ///
     55     /// \param TemplateLoc the location of the template name.
     56     ParsedTemplateArgument(const CXXScopeSpec &SS,
     57                            ParsedTemplateTy Template,
     58                            SourceLocation TemplateLoc)
     59       : Kind(ParsedTemplateArgument::Template),
     60         Arg(Template.getAsOpaquePtr()),
     61         SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
     62 
     63     /// \brief Determine whether the given template argument is invalid.
     64     bool isInvalid() const { return Arg == nullptr; }
     65 
     66     /// \brief Determine what kind of template argument we have.
     67     KindType getKind() const { return Kind; }
     68 
     69     /// \brief Retrieve the template type argument's type.
     70     ParsedType getAsType() const {
     71       assert(Kind == Type && "Not a template type argument");
     72       return ParsedType::getFromOpaquePtr(Arg);
     73     }
     74 
     75     /// \brief Retrieve the non-type template argument's expression.
     76     Expr *getAsExpr() const {
     77       assert(Kind == NonType && "Not a non-type template argument");
     78       return static_cast<Expr*>(Arg);
     79     }
     80 
     81     /// \brief Retrieve the template template argument's template name.
     82     ParsedTemplateTy getAsTemplate() const {
     83       assert(Kind == Template && "Not a template template argument");
     84       return ParsedTemplateTy::getFromOpaquePtr(Arg);
     85     }
     86 
     87     /// \brief Retrieve the location of the template argument.
     88     SourceLocation getLocation() const { return Loc; }
     89 
     90     /// \brief Retrieve the nested-name-specifier that precedes the template
     91     /// name in a template template argument.
     92     const CXXScopeSpec &getScopeSpec() const {
     93       assert(Kind == Template &&
     94              "Only template template arguments can have a scope specifier");
     95       return SS;
     96     }
     97 
     98     /// \brief Retrieve the location of the ellipsis that makes a template
     99     /// template argument into a pack expansion.
    100     SourceLocation getEllipsisLoc() const {
    101       assert(Kind == Template &&
    102              "Only template template arguments can have an ellipsis");
    103       return EllipsisLoc;
    104     }
    105 
    106     /// \brief Retrieve a pack expansion of the given template template
    107     /// argument.
    108     ///
    109     /// \param EllipsisLoc The location of the ellipsis.
    110     ParsedTemplateArgument getTemplatePackExpansion(
    111                                               SourceLocation EllipsisLoc) const;
    112 
    113   private:
    114     KindType Kind;
    115 
    116     /// \brief The actual template argument representation, which may be
    117     /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
    118     /// expression), or an ActionBase::TemplateTy (for a template).
    119     void *Arg;
    120 
    121     /// \brief The nested-name-specifier that can accompany a template template
    122     /// argument.
    123     CXXScopeSpec SS;
    124 
    125     /// \brief the location of the template argument.
    126     SourceLocation Loc;
    127 
    128     /// \brief The ellipsis location that can accompany a template template
    129     /// argument (turning it into a template template argument expansion).
    130     SourceLocation EllipsisLoc;
    131   };
    132 
    133   /// \brief Information about a template-id annotation
    134   /// token.
    135   ///
    136   /// A template-id annotation token contains the template declaration,
    137   /// template arguments, whether those template arguments were types,
    138   /// expressions, or template names, and the source locations for important
    139   /// tokens. All of the information about template arguments is allocated
    140   /// directly after this structure.
    141   struct TemplateIdAnnotation {
    142     /// \brief The nested-name-specifier that precedes the template name.
    143     CXXScopeSpec SS;
    144 
    145     /// TemplateKWLoc - The location of the template keyword within the
    146     /// source.
    147     SourceLocation TemplateKWLoc;
    148 
    149     /// TemplateNameLoc - The location of the template name within the
    150     /// source.
    151     SourceLocation TemplateNameLoc;
    152 
    153     /// FIXME: Temporarily stores the name of a specialization
    154     IdentifierInfo *Name;
    155 
    156     /// FIXME: Temporarily stores the overloaded operator kind.
    157     OverloadedOperatorKind Operator;
    158 
    159     /// The declaration of the template corresponding to the
    160     /// template-name.
    161     ParsedTemplateTy Template;
    162 
    163     /// The kind of template that Template refers to.
    164     TemplateNameKind Kind;
    165 
    166     /// The location of the '<' before the template argument
    167     /// list.
    168     SourceLocation LAngleLoc;
    169 
    170     /// The location of the '>' after the template argument
    171     /// list.
    172     SourceLocation RAngleLoc;
    173 
    174     /// NumArgs - The number of template arguments.
    175     unsigned NumArgs;
    176 
    177     /// \brief Retrieves a pointer to the template arguments
    178     ParsedTemplateArgument *getTemplateArgs() {
    179       return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
    180     }
    181 
    182     /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
    183     /// appends it to List.
    184     static TemplateIdAnnotation *
    185     Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
    186       TemplateIdAnnotation *TemplateId
    187         = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
    188                                       sizeof(ParsedTemplateArgument) * NumArgs);
    189       TemplateId->NumArgs = NumArgs;
    190 
    191       // Default-construct nested-name-specifier.
    192       new (&TemplateId->SS) CXXScopeSpec();
    193 
    194       // Default-construct parsed template arguments.
    195       ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
    196       for (unsigned I = 0; I != NumArgs; ++I)
    197         new (TemplateArgs + I) ParsedTemplateArgument();
    198 
    199       List.push_back(TemplateId);
    200       return TemplateId;
    201     }
    202 
    203     void Destroy() {
    204       SS.~CXXScopeSpec();
    205       free(this);
    206     }
    207   };
    208 
    209   /// Retrieves the range of the given template parameter lists.
    210   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
    211                                      unsigned NumParams);
    212 }
    213 
    214 #endif
    215