TemplateName.h revision f8fd82ba49827db0f6a6ba00c55a7b56b12a19fa
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
21namespace llvm {
22  class raw_ostream;
23}
24
25namespace clang {
26
27class DependentTemplateName;
28class IdentifierInfo;
29class NestedNameSpecifier;
30struct PrintingPolicy;
31class QualifiedTemplateName;
32class NamedDecl;
33class TemplateDecl;
34
35/// \brief A structure for storing the information associated with an
36/// overloaded template name.
37class OverloadedTemplateStorage {
38  union {
39    unsigned Size;
40    NamedDecl *Storage[1];
41  };
42
43  friend class ASTContext;
44
45  OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
46
47  NamedDecl **getStorage() {
48    return &Storage[1];
49  }
50  NamedDecl * const *getStorage() const {
51    return &Storage[1];
52  }
53
54public:
55  typedef NamedDecl *const *iterator;
56
57  unsigned size() const { return Size; }
58
59  iterator begin() const { return getStorage(); }
60  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
90class TemplateName {
91  typedef llvm::PointerUnion4<TemplateDecl *,
92                              OverloadedTemplateStorage *,
93                              QualifiedTemplateName *,
94                              DependentTemplateName *> StorageType;
95
96  StorageType Storage;
97
98  explicit TemplateName(void *Ptr) {
99    Storage = StorageType::getFromOpaqueValue(Ptr);
100  }
101
102public:
103  TemplateName() : Storage() { }
104  explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
105  explicit TemplateName(OverloadedTemplateStorage *Storage)
106    : Storage(Storage) { }
107  explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
108  explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
109
110  /// \brief Determine whether this template name is NULL.
111  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  OverloadedTemplateStorage *getAsOverloadedTemplate() const {
130    return Storage.dyn_cast<OverloadedTemplateStorage *>();
131  }
132
133  /// \brief Retrieve the underlying qualified template name
134  /// structure, if any.
135  QualifiedTemplateName *getAsQualifiedTemplateName() const {
136    return Storage.dyn_cast<QualifiedTemplateName *>();
137  }
138
139  /// \brief Retrieve the underlying dependent template name
140  /// structure, if any.
141  DependentTemplateName *getAsDependentTemplateName() const {
142    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  void Profile(llvm::FoldingSetNodeID &ID) {
164    ID.AddPointer(Storage.getOpaqueValue());
165  }
166
167  /// \brief Retrieve the template name as a void pointer.
168  void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
169
170  /// \brief Build a template name from a void pointer.
171  static TemplateName getFromVoidPointer(void *Ptr) {
172    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.
187class 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                        TemplateDecl *Template)
205    : Qualifier(NNS, TemplateKeyword? 1 : 0),
206      Template(Template) { }
207
208public:
209  /// \brief Return the nested name specifier that qualifies this name.
210  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
211
212  /// \brief Whether the template name was prefixed by the "template"
213  /// keyword.
214  bool hasTemplateKeyword() const { return Qualifier.getInt(); }
215
216  /// \brief The template declaration that this qualified name refers
217  /// to.
218  TemplateDecl *getDecl() const { return Template; }
219
220  /// \brief The template declaration to which this qualified name
221  /// refers.
222  TemplateDecl *getTemplateDecl() const { return Template; }
223
224  void Profile(llvm::FoldingSetNodeID &ID) {
225    Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
226  }
227
228  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
229                      bool TemplateKeyword, TemplateDecl *Template) {
230    ID.AddPointer(NNS);
231    ID.AddBoolean(TemplateKeyword);
232    ID.AddPointer(Template);
233  }
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.
244class 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                        const IdentifierInfo *Identifier)
278    : Qualifier(Qualifier, false), Identifier(Identifier),
279      CanonicalTemplateName(this) { }
280
281  DependentTemplateName(NestedNameSpecifier *Qualifier,
282                        const IdentifierInfo *Identifier,
283                        TemplateName Canon)
284    : Qualifier(Qualifier, false), Identifier(Identifier),
285      CanonicalTemplateName(Canon) { }
286
287  DependentTemplateName(NestedNameSpecifier *Qualifier,
288                        OverloadedOperatorKind Operator)
289  : Qualifier(Qualifier, true), Operator(Operator),
290    CanonicalTemplateName(this) { }
291
292  DependentTemplateName(NestedNameSpecifier *Qualifier,
293                        OverloadedOperatorKind Operator,
294                        TemplateName Canon)
295  : Qualifier(Qualifier, true), Operator(Operator),
296    CanonicalTemplateName(Canon) { }
297
298public:
299  /// \brief Return the nested name specifier that qualifies this name.
300  NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
301
302  /// \brief Determine whether this template name refers to an identifier.
303  bool isIdentifier() const { return !Qualifier.getInt(); }
304
305  /// \brief Returns the identifier to which this template name refers.
306  const IdentifierInfo *getIdentifier() const {
307    assert(isIdentifier() && "Template name isn't an identifier?");
308    return Identifier;
309  }
310
311  /// \brief Determine whether this template name refers to an overloaded
312  /// operator.
313  bool isOverloadedOperator() const { return Qualifier.getInt(); }
314
315  /// \brief Return the overloaded operator to which this template name refers.
316  OverloadedOperatorKind getOperator() const {
317    assert(isOverloadedOperator() &&
318           "Template name isn't an overloaded operator?");
319    return Operator;
320  }
321
322  void Profile(llvm::FoldingSetNodeID &ID) {
323    if (isIdentifier())
324      Profile(ID, getQualifier(), getIdentifier());
325    else
326      Profile(ID, getQualifier(), getOperator());
327  }
328
329  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
330                      const IdentifierInfo *Identifier) {
331    ID.AddPointer(NNS);
332    ID.AddBoolean(false);
333    ID.AddPointer(Identifier);
334  }
335
336  static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
337                      OverloadedOperatorKind Operator) {
338    ID.AddPointer(NNS);
339    ID.AddBoolean(true);
340    ID.AddInteger(Operator);
341  }
342};
343
344} // end namespace clang.
345
346namespace llvm {
347
348/// \brief The clang::TemplateName class is effectively a pointer.
349template<>
350class PointerLikeTypeTraits<clang::TemplateName> {
351public:
352  static inline void *getAsVoidPointer(clang::TemplateName TN) {
353    return TN.getAsVoidPointer();
354  }
355
356  static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
357    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
367