//===-- SymbolTable.cpp - Implement the SymbolTable class -----------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and revised by Reid
-// Spencer. It is distributed under the University of Illinois Open Source
+// Spencer. It is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the SymbolTable class for the VMCore library.
cast<DerivedType>(TI->second)->removeAbstractTypeUser(this);
}
- // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the
+ // TODO: FIXME: BIG ONE: This doesn't unreference abstract types for the
// planes that could still have entries!
#ifndef NDEBUG // Only do this in -g mode...
LeftoverValues = false;
}
}
-
+
assert(LeftoverValues && "Values remain in symbol table!");
#endif
}
// lookup a type by name - returns null on failure
-Type* SymbolTable::lookupType( const std::string& Name ) const {
- type_const_iterator TI = tmap.find( Name );
- if ( TI != tmap.end() )
+Type* SymbolTable::lookupType(const std::string& Name) const {
+ type_const_iterator TI = tmap.find(Name);
+ if (TI != tmap.end())
return const_cast<Type*>(TI->second);
return 0;
}
-// Remove a value
-void SymbolTable::remove(Value *N) {
- assert(N->hasName() && "Value doesn't have name!");
- if (InternallyInconsistent) return;
-
- plane_iterator PI = pmap.find(N->getType());
- assert(PI != pmap.end() &&
- "Trying to remove a value that doesn't have a type plane yet!");
- removeEntry(PI, PI->second.find(N->getName()));
-}
-
/// changeName - Given a value with a non-empty name, remove its existing entry
/// from the symbol table and insert a new one for Name. This is equivalent to
/// doing "remove(V), V->Name = Name, insert(V)", but is faster, and will not
assert(PI != pmap.end() && "Value doesn't have an entry in this table?");
ValueMap &VM = PI->second;
- value_iterator VI;
+ value_iterator VI = VM.find(V->getName());
+ assert(VI != VM.end() && "Value does have an entry in this table?");
- if (!InternallyInconsistent) {
- VI = VM.find(V->getName());
- assert(VI != VM.end() && "Value does have an entry in this table?");
-
- // Remove the old entry.
- VM.erase(VI);
- }
+ // Remove the old entry.
+ VM.erase(VI);
// See if we can insert the new name.
VI = VM.lower_bound(name);
}
}
+// Remove a value
+void SymbolTable::remove(Value *N) {
+ assert(N->hasName() && "Value doesn't have name!");
-// removeEntry - Remove a value from the symbol table...
-Value *SymbolTable::removeEntry(plane_iterator Plane, value_iterator Entry) {
- if (InternallyInconsistent) return 0;
- assert(Plane != pmap.end() &&
- Entry != Plane->second.end() && "Invalid entry to remove!");
+ plane_iterator PI = pmap.find(N->getType());
+ assert(PI != pmap.end() &&
+ "Trying to remove a value that doesn't have a type plane yet!");
+ ValueMap &VM = PI->second;
+ value_iterator Entry = VM.find(N->getName());
+ assert(Entry != VM.end() && "Invalid entry to remove!");
- Value *Result = Entry->second;
#if DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Removing Value: " << Result->getName() << "\n";
+ std::cerr << " Removing Value: " << Entry->second->getName() << "\n";
#endif
// Remove the value from the plane...
- Plane->second.erase(Entry);
+ VM.erase(Entry);
// If the plane is empty, remove it now!
- if (Plane->second.empty()) {
+ if (VM.empty()) {
// If the plane represented an abstract type that we were interested in,
// unlink ourselves from this plane.
//
- if (Plane->first->isAbstract()) {
+ if (N->getType()->isAbstract()) {
#if DEBUG_ABSTYPE
std::cerr << "Plane Empty: Removing type: "
- << Plane->first->getDescription() << "\n";
+ << N->getType()->getDescription() << "\n";
#endif
- cast<DerivedType>(Plane->first)->removeAbstractTypeUser(this);
+ cast<DerivedType>(N->getType())->removeAbstractTypeUser(this);
}
- pmap.erase(Plane);
+ pmap.erase(PI);
}
- return Result;
}
-
-// remove - Remove a type
-void SymbolTable::remove(const Type* Ty ) {
- type_iterator TI = this->type_begin();
- type_iterator TE = this->type_end();
-
- // Search for the entry
- while ( TI != TE && TI->second != Ty )
- ++TI;
-
- if ( TI != TE )
- this->removeEntry( TI );
-}
-
-
-// removeEntry - Remove a type from the symbol table...
-Type* SymbolTable::removeEntry(type_iterator Entry) {
- if (InternallyInconsistent) return 0;
- assert( Entry != tmap.end() && "Invalid entry to remove!");
+// remove - Remove a type from the symbol table...
+Type* SymbolTable::remove(type_iterator Entry) {
+ assert(Entry != tmap.end() && "Invalid entry to remove!");
const Type* Result = Entry->second;
#if DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Inserting definition: " << Name << ": "
+ std::cerr << " Inserting definition: " << Name << ": "
<< VTy->getDescription() << "\n";
#endif
VM = &PI->second;
VI = VM->lower_bound(Name);
if (VI != VM->end() && VI->first == Name) {
- std::string UniqueName = getUniqueName(VTy, Name);
- assert(InternallyInconsistent == false &&
- "Infinite loop inserting value!");
- InternallyInconsistent = true;
- V->setName(UniqueName);
- InternallyInconsistent = false;
+ V->Name = getUniqueName(VTy, Name);
+ VM->insert(make_pair(V->Name, V));
return;
}
}
// insertEntry - Insert a value into the symbol table with the specified
// name...
//
-void SymbolTable::insertEntry(const std::string& Name, const Type* T) {
+void SymbolTable::insert(const std::string& Name, const Type* T) {
+ assert(T && "Can't insert null type into symbol table!");
// Check to see if there is a naming conflict. If so, rename this type!
std::string UniqueName = Name;
#if DEBUG_SYMBOL_TABLE
dump();
- std::cerr << " Inserting type: " << UniqueName << ": "
+ std::cerr << " Inserting type: " << UniqueName << ": "
<< T->getDescription() << "\n";
#endif
value_iterator B = Plane.begin(), Bend = Plane.end();
while (B != Bend) { // Found nonempty type plane!
Value *V = B->second;
+ ++B;
if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
// Set name to "", removing from symbol table!
V->setName("");
RemovedSymbol = true;
}
- ++B;
}
}
for (type_iterator TI = tmap.begin(); TI != tmap.end(); ) {
- const Type* T = (TI++)->second;
- remove(T);
+ remove(TI++);
RemovedSymbol = true;
}
-
+
return RemovedSymbol;
}
plane_iterator NewTypeIt = pmap.find(NewType);
if (NewTypeIt == pmap.end()) { // If no plane exists, add one
NewTypeIt = pmap.insert(make_pair(NewType, ValueMap())).first;
-
+
if (NewType->isAbstract()) {
cast<DerivedType>(NewType)->addAbstractTypeUser(this);
#if DEBUG_ABSTYPE
// Ok we have two external global values. Make all uses of the new
// one use the old one...
NewGV->uncheckedReplaceAllUsesWith(ExistGV);
-
- // 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.
- //
- assert(InternallyInconsistent == false &&
- "Symbol table already inconsistent!");
- InternallyInconsistent = true;
-
- // Remove newM from the symtab
- NewGV->setName("");
- InternallyInconsistent = false;
+
+ // Update NewGV's name, we're about the remove it from the symbol
+ // table.
+ NewGV->Name = "";
// Now we can remove this global from the module entirely...
Module *M = NewGV->getParent();
std::cerr << "Removing type " << OldType->getDescription() << "\n";
#endif
OldType->removeAbstractTypeUser(this);
-
+
I->second = (Type*)NewType; // TODO FIXME when types aren't const
if (NewType->isAbstract()) {
#if DEBUG_ABSTYPE