aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r--lib/AST/DeclBase.cpp40
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");