]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / llvm / tools / clang / include / clang / Sema / ParsedTemplate.h
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(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
214 #endif