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