summaryrefslogtreecommitdiff
path: root/lib/VMCore/SymbolTable.cpp
blob: 395c23f2abc944ac0a2e704defb7e1d0fb6c4041 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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));
}