aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/c-common.h1
-rw-r--r--gcc/cp/ChangeLog43
-rw-r--r--gcc/cp/cp-tree.h18
-rw-r--r--gcc/cp/decl.c454
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/optimize.c1
-rw-r--r--gcc/cp/parse.y7
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/cp/rtti.c1
-rw-r--r--gcc/cp/semantics.c303
12 files changed, 412 insertions, 429 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index debb219..fff0a31 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2000-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.h (genrtl_clear_out_block): Remove.
+ * c-semantics.c (genrtl_clear_out_block): Remove.
+ (genrtl_while_stmt): Don't call it.
+ (genrtl_for_stmt): Likewise.
+
2000-09-11 Zack Weinberg <zack@wolery.cumb.org>
* cppfiles.c: Move all default-#defines to top of file.
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 4fb6560..389f32a 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -570,7 +570,6 @@ enum c_tree_code {
extern void add_c_tree_codes PARAMS ((void));
extern void genrtl_do_pushlevel PARAMS ((void));
-extern void genrtl_clear_out_block PARAMS ((void));
extern void genrtl_goto_stmt PARAMS ((tree));
extern void genrtl_expr_stmt PARAMS ((tree));
extern void genrtl_decl_stmt PARAMS ((tree));
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f3cfd5d..756c40f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,46 @@
+2000-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct saved_scope): Remove x_function_parms.
+ (current_function_parms): Don't define.
+ (struct cp_language_function): Remove parms_stored.
+ (current_function_just_assigned_this): Don't define.
+ (current_function_parms_stored): Likewise.
+ (static_ctors): Declare.
+ (static_dtors): Likewise.
+ (SF_EXPAND): Don't define.
+ (expand_start_early_try_stmts): Remove declaration.
+ (store_parm_decls): Likewise.
+ * decl.c (static_ctors): Don't declare.
+ (static_dtors): Likewise.
+ (struct binding_level): Remove this_block.
+ (poplevel): Remove dead code.
+ (set_block): Likewise.
+ (mark_binding_level): Don't mark this_block.
+ (mark_saved_scope): Don't mark x_function_parms.
+ (init_decl_processing): Don't add current_function_parms as a GC
+ root.
+ (check_function_type): Change prototype.
+ (start_function): Remove RTL-generation code.
+ (expand_start_early_try_stmts): Remove.
+ (store_parm_decls): Give it internal linkage. Remove
+ RTL-generation code.
+ (finish_function): Remove RTL-generation code.
+ * decl2.c (static_ctors): Fix formatting.
+ (static_dtors): Likewise.
+ * method.c (use_thunk): Don't call store_parm_decls.
+ (synthesize_method): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * parse.y (fn.def2): Likewise.
+ (.set_base_init): Likewise.
+ (nodecls): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (genrtl_try_block): Simplify.
+ (expand_body): Use genrtl_start_function and
+ genrtl_finish_function.
+ (genrtl_start_function): New function.
+ (genrtl_finish_function): Likewise.
+
2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
* error.c (cp_tree_printer, case 'P'): Append break.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 97e3298..de76e52 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -792,7 +792,6 @@ struct saved_scope {
varray_type lang_base;
tree *lang_stack;
tree lang_name;
- tree x_function_parms;
tree template_parms;
tree x_previous_class_type;
tree x_previous_class_values;
@@ -841,7 +840,6 @@ struct saved_scope {
/* Parsing a function declarator leaves a list of parameter names
or a chain or parameter decls here. */
-#define current_function_parms scope_chain->x_function_parms
#define current_template_parms scope_chain->template_parms
#define processing_template_decl scope_chain->x_processing_template_decl
@@ -889,7 +887,6 @@ struct cp_language_function
int returns_value;
int returns_null;
- int parms_stored;
int in_function_try_handler;
int x_expanding_p;
int name_declared;
@@ -956,12 +953,6 @@ struct cp_language_function
#define current_function_returns_null cp_function_chain->returns_null
-#define current_function_just_assigned_this \
- cp_function_chain->just_assigned_this
-
-#define current_function_parms_stored \
- cp_function_chain->parms_stored
-
/* Nonzero if we have already generated code to initialize virtual
function tables in this function. */
@@ -3509,6 +3500,11 @@ extern int flag_inline_trees;
extern int at_eof;
+/* Functions called along with real static constructors and destructors. */
+
+extern tree static_ctors;
+extern tree static_dtors;
+
enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
/* Some macros for char-based bitfields. */
@@ -3637,8 +3633,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
already been parsed. */
#define SF_INCLASS_INLINE 2 /* The function is an inline, defined
in the class body. */
-#define SF_EXPAND 4 /* Generate RTL for this function. */
-
/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2
is derived from TYPE1, or if TYPE2 is a pointer (reference) to a
@@ -3905,8 +3899,6 @@ extern tree start_enum PARAMS ((tree));
extern tree finish_enum PARAMS ((tree));
extern void build_enumerator PARAMS ((tree, tree, tree));
extern int start_function PARAMS ((tree, tree, tree, int));
-extern void expand_start_early_try_stmts PARAMS ((void));
-extern void store_parm_decls PARAMS ((void));
extern tree finish_function PARAMS ((int));
extern tree start_method PARAMS ((tree, tree, tree));
extern tree finish_method PARAMS ((tree));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d82c32e..78a2f76 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -46,8 +46,6 @@ Boston, MA 02111-1307, USA. */
extern int current_class_depth;
-extern tree static_ctors, static_dtors;
-
extern tree global_namespace;
extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
@@ -163,7 +161,7 @@ static void mark_saved_scope PARAMS ((void *));
static void mark_lang_function PARAMS ((struct cp_language_function *));
static void mark_stmt_tree PARAMS ((stmt_tree));
static void save_function_data PARAMS ((tree));
-static void check_function_type PARAMS ((tree));
+static void check_function_type PARAMS ((tree, tree));
static void destroy_local_var PARAMS ((tree));
static void finish_constructor_body PARAMS ((void));
static void finish_destructor_body PARAMS ((void));
@@ -179,6 +177,7 @@ static tree check_special_function_return_type
static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
static int case_compare PARAMS ((splay_tree_key, splay_tree_key));
+static void store_parm_decls PARAMS ((tree));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
@@ -447,10 +446,6 @@ struct binding_level
that were entered and exited one level down. */
tree blocks;
- /* The BLOCK node for this level, if one has been preallocated.
- If 0, the BLOCK is allocated (if needed) when the level is popped. */
- tree this_block;
-
/* The _TYPE node for this level, if parm_flag == 2. */
tree this_class;
@@ -1288,7 +1283,6 @@ poplevel (keep, reverse, functionbody)
tree subblocks;
tree block = NULL_TREE;
tree decl;
- int block_previously_created;
int leaving_for_scope;
if (cfun && !doing_semantic_analysis_p ())
@@ -1396,34 +1390,12 @@ poplevel (keep, reverse, functionbody)
or if this level is a function body,
create a BLOCK to record them for the life of this function. */
block = NULL_TREE;
- block_previously_created = (current_binding_level->this_block != NULL_TREE);
- if (block_previously_created)
- block = current_binding_level->this_block;
- else if (keep == 1 || functionbody)
+ if (keep == 1 || functionbody)
block = make_node (BLOCK);
if (block != NULL_TREE)
{
- if (block_previously_created)
- {
- if (decls || tags || subblocks)
- {
- if (BLOCK_VARS (block))
- warning ("internal compiler error: debugging info corrupted");
-
- BLOCK_VARS (block) = decls;
-
- /* We can have previous subblocks and new subblocks when
- doing fixup_gotos with complex cleanups. We chain the new
- subblocks onto the end of any pre-existing subblocks. */
- BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block),
- subblocks);
- }
- }
- else
- {
- BLOCK_VARS (block) = decls;
- BLOCK_SUBBLOCKS (block) = subblocks;
- }
+ BLOCK_VARS (block) = decls;
+ BLOCK_SUBBLOCKS (block) = subblocks;
}
/* In each subblock, record that this is its superior. */
@@ -1574,11 +1546,9 @@ poplevel (keep, reverse, functionbody)
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block)
- {
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
- }
+ current_binding_level->blocks
+ = chainon (current_binding_level->blocks, block);
+
/* If we did not make a block for the level just exited,
any blocks made for inner levels
(since they cannot be recorded as subblocks in that level)
@@ -1655,9 +1625,11 @@ insert_block (block)
void
set_block (block)
- register tree block;
+ tree block ATTRIBUTE_UNUSED;
{
- current_binding_level->this_block = block;
+ /* The RTL expansion machinery requires us to provide this callback,
+ but it is not applicable in function-at-a-time mode. */
+ my_friendly_assert (cfun && !doing_semantic_analysis_p (), 20000911);
}
/* Do a pushlevel for class declarations. */
@@ -2011,7 +1983,6 @@ mark_binding_level (arg)
ggc_mark_tree (lvl->type_shadowed);
ggc_mark_tree (lvl->shadowed_labels);
ggc_mark_tree (lvl->blocks);
- ggc_mark_tree (lvl->this_block);
ggc_mark_tree (lvl->this_class);
ggc_mark_tree (lvl->incomplete);
ggc_mark_tree (lvl->dead_vars_from_for);
@@ -2469,7 +2440,6 @@ mark_saved_scope (arg)
if (t->lang_base)
ggc_mark_tree_varray (t->lang_base);
ggc_mark_tree (t->lang_name);
- ggc_mark_tree (t->x_function_parms);
ggc_mark_tree (t->template_parms);
ggc_mark_tree (t->x_previous_class_type);
ggc_mark_tree (t->x_previous_class_values);
@@ -6868,7 +6838,6 @@ init_decl_processing ()
ggc_add_tree_root (&last_function_parm_tags, 1);
ggc_add_tree_root (&current_function_return_value, 1);
- ggc_add_tree_root (&current_function_parms, 1);
ggc_add_tree_root (&current_function_parm_tags, 1);
ggc_add_tree_root (&last_function_parms, 1);
ggc_add_tree_root (&error_mark_list, 1);
@@ -13593,8 +13562,9 @@ build_enumerator (name, value, enumtype)
/* We're defining DECL. Make sure that it's type is OK. */
static void
-check_function_type (decl)
+check_function_type (decl, current_function_parms)
tree decl;
+ tree current_function_parms;
{
tree fntype = TREE_TYPE (decl);
tree return_type = complete_type (TREE_TYPE (fntype));
@@ -13636,9 +13606,7 @@ check_function_type (decl)
FLAGS is a bitwise or of SF_PRE_PARSED (indicating that the
DECLARATOR is really the DECL for the function we are about to
process and that DECLSPECS should be ignored), SF_INCLASS_INLINE
- indicating that the function is an inline defined in-class, and
- SF_EXPAND indicating that we should generate RTL for this
- function.
+ indicating that the function is an inline defined in-class.
This function creates a binding context for the function body
as well as setting up the FUNCTION_DECL in current_function_decl.
@@ -13665,6 +13633,7 @@ start_function (declspecs, declarator, attrs, flags)
extern int used_extern_spec;
int doing_friend = 0;
struct binding_level *bl;
+ tree current_function_parms;
/* Sanity check. */
my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160);
@@ -13812,7 +13781,7 @@ start_function (declspecs, declarator, attrs, flags)
you declare a function, these types can be incomplete, but they
must be complete when you define the function. */
if (! processing_template_decl)
- check_function_type (decl1);
+ check_function_type (decl1, current_function_parms);
/* Build the return declaration for the function. */
restype = TREE_TYPE (fntype);
@@ -13837,7 +13806,6 @@ start_function (declspecs, declarator, attrs, flags)
bl = current_binding_level;
init_function_start (decl1, input_filename, lineno);
current_binding_level = bl;
- expanding_p = (flags & SF_EXPAND) != 0;
/* Even though we're inside a function body, we still don't want to
call expand_expr to calculate the size of a variable-sized array.
@@ -13846,9 +13814,8 @@ start_function (declspecs, declarator, attrs, flags)
immediate_size_expand = 0;
cfun->x_dont_save_pending_sizes_p = 1;
- /* If we're building a statement-tree, start the tree now. */
- if (processing_template_decl || !expanding_p)
- begin_stmt_tree (&DECL_SAVED_TREE (decl1));
+ /* Start the statement-tree, start the tree now. */
+ begin_stmt_tree (&DECL_SAVED_TREE (decl1));
/* Let the user know we're compiling this function. */
announce_function (decl1);
@@ -13877,29 +13844,11 @@ start_function (declspecs, declarator, attrs, flags)
current_function_decl = decl1;
cfun->decl = decl1;
- /* Initialize the per-function data. */
- if (!DECL_PENDING_INLINE_P (decl1) && DECL_SAVED_FUNCTION_DATA (decl1))
- {
- /* If we already parsed this function, and we're just expanding it
- now, restore saved state. */
- struct binding_level *bl = current_binding_level;
- *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (decl1);
- current_binding_level = bl;
-
- /* This function is being processed in whole-function mode; we
- already did semantic analysis. */
- cfun->x_whole_function_mode_p = 1;
+ my_friendly_assert ((DECL_PENDING_INLINE_P (decl1)
+ || !DECL_SAVED_FUNCTION_DATA (decl1)),
+ 20000911);
- /* If we decided that we didn't want to inline this function,
- make sure the back-end knows that. */
- if (!current_function_cannot_inline)
- current_function_cannot_inline = cp_function_chain->cannot_inline;
-
- /* We don't need the saved data anymore. */
- free (DECL_SAVED_FUNCTION_DATA (decl1));
- DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
- }
- else if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
+ if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
{
/* We know that this was set up by `grokclassfn'. We do not
wait until `store_parm_decls', since evil parse errors may
@@ -13987,18 +13936,12 @@ start_function (declspecs, declarator, attrs, flags)
DECL_INTERFACE_KNOWN (decl1) = 1;
}
- if (doing_semantic_analysis_p ())
- {
- pushlevel (0);
- current_binding_level->parm_flag = 1;
- }
+ pushlevel (0);
+ current_binding_level->parm_flag = 1;
if (attrs)
cplus_decl_attributes (decl1, NULL_TREE, attrs);
- if (!building_stmt_tree ())
- GNU_xref_function (decl1, current_function_parms);
-
/* We need to do this even if we aren't expanding yet so that
assemble_external works. */
make_function_rtl (decl1);
@@ -14038,25 +13981,20 @@ start_function (declspecs, declarator, attrs, flags)
DECL_CONTEXT (ctor_label) = current_function_decl;
}
+ store_parm_decls (current_function_parms);
+
return 1;
}
-/* Called after store_parm_decls for a function-try-block. */
-
-void
-expand_start_early_try_stmts ()
-{
- expand_start_try_stmts ();
-}
-
/* Store the parameter declarations into the current function declaration.
This is called after parsing the parameter declarations, before
digesting the body of the function.
Also install to binding contour return value identifier, if any. */
-void
-store_parm_decls ()
+static void
+store_parm_decls (current_function_parms)
+ tree current_function_parms;
{
register tree fndecl = current_function_decl;
register tree parm;
@@ -14071,10 +14009,6 @@ store_parm_decls ()
then CONST_DECLs for foo and bar are put here. */
tree nonparms = NULL_TREE;
- /* Create a binding level for the parms. */
- if (!building_stmt_tree ())
- expand_start_bindings (2);
-
if (current_function_parms)
{
/* This case is when the function was defined with an ANSI prototype.
@@ -14085,45 +14019,34 @@ store_parm_decls ()
tree specparms = current_function_parms;
tree next;
- if (doing_semantic_analysis_p ())
- {
- /* Must clear this because it might contain TYPE_DECLs declared
+ /* Must clear this because it might contain TYPE_DECLs declared
at class level. */
- storedecls (NULL_TREE);
+ storedecls (NULL_TREE);
- /* If we're doing semantic analysis, then we'll call pushdecl
+ /* If we're doing semantic analysis, then we'll call pushdecl
for each of these. We must do them in reverse order so that
they end in the correct forward order. */
- specparms = nreverse (specparms);
- }
+ specparms = nreverse (specparms);
for (parm = specparms; parm; parm = next)
{
next = TREE_CHAIN (parm);
if (TREE_CODE (parm) == PARM_DECL)
{
- tree type = TREE_TYPE (parm);
-
- if (doing_semantic_analysis_p ())
- {
- tree cleanup;
+ tree cleanup;
- if (DECL_NAME (parm) == NULL_TREE
- || TREE_CODE (parm) != VOID_TYPE)
- pushdecl (parm);
- else
- cp_error ("parameter `%D' declared void", parm);
+ if (DECL_NAME (parm) == NULL_TREE
+ || TREE_CODE (parm) != VOID_TYPE)
+ pushdecl (parm);
+ else
+ cp_error ("parameter `%D' declared void", parm);
- cleanup = (processing_template_decl
- ? NULL_TREE
- : maybe_build_cleanup (parm));
+ cleanup = (processing_template_decl
+ ? NULL_TREE
+ : maybe_build_cleanup (parm));
- if (cleanup)
- cleanups = tree_cons (parm, cleanup, cleanups);
- }
- else if (type != error_mark_node
- && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
- parms_have_cleanups = 1;
+ if (cleanup)
+ cleanups = tree_cons (parm, cleanup, cleanups);
}
else
{
@@ -14134,14 +14057,11 @@ store_parm_decls ()
}
}
- if (doing_semantic_analysis_p ())
- {
- /* Get the decls in their original chain order
- and record in the function. This is all and only the
- PARM_DECLs that were pushed into scope by the loop above. */
- DECL_ARGUMENTS (fndecl) = getdecls ();
- storetags (chainon (parmtags, gettags ()));
- }
+ /* Get the decls in their original chain order and record in the
+ function. This is all and only the PARM_DECLs that were
+ pushed into scope by the loop above. */
+ DECL_ARGUMENTS (fndecl) = getdecls ();
+ storetags (chainon (parmtags, gettags ()));
}
else
DECL_ARGUMENTS (fndecl) = NULL_TREE;
@@ -14150,20 +14070,7 @@ store_parm_decls ()
as the decl-chain of the current lexical scope.
Put the enumerators in as well, at the front so that
DECL_ARGUMENTS is not modified. */
- if (doing_semantic_analysis_p ())
- storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
-
- /* Initialize the RTL code for the function. */
- DECL_SAVED_INSNS (fndecl) = 0;
- if (! building_stmt_tree ())
- expand_function_start (fndecl, parms_have_cleanups);
-
- current_function_parms_stored = 1;
-
- /* If this function is `main', emit a call to `__main'
- to run global initializers, etc. */
- if (DECL_MAIN_P (fndecl) && !building_stmt_tree ())
- expand_main_function ();
+ storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
/* Now that we have initialized the parms, we can start their
cleanups. We cannot do this before, since expand_decl_cleanup
@@ -14176,19 +14083,13 @@ store_parm_decls ()
}
/* Create a binding contour which can be used to catch
- cleanup-generated temporaries. Also, if the return value needs or
- has initialization, deal with that now. */
+ cleanup-generated temporaries. */
if (parms_have_cleanups)
- {
- pushlevel (0);
- if (!building_stmt_tree ())
- expand_start_bindings (2);
- }
+ pushlevel (0);
/* Do the starting of the exception specifications, if we have any. */
if (flag_exceptions && !processing_template_decl
&& flag_enforce_eh_specs
- && building_stmt_tree ()
&& TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
current_eh_spec_try_block = expand_start_eh_spec ();
}
@@ -14384,13 +14285,9 @@ finish_function (flags)
{
register tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
- /* Label to use if this function is supposed to return a value. */
- tree no_return_label = NULL_TREE;
int call_poplevel = (flags & 1) != 0;
int inclass_inline = (flags & 2) != 0;
- int expand_p;
int nested;
- int current_line = lineno;
/* When we get some parse errors, we can end up without a
current_function_decl, so cope. */
@@ -14404,18 +14301,11 @@ finish_function (flags)
This caused &foo to be of type ptr-to-const-function
which then got a warning when stored in a ptr-to-function variable. */
- /* This happens on strange parse errors. */
- if (! current_function_parms_stored)
- {
- call_poplevel = 0;
- store_parm_decls ();
- }
+ my_friendly_assert (building_stmt_tree (), 20000911);
/* For a cloned function, we've already got all the code we need;
there's no need to add any extra bits. */
- if (building_stmt_tree () && DECL_CLONED_FUNCTION_P (fndecl))
- ;
- else if (building_stmt_tree ())
+ if (!DECL_CLONED_FUNCTION_P (fndecl))
{
if (DECL_CONSTRUCTOR_P (fndecl))
{
@@ -14443,132 +14333,16 @@ finish_function (flags)
(TREE_TYPE (current_function_decl)),
current_eh_spec_try_block);
}
- else
- {
-#if 0
- if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/)
- {
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- tree ttype = target_type (fntype);
- tree parmdecl;
-
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
-
- for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl))
- {
- ttype = target_type (TREE_TYPE (parmdecl));
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
- }
- }
-#endif
-
- /* Clean house because we will need to reorder insns here. */
- do_pending_stack_adjust ();
-
- if (dtor_label)
- ;
- else if (DECL_CONSTRUCTOR_P (fndecl))
- {
- if (call_poplevel)
- do_poplevel ();
- }
- else if (return_label != NULL_RTX
- && flag_this_is_variable <= 0
- && current_function_return_value == NULL_TREE
- && ! DECL_NAME (DECL_RESULT (current_function_decl)))
- no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
-
- if (flag_exceptions)
- expand_exception_blocks ();
-
- /* If this function is supposed to return a value, ensure that
- we do not fall into the cleanups by mistake. The end of our
- function will look like this:
-
- user code (may have return stmt somewhere)
- goto no_return_label
- cleanup_label:
- cleanups
- goto return_label
- no_return_label:
- NOTE_INSN_FUNCTION_END
- return_label:
- things for return
-
- If the user omits a return stmt in the USER CODE section, we
- will have a control path which reaches NOTE_INSN_FUNCTION_END.
- Otherwise, we won't. */
- if (no_return_label)
- {
- DECL_CONTEXT (no_return_label) = fndecl;
- DECL_INITIAL (no_return_label) = error_mark_node;
- DECL_SOURCE_FILE (no_return_label) = input_filename;
- DECL_SOURCE_LINE (no_return_label) = current_line;
- expand_goto (no_return_label);
- }
-
- if (cleanup_label)
- {
- /* Remove the binding contour which is used
- to catch cleanup-generated temporaries. */
- expand_end_bindings (0, 0, 0);
- poplevel (0, 0, 0);
-
- /* Emit label at beginning of cleanup code for parameters. */
- emit_label (cleanup_label);
- }
-
- /* Get return value into register if that's where it's supposed
- to be. */
- if (original_result_rtx)
- fixup_result_decl (DECL_RESULT (fndecl), original_result_rtx);
-
- /* Finish building code that will trigger warnings if users forget
- to make their functions return values. */
- if (no_return_label || cleanup_label)
- emit_jump (return_label);
- if (no_return_label)
- {
- /* We don't need to call `expand_*_return' here because we
- don't need any cleanups here--this path of code is only
- for error checking purposes. */
- expand_label (no_return_label);
- }
-
- /* We hard-wired immediate_size_expand to zero in
- start_function. Expand_function_end will decrement this
- variable. So, we set the variable to one here, so that after
- the decrement it will remain zero. */
- immediate_size_expand = 1;
-
- /* Generate rtl for function exit. */
- expand_function_end (input_filename, current_line, 1);
- }
-
- /* We have to save this value here in case
- maybe_end_member_template_processing decides to pop all the
- template parameters. */
- expand_p = !building_stmt_tree ();
/* If we're saving up tree structure, tie off the function now. */
- if (!expand_p)
- finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
+ finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
/* This must come after expand_function_end because cleanups might
have declarations (from inline functions) that need to go into
this function's blocks. */
- if (doing_semantic_analysis_p ())
- {
- if (current_binding_level->parm_flag != 1)
- my_friendly_abort (122);
- poplevel (1, 0, 1);
- }
+ if (current_binding_level->parm_flag != 1)
+ my_friendly_abort (122);
+ poplevel (1, 0, 1);
/* Remember that we were in class scope. */
if (current_class_name)
@@ -14582,7 +14356,7 @@ finish_function (flags)
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
/* Save away current state, if appropriate. */
- if (!expanding_p && !processing_template_decl)
+ if (!processing_template_decl)
save_function_data (fndecl);
/* If this function calls `setjmp' it cannot be inlined. When
@@ -14594,96 +14368,15 @@ finish_function (flags)
this function to modify local variables in `c', but their
addresses may have been stored somewhere accessible to this
function.) */
- if (!expanding_p && !processing_template_decl && calls_setjmp_p (fndecl))
+ if (!processing_template_decl && calls_setjmp_p (fndecl))
DECL_UNINLINABLE (fndecl) = 1;
- if (expand_p)
- {
- int returns_null;
- int returns_value;
-
- /* So we can tell if jump_optimize sets it to 1. */
- can_reach_end = 0;
-
- /* Before we call rest_of_compilation (which will pop the
- CURRENT_FUNCTION), we must save these values. */
- returns_null = current_function_returns_null;
- returns_value = current_function_returns_value;
-
- /* If this is a nested function (like a template instantiation
- that we're compiling in the midst of compiling something
- else), push a new GC context. That will keep local variables
- on the stack from being collected while we're doing the
- compilation of this function. */
- if (function_depth > 1)
- ggc_push_context ();
-
- /* Run the optimizers and output the assembler code for this
- function. */
- rest_of_compilation (fndecl);
-
- /* Undo the call to ggc_push_context above. */
- if (function_depth > 1)
- ggc_pop_context ();
-
- if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
- {
- /* Set DECL_EXTERNAL so that assemble_external will be called as
- necessary. We'll clear it again in finish_file. */
- if (! DECL_EXTERNAL (fndecl))
- DECL_NOT_REALLY_EXTERN (fndecl) = 1;
- DECL_EXTERNAL (fndecl) = 1;
- defer_fn (fndecl);
- }
-
-#if 0
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- if (ctype && TREE_ASM_WRITTEN (fndecl))
- note_debug_info_needed (ctype);
-#endif
-
- /* If this function is marked with the constructor attribute,
- add it to the list of functions to be called along with
- constructors from static duration objects. */
- if (DECL_STATIC_CONSTRUCTOR (fndecl))
- static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
-
- /* If this function is marked with the destructor attribute,
- add it to the list of functions to be called along with
- destructors from static duration objects. */
- if (DECL_STATIC_DESTRUCTOR (fndecl))
- static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
-
- if (DECL_NAME (DECL_RESULT (fndecl)))
- returns_value |= can_reach_end;
- else
- returns_null |= can_reach_end;
-
- if (TREE_THIS_VOLATILE (fndecl) && returns_null)
- warning ("`noreturn' function does return");
- else if (returns_null
- && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE)
- {
- /* Always complain if there's just no return statement. */
- if (!returns_value)
- warning ("no return statement in function returning non-void");
- else if (warn_return_type || pedantic)
- /* If this function returns non-void and control can drop through,
- complain. */
- warning ("control reaches end of non-void function");
- }
- }
- else
- {
- /* Clear out memory we no longer need. */
- free_after_parsing (cfun);
- /* Since we never call rest_of_compilation, we never clear
- CFUN. Do so explicitly. */
- free_after_compilation (cfun);
- cfun = NULL;
- }
+ /* Clear out memory we no longer need. */
+ free_after_parsing (cfun);
+ /* Since we never call rest_of_compilation, we never clear
+ CFUN. Do so explicitly. */
+ free_after_compilation (cfun);
+ cfun = NULL;
/* If this is a in-class inline definition, we may have to pop the
bindings for the template parameters that we added in
@@ -14698,19 +14391,6 @@ finish_function (flags)
--function_depth;
- if (!DECL_SAVED_INSNS (fndecl) && !DECL_SAVED_FUNCTION_DATA (fndecl)
- && !(flag_inline_trees && DECL_INLINE (fndecl)))
- {
- tree t;
-
- /* Stop pointing to the local nodes about to be freed. */
- /* But DECL_INITIAL must remain nonzero so we know this
- was an actual function definition. */
- DECL_INITIAL (fndecl) = error_mark_node;
- for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t))
- DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX;
- }
-
/* Clean up. */
if (! nested)
{
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e97d525..250068a 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -128,7 +128,8 @@ int at_eof;
/* Functions called along with real static constructors and destructors. */
-tree static_ctors, static_dtors;
+tree static_ctors;
+tree static_dtors;
/* The :: namespace. */
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 1e5c4e3..8bcc333 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -2258,7 +2258,6 @@ use_thunk (thunk_fndecl, emit_p)
DECL_RESULT (thunk_fndecl) = NULL_TREE;
start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
- store_parm_decls ();
/* Adjust the this pointer by the constant. */
t = ssize_int (delta);
@@ -2530,7 +2529,6 @@ synthesize_method (fndecl)
interface_unknown = 1;
start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
- store_parm_decls ();
clear_last_expr ();
if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index d80877c..fdc1a52 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -932,7 +932,6 @@ maybe_clone_body (fn)
/* Start processing the function. */
push_to_top_level ();
start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED);
- store_parm_decls ();
/* Just clone the body, as if we were making an inline call.
But, remap the parameters in the callee to the parameters of
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index bd3c9c5..75930f3 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -835,8 +835,6 @@ fn.def2:
return_id:
RETURN_KEYWORD IDENTIFIER
{
- if (! current_function_parms_stored)
- store_parm_decls ();
$$ = $2;
}
;
@@ -863,9 +861,6 @@ base_init:
.set_base_init:
/* empty */
{
- if (! current_function_parms_stored)
- store_parm_decls ();
-
if (DECL_CONSTRUCTOR_P (current_function_decl))
/* Make a contour for the initializer list. */
do_pushlevel ();
@@ -1723,8 +1718,6 @@ string:
nodecls:
/* empty */
{
- if (! current_function_parms_stored)
- store_parm_decls ();
setup_vtbl_ptr (NULL_TREE, NULL_TREE);
}
;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index dc6f00f..99443b5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9686,7 +9686,6 @@ instantiate_decl (d, defer_ok)
/* Set up context. */
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
- store_parm_decls ();
/* We already set up __FUNCTION__, etc., so we don't want to do
it again now. */
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index c14dd9b..3eea2d2 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1195,7 +1195,6 @@ synthesize_tinfo_fn (fndecl)
start_function (NULL_TREE, fndecl, NULL_TREE,
SF_DEFAULT | SF_PRE_PARSED);
DECL_DEFER_OUTPUT (fndecl) = 1;
- store_parm_decls ();
clear_last_expr ();
/* Begin the body of the function. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b7abff2..88eaa72 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -57,6 +57,8 @@ static void genrtl_ctor_stmt PARAMS ((tree));
static void genrtl_subobject PARAMS ((tree));
static void genrtl_named_return_value PARAMS ((void));
static void cp_expand_stmt PARAMS ((tree));
+static void genrtl_start_function PARAMS ((tree));
+static void genrtl_finish_function PARAMS ((tree));
/* Finish processing the COND, the SUBSTMT condition for STMT. */
@@ -596,17 +598,9 @@ genrtl_try_block (t)
}
else
{
- if (FN_TRY_BLOCK_P (t))
- {
- if (! current_function_parms_stored)
- store_parm_decls ();
- expand_start_early_try_stmts ();
- }
- else
- {
- emit_line_note (input_filename, lineno);
- expand_start_try_stmts ();
- }
+ if (!FN_TRY_BLOCK_P (t))
+ emit_line_note (input_filename, lineno);
+ expand_start_try_stmts ();
expand_stmt (TRY_STMTS (t));
@@ -2387,7 +2381,6 @@ emit_associated_thunks (fn)
}
}
-
/* Generate RTL for FN. */
void
@@ -2484,8 +2477,7 @@ expand_body (fn)
lineno = DECL_SOURCE_LINE (fn);
input_filename = DECL_SOURCE_FILE (fn);
- start_function (NULL_TREE, fn, NULL_TREE, SF_PRE_PARSED | SF_EXPAND);
- store_parm_decls ();
+ genrtl_start_function (fn);
current_function_is_thunk = DECL_THUNK_P (fn);
/* We don't need to redeclare __FUNCTION__, __PRETTY_FUNCTION__, or
@@ -2505,7 +2497,7 @@ expand_body (fn)
lineno = STMT_LINENO (DECL_SAVED_TREE (fn));
/* Generate code for the function. */
- finish_function (0);
+ genrtl_finish_function (fn);
/* If possible, obliterate the body of the function so that it can
be garbage collected. */
@@ -2528,6 +2520,287 @@ expand_body (fn)
timevar_pop (TV_EXPAND);
}
+/* Start generating the RTL for FN. */
+
+static void
+genrtl_start_function (fn)
+ tree fn;
+{
+ tree parm;
+
+ /* Tell everybody what function we're processing. */
+ current_function_decl = fn;
+ /* Get the RTL machinery going for this function. */
+ init_function_start (fn, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn));
+ /* Let everybody know that we're expanding this function, not doing
+ semantic analysis. */
+ expanding_p = 1;
+
+ /* Even though we're inside a function body, we still don't want to
+ call expand_expr to calculate the size of a variable-sized array.
+ We haven't necessarily assigned RTL to all variables yet, so it's
+ not safe to try to expand expressions involving them. */
+ immediate_size_expand = 0;
+ cfun->x_dont_save_pending_sizes_p = 1;
+
+ /* Let the user know we're compiling this function. */
+ announce_function (fn);
+
+ /* Initialize the per-function data. */
+ my_friendly_assert (!DECL_PENDING_INLINE_P (fn), 20000911);
+ if (DECL_SAVED_FUNCTION_DATA (fn))
+ {
+ /* If we already parsed this function, and we're just expanding it
+ now, restore saved state. */
+ *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
+
+ /* This function is being processed in whole-function mode; we
+ already did semantic analysis. */
+ cfun->x_whole_function_mode_p = 1;
+
+ /* If we decided that we didn't want to inline this function,
+ make sure the back-end knows that. */
+ if (!current_function_cannot_inline)
+ current_function_cannot_inline = cp_function_chain->cannot_inline;
+
+ /* We don't need the saved data anymore. */
+ free (DECL_SAVED_FUNCTION_DATA (fn));
+ DECL_SAVED_FUNCTION_DATA (fn) = NULL;
+ }
+
+ /* Tell the cross-reference machinery that we're defining this
+ function. */
+ GNU_xref_function (fn, DECL_ARGUMENTS (fn));
+
+ /* Keep track of how many functions we're presently expanding. */
+ ++function_depth;
+
+ /* Create a binding level for the parameters. */
+ expand_start_bindings (2);
+ /* Clear out any previously saved instructions for this function, in
+ case it was defined more than once. */
+ DECL_SAVED_INSNS (fn) = NULL;
+ /* Go through the PARM_DECLs for this function to see if any need
+ cleanups. */
+ for (parm = DECL_ARGUMENTS (fn); parm; parm = TREE_CHAIN (parm))
+ if (TREE_TYPE (parm) != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (parm)))
+ {
+ expand_function_start (fn, /*parms_have_cleanups=*/1);
+ break;
+ }
+ if (!parm)
+ expand_function_start (fn, /*parms_have_cleanups=*/0);
+ /* If this function is `main'. */
+ if (DECL_MAIN_P (fn))
+ expand_main_function ();
+ /* Create a binding contour which can be used to catch
+ cleanup-generated temporaries. */
+ expand_start_bindings (2);
+}
+
+/* Finish generating the RTL for FN. */
+
+static void
+genrtl_finish_function (fn)
+ tree fn;
+{
+ int returns_null;
+ int returns_value;
+ tree no_return_label = NULL_TREE;
+
+#if 0
+ if (write_symbols != NO_DEBUG)
+ {
+ /* Keep this code around in case we later want to control debug info
+ based on whether a type is "used". (jason 1999-11-11) */
+
+ tree ttype = target_type (fntype);
+ tree parmdecl;
+
+ if (IS_AGGR_TYPE (ttype))
+ /* Let debugger know it should output info for this type. */
+ note_debug_info_needed (ttype);
+
+ for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl))
+ {
+ ttype = target_type (TREE_TYPE (parmdecl));
+ if (IS_AGGR_TYPE (ttype))
+ /* Let debugger know it should output info for this type. */
+ note_debug_info_needed (ttype);
+ }
+ }
+#endif
+
+ /* Clean house because we will need to reorder insns here. */
+ do_pending_stack_adjust ();
+
+ if (!dtor_label && !DECL_CONSTRUCTOR_P (fn)
+ && return_label != NULL_RTX
+ && current_function_return_value == NULL_TREE
+ && ! DECL_NAME (DECL_RESULT (current_function_decl)))
+ no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+
+ if (flag_exceptions)
+ expand_exception_blocks ();
+
+ /* If this function is supposed to return a value, ensure that
+ we do not fall into the cleanups by mistake. The end of our
+ function will look like this:
+
+ user code (may have return stmt somewhere)
+ goto no_return_label
+ cleanup_label:
+ cleanups
+ goto return_label
+ no_return_label:
+ NOTE_INSN_FUNCTION_END
+ return_label:
+ things for return
+
+ If the user omits a return stmt in the USER CODE section, we
+ will have a control path which reaches NOTE_INSN_FUNCTION_END.
+ Otherwise, we won't. */
+ if (no_return_label)
+ {
+ DECL_CONTEXT (no_return_label) = fn;
+ DECL_INITIAL (no_return_label) = error_mark_node;
+ DECL_SOURCE_FILE (no_return_label) = input_filename;
+ DECL_SOURCE_LINE (no_return_label) = lineno;
+ expand_goto (no_return_label);
+ }
+
+ if (cleanup_label)
+ {
+ /* Remove the binding contour which is used to catch
+ cleanup-generated temporaries. */
+ expand_end_bindings (0, 0, 0);
+ poplevel (0, 0, 0);
+
+ /* Emit label at beginning of cleanup code for parameters. */
+ emit_label (cleanup_label);
+ }
+
+ /* Get return value into register if that's where it's supposed to
+ be. */
+ if (original_result_rtx)
+ fixup_result_decl (DECL_RESULT (fn), original_result_rtx);
+
+ /* Finish building code that will trigger warnings if users forget
+ to make their functions return values. */
+ if (no_return_label || cleanup_label)
+ emit_jump (return_label);
+ if (no_return_label)
+ {
+ /* We don't need to call `expand_*_return' here because we don't
+ need any cleanups here--this path of code is only for error
+ checking purposes. */
+ expand_label (no_return_label);
+ }
+
+ /* We hard-wired immediate_size_expand to zero in start_function.
+ Expand_function_end will decrement this variable. So, we set the
+ variable to one here, so that after the decrement it will remain
+ zero. */
+ immediate_size_expand = 1;
+
+ /* Generate rtl for function exit. */
+ expand_function_end (input_filename, lineno, 1);
+
+ /* So we can tell if jump_optimize sets it to 1. */
+ can_reach_end = 0;
+
+ /* Before we call rest_of_compilation (which will pop the
+ CURRENT_FUNCTION), we must save these values. */
+ returns_null = current_function_returns_null;
+ returns_value = current_function_returns_value;
+
+ /* If this is a nested function (like a template instantiation that
+ we're compiling in the midst of compiling something else), push a
+ new GC context. That will keep local variables on the stack from
+ being collected while we're doing the compilation of this
+ function. */
+ if (function_depth > 1)
+ ggc_push_context ();
+
+ /* Run the optimizers and output the assembler code for this
+ function. */
+ rest_of_compilation (fn);
+
+ /* Undo the call to ggc_push_context above. */
+ if (function_depth > 1)
+ ggc_pop_context ();
+
+ if (DECL_SAVED_INSNS (fn) && ! TREE_ASM_WRITTEN (fn))
+ {
+ /* Set DECL_EXTERNAL so that assemble_external will be called as
+ necessary. We'll clear it again in finish_file. */
+ if (! DECL_EXTERNAL (fn))
+ DECL_NOT_REALLY_EXTERN (fn) = 1;
+ DECL_EXTERNAL (fn) = 1;
+ defer_fn (fn);
+ }
+
+#if 0
+ /* Keep this code around in case we later want to control debug info
+ based on whether a type is "used". (jason 1999-11-11) */
+
+ if (ctype && TREE_ASM_WRITTEN (fn))
+ note_debug_info_needed (ctype);
+#endif
+
+ /* If this function is marked with the constructor attribute, add it
+ to the list of functions to be called along with constructors
+ from static duration objects. */
+ if (DECL_STATIC_CONSTRUCTOR (fn))
+ static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
+
+ /* If this function is marked with the destructor attribute, add it
+ to the list of functions to be called along with destructors from
+ static duration objects. */
+ if (DECL_STATIC_DESTRUCTOR (fn))
+ static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
+
+ if (DECL_NAME (DECL_RESULT (fn)))
+ returns_value |= can_reach_end;
+ else
+ returns_null |= can_reach_end;
+
+ if (TREE_THIS_VOLATILE (fn) && returns_null)
+ warning ("`noreturn' function does return");
+ else if (returns_null
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != VOID_TYPE)
+ {
+ /* Always complain if there's just no return statement. */
+ if (!returns_value)
+ warning ("no return statement in function returning non-void");
+ else if (warn_return_type || pedantic)
+ /* If this function returns non-void and control can drop through,
+ complain. */
+ warning ("control reaches end of non-void function");
+ }
+
+ --function_depth;
+
+ if (!DECL_SAVED_INSNS (fn)
+ && !(flag_inline_trees && DECL_INLINE (fn)))
+ {
+ tree t;
+
+ /* Stop pointing to the local nodes about to be freed. */
+ /* But DECL_INITIAL must remain nonzero so we know this
+ was an actual function definition. */
+ DECL_INITIAL (fn) = error_mark_node;
+ for (t = DECL_ARGUMENTS (fn); t; t = TREE_CHAIN (t))
+ DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX;
+ }
+
+ /* Let the error reporting routines know that we're outside a
+ function. For a nested function, this value is used in
+ pop_cp_function_context and then reset via pop_function_context. */
+ current_function_decl = NULL_TREE;
+}
+
/* Perform initialization related to this module. */
void