zcov: / include/clang/AST/TemplateName.h


Files: 1 Branches Taken: 50.0% 4 / 8
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 8 / 8
Line Coverage: 96.2% 77 / 80


Programs: 31 Runs 48167


       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 DependentTemplateName;
      28                 : class IdentifierInfo;
      29                 : class NestedNameSpecifier;
      30                 : struct PrintingPolicy;
      31                 : class QualifiedTemplateName;
      32                 : class NamedDecl;
      33                 : class TemplateDecl;
      34                 : 
      35                 : /// \brief A structure for storing the information associated with an
      36                 : /// overloaded template name.
      37                 : class OverloadedTemplateStorage {
      38                 :   union {
      39                 :     unsigned Size;
      40                 :     NamedDecl *Storage[1];
      41                 :   };
      42                 : 
      43                 :   friend class ASTContext;
      44                 : 
      45               28:   OverloadedTemplateStorage(unsigned Size) : Size(Size) {}
      46                 : 
      47               28:   NamedDecl **getStorage() {
      48               28:     return &Storage[1];
      49                 :   }
      50               69:   NamedDecl * const *getStorage() const {
      51               69:     return &Storage[1];
      52                 :   }
      53                 : 
      54                 : public:
      55                 :   typedef NamedDecl *const *iterator;
      56                 : 
      57               20:   unsigned size() const { return Size; }
      58                 : 
      59               49:   iterator begin() const { return getStorage(); }
      60               20:   iterator end() const { return getStorage() + size(); }
      61                 : };
      62                 : 
      63                 : /// \brief Represents a C++ template name within the type system.
      64                 : ///
      65                 : /// A C++ template name refers to a template within the C++ type
      66                 : /// system. In most cases, a template name is simply a reference to a
      67                 : /// class template, e.g.
      68                 : ///
      69                 : /// \code
      70                 : /// template<typename T> class X { };
      71                 : ///
      72                 : /// X<int> xi;
      73                 : /// \endcode
      74                 : ///
      75                 : /// Here, the 'X' in \c X<int> is a template name that refers to the
      76                 : /// declaration of the class template X, above. Template names can
      77                 : /// also refer to function templates, C++0x template aliases, etc.
      78                 : ///
      79                 : /// Some template names are dependent. For example, consider:
      80                 : ///
      81                 : /// \code
      82                 : /// template<typename MetaFun, typename T1, typename T2> struct apply2 {
      83                 : ///   typedef typename MetaFun::template apply<T1, T2>::type type;
      84                 : /// };
      85                 : /// \endcode
      86                 : ///
      87                 : /// Here, "apply" is treated as a template name within the typename
      88                 : /// specifier in the typedef. "apply" is a nested template, and can
      89                 : /// only be understood in the context of
      90                 : class TemplateName {
      91                 :   typedef llvm::PointerUnion4<TemplateDecl *,
      92                 :                               OverloadedTemplateStorage *,
      93                 :                               QualifiedTemplateName *,
      94                 :                               DependentTemplateName *> StorageType;
      95                 : 
      96                 :   StorageType Storage;
      97                 : 
      98             2991:   explicit TemplateName(void *Ptr) {
      99             2991:     Storage = StorageType::getFromOpaqueValue(Ptr);
     100             2991:   }
     101                 : 
     102                 : public:
     103             2572:   TemplateName() : Storage() { }
     104             4564:   explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
     105               28:   explicit TemplateName(OverloadedTemplateStorage *Storage)
     106               28:     : Storage(Storage) { }
     107              300:   explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
     108               83:   explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
     109                 : 
     110                 :   /// \brief Determine whether this template name is NULL.
     111             1358:   bool isNull() const { return Storage.isNull(); }
     112                 : 
     113                 :   /// \brief Retrieve the the underlying template declaration that
     114                 :   /// this template name refers to, if known.
     115                 :   ///
     116                 :   /// \returns The template declaration that this template name refers
     117                 :   /// to, if any. If the template name does not refer to a specific
     118                 :   /// declaration because it is a dependent name, or if it refers to a
     119                 :   /// set of function templates, returns NULL.
     120                 :   TemplateDecl *getAsTemplateDecl() const;
     121                 : 
     122                 :   /// \brief Retrieve the the underlying, overloaded function template
     123                 :   // declarations that this template name refers to, if known.
     124                 :   ///
     125                 :   /// \returns The set of overloaded function templates that this template
     126                 :   /// name refers to, if known. If the template name does not refer to a
     127                 :   /// specific set of function templates because it is a dependent name or
     128                 :   /// refers to a single template, returns NULL.
     129              149:   OverloadedTemplateStorage *getAsOverloadedTemplate() const {
     130              149:     return Storage.dyn_cast<OverloadedTemplateStorage *>();
     131                 :   }
     132                 : 
     133                 :   /// \brief Retrieve the underlying qualified template name
     134                 :   /// structure, if any.
     135             2538:   QualifiedTemplateName *getAsQualifiedTemplateName() const {
     136             2538:     return Storage.dyn_cast<QualifiedTemplateName *>();
     137                 :   }
     138                 : 
     139                 :   /// \brief Retrieve the underlying dependent template name
     140                 :   /// structure, if any.
     141             1383:   DependentTemplateName *getAsDependentTemplateName() const {
     142             1383:     return Storage.dyn_cast<DependentTemplateName *>();
     143                 :   }
     144                 : 
     145                 :   /// \brief Determines whether this is a dependent template name.
     146                 :   bool isDependent() const;
     147                 : 
     148                 :   /// \brief Print the template name.
     149                 :   ///
     150                 :   /// \param OS the output stream to which the template name will be
     151                 :   /// printed.
     152                 :   ///
     153                 :   /// \param SuppressNNS if true, don't print the
     154                 :   /// nested-name-specifier that precedes the template name (if it has
     155                 :   /// one).
     156                 :   void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
     157                 :              bool SuppressNNS = false) const;
     158                 : 
     159                 :   /// \brief Debugging aid that dumps the template name to standard
     160                 :   /// error.
     161                 :   void dump() const;
     162                 : 
     163             1374:   void Profile(llvm::FoldingSetNodeID &ID) {
     164             1374:     ID.AddPointer(Storage.getOpaqueValue());
     165             1374:   }
     166                 : 
     167                 :   /// \brief Retrieve the template name as a void pointer.
     168             3017:   void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
     169                 : 
     170                 :   /// \brief Build a template name from a void pointer.
     171             2991:   static TemplateName getFromVoidPointer(void *Ptr) {
     172             2991:     return TemplateName(Ptr);
     173                 :   }
     174                 : };
     175                 : 
     176                 : /// \brief Represents a template name that was expressed as a
     177                 : /// qualified name.
     178                 : ///
     179                 : /// This kind of template name refers to a template name that was
     180                 : /// preceded by a nested name specifier, e.g., \c std::vector. Here,
     181                 : /// the nested name specifier is "std::" and the template name is the
     182                 : /// declaration for "vector". The QualifiedTemplateName class is only
     183                 : /// used to provide "sugar" for template names that were expressed
     184                 : /// with a qualified name, and has no semantic meaning. In this
     185                 : /// manner, it is to TemplateName what QualifiedNameType is to Type,
     186                 : /// providing extra syntactic sugar for downstream clients.
     187                 : class QualifiedTemplateName : public llvm::FoldingSetNode {
     188                 :   /// \brief The nested name specifier that qualifies the template name.
     189                 :   ///
     190                 :   /// The bit is used to indicate whether the "template" keyword was
     191                 :   /// present before the template name itself. Note that the
     192                 :   /// "template" keyword is always redundant in this case (otherwise,
     193                 :   /// the template name would be a dependent name and we would express
     194                 :   /// this name with DependentTemplateName).
     195                 :   llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
     196                 : 
     197                 :   /// \brief The template declaration or set of overloaded function templates
     198                 :   /// that this qualified name refers to.
     199                 :   TemplateDecl *Template;
     200                 : 
     201                 :   friend class ASTContext;
     202                 : 
     203                 :   QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
     204              202:                         TemplateDecl *Template)
     205                 :     : Qualifier(NNS, TemplateKeyword? 1 : 0),
                        0: branch 1 not taken
                      202: branch 2 taken
     206              202:       Template(Template) { }
     207                 : 
     208                 : public:
     209                 :   /// \brief Return the nested name specifier that qualifies this name.
     210              154:   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
     211                 : 
     212                 :   /// \brief Whether the template name was prefixed by the "template"
     213                 :   /// keyword.
     214              132:   bool hasTemplateKeyword() const { return Qualifier.getInt(); }
     215                 : 
     216                 :   /// \brief The template declaration that this qualified name refers
     217                 :   /// to.
     218                8:   TemplateDecl *getDecl() const { return Template; }
     219                 : 
     220                 :   /// \brief The template declaration to which this qualified name
     221                 :   /// refers.
     222             1149:   TemplateDecl *getTemplateDecl() const { return Template; }
     223                 : 
     224              121:   void Profile(llvm::FoldingSetNodeID &ID) {
     225              121:     Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
     226              121:   }
     227                 : 
     228                 :   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
     229              421:                       bool TemplateKeyword, TemplateDecl *Template) {
     230              421:     ID.AddPointer(NNS);
     231              421:     ID.AddBoolean(TemplateKeyword);
     232              421:     ID.AddPointer(Template);
     233              421:   }
     234                 : };
     235                 : 
     236                 : /// \brief Represents a dependent template name that cannot be
     237                 : /// resolved prior to template instantiation.
     238                 : ///
     239                 : /// This kind of template name refers to a dependent template name,
     240                 : /// including its nested name specifier (if any). For example,
     241                 : /// DependentTemplateName can refer to "MetaFun::template apply",
     242                 : /// where "MetaFun::" is the nested name specifier and "apply" is the
     243                 : /// template name referenced. The "template" keyword is implied.
     244                 : class DependentTemplateName : public llvm::FoldingSetNode {
     245                 :   /// \brief The nested name specifier that qualifies the template
     246                 :   /// name.
     247                 :   ///
     248                 :   /// The bit stored in this qualifier describes whether the \c Name field
     249                 :   /// is interpreted as an IdentifierInfo pointer (when clear) or as an
     250                 :   /// overloaded operator kind (when set).
     251                 :   llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
     252                 : 
     253                 :   /// \brief The dependent template name.
     254                 :   union {
     255                 :     /// \brief The identifier template name.
     256                 :     ///
     257                 :     /// Only valid when the bit on \c Qualifier is clear.
     258                 :     const IdentifierInfo *Identifier;
     259                 :     
     260                 :     /// \brief The overloaded operator name.
     261                 :     ///
     262                 :     /// Only valid when the bit on \c Qualifier is set.
     263                 :     OverloadedOperatorKind Operator;
     264                 :   };
     265                 : 
     266                 :   /// \brief The canonical template name to which this dependent
     267                 :   /// template name refers.
     268                 :   ///
     269                 :   /// The canonical template name for a dependent template name is
     270                 :   /// another dependent template name whose nested name specifier is
     271                 :   /// canonical.
     272                 :   TemplateName CanonicalTemplateName;
     273                 : 
     274                 :   friend class ASTContext;
     275                 : 
     276                 :   DependentTemplateName(NestedNameSpecifier *Qualifier,
     277               17:                         const IdentifierInfo *Identifier)
     278                 :     : Qualifier(Qualifier, false), Identifier(Identifier), 
     279               17:       CanonicalTemplateName(this) { }
     280                 : 
     281                 :   DependentTemplateName(NestedNameSpecifier *Qualifier,
     282                 :                         const IdentifierInfo *Identifier,
     283               23:                         TemplateName Canon)
     284                 :     : Qualifier(Qualifier, false), Identifier(Identifier), 
     285               23:       CanonicalTemplateName(Canon) { }
     286                 : 
     287                 :   DependentTemplateName(NestedNameSpecifier *Qualifier,
     288                2:                         OverloadedOperatorKind Operator)
     289                 :   : Qualifier(Qualifier, true), Operator(Operator), 
     290                2:     CanonicalTemplateName(this) { }
     291                 :   
     292                 :   DependentTemplateName(NestedNameSpecifier *Qualifier,
     293                 :                         OverloadedOperatorKind Operator,
     294                0:                         TemplateName Canon)
     295                 :   : Qualifier(Qualifier, true), Operator(Operator), 
     296                0:     CanonicalTemplateName(Canon) { }
     297                 :   
     298                 : public:
     299                 :   /// \brief Return the nested name specifier that qualifies this name.
     300               58:   NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
     301                 : 
     302                 :   /// \brief Determine whether this template name refers to an identifier.
     303               94:   bool isIdentifier() const { return !Qualifier.getInt(); }
     304                 : 
     305                 :   /// \brief Returns the identifier to which this template name refers.
     306               46:   const IdentifierInfo *getIdentifier() const { 
                       46: branch 1 taken
                        0: branch 2 not taken
     307               46:     assert(isIdentifier() && "Template name isn't an identifier?");
     308               46:     return Identifier;
     309                 :   }
     310                 :   
     311                 :   /// \brief Determine whether this template name refers to an overloaded
     312                 :   /// operator.
     313                2:   bool isOverloadedOperator() const { return Qualifier.getInt(); }
     314                 :   
     315                 :   /// \brief Return the overloaded operator to which this template name refers.
     316                2:   OverloadedOperatorKind getOperator() const { 
     317                 :     assert(isOverloadedOperator() &&
                        2: branch 1 taken
                        0: branch 2 not taken
     318                2:            "Template name isn't an overloaded operator?");
     319                2:     return Operator; 
     320                 :   }
     321                 :   
     322               27:   void Profile(llvm::FoldingSetNodeID &ID) {
                       27: branch 1 taken
                        0: branch 2 not taken
     323               27:     if (isIdentifier())
     324               27:       Profile(ID, getQualifier(), getIdentifier());
     325                 :     else
     326                0:       Profile(ID, getQualifier(), getOperator());
     327               27:   }
     328                 : 
     329                 :   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
     330               89:                       const IdentifierInfo *Identifier) {
     331               89:     ID.AddPointer(NNS);
     332               89:     ID.AddBoolean(false);
     333               89:     ID.AddPointer(Identifier);
     334               89:   }
     335                 : 
     336                 :   static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
     337                2:                       OverloadedOperatorKind Operator) {
     338                2:     ID.AddPointer(NNS);
     339                2:     ID.AddBoolean(true);
     340                2:     ID.AddInteger(Operator);
     341                2:   }
     342                 : };
     343                 : 
     344                 : } // end namespace clang.
     345                 : 
     346                 : namespace llvm {
     347                 : 
     348                 : /// \brief The clang::TemplateName class is effectively a pointer.
     349                 : template<>
     350                 : class PointerLikeTypeTraits<clang::TemplateName> {
     351                 : public:
     352             2613:   static inline void *getAsVoidPointer(clang::TemplateName TN) {
     353             2613:     return TN.getAsVoidPointer();
     354                 :   }
     355                 : 
     356             2624:   static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
     357             2624:     return clang::TemplateName::getFromVoidPointer(Ptr);
     358                 :   }
     359                 : 
     360                 :   // No bits are available!
     361                 :   enum { NumLowBitsAvailable = 0 };
     362                 : };
     363                 : 
     364                 : } // end namespace llvm.
     365                 : 
     366                 : #endif

Generated: 2010-02-10 01:31 by zcov