 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
50.0% |
4 / 8 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
8 / 8 |
| |
|
Line Coverage: |
96.2% |
77 / 80 |
| |
 |
|
 |
1 : //===--- TemplateName.h - C++ Template Name Representation-------*- 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 defines the TemplateName interface and subclasses.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_AST_TEMPLATENAME_H
15 : #define LLVM_CLANG_AST_TEMPLATENAME_H
16 :
17 : #include "llvm/ADT/FoldingSet.h"
18 : #include "llvm/ADT/PointerUnion.h"
19 : #include "clang/Basic/OperatorKinds.h"
20 :
21 : namespace llvm {
22 : class raw_ostream;
23 : }
24 :
25 : namespace clang {
26 :
27 : class DependentTemplateName;
28 : class IdentifierInfo;
29 : class NestedNameSpecifier;
30 : struct PrintingPolicy;
31 : class QualifiedTemplateName;
32 : class NamedDecl;
33 : class TemplateDecl;
34 :
35 : /// \brief A structure for storing the information associated with an
36 : /// overloaded template name.
37 : class OverloadedTemplateStorage {
38 : union {
39 : unsigned Size;
40 : NamedDecl *Storage[1];
41 : };
42 :
43 : friend class ASTContext;
44 :
45 28: OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
46 :
47 28: NamedDecl **getStorage() {
48 28: return &Storage[1];
49 : }
50 69: NamedDecl * const *getStorage() const {
51 69: return &Storage[1];
52 : }
53 :
54 : public:
55 : typedef NamedDecl *const *iterator;
56 :
57 20: unsigned size() const { return Size; }
58 :
59 49: iterator begin() const { return getStorage(); }
60 20: iterator end() const { return getStorage() + size(); }
61 : };
62 :
63 : /// \brief Represents a C++ template name within the type system.
64 : ///
65 : /// A C++ template name refers to a template within the C++ type
66 : /// system. In most cases, a template name is simply a reference to a
67 : /// class template, e.g.
68 : ///
69 : /// \code
70 : /// template<typename T> class X { };
71 : ///
72 : /// X<int> xi;
73 : /// \endcode
74 : ///
75 : /// Here, the 'X' in \c X<int> is a template name that refers to the
76 : /// declaration of the class template X, above. Template names can
77 : /// also refer to function templates, C++0x template aliases, etc.
78 : ///
79 : /// Some template names are dependent. For example, consider:
80 : ///
81 : /// \code
82 : /// template<typename MetaFun, typename T1, typename T2> struct apply2 {
83 : /// typedef typename MetaFun::template apply<T1, T2>::type type;
84 : /// };
85 : /// \endcode
86 : ///
87 : /// Here, "apply" is treated as a template name within the typename
88 : /// specifier in the typedef. "apply" is a nested template, and can
89 : /// only be understood in the context of
90 : class TemplateName {
91 : typedef llvm::PointerUnion4<TemplateDecl *,
92 : OverloadedTemplateStorage *,
93 : QualifiedTemplateName *,
94 : DependentTemplateName *> StorageType;
95 :
96 : StorageType Storage;
97 :
98 2991: explicit TemplateName(void *Ptr) {
99 2991: Storage = StorageType::getFromOpaqueValue(Ptr);
100 2991: }
101 :
102 : public:
103 2572: TemplateName() : Storage() { }
104 4564: explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
105 28: explicit TemplateName(OverloadedTemplateStorage *Storage)
106 28: : Storage(Storage) { }
107 300: explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
108 83: explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
109 :
110 : /// \brief Determine whether this template name is NULL.
111 1358: bool isNull() const { return Storage.isNull(); }
112 :
113 : /// \brief Retrieve the the underlying template declaration that
114 : /// this template name refers to, if known.
115 : ///
116 : /// \returns The template declaration that this template name refers
117 : /// to, if any. If the template name does not refer to a specific
118 : /// declaration because it is a dependent name, or if it refers to a
119 : /// set of function templates, returns NULL.
120 : TemplateDecl *getAsTemplateDecl() const;
121 :
122 : /// \brief Retrieve the the underlying, overloaded function template
123 : // declarations that this template name refers to, if known.
124 : ///
125 : /// \returns The set of overloaded function templates that this template
126 : /// name refers to, if known. If the template name does not refer to a
127 : /// specific set of function templates because it is a dependent name or
128 : /// refers to a single template, returns NULL.
129 149: OverloadedTemplateStorage *getAsOverloadedTemplate() const {
130 149: return Storage.dyn_cast<OverloadedTemplateStorage *>();
131 : }
132 :
133 : /// \brief Retrieve the underlying qualified template name
134 : /// structure, if any.
135 2538: QualifiedTemplateName *getAsQualifiedTemplateName() const {
136 2538: return Storage.dyn_cast<QualifiedTemplateName *>();
137 : }
138 :
139 : /// \brief Retrieve the underlying dependent template name
140 : /// structure, if any.
141 1383: DependentTemplateName *getAsDependentTemplateName() const {
142 1383: return Storage.dyn_cast<DependentTemplateName *>();
143 : }
144 :
145 : /// \brief Determines whether this is a dependent template name.
146 : bool isDependent() const;
147 :
148 : /// \brief Print the template name.
149 : ///
150 : /// \param OS the output stream to which the template name will be
151 : /// printed.
152 : ///
153 : /// \param SuppressNNS if true, don't print the
154 : /// nested-name-specifier that precedes the template name (if it has
155 : /// one).
156 : void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
157 : bool SuppressNNS = false) const;
158 :
159 : /// \brief Debugging aid that dumps the template name to standard
160 : /// error.
161 : void dump() const;
162 :
163 1374: void Profile(llvm::FoldingSetNodeID &ID) {
164 1374: ID.AddPointer(Storage.getOpaqueValue());
165 1374: }
166 :
167 : /// \brief Retrieve the template name as a void pointer.
168 3017: void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
169 :
170 : /// \brief Build a template name from a void pointer.
171 2991: static TemplateName getFromVoidPointer(void *Ptr) {
172 2991: return TemplateName(Ptr);
173 : }
174 : };
175 :
176 : /// \brief Represents a template name that was expressed as a
177 : /// qualified name.
178 : ///
179 : /// This kind of template name refers to a template name that was
180 : /// preceded by a nested name specifier, e.g., \c std::vector. Here,
181 : /// the nested name specifier is "std::" and the template name is the
182 : /// declaration for "vector". The QualifiedTemplateName class is only
183 : /// used to provide "sugar" for template names that were expressed
184 : /// with a qualified name, and has no semantic meaning. In this
185 : /// manner, it is to TemplateName what QualifiedNameType is to Type,
186 : /// providing extra syntactic sugar for downstream clients.
187 : class QualifiedTemplateName : public llvm::FoldingSetNode {
188 : /// \brief The nested name specifier that qualifies the template name.
189 : ///
190 : /// The bit is used to indicate whether the "template" keyword was
191 : /// present before the template name itself. Note that the
192 : /// "template" keyword is always redundant in this case (otherwise,
193 : /// the template name would be a dependent name and we would express
194 : /// this name with DependentTemplateName).
195 : llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
196 :
197 : /// \brief The template declaration or set of overloaded function templates
198 : /// that this qualified name refers to.
199 : TemplateDecl *Template;
200 :
201 : friend class ASTContext;
202 :
203 : QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
204 202: TemplateDecl *Template)
205 : : Qualifier(NNS, TemplateKeyword? 1 : 0),
0: branch 1 not taken
202: branch 2 taken
206 202: Template(Template) { }
207 :
208 : public:
209 : /// \brief Return the nested name specifier that qualifies this name.
210 154: NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
211 :
212 : /// \brief Whether the template name was prefixed by the "template"
213 : /// keyword.
214 132: bool hasTemplateKeyword() const { return Qualifier.getInt(); }
215 :
216 : /// \brief The template declaration that this qualified name refers
217 : /// to.
218 8: TemplateDecl *getDecl() const { return Template; }
219 :
220 : /// \brief The template declaration to which this qualified name
221 : /// refers.
222 1149: TemplateDecl *getTemplateDecl() const { return Template; }
223 :
224 121: void Profile(llvm::FoldingSetNodeID &ID) {
225 121: Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
226 121: }
227 :
228 : static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
229 421: bool TemplateKeyword, TemplateDecl *Template) {
230 421: ID.AddPointer(NNS);
231 421: ID.AddBoolean(TemplateKeyword);
232 421: ID.AddPointer(Template);
233 421: }
234 : };
235 :
236 : /// \brief Represents a dependent template name that cannot be
237 : /// resolved prior to template instantiation.
238 : ///
239 : /// This kind of template name refers to a dependent template name,
240 : /// including its nested name specifier (if any). For example,
241 : /// DependentTemplateName can refer to "MetaFun::template apply",
242 : /// where "MetaFun::" is the nested name specifier and "apply" is the
243 : /// template name referenced. The "template" keyword is implied.
244 : class DependentTemplateName : public llvm::FoldingSetNode {
245 : /// \brief The nested name specifier that qualifies the template
246 : /// name.
247 : ///
248 : /// The bit stored in this qualifier describes whether the \c Name field
249 : /// is interpreted as an IdentifierInfo pointer (when clear) or as an
250 : /// overloaded operator kind (when set).
251 : llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
252 :
253 : /// \brief The dependent template name.
254 : union {
255 : /// \brief The identifier template name.
256 : ///
257 : /// Only valid when the bit on \c Qualifier is clear.
258 : const IdentifierInfo *Identifier;
259 :
260 : /// \brief The overloaded operator name.
261 : ///
262 : /// Only valid when the bit on \c Qualifier is set.
263 : OverloadedOperatorKind Operator;
264 : };
265 :
266 : /// \brief The canonical template name to which this dependent
267 : /// template name refers.
268 : ///
269 : /// The canonical template name for a dependent template name is
270 : /// another dependent template name whose nested name specifier is
271 : /// canonical.
272 : TemplateName CanonicalTemplateName;
273 :
274 : friend class ASTContext;
275 :
276 : DependentTemplateName(NestedNameSpecifier *Qualifier,
277 17: const IdentifierInfo *Identifier)
278 : : Qualifier(Qualifier, false), Identifier(Identifier),
279 17: CanonicalTemplateName(this) { }
280 :
281 : DependentTemplateName(NestedNameSpecifier *Qualifier,
282 : const IdentifierInfo *Identifier,
283 23: TemplateName Canon)
284 : : Qualifier(Qualifier, false), Identifier(Identifier),
285 23: CanonicalTemplateName(Canon) { }
286 :
287 : DependentTemplateName(NestedNameSpecifier *Qualifier,
288 2: OverloadedOperatorKind Operator)
289 : : Qualifier(Qualifier, true), Operator(Operator),
290 2: CanonicalTemplateName(this) { }
291 :
292 : DependentTemplateName(NestedNameSpecifier *Qualifier,
293 : OverloadedOperatorKind Operator,
294 0: TemplateName Canon)
295 : : Qualifier(Qualifier, true), Operator(Operator),
296 0: CanonicalTemplateName(Canon) { }
297 :
298 : public:
299 : /// \brief Return the nested name specifier that qualifies this name.
300 58: NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
301 :
302 : /// \brief Determine whether this template name refers to an identifier.
303 94: bool isIdentifier() const { return !Qualifier.getInt(); }
304 :
305 : /// \brief Returns the identifier to which this template name refers.
306 46: const IdentifierInfo *getIdentifier() const {
46: branch 1 taken
0: branch 2 not taken
307 46: assert(isIdentifier() && "Template name isn't an identifier?");
308 46: return Identifier;
309 : }
310 :
311 : /// \brief Determine whether this template name refers to an overloaded
312 : /// operator.
313 2: bool isOverloadedOperator() const { return Qualifier.getInt(); }
314 :
315 : /// \brief Return the overloaded operator to which this template name refers.
316 2: OverloadedOperatorKind getOperator() const {
317 : assert(isOverloadedOperator() &&
2: branch 1 taken
0: branch 2 not taken
318 2: "Template name isn't an overloaded operator?");
319 2: return Operator;
320 : }
321 :
322 27: void Profile(llvm::FoldingSetNodeID &ID) {
27: branch 1 taken
0: branch 2 not taken
323 27: if (isIdentifier())
324 27: Profile(ID, getQualifier(), getIdentifier());
325 : else
326 0: Profile(ID, getQualifier(), getOperator());
327 27: }
328 :
329 : static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
330 89: const IdentifierInfo *Identifier) {
331 89: ID.AddPointer(NNS);
332 89: ID.AddBoolean(false);
333 89: ID.AddPointer(Identifier);
334 89: }
335 :
336 : static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
337 2: OverloadedOperatorKind Operator) {
338 2: ID.AddPointer(NNS);
339 2: ID.AddBoolean(true);
340 2: ID.AddInteger(Operator);
341 2: }
342 : };
343 :
344 : } // end namespace clang.
345 :
346 : namespace llvm {
347 :
348 : /// \brief The clang::TemplateName class is effectively a pointer.
349 : template<>
350 : class PointerLikeTypeTraits<clang::TemplateName> {
351 : public:
352 2613: static inline void *getAsVoidPointer(clang::TemplateName TN) {
353 2613: return TN.getAsVoidPointer();
354 : }
355 :
356 2624: static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
357 2624: return clang::TemplateName::getFromVoidPointer(Ptr);
358 : }
359 :
360 : // No bits are available!
361 : enum { NumLowBitsAvailable = 0 };
362 : };
363 :
364 : } // end namespace llvm.
365 :
366 : #endif
Generated: 2010-02-10 01:31 by zcov