 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
83.3% |
10 / 12 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
100.0% |
12 / 12 |
| |
|
Line Coverage: |
96.6% |
28 / 29 |
| |
 |
|
 |
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 2309: 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 3446: NestedNameSpecifier() : Prefix(0, 0), Specifier(0) { }
81 :
82 : /// \brief Copy constructor used internally to clone nested name
83 : /// specifiers.
84 2280: NestedNameSpecifier(const NestedNameSpecifier &Other)
85 : : llvm::FoldingSetNode(Other), Prefix(Other.Prefix),
86 2280: Specifier(Other.Specifier) {
87 2280: }
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 2496: NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
136 :
137 : /// \brief Determine what kind of nested name specifier is stored.
138 24013: SpecifierKind getKind() const {
500: branch 0 taken
23513: branch 1 taken
139 24013: if (Specifier == 0)
140 500: return Global;
141 23513: return (SpecifierKind)Prefix.getInt();
142 : }
143 :
144 : /// \brief Retrieve the identifier stored in this nested name
145 : /// specifier.
146 119: IdentifierInfo *getAsIdentifier() const {
86: branch 1 taken
33: branch 2 taken
147 119: if (Prefix.getInt() == Identifier)
148 86: return (IdentifierInfo *)Specifier;
149 :
150 33: return 0;
151 : }
152 :
153 : /// \brief Retrieve the namespace stored in this nested name
154 : /// specifier.
155 1618: NamespaceDecl *getAsNamespace() const {
1618: branch 1 taken
0: branch 2 not taken
156 1618: if (Prefix.getInt() == Namespace)
157 1618: return (NamespaceDecl *)Specifier;
158 :
159 0: return 0;
160 : }
161 :
162 : /// \brief Retrieve the type stored in this nested name specifier.
163 22163: Type *getAsType() const {
180: branch 1 taken
21983: branch 2 taken
0: branch 4 not taken
180: branch 5 taken
21983: branch 6 taken
180: branch 7 taken
164 22163: if (Prefix.getInt() == TypeSpec ||
165 : Prefix.getInt() == TypeSpecWithTemplate)
166 21983: return (Type *)Specifier;
167 :
168 180: 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 5709: void Profile(llvm::FoldingSetNodeID &ID) const {
180 5709: ID.AddPointer(Prefix.getOpaqueValue());
181 5709: ID.AddPointer(Specifier);
182 5709: }
183 :
184 : void Destroy(ASTContext &Context);
185 :
186 : /// \brief Dump the nested name specifier to standard output to aid
187 : /// in debugging.
188 : void dump(const LangOptions &LO);
189 : };
190 :
191 : /// Insertion operator for diagnostics. This allows sending NestedNameSpecifiers
192 : /// into a diagnostic with <<.
193 : inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
194 17: NestedNameSpecifier *NNS) {
195 : DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
196 17: Diagnostic::ak_nestednamespec);
197 17: return DB;
198 : }
199 :
200 : }
201 :
202 : #endif
Generated: 2010-02-10 01:31 by zcov