summaryrefslogtreecommitdiff
path: root/lib/VMCore/SymbolTable.cpp
blob: 07e4b87f020fc519e92556aca2d5db5db25122ad (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//===-- 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));
}