Commit b35d4555 by Mark Mitchell Committed by Mark Mitchell

Turn on function-at-a-time processing.

	* cp-tree.h (doing_semantic_analysis_p): New macro.
	(SF_DEFAULT): Define to zero, not SF_EXPAND.
	(start_handler_parms): Change prototype.
	(expand_start_catch_block): Likewise.
	(expand_end_catch_block): Likewise.
	(expand_start_eh_spec): Likewise.
	(expand_end_eh_spec): Declare.
	(finish_handler_parms): Change prototype.
	(begin_catch_block): Declare.
	(finish_handler): Change prototype.
	(do_pushlevel): Declare.
	(do_poplevel): Likewise.
	* decl.c (pushlevel): Don't create
	binding levels when not doing semantic analysis.
	(poplevel): Don't pop them.
	(pushdecl): Assert that we are never called when not doing
	semantic analysis.
	(pushdecl_top_level): Use push_to_top_level.
	(make_label_decl): Don't fiddle with obstacks.  Make RTL For the
	label when expanding.
	(cp_finish_decl): Only inject for-scope variables when doing
	semantic analysis.  Add comments.
	(start_handler_parms): Return the handler parm.
	(start_function): Reorganize.  Don't clear DECL_INITIAL if it is
	already set.  Reinitialize from saved function data if available.
	Don't pushlevel when not doing semantic analysis.
	(store_parm_decls): Only generate RTL when expanding.  Only
	pushdecl when doing semantic analysis.  Set
	current_eh_spec_try_block if appropriate.
	(finish_function): Simplify.  Use do_pushlevel and do_poplevel.
	Combine common code.  Don't poplevel when not doing semantic
	analysis.
	(push_cp_function_context): Don't expand functions without an
	explicit call to expand_body.
	(mark_lang_function): Make eh_spec_try_block and
	x_scope_stmt_stack.
	* except.c (expand_end_eh_spec): Don't
	declare.
	(process_start_catch_block): Likewise.
	(push_eh_cleanup): Use finish_decl_cleanup.
	(initialize_handler_parm): New function.
	(expand_start_catch_block): Use it.
	(expand_end_catch_block): Use tree-generation functions, not
	RTL-generation functions.
	(expand_start_eh_spec): Likewise.
	(expand_end_eh_spec): Likewise.
	(expand_exception_blocks): Simplify.
	(start_anon_func): Use do_pushlevel.
	(end_anon_func): Use do_poplvel.  Call expand_body for the
	function.
	* expr.c (do_case): Don't call define_case_label.
	* init.c (create_temporary_var): Set DECL_CONTEXT for local
	variables.
	* method.c (emit_thunk): Call expand_body for the
	thunk.
	(sythesize_method): Likewise.
	* parse.y (handler_args): Give it ttype.
	(eat_saved_input): Call expand_body.
	(base_init): Use do_pushlevel.
	(pending_inline): Call expand_body.
	(handler): Adjust calls to finish_handler_parms and
	finish_handler.
	(handler_args): Don't call expand_start_catch_block.  Return the
	catch parameter.  * pt.c (tsubst_expr): Adjust HANDLER handling.
	* parse.c: Regenerated.
	* rtti.c (synthesize_tinfo_fn): Call finish_function.
	* semantics.c (do_pushlevel): Give it external linkage.  Build
	SCOPE_STMTs.
	(do_poplevel): Likewise.
	(finish_case_label): Call define_case_label when doing semantic
	analysis.
	(finish_goto_stmt): Create RTL for labels.
	(finish_function_try_block): Set in_function_try_handler
	unconditionally.
	(finish_function_handler_sequence): Unset it.
	(finish_handler_parms): Use expand_start_catch_block even when
	building a statement-tree.
	(begin_catch_block): New function.
	(finish_handler): Move a little RTL-generation logic here.
	(finish_decl_cleanup): Allow cleanups for empty declarations.
	(finish_named_return_value): Don't pushdecl when not doing
	semantic analysis.
	(expand_stmt): Don't do semantic analysis for variable
	declarations.  Handle START_CATCH_STMT.  Call expand_label
	directly for a LABEL_STMT.  Tweak handling of GOTO_STMT.  Adjust
	HANDLERs.  Handle SCOPE_STMT, CTOR_INITIALIZER, and RETURN_INIT.
	(expand_body): Let expand_stmt handle CTOR_INITIALIZER,
	RETURN_INIT and function try blocks.

From-SVN: r29490
parent 2c146a76
1999-09-17 Mark Mitchell <mark@codesourcery.com> 1999-09-17 Mark Mitchell <mark@codesourcery.com>
Turn on function-at-a-time processing.
* cp-tree.h (doing_semantic_analysis_p): New macro.
(SF_DEFAULT): Define to zero, not SF_EXPAND.
(start_handler_parms): Change prototype.
(expand_start_catch_block): Likewise.
(expand_end_catch_block): Likewise.
(expand_start_eh_spec): Likewise.
(expand_end_eh_spec): Declare.
(finish_handler_parms): Change prototype.
(begin_catch_block): Declare.
(finish_handler): Change prototype.
(do_pushlevel): Declare.
(do_poplevel): Likewise.
* decl.c (pushlevel): Don't create
binding levels when not doing semantic analysis.
(poplevel): Don't pop them.
(pushdecl): Assert that we are never called when not doing
semantic analysis.
(pushdecl_top_level): Use push_to_top_level.
(make_label_decl): Don't fiddle with obstacks. Make RTL For the
label when expanding.
(cp_finish_decl): Only inject for-scope variables when doing
semantic analysis. Add comments.
(start_handler_parms): Return the handler parm.
(start_function): Reorganize. Don't clear DECL_INITIAL if it is
already set. Reinitialize from saved function data if available.
Don't pushlevel when not doing semantic analysis.
(store_parm_decls): Only generate RTL when expanding. Only
pushdecl when doing semantic analysis. Set
current_eh_spec_try_block if appropriate.
(finish_function): Simplify. Use do_pushlevel and do_poplevel.
Combine common code. Don't poplevel when not doing semantic
analysis.
(push_cp_function_context): Don't expand functions without an
explicit call to expand_body.
(mark_lang_function): Make eh_spec_try_block and
x_scope_stmt_stack.
* except.c (expand_end_eh_spec): Don't
declare.
(process_start_catch_block): Likewise.
(push_eh_cleanup): Use finish_decl_cleanup.
(initialize_handler_parm): New function.
(expand_start_catch_block): Use it.
(expand_end_catch_block): Use tree-generation functions, not
RTL-generation functions.
(expand_start_eh_spec): Likewise.
(expand_end_eh_spec): Likewise.
(expand_exception_blocks): Simplify.
(start_anon_func): Use do_pushlevel.
(end_anon_func): Use do_poplvel. Call expand_body for the
function.
* expr.c (do_case): Don't call define_case_label.
* init.c (create_temporary_var): Set DECL_CONTEXT for local
variables.
* method.c (emit_thunk): Call expand_body for the
thunk.
(sythesize_method): Likewise.
* parse.y (handler_args): Give it ttype.
(eat_saved_input): Call expand_body.
(base_init): Use do_pushlevel.
(pending_inline): Call expand_body.
(handler): Adjust calls to finish_handler_parms and
finish_handler.
(handler_args): Don't call expand_start_catch_block. Return the
catch parameter. * pt.c (tsubst_expr): Adjust HANDLER handling.
* parse.c: Regenerated.
* rtti.c (synthesize_tinfo_fn): Call finish_function.
* semantics.c (do_pushlevel): Give it external linkage. Build
SCOPE_STMTs.
(do_poplevel): Likewise.
(finish_case_label): Call define_case_label when doing semantic
analysis.
(finish_goto_stmt): Create RTL for labels.
(finish_function_try_block): Set in_function_try_handler
unconditionally.
(finish_function_handler_sequence): Unset it.
(finish_handler_parms): Use expand_start_catch_block even when
building a statement-tree.
(begin_catch_block): New function.
(finish_handler): Move a little RTL-generation logic here.
(finish_decl_cleanup): Allow cleanups for empty declarations.
(finish_named_return_value): Don't pushdecl when not doing
semantic analysis.
(expand_stmt): Don't do semantic analysis for variable
declarations. Handle START_CATCH_STMT. Call expand_label
directly for a LABEL_STMT. Tweak handling of GOTO_STMT. Adjust
HANDLERs. Handle SCOPE_STMT, CTOR_INITIALIZER, and RETURN_INIT.
(expand_body): Let expand_stmt handle CTOR_INITIALIZER,
RETURN_INIT and function try blocks.
* cp-tree.h (language_function): Add x_eh_spec_try_block. Add * cp-tree.h (language_function): Add x_eh_spec_try_block. Add
x_scope_stmt_stack. Add x_in_charge_parm. x_scope_stmt_stack. Add x_in_charge_parm.
(current_eh_spec_try_block): New macro. (current_eh_spec_try_block): New macro.
......
...@@ -747,6 +747,12 @@ struct language_function ...@@ -747,6 +747,12 @@ struct language_function
#define expanding_p cp_function_chain->x_expanding_p #define expanding_p cp_function_chain->x_expanding_p
/* Non-zero if we are in the semantic analysis phase for the current
function. */
#define doing_semantic_analysis_p() \
(!expanding_p || !current_function->x_whole_function_mode_p)
/* Non-zero if we should treat statements as full expressions. In /* Non-zero if we should treat statements as full expressions. In
particular, this variable is no-zero if at the end of a statement particular, this variable is no-zero if at the end of a statement
we should destroy any temporaries created during that statement. we should destroy any temporaries created during that statement.
...@@ -3022,11 +3028,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; ...@@ -3022,11 +3028,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
result of a using declaration. */ result of a using declaration. */
/* Used with start function. */ /* Used with start function. */
#define SF_DEFAULT SF_EXPAND #define SF_DEFAULT 0 /* No flags. */
/* No flags. Temporarily, this is
SF_EXPAND. Once we are fully
function-at-a-time, this will be
0. */
#define SF_PRE_PARSED 1 /* The function declaration has #define SF_PRE_PARSED 1 /* The function declaration has
already been parsed. */ already been parsed. */
#define SF_INCLASS_INLINE 2 /* The function is an inline, defined #define SF_INCLASS_INLINE 2 /* The function is an inline, defined
...@@ -3237,7 +3239,7 @@ extern void finish_decl PROTO((tree, tree, tree)); ...@@ -3237,7 +3239,7 @@ extern void finish_decl PROTO((tree, tree, tree));
extern void maybe_inject_for_scope_var PROTO((tree)); extern void maybe_inject_for_scope_var PROTO((tree));
extern void initialize_local_var PROTO((tree, tree, int)); extern void initialize_local_var PROTO((tree, tree, int));
extern void expand_static_init PROTO((tree, tree)); extern void expand_static_init PROTO((tree, tree));
extern void start_handler_parms PROTO((tree, tree)); extern tree start_handler_parms PROTO((tree, tree));
extern int complete_array_type PROTO((tree, tree, int)); extern int complete_array_type PROTO((tree, tree, int));
extern tree build_ptrmemfunc_type PROTO((tree)); extern tree build_ptrmemfunc_type PROTO((tree));
/* the grokdeclarator prototype is in decl.h */ /* the grokdeclarator prototype is in decl.h */
...@@ -3389,10 +3391,11 @@ extern int cp_line_of PROTO((tree)); ...@@ -3389,10 +3391,11 @@ extern int cp_line_of PROTO((tree));
/* in except.c */ /* in except.c */
extern void init_exception_processing PROTO((void)); extern void init_exception_processing PROTO((void));
extern void expand_start_catch_block PROTO((tree)); extern tree expand_start_catch_block PROTO((tree));
extern void expand_end_catch_block PROTO((void)); extern void expand_end_catch_block PROTO((tree));
extern void expand_builtin_throw PROTO((void)); extern void expand_builtin_throw PROTO((void));
extern void expand_start_eh_spec PROTO((void)); extern tree expand_start_eh_spec PROTO((void));
extern void expand_end_eh_spec PROTO((tree, tree));
extern void expand_exception_blocks PROTO((void)); extern void expand_exception_blocks PROTO((void));
extern tree start_anon_func PROTO((void)); extern tree start_anon_func PROTO((void));
extern void end_anon_func PROTO((void)); extern void end_anon_func PROTO((void));
...@@ -3660,9 +3663,9 @@ extern void finish_function_try_block PROTO((tree)); ...@@ -3660,9 +3663,9 @@ extern void finish_function_try_block PROTO((tree));
extern void finish_function_handler_sequence PROTO((tree)); extern void finish_function_handler_sequence PROTO((tree));
extern void finish_cleanup_try_block PROTO((tree)); extern void finish_cleanup_try_block PROTO((tree));
extern tree begin_handler PROTO((void)); extern tree begin_handler PROTO((void));
extern void start_handler_parms PROTO((tree, tree)); extern tree finish_handler_parms PROTO((tree, tree));
extern void finish_handler_parms PROTO((tree)); extern void begin_catch_block PROTO((tree));
extern void finish_handler PROTO((tree)); extern void finish_handler PROTO((tree, tree));
extern void finish_cleanup PROTO((tree, tree)); extern void finish_cleanup PROTO((tree, tree));
extern tree begin_compound_stmt PROTO((int)); extern tree begin_compound_stmt PROTO((int));
extern tree finish_compound_stmt PROTO((int, tree)); extern tree finish_compound_stmt PROTO((int, tree));
...@@ -3713,6 +3716,8 @@ extern void expand_body PROTO((tree)); ...@@ -3713,6 +3716,8 @@ extern void expand_body PROTO((tree));
extern void begin_stmt_tree PROTO((tree)); extern void begin_stmt_tree PROTO((tree));
extern void finish_stmt_tree PROTO((tree)); extern void finish_stmt_tree PROTO((tree));
extern void prep_stmt PROTO((tree)); extern void prep_stmt PROTO((tree));
extern void do_pushlevel PROTO((void));
extern tree do_poplevel PROTO((void));
/* Non-zero if we are presently building a statement tree, rather /* Non-zero if we are presently building a statement tree, rather
than expanding each statement as we encounter it. */ than expanding each statement as we encounter it. */
#define building_stmt_tree() \ #define building_stmt_tree() \
......
...@@ -39,7 +39,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -39,7 +39,6 @@ Boston, MA 02111-1307, USA. */
static void push_eh_cleanup PROTO((void)); static void push_eh_cleanup PROTO((void));
static tree build_eh_type_type PROTO((tree)); static tree build_eh_type_type PROTO((tree));
static tree build_eh_type PROTO((tree)); static tree build_eh_type PROTO((tree));
static void expand_end_eh_spec PROTO((tree));
static tree call_eh_info PROTO((void)); static tree call_eh_info PROTO((void));
static void push_eh_info PROTO((void)); static void push_eh_info PROTO((void));
static tree get_eh_info PROTO((void)); static tree get_eh_info PROTO((void));
...@@ -50,11 +49,11 @@ static tree get_eh_caught PROTO((void)); ...@@ -50,11 +49,11 @@ static tree get_eh_caught PROTO((void));
static tree get_eh_handlers PROTO((void)); static tree get_eh_handlers PROTO((void));
#endif #endif
static tree do_pop_exception PROTO((void)); static tree do_pop_exception PROTO((void));
static void process_start_catch_block PROTO((tree));
static tree build_eh_type_type_ref PROTO((tree)); static tree build_eh_type_type_ref PROTO((tree));
static tree build_terminate_handler PROTO((void)); static tree build_terminate_handler PROTO((void));
static tree alloc_eh_object PROTO((tree)); static tree alloc_eh_object PROTO((tree));
static int complete_ptr_ref_or_void_ptr_p PROTO((tree, tree)); static int complete_ptr_ref_or_void_ptr_p PROTO((tree, tree));
static void initialize_handler_parm PROTO((tree));
#if 0 #if 0
/* This is the startup, and finish stuff per exception table. */ /* This is the startup, and finish stuff per exception table. */
...@@ -483,7 +482,7 @@ push_eh_cleanup () ...@@ -483,7 +482,7 @@ push_eh_cleanup ()
yes = suspend_momentary (); yes = suspend_momentary ();
/* All cleanups must last longer than normal. */ /* All cleanups must last longer than normal. */
expand_decl_cleanup (NULL_TREE, do_pop_exception ()); finish_decl_cleanup (NULL_TREE, do_pop_exception ());
resume_momentary (yes); resume_momentary (yes);
} }
...@@ -499,73 +498,18 @@ build_terminate_handler () ...@@ -499,73 +498,18 @@ build_terminate_handler ()
return term; return term;
} }
/* Call this to start a catch block. Typename is the typename, and identifier /* Initialize the catch parameter DECL. */
is the variable to place the object in or NULL if the variable doesn't
matter. If typename is NULL, that means its a "catch (...)" or catch
everything. In that case we don't need to do any type checking.
(ie: it ends up as the "else" clause rather than an "else if" clause) */
void
expand_start_catch_block (decl)
tree decl;
{
if (building_stmt_tree ())
{
if (decl)
{
/* We must ensure that DECL_CONTEXT is set up before we call
push_template_decl; that code depends on DECL_CONTEXT
being set correctly. */
DECL_CONTEXT (decl) = current_function_decl;
if (processing_template_decl)
decl = push_template_decl (decl);
pushdecl (decl);
add_decl_stmt (decl);
}
return;
}
if (! doing_eh (1))
return;
process_start_catch_block (decl);
}
/* This function performs the expand_start_catch_block functionality for
exceptions implemented in the new style. __throw determines whether
a handler needs to be called or not, so the handler itself has to do
nothing additional. */
static void static void
process_start_catch_block (decl) initialize_handler_parm (decl)
tree decl; tree decl;
{ {
tree init;
/* Create a binding level for the eh_info and the exception object
cleanup. */
pushlevel (0);
expand_start_bindings (0);
if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
decl = NULL_TREE;
if (decl)
start_catch_handler (build_eh_type_type_ref (TREE_TYPE (decl)));
else
start_catch_handler (CATCH_ALL_TYPE);
emit_line_note (input_filename, lineno);
push_eh_info ();
if (decl)
{
tree exp; tree exp;
tree init;
tree init_type; tree init_type;
/* Make sure we mark the catch param as used, otherwise we'll get /* Make sure we mark the catch param as used, otherwise we'll get a
a warning about an unused ((anonymous)). */ warning about an unused ((anonymous)). */
TREE_USED (decl) = 1; TREE_USED (decl) = 1;
/* Figure out the type that the initializer is. */ /* Figure out the type that the initializer is. */
...@@ -584,12 +528,6 @@ process_start_catch_block (decl) ...@@ -584,12 +528,6 @@ process_start_catch_block (decl)
exp = ocp_convert (init_type , exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0); exp = ocp_convert (init_type , exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0);
push_eh_cleanup ();
/* Create a binding level for the parm. */
pushlevel (0);
expand_start_bindings (0);
init = convert_from_reference (exp); init = convert_from_reference (exp);
/* If the constructor for the catch parm exits via an exception, we /* If the constructor for the catch parm exits via an exception, we
...@@ -605,25 +543,51 @@ process_start_catch_block (decl) ...@@ -605,25 +543,51 @@ process_start_catch_block (decl)
} }
/* Let `cp_finish_decl' know that this initializer is ok. */ /* Let `cp_finish_decl' know that this initializer is ok. */
DECL_INITIAL (decl) = init; DECL_INITIAL (decl) = error_mark_node;
decl = pushdecl (decl); decl = pushdecl (decl);
start_decl_1 (decl); start_decl_1 (decl);
cp_finish_decl (decl, init, NULL_TREE, 0, cp_finish_decl (decl, init, NULL_TREE, 0,
LOOKUP_ONLYCONVERTING|DIRECT_BIND); LOOKUP_ONLYCONVERTING|DIRECT_BIND);
} }
/* Call this to start a catch block. DECL is the catch parameter. */
tree
expand_start_catch_block (decl)
tree decl;
{
tree compound_stmt_1;
tree compound_stmt_2;
tree type;
if (! doing_eh (1))
return NULL_TREE;
/* Make sure this declaration is reasonable. */
if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
decl = NULL_TREE;
/* Create a binding level for the eh_info and the exception object
cleanup. */
compound_stmt_1 = begin_compound_stmt (/*has_no_scope=*/0);
if (decl)
type = build_eh_type_type_ref (TREE_TYPE (decl));
else else
{ type = NULL_TREE;
begin_catch_block (type);
push_eh_info ();
push_eh_cleanup (); push_eh_cleanup ();
/* Create a binding level for the parm. */ /* Create a binding level for the parm. */
pushlevel (0); compound_stmt_2 = begin_compound_stmt (/*has_no_scope=*/0);
expand_start_bindings (0);
/* Fall into the catch all section. */ if (decl)
} initialize_handler_parm (decl);
emit_line_note (input_filename, lineno); return build_tree_list (compound_stmt_1, compound_stmt_2);
} }
...@@ -632,8 +596,12 @@ process_start_catch_block (decl) ...@@ -632,8 +596,12 @@ process_start_catch_block (decl)
the label to jump to if this catch block didn't match. */ the label to jump to if this catch block didn't match. */
void void
expand_end_catch_block () expand_end_catch_block (blocks)
tree blocks;
{ {
tree compound_stmt_1 = blocks ? TREE_PURPOSE (blocks): NULL_TREE;
tree compound_stmt_2 = blocks ? TREE_VALUE (blocks): NULL_TREE;
if (! doing_eh (1)) if (! doing_eh (1))
return; return;
...@@ -642,22 +610,12 @@ expand_end_catch_block () ...@@ -642,22 +610,12 @@ expand_end_catch_block ()
if (in_function_try_handler if (in_function_try_handler
&& (DECL_CONSTRUCTOR_P (current_function_decl) && (DECL_CONSTRUCTOR_P (current_function_decl)
|| DECL_DESTRUCTOR_P (current_function_decl))) || DECL_DESTRUCTOR_P (current_function_decl)))
expand_throw (NULL_TREE); finish_expr_stmt (build_throw (NULL_TREE));
/* Cleanup the EH parameter. */ /* Cleanup the EH parameter. */
expand_end_bindings (getdecls (), kept_level_p (), 0); finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_1);
poplevel (kept_level_p (), 1, 0);
/* Cleanup the EH object. */ /* Cleanup the EH object. */
expand_end_bindings (getdecls (), kept_level_p (), 0); finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_2);
poplevel (kept_level_p (), 1, 0);
/* Fall to outside the try statement when done executing handler and
we fall off end of handler. This is jump Lresume in the
documentation. */
expand_goto (top_label_entry (&caught_return_label_stack));
end_catch_handler ();
} }
/* An exception spec is implemented more or less like: /* An exception spec is implemented more or less like:
...@@ -671,21 +629,25 @@ expand_end_catch_block () ...@@ -671,21 +629,25 @@ expand_end_catch_block ()
__check_eh_spec in exception.cc handles all the details. */ __check_eh_spec in exception.cc handles all the details. */
void tree
expand_start_eh_spec () expand_start_eh_spec ()
{ {
expand_start_try_stmts (); return begin_try_block ();
} }
static void void
expand_end_eh_spec (raises) expand_end_eh_spec (raises, try_block)
tree raises; tree raises;
tree try_block;
{ {
tree tmp, fn, decl, types = NULL_TREE; tree tmp, fn, decl, types = NULL_TREE;
tree blocks;
tree handler;
int count = 0; int count = 0;
expand_start_all_catch (); finish_try_block (try_block);
expand_start_catch_block (NULL_TREE); handler = begin_handler ();
blocks = finish_handler_parms (NULL_TREE, handler);
/* Build up an array of type_infos. */ /* Build up an array of type_infos. */
for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises)) for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises))
...@@ -733,10 +695,10 @@ expand_end_eh_spec (raises) ...@@ -733,10 +695,10 @@ expand_end_eh_spec (raises)
tmp = tree_cons (NULL_TREE, build_int_2 (count, 0), tmp = tree_cons (NULL_TREE, build_int_2 (count, 0),
tree_cons (NULL_TREE, decl, NULL_TREE)); tree_cons (NULL_TREE, decl, NULL_TREE));
tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp); tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp);
expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL); finish_expr_stmt (tmp);
expand_end_catch_block (); finish_handler (blocks, handler);
expand_end_all_catch (); finish_handler_sequence (try_block);
} }
/* This is called to expand all the toplevel exception handling /* This is called to expand all the toplevel exception handling
...@@ -753,21 +715,6 @@ expand_exception_blocks () ...@@ -753,21 +715,6 @@ expand_exception_blocks ()
catch_clauses = get_insns (); catch_clauses = get_insns ();
end_sequence (); end_sequence ();
/* Do this after we expand leftover cleanups, so that the
expand_eh_region_end that expand_end_eh_spec does will match the
right expand_eh_region_start, and make sure it comes out before
the terminate protected region. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
{
expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
do_pending_stack_adjust ();
push_to_sequence (catch_clauses);
expand_leftover_cleanups ();
do_pending_stack_adjust ();
catch_clauses = get_insns ();
end_sequence ();
}
if (catch_clauses) if (catch_clauses)
{ {
rtx funcend = gen_label_rtx (); rtx funcend = gen_label_rtx ();
...@@ -815,12 +762,7 @@ start_anon_func () ...@@ -815,12 +762,7 @@ start_anon_func ()
start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"), start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"),
void_list_node), void_list_node),
t, NULL_TREE, SF_DEFAULT); t, NULL_TREE, SF_DEFAULT);
store_parm_decls (); do_pushlevel ();
pushlevel (0);
clear_last_expr ();
push_momentary ();
expand_start_bindings (0);
emit_line_note (input_filename, lineno);
interface_unknown = old_interface_unknown; interface_unknown = old_interface_unknown;
...@@ -832,11 +774,9 @@ start_anon_func () ...@@ -832,11 +774,9 @@ start_anon_func ()
void void
end_anon_func () end_anon_func ()
{ {
expand_end_bindings (getdecls (), 1, 0); do_poplevel ();
poplevel (1, 0, 0);
pop_momentary ();
finish_function (lineno, 0); expand_body (finish_function (lineno, 0));
pop_from_top_level (); pop_from_top_level ();
} }
......
...@@ -456,5 +456,6 @@ do_case (start, end) ...@@ -456,5 +456,6 @@ do_case (start, end)
cp_error ("case label `%E' within scope of cleanup or variable array", start); cp_error ("case label `%E' within scope of cleanup or variable array", start);
} }
} }
define_case_label ();
current_function_return_value = NULL_TREE;
} }
...@@ -2656,6 +2656,7 @@ create_temporary_var (type) ...@@ -2656,6 +2656,7 @@ create_temporary_var (type)
DECL_SOURCE_FILE (decl) = input_filename; DECL_SOURCE_FILE (decl) = input_filename;
DECL_SOURCE_LINE (decl) = lineno; DECL_SOURCE_LINE (decl) = lineno;
DECL_IGNORED_P (decl) = 1; DECL_IGNORED_P (decl) = 1;
DECL_CONTEXT (decl) = current_function_decl;
return decl; return decl;
} }
......
...@@ -2149,7 +2149,7 @@ emit_thunk (thunk_fndecl) ...@@ -2149,7 +2149,7 @@ emit_thunk (thunk_fndecl)
t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t); t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);
finish_return_stmt (t); finish_return_stmt (t);
finish_function (lineno, 0); expand_body (finish_function (lineno, 0));
/* Don't let the backend defer this function. */ /* Don't let the backend defer this function. */
if (DECL_DEFER_OUTPUT (thunk_fndecl)) if (DECL_DEFER_OUTPUT (thunk_fndecl))
...@@ -2402,7 +2402,7 @@ synthesize_method (fndecl) ...@@ -2402,7 +2402,7 @@ synthesize_method (fndecl)
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
} }
finish_function (lineno, 0); expand_body (finish_function (lineno, 0));
extract_interface_info (); extract_interface_info ();
if (! context) if (! context)
......
...@@ -282,7 +282,7 @@ empty_parms () ...@@ -282,7 +282,7 @@ empty_parms ()
%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
%type <ttype> named_class_head_sans_basetype_defn %type <ttype> named_class_head_sans_basetype_defn
%type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
%type <ttype> handler_args
%type <ttype> self_template_type .finish_template_type %type <ttype> self_template_type .finish_template_type
%token NSNAME %token NSNAME
...@@ -660,9 +660,9 @@ eat_saved_input: ...@@ -660,9 +660,9 @@ eat_saved_input:
fndef: fndef:
fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error
{ finish_function (lineno, (int)$3); } { expand_body (finish_function (lineno, (int)$3)); }
| fn.def1 maybe_return_init function_try_block | fn.def1 maybe_return_init function_try_block
{ finish_function (lineno, (int)$3); } { expand_body (finish_function (lineno, (int)$3)); }
| fn.def1 maybe_return_init error | fn.def1 maybe_return_init error
{ } { }
; ;
...@@ -805,12 +805,8 @@ base_init: ...@@ -805,12 +805,8 @@ base_init:
store_parm_decls (); store_parm_decls ();
if (DECL_CONSTRUCTOR_P (current_function_decl)) if (DECL_CONSTRUCTOR_P (current_function_decl))
{
/* Make a contour for the initializer list. */ /* Make a contour for the initializer list. */
pushlevel (0); do_pushlevel ();
clear_last_expr ();
expand_start_bindings (0);
}
else if (current_class_type == NULL_TREE) else if (current_class_type == NULL_TREE)
error ("base initializers not allowed for non-member functions"); error ("base initializers not allowed for non-member functions");
else if (! DECL_CONSTRUCTOR_P (current_function_decl)) else if (! DECL_CONSTRUCTOR_P (current_function_decl))
...@@ -2073,12 +2069,12 @@ fn.defpen: ...@@ -2073,12 +2069,12 @@ fn.defpen:
pending_inline: pending_inline:
fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error
{ {
finish_function (lineno, (int)$3 | 2); expand_body (finish_function (lineno, (int)$3 | 2));
process_next_inline ($1); process_next_inline ($1);
} }
| fn.defpen maybe_return_init function_try_block | fn.defpen maybe_return_init function_try_block
{ {
finish_function (lineno, (int)$3 | 2); expand_body (finish_function (lineno, (int)$3 | 2));
process_next_inline ($1); process_next_inline ($1);
} }
| fn.defpen maybe_return_init error | fn.defpen maybe_return_init error
...@@ -3368,9 +3364,9 @@ handler: ...@@ -3368,9 +3364,9 @@ handler:
CATCH CATCH
{ $<ttype>$ = begin_handler(); } { $<ttype>$ = begin_handler(); }
handler_args handler_args
{ finish_handler_parms ($<ttype>2); } { $<ttype>$ = finish_handler_parms ($3, $<ttype>2); }
compstmt compstmt
{ finish_handler ($<ttype>2); } { finish_handler ($<ttype>4, $<ttype>2); }
; ;
type_specifier_seq: type_specifier_seq:
...@@ -3380,7 +3376,7 @@ type_specifier_seq: ...@@ -3380,7 +3376,7 @@ type_specifier_seq:
handler_args: handler_args:
'(' ELLIPSIS ')' '(' ELLIPSIS ')'
{ expand_start_catch_block (NULL_TREE); } { $$ = NULL_TREE; }
/* This doesn't allow reference parameters, the below does. /* This doesn't allow reference parameters, the below does.
| '(' type_specifier_seq absdcl ')' | '(' type_specifier_seq absdcl ')'
{ check_for_new_type ("inside exception declarations", $2); { check_for_new_type ("inside exception declarations", $2);
...@@ -3398,7 +3394,7 @@ handler_args: ...@@ -3398,7 +3394,7 @@ handler_args:
| '(' parm ')' | '(' parm ')'
{ {
check_for_new_type ("inside exception declarations", $2); check_for_new_type ("inside exception declarations", $2);
start_handler_parms (TREE_PURPOSE ($2.t), $$ = start_handler_parms (TREE_PURPOSE ($2.t),
TREE_VALUE ($2.t)); TREE_VALUE ($2.t));
} }
; ;
......
...@@ -7477,17 +7477,23 @@ tsubst_expr (t, args, complain, in_decl) ...@@ -7477,17 +7477,23 @@ tsubst_expr (t, args, complain, in_decl)
break; break;
case HANDLER: case HANDLER:
{
tree decl;
tree blocks;
prep_stmt (t); prep_stmt (t);
stmt = begin_handler (); stmt = begin_handler ();
if (HANDLER_PARMS (t)) if (HANDLER_PARMS (t))
expand_start_catch_block {
(tsubst (DECL_STMT_DECL (HANDLER_PARMS (t)), decl = DECL_STMT_DECL (HANDLER_PARMS (t));
args, complain, in_decl)); decl = tsubst (decl, args, complain, in_decl);
}
else else
expand_start_catch_block (NULL_TREE); decl = NULL_TREE;
finish_handler_parms (stmt); blocks = finish_handler_parms (decl, stmt);
tsubst_expr (HANDLER_BODY (t), args, complain, in_decl); tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
finish_handler (stmt); finish_handler (blocks, stmt);
}
break; break;
case TAG_DEFN: case TAG_DEFN:
......
...@@ -1196,5 +1196,5 @@ synthesize_tinfo_fn (fndecl) ...@@ -1196,5 +1196,5 @@ synthesize_tinfo_fn (fndecl)
pop_momentary (); pop_momentary ();
/* Finish the function body. */ /* Finish the function body. */
finish_compound_stmt (/*has_no_scope=*/0, compound_stmt); finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
finish_function (lineno, 0); expand_body (finish_function (lineno, 0));
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment