NestedNameSpecifier.h revision d249e1d1f1498b81314459ceda19d6ff25c278ad
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 NamespaceDecl;
28ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorclass IdentifierInfo;
29d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregorclass PrintingPolicy;
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.
441734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  ///
451734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// The pointer is the nested-name-specifier that precedes this
461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// one. The integer stores one of the first four values of type
471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// SpecifierKind.
481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  llvm::PointerIntPair<NestedNameSpecifier *, 2> Prefix;
49ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
50ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The last component in the nested name specifier, which
51ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// can be an identifier, a declaration, or a type.
52ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  ///
53ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// When the pointer is NULL, this specifier represents the global
54ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier '::'. Otherwise, the pointer is one of
55ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  /// specifier as encoded within the prefix.
571734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  void* Specifier;
58e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
59e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorpublic:
60ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief The kind of specifier that completes this nested name
61ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
62ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  enum SpecifierKind {
63ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief An identifier, stored as an IdentifierInfo*.
64ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Identifier = 0,
65ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A namespace, stored as a Namespace*.
66ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Namespace = 1,
67ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type, stored as a Type*.
68ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    TypeSpec = 2,
69ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief A type that was preceded by the 'template' keyword,
70ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// stored as a Type*.
71ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    TypeSpecWithTemplate = 3,
72ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    /// \brief The global specifier '::'. There is no stored value.
73ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Global = 4
74ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  };
75ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
76ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorprivate:
77ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds the global specifier.
781734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
79ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
80ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Copy constructor used internally to clone nested name
81ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifiers.
82ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier(const NestedNameSpecifier &Other)
83ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
84ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      Specifier(Other.Specifier) {
85e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
86e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
87ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
88e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
89ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Either find or insert the given nested name specifier
90ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// mockup in the given context.
911734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  static NestedNameSpecifier *FindOrInsert(ASTContext &Context,
921734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor                                           const NestedNameSpecifier &Mockup);
93e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorpublic:
95ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a specifier combining a prefix and an identifier.
96e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
97ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix must be dependent, since nested name specifiers
98ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// referencing an identifier are only permitted when the identifier
99ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// cannot be resolved.
100ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  static NestedNameSpecifier *Create(ASTContext &Context,
101ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     NestedNameSpecifier *Prefix,
102ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     IdentifierInfo *II);
103ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
104ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a namespace.
105ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  static NestedNameSpecifier *Create(ASTContext &Context,
106ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     NestedNameSpecifier *Prefix,
107ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     NamespaceDecl *NS);
108ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
109ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Builds a nested name specifier that names a type.
110ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  static NestedNameSpecifier *Create(ASTContext &Context,
111ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     NestedNameSpecifier *Prefix,
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                     bool Template, Type *T);
113ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
114ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Returns the nested name specifier representing the global
115ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// scope.
116ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  static NestedNameSpecifier *GlobalSpecifier(ASTContext &Context);
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
118ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Return the prefix of this nested name specifier.
119e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  ///
120ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// The prefix contains all of the parts of the nested name
121ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier that preced this current specifier. For example, for a
122ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// nested name specifier that represents "foo::bar::", the current
123ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier will contain "bar::" and the prefix will contain
124ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// "foo::".
1251734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
126ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
127ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Determine what kind of nested name specifier is stored.
128ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  SpecifierKind getKind() const {
1291734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (Specifier == 0)
130ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      return Global;
1311734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    return (SpecifierKind)Prefix.getInt();
132ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
133e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
134ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the identifier stored in this nested name
135ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
136ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  IdentifierInfo *getAsIdentifier() const {
1371734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (Prefix.getInt() == Identifier)
1381734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (IdentifierInfo *)Specifier;
139e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
140e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor    return 0;
141e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
142ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
143ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the namespace stored in this nested name
144ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// specifier.
145ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NamespaceDecl *getAsNamespace() const {
1461734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (Prefix.getInt() == Namespace)
1471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (NamespaceDecl *)Specifier;
148e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return 0;
150e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
151e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
152ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Retrieve the type stored in this nested name specifier.
153ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  Type *getAsType() const {
1541734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    if (Prefix.getInt() == TypeSpec ||
1551734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor        Prefix.getInt() == TypeSpecWithTemplate)
1561734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor      return (Type *)Specifier;
157ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
158ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return 0;
159ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
160ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
161ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Whether this nested name specifier refers to a dependent
162ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// type or not.
163ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  bool isDependent() const;
164ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
165ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// \brief Print this nested name specifier to the given output
166ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  /// stream.
167d249e1d1f1498b81314459ceda19d6ff25c278adDouglas Gregor  void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
168e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
169ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Profile(llvm::FoldingSetNodeID &ID) const {
1701734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Prefix.getOpaqueValue());
1711734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    ID.AddPointer(Specifier);
172e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor  }
173bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
174ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void Destroy(ASTContext &Context);
175d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
176d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// \brief Dump the nested name specifier to standard output to aid
177d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  /// in debugging.
1789bde77309fd2f9f7a53446e374472c48c81f5182Douglas Gregor  void dump();
179e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor};
180e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
181e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor}
182e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
183e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#endif
184