From: Argyrios Kyrtzidis Date: Thu, 17 Jul 2008 17:49:50 +0000 (+0000) Subject: Unify ctx_iterator/ctx_begin()/ctx_end() and iterator/begin()/end() so that a single... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=90eb539bc3121bdc0e867ab1cd6bdca3b36d961e;p=clang 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(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53724 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 33b2102fd1..0b63ad9b53 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -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(); - if (!Ptr) return end(II); + if (!Ptr) return end(); LookupContext LC(Ctx); if (isDeclPtr(Ptr)) { NamedDecl *D = static_cast(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)); -} -/// 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(); - if (!Ptr) return ctx_end(II); - - LookupContext LC(Ctx); + IdDeclInfo *IDI = toIdDeclInfo(Ptr); - if (isDeclPtr(Ptr)) { - NamedDecl *D = static_cast(Ptr); + 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 (LC == LookupContext(D)) - return ctx_iterator(D); - else - return ctx_end(II); + if (I != IDI->decls_begin()) + return iterator(I-1, LookInParentCtx); + else // No decls found. + return end(); +} +/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter. +void IdentifierResolver::iterator::PreIncIter() { + NamedDecl *D = **this; + LookupContext Ctx(D); + void *InfoPtr = D->getIdentifier()->getFETokenInfo(); + 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(); } diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h index 4903adc685..294904271c 100644 --- a/lib/Sema/IdentifierResolver.h +++ b/lib/Sema/IdentifierResolver.h @@ -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(); - 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(); - 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 - class SwizzledIterator { +public: + + /// 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; - SwizzledIterator() : Ptr(0) {} - SwizzledIterator(NamedDecl *D) { + iterator() : Ptr(0) {} + /// A single NamedDecl. (Ptr & 0x1 == 0) + iterator(NamedDecl *D) { Ptr = reinterpret_cast(D); + assert((Ptr & 0x1) == 0 && "Invalid Ptr!"); } - SwizzledIterator(Iter I) { - Ptr = reinterpret_cast(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(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(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(Ptr & ~0x3); + } + friend class IdentifierResolver; public: NamedDecl *operator*() const { @@ -273,56 +223,36 @@ class IdentifierResolver { return reinterpret_cast(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(I.getBase()) | 0x1; - } - else // This is a single NamedDecl*. + iterator& operator++() { + if (!isIterator()) // common case. Ptr = 0; - + else + PreIncIter(); return *this; } - }; -public: - - typedef SwizzledIterator iterator; - typedef SwizzledIterator 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(); - 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); + private: + void PreIncIter(); + }; - static ctx_iterator ctx_end(const IdentifierInfo *II) { - void *Ptr = II->getFETokenInfo(); - if (!Ptr || isDeclPtr(Ptr)) - return ctx_iterator(); + /// 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); - 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 diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6acbb2d184..e2ac7c5ea5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(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;