diff options
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 180 |
1 files changed, 47 insertions, 133 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 7e3309edf8b..6c16801e4e2 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -103,21 +103,21 @@ static int current_function_prototype_line; /* The current statement tree. */ -static struct stmt_tree_s c_stmt_tree; +static GTY(()) struct stmt_tree_s c_stmt_tree; /* The current scope statement stack. */ -static tree c_scope_stmt_stack; +static GTY(()) tree c_scope_stmt_stack; /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function that have names. Here so we can clear out their names' definitions at the end of the function. */ -static tree named_labels; +static GTY(()) tree named_labels; /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ -static tree shadowed_labels; +static GTY(()) tree shadowed_labels; /* Nonzero when store_parm_decls is called indicates a varargs function. Value not meaningful after store_parm_decls. */ @@ -164,7 +164,7 @@ static int current_extern_inline; /* Note that the information in the `names' component of the global contour is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ -struct binding_level +struct binding_level GTY(()) { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order supplied. @@ -229,17 +229,17 @@ struct binding_level /* The binding level currently in effect. */ -static struct binding_level *current_binding_level; +static GTY(()) struct binding_level *current_binding_level; /* A chain of binding_level structures awaiting reuse. */ -static struct binding_level *free_binding_level; +static GTY((deletable (""))) struct binding_level *free_binding_level; /* The outermost binding level, for names of file scope. This is created when the compiler is started and exists through the entire run. */ -static struct binding_level *global_binding_level; +static GTY(()) struct binding_level *global_binding_level; /* Binding level structures are initialized by copying this one. */ @@ -262,7 +262,7 @@ static int keep_next_if_subblocks; saved values of named_labels and shadowed_labels for a label binding level outside the current one. */ -static struct binding_level *label_level_chain; +static GTY(()) struct binding_level *label_level_chain; /* Functions called automatically at the beginning and end of execution. */ @@ -271,7 +271,7 @@ tree static_ctors, static_dtors; /* Forward declarations. */ static struct binding_level * make_binding_level PARAMS ((void)); -static void mark_binding_level PARAMS ((void *)); +static void pop_binding_level PARAMS ((struct binding_level **)); static void clear_limbo_values PARAMS ((tree)); static int duplicate_decls PARAMS ((tree, tree, int)); static int redeclaration_error_message PARAMS ((tree, tree)); @@ -755,13 +755,33 @@ c_finish_incomplete_decl (decl) } } -/* Create a new `struct binding_level'. */ +/* Reuse or create a struct for this binding level. */ static struct binding_level * make_binding_level () { - /* NOSTRICT */ - return (struct binding_level *) xmalloc (sizeof (struct binding_level)); + if (free_binding_level) + { + struct binding_level *result = free_binding_level; + free_binding_level = result->level_chain; + return result; + } + else + return (struct binding_level *) ggc_alloc (sizeof (struct binding_level)); +} + +/* Remove a binding level from a list and add it to the level chain. */ + +static void +pop_binding_level (lp) + struct binding_level **lp; +{ + struct binding_level *l = *lp; + *lp = l->level_chain; + + memset (l, 0, sizeof (struct binding_level)); + l->level_chain = free_binding_level; + free_binding_level = l; } /* Nonzero if we are currently in the global binding level. */ @@ -829,17 +849,7 @@ pushlevel (tag_transparent) named_labels = 0; } - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } + newlevel = make_binding_level (); /* Add this level to the front of the chain (stack) of levels that are active. */ @@ -1060,13 +1070,7 @@ poplevel (keep, reverse, functionbody) /* Pop the current level, and free the structure for reuse. */ - { - struct binding_level *level = current_binding_level; - current_binding_level = current_binding_level->level_chain; - - level->level_chain = free_binding_level; - free_binding_level = level; - } + pop_binding_level (¤t_binding_level); /* Dispose of the block that we just made inside some higher level. */ if (functionbody) @@ -1145,17 +1149,7 @@ push_label_level () { struct binding_level *newlevel; - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } + newlevel = make_binding_level (); /* Add this level to the front of the chain (stack) of label levels. */ @@ -1217,9 +1211,7 @@ pop_label_level () shadowed_labels = level->shadowed; /* Pop the current level, and free the structure for reuse. */ - label_level_chain = label_level_chain->level_chain; - level->level_chain = free_binding_level; - free_binding_level = level; + pop_binding_level (&label_level_chain); } /* Push a definition or a declaration of struct, union or enum tag "name". @@ -2864,26 +2856,6 @@ lookup_name_current_level (name) return t; } -/* Mark ARG for GC. */ - -static void -mark_binding_level (arg) - void *arg; -{ - struct binding_level *level = *(struct binding_level **) arg; - - for (; level != 0; level = level->level_chain) - { - ggc_mark_tree (level->names); - ggc_mark_tree (level->tags); - ggc_mark_tree (level->shadowed); - ggc_mark_tree (level->blocks); - ggc_mark_tree (level->this_block); - ggc_mark_tree (level->parm_order); - ggc_mark_tree (level->incomplete_list); - } -} - /* Create the predefined scalar types of C, and some nodes representing standard constants (0, 1, (void *) 0). Initialize the global binding level. @@ -2937,20 +2909,6 @@ c_init_decl_processing () make_fname_decl = c_make_fname_decl; start_fname_decls (); - - /* Record our roots. */ - - ggc_add_tree_root (c_global_trees, CTI_MAX); - ggc_add_root (&c_stmt_tree, 1, sizeof c_stmt_tree, mark_stmt_tree); - ggc_add_tree_root (&c_scope_stmt_stack, 1); - ggc_add_tree_root (&named_labels, 1); - ggc_add_tree_root (&shadowed_labels, 1); - ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level, - mark_binding_level); - ggc_add_root (&label_level_chain, 1, sizeof label_level_chain, - mark_binding_level); - ggc_add_tree_root (&static_ctors, 1); - ggc_add_tree_root (&static_dtors, 1); } /* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the @@ -7045,9 +7003,9 @@ check_for_loop_decls () that keep track of the progress of compilation of the current function. Used for nested functions. */ -struct c_language_function +struct language_function GTY(()) { - struct language_function base; + struct c_language_function base; tree named_labels; tree shadowed_labels; int returns_value; @@ -7065,10 +7023,10 @@ void c_push_function_context (f) struct function *f; { - struct c_language_function *p; - p = ((struct c_language_function *) - xmalloc (sizeof (struct c_language_function))); - f->language = (struct language_function *) p; + struct language_function *p; + p = ((struct language_function *) + ggc_alloc (sizeof (struct language_function))); + f->language = p; p->base.x_stmt_tree = c_stmt_tree; p->base.x_scope_stmt_stack = c_scope_stmt_stack; @@ -7088,8 +7046,7 @@ void c_pop_function_context (f) struct function *f; { - struct c_language_function *p - = (struct c_language_function *) f->language; + struct language_function *p = f->language; tree link; /* Bring back all the labels that were shadowed. */ @@ -7119,26 +7076,7 @@ c_pop_function_context (f) current_extern_inline = p->extern_inline; current_binding_level = p->binding_level; - free (p); - f->language = 0; -} - -/* Mark the language specific parts of F for GC. */ - -void -c_mark_function_context (f) - struct function *f; -{ - struct c_language_function *p - = (struct c_language_function *) f->language; - - if (p == 0) - return; - - mark_c_language_function (&p->base); - ggc_mark_tree (p->shadowed_labels); - ggc_mark_tree (p->named_labels); - mark_binding_level (&p->binding_level); + f->language = NULL; } /* Copy the DECL_LANG_SPECIFIC data associated with DECL. */ @@ -7158,32 +7096,6 @@ c_dup_lang_specific_decl (decl) DECL_LANG_SPECIFIC (decl) = ld; } -/* Mark the language specific bits in T for GC. */ - -void -c_mark_tree (t) - tree t; -{ - if (TREE_CODE (t) == IDENTIFIER_NODE) - { - struct lang_identifier *i = (struct lang_identifier *) t; - ggc_mark_tree (i->global_value); - ggc_mark_tree (i->local_value); - ggc_mark_tree (i->label_value); - ggc_mark_tree (i->implicit_decl); - ggc_mark_tree (i->error_locus); - ggc_mark_tree (i->limbo_value); - } - else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t)) - ggc_mark (TYPE_LANG_SPECIFIC (t)); - else if (DECL_P (t) && DECL_LANG_SPECIFIC (t)) - { - ggc_mark (DECL_LANG_SPECIFIC (t)); - c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base); - ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes); - } -} - /* The functions below are required for functionality of doing function at once processing in the C front end. Currently these functions are not called from anywhere in the C front end, but as @@ -7319,3 +7231,5 @@ make_pointer_declarator (type_quals_attrs, target) itarget = tree_cons (attrs, target, NULL_TREE); return build1 (INDIRECT_REF, quals, itarget); } + +#include "gt-c-decl.h" |