blob: e054b8850c9ab8cf5fdeebb1ac53858a8bc43015 [file] [log] [blame]
Chris Lattner2f7c9632001-06-06 20:29:01 +00001//===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=//
2//
3// This file implements the SymbolTable class for the VMCore library.
4//
5//===----------------------------------------------------------------------===//
6
7#include "llvm/SymbolTable.h"
8#include "llvm/InstrTypes.h"
Chris Lattnere2472bb2001-07-23 17:46:59 +00009#include "llvm/Support/StringExtras.h"
Chris Lattner2f7c9632001-06-06 20:29:01 +000010#ifndef NDEBUG
11#include "llvm/BasicBlock.h" // Required for assertions to work.
12#include "llvm/Type.h"
13#endif
14
15SymbolTable::~SymbolTable() {
16#ifndef NDEBUG // Only do this in -g mode...
17 bool Good = true;
Chris Lattner4cee8d82001-06-27 23:41:11 +000018 for (iterator i = begin(); i != end(); ++i) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000019 if (i->second.begin() != i->second.end()) {
Chris Lattner4cee8d82001-06-27 23:41:11 +000020 for (type_iterator I = i->second.begin(); I != i->second.end(); ++I)
Chris Lattner2f7c9632001-06-06 20:29:01 +000021 cerr << "Value still in symbol table! Type = " << i->first->getName()
22 << " Name = " << I->first << endl;
23 Good = false;
24 }
25 }
26 assert(Good && "Values remain in symbol table!");
27#endif
28}
29
30SymbolTable::type_iterator SymbolTable::type_find(const Value *D) {
31 assert(D->hasName() && "type_find(Value*) only works on named nodes!");
32 return type_find(D->getType(), D->getName());
33}
34
35
36// find - returns end(Ty->getIDNumber()) on failure...
37SymbolTable::type_iterator SymbolTable::type_find(const Type *Ty,
38 const string &Name) {
39 iterator I = find(Ty);
40 if (I == end()) { // Not in collection yet... insert dummy entry
41 (*this)[Ty] = VarMap();
42 I = find(Ty);
43 assert(I != end() && "How did insert fail?");
44 }
45
46 return I->second.find(Name);
47}
48
Chris Lattner01683cc2001-06-25 07:33:13 +000049// getUniqueName - Given a base name, return a string that is either equal to
50// it (or derived from it) that does not already occur in the symbol table for
51// the specified type.
52//
53string SymbolTable::getUniqueName(const Type *Ty, const string &BaseName) {
54 iterator I = find(Ty);
55 if (I == end()) return BaseName;
56
57 string TryName = BaseName;
58 unsigned Counter = 0;
59 type_iterator End = I->second.end();
60
61 while (I->second.find(TryName) != End) // Loop until we find unoccupied
62 TryName = BaseName + utostr(++Counter); // Name in the symbol table
63 return TryName;
64}
65
66
Chris Lattner2f7c9632001-06-06 20:29:01 +000067
68// lookup - Returns null on failure...
69Value *SymbolTable::lookup(const Type *Ty, const string &Name) {
70 iterator I = find(Ty);
71 if (I != end()) { // We have symbols in that plane...
72 type_iterator J = I->second.find(Name);
73 if (J != I->second.end()) // and the name is in our hash table...
74 return J->second;
75 }
76
77 return ParentSymTab ? ParentSymTab->lookup(Ty, Name) : 0;
78}
79
80void SymbolTable::remove(Value *N) {
81 assert(N->hasName() && "Value doesn't have name!");
82 assert(type_find(N) != type_end(N->getType()) &&
83 "Value not in symbol table!");
84 type_remove(type_find(N));
85}
86
87
88#define DEBUG_SYMBOL_TABLE 0
89
90Value *SymbolTable::type_remove(const type_iterator &It) {
91 Value *Result = It->second;
92#if DEBUG_SYMBOL_TABLE
93 cerr << this << " Removing Value: " << Result->getName() << endl;
94#endif
95
96 find(Result->getType())->second.erase(It);
97
98 return Result;
99}
100
101void SymbolTable::insert(Value *N) {
102 assert(N->hasName() && "Value must be named to go into symbol table!");
103
104 // TODO: The typeverifier should catch this when its implemented
105 if (lookup(N->getType(), N->getName())) {
106 cerr << "SymbolTable WARNING: Name already in symbol table: '"
107 << N->getName() << "'\n";
108 abort(); // TODO: REMOVE THIS
109 }
110
111#if DEBUG_SYMBOL_TABLE
112 cerr << this << " Inserting definition: " << N->getName() << ": "
113 << N->getType()->getName() << endl;
114#endif
115
116 iterator I = find(N->getType());
117 if (I == end()) { // Not in collection yet... insert dummy entry
118 (*this)[N->getType()] = VarMap();
119 I = find(N->getType());
120 assert(I != end() && "How did insert fail?");
121 }
122
123 I->second.insert(make_pair(N->getName(), N));
124}
125