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