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

          Line data    Source code
       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             : #include "llvm/Support/Compiler.h"
      21             : 
      22             : namespace clang {
      23             : 
      24             : class ASTContext;
      25             : class CXXRecordDecl;
      26             : class NamespaceAliasDecl;
      27             : class NamespaceDecl;
      28             : class IdentifierInfo;
      29             : struct PrintingPolicy;
      30             : class Type;
      31             : class TypeLoc;
      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), decltype specifier, or the global specifier ('::').
      42             : /// The last two specifiers can only appear at the start of a 
      43             : /// nested-namespace-specifier.
      44             : class NestedNameSpecifier : public llvm::FoldingSetNode {
      45             : 
      46             :   /// \brief Enumeration describing
      47             :   enum StoredSpecifierKind {
      48             :     StoredIdentifier = 0,
      49             :     StoredDecl = 1,
      50             :     StoredTypeSpec = 2,
      51             :     StoredTypeSpecWithTemplate = 3
      52             :   };
      53             : 
      54             :   /// \brief The nested name specifier that precedes this nested name
      55             :   /// specifier.
      56             :   ///
      57             :   /// The pointer is the nested-name-specifier that precedes this
      58             :   /// one. The integer stores one of the first four values of type
      59             :   /// SpecifierKind.
      60             :   llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
      61             : 
      62             :   /// \brief The last component in the nested name specifier, which
      63             :   /// can be an identifier, a declaration, or a type.
      64             :   ///
      65             :   /// When the pointer is NULL, this specifier represents the global
      66             :   /// specifier '::'. Otherwise, the pointer is one of
      67             :   /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
      68             :   /// specifier as encoded within the prefix.
      69             :   void* Specifier;
      70             : 
      71             : public:
      72             :   /// \brief The kind of specifier that completes this nested name
      73             :   /// specifier.
      74             :   enum SpecifierKind {
      75             :     /// \brief An identifier, stored as an IdentifierInfo*.
      76             :     Identifier,
      77             :     /// \brief A namespace, stored as a NamespaceDecl*.
      78             :     Namespace,
      79             :     /// \brief A namespace alias, stored as a NamespaceAliasDecl*.
      80             :     NamespaceAlias,
      81             :     /// \brief A type, stored as a Type*.
      82             :     TypeSpec,
      83             :     /// \brief A type that was preceded by the 'template' keyword,
      84             :     /// stored as a Type*.
      85             :     TypeSpecWithTemplate,
      86             :     /// \brief The global specifier '::'. There is no stored value.
      87             :     Global,
      88             :     /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
      89             :     /// the class it appeared in.
      90             :     Super
      91             :   };
      92             : 
      93             : private:
      94             :   /// \brief Builds the global specifier.
      95             :   NestedNameSpecifier()
      96             :     : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
      97             : 
      98             :   /// \brief Copy constructor used internally to clone nested name
      99             :   /// specifiers.
     100             :   NestedNameSpecifier(const NestedNameSpecifier &Other)
     101             :     : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
     102             :       Specifier(Other.Specifier) {
     103             :   }
     104             : 
     105             :   void operator=(const NestedNameSpecifier &) = delete;
     106             : 
     107             :   /// \brief Either find or insert the given nested name specifier
     108             :   /// mockup in the given context.
     109             :   static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
     110             :                                            const NestedNameSpecifier &Mockup);
     111             : 
     112             : public:
     113             :   /// \brief Builds a specifier combining a prefix and an identifier.
     114             :   ///
     115             :   /// The prefix must be dependent, since nested name specifiers
     116             :   /// referencing an identifier are only permitted when the identifier
     117             :   /// cannot be resolved.
     118             :   static NestedNameSpecifier *Create(const ASTContext &Context,
     119             :                                      NestedNameSpecifier *Prefix,
     120             :                                      IdentifierInfo *II);
     121             : 
     122             :   /// \brief Builds a nested name specifier that names a namespace.
     123             :   static NestedNameSpecifier *Create(const ASTContext &Context,
     124             :                                      NestedNameSpecifier *Prefix,
     125             :                                      const NamespaceDecl *NS);
     126             : 
     127             :   /// \brief Builds a nested name specifier that names a namespace alias.
     128             :   static NestedNameSpecifier *Create(const ASTContext &Context,
     129             :                                      NestedNameSpecifier *Prefix,
     130             :                                      NamespaceAliasDecl *Alias);
     131             : 
     132             :   /// \brief Builds a nested name specifier that names a type.
     133             :   static NestedNameSpecifier *Create(const ASTContext &Context,
     134             :                                      NestedNameSpecifier *Prefix,
     135             :                                      bool Template, const Type *T);
     136             : 
     137             :   /// \brief Builds a specifier that consists of just an identifier.
     138             :   ///
     139             :   /// The nested-name-specifier is assumed to be dependent, but has no
     140             :   /// prefix because the prefix is implied by something outside of the
     141             :   /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
     142             :   /// type.
     143             :   static NestedNameSpecifier *Create(const ASTContext &Context,
     144             :                                      IdentifierInfo *II);
     145             : 
     146             :   /// \brief Returns the nested name specifier representing the global
     147             :   /// scope.
     148             :   static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
     149             : 
     150             :   /// \brief Returns the nested name specifier representing the __super scope
     151             :   /// for the given CXXRecordDecl.
     152             :   static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
     153             :                                              CXXRecordDecl *RD);
     154             : 
     155             :   /// \brief Return the prefix of this nested name specifier.
     156             :   ///
     157             :   /// The prefix contains all of the parts of the nested name
     158             :   /// specifier that preced this current specifier. For example, for a
     159             :   /// nested name specifier that represents "foo::bar::", the current
     160             :   /// specifier will contain "bar::" and the prefix will contain
     161             :   /// "foo::".
     162           4 :   NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
     163             : 
     164             :   /// \brief Determine what kind of nested name specifier is stored.
     165             :   SpecifierKind getKind() const;
     166             : 
     167             :   /// \brief Retrieve the identifier stored in this nested name
     168             :   /// specifier.
     169             :   IdentifierInfo *getAsIdentifier() const {
     170             :     if (Prefix.getInt() == StoredIdentifier)
     171             :       return (IdentifierInfo *)Specifier;
     172             : 
     173             :     return nullptr;
     174             :   }
     175             : 
     176             :   /// \brief Retrieve the namespace stored in this nested name
     177             :   /// specifier.
     178             :   NamespaceDecl *getAsNamespace() const;
     179             : 
     180             :   /// \brief Retrieve the namespace alias stored in this nested name
     181             :   /// specifier.
     182             :   NamespaceAliasDecl *getAsNamespaceAlias() const;
     183             : 
     184             :   /// \brief Retrieve the record declaration stored in this nested name
     185             :   /// specifier.
     186             :   CXXRecordDecl *getAsRecordDecl() const;
     187             : 
     188             :   /// \brief Retrieve the type stored in this nested name specifier.
     189             :   const Type *getAsType() const {
     190           0 :     if (Prefix.getInt() == StoredTypeSpec ||
     191           0 :         Prefix.getInt() == StoredTypeSpecWithTemplate)
     192           0 :       return (const Type *)Specifier;
     193             : 
     194           0 :     return nullptr;
     195           0 :   }
     196             : 
     197             :   /// \brief Whether this nested name specifier refers to a dependent
     198             :   /// type or not.
     199             :   bool isDependent() const;
     200             : 
     201             :   /// \brief Whether this nested name specifier involves a template
     202             :   /// parameter.
     203             :   bool isInstantiationDependent() const;
     204             : 
     205             :   /// \brief Whether this nested-name-specifier contains an unexpanded
     206             :   /// parameter pack (for C++11 variadic templates).
     207             :   bool containsUnexpandedParameterPack() const;
     208             : 
     209             :   /// \brief Print this nested name specifier to the given output
     210             :   /// stream.
     211             :   void print(raw_ostream &OS, const PrintingPolicy &Policy) const;
     212             : 
     213             :   void Profile(llvm::FoldingSetNodeID &ID) const {
     214             :     ID.AddPointer(Prefix.getOpaqueValue());
     215             :     ID.AddPointer(Specifier);
     216             :   }
     217             : 
     218             :   /// \brief Dump the nested name specifier to standard output to aid
     219             :   /// in debugging.
     220             :   void dump(const LangOptions &LO);
     221             : };
     222             : 
     223             : /// \brief A C++ nested-name-specifier augmented with source location
     224             : /// information.
     225             : class NestedNameSpecifierLoc {
     226             :   NestedNameSpecifier *Qualifier;
     227             :   void *Data;
     228             : 
     229             :   /// \brief Determines the data length for the last component in the
     230             :   /// given nested-name-specifier.
     231             :   static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
     232             : 
     233             :   /// \brief Determines the data length for the entire
     234             :   /// nested-name-specifier.
     235             :   static unsigned getDataLength(NestedNameSpecifier *Qualifier);
     236             : 
     237             : public:
     238             :   /// \brief Construct an empty nested-name-specifier.
     239          57 :   NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
     240             : 
     241             :   /// \brief Construct a nested-name-specifier with source location information
     242             :   /// from
     243             :   NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
     244           4 :     : Qualifier(Qualifier), Data(Data) { }
     245             : 
     246             :   /// \brief Evalutes true when this nested-name-specifier location is
     247             :   /// non-empty.
     248          65 :   explicit operator bool() const { return Qualifier; }
     249             : 
     250             :   /// \brief Evalutes true when this nested-name-specifier location is
     251             :   /// empty.
     252             :   bool hasQualifier() const { return Qualifier; }
     253             : 
     254             :   /// \brief Retrieve the nested-name-specifier to which this instance
     255             :   /// refers.
     256             :   NestedNameSpecifier *getNestedNameSpecifier() const {
     257           4 :     return Qualifier;
     258             :   }
     259             : 
     260             :   /// \brief Retrieve the opaque pointer that refers to source-location data.
     261             :   void *getOpaqueData() const { return Data; }
     262             : 
     263             :   /// \brief Retrieve the source range covering the entirety of this
     264             :   /// nested-name-specifier.
     265             :   ///
     266             :   /// For example, if this instance refers to a nested-name-specifier
     267             :   /// \c \::std::vector<int>::, the returned source range would cover
     268             :   /// from the initial '::' to the last '::'.
     269             :   SourceRange getSourceRange() const LLVM_READONLY;
     270             : 
     271             :   /// \brief Retrieve the source range covering just the last part of
     272             :   /// this nested-name-specifier, not including the prefix.
     273             :   ///
     274             :   /// For example, if this instance refers to a nested-name-specifier
     275             :   /// \c \::std::vector<int>::, the returned source range would cover
     276             :   /// from "vector" to the last '::'.
     277             :   SourceRange getLocalSourceRange() const;
     278             : 
     279             :   /// \brief Retrieve the location of the beginning of this
     280             :   /// nested-name-specifier.
     281             :   SourceLocation getBeginLoc() const {
     282             :     return getSourceRange().getBegin();
     283             :   }
     284             : 
     285             :   /// \brief Retrieve the location of the end of this
     286             :   /// nested-name-specifier.
     287             :   SourceLocation getEndLoc() const {
     288             :     return getSourceRange().getEnd();
     289             :   }
     290             : 
     291             :   /// \brief Retrieve the location of the beginning of this
     292             :   /// component of the nested-name-specifier.
     293             :   SourceLocation getLocalBeginLoc() const {
     294             :     return getLocalSourceRange().getBegin();
     295             :   }
     296             : 
     297             :   /// \brief Retrieve the location of the end of this component of the
     298             :   /// nested-name-specifier.
     299             :   SourceLocation getLocalEndLoc() const {
     300             :     return getLocalSourceRange().getEnd();
     301             :   }
     302             : 
     303             :   /// \brief Return the prefix of this nested-name-specifier.
     304             :   ///
     305             :   /// For example, if this instance refers to a nested-name-specifier
     306             :   /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
     307             :   /// returned prefix may be empty, if this is the first component of
     308             :   /// the nested-name-specifier.
     309             :   NestedNameSpecifierLoc getPrefix() const {
     310           4 :     if (!Qualifier)
     311           0 :       return *this;
     312             : 
     313           4 :     return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
     314           4 :   }
     315             : 
     316             :   /// \brief For a nested-name-specifier that refers to a type,
     317             :   /// retrieve the type with source-location information.
     318             :   TypeLoc getTypeLoc() const;
     319             : 
     320             :   /// \brief Determines the data length for the entire
     321             :   /// nested-name-specifier.
     322             :   unsigned getDataLength() const { return getDataLength(Qualifier); }
     323             : 
     324             :   friend bool operator==(NestedNameSpecifierLoc X,
     325             :                          NestedNameSpecifierLoc Y) {
     326             :     return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
     327             :   }
     328             : 
     329             :   friend bool operator!=(NestedNameSpecifierLoc X,
     330             :                          NestedNameSpecifierLoc Y) {
     331             :     return !(X == Y);
     332             :   }
     333             : };
     334             : 
     335             : /// \brief Class that aids in the construction of nested-name-specifiers along
     336             : /// with source-location information for all of the components of the
     337             : /// nested-name-specifier.
     338             : class NestedNameSpecifierLocBuilder {
     339             :   /// \brief The current representation of the nested-name-specifier we're
     340             :   /// building.
     341             :   NestedNameSpecifier *Representation;
     342             : 
     343             :   /// \brief Buffer used to store source-location information for the
     344             :   /// nested-name-specifier.
     345             :   ///
     346             :   /// Note that we explicitly manage the buffer (rather than using a
     347             :   /// SmallVector) because \c Declarator expects it to be possible to memcpy()
     348             :   /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
     349             :   char *Buffer;
     350             : 
     351             :   /// \brief The size of the buffer used to store source-location information
     352             :   /// for the nested-name-specifier.
     353             :   unsigned BufferSize;
     354             : 
     355             :   /// \brief The capacity of the buffer used to store source-location
     356             :   /// information for the nested-name-specifier.
     357             :   unsigned BufferCapacity;
     358             : 
     359             : public:
     360             :   NestedNameSpecifierLocBuilder()
     361             :     : Representation(nullptr), Buffer(nullptr), BufferSize(0),
     362             :       BufferCapacity(0) {}
     363             : 
     364             :   NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
     365             : 
     366             :   NestedNameSpecifierLocBuilder &
     367             :   operator=(const NestedNameSpecifierLocBuilder &Other);
     368             : 
     369             :   ~NestedNameSpecifierLocBuilder() {
     370             :     if (BufferCapacity)
     371             :       free(Buffer);
     372             :   }
     373             : 
     374             :   /// \brief Retrieve the representation of the nested-name-specifier.
     375             :   NestedNameSpecifier *getRepresentation() const { return Representation; }
     376             : 
     377             :   /// \brief Extend the current nested-name-specifier by another
     378             :   /// nested-name-specifier component of the form 'type::'.
     379             :   ///
     380             :   /// \param Context The AST context in which this nested-name-specifier
     381             :   /// resides.
     382             :   ///
     383             :   /// \param TemplateKWLoc The location of the 'template' keyword, if present.
     384             :   ///
     385             :   /// \param TL The TypeLoc that describes the type preceding the '::'.
     386             :   ///
     387             :   /// \param ColonColonLoc The location of the trailing '::'.
     388             :   void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
     389             :               SourceLocation ColonColonLoc);
     390             : 
     391             :   /// \brief Extend the current nested-name-specifier by another
     392             :   /// nested-name-specifier component of the form 'identifier::'.
     393             :   ///
     394             :   /// \param Context The AST context in which this nested-name-specifier
     395             :   /// resides.
     396             :   ///
     397             :   /// \param Identifier The identifier.
     398             :   ///
     399             :   /// \param IdentifierLoc The location of the identifier.
     400             :   ///
     401             :   /// \param ColonColonLoc The location of the trailing '::'.
     402             :   void Extend(ASTContext &Context, IdentifierInfo *Identifier,
     403             :               SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
     404             : 
     405             :   /// \brief Extend the current nested-name-specifier by another
     406             :   /// nested-name-specifier component of the form 'namespace::'.
     407             :   ///
     408             :   /// \param Context The AST context in which this nested-name-specifier
     409             :   /// resides.
     410             :   ///
     411             :   /// \param Namespace The namespace.
     412             :   ///
     413             :   /// \param NamespaceLoc The location of the namespace name.
     414             :   ///
     415             :   /// \param ColonColonLoc The location of the trailing '::'.
     416             :   void Extend(ASTContext &Context, NamespaceDecl *Namespace,
     417             :               SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
     418             : 
     419             :   /// \brief Extend the current nested-name-specifier by another
     420             :   /// nested-name-specifier component of the form 'namespace-alias::'.
     421             :   ///
     422             :   /// \param Context The AST context in which this nested-name-specifier
     423             :   /// resides.
     424             :   ///
     425             :   /// \param Alias The namespace alias.
     426             :   ///
     427             :   /// \param AliasLoc The location of the namespace alias
     428             :   /// name.
     429             :   ///
     430             :   /// \param ColonColonLoc The location of the trailing '::'.
     431             :   void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
     432             :               SourceLocation AliasLoc, SourceLocation ColonColonLoc);
     433             : 
     434             :   /// \brief Turn this (empty) nested-name-specifier into the global
     435             :   /// nested-name-specifier '::'.
     436             :   void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
     437             :   
     438             :   /// \brief Turns this (empty) nested-name-specifier into '__super'
     439             :   /// nested-name-specifier.
     440             :   ///
     441             :   /// \param Context The AST context in which this nested-name-specifier
     442             :   /// resides.
     443             :   ///
     444             :   /// \param RD The declaration of the class in which nested-name-specifier
     445             :   /// appeared.
     446             :   ///
     447             :   /// \param SuperLoc The location of the '__super' keyword.
     448             :   /// name.
     449             :   ///
     450             :   /// \param ColonColonLoc The location of the trailing '::'.
     451             :   void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, 
     452             :                  SourceLocation SuperLoc, SourceLocation ColonColonLoc);
     453             :   /// \brief Make a new nested-name-specifier from incomplete source-location
     454             :   /// information.
     455             :   ///
     456             :   /// This routine should be used very, very rarely, in cases where we
     457             :   /// need to synthesize a nested-name-specifier. Most code should instead use
     458             :   /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
     459             :   void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
     460             :                    SourceRange R);
     461             : 
     462             :   /// \brief Adopt an existing nested-name-specifier (with source-range
     463             :   /// information).
     464             :   void Adopt(NestedNameSpecifierLoc Other);
     465             : 
     466             :   /// \brief Retrieve the source range covered by this nested-name-specifier.
     467             :   SourceRange getSourceRange() const LLVM_READONLY {
     468             :     return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
     469             :   }
     470             : 
     471             :   /// \brief Retrieve a nested-name-specifier with location information,
     472             :   /// copied into the given AST context.
     473             :   ///
     474             :   /// \param Context The context into which this nested-name-specifier will be
     475             :   /// copied.
     476             :   NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
     477             : 
     478             :   /// \brief Retrieve a nested-name-specifier with location
     479             :   /// information based on the information in this builder.
     480             :   ///
     481             :   /// This loc will contain references to the builder's internal data and may
     482             :   /// be invalidated by any change to the builder.
     483             :   NestedNameSpecifierLoc getTemporary() const {
     484             :     return NestedNameSpecifierLoc(Representation, Buffer);
     485             :   }
     486             : 
     487             :   /// \brief Clear out this builder, and prepare it to build another
     488             :   /// nested-name-specifier with source-location information.
     489             :   void Clear() {
     490             :     Representation = nullptr;
     491             :     BufferSize = 0;
     492             :   }
     493             : 
     494             :   /// \brief Retrieve the underlying buffer.
     495             :   ///
     496             :   /// \returns A pair containing a pointer to the buffer of source-location
     497             :   /// data and the size of the source-location data that resides in that
     498             :   /// buffer.
     499             :   std::pair<char *, unsigned> getBuffer() const {
     500             :     return std::make_pair(Buffer, BufferSize);
     501             :   }
     502             : };
     503             : 
     504             : /// Insertion operator for diagnostics.  This allows sending
     505             : /// NestedNameSpecifiers into a diagnostic with <<.
     506             : inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
     507             :                                            NestedNameSpecifier *NNS) {
     508             :   DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
     509             :                   DiagnosticsEngine::ak_nestednamespec);
     510             :   return DB;
     511             : }
     512             : 
     513             : }
     514             : 
     515             : #endif

Generated by: LCOV version 1.11