aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore/ValueSymbolTable.cpp
blob: 6efb9983874ef087f91f5ae2dc262bd36968556c (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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//===-- ValueSymbolTable.cpp - Implement the ValueSymbolTable class -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group.  It is distributed under 
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the ValueSymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/GlobalValue.h"
#include "llvm/Type.h"
#include "llvm/ValueSymbolTable.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;

#define DEBUG_SYMBOL_TABLE 0
#define DEBUG_ABSTYPE 0

// Class destructor
ValueSymbolTable::~ValueSymbolTable() {
#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ++VI)
    if (!isa<Constant>(VI->second) ) {
      DOUT << "Value still in symbol table! Type = '"
           << VI->second->getType()->getDescription() << "' Name = '"
           << VI->first << "'\n";
      LeftoverValues = false;
    }
  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

// 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.
//
std::string ValueSymbolTable::getUniqueName(const std::string &BaseName) const {
  std::string TryName = BaseName;
  const_iterator End = vmap.end();

  // See if the name exists
  while (vmap.find(TryName) != End)            // Loop until we find a free
    TryName = BaseName + utostr(++LastUnique); // name in the symbol table
  return TryName;
}


// lookup a value - Returns null on failure...
//
Value *ValueSymbolTable::lookup(const std::string &Name) const {
  const_iterator VI = vmap.find(Name);
  if (VI != vmap.end())                   // We found the symbol
    return const_cast<Value*>(VI->second);
  return 0;
}

// Strip the symbol table of its names.
//
bool ValueSymbolTable::strip() {
  bool RemovedSymbol = false;
  for (iterator VI = vmap.begin(), VE = vmap.end(); VI != VE; ) {
    Value *V = VI->second;
    ++VI;
    if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
      // Set name to "", removing from symbol table!
      V->setName("");
      RemovedSymbol = true;
    }
  }
  return RemovedSymbol;
}

// Insert a value into the symbol table with the specified name...
//
void ValueSymbolTable::insert(Value* V) {
  assert(V && "Can't insert null Value into symbol table!");
  assert(V->hasName() && "Can't insert nameless Value into symbol table");

  // Check to see if there is a naming conflict.  If so, rename this type!
  std::string UniqueName = getUniqueName(V->getName());

#if DEBUG_SYMBOL_TABLE
  dump();
  DOUT << " Inserting value: " << UniqueName << ": " << V->dump() << "\n";
#endif

  // Insert the vmap entry
  vmap.insert(make_pair(UniqueName, V));
}

// Remove a value
bool ValueSymbolTable::erase(Value *V) {
  assert(V->hasName() && "Value doesn't have name!");
  iterator Entry = vmap.find(V->getName());
  if (Entry == vmap.end())
    return false;

#if DEBUG_SYMBOL_TABLE
  dump();
  DOUT << " Removing Value: " << Entry->second->getName() << "\n";
#endif

  // Remove the value from the plane...
  vmap.erase(Entry);
  return true;
}


// rename - Given a value with a non-empty name, remove its existing entry
// from the symbol table and insert a new one for Name.  This is equivalent to
// doing "remove(V), V->Name = Name, insert(V)", 
//
bool ValueSymbolTable::rename(Value *V, const std::string &name) {
  assert(V && "Can't rename a null Value");
  assert(V->hasName() && "Can't rename a nameless Value");
  assert(!V->getName().empty() && "Can't rename an Value with null name");
  assert(V->getName() != name && "Can't rename a Value with same name");
  assert(!name.empty() && "Can't rename a named Value with a null name");

  // Find the name
  iterator VI = vmap.find(V->getName());

  // If we didn't find it, we're done
  if (VI == vmap.end())
    return false;

  // Remove the old entry.
  vmap.erase(VI);

  // See if we can insert the new name.
  VI = vmap.lower_bound(name);

  // Is there a naming conflict?
  if (VI != vmap.end() && VI->first == name) {
    V->Name = getUniqueName( name);
    vmap.insert(make_pair(V->Name, V));
  } else {
    V->Name = name;
    vmap.insert(VI, make_pair(name, V));
  }

  return true;
}

// DumpVal - a std::for_each function for dumping a value
//
static void DumpVal(const std::pair<const std::string, Value *> &V) {
  DOUT << "  '" << V.first << "' = ";
  V.second->dump();
  DOUT << "\n";
}

// dump - print out the symbol table
//
void ValueSymbolTable::dump() const {
  DOUT << "ValueSymbolTable:\n";
  for_each(vmap.begin(), vmap.end(), DumpVal);
}