summaryrefslogtreecommitdiff
path: root/include/llvm/SymbolTable.h
blob: 52a2c29ea7814917fa0dfbd5b42c0f01c71cee75 (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
//===-- llvm/SymbolTable.h - Implement a type plane'd symtab ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and re-written by Reid
// Spencer. It is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the main symbol table for LLVM.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SYMBOL_TABLE_H
#define LLVM_SYMBOL_TABLE_H

#include "llvm/Value.h"
#include "llvm/Support/DataTypes.h"
#include <map>

namespace llvm {

/// This class provides a symbol table of name/value pairs that is broken
/// up by type. For each Type* there is a "plane" of name/value pairs in
/// the symbol table.  Identical types may have overlapping symbol names as
/// long as they are distinct. The SymbolTable also tracks,  separately, a
/// map of name/type pairs. This allows types to be named. Types are treated
/// distinctly from Values.
///
/// The SymbolTable provides several utility functions for answering common
/// questions about its contents as well as an iterator interface for
/// directly iterating over the contents. To reduce confusion, the terms
/// "type", "value", and "plane" are used consistently. For example,
/// There is a TypeMap typedef that is the mapping of names to Types.
/// Similarly there is a ValueMap typedef that is the mapping of
/// names to Values. Finally, there is a PlaneMap typedef that is the
/// mapping of types to planes of ValueMap. This is the basic structure
/// of the symbol table. When you call type_begin() you're asking
/// for an iterator at the start of the TypeMap. When you call
/// plane_begin(), you're asking for an iterator at the start of
/// the PlaneMap. Finally, when you call value_begin(), you're asking
/// for an iterator at the start of a ValueMap for a specific type
/// plane.
class SymbolTable : public AbstractTypeUser {

/// @name Types
/// @{
public:

  /// @brief A mapping of names to types.
  typedef std::map<const std::string, const Type*> TypeMap;

  /// @brief An iterator over the TypeMap.
  typedef TypeMap::iterator type_iterator;

  /// @brief A const_iterator over the TypeMap.
  typedef TypeMap::const_iterator type_const_iterator;

  /// @brief A mapping of names to values.
  typedef std::map<const std::string, Value *> ValueMap;

  /// @brief An iterator over a ValueMap.
  typedef ValueMap::iterator value_iterator;

  /// @brief A const_iterator over a ValueMap.
  typedef ValueMap::const_iterator value_const_iterator;

  /// @brief A mapping of types to names to values (type planes).
  typedef std::map<const Type *, ValueMap> PlaneMap;

  /// @brief An iterator over the type planes.
  typedef PlaneMap::iterator plane_iterator;

  /// @brief A const_iterator over the type planes
  typedef PlaneMap::const_iterator plane_const_iterator;

/// @}
/// @name Constructors
/// @{
public:

  SymbolTable() : LastUnique(0) {}
  ~SymbolTable();

/// @}
/// @name Accessors
/// @{
public:

  /// This method finds the value with the given \p name in the
  /// type plane \p Ty and returns it. This method will not find any
  /// Types, only Values. Use lookupType to find Types by name.
  /// @returns null on failure, otherwise the Value associated with
  /// the \p name in type plane \p Ty.
  /// @brief Lookup a named, typed value.
  Value *lookup(const Type *Ty, const std::string &name) const;

  /// This method finds the type with the given \p name in the
  /// type  map and returns it.
  /// @returns null if the name is not found, otherwise the Type
  /// associated with the \p name.
  /// @brief Lookup a type by name.
  Type* lookupType(const std::string& name) const;

  /// @returns true iff the type map and the type plane are both not
  /// empty.
  /// @brief Determine if the symbol table is empty
  inline bool isEmpty() const { return pmap.empty() && tmap.empty(); }

  /// @brief The number of name/type pairs is returned.
  inline unsigned num_types() const { return unsigned(tmap.size()); }

  /// 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.
  /// @brief Get a name unique to this symbol table
  std::string getUniqueName(const Type *Ty,
                            const std::string &BaseName) const;

  /// This function can be used from the debugger to display the
  /// content of the symbol table while debugging.
  /// @brief Print out symbol table on stderr
  void dump() const;

/// @}
/// @name Iteration
/// @{
public:

  /// Get an iterator that starts at the beginning of the type planes.
  /// The iterator will iterate over the Type/ValueMap pairs in the
  /// type planes.
  inline plane_iterator plane_begin() { return pmap.begin(); }

  /// Get a const_iterator that starts at the beginning of the type
  /// planes.  The iterator will iterate over the Type/ValueMap pairs
  /// in the type planes.
  inline plane_const_iterator plane_begin() const { return pmap.begin(); }

  /// Get an iterator at the end of the type planes. This serves as
  /// the marker for end of iteration over the type planes.
  inline plane_iterator plane_end() { return pmap.end(); }

  /// Get a const_iterator at the end of the type planes. This serves as
  /// the marker for end of iteration over the type planes.
  inline plane_const_iterator plane_end() const { return pmap.end(); }

  /// Get an iterator that starts at the beginning of a type plane.
  /// The iterator will iterate over the name/value pairs in the type plane.
  /// @note The type plane must already exist before using this.
  inline value_iterator value_begin(const Type *Typ) {
    assert(Typ && "Can't get value iterator with null type!");
    return pmap.find(Typ)->second.begin();
  }

  /// Get a const_iterator that starts at the beginning of a type plane.
  /// The iterator will iterate over the name/value pairs in the type plane.
  /// @note The type plane must already exist before using this.
  inline value_const_iterator value_begin(const Type *Typ) const {
    assert(Typ && "Can't get value iterator with null type!");
    return pmap.find(Typ)->second.begin();
  }

  /// Get an iterator to the end of a type plane. This serves as the marker
  /// for end of iteration of the type plane.
  /// @note The type plane must already exist before using this.
  inline value_iterator value_end(const Type *Typ) {
    assert(Typ && "Can't get value iterator with null type!");
    return pmap.find(Typ)->second.end();
  }

  /// Get a const_iterator to the end of a type plane. This serves as the
  /// marker for end of iteration of the type plane.
  /// @note The type plane must already exist before using this.
  inline value_const_iterator value_end(const Type *Typ) const {
    assert(Typ && "Can't get value iterator with null type!");
    return pmap.find(Typ)->second.end();
  }

  /// Get an iterator to the start of the name/Type map.
  inline type_iterator type_begin() { return tmap.begin(); }

  /// @brief Get a const_iterator to the start of the name/Type map.
  inline type_const_iterator type_begin() const { return tmap.begin(); }

  /// Get an iterator to the end of the name/Type map. This serves as the
  /// marker for end of iteration of the types.
  inline type_iterator type_end() { return tmap.end(); }

  /// Get a const-iterator to the end of the name/Type map. This serves
  /// as the marker for end of iteration of the types.
  inline type_const_iterator type_end() const { return tmap.end(); }

  /// This method returns a plane_const_iterator for iteration over
  /// the type planes starting at a specific plane, given by \p Ty.
  /// @brief Find a type plane.
  inline plane_const_iterator find(const Type* Typ) const {
    assert(Typ && "Can't find type plane with null type!");
    return pmap.find(Typ);
  }

  /// This method returns a plane_iterator for iteration over the
  /// type planes starting at a specific plane, given by \p Ty.
  /// @brief Find a type plane.
  inline plane_iterator find(const Type* Typ) {
    assert(Typ && "Can't find type plane with null type!");
    return pmap.find(Typ);
  }


/// @}
/// @name Mutators
/// @{
public:

  /// This method will strip the symbol table of its names leaving the type and
  /// values.
  /// @brief Strip the symbol table.
  bool strip();

  /// Inserts a type into the symbol table with the specified name. There can be
  /// a many-to-one mapping between names and types. This method allows a type
  /// with an existing entry in the symbol table to get a new name.
  /// @brief Insert a type under a new name.
  void insert(const std::string &Name, const Type *Typ);

  /// Remove a type at the specified position in the symbol table.
  /// @returns the removed Type.
  Type* remove(type_iterator TI);

/// @}
/// @name Mutators used by Value::setName and other LLVM internals.
/// @{
public:

  /// This method adds the provided value \p N to the symbol table.  The Value
  /// must have both a name and a type which are extracted and used to place the
  /// value in the correct type plane under the value's name.
  /// @brief Add a named value to the symbol table
  inline void insert(Value *Val) {
    assert(Val && "Can't insert null type into symbol table!");
    assert(Val->hasName() && "Value must be named to go into symbol table!");
    insertEntry(Val->getName(), Val->getType(), Val);
  }

  /// This method removes a named value from the symbol table. The type and name
  /// of the Value are extracted from \p N and used to lookup the Value in the
  /// correct type plane. If the Value is not in the symbol table, this method
  /// silently ignores the request.
  /// @brief Remove a named value from the symbol table.
  void remove(Value* Val);

  /// changeName - 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)", but is faster,
  /// and will not temporarily remove the symbol table plane if V is the last
  /// value in the symtab with that name (which could invalidate iterators to
  /// that plane).
  void changeName(Value *V, const std::string &Name);

/// @}
/// @name Internal Methods
/// @{
private:
  /// @brief Insert a value into the symbol table with the specified name.
  void insertEntry(const std::string &Name, const Type *Ty, Value *V);

  /// This function is called when one of the types in the type plane
  /// is refined.
  virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);

  /// This function markes a type as being concrete (defined).
  virtual void typeBecameConcrete(const DerivedType *AbsTy);

/// @}
/// @name Internal Data
/// @{
private:

  /// This is the main content of the symbol table. It provides
  /// separate type planes for named values. That is, each named
  /// value is organized into a separate dictionary based on
  /// Type. This means that the same name can be used for different
  /// types without conflict.
  /// @brief The mapping of types to names to values.
  PlaneMap pmap;

  /// This is the type plane. It is separated from the pmap
  /// because the elements of the map are name/Type pairs not
  /// name/Value pairs and Type is not a Value.
  TypeMap tmap;

  /// This value is used to retain the last unique value used
  /// by getUniqueName to generate unique names.
  mutable uint32_t LastUnique;

/// @}

};

} // End llvm namespace

// vim: sw=2

#endif