From e638c10cb0fd3e5e50e0eec226367eba861eba0f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 23 Oct 2001 02:32:45 +0000 Subject: [PATCH] More symbol table bugfixes that are impossible to track down. Goody git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@960 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/SymbolTable.h | 19 +++++++++----- lib/VMCore/SymbolTable.cpp | 54 ++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/include/llvm/SymbolTable.h b/include/llvm/SymbolTable.h index c53cb785fa6..ee53f6d5a34 100644 --- a/include/llvm/SymbolTable.h +++ b/include/llvm/SymbolTable.h @@ -24,13 +24,8 @@ #include "llvm/ConstPoolVals.h" #endif -class Value; class Type; -// TODO: Change this back to vector > -// Make the vector be a data member, and base it on UniqueID's -// That should be much more efficient! -// class SymbolTable : public AbstractTypeUser, public map > { public: @@ -47,7 +42,10 @@ public: typedef VarMap::iterator type_iterator; typedef VarMap::const_iterator type_const_iterator; - inline SymbolTable(SymbolTable *P = 0) { ParentSymTab = P; } + inline SymbolTable(SymbolTable *P = 0) { + ParentSymTab = P; + InternallyInconsistent = false; + } ~SymbolTable(); SymbolTable *getParentSymTab() { return ParentSymTab; } @@ -106,6 +104,15 @@ public: void dump() const; // Debug method, print out symbol table private: + // InternallyInconsistent - There are times when the symbol table is + // internally inconsistent with the rest of the program. In this one case, a + // value exists with a Name, and it's not in the symbol table. When we call + // V->setName(""), it tries to remove itself from the symbol table and dies. + // We know this is happening, and so if the flag InternallyInconsistent is + // set, removal from the symbol table is a noop. + // + bool InternallyInconsistent; + inline super::value_type operator[](const Type *Ty) { assert(0 && "Should not use this operator to access symbol table!"); return super::value_type(); diff --git a/lib/VMCore/SymbolTable.cpp b/lib/VMCore/SymbolTable.cpp index ecac7c2a3d1..f84e945e7d6 100644 --- a/lib/VMCore/SymbolTable.cpp +++ b/lib/VMCore/SymbolTable.cpp @@ -80,6 +80,7 @@ void SymbolTable::remove(Value *N) { // removeEntry - Remove a value from the symbol table... // Value *SymbolTable::removeEntry(iterator Plane, type_iterator Entry) { + if (InternallyInconsistent) return 0; assert(Plane != super::end() && Entry != Plane->second.end() && "Invalid entry to remove!"); @@ -206,37 +207,32 @@ void SymbolTable::refineAbstractType(const DerivedType *OldType, // The only thing we are allowing for now is two method prototypes being // folded into one. // - if (Method *ExistM = dyn_cast(TI->second)) - if (Method *NewM = dyn_cast(V.second)) - if (ExistM->isExternal() && NewM->isExternal()) { - // Ok we have two external methods. Make all uses of the new one - // use the old one... - // - NewM->replaceAllUsesWith(ExistM); + Method *ExistM = dyn_cast(TI->second); + Method *NewM = dyn_cast(V.second); - // Now we just convert it to an unnamed method... which won't get - // added to our symbol table. The problem is that if we call - // setName on the method that it will try to remove itself from - // the symbol table and die... because it's not in the symtab - // right now. To fix this, we temporarily insert it (by setting - // TI's entry to the old value. Then after it is removed, we - // restore ExistM into the symbol table. - // - if (NewM->getType() == NewType) { - TI->second = NewM; // Add newM to the symtab + if (ExistM && NewM && ExistM->isExternal() && NewM->isExternal()) { + // Ok we have two external methods. Make all uses of the new one + // use the old one... + // + NewM->replaceAllUsesWith(ExistM); + + // Now we just convert it to an unnamed method... which won't get + // added to our symbol table. The problem is that if we call + // setName on the method that it will try to remove itself from + // the symbol table and die... because it's not in the symtab + // right now. To fix this, we have an internally consistent flag + // that turns remove into a noop. Thus the name will get null'd + // out, but the symbol table won't get upset. + // + InternallyInconsistent = true; - // Remove newM from the symtab - NewM->setName(""); - - // Readd ExistM to the symbol table.... - NewPlane.insert(make_pair(V.first, ExistM)); - } else { - NewM->setName(""); - } - continue; - } - assert(0 && "Two ploanes folded together with overlapping " - "value names!"); + // Remove newM from the symtab + NewM->setName(""); + InternallyInconsistent = false; + } else { + assert(0 && "Two ploanes folded together with overlapping " + "value names!"); + } } else { insertEntry(V.first, NewType, V.second);