Initial revision

llvm-svn: 2
diff --git a/llvm/lib/VMCore/SymbolTable.cpp b/llvm/lib/VMCore/SymbolTable.cpp
new file mode 100644
index 0000000..395c23f
--- /dev/null
+++ b/llvm/lib/VMCore/SymbolTable.cpp
@@ -0,0 +1,106 @@
+//===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=//
+//
+// This file implements the SymbolTable class for the VMCore library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/SymbolTable.h"
+#include "llvm/InstrTypes.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);
+}
+
+
+// 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));
+}
+