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