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/Basic/LLVM.h"
     18 #include "clang/Basic/OperatorKinds.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 NestedNameSpecifier;
     29 class OverloadedTemplateStorage;
     30 struct PrintingPolicy;
     31 class QualifiedTemplateName;
     32 class NamedDecl;
     33 class SubstTemplateTemplateParmStorage;
     34 class SubstTemplateTemplateParmPackStorage;
     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              : 0;
     75   }
     76 
     77   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
     78     return Bits.Kind == SubstTemplateTemplateParm
     79              ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
     80              : 0;
     81   }
     82 
     83   SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
     84     return Bits.Kind == SubstTemplateTemplateParmPack
     85              ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
     86              : 0;
     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     Storage = StorageType::getFromOpaqueValue(Ptr);
    185   }
    186 
    187 public:
    188   // \brief Kind of name that is actually stored.
    189   enum NameKind {
    190     /// \brief A single template declaration.
    191     Template,
    192     /// \brief A set of overloaded template declarations.
    193     OverloadedTemplate,
    194     /// \brief A qualified template name, where the qualification is kept
    195     /// to describe the source code as written.
    196     QualifiedTemplate,
    197     /// \brief A dependent template name that has not been resolved to a
    198     /// template (or set of templates).
    199     DependentTemplate,
    200     /// \brief A template template parameter that has been substituted
    201     /// for some other template name.
    202     SubstTemplateTemplateParm,
    203     /// \brief A template template parameter pack that has been substituted for
    204     /// a template template argument pack, but has not yet been expanded into
    205     /// individual arguments.
    206     SubstTemplateTemplateParmPack
    207   };
    208 
    209   TemplateName() : Storage() { }
    210   explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
    211   explicit TemplateName(OverloadedTemplateStorage *Storage)
    212     : Storage(Storage) { }
    213   explicit TemplateName(SubstTemplateTemplateParmStorage *Storage);
    214   explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage)
    215     : Storage(Storage) { }
    216   explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
    217   explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
    218 
    219   /// \brief Determine whether this template name is NULL.
    220   bool isNull() const { return Storage.isNull(); }
    221 
    222   // \brief Get the kind of name that is actually stored.
    223   NameKind getKind() const;
    224 
    225   /// \brief Retrieve the underlying template declaration that
    226   /// this template name refers to, if known.
    227   ///
    228   /// \returns The template declaration that this template name refers
    229   /// to, if any. If the template name does not refer to a specific
    230   /// declaration because it is a dependent name, or if it refers to a
    231   /// set of function templates, returns NULL.
    232   TemplateDecl *getAsTemplateDecl() const;
    233 
    234   /// \brief Retrieve the underlying, overloaded function template
    235   // declarations that this template name refers to, if known.
    236   ///
    237   /// \returns The set of overloaded function templates that this template
    238   /// name refers to, if known. If the template name does not refer to a
    239   /// specific set of function templates because it is a dependent name or
    240   /// refers to a single template, returns NULL.
    241   OverloadedTemplateStorage *getAsOverloadedTemplate() const {
    242     if (UncommonTemplateNameStorage *Uncommon =
    243                               Storage.dyn_cast<UncommonTemplateNameStorage *>())
    244       return Uncommon->getAsOverloadedStorage();
    245 
    246     return 0;
    247   }
    248 
    249   /// \brief Retrieve the substituted template template parameter, if
    250   /// known.
    251   ///
    252   /// \returns The storage for the substituted template template parameter,
    253   /// if known. Otherwise, returns NULL.
    254   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const {
    255     if (UncommonTemplateNameStorage *uncommon =
    256           Storage.dyn_cast<UncommonTemplateNameStorage *>())
    257       return uncommon->getAsSubstTemplateTemplateParm();
    258 
    259     return 0;
    260   }
    261 
    262   /// \brief Retrieve the substituted template template parameter pack, if
    263   /// known.
    264   ///
    265   /// \returns The storage for the substituted template template parameter pack,
    266   /// if known. Otherwise, returns NULL.
    267   SubstTemplateTemplateParmPackStorage *
    268   getAsSubstTemplateTemplateParmPack() const {
    269     if (UncommonTemplateNameStorage *Uncommon =
    270         Storage.dyn_cast<UncommonTemplateNameStorage *>())
    271       return Uncommon->getAsSubstTemplateTemplateParmPack();
    272 
    273     return 0;
    274   }
    275 
    276   /// \brief Retrieve the underlying qualified template name
    277   /// structure, if any.
    278   QualifiedTemplateName *getAsQualifiedTemplateName() const {
    279     return Storage.dyn_cast<QualifiedTemplateName *>();
    280   }
    281 
    282   /// \brief Retrieve the underlying dependent template name
    283   /// structure, if any.
    284   DependentTemplateName *getAsDependentTemplateName() const {
    285     return Storage.dyn_cast<DependentTemplateName *>();
    286   }
    287 
    288   TemplateName getUnderlying() const;
    289 
    290   /// \brief Determines whether this is a dependent template name.
    291   bool isDependent() const;
    292 
    293   /// \brief Determines whether this is a template name that somehow
    294   /// depends on a template parameter.
    295   bool isInstantiationDependent() const;
    296 
    297   /// \brief Determines whether this template name contains an
    298   /// unexpanded parameter pack (for C++0x variadic templates).
    299   bool containsUnexpandedParameterPack() const;
    300 
    301   /// \brief Print the template name.
    302   ///
    303   /// \param OS the output stream to which the template name will be
    304   /// printed.
    305   ///
    306   /// \param SuppressNNS if true, don't print the
    307   /// nested-name-specifier that precedes the template name (if it has
    308   /// one).
    309   void print(raw_ostream &OS, const PrintingPolicy &Policy,
    310              bool SuppressNNS = false) const;
    311 
    312   /// \brief Debugging aid that dumps the template name.
    313   void dump(raw_ostream &OS) const;
    314 
    315   /// \brief Debugging aid that dumps the template name to standard
    316   /// error.
    317   void dump() const;
    318 
    319   void Profile(llvm::FoldingSetNodeID &ID) {
    320     ID.AddPointer(Storage.getOpaqueValue());
    321   }
    322 
    323   /// \brief Retrieve the template name as a void pointer.
    324   void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
    325 
    326   /// \brief Build a template name from a void pointer.
    327   static TemplateName getFromVoidPointer(void *Ptr) {
    328     return TemplateName(Ptr);
    329   }
    330 };
    331 
    332 /// Insertion operator for diagnostics.  This allows sending TemplateName's
    333 /// into a diagnostic with <<.
    334 const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
    335                                     TemplateName N);
    336 
    337 /// \brief A structure for storing the information associated with a
    338 /// substituted template template parameter.
    339 class SubstTemplateTemplateParmStorage
    340   : public UncommonTemplateNameStorage, public llvm::FoldingSetNode {
    341   friend class ASTContext;
    342 
    343   TemplateTemplateParmDecl *Parameter;
    344   TemplateName Replacement;
    345 
    346   SubstTemplateTemplateParmStorage(TemplateTemplateParmDecl *parameter,
    347                                    TemplateName replacement)
    348     : UncommonTemplateNameStorage(SubstTemplateTemplateParm, 0),
    349       Parameter(parameter), Replacement(replacement) {}
    350 
    351 public:
    352   TemplateTemplateParmDecl *getParameter() const { return Parameter; }
    353   TemplateName getReplacement() const { return Replacement; }
    354 
    355   void Profile(llvm::FoldingSetNodeID &ID);
    356 
    357   static void Profile(llvm::FoldingSetNodeID &ID,
    358                       TemplateTemplateParmDecl *parameter,
    359                       TemplateName replacement);
    360 };
    361 
    362 inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage)
    363   : Storage(Storage) { }
    364 
    365 inline TemplateName TemplateName::getUnderlying() const {
    366   if (SubstTemplateTemplateParmStorage *subst
    367         = getAsSubstTemplateTemplateParm())
    368     return subst->getReplacement().getUnderlying();
    369   return *this;
    370 }
    371 
    372 /// \brief Represents a template name that was expressed as a
    373 /// qualified name.
    374 ///
    375 /// This kind of template name refers to a template name that was
    376 /// preceded by a nested name specifier, e.g., \c std::vector. Here,
    377 /// the nested name specifier is "std::" and the template name is the
    378 /// declaration for "vector". The QualifiedTemplateName class is only
    379 /// used to provide "sugar" for template names that were expressed
    380 /// with a qualified name, and has no semantic meaning. In this
    381 /// manner, it is to TemplateName what ElaboratedType is to Type,
    382 /// providing extra syntactic sugar for downstream clients.
    383 class QualifiedTemplateName : public llvm::FoldingSetNode {
    384   /// \brief The nested name specifier that qualifies the template name.
    385   ///
    386   /// The bit is used to indicate whether the "template" keyword was
    387   /// present before the template name itself. Note that the
    388   /// "template" keyword is always redundant in this case (otherwise,
    389   /// the template name would be a dependent name and we would express
    390   /// this name with DependentTemplateName).
    391   llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
    392 
    393   /// \brief The template declaration or set of overloaded function templates
    394   /// that this qualified name refers to.
    395   TemplateDecl *Template;
    396 
    397   friend class ASTContext;
    398 
    399   QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
    400                         TemplateDecl *Template)
    401     : Qualifier(NNS, TemplateKeyword? 1 : 0),
    402       Template(Template) { }
    403 
    404 public:
    405   /// \brief Return the nested name specifier that qualifies this name.
    406   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
    407 
    408   /// \brief Whether the template name was prefixed by the "template"
    409   /// keyword.
    410   bool hasTemplateKeyword() const { return Qualifier.getInt(); }
    411 
    412   /// \brief The template declaration that this qualified name refers
    413   /// to.
    414   TemplateDecl *getDecl() const { return Template; }
    415 
    416   /// \brief The template declaration to which this qualified name
    417   /// refers.
    418   TemplateDecl *getTemplateDecl() const { return Template; }
    419 
    420   void Profile(llvm::FoldingSetNodeID &ID) {
    421     Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
    422   }
    423 
    424   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
    425                       bool TemplateKeyword, TemplateDecl *Template) {
    426     ID.AddPointer(NNS);
    427     ID.AddBoolean(TemplateKeyword);
    428     ID.AddPointer(Template);
    429   }
    430 };
    431 
    432 /// \brief Represents a dependent template name that cannot be
    433 /// resolved prior to template instantiation.
    434 ///
    435 /// This kind of template name refers to a dependent template name,
    436 /// including its nested name specifier (if any). For example,
    437 /// DependentTemplateName can refer to "MetaFun::template apply",
    438 /// where "MetaFun::" is the nested name specifier and "apply" is the
    439 /// template name referenced. The "template" keyword is implied.
    440 class DependentTemplateName : public llvm::FoldingSetNode {
    441   /// \brief The nested name specifier that qualifies the template
    442   /// name.
    443   ///
    444   /// The bit stored in this qualifier describes whether the \c Name field
    445   /// is interpreted as an IdentifierInfo pointer (when clear) or as an
    446   /// overloaded operator kind (when set).
    447   llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
    448 
    449   /// \brief The dependent template name.
    450   union {
    451     /// \brief The identifier template name.
    452     ///
    453     /// Only valid when the bit on \c Qualifier is clear.
    454     const IdentifierInfo *Identifier;
    455 
    456     /// \brief The overloaded operator name.
    457     ///
    458     /// Only valid when the bit on \c Qualifier is set.
    459     OverloadedOperatorKind Operator;
    460   };
    461 
    462   /// \brief The canonical template name to which this dependent
    463   /// template name refers.
    464   ///
    465   /// The canonical template name for a dependent template name is
    466   /// another dependent template name whose nested name specifier is
    467   /// canonical.
    468   TemplateName CanonicalTemplateName;
    469 
    470   friend class ASTContext;
    471 
    472   DependentTemplateName(NestedNameSpecifier *Qualifier,
    473                         const IdentifierInfo *Identifier)
    474     : Qualifier(Qualifier, false), Identifier(Identifier),
    475       CanonicalTemplateName(this) { }
    476 
    477   DependentTemplateName(NestedNameSpecifier *Qualifier,
    478                         const IdentifierInfo *Identifier,
    479                         TemplateName Canon)
    480     : Qualifier(Qualifier, false), Identifier(Identifier),
    481       CanonicalTemplateName(Canon) { }
    482 
    483   DependentTemplateName(NestedNameSpecifier *Qualifier,
    484                         OverloadedOperatorKind Operator)
    485   : Qualifier(Qualifier, true), Operator(Operator),
    486     CanonicalTemplateName(this) { }
    487 
    488   DependentTemplateName(NestedNameSpecifier *Qualifier,
    489                         OverloadedOperatorKind Operator,
    490                         TemplateName Canon)
    491   : Qualifier(Qualifier, true), Operator(Operator),
    492     CanonicalTemplateName(Canon) { }
    493 
    494 public:
    495   /// \brief Return the nested name specifier that qualifies this name.
    496   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
    497 
    498   /// \brief Determine whether this template name refers to an identifier.
    499   bool isIdentifier() const { return !Qualifier.getInt(); }
    500 
    501   /// \brief Returns the identifier to which this template name refers.
    502   const IdentifierInfo *getIdentifier() const {
    503     assert(isIdentifier() && "Template name isn't an identifier?");
    504     return Identifier;
    505   }
    506 
    507   /// \brief Determine whether this template name refers to an overloaded
    508   /// operator.
    509   bool isOverloadedOperator() const { return Qualifier.getInt(); }
    510 
    511   /// \brief Return the overloaded operator to which this template name refers.
    512   OverloadedOperatorKind getOperator() const {
    513     assert(isOverloadedOperator() &&
    514            "Template name isn't an overloaded operator?");
    515     return Operator;
    516   }
    517 
    518   void Profile(llvm::FoldingSetNodeID &ID) {
    519     if (isIdentifier())
    520       Profile(ID, getQualifier(), getIdentifier());
    521     else
    522       Profile(ID, getQualifier(), getOperator());
    523   }
    524 
    525   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
    526                       const IdentifierInfo *Identifier) {
    527     ID.AddPointer(NNS);
    528     ID.AddBoolean(false);
    529     ID.AddPointer(Identifier);
    530   }
    531 
    532   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
    533                       OverloadedOperatorKind Operator) {
    534     ID.AddPointer(NNS);
    535     ID.AddBoolean(true);
    536     ID.AddInteger(Operator);
    537   }
    538 };
    539 
    540 } // end namespace clang.
    541 
    542 namespace llvm {
    543 
    544 /// \brief The clang::TemplateName class is effectively a pointer.
    545 template<>
    546 class PointerLikeTypeTraits<clang::TemplateName> {
    547 public:
    548   static inline void *getAsVoidPointer(clang::TemplateName TN) {
    549     return TN.getAsVoidPointer();
    550   }
    551 
    552   static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
    553     return clang::TemplateName::getFromVoidPointer(Ptr);
    554   }
    555 
    556   // No bits are available!
    557   enum { NumLowBitsAvailable = 0 };
    558 };
    559 
    560 } // end namespace llvm.
    561 
    562 #endif
    563