diff options
author | John McCall <rjmccall@apple.com> | 2009-12-10 09:41:52 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-12-10 09:41:52 +0000 |
commit | 9f54ad4381370c6b771424b53d219e661d6d6706 (patch) | |
tree | cf7e1c1bceaefab55c52fa3458005811e59d0185 /lib/AST/DeclBase.cpp | |
parent | 153c33ed957b135a366178c61bbe22b6b1362a2a (diff) |
Implement redeclaration checking and hiding semantics for using declarations. There
are a couple of O(n^2) operations in this, some analogous to the usual O(n^2)
redeclaration problem and some not. In particular, retroactively removing
shadow declarations when they're hidden by later decls is pretty unfortunate.
I'm not yet convinced it's worse than the alternative, though.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91045 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r-- | lib/AST/DeclBase.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index c557e615e7..2022b4a28c 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -636,6 +636,46 @@ bool DeclContext::decls_empty() const { return !FirstDecl; } +void DeclContext::removeDecl(Decl *D) { + assert(D->getLexicalDeclContext() == this && + "decl being removed from non-lexical context"); + assert((D->NextDeclInContext || D == LastDecl) && + "decl is not in decls list"); + + // Remove D from the decl chain. This is O(n) but hopefully rare. + if (D == FirstDecl) { + if (D == LastDecl) + FirstDecl = LastDecl = 0; + else + FirstDecl = D->NextDeclInContext; + } else { + for (Decl *I = FirstDecl; true; I = I->NextDeclInContext) { + assert(I && "decl not found in linked list"); + if (I->NextDeclInContext == D) { + I->NextDeclInContext = D->NextDeclInContext; + if (D == LastDecl) LastDecl = I; + break; + } + } + } + + // Mark that D is no longer in the decl chain. + D->NextDeclInContext = 0; + + // Remove D from the lookup table if necessary. + if (isa<NamedDecl>(D)) { + NamedDecl *ND = cast<NamedDecl>(D); + + void *OpaqueMap = getPrimaryContext()->LookupPtr; + if (!OpaqueMap) return; + + StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(OpaqueMap); + StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); + assert(Pos != Map->end() && "no lookup entry for decl"); + Pos->second.remove(ND); + } +} + void DeclContext::addHiddenDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context"); |