diff options
Diffstat (limited to 'src/symbol.c')
-rw-r--r-- | src/symbol.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/src/symbol.c b/src/symbol.c index 80c01a3..677f510 100644 --- a/src/symbol.c +++ b/src/symbol.c | |||
@@ -24,6 +24,7 @@ static Hash_table *symbol_table; | |||
24 | 24 | ||
25 | static struct linked_list *static_symbol_list; | 25 | static struct linked_list *static_symbol_list; |
26 | static struct linked_list *auto_symbol_list; | 26 | static struct linked_list *auto_symbol_list; |
27 | static struct linked_list *static_func_list; | ||
27 | 28 | ||
28 | static void | 29 | static void |
29 | append_symbol(struct linked_list **plist, Symbol *sp) | 30 | append_symbol(struct linked_list **plist, Symbol *sp) |
@@ -207,11 +208,13 @@ static_free(void *data) | |||
207 | 208 | ||
208 | if (!t) | 209 | if (!t) |
209 | return; | 210 | return; |
210 | if (sym->flag == symbol_temp | 211 | if (sym->flag == symbol_temp) |
211 | || globals_only()) | ||
212 | delete_symbol(sym); | 212 | delete_symbol(sym); |
213 | else | 213 | else { |
214 | unlink_symbol(sym); | 214 | unlink_symbol(sym); |
215 | if (symbol_is_function(sym)) | ||
216 | linked_list_append(&static_func_list, sym); | ||
217 | } | ||
215 | } | 218 | } |
216 | 219 | ||
217 | void | 220 | void |
@@ -280,8 +283,9 @@ collect_processor(void *data, void *proc_data) | |||
280 | return true; | 283 | return true; |
281 | } | 284 | } |
282 | 285 | ||
283 | int | 286 | size_t |
284 | collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p)) | 287 | collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p), |
288 | size_t reserved_slots) | ||
285 | { | 289 | { |
286 | struct collect_data cdata; | 290 | struct collect_data cdata; |
287 | 291 | ||
@@ -289,7 +293,7 @@ collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p)) | |||
289 | cdata.index = 0; | 293 | cdata.index = 0; |
290 | cdata.sel = sel; | 294 | cdata.sel = sel; |
291 | hash_do_for_each (symbol_table, collect_processor, &cdata); | 295 | hash_do_for_each (symbol_table, collect_processor, &cdata); |
292 | cdata.sym = calloc(cdata.index, sizeof(*cdata.sym)); | 296 | cdata.sym = calloc(cdata.index + reserved_slots, sizeof(*cdata.sym)); |
293 | if (!cdata.sym) | 297 | if (!cdata.sym) |
294 | xalloc_die(); | 298 | xalloc_die(); |
295 | cdata.index = 0; | 299 | cdata.index = 0; |
@@ -298,6 +302,31 @@ collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p)) | |||
298 | return cdata.index; | 302 | return cdata.index; |
299 | } | 303 | } |
300 | 304 | ||
305 | size_t | ||
306 | collect_functions(Symbol ***return_sym) | ||
307 | { | ||
308 | Symbol **symbols; | ||
309 | size_t num, snum; | ||
310 | struct linked_list_entry *p; | ||
311 | |||
312 | /* Count static functions */ | ||
313 | snum = 0; | ||
314 | if (static_func_list) | ||
315 | for (p = linked_list_head(static_func_list); p; p = p->next) | ||
316 | snum++; | ||
317 | |||
318 | /* Collect global functions */ | ||
319 | num = collect_symbols(&symbols, symbol_is_function, snum); | ||
320 | |||
321 | /* Collect static functions */ | ||
322 | if (snum) | ||
323 | for (p = linked_list_head(static_func_list); p; p = p->next) | ||
324 | symbols[num++] = p->data; | ||
325 | *return_sym = symbols; | ||
326 | return num; | ||
327 | } | ||
328 | |||
329 | |||
301 | 330 | ||
302 | /* Special handling for function parameters */ | 331 | /* Special handling for function parameters */ |
303 | 332 | ||