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>
12 /* snoot symbol table management */
16 struct entry
/* symbol table entry: */
18 struct symbol sym
; /* the symbol */
19 List refs
; /* list form of sym.uses */
20 struct entry
*link
; /* next entry on hash chain */
23 struct table
/* symbol tables: */
25 int level
; /* scope level for this table */
26 struct table
*previous
; /* table for previous scope */
27 Symbol list
; /* list of entries via up fields */
28 struct entry
*buckets
[HASHSIZE
];
32 tconstants
= { CONSTANTS
},
33 texternals
= { GLOBAL
},
34 tidentifiers
= { GLOBAL
},
37 Table constants
= &tconstants
; /* constants */
38 Table externals
= &texternals
; /* externals */
39 Table identifiers
= &tidentifiers
; /* identifiers */
40 Table globals
= &tidentifiers
; /* globals */
41 Table labels
[2]; /* labels */
42 Table types
= &ttypes
; /* types */
44 int bnumber
; /* current block number */
45 int level
; /* current block level */
47 /* constant - install and return constant value of type ty */
48 extern Symbol
symbol_for_string_const(type_node
*ty
, char *value
)
51 unsigned h
= ((unsigned)value
) & (HASHSIZE
- 1);
54 for (p
= constants
->buckets
[h
]; p
!= NULL
; p
= p
->link
)
56 if (eqtype(ty
, p
->sym
.type
, TRUE
))
58 if (value
== p
->sym
.u
.c
.v
.p
)
62 p
= (struct entry
*)alloc(sizeof *p
);
64 p
->sym
.scope
= CONSTANTS
;
66 p
->sym
.sclass
= STATIC
;
67 p
->sym
.u
.c
.v
.p
= value
;
68 p
->sym
.u
.c
.loc
= NULL
;
69 p
->sym
.suif_symbol
= NULL
;
73 p
->sym
.initialized
= 0;
75 p
->sym
.src
.file
= NULL
;
79 p
->link
= constants
->buckets
[h
];
80 p
->sym
.up
= constants
->list
;
81 constants
->list
= &p
->sym
;
82 constants
->buckets
[h
] = p
;
88 /* enterscope - enter a scope */
91 if (++level
>= USHRT_MAX
)
92 error("compound statements nested too deeply\n");
95 /* exitscope - exit a scope */
98 if (identifiers
->level
== level
)
104 for (p
= identifiers
->list
; (p
!= NULL
) && (p
->scope
== level
);
109 warning("more than 127 identifiers declared in a block\n");
115 setuses(identifiers
);
116 identifiers
= identifiers
->previous
;
118 if (types
->level
== level
)
122 foreach(types
, level
, fielduses
, NULL
);
125 types
= types
->previous
;
127 assert(level
>= GLOBAL
);
131 /* fielduses - convert use lists for fields in type p */
132 void fielduses(Symbol p
, Generic
)
134 if ((p
->type
!= NULL
) && isstruct_or_union(p
->type
))
136 struct_type
*the_struct
= (struct_type
*)(p
->type
->unqual());
137 Table field_table
= get_field_table(the_struct
);
138 if (field_table
!= NULL
)
139 setuses(field_table
);
143 /* findtype - find type ty in identifiers */
144 Symbol
findtype(type_node
*ty
)
146 Table tp
= identifiers
;
153 for (i
= 0; i
< HASHSIZE
; i
++)
155 for (p
= tp
->buckets
[i
]; p
!= NULL
; p
= p
->link
)
157 if (p
->sym
.type
== ty
&& p
->sym
.sclass
== TYPEDEF
)
161 } while ((tp
= tp
->previous
) != NULL
);
165 /* foreach - call f(p) for each entry p in table tp */
166 void foreach(Table tp
, int lev
, void (*apply
)(Symbol
, Generic
), Generic cl
)
169 while ((tp
!= NULL
) && (tp
->level
> lev
))
171 if ((tp
!= NULL
) && (tp
->level
== lev
))
176 for (p
= tp
->list
; (p
!= NULL
) && (p
->scope
== lev
); p
= p
->up
)
185 /* genlabel - generate a system generated label */
186 label_sym
*genlabel(void)
188 label_sym
*result
= curr_proc
->block()->proc_syms()->new_unique_label("L");
189 result
->reset_userdef();
193 /* gen_user_label - generate a user generated label */
194 label_sym
*gen_user_label(char *name
)
196 proc_symtab
*the_proc_symtab
= curr_proc
->block()->proc_syms();
198 /* if the label already exists and isn't user-defined, rename the
200 label_sym
*old_label
= the_proc_symtab
->lookup_label(name
, FALSE
);
201 if ((old_label
!= NULL
) && (!old_label
->is_userdef()))
203 label_sym
*temp_label
= the_proc_symtab
->new_unique_label("L");
204 old_label
->set_name(temp_label
->name());
205 the_proc_symtab
->remove_sym(temp_label
);
209 label_sym
*result
= the_proc_symtab
->new_label(name
);
210 result
->set_userdef();
214 const char *gen_internal_name(void)
217 static int name_counter
= 1;
219 sprintf(num_buffer
, "%d", name_counter
);
221 return lexicon
->enter(num_buffer
)->sp
;
224 /* install - install name in table *tp; permanently allocate entry iff
226 Symbol
install(const char *name
, Table
*tpp
, int perm
)
229 unsigned h
= (unsigned)name
& (HASHSIZE
- 1);
231 if (((tpp
== &identifiers
) || (tpp
== &types
)) && ((*tpp
)->level
< level
))
232 *tpp
= table(*tpp
, level
);
234 p
= (struct entry
*)alloc(sizeof *p
);
236 p
= (struct entry
*)talloc(sizeof *p
);
238 p
->sym
.scope
= (*tpp
)->level
;
239 p
->sym
.up
= (*tpp
)->list
;
240 p
->sym
.suif_symbol
= NULL
;
243 p
->sym
.temporary
= 0;
245 p
->sym
.initialized
= 0;
248 p
->sym
.src
.file
= NULL
;
252 (*tpp
)->list
= &p
->sym
;
253 p
->link
= (*tpp
)->buckets
[h
];
254 (*tpp
)->buckets
[h
] = p
;
259 /* lookup - lookup name in table tp, return pointer to entry */
260 Symbol
lookup(const char *name
, Table tp
)
263 unsigned h
= (unsigned)name
& (HASHSIZE
- 1);
268 for (p
= tp
->buckets
[h
]; p
!= NULL
; p
= p
->link
)
270 if (name
== p
->sym
.name
)
273 } while ((tp
= tp
->previous
));
277 /* setuses - convert p->refs to p->uses for all p at the current level in *tp
279 void setuses(Table tp
)
285 for (i
= 0; i
< HASHSIZE
; i
++)
287 for (p
= tp
->buckets
[i
]; p
!= NULL
; p
= p
->link
)
290 p
->sym
.uses
= (Coordinate
**)ltoa(p
->refs
, 0);
297 /* table - create a new table with predecessor tp, scope lev */
298 Table
table(Table tp
, int lev
)
301 Table new_table
= (Table
)talloc(sizeof *new_table
);
303 assert((lev
> GLOBAL
) || (lev
== LABELS
));
304 new_table
->previous
= tp
;
305 new_table
->level
= lev
;
306 new_table
->list
= ((tp
!= NULL
) ? tp
->list
: NULL
);
307 for (i
= 0; i
< HASHSIZE
; i
++)
308 new_table
->buckets
[i
] = 0;
312 /* use - add src to the list of uses for p */
313 void use(Symbol p
, Coordinate src
)
317 Coordinate
*cp
= (Coordinate
*)alloc(sizeof *cp
);
319 ((struct entry
*)p
)->refs
=
320 append((Generic
)cp
, ((struct entry
*)p
)->refs
);
324 extern void annotate_with_refs(Symbol the_sym
)
327 assert(the_sym
->suif_symbol
!= NULL
);
329 struct entry
*the_entry
= (struct entry
*)the_sym
;
330 List ref_list
= the_entry
->refs
;
331 if (ref_list
== NULL
)
334 immed_list
*the_immeds
= new immed_list
;
335 while (ref_list
!= NULL
)
337 Coordinate
*this_coordinate
= (Coordinate
*)ref_list
->x
;
338 the_immeds
->append(immed(this_coordinate
->file
));
339 the_immeds
->append(immed((int)this_coordinate
->x
));
340 the_immeds
->append(immed((int)this_coordinate
->y
));
341 ref_list
= ref_list
->link
;
344 the_sym
->suif_symbol
->append_annote(k_source_references
, the_immeds
);