Skip to content

Commit fa8e15b

Browse files
committed
-Implement proper name lookup for namespaces.
-identifierResolver exposes an iterator interface to get all decls through the scope chain. -The semantic staff (checking IdentifierNamespace and Doug's checking for shadowed tags were moved out of IdentifierResolver and back into Sema. IdentifierResolver just gives an iterator for all reachable decls of an identifier. llvm-svn: 50923
1 parent 867af26 commit fa8e15b

File tree

6 files changed

+493
-175
lines changed

6 files changed

+493
-175
lines changed

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D) {
12511251

12521252
// Enter function-declaration scope, limiting any declarators to the
12531253
// function prototype scope, including parameter declarators.
1254-
EnterScope(Scope::DeclScope);
1254+
EnterScope(Scope::FnScope|Scope::DeclScope);
12551255

12561256
bool IsVariadic = false;
12571257
while (1) {
@@ -1526,3 +1526,4 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
15261526
}
15271527
}
15281528

1529+

clang/lib/Sema/IdentifierResolver.cpp

Lines changed: 68 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -13,67 +13,16 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "IdentifierResolver.h"
16-
#include "clang/Basic/IdentifierTable.h"
17-
#include "clang/AST/Decl.h"
18-
#include "clang/Parse/Scope.h"
1916
#include <list>
2017
#include <vector>
2118

2219
using namespace clang;
2320

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-
7221

7322
/// IdDeclInfoMap - Associates IdDeclInfos with Identifiers.
7423
/// Allocates 'pools' (vectors of IdDeclInfos) to avoid allocating each
7524
/// individual IdDeclInfo to heap.
76-
class IdDeclInfoMap {
25+
class IdentifierResolver::IdDeclInfoMap {
7726
static const unsigned int VECTOR_SIZE = 512;
7827
// Holds vectors of IdDeclInfos that serve as 'pools'.
7928
// New vectors are added when the current one is full.
@@ -88,17 +37,14 @@ class IdDeclInfoMap {
8837
IdDeclInfo &operator[](IdentifierInfo *II);
8938
};
9039

91-
} // end anonymous namespace
92-
9340

9441
IdentifierResolver::IdentifierResolver() : IdDeclInfos(new IdDeclInfoMap) {}
9542
IdentifierResolver::~IdentifierResolver() {
96-
delete static_cast<IdDeclInfoMap*>(IdDeclInfos);
43+
delete IdDeclInfos;
9744
}
9845

9946
/// 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) {
10248
IdentifierInfo *II = D->getIdentifier();
10349
void *Ptr = II->getFETokenInfo<void>();
10450

@@ -111,56 +57,40 @@ void IdentifierResolver::AddDecl(NamedDecl *D, Scope *S) {
11157

11258
if (isDeclPtr(Ptr)) {
11359
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);
11763
} else
11864
IDI = toIdDeclInfo(Ptr);
11965

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);
14067
}
14168

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+
14576
IdentifierInfo *II = D->getIdentifier();
14677
void *Ptr = II->getFETokenInfo<void>();
147-
148-
if (!Ptr) {
149-
II->setFETokenInfo(D);
150-
return;
151-
}
78+
assert(Ptr && "No decl from Ptr ?");
15279

15380
IdDeclInfo *IDI;
15481

15582
if (isDeclPtr(Ptr)) {
15683
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+
}
16291

163-
IDI->PushGlobalShadowed(D);
92+
IDI = toIdDeclInfo(Ptr);
93+
IDI->AddShadowed(D, Shadow);
16494
}
16595

16696
/// RemoveDecl - Unlink the decl from its shadowed decl chain.
@@ -178,71 +108,72 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
178108
return;
179109
}
180110

181-
return toIdDeclInfo(Ptr)->RemoveShadowed(D);
111+
return toIdDeclInfo(Ptr)->RemoveDecl(D);
182112
}
183113

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+
188120
void *Ptr = II->getFETokenInfo<void>();
121+
if (!Ptr) return end(II);
189122

190-
if (!Ptr) return NULL;
123+
LookupContext LC(Ctx);
191124

192125
if (isDeclPtr(Ptr)) {
193126
NamedDecl *D = static_cast<NamedDecl*>(Ptr);
194-
return (D->getIdentifierNamespace() & NS) ? D : NULL;
195-
}
196127

197-
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
128+
if (LC.isEqOrContainedBy(LookupContext(D)))
129+
return iterator(D);
130+
else
131+
return end(II);
198132

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;
206133
}
207-
208-
// we didn't find the decl.
209-
return NULL;
134+
135+
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
136+
return iterator(IDI->FindContext(LC));
210137
}
211138

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);
224157

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-
}
231158
}
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();
232164

233-
assert(false && "Didn't find this decl on its identifier's chain!");
165+
return ctx_iterator(I);
234166
}
235167

168+
236169
/// Returns the IdDeclInfo associated to the IdentifierInfo.
237170
/// 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) {
239173
assert (II && "null IdentifierInfo passed");
240174
void *Ptr = II->getFETokenInfo<void>();
241175

242-
if (Ptr) {
243-
assert(!isDeclPtr(Ptr) && "didn't clear decl for FEToken");
244-
return *toIdDeclInfo(Ptr);
245-
}
176+
if (Ptr) return *toIdDeclInfo(Ptr);
246177

247178
if (CurIndex == VECTOR_SIZE) {
248179
// Add a IdDeclInfo vector 'pool'

0 commit comments

Comments
 (0)