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 | 84d8767c1582d1ee300ecf9899b76d57a34c3597 (patch) | |
tree | 1d36caa744cc145503c6493c21da4d1b945b6cea /clang/lib/AST/DeclBase.cpp | |
parent | e919e382a4fa116b3a15cb8855dd928f0ce674a2 (diff) | |
download | bcm5719-llvm-84d8767c1582d1ee300ecf9899b76d57a34c3597.tar.gz bcm5719-llvm-84d8767c1582d1ee300ecf9899b76d57a34c3597.zip |
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.
llvm-svn: 91045
Diffstat (limited to 'clang/lib/AST/DeclBase.cpp')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index c557e615e78..2022b4a28cd 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/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"); |