1212795Sdim//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim//  This file provides data structures that store the parsed representation of
11212795Sdim//  templates.
12212795Sdim//
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim#ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
15212795Sdim#define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H
16212795Sdim
17212795Sdim#include "clang/Sema/DeclSpec.h"
18212795Sdim#include "clang/Sema/Ownership.h"
19212795Sdim#include <cassert>
20212795Sdim
21212795Sdimnamespace clang {
22212795Sdim  /// \brief Represents the parsed form of a C++ template argument.
23212795Sdim  class ParsedTemplateArgument {
24212795Sdim  public:
25212795Sdim    /// \brief Describes the kind of template argument that was parsed.
26212795Sdim    enum KindType {
27212795Sdim      /// \brief A template type parameter, stored as a type.
28212795Sdim      Type,
29212795Sdim      /// \brief A non-type template parameter, stored as an expression.
30212795Sdim      NonType,
31212795Sdim      /// \brief A template template argument, stored as a template name.
32212795Sdim      Template
33212795Sdim    };
34212795Sdim
35218893Sdim    /// \brief Build an empty template argument.
36218893Sdim    ///
37218893Sdim    /// This template argument is invalid.
38212795Sdim    ParsedTemplateArgument() : Kind(Type), Arg(0) { }
39212795Sdim
40212795Sdim    /// \brief Create a template type argument or non-type template argument.
41212795Sdim    ///
42212795Sdim    /// \param Arg the template type argument or non-type template argument.
43212795Sdim    /// \param Loc the location of the type.
44212795Sdim    ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
45212795Sdim      : Kind(Kind), Arg(Arg), Loc(Loc) { }
46212795Sdim
47212795Sdim    /// \brief Create a template template argument.
48212795Sdim    ///
49212795Sdim    /// \param SS the C++ scope specifier that precedes the template name, if
50212795Sdim    /// any.
51212795Sdim    ///
52212795Sdim    /// \param Template the template to which this template template
53212795Sdim    /// argument refers.
54212795Sdim    ///
55212795Sdim    /// \param TemplateLoc the location of the template name.
56212795Sdim    ParsedTemplateArgument(const CXXScopeSpec &SS,
57212795Sdim                           ParsedTemplateTy Template,
58212795Sdim                           SourceLocation TemplateLoc)
59212795Sdim      : Kind(ParsedTemplateArgument::Template),
60212795Sdim        Arg(Template.getAsOpaquePtr()),
61239462Sdim        SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
62212795Sdim
63212795Sdim    /// \brief Determine whether the given template argument is invalid.
64212795Sdim    bool isInvalid() const { return Arg == 0; }
65212795Sdim
66212795Sdim    /// \brief Determine what kind of template argument we have.
67212795Sdim    KindType getKind() const { return Kind; }
68212795Sdim
69212795Sdim    /// \brief Retrieve the template type argument's type.
70212795Sdim    ParsedType getAsType() const {
71212795Sdim      assert(Kind == Type && "Not a template type argument");
72212795Sdim      return ParsedType::getFromOpaquePtr(Arg);
73212795Sdim    }
74212795Sdim
75212795Sdim    /// \brief Retrieve the non-type template argument's expression.
76212795Sdim    Expr *getAsExpr() const {
77212795Sdim      assert(Kind == NonType && "Not a non-type template argument");
78212795Sdim      return static_cast<Expr*>(Arg);
79212795Sdim    }
80212795Sdim
81212795Sdim    /// \brief Retrieve the template template argument's template name.
82212795Sdim    ParsedTemplateTy getAsTemplate() const {
83212795Sdim      assert(Kind == Template && "Not a template template argument");
84212795Sdim      return ParsedTemplateTy::getFromOpaquePtr(Arg);
85212795Sdim    }
86212795Sdim
87212795Sdim    /// \brief Retrieve the location of the template argument.
88212795Sdim    SourceLocation getLocation() const { return Loc; }
89212795Sdim
90212795Sdim    /// \brief Retrieve the nested-name-specifier that precedes the template
91212795Sdim    /// name in a template template argument.
92212795Sdim    const CXXScopeSpec &getScopeSpec() const {
93212795Sdim      assert(Kind == Template &&
94212795Sdim             "Only template template arguments can have a scope specifier");
95212795Sdim      return SS;
96212795Sdim    }
97212795Sdim
98218893Sdim    /// \brief Retrieve the location of the ellipsis that makes a template
99218893Sdim    /// template argument into a pack expansion.
100218893Sdim    SourceLocation getEllipsisLoc() const {
101218893Sdim      assert(Kind == Template &&
102218893Sdim             "Only template template arguments can have an ellipsis");
103218893Sdim      return EllipsisLoc;
104218893Sdim    }
105218893Sdim
106218893Sdim    /// \brief Retrieve a pack expansion of the given template template
107218893Sdim    /// argument.
108218893Sdim    ///
109218893Sdim    /// \param EllipsisLoc The location of the ellipsis.
110218893Sdim    ParsedTemplateArgument getTemplatePackExpansion(
111218893Sdim                                              SourceLocation EllipsisLoc) const;
112218893Sdim
113212795Sdim  private:
114212795Sdim    KindType Kind;
115212795Sdim
116212795Sdim    /// \brief The actual template argument representation, which may be
117226633Sdim    /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an
118212795Sdim    /// expression), or an ActionBase::TemplateTy (for a template).
119212795Sdim    void *Arg;
120212795Sdim
121212795Sdim    /// \brief The nested-name-specifier that can accompany a template template
122212795Sdim    /// argument.
123212795Sdim    CXXScopeSpec SS;
124239462Sdim
125239462Sdim    /// \brief the location of the template argument.
126239462Sdim    SourceLocation Loc;
127239462Sdim
128218893Sdim    /// \brief The ellipsis location that can accompany a template template
129218893Sdim    /// argument (turning it into a template template argument expansion).
130218893Sdim    SourceLocation EllipsisLoc;
131212795Sdim  };
132212795Sdim
133212795Sdim  /// \brief Information about a template-id annotation
134212795Sdim  /// token.
135212795Sdim  ///
136212795Sdim  /// A template-id annotation token contains the template declaration,
137212795Sdim  /// template arguments, whether those template arguments were types,
138212795Sdim  /// expressions, or template names, and the source locations for important
139212795Sdim  /// tokens. All of the information about template arguments is allocated
140212795Sdim  /// directly after this structure.
141212795Sdim  struct TemplateIdAnnotation {
142221345Sdim    /// \brief The nested-name-specifier that precedes the template name.
143221345Sdim    CXXScopeSpec SS;
144234353Sdim
145234353Sdim    /// TemplateKWLoc - The location of the template keyword within the
146234353Sdim    /// source.
147234353Sdim    SourceLocation TemplateKWLoc;
148234353Sdim
149212795Sdim    /// TemplateNameLoc - The location of the template name within the
150212795Sdim    /// source.
151212795Sdim    SourceLocation TemplateNameLoc;
152212795Sdim
153212795Sdim    /// FIXME: Temporarily stores the name of a specialization
154212795Sdim    IdentifierInfo *Name;
155212795Sdim
156212795Sdim    /// FIXME: Temporarily stores the overloaded operator kind.
157212795Sdim    OverloadedOperatorKind Operator;
158212795Sdim
159212795Sdim    /// The declaration of the template corresponding to the
160212795Sdim    /// template-name.
161212795Sdim    ParsedTemplateTy Template;
162212795Sdim
163212795Sdim    /// The kind of template that Template refers to.
164212795Sdim    TemplateNameKind Kind;
165212795Sdim
166212795Sdim    /// The location of the '<' before the template argument
167212795Sdim    /// list.
168212795Sdim    SourceLocation LAngleLoc;
169212795Sdim
170212795Sdim    /// The location of the '>' after the template argument
171212795Sdim    /// list.
172212795Sdim    SourceLocation RAngleLoc;
173212795Sdim
174212795Sdim    /// NumArgs - The number of template arguments.
175212795Sdim    unsigned NumArgs;
176212795Sdim
177212795Sdim    /// \brief Retrieves a pointer to the template arguments
178212795Sdim    ParsedTemplateArgument *getTemplateArgs() {
179212795Sdim      return reinterpret_cast<ParsedTemplateArgument *>(this + 1);
180212795Sdim    }
181234982Sdim
182234982Sdim    /// \brief Creates a new TemplateIdAnnotation with NumArgs arguments and
183234982Sdim    /// appends it to List.
184234982Sdim    static TemplateIdAnnotation *
185234982Sdim    Allocate(unsigned NumArgs, SmallVectorImpl<TemplateIdAnnotation*> &List) {
186212795Sdim      TemplateIdAnnotation *TemplateId
187221345Sdim        = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
188212795Sdim                                      sizeof(ParsedTemplateArgument) * NumArgs);
189212795Sdim      TemplateId->NumArgs = NumArgs;
190219077Sdim
191221345Sdim      // Default-construct nested-name-specifier.
192221345Sdim      new (&TemplateId->SS) CXXScopeSpec();
193221345Sdim
194219077Sdim      // Default-construct parsed template arguments.
195219077Sdim      ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
196219077Sdim      for (unsigned I = 0; I != NumArgs; ++I)
197219077Sdim        new (TemplateArgs + I) ParsedTemplateArgument();
198219077Sdim
199234982Sdim      List.push_back(TemplateId);
200212795Sdim      return TemplateId;
201212795Sdim    }
202212795Sdim
203221345Sdim    void Destroy() {
204221345Sdim      SS.~CXXScopeSpec();
205221345Sdim      free(this);
206221345Sdim    }
207212795Sdim  };
208218893Sdim
209218893Sdim  /// Retrieves the range of the given template parameter lists.
210218893Sdim  SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
211218893Sdim                                     unsigned NumParams);
212212795Sdim}
213212795Sdim
214212795Sdim#endif
215