summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-10 09:41:52 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-10 09:41:52 +0000
commit84d8767c1582d1ee300ecf9899b76d57a34c3597 (patch)
tree1d36caa744cc145503c6493c21da4d1b945b6cea /clang/lib/AST/DeclBase.cpp
parente919e382a4fa116b3a15cb8855dd928f0ce674a2 (diff)
downloadbcm5719-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.cpp40
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");
OpenPOWER on IntegriCloud