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


Files: 1 Branches Taken: 83.3% 10 / 12
Generated: 2010-02-10 01:31 Branches Executed: 100.0% 12 / 12
Line Coverage: 96.6% 28 / 29


Programs: 21 Runs 33077


       1                 : //===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- 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 NestedNameSpecifier class, which represents
      11                 : //  a C++ nested-name-specifier.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
      15                 : #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
      16                 : 
      17                 : #include "clang/Basic/Diagnostic.h"
      18                 : #include "llvm/ADT/FoldingSet.h"
      19                 : #include "llvm/ADT/PointerIntPair.h"
      20                 : 
      21                 : namespace llvm {
      22                 :   class raw_ostream;
      23                 : }
      24                 : 
      25                 : namespace clang {
      26                 : 
      27                 : class ASTContext;
      28                 : class NamespaceDecl;
      29                 : class IdentifierInfo;
      30                 : struct PrintingPolicy;
      31                 : class Type;
      32                 : class LangOptions;
      33                 : 
      34                 : /// \brief Represents a C++ nested name specifier, such as
      35                 : /// "::std::vector<int>::".
      36                 : ///
      37                 : /// C++ nested name specifiers are the prefixes to qualified
      38                 : /// namespaces. For example, "foo::" in "foo::x" is a nested name
      39                 : /// specifier. Nested name specifiers are made up of a sequence of
      40                 : /// specifiers, each of which can be a namespace, type, identifier
      41                 : /// (for dependent names), or the global specifier ('::', must be the
      42                 : /// first specifier).
      43             2309: class NestedNameSpecifier : public llvm::FoldingSetNode {
      44                 :   /// \brief The nested name specifier that precedes this nested name
      45                 :   /// specifier.
      46                 :   ///
      47                 :   /// The pointer is the nested-name-specifier that precedes this
      48                 :   /// one. The integer stores one of the first four values of type
      49                 :   /// SpecifierKind.
      50                 :   llvm::PointerIntPair<NestedNameSpecifier *, 2> Prefix;
      51                 : 
      52                 :   /// \brief The last component in the nested name specifier, which
      53                 :   /// can be an identifier, a declaration, or a type.
      54                 :   ///
      55                 :   /// When the pointer is NULL, this specifier represents the global
      56                 :   /// specifier '::'. Otherwise, the pointer is one of
      57                 :   /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
      58                 :   /// specifier as encoded within the prefix.
      59                 :   void* Specifier;
      60                 : 
      61                 : public:
      62                 :   /// \brief The kind of specifier that completes this nested name
      63                 :   /// specifier.
      64                 :   enum SpecifierKind {
      65                 :     /// \brief An identifier, stored as an IdentifierInfo*.
      66                 :     Identifier = 0,
      67                 :     /// \brief A namespace, stored as a Namespace*.
      68                 :     Namespace = 1,
      69                 :     /// \brief A type, stored as a Type*.
      70                 :     TypeSpec = 2,
      71                 :     /// \brief A type that was preceded by the 'template' keyword,
      72                 :     /// stored as a Type*.
      73                 :     TypeSpecWithTemplate = 3,
      74                 :     /// \brief The global specifier '::'. There is no stored value.
      75                 :     Global = 4
      76                 :   };
      77                 : 
      78                 : private:
      79                 :   /// \brief Builds the global specifier.
      80             3446:   NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
      81                 : 
      82                 :   /// \brief Copy constructor used internally to clone nested name
      83                 :   /// specifiers.
      84             2280:   NestedNameSpecifier(const NestedNameSpecifier &Other)
      85                 :     : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
      86             2280:       Specifier(Other.Specifier) {
      87             2280:   }
      88                 : 
      89                 :   NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
      90                 : 
      91                 :   /// \brief Either find or insert the given nested name specifier
      92                 :   /// mockup in the given context.
      93                 :   static NestedNameSpecifier *FindOrInsert(ASTContext &Context,
      94                 :                                            const NestedNameSpecifier &Mockup);
      95                 : 
      96                 : public:
      97                 :   /// \brief Builds a specifier combining a prefix and an identifier.
      98                 :   ///
      99                 :   /// The prefix must be dependent, since nested name specifiers
     100                 :   /// referencing an identifier are only permitted when the identifier
     101                 :   /// cannot be resolved.
     102                 :   static NestedNameSpecifier *Create(ASTContext &Context,
     103                 :                                      NestedNameSpecifier *Prefix,
     104                 :                                      IdentifierInfo *II);
     105                 : 
     106                 :   /// \brief Builds a nested name specifier that names a namespace.
     107                 :   static NestedNameSpecifier *Create(ASTContext &Context,
     108                 :                                      NestedNameSpecifier *Prefix,
     109                 :                                      NamespaceDecl *NS);
     110                 : 
     111                 :   /// \brief Builds a nested name specifier that names a type.
     112                 :   static NestedNameSpecifier *Create(ASTContext &Context,
     113                 :                                      NestedNameSpecifier *Prefix,
     114                 :                                      bool Template, Type *T);
     115                 : 
     116                 :   /// \brief Builds a specifier that consists of just an identifier.
     117                 :   ///
     118                 :   /// The nested-name-specifier is assumed to be dependent, but has no
     119                 :   /// prefix because the prefix is implied by something outside of the
     120                 :   /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
     121                 :   /// type.
     122                 :   static NestedNameSpecifier *Create(ASTContext &Context, IdentifierInfo *II);
     123                 : 
     124                 :   /// \brief Returns the nested name specifier representing the global
     125                 :   /// scope.
     126                 :   static NestedNameSpecifier *GlobalSpecifier(ASTContext &Context);
     127                 : 
     128                 :   /// \brief Return the prefix of this nested name specifier.
     129                 :   ///
     130                 :   /// The prefix contains all of the parts of the nested name
     131                 :   /// specifier that preced this current specifier. For example, for a
     132                 :   /// nested name specifier that represents "foo::bar::", the current
     133                 :   /// specifier will contain "bar::" and the prefix will contain
     134                 :   /// "foo::".
     135             2496:   NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
     136                 : 
     137                 :   /// \brief Determine what kind of nested name specifier is stored.
     138            24013:   SpecifierKind getKind() const {
                      500: branch 0 taken
                    23513: branch 1 taken
     139            24013:     if (Specifier == 0)
     140              500:       return Global;
     141            23513:     return (SpecifierKind)Prefix.getInt();
     142                 :   }
     143                 : 
     144                 :   /// \brief Retrieve the identifier stored in this nested name
     145                 :   /// specifier.
     146              119:   IdentifierInfo *getAsIdentifier() const {
                       86: branch 1 taken
                       33: branch 2 taken
     147              119:     if (Prefix.getInt() == Identifier)
     148               86:       return (IdentifierInfo *)Specifier;
     149                 : 
     150               33:     return 0;
     151                 :   }
     152                 : 
     153                 :   /// \brief Retrieve the namespace stored in this nested name
     154                 :   /// specifier.
     155             1618:   NamespaceDecl *getAsNamespace() const {
                     1618: branch 1 taken
                        0: branch 2 not taken
     156             1618:     if (Prefix.getInt() == Namespace)
     157             1618:       return (NamespaceDecl *)Specifier;
     158                 : 
     159                0:     return 0;
     160                 :   }
     161                 : 
     162                 :   /// \brief Retrieve the type stored in this nested name specifier.
     163            22163:   Type *getAsType() const {
                      180: branch 1 taken
                    21983: branch 2 taken
                        0: branch 4 not taken
                      180: branch 5 taken
                    21983: branch 6 taken
                      180: branch 7 taken
     164            22163:     if (Prefix.getInt() == TypeSpec ||
     165                 :         Prefix.getInt() == TypeSpecWithTemplate)
     166            21983:       return (Type *)Specifier;
     167                 : 
     168              180:     return 0;
     169                 :   }
     170                 : 
     171                 :   /// \brief Whether this nested name specifier refers to a dependent
     172                 :   /// type or not.
     173                 :   bool isDependent() const;
     174                 : 
     175                 :   /// \brief Print this nested name specifier to the given output
     176                 :   /// stream.
     177                 :   void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
     178                 : 
     179             5709:   void Profile(llvm::FoldingSetNodeID &ID) const {
     180             5709:     ID.AddPointer(Prefix.getOpaqueValue());
     181             5709:     ID.AddPointer(Specifier);
     182             5709:   }
     183                 : 
     184                 :   void Destroy(ASTContext &Context);
     185                 : 
     186                 :   /// \brief Dump the nested name specifier to standard output to aid
     187                 :   /// in debugging.
     188                 :   void dump(const LangOptions &LO);
     189                 : };
     190                 : 
     191                 : /// Insertion operator for diagnostics.  This allows sending NestedNameSpecifiers
     192                 : /// into a diagnostic with <<.
     193                 : inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
     194               17:                                            NestedNameSpecifier *NNS) {
     195                 :   DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
     196               17:                   Diagnostic::ak_nestednamespec);
     197               17:   return DB;
     198                 : }
     199                 : 
     200                 : }
     201                 : 
     202                 : #endif

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