Unify ctx_iterator/ctx_begin()/ctx_end() and iterator/begin()/end() so that a single iterator type is used for both traversing decls of the same declaration context *and* of the parent declaration contexts, depending on the value of the bool parameter 'LookInParentCtx' that is passed to IdentifierResolver::begin().
llvm-svn: 53724
This commit is contained in:
parent
7e5edf1a1f
commit
ef34aed1f9
|
@ -111,58 +111,70 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
|
|||
return toIdDeclInfo(Ptr)->RemoveDecl(D);
|
||||
}
|
||||
|
||||
/// begin - Returns an iterator for all decls, starting at the given
|
||||
/// declaration context.
|
||||
/// begin - Returns an iterator for decls of identifier 'II', starting at
|
||||
/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
|
||||
/// decls of parent declaration contexts too.
|
||||
IdentifierResolver::iterator
|
||||
IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx) {
|
||||
IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx,
|
||||
bool LookInParentCtx) {
|
||||
assert(Ctx && "null param passed");
|
||||
|
||||
void *Ptr = II->getFETokenInfo<void>();
|
||||
if (!Ptr) return end(II);
|
||||
if (!Ptr) return end();
|
||||
|
||||
LookupContext LC(Ctx);
|
||||
|
||||
if (isDeclPtr(Ptr)) {
|
||||
NamedDecl *D = static_cast<NamedDecl*>(Ptr);
|
||||
LookupContext DC(D);
|
||||
|
||||
if (LC.isEqOrContainedBy(LookupContext(D)))
|
||||
if (( LookInParentCtx && LC.isEqOrContainedBy(DC)) ||
|
||||
(!LookInParentCtx && LC == DC))
|
||||
return iterator(D);
|
||||
else
|
||||
return end(II);
|
||||
|
||||
return end();
|
||||
}
|
||||
|
||||
|
||||
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
||||
return iterator(IDI->FindContext(LC));
|
||||
|
||||
IdDeclInfo::DeclsTy::iterator I;
|
||||
if (LookInParentCtx)
|
||||
I = IDI->FindContext(LC);
|
||||
else {
|
||||
for (I = IDI->decls_end(); I != IDI->decls_begin(); --I)
|
||||
if (LookupContext(*(I-1)) == LC)
|
||||
break;
|
||||
}
|
||||
|
||||
if (I != IDI->decls_begin())
|
||||
return iterator(I-1, LookInParentCtx);
|
||||
else // No decls found.
|
||||
return end();
|
||||
}
|
||||
|
||||
/// ctx_begin - Returns an iterator for only decls that belong to the given
|
||||
/// declaration context.
|
||||
IdentifierResolver::ctx_iterator
|
||||
IdentifierResolver::ctx_begin(const IdentifierInfo *II, DeclContext *Ctx) {
|
||||
assert(Ctx && "null param passed");
|
||||
|
||||
void *Ptr = II->getFETokenInfo<void>();
|
||||
if (!Ptr) return ctx_end(II);
|
||||
|
||||
LookupContext LC(Ctx);
|
||||
|
||||
if (isDeclPtr(Ptr)) {
|
||||
NamedDecl *D = static_cast<NamedDecl*>(Ptr);
|
||||
|
||||
if (LC == LookupContext(D))
|
||||
return ctx_iterator(D);
|
||||
else
|
||||
return ctx_end(II);
|
||||
/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter.
|
||||
void IdentifierResolver::iterator::PreIncIter() {
|
||||
NamedDecl *D = **this;
|
||||
LookupContext Ctx(D);
|
||||
void *InfoPtr = D->getIdentifier()->getFETokenInfo<void>();
|
||||
assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
|
||||
IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
|
||||
|
||||
BaseIter I = getIterator();
|
||||
if (LookInParentCtx())
|
||||
I = Info->FindContext(Ctx, I);
|
||||
else {
|
||||
if (I != Info->decls_begin() && LookupContext(*(I-1)) != Ctx) {
|
||||
// The next decl is in different declaration context.
|
||||
// Skip remaining decls and set the iterator to the end.
|
||||
I = Info->decls_begin();
|
||||
}
|
||||
}
|
||||
|
||||
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
||||
IdDeclInfo::DeclsTy::iterator I = IDI->FindContext(LookupContext(Ctx));
|
||||
if (I != IDI->decls_begin() && LC != LookupContext(*(I-1)))
|
||||
I = IDI->decls_begin();
|
||||
|
||||
return ctx_iterator(I);
|
||||
if (I != Info->decls_begin())
|
||||
*this = iterator(I-1, LookInParentCtx());
|
||||
else // No more decls.
|
||||
*this = end();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -134,75 +134,6 @@ class IdentifierResolver {
|
|||
return Decls.begin();
|
||||
}
|
||||
|
||||
/// iterator - Iterate over the decls by walking their parent contexts too.
|
||||
class iterator {
|
||||
public:
|
||||
typedef DeclsTy::iterator BaseIter;
|
||||
|
||||
iterator(const BaseIter &DeclIt) : DI(DeclIt) {}
|
||||
const BaseIter &getBase() { return DI; }
|
||||
|
||||
NamedDecl *&operator*() const {
|
||||
return *(DI-1);
|
||||
}
|
||||
|
||||
bool operator==(const iterator &RHS) const {
|
||||
return DI == RHS.DI;
|
||||
}
|
||||
bool operator!=(const iterator &RHS) const {
|
||||
return DI != RHS.DI;
|
||||
}
|
||||
|
||||
// Preincrement.
|
||||
iterator& operator++() {
|
||||
NamedDecl *D = **this;
|
||||
void *Ptr = D->getIdentifier()->getFETokenInfo<void>();
|
||||
assert(!isDeclPtr(Ptr) && "Decl with wrong id ?");
|
||||
DI = toIdDeclInfo(Ptr)->FindContext(LookupContext(D), DI-1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
BaseIter DI;
|
||||
};
|
||||
|
||||
/// ctx_iterator - Iterator over the decls of a specific context only.
|
||||
class ctx_iterator {
|
||||
public:
|
||||
typedef DeclsTy::iterator BaseIter;
|
||||
|
||||
ctx_iterator(const BaseIter &DeclIt) : DI(DeclIt) {}
|
||||
const BaseIter &getBase() { return DI; }
|
||||
|
||||
NamedDecl *&operator*() const {
|
||||
return *(DI-1);
|
||||
}
|
||||
|
||||
bool operator==(const ctx_iterator &RHS) const {
|
||||
return DI == RHS.DI;
|
||||
}
|
||||
bool operator!=(const ctx_iterator &RHS) const {
|
||||
return DI != RHS.DI;
|
||||
}
|
||||
|
||||
// Preincrement.
|
||||
ctx_iterator& operator++() {
|
||||
NamedDecl *D = **this;
|
||||
void *Ptr = D->getIdentifier()->getFETokenInfo<void>();
|
||||
assert(!isDeclPtr(Ptr) && "Decl with wrong id ?");
|
||||
IdDeclInfo *Info = toIdDeclInfo(Ptr);
|
||||
|
||||
--DI;
|
||||
if (DI != Info->Decls.begin() &&
|
||||
LookupContext(D) != LookupContext(**this))
|
||||
DI = Info->Decls.begin();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
BaseIter DI;
|
||||
};
|
||||
|
||||
void AddDecl(NamedDecl *D) {
|
||||
Decls.insert(FindContext(LookupContext(D)), D);
|
||||
}
|
||||
|
@ -242,28 +173,47 @@ class IdentifierResolver {
|
|||
DeclsTy Decls;
|
||||
};
|
||||
|
||||
/// SwizzledIterator - Can be instantiated either with a single NamedDecl*
|
||||
/// (the common case where only one decl is associated with an identifier) or
|
||||
/// with an 'Iter' iterator, when there are more than one decls to lookup.
|
||||
template<typename Iter>
|
||||
class SwizzledIterator {
|
||||
uintptr_t Ptr;
|
||||
public:
|
||||
|
||||
SwizzledIterator() : Ptr(0) {}
|
||||
SwizzledIterator(NamedDecl *D) {
|
||||
/// iterator - Iterate over the decls of a specified identifier.
|
||||
/// It will walk or not the parent declaration contexts depending on how
|
||||
/// it was instantiated.
|
||||
class iterator {
|
||||
/// Ptr - There are 3 forms that 'Ptr' represents:
|
||||
/// 1) A single NamedDecl. (Ptr & 0x1 == 0)
|
||||
/// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
|
||||
/// same declaration context. (Ptr & 0x3 == 0x1)
|
||||
/// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
|
||||
/// declaration contexts too. (Ptr & 0x3 == 0x3)
|
||||
uintptr_t Ptr;
|
||||
typedef IdDeclInfo::DeclsTy::iterator BaseIter;
|
||||
|
||||
iterator() : Ptr(0) {}
|
||||
/// A single NamedDecl. (Ptr & 0x1 == 0)
|
||||
iterator(NamedDecl *D) {
|
||||
Ptr = reinterpret_cast<uintptr_t>(D);
|
||||
assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
|
||||
}
|
||||
SwizzledIterator(Iter I) {
|
||||
Ptr = reinterpret_cast<uintptr_t>(I.getBase()) | 0x1;
|
||||
/// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
|
||||
/// contexts depending on 'LookInParentCtx'.
|
||||
iterator(BaseIter I, bool LookInParentCtx) {
|
||||
Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
|
||||
assert((Ptr & 0x2) == 0 && "Invalid Ptr!");
|
||||
if (LookInParentCtx) Ptr |= 0x2;
|
||||
}
|
||||
|
||||
bool isIterator() const { return (Ptr & 0x1); }
|
||||
|
||||
Iter getIterator() const {
|
||||
assert(isIterator() && "Ptr not an iterator.");
|
||||
return reinterpret_cast<typename Iter::BaseIter>(Ptr & ~0x1);
|
||||
bool LookInParentCtx() const {
|
||||
assert(isIterator() && "Ptr not an iterator!");
|
||||
return (Ptr & 0x2) != 0;
|
||||
}
|
||||
|
||||
BaseIter getIterator() const {
|
||||
assert(isIterator() && "Ptr not an iterator!");
|
||||
return reinterpret_cast<BaseIter>(Ptr & ~0x3);
|
||||
}
|
||||
|
||||
friend class IdentifierResolver;
|
||||
public:
|
||||
NamedDecl *operator*() const {
|
||||
|
@ -273,56 +223,36 @@ class IdentifierResolver {
|
|||
return reinterpret_cast<NamedDecl*>(Ptr);
|
||||
}
|
||||
|
||||
bool operator==(const SwizzledIterator &RHS) const {
|
||||
bool operator==(const iterator &RHS) const {
|
||||
return Ptr == RHS.Ptr;
|
||||
}
|
||||
bool operator!=(const SwizzledIterator &RHS) const {
|
||||
bool operator!=(const iterator &RHS) const {
|
||||
return Ptr != RHS.Ptr;
|
||||
}
|
||||
|
||||
|
||||
// Preincrement.
|
||||
SwizzledIterator& operator++() {
|
||||
if (isIterator()) {
|
||||
Iter I = getIterator();
|
||||
++I;
|
||||
Ptr = reinterpret_cast<uintptr_t>(I.getBase()) | 0x1;
|
||||
}
|
||||
else // This is a single NamedDecl*.
|
||||
iterator& operator++() {
|
||||
if (!isIterator()) // common case.
|
||||
Ptr = 0;
|
||||
|
||||
else
|
||||
PreIncIter();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void PreIncIter();
|
||||
};
|
||||
|
||||
public:
|
||||
/// begin - Returns an iterator for decls of identifier 'II', starting at
|
||||
/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
|
||||
/// decls of parent declaration contexts too.
|
||||
/// Default for 'LookInParentCtx is true.
|
||||
static iterator begin(const IdentifierInfo *II, DeclContext *Ctx,
|
||||
bool LookInParentCtx = true);
|
||||
|
||||
typedef SwizzledIterator<IdDeclInfo::iterator> iterator;
|
||||
typedef SwizzledIterator<IdDeclInfo::ctx_iterator> ctx_iterator;
|
||||
|
||||
/// begin - Returns an iterator for all decls, starting at the given
|
||||
/// declaration context.
|
||||
static iterator begin(const IdentifierInfo *II, DeclContext *Ctx);
|
||||
|
||||
static iterator end(const IdentifierInfo *II) {
|
||||
void *Ptr = II->getFETokenInfo<void>();
|
||||
if (!Ptr || isDeclPtr(Ptr))
|
||||
return iterator();
|
||||
|
||||
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
||||
return iterator(IDI->decls_begin());
|
||||
}
|
||||
|
||||
/// ctx_begin - Returns an iterator for only decls that belong to the given
|
||||
/// declaration context.
|
||||
static ctx_iterator ctx_begin(const IdentifierInfo *II, DeclContext *Ctx);
|
||||
|
||||
static ctx_iterator ctx_end(const IdentifierInfo *II) {
|
||||
void *Ptr = II->getFETokenInfo<void>();
|
||||
if (!Ptr || isDeclPtr(Ptr))
|
||||
return ctx_iterator();
|
||||
|
||||
IdDeclInfo *IDI = toIdDeclInfo(Ptr);
|
||||
return ctx_iterator(IDI->decls_begin());
|
||||
/// end - Returns an iterator that has 'finished'.
|
||||
static iterator end() {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
|
||||
|
|
|
@ -91,15 +91,16 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
|
|||
// in this case the class name or enumeration name is hidden.
|
||||
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
|
||||
// We are pushing the name of a tag (enum or class).
|
||||
IdentifierResolver::ctx_iterator
|
||||
CIT = IdResolver.ctx_begin(TD->getIdentifier(), TD->getDeclContext());
|
||||
if (CIT != IdResolver.ctx_end(TD->getIdentifier()) &&
|
||||
IdResolver.isDeclInScope(*CIT, TD->getDeclContext(), S)) {
|
||||
IdentifierResolver::iterator
|
||||
I = IdResolver.begin(TD->getIdentifier(),
|
||||
TD->getDeclContext(), false/*LookInParentCtx*/);
|
||||
if (I != IdResolver.end() &&
|
||||
IdResolver.isDeclInScope(*I, TD->getDeclContext(), S)) {
|
||||
// There is already a declaration with the same name in the same
|
||||
// scope. It must be found before we find the new declaration,
|
||||
// so swap the order on the shadowed declaration chain.
|
||||
|
||||
IdResolver.AddShadowedDecl(TD, *CIT);
|
||||
IdResolver.AddShadowedDecl(TD, *I);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +159,7 @@ Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI,
|
|||
// that is in the appropriate namespace. This search should not take long, as
|
||||
// shadowing of names is uncommon, and deep shadowing is extremely uncommon.
|
||||
for (IdentifierResolver::iterator
|
||||
I = IdResolver.begin(II, CurContext), E = IdResolver.end(II); I != E; ++I)
|
||||
I = IdResolver.begin(II, CurContext), E = IdResolver.end(); I != E; ++I)
|
||||
if ((*I)->getIdentifierNamespace() & NS)
|
||||
return *I;
|
||||
|
||||
|
|
Loading…
Reference in New Issue