1 /* Symbol Table Classes */
3 /* Copyright (c) 1994 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
18 "$Id: symtab.h,v 1.2 1999/08/25 03:29:17 brm Exp $")
22 class base_symtab_list
;
35 /* These functions affect how base_symtab::write() writes out the duplicate
38 extern void enable_automatic_renaming(void);
39 extern void disable_automatic_renaming(void);
42 * The ID numbers used for sym_nodes and type_nodes are divided into
43 * three ranges. To make it easier to read an ID number, this function
44 * prints it as a single character to identify the range ("g" = global,
45 * "f" = file, "p" = procedure) combined with the offset of the number
49 extern void print_id_number(FILE *fp
, unsigned id
);
53 * A symtab contains lists of symbols and types that may be used within the
54 * scope associated with the symtab. The base_symtab class is abstract and
55 * contains variables and methods shared by all of the other symbol tables.
56 * The symtabs form a strict hierarchy starting with the global symtab,
57 * followed by one symtab per file, followed by symtabs for the individual
58 * procedures and blocks. Each symtab has a name and all of the children of
59 * a particular symtab should have unique names. Symtabs are automatically
60 * removed and destroyed along with the corresponding "scopes", e.g.
61 * deleting a tree_block also deletes its block_symtab.
64 class base_symtab
: public suif_object
{
65 friend class sym_node
;
66 friend class type_node
;
70 void chain_name_helper();
73 sym_node_list
*syms
; /* list of symbols */
74 var_def_list
*defs
; /* variable definitions */
75 type_node_list
*typs
; /* list of types */
76 base_symtab
*par
; /* parent symtab */
77 base_symtab_list
*childs
; /* list of child symtabs */
78 const char *nm
; /* name of this symtab */
79 unsigned next_sym_id
; /* next unused symbol ID number */
80 unsigned next_type_id
; /* next unused type ID number */
81 unsigned var_counter
; /* for creating unique var_syms */
82 string_index
*sym_name_index
; /* for fast lookups by name */
83 ptr_index
*def_index
; /* for fast lookups by var_sym */
84 ptr_index
*sym_id_index
; /* for fast lookups by id # */
85 ptr_index
*type_id_index
; /* for fast lookups by id # */
87 void print_contents(FILE *fp
, int depth
);
89 void add_contents_to_replacements(replacements
*r
);
90 virtual base_symtab
*new_peer(char *n
) = 0;
91 /* create a new symtab of the same
92 sub-class as this one */
94 void register_name_change(sym_node
*the_sym
, const char *new_name
);
95 void register_sym_id_change(sym_node
*the_sym
, unsigned new_id
);
96 void register_type_id_change(type_node
*the_type
, unsigned new_id
);
97 void add_name_entry(sym_node
*the_sym
, const char *new_name
);
98 void remove_name_entry(sym_node
*the_sym
, const char *old_name
);
99 void register_def_sym_change(var_def
*the_def
, var_sym
*new_var
);
101 void set_sym_extern(sym_node
*the_sym
, boolean new_value
)
102 { the_sym
->set_extern(new_value
); }
103 void set_sym_id(sym_node
*the_sym
, unsigned new_id
)
104 { the_sym
->set_sym_id(new_id
); }
106 void remove_def_internal(var_def
*d
, boolean in_destructor
);
109 base_symtab(const char *n
); /* the symtab name */
110 virtual ~base_symtab();
112 object_kinds
object_kind() { return SYMTAB_OBJ
; }
114 virtual symtab_kinds
kind() = 0;
116 boolean
is_global() { return ((kind() == SYMTAB_GLOBAL
) ||
117 (kind() == SYMTAB_FILE
)); }
118 boolean
is_file() { return (kind() == SYMTAB_FILE
); }
119 boolean
is_block() { return ((kind() == SYMTAB_BLOCK
) ||
120 (kind() == SYMTAB_PROC
)); }
121 boolean
is_proc() { return kind() == SYMTAB_PROC
; }
123 base_symtab
*parent() { return par
; }
124 sym_node_list
*symbols() { return syms
; }
125 var_def_list
*var_defs() { return defs
; }
126 base_symtab_list
*children() { return childs
; }
127 type_node_list
*types() { return typs
; }
128 const char *name() { return nm
; }
129 char *chain_name(); /* writes to static buffer! */
131 void set_name(const char *n
);
132 void rename_duplicates(); /* give unique names to everything */
134 base_symtab
*lookup_child(const char *name
);
135 var_def
*lookup_var_def(var_sym
*v
);
136 type_node
*lookup_type(type_node
*t
, boolean up
=TRUE
);
137 sym_node
*lookup_sym(const char *name
, sym_kinds k
, boolean up
=TRUE
);
138 var_sym
*lookup_var(const char *name
, boolean up
=TRUE
)
139 { return (var_sym
*)lookup_sym(name
, SYM_VAR
, up
); }
141 boolean
is_visible(type_node
*the_type
)
142 { return is_ancestor(the_type
->parent()); }
143 boolean
is_visible(sym_node
*the_sym
)
144 { return is_ancestor(the_sym
->parent()); }
146 sym_node
*lookup_sym_id(unsigned i
);
147 type_node
*lookup_type_id(unsigned i
);
149 var_sym
*new_var(type_node
*t
, const char *n
);
150 var_sym
*new_unique_var(type_node
*t
, const char *base
= NULL
);
151 var_def
*define_var(var_sym
*v
, int a
);
153 boolean
is_ancestor(base_symtab
*s
);
155 /* add a type and its component types if they do not already exist in this
156 or a parent symtab; deletes type_nodes that are replaced */
157 type_node
*install_type(type_node
*t
);
159 /* attempt to move a type so that it is visible in this scope */
160 boolean
make_type_visible(type_node
*t
, boolean check
= FALSE
);
162 void resolve_exposed_refs(replacements
*r
);
163 base_symtab
*clone_helper(replacements
*r
, boolean no_copy
= FALSE
);
165 void add_child(base_symtab
*c
); /* sets c->parent */
166 virtual void add_sym(sym_node
*s
); /* sets s->table */
167 void add_type(type_node
*t
); /* sets t->table */
168 void add_def(var_def
*d
); /* sets d->table */
170 void remove_child(base_symtab
*c
); /* doesn't delete c */
171 void remove_sym(sym_node
*s
); /* doesn't delete s */
172 void remove_type(type_node
*t
); /* doesn't delete t */
173 void remove_def(var_def
*d
); /* doesn't delete d */
175 virtual void print(FILE *fp
=stdout
, int depth
=0) = 0;
176 virtual void write(out_stream
*os
);
177 virtual void read(in_stream
*is
);
180 DECLARE_DLIST_CLASS(base_symtab_list
, base_symtab
*);
184 * The global_symtab at the root of the symbol table hierarchy is used to
185 * hold symbols and types shared across files (i.e. those with external
186 * linkage). This class is also reused as the base class for file_symtabs.
187 * Since only global and file symtabs may contain procedure symbols, this
188 * class includes methods to create new proc_syms and to lookup existing
189 * ones. The number_globals function is automatically called just before
190 * writing the symtab to assign ID numbers to new symbol and type nodes.
193 class global_symtab
: public base_symtab
{
194 friend class file_set
;
197 virtual base_symtab
*new_peer(char *n
) { return new global_symtab(n
); }
200 global_symtab(const char *n
); /* name (usually "global") */
202 symtab_kinds
kind() { return SYMTAB_GLOBAL
; }
204 proc_sym
*new_proc(func_type
*r
, src_lang_type src
, const char *n
);
205 proc_sym
*lookup_proc(const char *s
, boolean up
=TRUE
)
206 { return (proc_sym
*)lookup_sym(s
, SYM_PROC
, up
); }
208 void predefine_types(); /* create common types */
209 void number_globals();
211 void add_sym(sym_node
*s
);
212 void print(FILE *fp
=stdout
, int depth
=0);
213 void write(out_stream
*os
);
218 * A file symtab is associated with a particular file_set_entry to hold
219 * symbols and types declared in the scope of the file (e.g. it contains
220 * the global variables declared with "static" linkage). This class is
221 * identical to the global_symtab class except for the file_set_entry
225 class file_symtab
: public global_symtab
{
226 friend class suif_linker
;
229 file_set_entry
*fset
; /* corresponding file_set_entry */
231 void set_fse(file_set_entry
*new_fse
) { fset
= new_fse
; }
234 virtual base_symtab
*new_peer(char *n
)
235 { return new file_symtab(n
, fse()); }
238 file_symtab(const char *n
, /* name (usually the input filename) */
239 file_set_entry
*fse
); /* corresponding file_set_entry */
241 symtab_kinds
kind() { return SYMTAB_FILE
; }
242 file_set_entry
*fse() { return fset
; }
244 void print(FILE *fp
=stdout
, int depth
=0);
249 * The block_symtab class is used for nested block symbol tables and as the
250 * base class for procedure symbol tables. Each one is associated with a
251 * particular tree_block (or tree_proc). The "new_unique_child" method can
252 * be used to create a new child block symtab with a unique name. Since
253 * label symbols may only be entered in symtabs within procedures, this
254 * class provides methods to create new labels and lookup existing ones.
257 class block_symtab
: public base_symtab
{
258 friend class tree_block
;
259 friend class tree_proc
;
262 unsigned label_counter
; /* for creating unique label_syms */
265 tree_block
*blk
; /* corresponding block */
267 void set_block(tree_block
*b
) { blk
= b
; }
268 void number_locals(unsigned *next_sym_idp
, unsigned *next_type_idp
);
270 virtual base_symtab
*new_peer(char *n
) { return new block_symtab(n
); }
273 block_symtab(const char *n
); /* block name */
275 symtab_kinds
kind() { return SYMTAB_BLOCK
; }
276 tree_block
*block() { return blk
; }
278 block_symtab
*new_unique_child(char *base
= NULL
);
280 label_sym
*new_label(char *n
);
281 label_sym
*new_unique_label(const char *base
= NULL
);
283 label_sym
*lookup_label(char *s
, boolean up
=TRUE
)
284 { return (label_sym
*)lookup_sym(s
, SYM_LABEL
, up
); }
286 void find_exposed_refs(base_symtab
*dst_scope
, replacements
*r
);
287 block_symtab
*clone_helper(replacements
*r
, boolean no_copy
= FALSE
);
289 void add_sym(sym_node
*s
);
290 void print(FILE *fp
=stdout
, int depth
=0);
291 void write(out_stream
*os
);
292 void read(in_stream
*is
);
297 * A proc_symtab is used as the top-level symbol table for a procedure.
298 * This class is basically the same as the block_symtab class with a few
299 * extensions. The proc_symtab also contains the list of parameters for
300 * the procedure. This is an ordered list of pointers to var_syms in the
301 * symtab; the flags for these var_syms must also be set to indicate that
302 * they are parameters. All of the instructions within the procedure are
303 * assigned unique numbers, and the proc_symtab keeps track of the next
304 * instruction number to be used. (The "tree_proc::number_instrs" function
305 * is used to assign these instruction numbers.) Finally, the "number_locals"
306 * function is called automatically just before writing the symtab to
307 * assign ID numbers to the symbols and types in this symtab and all of its
311 class proc_symtab
: public block_symtab
{
312 friend class block_symtab
;
313 friend class tree_proc
;
316 sym_node_list
*prms
; /* parameter list (in order) */
317 unsigned next_inum
; /* next unused instruction number */
320 virtual base_symtab
*new_peer(char *n
) { return new proc_symtab(n
); }
323 proc_symtab(const char *n
); /* name (usually the procedure name) */
326 symtab_kinds
kind() { return SYMTAB_PROC
; }
327 sym_node_list
*params() { return prms
; }
329 unsigned instr_num() { return next_inum
; }
330 unsigned next_instr_num() { return next_inum
++; }
332 void number_locals();
334 proc_symtab
*clone_helper(replacements
*r
, boolean no_copy
= FALSE
);
336 void print(FILE *fp
=stdout
, int depth
=0);
337 void write(out_stream
*os
);
338 void read(in_stream
*is
);
341 #endif /* SYMTAB_H */