]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/llvm/tools/clang/include/clang/Sema/ParsedTemplate.h
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.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         Loc(TemplateLoc), SS(SS), 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 location of the template argument.
122     SourceLocation Loc;
123     
124     /// \brief The nested-name-specifier that can accompany a template template
125     /// argument.
126     CXXScopeSpec SS;
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     /// TemplateNameLoc - The location of the template name within the
146     /// source.
147     SourceLocation TemplateNameLoc;
148     
149     /// FIXME: Temporarily stores the name of a specialization
150     IdentifierInfo *Name;
151     
152     /// FIXME: Temporarily stores the overloaded operator kind.
153     OverloadedOperatorKind Operator;
154     
155     /// The declaration of the template corresponding to the
156     /// template-name.
157     ParsedTemplateTy Template;
158     
159     /// The kind of template that Template refers to.
160     TemplateNameKind Kind;
161     
162     /// The location of the '<' before the template argument
163     /// list.
164     SourceLocation LAngleLoc;
165     
166     /// The location of the '>' after the template argument
167     /// list.
168     SourceLocation RAngleLoc;
169     
170     /// NumArgs - The number of template arguments.
171     unsigned NumArgs;
172     
173     /// \brief Retrieves a pointer to the template arguments
174     ParsedTemplateArgument *getTemplateArgs() { 
175       return reinterpret_cast<ParsedTemplateArgument *>(this + 1); 
176     }
177     
178     static TemplateIdAnnotation* Allocate(unsigned NumArgs) {
179       TemplateIdAnnotation *TemplateId
180         = (TemplateIdAnnotation *)std::malloc(sizeof(TemplateIdAnnotation) +
181                                       sizeof(ParsedTemplateArgument) * NumArgs);
182       TemplateId->NumArgs = NumArgs;
183       
184       // Default-construct nested-name-specifier.
185       new (&TemplateId->SS) CXXScopeSpec();
186       
187       // Default-construct parsed template arguments.
188       ParsedTemplateArgument *TemplateArgs = TemplateId->getTemplateArgs();
189       for (unsigned I = 0; I != NumArgs; ++I)
190         new (TemplateArgs + I) ParsedTemplateArgument();
191       
192       return TemplateId;
193     }
194     
195     void Destroy() { 
196       SS.~CXXScopeSpec();
197       free(this); 
198     }
199   };
200
201   /// Retrieves the range of the given template parameter lists.
202   SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params,
203                                      unsigned NumParams);  
204   
205   inline const ParsedTemplateArgument &
206   ASTTemplateArgsPtr::operator[](unsigned Arg) const { 
207     return Args[Arg]; 
208   }
209 }
210
211 #endif