ParsedTemplate.h revision db3d68f188eb0883407a25ef09c1d85e217b97ef
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
21namespace 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(0) { }
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 == 0; }
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  inline const ParsedTemplateArgument &
214  ASTTemplateArgsPtr::operator[](unsigned Arg) const {
215    return Args[Arg];
216  }
217}
218
219#endif
220