]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/TemplateName.h
Submitted by: phil
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / TemplateName.h
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 "clang/Basic/LLVM.h"
18 #include "llvm/ADT/FoldingSet.h"
19 #include "llvm/ADT/PointerUnion.h"
20
21 namespace clang {
22   
23 class ASTContext;
24 class DependentTemplateName;
25 class DiagnosticBuilder;
26 class IdentifierInfo;
27 class NamedDecl;
28 class NestedNameSpecifier;
29 enum OverloadedOperatorKind : int;
30 class OverloadedTemplateStorage;
31 struct PrintingPolicy;
32 class QualifiedTemplateName;
33 class SubstTemplateTemplateParmPackStorage;
34 class SubstTemplateTemplateParmStorage;
35 class TemplateArgument;
36 class TemplateDecl;
37 class TemplateTemplateParmDecl;
38   
39 /// \brief Implementation class used to describe either a set of overloaded
40 /// template names or an already-substituted template template parameter pack.
41 class UncommonTemplateNameStorage {
42 protected:
43   enum Kind {
44     Overloaded,
45     SubstTemplateTemplateParm,
46     SubstTemplateTemplateParmPack
47   };
48
49   struct BitsTag {
50     /// \brief A Kind.
51     unsigned Kind : 2;
52     
53     /// \brief The number of stored templates or template arguments,
54     /// depending on which subclass we have.
55     unsigned Size : 30;
56   };
57
58   union {
59     struct BitsTag Bits;
60     void *PointerAlignment;
61   };
62   
63   UncommonTemplateNameStorage(Kind kind, unsigned size) {
64     Bits.Kind = kind;
65     Bits.Size = size;
66   }
67   
68 public:
69   unsigned size() const { return Bits.Size; }
70   
71   OverloadedTemplateStorage *getAsOverloadedStorage()  {
72     return Bits.Kind == Overloaded
73              ? reinterpret_cast<OverloadedTemplateStorage *>(this) 
74              : nullptr;
75   }
76   
77   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
78     return Bits.Kind == SubstTemplateTemplateParm
79              ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
80              : nullptr;
81   }
82
83   SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
84     return Bits.Kind == SubstTemplateTemplateParmPack
85              ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
86              : nullptr;
87   }
88 };
89   
90 /// \brief A structure for storing the information associated with an
91 /// overloaded template name.
92 class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
93   friend class ASTContext;
94
95   OverloadedTemplateStorage(unsigned size) 
96     : UncommonTemplateNameStorage(Overloaded, size) { }
97
98   NamedDecl **getStorage() {
99     return reinterpret_cast<NamedDecl **>(this + 1);
100   }
101   NamedDecl * const *getStorage() const {
102     return reinterpret_cast<NamedDecl *const *>(this + 1);
103   }
104
105 public:
106   typedef NamedDecl *const *iterator;
107
108   iterator begin() const { return getStorage(); }
109   iterator end() const { return getStorage() + size(); }
110 };
111
112 /// \brief A structure for storing an already-substituted template template
113 /// parameter pack.
114 ///
115 /// This kind of template names occurs when the parameter pack has been 
116 /// provided with a template template argument pack in a context where its
117 /// enclosing pack expansion could not be fully expanded.
118 class SubstTemplateTemplateParmPackStorage
119   : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
120 {
121   TemplateTemplateParmDecl *Parameter;
122   const TemplateArgument *Arguments;
123   
124 public:
125   SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
126                                        unsigned Size, 
127                                        const TemplateArgument *Arguments)
128     : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
129       Parameter(Parameter), Arguments(Arguments) { }
130   
131   /// \brief Retrieve the template template parameter pack being substituted.
132   TemplateTemplateParmDecl *getParameterPack() const {
133     return Parameter;
134   }
135   
136   /// \brief Retrieve the template template argument pack with which this
137   /// parameter was substituted.
138   TemplateArgument getArgumentPack() const;
139   
140   void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
141   
142   static void Profile(llvm::FoldingSetNodeID &ID,
143                       ASTContext &Context,
144                       TemplateTemplateParmDecl *Parameter,
145                       const TemplateArgument &ArgPack);
146 };
147
148 /// \brief Represents a C++ template name within the type system.
149 ///
150 /// A C++ template name refers to a template within the C++ type
151 /// system. In most cases, a template name is simply a reference to a
152 /// class template, e.g.
153 ///
154 /// \code
155 /// template<typename T> class X { };
156 ///
157 /// X<int> xi;
158 /// \endcode
159 ///
160 /// Here, the 'X' in \c X<int> is a template name that refers to the
161 /// declaration of the class template X, above. Template names can
162 /// also refer to function templates, C++0x template aliases, etc.
163 ///
164 /// Some template names are dependent. For example, consider:
165 ///
166 /// \code
167 /// template<typename MetaFun, typename T1, typename T2> struct apply2 {
168 ///   typedef typename MetaFun::template apply<T1, T2>::type type;
169 /// };
170 /// \endcode
171 ///
172 /// Here, "apply" is treated as a template name within the typename
173 /// specifier in the typedef. "apply" is a nested template, and can
174 /// only be understood in the context of
175 class TemplateName {
176   typedef llvm::PointerUnion4<TemplateDecl *,
177                               UncommonTemplateNameStorage *,
178                               QualifiedTemplateName *,
179                               DependentTemplateName *> StorageType;
180
181   StorageType Storage;
182
183   explicit TemplateName(void *Ptr);
184
185 public:
186   // \brief Kind of name that is actually stored.
187   enum NameKind {
188     /// \brief A single template declaration.
189     Template,
190     /// \brief A set of overloaded template declarations.
191     OverloadedTemplate,
192     /// \brief A qualified template name, where the qualification is kept 
193     /// to describe the source code as written.
194     QualifiedTemplate,
195     /// \brief A dependent template name that has not been resolved to a 
196     /// template (or set of templates).
197     DependentTemplate,
198     /// \brief A template template parameter that has been substituted
199     /// for some other template name.
200     SubstTemplateTemplateParm,
201     /// \brief A template template parameter pack that has been substituted for 
202     /// a template template argument pack, but has not yet been expanded into
203     /// individual arguments.
204     SubstTemplateTemplateParmPack
205   };
206
207   TemplateName() : Storage() { }
208   explicit TemplateName(TemplateDecl *Template);
209   explicit TemplateName(OverloadedTemplateStorage *Storage);
210   explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
211   explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage);
212   explicit TemplateName(QualifiedTemplateName *Qual);
213   explicit TemplateName(DependentTemplateName *Dep);
214
215   /// \brief Determine whether this template name is NULL.
216   bool isNull() const;
217   
218   // \brief Get the kind of name that is actually stored.
219   NameKind getKind() const;
220
221   /// \brief Retrieve the underlying template declaration that
222   /// this template name refers to, if known.
223   ///
224   /// \returns The template declaration that this template name refers
225   /// to, if any. If the template name does not refer to a specific
226   /// declaration because it is a dependent name, or if it refers to a
227   /// set of function templates, returns NULL.
228   TemplateDecl *getAsTemplateDecl() const;
229
230   /// \brief Retrieve the underlying, overloaded function template
231   // declarations that this template name refers to, if known.
232   ///
233   /// \returns The set of overloaded function templates that this template
234   /// name refers to, if known. If the template name does not refer to a
235   /// specific set of function templates because it is a dependent name or
236   /// refers to a single template, returns NULL.
237   OverloadedTemplateStorage *getAsOverloadedTemplate() const;
238
239   /// \brief Retrieve the substituted template template parameter, if 
240   /// known.
241   ///
242   /// \returns The storage for the substituted template template parameter,
243   /// if known. Otherwise, returns NULL.
244   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const;
245
246   /// \brief Retrieve the substituted template template parameter pack, if 
247   /// known.
248   ///
249   /// \returns The storage for the substituted template template parameter pack,
250   /// if known. Otherwise, returns NULL.
251   SubstTemplateTemplateParmPackStorage *
252   getAsSubstTemplateTemplateParmPack() const;
253
254   /// \brief Retrieve the underlying qualified template name
255   /// structure, if any.
256   QualifiedTemplateName *getAsQualifiedTemplateName() const;
257
258   /// \brief Retrieve the underlying dependent template name
259   /// structure, if any.
260   DependentTemplateName *getAsDependentTemplateName() const;
261
262   TemplateName getUnderlying() const;
263
264   /// \brief Determines whether this is a dependent template name.
265   bool isDependent() const;
266
267   /// \brief Determines whether this is a template name that somehow
268   /// depends on a template parameter.
269   bool isInstantiationDependent() const;
270
271   /// \brief Determines whether this template name contains an
272   /// unexpanded parameter pack (for C++0x variadic templates).
273   bool containsUnexpandedParameterPack() const;
274
275   /// \brief Print the template name.
276   ///
277   /// \param OS the output stream to which the template name will be
278   /// printed.
279   ///
280   /// \param SuppressNNS if true, don't print the
281   /// nested-name-specifier that precedes the template name (if it has
282   /// one).
283   void print(raw_ostream &OS, const PrintingPolicy &Policy,
284              bool SuppressNNS = false) const;
285
286   /// \brief Debugging aid that dumps the template name.
287   void dump(raw_ostream &OS) const;
288
289   /// \brief Debugging aid that dumps the template name to standard
290   /// error.
291   void dump() const;
292
293   void Profile(llvm::FoldingSetNodeID &ID) {
294     ID.AddPointer(Storage.getOpaqueValue());
295   }
296
297   /// \brief Retrieve the template name as a void pointer.
298   void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
299
300   /// \brief Build a template name from a void pointer.
301   static TemplateName getFromVoidPointer(void *Ptr) {
302     return TemplateName(Ptr);
303   }
304 };
305
306 /// Insertion operator for diagnostics.  This allows sending TemplateName's
307 /// into a diagnostic with <<.
308 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
309                                     TemplateName N);
310
311 /// \brief A structure for storing the information associated with a
312 /// substituted template template parameter.
313 class SubstTemplateTemplateParmStorage
314   : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
315   friend class ASTContext;
316
317   TemplateTemplateParmDecl *Parameter;
318   TemplateName Replacement;
319
320   SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
321                                    TemplateName replacement)
322     : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
323       Parameter(parameter), Replacement(replacement) {}
324
325 public:
326   TemplateTemplateParmDecl *getParameter() const { return Parameter; }
327   TemplateName getReplacement() const { return Replacement; }
328
329   void Profile(llvm::FoldingSetNodeID &ID);
330   
331   static void Profile(llvm::FoldingSetNodeID &ID,
332                       TemplateTemplateParmDecl *parameter,
333                       TemplateName replacement);
334 };
335
336 inline TemplateName TemplateName::getUnderlying() const {
337   if (SubstTemplateTemplateParmStorage *subst
338         = getAsSubstTemplateTemplateParm())
339     return subst->getReplacement().getUnderlying();
340   return *this;
341 }
342
343 /// \brief Represents a template name that was expressed as a
344 /// qualified name.
345 ///
346 /// This kind of template name refers to a template name that was
347 /// preceded by a nested name specifier, e.g., \c std::vector. Here,
348 /// the nested name specifier is "std::" and the template name is the
349 /// declaration for "vector". The QualifiedTemplateName class is only
350 /// used to provide "sugar" for template names that were expressed
351 /// with a qualified name, and has no semantic meaning. In this
352 /// manner, it is to TemplateName what ElaboratedType is to Type,
353 /// providing extra syntactic sugar for downstream clients.
354 class QualifiedTemplateName : public llvm::FoldingSetNode {
355   /// \brief The nested name specifier that qualifies the template name.
356   ///
357   /// The bit is used to indicate whether the "template" keyword was
358   /// present before the template name itself. Note that the
359   /// "template" keyword is always redundant in this case (otherwise,
360   /// the template name would be a dependent name and we would express
361   /// this name with DependentTemplateName).
362   llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
363
364   /// \brief The template declaration or set of overloaded function templates
365   /// that this qualified name refers to.
366   TemplateDecl *Template;
367
368   friend class ASTContext;
369
370   QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
371                         TemplateDecl *Template)
372     : Qualifier(NNS, TemplateKeyword? 1 : 0),
373       Template(Template) { }
374
375 public:
376   /// \brief Return the nested name specifier that qualifies this name.
377   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
378
379   /// \brief Whether the template name was prefixed by the "template"
380   /// keyword.
381   bool hasTemplateKeyword() const { return Qualifier.getInt(); }
382
383   /// \brief The template declaration that this qualified name refers
384   /// to.
385   TemplateDecl *getDecl() const { return Template; }
386
387   /// \brief The template declaration to which this qualified name
388   /// refers.
389   TemplateDecl *getTemplateDecl() const { return Template; }
390
391   void Profile(llvm::FoldingSetNodeID &ID) {
392     Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
393   }
394
395   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
396                       bool TemplateKeyword, TemplateDecl *Template) {
397     ID.AddPointer(NNS);
398     ID.AddBoolean(TemplateKeyword);
399     ID.AddPointer(Template);
400   }
401 };
402
403 /// \brief Represents a dependent template name that cannot be
404 /// resolved prior to template instantiation.
405 ///
406 /// This kind of template name refers to a dependent template name,
407 /// including its nested name specifier (if any). For example,
408 /// DependentTemplateName can refer to "MetaFun::template apply",
409 /// where "MetaFun::" is the nested name specifier and "apply" is the
410 /// template name referenced. The "template" keyword is implied.
411 class DependentTemplateName : public llvm::FoldingSetNode {
412   /// \brief The nested name specifier that qualifies the template
413   /// name.
414   ///
415   /// The bit stored in this qualifier describes whether the \c Name field
416   /// is interpreted as an IdentifierInfo pointer (when clear) or as an
417   /// overloaded operator kind (when set).
418   llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
419
420   /// \brief The dependent template name.
421   union {
422     /// \brief The identifier template name.
423     ///
424     /// Only valid when the bit on \c Qualifier is clear.
425     const IdentifierInfo *Identifier;
426     
427     /// \brief The overloaded operator name.
428     ///
429     /// Only valid when the bit on \c Qualifier is set.
430     OverloadedOperatorKind Operator;
431   };
432
433   /// \brief The canonical template name to which this dependent
434   /// template name refers.
435   ///
436   /// The canonical template name for a dependent template name is
437   /// another dependent template name whose nested name specifier is
438   /// canonical.
439   TemplateName CanonicalTemplateName;
440
441   friend class ASTContext;
442
443   DependentTemplateName(NestedNameSpecifier *Qualifier,
444                         const IdentifierInfo *Identifier)
445     : Qualifier(Qualifier, false), Identifier(Identifier), 
446       CanonicalTemplateName(this) { }
447
448   DependentTemplateName(NestedNameSpecifier *Qualifier,
449                         const IdentifierInfo *Identifier,
450                         TemplateName Canon)
451     : Qualifier(Qualifier, false), Identifier(Identifier), 
452       CanonicalTemplateName(Canon) { }
453
454   DependentTemplateName(NestedNameSpecifier *Qualifier,
455                         OverloadedOperatorKind Operator)
456   : Qualifier(Qualifier, true), Operator(Operator), 
457     CanonicalTemplateName(this) { }
458   
459   DependentTemplateName(NestedNameSpecifier *Qualifier,
460                         OverloadedOperatorKind Operator,
461                         TemplateName Canon)
462   : Qualifier(Qualifier, true), Operator(Operator), 
463     CanonicalTemplateName(Canon) { }
464   
465 public:
466   /// \brief Return the nested name specifier that qualifies this name.
467   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
468
469   /// \brief Determine whether this template name refers to an identifier.
470   bool isIdentifier() const { return !Qualifier.getInt(); }
471
472   /// \brief Returns the identifier to which this template name refers.
473   const IdentifierInfo *getIdentifier() const { 
474     assert(isIdentifier() && "Template name isn't an identifier?");
475     return Identifier;
476   }
477   
478   /// \brief Determine whether this template name refers to an overloaded
479   /// operator.
480   bool isOverloadedOperator() const { return Qualifier.getInt(); }
481   
482   /// \brief Return the overloaded operator to which this template name refers.
483   OverloadedOperatorKind getOperator() const { 
484     assert(isOverloadedOperator() &&
485            "Template name isn't an overloaded operator?");
486     return Operator; 
487   }
488   
489   void Profile(llvm::FoldingSetNodeID &ID) {
490     if (isIdentifier())
491       Profile(ID, getQualifier(), getIdentifier());
492     else
493       Profile(ID, getQualifier(), getOperator());
494   }
495
496   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
497                       const IdentifierInfo *Identifier) {
498     ID.AddPointer(NNS);
499     ID.AddBoolean(false);
500     ID.AddPointer(Identifier);
501   }
502
503   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
504                       OverloadedOperatorKind Operator) {
505     ID.AddPointer(NNS);
506     ID.AddBoolean(true);
507     ID.AddInteger(Operator);
508   }
509 };
510
511 } // end namespace clang.
512
513 namespace llvm {
514
515 /// \brief The clang::TemplateName class is effectively a pointer.
516 template<>
517 class PointerLikeTypeTraits<clang::TemplateName> {
518 public:
519   static inline void *getAsVoidPointer(clang::TemplateName TN) {
520     return TN.getAsVoidPointer();
521   }
522
523   static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
524     return clang::TemplateName::getFromVoidPointer(Ptr);
525   }
526
527   // No bits are available!
528   enum { NumLowBitsAvailable = 0 };
529 };
530
531 } // end namespace llvm.
532
533 #endif