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