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