| //===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=// |
| // |
| // This file implements the SymbolTable class for the VMCore library. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/SymbolTable.h" |
| #include "llvm/InstrTypes.h" |
| #include "llvm/Tools/StringExtras.h" |
| #ifndef NDEBUG |
| #include "llvm/BasicBlock.h" // Required for assertions to work. |
| #include "llvm/Type.h" |
| #endif |
| |
| SymbolTable::~SymbolTable() { |
| #ifndef NDEBUG // Only do this in -g mode... |
| bool Good = true; |
| for (iterator i = begin(); i != end(); ++i) { |
| if (i->second.begin() != i->second.end()) { |
| for (type_iterator I = i->second.begin(); I != i->second.end(); ++I) |
| cerr << "Value still in symbol table! Type = " << i->first->getName() |
| << " Name = " << I->first << endl; |
| Good = false; |
| } |
| } |
| assert(Good && "Values remain in symbol table!"); |
| #endif |
| } |
| |
| SymbolTable::type_iterator SymbolTable::type_find(const Value *D) { |
| assert(D->hasName() && "type_find(Value*) only works on named nodes!"); |
| return type_find(D->getType(), D->getName()); |
| } |
| |
| |
| // find - returns end(Ty->getIDNumber()) on failure... |
| SymbolTable::type_iterator SymbolTable::type_find(const Type *Ty, |
| const string &Name) { |
| iterator I = find(Ty); |
| if (I == end()) { // Not in collection yet... insert dummy entry |
| (*this)[Ty] = VarMap(); |
| I = find(Ty); |
| assert(I != end() && "How did insert fail?"); |
| } |
| |
| return I->second.find(Name); |
| } |
| |
| // getUniqueName - Given a base name, return a string that is either equal to |
| // it (or derived from it) that does not already occur in the symbol table for |
| // the specified type. |
| // |
| string SymbolTable::getUniqueName(const Type *Ty, const string &BaseName) { |
| iterator I = find(Ty); |
| if (I == end()) return BaseName; |
| |
| string TryName = BaseName; |
| unsigned Counter = 0; |
| type_iterator End = I->second.end(); |
| |
| while (I->second.find(TryName) != End) // Loop until we find unoccupied |
| TryName = BaseName + utostr(++Counter); // Name in the symbol table |
| return TryName; |
| } |
| |
| |
| |
| // lookup - Returns null on failure... |
| Value *SymbolTable::lookup(const Type *Ty, const string &Name) { |
| iterator I = find(Ty); |
| if (I != end()) { // We have symbols in that plane... |
| type_iterator J = I->second.find(Name); |
| if (J != I->second.end()) // and the name is in our hash table... |
| return J->second; |
| } |
| |
| return ParentSymTab ? ParentSymTab->lookup(Ty, Name) : 0; |
| } |
| |
| void SymbolTable::remove(Value *N) { |
| assert(N->hasName() && "Value doesn't have name!"); |
| assert(type_find(N) != type_end(N->getType()) && |
| "Value not in symbol table!"); |
| type_remove(type_find(N)); |
| } |
| |
| |
| #define DEBUG_SYMBOL_TABLE 0 |
| |
| Value *SymbolTable::type_remove(const type_iterator &It) { |
| Value *Result = It->second; |
| #if DEBUG_SYMBOL_TABLE |
| cerr << this << " Removing Value: " << Result->getName() << endl; |
| #endif |
| |
| find(Result->getType())->second.erase(It); |
| |
| return Result; |
| } |
| |
| void SymbolTable::insert(Value *N) { |
| assert(N->hasName() && "Value must be named to go into symbol table!"); |
| |
| // TODO: The typeverifier should catch this when its implemented |
| if (lookup(N->getType(), N->getName())) { |
| cerr << "SymbolTable WARNING: Name already in symbol table: '" |
| << N->getName() << "'\n"; |
| abort(); // TODO: REMOVE THIS |
| } |
| |
| #if DEBUG_SYMBOL_TABLE |
| cerr << this << " Inserting definition: " << N->getName() << ": " |
| << N->getType()->getName() << endl; |
| #endif |
| |
| iterator I = find(N->getType()); |
| if (I == end()) { // Not in collection yet... insert dummy entry |
| (*this)[N->getType()] = VarMap(); |
| I = find(N->getType()); |
| assert(I != end() && "How did insert fail?"); |
| } |
| |
| I->second.insert(make_pair(N->getName(), N)); |
| } |
| |