LCOV - code coverage report
Current view: top level - clang/AST - TemplateName.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 0 8 0.0 %
Date: 2016-01-31 12:01:00 Functions: 0 6 0.0 %

          Line data    Source code
       1             : //===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : //  This file defines the TemplateName interface and subclasses.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_CLANG_AST_TEMPLATENAME_H
      15             : #define LLVM_CLANG_AST_TEMPLATENAME_H
      16             : 
      17             : #include "clang/Basic/LLVM.h"
      18             : #include "llvm/ADT/FoldingSet.h"
      19             : #include "llvm/ADT/PointerUnion.h"
      20             : 
      21             : namespace clang {
      22             :   
      23             : class ASTContext;
      24             : class DependentTemplateName;
      25             : class DiagnosticBuilder;
      26             : class IdentifierInfo;
      27             : class NamedDecl;
      28             : class NestedNameSpecifier;
      29             : enum OverloadedOperatorKind : int;
      30             : class OverloadedTemplateStorage;
      31             : struct PrintingPolicy;
      32             : class QualifiedTemplateName;
      33             : class SubstTemplateTemplateParmPackStorage;
      34             : class SubstTemplateTemplateParmStorage;
      35             : class TemplateArgument;
      36             : class TemplateDecl;
      37             : class TemplateTemplateParmDecl;
      38             :   
      39             : /// \brief Implementation class used to describe either a set of overloaded
      40             : /// template names or an already-substituted template template parameter pack.
      41             : class UncommonTemplateNameStorage {
      42             : protected:
      43             :   enum Kind {
      44             :     Overloaded,
      45             :     SubstTemplateTemplateParm,
      46             :     SubstTemplateTemplateParmPack
      47             :   };
      48             : 
      49             :   struct BitsTag {
      50             :     /// \brief A Kind.
      51             :     unsigned Kind : 2;
      52             :     
      53             :     /// \brief The number of stored templates or template arguments,
      54             :     /// depending on which subclass we have.
      55             :     unsigned Size : 30;
      56             :   };
      57             : 
      58             :   union {
      59             :     struct BitsTag Bits;
      60             :     void *PointerAlignment;
      61             :   };
      62             :   
      63             :   UncommonTemplateNameStorage(Kind kind, unsigned size) {
      64             :     Bits.Kind = kind;
      65             :     Bits.Size = size;
      66             :   }
      67             :   
      68             : public:
      69             :   unsigned size() const { return Bits.Size; }
      70             :   
      71             :   OverloadedTemplateStorage *getAsOverloadedStorage()  {
      72             :     return Bits.Kind == Overloaded
      73             :              ? reinterpret_cast<OverloadedTemplateStorage *>(this) 
      74             :              : nullptr;
      75             :   }
      76             :   
      77             :   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
      78             :     return Bits.Kind == SubstTemplateTemplateParm
      79             :              ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
      80             :              : nullptr;
      81             :   }
      82             : 
      83             :   SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
      84             :     return Bits.Kind == SubstTemplateTemplateParmPack
      85             :              ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
      86             :              : nullptr;
      87             :   }
      88             : };
      89             :   
      90             : /// \brief A structure for storing the information associated with an
      91             : /// overloaded template name.
      92             : class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
      93             :   friend class ASTContext;
      94             : 
      95             :   OverloadedTemplateStorage(unsigned size) 
      96             :     : UncommonTemplateNameStorage(Overloaded, size) { }
      97             : 
      98             :   NamedDecl **getStorage() {
      99             :     return reinterpret_cast<NamedDecl **>(this + 1);
     100             :   }
     101             :   NamedDecl * const *getStorage() const {
     102             :     return reinterpret_cast<NamedDecl *const *>(this + 1);
     103             :   }
     104             : 
     105             : public:
     106             :   typedef NamedDecl *const *iterator;
     107             : 
     108             :   iterator begin() const { return getStorage(); }
     109             :   iterator end() const { return getStorage() + size(); }
     110             : };
     111             : 
     112             : /// \brief A structure for storing an already-substituted template template
     113             : /// parameter pack.
     114             : ///
     115             : /// This kind of template names occurs when the parameter pack has been 
     116             : /// provided with a template template argument pack in a context where its
     117             : /// enclosing pack expansion could not be fully expanded.
     118             : class SubstTemplateTemplateParmPackStorage
     119             :   : public UncommonTemplateNameStorage, public llvm::FoldingSetNode
     120             : {
     121             :   TemplateTemplateParmDecl *Parameter;
     122             :   const TemplateArgument *Arguments;
     123             :   
     124             : public:
     125             :   SubstTemplateTemplateParmPackStorage(TemplateTemplateParmDecl *Parameter,
     126             :                                        unsigned Size, 
     127             :                                        const TemplateArgument *Arguments)
     128             :     : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Size),
     129             :       Parameter(Parameter), Arguments(Arguments) { }
     130             :   
     131             :   /// \brief Retrieve the template template parameter pack being substituted.
     132             :   TemplateTemplateParmDecl *getParameterPack() const {
     133             :     return Parameter;
     134             :   }
     135             :   
     136             :   /// \brief Retrieve the template template argument pack with which this
     137             :   /// parameter was substituted.
     138             :   TemplateArgument getArgumentPack() const;
     139             :   
     140             :   void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context);
     141             :   
     142             :   static void Profile(llvm::FoldingSetNodeID &ID,
     143             :                       ASTContext &Context,
     144             :                       TemplateTemplateParmDecl *Parameter,
     145             :                       const TemplateArgument &ArgPack);
     146             : };
     147             : 
     148             : /// \brief Represents a C++ template name within the type system.
     149             : ///
     150             : /// A C++ template name refers to a template within the C++ type
     151             : /// system. In most cases, a template name is simply a reference to a
     152             : /// class template, e.g.
     153             : ///
     154             : /// \code
     155             : /// template<typename T> class X { };
     156             : ///
     157             : /// X<int> xi;
     158             : /// \endcode
     159             : ///
     160             : /// Here, the 'X' in \c X<int> is a template name that refers to the
     161             : /// declaration of the class template X, above. Template names can
     162             : /// also refer to function templates, C++0x template aliases, etc.
     163             : ///
     164             : /// Some template names are dependent. For example, consider:
     165             : ///
     166             : /// \code
     167             : /// template<typename MetaFun, typename T1, typename T2> struct apply2 {
     168             : ///   typedef typename MetaFun::template apply<T1, T2>::type type;
     169             : /// };
     170             : /// \endcode
     171             : ///
     172             : /// Here, "apply" is treated as a template name within the typename
     173             : /// specifier in the typedef. "apply" is a nested template, and can
     174             : /// only be understood in the context of
     175             : class TemplateName {
     176             :   typedef llvm::PointerUnion4<TemplateDecl *,
     177             :                               UncommonTemplateNameStorage *,
     178             :                               QualifiedTemplateName *,
     179             :                               DependentTemplateName *> StorageType;
     180             : 
     181             :   StorageType Storage;
     182             : 
     183           0 :   explicit TemplateName(void *Ptr) {
     184           0 :     Storage = StorageType::getFromOpaqueValue(Ptr);
     185           0 :   }
     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 nullptr;
     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 nullptr;
     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 nullptr;
     274             :   }
     275             : 
     276             :   /// \brief Retrieve the underlying qualified template name
     277             :   /// structure, if any.
     278             :   QualifiedTemplateName *getAsQualifiedTemplateName() const {
     279           0 :     return Storage.dyn_cast<QualifiedTemplateName *>();
     280             :   }
     281             : 
     282             :   /// \brief Retrieve the underlying dependent template name
     283             :   /// structure, if any.
     284             :   DependentTemplateName *getAsDependentTemplateName() const {
     285           0 :     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           0 :     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           0 :   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           0 :   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

Generated by: LCOV version 1.11