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