summaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c180
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 (&current_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 (&current_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"