]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h
Merge ACPICA 20101209.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / NestedNameSpecifier.h
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
21 namespace llvm {
22   class raw_ostream;
23 }
24
25 namespace clang {
26
27 class ASTContext;
28 class NamespaceDecl;
29 class IdentifierInfo;
30 struct PrintingPolicy;
31 class Type;
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), or the global specifier ('::', must be the
42 /// first specifier).
43 class NestedNameSpecifier : public llvm::FoldingSetNode {
44   /// \brief The nested name specifier that precedes this nested name
45   /// specifier.
46   ///
47   /// The pointer is the nested-name-specifier that precedes this
48   /// one. The integer stores one of the first four values of type
49   /// SpecifierKind.
50   llvm::PointerIntPair<NestedNameSpecifier *, 2> Prefix;
51
52   /// \brief The last component in the nested name specifier, which
53   /// can be an identifier, a declaration, or a type.
54   ///
55   /// When the pointer is NULL, this specifier represents the global
56   /// specifier '::'. Otherwise, the pointer is one of
57   /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
58   /// specifier as encoded within the prefix.
59   void* Specifier;
60
61 public:
62   /// \brief The kind of specifier that completes this nested name
63   /// specifier.
64   enum SpecifierKind {
65     /// \brief An identifier, stored as an IdentifierInfo*.
66     Identifier = 0,
67     /// \brief A namespace, stored as a Namespace*.
68     Namespace = 1,
69     /// \brief A type, stored as a Type*.
70     TypeSpec = 2,
71     /// \brief A type that was preceded by the 'template' keyword,
72     /// stored as a Type*.
73     TypeSpecWithTemplate = 3,
74     /// \brief The global specifier '::'. There is no stored value.
75     Global = 4
76   };
77
78 private:
79   /// \brief Builds the global specifier.
80   NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
81
82   /// \brief Copy constructor used internally to clone nested name
83   /// specifiers.
84   NestedNameSpecifier(const NestedNameSpecifier &Other)
85     : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
86       Specifier(Other.Specifier) {
87   }
88
89   NestedNameSpecifier &operator=(const NestedNameSpecifier &); // do not implement
90
91   /// \brief Either find or insert the given nested name specifier
92   /// mockup in the given context.
93   static NestedNameSpecifier *FindOrInsert(ASTContext &Context,
94                                            const NestedNameSpecifier &Mockup);
95
96 public:
97   /// \brief Builds a specifier combining a prefix and an identifier.
98   ///
99   /// The prefix must be dependent, since nested name specifiers
100   /// referencing an identifier are only permitted when the identifier
101   /// cannot be resolved.
102   static NestedNameSpecifier *Create(ASTContext &Context,
103                                      NestedNameSpecifier *Prefix,
104                                      IdentifierInfo *II);
105
106   /// \brief Builds a nested name specifier that names a namespace.
107   static NestedNameSpecifier *Create(ASTContext &Context,
108                                      NestedNameSpecifier *Prefix,
109                                      NamespaceDecl *NS);
110
111   /// \brief Builds a nested name specifier that names a type.
112   static NestedNameSpecifier *Create(ASTContext &Context,
113                                      NestedNameSpecifier *Prefix,
114                                      bool Template, Type *T);
115
116   /// \brief Builds a specifier that consists of just an identifier.
117   ///
118   /// The nested-name-specifier is assumed to be dependent, but has no
119   /// prefix because the prefix is implied by something outside of the
120   /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
121   /// type.
122   static NestedNameSpecifier *Create(ASTContext &Context, IdentifierInfo *II);
123
124   /// \brief Returns the nested name specifier representing the global
125   /// scope.
126   static NestedNameSpecifier *GlobalSpecifier(ASTContext &Context);
127
128   /// \brief Return the prefix of this nested name specifier.
129   ///
130   /// The prefix contains all of the parts of the nested name
131   /// specifier that preced this current specifier. For example, for a
132   /// nested name specifier that represents "foo::bar::", the current
133   /// specifier will contain "bar::" and the prefix will contain
134   /// "foo::".
135   NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
136
137   /// \brief Determine what kind of nested name specifier is stored.
138   SpecifierKind getKind() const {
139     if (Specifier == 0)
140       return Global;
141     return (SpecifierKind)Prefix.getInt();
142   }
143
144   /// \brief Retrieve the identifier stored in this nested name
145   /// specifier.
146   IdentifierInfo *getAsIdentifier() const {
147     if (Prefix.getInt() == Identifier)
148       return (IdentifierInfo *)Specifier;
149
150     return 0;
151   }
152
153   /// \brief Retrieve the namespace stored in this nested name
154   /// specifier.
155   NamespaceDecl *getAsNamespace() const {
156     if (Prefix.getInt() == Namespace)
157       return (NamespaceDecl *)Specifier;
158
159     return 0;
160   }
161
162   /// \brief Retrieve the type stored in this nested name specifier.
163   Type *getAsType() const {
164     if (Prefix.getInt() == TypeSpec ||
165         Prefix.getInt() == TypeSpecWithTemplate)
166       return (Type *)Specifier;
167
168     return 0;
169   }
170
171   /// \brief Whether this nested name specifier refers to a dependent
172   /// type or not.
173   bool isDependent() const;
174
175   /// \brief Print this nested name specifier to the given output
176   /// stream.
177   void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
178
179   void Profile(llvm::FoldingSetNodeID &ID) const {
180     ID.AddPointer(Prefix.getOpaqueValue());
181     ID.AddPointer(Specifier);
182   }
183
184   /// \brief Dump the nested name specifier to standard output to aid
185   /// in debugging.
186   void dump(const LangOptions &LO);
187 };
188
189 /// Insertion operator for diagnostics.  This allows sending NestedNameSpecifiers
190 /// into a diagnostic with <<.
191 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
192                                            NestedNameSpecifier *NNS) {
193   DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
194                   Diagnostic::ak_nestednamespec);
195   return DB;
196 }
197
198 }
199
200 #endif