13
13
// ===----------------------------------------------------------------------===//
14
14
15
15
#include " IdentifierResolver.h"
16
- #include " clang/Basic/IdentifierTable.h"
17
- #include " clang/AST/Decl.h"
18
- #include " clang/Parse/Scope.h"
19
16
#include < list>
20
17
#include < vector>
21
18
22
19
using namespace clang ;
23
20
24
- namespace {
25
-
26
- class IdDeclInfo ;
27
-
28
- // / Identifier's FETokenInfo contains a Decl pointer if lower bit == 0.
29
- static inline bool isDeclPtr (void *Ptr) {
30
- return (reinterpret_cast <uintptr_t >(Ptr) & 0x1 ) == 0 ;
31
- }
32
-
33
- // / Identifier's FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
34
- static inline IdDeclInfo *toIdDeclInfo (void *Ptr) {
35
- return reinterpret_cast <IdDeclInfo*>(
36
- reinterpret_cast <uintptr_t >(Ptr) & ~0x1
37
- );
38
- }
39
-
40
-
41
- // / IdDeclInfo - Keeps track of information about decls associated to a
42
- // / particular identifier. IdDeclInfos are lazily constructed and assigned
43
- // / to an identifier the first time a decl with that identifier is shadowed
44
- // / in some scope.
45
- class IdDeclInfo {
46
- typedef llvm::SmallVector<NamedDecl *, 2 > ShadowedTy;
47
- ShadowedTy ShadowedDecls;
48
-
49
- public:
50
- typedef ShadowedTy::iterator ShadowedIter;
51
-
52
- inline ShadowedIter shadowed_begin () { return ShadowedDecls.begin (); }
53
- inline ShadowedIter shadowed_end () { return ShadowedDecls.end (); }
54
-
55
- // / Add a decl in the scope chain.
56
- void PushShadowed (NamedDecl *D) {
57
- assert (D && " Decl null" );
58
- ShadowedDecls.push_back (D);
59
- }
60
-
61
- // / Add the decl at the top of scope chain.
62
- void PushGlobalShadowed (NamedDecl *D) {
63
- assert (D && " Decl null" );
64
- ShadowedDecls.insert (ShadowedDecls.begin (), D);
65
- }
66
-
67
- // / RemoveShadowed - Remove the decl from the scope chain.
68
- // / The decl must already be part of the decl chain.
69
- void RemoveShadowed (NamedDecl *D);
70
- };
71
-
72
21
73
22
// / IdDeclInfoMap - Associates IdDeclInfos with Identifiers.
74
23
// / Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
75
24
// / individual IdDeclInfo to heap.
76
- class IdDeclInfoMap {
25
+ class IdentifierResolver :: IdDeclInfoMap {
77
26
static const unsigned int VECTOR_SIZE = 512 ;
78
27
// Holds vectors of IdDeclInfos that serve as 'pools'.
79
28
// New vectors are added when the current one is full.
@@ -88,17 +37,14 @@ class IdDeclInfoMap {
88
37
IdDeclInfo &operator [](IdentifierInfo *II);
89
38
};
90
39
91
- } // end anonymous namespace
92
-
93
40
94
41
IdentifierResolver::IdentifierResolver () : IdDeclInfos(new IdDeclInfoMap) {}
95
42
IdentifierResolver::~IdentifierResolver () {
96
- delete static_cast <IdDeclInfoMap*>( IdDeclInfos) ;
43
+ delete IdDeclInfos;
97
44
}
98
45
99
46
// / AddDecl - Link the decl to its shadowed decl chain.
100
- void IdentifierResolver::AddDecl (NamedDecl *D, Scope *S) {
101
- assert (D && S && " null param passed" );
47
+ void IdentifierResolver::AddDecl (NamedDecl *D) {
102
48
IdentifierInfo *II = D->getIdentifier ();
103
49
void *Ptr = II->getFETokenInfo <void >();
104
50
@@ -111,56 +57,40 @@ void IdentifierResolver::AddDecl(NamedDecl *D, Scope *S) {
111
57
112
58
if (isDeclPtr (Ptr)) {
113
59
II->setFETokenInfo (NULL );
114
- IdDeclInfoMap &Map = * static_cast <IdDeclInfoMap*>( IdDeclInfos);
115
- IDI = &Map[II] ;
116
- IDI->PushShadowed ( static_cast <NamedDecl*>(Ptr) );
60
+ IDI = &(* IdDeclInfos)[II] ;
61
+ NamedDecl *PrevD = static_cast <NamedDecl*>(Ptr) ;
62
+ IDI->AddDecl (PrevD );
117
63
} else
118
64
IDI = toIdDeclInfo (Ptr);
119
65
120
- // C++ [basic.scope]p4:
121
- // -- exactly one declaration shall declare a class name or
122
- // enumeration name that is not a typedef name and the other
123
- // declarations shall all refer to the same object or
124
- // enumerator, or all refer to functions and function templates;
125
- // in this case the class name or enumeration name is hidden.
126
- if (isa<TagDecl>(D) && IDI->shadowed_end () != IDI->shadowed_begin ()) {
127
- // We are pushing the name of a tag (enum or class).
128
- IdDeclInfo::ShadowedIter TopIter = IDI->shadowed_end () - 1 ;
129
- if (S->isDeclScope (*TopIter)) {
130
- // There is already a declaration with the same name in the same
131
- // scope. It must be found before we find the new declaration,
132
- // so swap the order on the shadowed declaration stack.
133
- NamedDecl *Temp = *TopIter;
134
- *TopIter = D;
135
- D = Temp;
136
- }
137
- }
138
-
139
- IDI->PushShadowed (D);
66
+ IDI->AddDecl (D);
140
67
}
141
68
142
- // / AddGlobalDecl - Link the decl at the top of the shadowed decl chain.
143
- void IdentifierResolver::AddGlobalDecl (NamedDecl *D) {
144
- assert (D && " null param passed" );
69
+ // / AddShadowedDecl - Link the decl to its shadowed decl chain putting it
70
+ // / after the decl that the iterator points to, thus the 'CIT' decl will be
71
+ // / encountered before the 'D' decl.
72
+ void IdentifierResolver::AddShadowedDecl (NamedDecl *D, NamedDecl *Shadow) {
73
+ assert (D->getIdentifier () == Shadow->getIdentifier () && " Different ids!" );
74
+ assert (LookupContext (D) == LookupContext (Shadow) && " Different context!" );
75
+
145
76
IdentifierInfo *II = D->getIdentifier ();
146
77
void *Ptr = II->getFETokenInfo <void >();
147
-
148
- if (!Ptr) {
149
- II->setFETokenInfo (D);
150
- return ;
151
- }
78
+ assert (Ptr && " No decl from Ptr ?" );
152
79
153
80
IdDeclInfo *IDI;
154
81
155
82
if (isDeclPtr (Ptr)) {
156
83
II->setFETokenInfo (NULL );
157
- IdDeclInfoMap &Map = *static_cast <IdDeclInfoMap*>(IdDeclInfos);
158
- IDI = &Map[II];
159
- IDI->PushShadowed (static_cast <NamedDecl*>(Ptr));
160
- } else
161
- IDI = toIdDeclInfo (Ptr);
84
+ IDI = &(*IdDeclInfos)[II];
85
+ NamedDecl *PrevD = static_cast <NamedDecl*>(Ptr);
86
+ assert (PrevD == Shadow && " Invalid shadow decl ?" );
87
+ IDI->AddDecl (D);
88
+ IDI->AddDecl (PrevD);
89
+ return ;
90
+ }
162
91
163
- IDI->PushGlobalShadowed (D);
92
+ IDI = toIdDeclInfo (Ptr);
93
+ IDI->AddShadowed (D, Shadow);
164
94
}
165
95
166
96
// / RemoveDecl - Unlink the decl from its shadowed decl chain.
@@ -178,71 +108,72 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
178
108
return ;
179
109
}
180
110
181
- return toIdDeclInfo (Ptr)->RemoveShadowed (D);
111
+ return toIdDeclInfo (Ptr)->RemoveDecl (D);
182
112
}
183
113
184
- // / Lookup - Find the non-shadowed decl that belongs to a particular
185
- // / Decl::IdentifierNamespace.
186
- NamedDecl *IdentifierResolver::Lookup (const IdentifierInfo *II, unsigned NS) {
187
- assert (II && " null param passed" );
114
+ // / begin - Returns an iterator for all decls, starting at the given
115
+ // / declaration context.
116
+ IdentifierResolver::iterator
117
+ IdentifierResolver::begin (const IdentifierInfo *II, DeclContext *Ctx) {
118
+ assert (Ctx && " null param passed" );
119
+
188
120
void *Ptr = II->getFETokenInfo <void >();
121
+ if (!Ptr) return end (II);
189
122
190
- if (!Ptr) return NULL ;
123
+ LookupContext LC (Ctx) ;
191
124
192
125
if (isDeclPtr (Ptr)) {
193
126
NamedDecl *D = static_cast <NamedDecl*>(Ptr);
194
- return (D->getIdentifierNamespace () & NS) ? D : NULL ;
195
- }
196
127
197
- IdDeclInfo *IDI = toIdDeclInfo (Ptr);
128
+ if (LC.isEqOrContainedBy (LookupContext (D)))
129
+ return iterator (D);
130
+ else
131
+ return end (II);
198
132
199
- // ShadowedDecls are ordered from most shadowed to less shadowed.
200
- // So we do a reverse iteration from end to begin.
201
- for (IdDeclInfo::ShadowedIter SI = IDI->shadowed_end ();
202
- SI != IDI->shadowed_begin (); --SI) {
203
- NamedDecl *D = *(SI-1 );
204
- if (D->getIdentifierNamespace () & NS)
205
- return D;
206
133
}
207
-
208
- // we didn't find the decl.
209
- return NULL ;
134
+
135
+ IdDeclInfo *IDI = toIdDeclInfo (Ptr);
136
+ return iterator (IDI-> FindContext (LC)) ;
210
137
}
211
138
212
- // / RemoveShadowed - Remove the decl from the scope chain.
213
- // / The decl must already be part of the decl chain.
214
- void IdDeclInfo::RemoveShadowed (NamedDecl *D) {
215
- assert (D && " null decl passed" );
216
- assert (!ShadowedDecls.empty () &&
217
- " Didn't find this decl on its identifier's chain!" );
218
-
219
- // common case
220
- if (D == ShadowedDecls.back ()) {
221
- ShadowedDecls.pop_back ();
222
- return ;
223
- }
139
+ // / ctx_begin - Returns an iterator for only decls that belong to the given
140
+ // / declaration context.
141
+ IdentifierResolver::ctx_iterator
142
+ IdentifierResolver::ctx_begin (const IdentifierInfo *II, DeclContext *Ctx) {
143
+ assert (Ctx && " null param passed" );
144
+
145
+ void *Ptr = II->getFETokenInfo <void >();
146
+ if (!Ptr) return ctx_end (II);
147
+
148
+ LookupContext LC (Ctx);
149
+
150
+ if (isDeclPtr (Ptr)) {
151
+ NamedDecl *D = static_cast <NamedDecl*>(Ptr);
152
+
153
+ if (LC == LookupContext (D))
154
+ return ctx_iterator (D);
155
+ else
156
+ return ctx_end (II);
224
157
225
- for (ShadowedIter SI = ShadowedDecls.end ()-1 ;
226
- SI != ShadowedDecls.begin (); --SI) {
227
- if (*(SI-1 ) == D) {
228
- ShadowedDecls.erase (SI-1 );
229
- return ;
230
- }
231
158
}
159
+
160
+ IdDeclInfo *IDI = toIdDeclInfo (Ptr);
161
+ IdDeclInfo::DeclsTy::iterator I = IDI->FindContext (LookupContext (Ctx));
162
+ if (I != IDI->decls_begin () && LC != LookupContext (*(I-1 )))
163
+ I = IDI->decls_begin ();
232
164
233
- assert ( false && " Didn't find this decl on its identifier's chain! " );
165
+ return ctx_iterator (I );
234
166
}
235
167
168
+
236
169
// / Returns the IdDeclInfo associated to the IdentifierInfo.
237
170
// / It creates a new IdDeclInfo if one was not created before for this id.
238
- IdDeclInfo &IdDeclInfoMap::operator [](IdentifierInfo *II) {
171
+ IdentifierResolver::IdDeclInfo &
172
+ IdentifierResolver::IdDeclInfoMap::operator [](IdentifierInfo *II) {
239
173
assert (II && " null IdentifierInfo passed" );
240
174
void *Ptr = II->getFETokenInfo <void >();
241
175
242
- if (Ptr) {
243
- assert (!isDeclPtr (Ptr) && " didn't clear decl for FEToken" );
244
- return *toIdDeclInfo (Ptr);
245
- }
176
+ if (Ptr) return *toIdDeclInfo (Ptr);
246
177
247
178
if (CurIndex == VECTOR_SIZE) {
248
179
// Add a IdDeclInfo vector 'pool'
0 commit comments