Commit 558475f0 by Mark Mitchell Committed by Mark Mitchell

cp-tree.def (STMT_EXPR): New tree node.

	* cp-tree.def (STMT_EXPR): New tree node.
	* cp-tree.h (STMT_EXPR_STMT): New macro.
	(store_return_init): Change prototype.
	(finish_named_return_value): New function.
	(expand_stmt): Likewise.
	(expand_body): Likewise.
	(begin_stmt_tree): Likewise.
	(finish_stmt_tree): Likewise.
	(expanding_p): New variable.
	(last_expr_type): Likewise.
	(building_stmt_tree): New macro.
	* decl.c (start_function): Use building_stmt_tree, not
	processing_template_decl, where appropriate.
	(store_parm_decls): Likewise.
	(store_return_init): Move most of the body to semantics.c.
	(finish_function): Use building_stmt_tree.
	(finish_stmt): Clear last_expr_type here.
	(cp_function): Add expanding_p, last_tree, last_expr_type.
	(push_cp_function_context): Save them.
	(pop_cp_function_context): Restore them.
	* decl2.c (setup_vtbl_ptr): Move to semantics.c.
	* error.c (dump_expr): Handle STMT_EXPR.
	* except.c (expand_start_catch_block): Use building_stmt_tree.
	Use add_decl_stmt.
	* expr.c (cplus_expand_expr): Handle STMT_EXPR.
	(do_case): Move add_tree call to semantics.c.
	* parse.y (return_init): Use finish_named_return_value.
	(for.init.statement): Use finish_expr_stmt.
	* parse.c: Regenerated.
	* pt.c (do_pushlevel): Move to semantics.c.
	(do_poplevel): Likewise.
	(tsubst_copy): Handle STMT_EXPR instead of BIND_EXPR.
	(tsubst_expr): Don't expand all the way to RTL here.  Handle
	RETURN_INIT and CTOR_INITIALIZER.
	(instantiate_decl): Call expand_body after tsubst'ing into
	DECL_SAVED_TREE.
	* semantics.c (expand_stmts): New function.
	(expanding_p): New variable.
	(last_expr_type): Likewise.
	(finish_expr_stmt): Use building_stmt_tree.
	(begin_if_stmt): Likewise.
	(finish_if_stmt_cond): Likewise.
	(finish_then_clause): Likewise.
	(begin_else_clause): Likewise.
	(finish_else_clause): Likewise.
	(begin_while_stmt): Likewise.
	(finish_while_stmt_cond): Likewise.
	(finish_while_stmt): Likewise.
	(finish_do_body): Likewise.
	(finish_do_stmt): Likewise.
	(finish_return_stmt): Likewise.
	(begin_for_stmt): Likewise.
	(fnish_for_init_stmt): Likewise.
	(finish_for_cond): Likewise.
	(finish_for_expr): Likewise.
	(finish_for_stmt): Likewise.
	(finish_break_stmt): Likewise.
	(finish_continue_stmt): Likewise.
	(finish_switch_cond): Likewise.
	(finish_switch_stmt): Likewise.
	(finish_case_label): Call add_tree here if necessary.
	(finish_goto_statement): Use building_stmt_tree.
	(begin_try_block): Likewise.
	(begin_function_try_block): Likewise.
	(finish_try_block): Likewise.
	(finish_function_try_block): Likewise.
	(finish_handler_sequence): Likewise.
	(finish_function_handler_sequence): Likewise.
	(begin_handler): Likewise.
	(finish_handler_parms): Likewise.
	(finish_handler): Likewise.
	(begin_compound_stmt): Likewise.
	(finish_compound_stmt): Likewise.
	(finish_asm_stmt): Likewise.
	(finish_label_stmt): Likewise.
	(finish_named_return_value): New function.
	(setup_vtbl_ptr): Moved here from decl2.c.
	(do_pushlevel): Moved here from pt.c.
	(do_poplevel): Likewise.
	(begin_stmt_expr): Use building_stmt_tree.
	(finish_stmt_expr): Likewise.  Build a STMT_EXPR, not a BIND_EXPR,
	when building_stmt_tree.
	(begin_stmt_tree): New function.
	(finish_stmt_tree): Likewise.
	(expand_stmt): Likewise.
	(expand_body): Likewise.
	* tree.c (build_cplus_method_type): Make sure the argument types
	end up on the same obstack as the METHOD_TYPE.
	(search_tree): Handle COMPOUND_EXPR, MODIFY_EXPR,
	THROW_EXPR, STMT_EXPR.
	(mapcar): Break out common cases.  Handle COMPOUND_EXPR,
	MODIFY_EXPR, THROW_EXPR, STMT_EXPR, RTL_EXPR.  Abort, rather than
	sorry, if an unsupported node is encountered.
	* typeck.c (require_complete_type_in_void): Handle BIND_EXPR.
	(c_expand_return): Don't call add_tree here.

From-SVN: r28729
parent 63ebc275
1999-08-16 Mark Mitchell <mark@codesourcery.com>
* cp-tree.def (STMT_EXPR): New tree node.
* cp-tree.h (STMT_EXPR_STMT): New macro.
(store_return_init): Change prototype.
(finish_named_return_value): New function.
(expand_stmt): Likewise.
(expand_body): Likewise.
(begin_stmt_tree): Likewise.
(finish_stmt_tree): Likewise.
(expanding_p): New variable.
(last_expr_type): Likewise.
(building_stmt_tree): New macro.
* decl.c (start_function): Use building_stmt_tree, not
processing_template_decl, where appropriate.
(store_parm_decls): Likewise.
(store_return_init): Move most of the body to semantics.c.
(finish_function): Use building_stmt_tree.
(finish_stmt): Clear last_expr_type here.
(cp_function): Add expanding_p, last_tree, last_expr_type.
(push_cp_function_context): Save them.
(pop_cp_function_context): Restore them.
* decl2.c (setup_vtbl_ptr): Move to semantics.c.
* error.c (dump_expr): Handle STMT_EXPR.
* except.c (expand_start_catch_block): Use building_stmt_tree.
Use add_decl_stmt.
* expr.c (cplus_expand_expr): Handle STMT_EXPR.
(do_case): Move add_tree call to semantics.c.
* parse.y (return_init): Use finish_named_return_value.
(for.init.statement): Use finish_expr_stmt.
* parse.c: Regenerated.
* pt.c (do_pushlevel): Move to semantics.c.
(do_poplevel): Likewise.
(tsubst_copy): Handle STMT_EXPR instead of BIND_EXPR.
(tsubst_expr): Don't expand all the way to RTL here. Handle
RETURN_INIT and CTOR_INITIALIZER.
(instantiate_decl): Call expand_body after tsubst'ing into
DECL_SAVED_TREE.
* semantics.c (expand_stmts): New function.
(expanding_p): New variable.
(last_expr_type): Likewise.
(finish_expr_stmt): Use building_stmt_tree.
(begin_if_stmt): Likewise.
(finish_if_stmt_cond): Likewise.
(finish_then_clause): Likewise.
(begin_else_clause): Likewise.
(finish_else_clause): Likewise.
(begin_while_stmt): Likewise.
(finish_while_stmt_cond): Likewise.
(finish_while_stmt): Likewise.
(finish_do_body): Likewise.
(finish_do_stmt): Likewise.
(finish_return_stmt): Likewise.
(begin_for_stmt): Likewise.
(fnish_for_init_stmt): Likewise.
(finish_for_cond): Likewise.
(finish_for_expr): Likewise.
(finish_for_stmt): Likewise.
(finish_break_stmt): Likewise.
(finish_continue_stmt): Likewise.
(finish_switch_cond): Likewise.
(finish_switch_stmt): Likewise.
(finish_case_label): Call add_tree here if necessary.
(finish_goto_statement): Use building_stmt_tree.
(begin_try_block): Likewise.
(begin_function_try_block): Likewise.
(finish_try_block): Likewise.
(finish_function_try_block): Likewise.
(finish_handler_sequence): Likewise.
(finish_function_handler_sequence): Likewise.
(begin_handler): Likewise.
(finish_handler_parms): Likewise.
(finish_handler): Likewise.
(begin_compound_stmt): Likewise.
(finish_compound_stmt): Likewise.
(finish_asm_stmt): Likewise.
(finish_label_stmt): Likewise.
(finish_named_return_value): New function.
(setup_vtbl_ptr): Moved here from decl2.c.
(do_pushlevel): Moved here from pt.c.
(do_poplevel): Likewise.
(begin_stmt_expr): Use building_stmt_tree.
(finish_stmt_expr): Likewise. Build a STMT_EXPR, not a BIND_EXPR,
when building_stmt_tree.
(begin_stmt_tree): New function.
(finish_stmt_tree): Likewise.
(expand_stmt): Likewise.
(expand_body): Likewise.
* tree.c (build_cplus_method_type): Make sure the argument types
end up on the same obstack as the METHOD_TYPE.
(search_tree): Handle COMPOUND_EXPR, MODIFY_EXPR,
THROW_EXPR, STMT_EXPR.
(mapcar): Break out common cases. Handle COMPOUND_EXPR,
MODIFY_EXPR, THROW_EXPR, STMT_EXPR, RTL_EXPR. Abort, rather than
sorry, if an unsupported node is encountered.
* typeck.c (require_complete_type_in_void): Handle BIND_EXPR.
(c_expand_return): Don't call add_tree here.
1999-08-15 Mark Mitchell <mark@codesourcery.com>
* pt.c (check_default_tmpl_args): Don't check in local scopes.
......
......@@ -235,6 +235,10 @@ DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2)
DEFTREECODE (HANDLER, "catch_stmt", 'e', 2)
/* A STMT_EXPR represents a statement-expression. The
STMT_EXPR_STMT is the statement given by the expression. */
DEFTREECODE (STMT_EXPR, "cp_stmt_expr", 'e', 1)
DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
/* And some codes for expressing conversions for overload resolution. */
......
......@@ -2138,6 +2138,7 @@ extern int flag_new_for_scope;
#define ASM_INPUTS(NODE) TREE_OPERAND (NODE, 3)
#define ASM_CLOBBERS(NODE) TREE_OPERAND (NODE, 4)
#define DECL_STMT_DECL(NODE) TREE_OPERAND (NODE, 0)
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (NODE, 0)
/* Nonzero for an ASM_STMT if the assembly statement is volatile. */
#define ASM_VOLATILE_P(NODE) \
......@@ -2919,7 +2920,7 @@ extern tree build_enumerator PROTO((tree, tree, tree));
extern int start_function PROTO((tree, tree, tree, int));
extern void expand_start_early_try_stmts PROTO((void));
extern void store_parm_decls PROTO((void));
extern void store_return_init PROTO((tree, tree));
extern void store_return_init PROTO((tree));
extern void finish_function PROTO((int, int, int));
extern tree start_method PROTO((tree, tree, tree));
extern tree finish_method PROTO((tree));
......@@ -3365,6 +3366,17 @@ extern void finish_member_declaration PROTO((tree));
extern void check_multiple_declarators PROTO((void));
extern tree finish_typeof PROTO((tree));
extern void add_decl_stmt PROTO((tree));
extern void finish_named_return_value PROTO((tree, tree));
extern tree expand_stmt PROTO((tree));
extern void expand_body PROTO((tree));
extern void begin_stmt_tree PROTO((tree));
extern void finish_stmt_tree PROTO((tree));
extern int expanding_p;
extern tree last_expr_type;
/* Non-zero if we are presently building a statement tree, rather
than expanding each statement as we encounter it. */
#define building_stmt_tree() \
(processing_template_decl || !expanding_p)
/* in spew.c */
extern void init_spew PROTO((void));
......
......@@ -4341,7 +4341,7 @@ maybe_push_decl (decl)
&& TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
|| TREE_CODE (type) == UNKNOWN_TYPE
/* The declaration of template specializations does not affect
/* The declaration of a template specialization does not affect
the functions available for overload resolution, so we do not
call pushdecl. */
|| (TREE_CODE (decl) == FUNCTION_DECL
......@@ -12882,7 +12882,8 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
&& IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE)
cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)));
announce_function (decl1);
if (!building_stmt_tree ())
announce_function (decl1);
/* Set up current_class_type, and enter the scope of the class, if
appropriate. */
......@@ -13110,12 +13111,14 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
pushlevel (0);
current_binding_level->parm_flag = 1;
GNU_xref_function (decl1, current_function_parms);
if (attrs)
cplus_decl_attributes (decl1, NULL_TREE, attrs);
make_function_rtl (decl1);
if (!building_stmt_tree ())
{
GNU_xref_function (decl1, current_function_parms);
make_function_rtl (decl1);
}
/* Promote the value to int before returning it. */
if (C_PROMOTING_INTEGER_TYPE_P (restype))
......@@ -13141,9 +13144,8 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
if (! hack_decl_function_context (decl1))
temporary_allocation ();
if (processing_template_decl)
last_tree = DECL_SAVED_TREE (decl1)
= build_nt (EXPR_STMT, void_zero_node);
if (building_stmt_tree ())
begin_stmt_tree (decl1);
++function_depth;
......@@ -13254,7 +13256,7 @@ store_parm_decls ()
pushdecl (parm);
}
if (! processing_template_decl
if (! building_stmt_tree ()
&& (cleanup = maybe_build_cleanup (parm), cleanup))
{
expand_decl (parm);
......@@ -13295,21 +13297,20 @@ store_parm_decls ()
/* Initialize the RTL code for the function. */
DECL_SAVED_INSNS (fndecl) = 0;
if (! processing_template_decl)
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))
if (DECL_MAIN_P (fndecl) && !building_stmt_tree ())
expand_main_function ();
/* Now that we have initialized the parms, we can start their
cleanups. We cannot do this before, since expand_decl_cleanup
should not be called before the parm can be used. */
if (cleanups
&& ! processing_template_decl)
if (cleanups && !building_stmt_tree ())
{
for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups))
{
......@@ -13325,10 +13326,11 @@ store_parm_decls ()
if (parms_have_cleanups)
{
pushlevel (0);
expand_start_bindings (0);
if (!building_stmt_tree ())
expand_start_bindings (0);
}
if (! processing_template_decl && flag_exceptions)
if (! building_stmt_tree () && flag_exceptions)
{
/* Do the starting of the exception specifications, if we have any. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
......@@ -13343,55 +13345,15 @@ store_parm_decls ()
the current function. */
void
store_return_init (return_id, init)
tree return_id, init;
store_return_init (decl)
tree decl;
{
tree decl = DECL_RESULT (current_function_decl);
if (pedantic)
/* Give this error as many times as there are occurrences,
so that users can use Emacs compilation buffers to find
and fix all such places. */
pedwarn ("ANSI C++ does not permit named return values");
if (return_id != NULL_TREE)
{
if (DECL_NAME (decl) == NULL_TREE)
{
DECL_NAME (decl) = return_id;
DECL_ASSEMBLER_NAME (decl) = return_id;
}
else
cp_error ("return identifier `%D' already in place", decl);
}
/* Can't let this happen for constructors. */
if (DECL_CONSTRUCTOR_P (current_function_decl))
/* If this named return value comes in a register, put it in a
pseudo-register. */
if (DECL_REGISTER (decl))
{
error ("can't redefine default return value for constructors");
return;
}
/* If we have a named return value, put that in our scope as well. */
if (DECL_NAME (decl) != NULL_TREE)
{
/* If this named return value comes in a register,
put it in a pseudo-register. */
if (DECL_REGISTER (decl))
{
original_result_rtx = DECL_RTL (decl);
DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
}
/* Let `cp_finish_decl' know that this initializer is ok. */
DECL_INITIAL (decl) = init;
pushdecl (decl);
if (processing_template_decl && current_function_decl)
add_tree (build_min_nt (RETURN_INIT, return_id,
copy_to_permanent (init)));
else
cp_finish_decl (decl, init, NULL_TREE, 0, 0);
original_result_rtx = DECL_RTL (decl);
DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
}
}
......@@ -13430,7 +13392,7 @@ finish_function (lineno, flags, nested)
tree decls = NULL_TREE;
int call_poplevel = (flags & 1) != 0;
int inclass_inline = (flags & 2) != 0;
int in_template;
int expand_p;
/* When we get some parse errors, we can end up without a
current_function_decl, so cope. */
......@@ -13453,7 +13415,7 @@ finish_function (lineno, flags, nested)
store_parm_decls ();
}
if (processing_template_decl)
if (building_stmt_tree ())
{
if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel)
{
......@@ -13834,19 +13796,15 @@ finish_function (lineno, flags, nested)
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 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 processing a template, squirrel away the definition
until we do an instantiation. */
if (processing_template_decl)
{
DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl));
/* We have to save this value here in case
maybe_end_member_template_processing decides to pop all the
template parameters. */
in_template = 1;
}
else
in_template = 0;
/* If we're saving up tree structure, tie off the function now. */
if (!expand_p)
finish_stmt_tree (fndecl);
/* This must come after expand_function_end because cleanups might
have declarations (from inline functions) that need to go into
......@@ -13880,7 +13838,7 @@ finish_function (lineno, flags, nested)
to the FUNCTION_DECL node itself. */
BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
if (!in_template)
if (expand_p)
{
int saved_flag_keep_inline_functions =
flag_keep_inline_functions;
......@@ -14285,12 +14243,6 @@ void
cplus_expand_expr_stmt (exp)
tree exp;
{
if (processing_template_decl)
{
add_tree (build_min_nt (EXPR_STMT, exp));
return;
}
/* Arrange for all temps to disappear. */
expand_start_target_temps ();
......@@ -14324,28 +14276,30 @@ cplus_expand_expr_stmt (exp)
expand_end_target_temps ();
}
/* When a stmt has been parsed, this function is called.
Currently, this function only does something within a
constructor's scope: if a stmt has just assigned to this,
and we are in a derived class, we call `emit_base_init'. */
/* When a stmt has been parsed, this function is called. */
void
finish_stmt ()
{
if (current_function_assigns_this
|| ! current_function_just_assigned_this)
return;
if (DECL_CONSTRUCTOR_P (current_function_decl))
if (!current_function_assigns_this
&& current_function_just_assigned_this)
{
/* Constructors must wait until we are out of control
zones before calling base constructors. */
if (in_control_zone_p ())
return;
expand_expr_stmt (base_init_expr);
check_base_init (current_class_type);
if (DECL_CONSTRUCTOR_P (current_function_decl))
{
/* Constructors must wait until we are out of control
zones before calling base constructors. */
if (in_control_zone_p ())
return;
expand_expr_stmt (base_init_expr);
check_base_init (current_class_type);
}
current_function_assigns_this = 1;
}
current_function_assigns_this = 1;
/* Always assume this statement was not an expression statement. If
it actually was an expression statement, its our callers
responsibility to fix this up. */
last_expr_type = NULL_TREE;
}
/* Change a static member function definition into a FUNCTION_TYPE, instead
......@@ -14408,6 +14362,9 @@ struct cp_function
struct binding_level *binding_level;
int static_labelno;
int in_function_try_handler;
int expanding_p;
tree last_tree;
tree last_expr_type;
};
static struct cp_function *cp_function_chain;
......@@ -14451,6 +14408,13 @@ push_cp_function_context (context)
p->current_class_ref = current_class_ref;
p->static_labelno = static_labelno;
p->in_function_try_handler = in_function_try_handler;
p->last_tree = last_tree;
p->last_expr_type = last_expr_type;
p->expanding_p = expanding_p;
/* For now, we always assume we're expanding all the way to RTL
unless we're explicitly doing otherwise. */
expanding_p = 1;
}
/* Restore the variables used during compilation of a C++ function. */
......@@ -14494,6 +14458,9 @@ pop_cp_function_context (context)
current_class_ref = p->current_class_ref;
static_labelno = p->static_labelno;
in_function_try_handler = p->in_function_try_handler;
last_tree = p->last_tree;
last_expr_type = p->last_expr_type;
expanding_p = p->expanding_p;
free (p);
}
......
......@@ -2001,27 +2001,6 @@ constructor_name (thing)
return t;
}
/* Cache the value of this class's main virtual function table pointer
in a register variable. This will save one indirection if a
more than one virtual function call is made this function. */
void
setup_vtbl_ptr ()
{
extern tree base_init_expr;
if (base_init_expr == 0
&& DECL_CONSTRUCTOR_P (current_function_decl))
{
if (processing_template_decl)
add_tree (build_min_nt
(CTOR_INITIALIZER,
current_member_init_list, current_base_init_list));
else
emit_base_init (current_class_type, 0);
}
}
/* Record the existence of an addressable inline function. */
void
......
......@@ -1780,6 +1780,12 @@ dump_expr (t, nop)
dump_decl (t, 0);
break;
case STMT_EXPR:
/* We don't yet have a way of dumping statements in a
human-readable format. */
OB_PUTS ("{ ... }");
break;
case BIND_EXPR:
OB_PUTS ("{ ");
dump_expr (TREE_OPERAND (t, 1), nop);
......
......@@ -558,17 +558,14 @@ expand_start_catch_block (declspecs, declarator)
{
tree decl;
if (processing_template_decl)
if (building_stmt_tree ())
{
if (declspecs)
{
decl = grokdeclarator (declarator, declspecs, CATCHPARM,
1, NULL_TREE);
pushdecl (decl);
decl = build_min_nt (DECL_STMT, copy_to_permanent (declarator),
copy_to_permanent (declspecs),
NULL_TREE);
add_tree (decl);
add_decl_stmt (decl);
}
return;
}
......@@ -579,7 +576,6 @@ expand_start_catch_block (declspecs, declarator)
process_start_catch_block (declspecs, declarator);
}
/* 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
......
......@@ -246,6 +246,15 @@ cplus_expand_expr (exp, target, tmode, modifier)
case NEW_EXPR:
return expand_expr (build_new_1 (exp), target, tmode, modifier);
case STMT_EXPR:
{
tree rtl_expr = begin_stmt_expr ();
tree block = expand_stmt (STMT_EXPR_STMT (exp));
finish_stmt_expr (rtl_expr, block);
return expand_expr (rtl_expr, target, tmode, modifier);
}
break;
default:
break;
}
......@@ -388,12 +397,6 @@ do_case (start, end)
if (end && pedantic)
pedwarn ("ANSI C++ forbids range expressions in switch statement");
if (processing_template_decl)
{
add_tree (build_min_nt (CASE_LABEL, start, end));
return;
}
if (start)
value1 = check_cp_case_value (start);
if (end)
......
......@@ -4912,15 +4912,15 @@ case 122:
break;}
case 123:
#line 770 "parse.y"
{ store_return_init (yyval.ttype, yyvsp[0].ttype); ;
{ finish_named_return_value (yyval.ttype, yyvsp[0].ttype); ;
break;}
case 124:
#line 772 "parse.y"
{ store_return_init (yyval.ttype, yyvsp[-1].ttype); ;
{ finish_named_return_value (yyval.ttype, yyvsp[-1].ttype); ;
break;}
case 125:
#line 774 "parse.y"
{ store_return_init (yyval.ttype, NULL_TREE); ;
{ finish_named_return_value (yyval.ttype, NULL_TREE); ;
break;}
case 126:
#line 779 "parse.y"
......@@ -7732,7 +7732,7 @@ case 783:
break;}
case 784:
#line 3411 "parse.y"
{ if (yyvsp[-1].ttype) cplus_expand_expr_stmt (yyvsp[-1].ttype); ;
{ finish_expr_stmt (yyvsp[-1].ttype); ;
break;}
case 786:
#line 3414 "parse.y"
......
......@@ -767,11 +767,11 @@ return_id:
return_init:
return_id maybe_init
{ store_return_init ($<ttype>$, $2); }
{ finish_named_return_value ($<ttype>$, $2); }
| return_id '(' nonnull_exprlist ')'
{ store_return_init ($<ttype>$, $3); }
{ finish_named_return_value ($<ttype>$, $3); }
| return_id LEFT_RIGHT
{ store_return_init ($<ttype>$, NULL_TREE); }
{ finish_named_return_value ($<ttype>$, NULL_TREE); }
;
base_init:
......@@ -3408,7 +3408,7 @@ label_colon:
for.init.statement:
xexpr ';'
{ if ($1) cplus_expand_expr_stmt ($1); }
{ finish_expr_stmt ($1); }
| decl
| '{' compstmtend
{ if (pedantic)
......
......@@ -412,15 +412,20 @@ build_cplus_method_type (basetype, rettype, argtypes)
ptype = build_pointer_type (basetype);
/* The actual arglist for this function includes a "hidden" argument
which is "this". Put it into the list of argument types. */
which is "this". Put it into the list of argument types. Make
sure that the new argument list is allocated on the same obstack
as the type. */
push_obstacks (TYPE_OBSTACK (t), TYPE_OBSTACK (t));
argtypes = tree_cons (NULL_TREE, ptype, argtypes);
TYPE_ARG_TYPES (t) = argtypes;
TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
pop_obstacks ();
/* If we already have such a type, use the old one and free this one.
Note that it also frees up the above cons cell if found. */
hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes);
hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
type_hash_list (argtypes);
t = type_hash_canon (hashcode, t);
if (TYPE_SIZE (t) == 0)
......@@ -1646,6 +1651,8 @@ search_tree (t, func)
case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR:
case CALL_EXPR:
case COMPOUND_EXPR:
case MODIFY_EXPR:
TRY (TREE_OPERAND (t, 0));
TRY (TREE_OPERAND (t, 1));
break;
......@@ -1657,6 +1664,7 @@ search_tree (t, func)
case COMPONENT_REF:
case CLEANUP_POINT_EXPR:
case LOOKUP_EXPR:
case THROW_EXPR:
TRY (TREE_OPERAND (t, 0));
break;
......@@ -1681,6 +1689,7 @@ search_tree (t, func)
break;
case BIND_EXPR:
case STMT_EXPR:
break;
case REAL_TYPE:
......@@ -1774,6 +1783,7 @@ mapcar (t, func)
tree (*func) PROTO((tree));
{
tree tmp;
enum tree_code code;
if (t == NULL_TREE)
return t;
......@@ -1785,6 +1795,24 @@ mapcar (t, func)
return tmp;
}
/* Handle some common cases up front. */
code = TREE_CODE (t);
if (TREE_CODE_CLASS (code) == '1')
{
t = copy_node (t);
TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;
}
else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
{
t = copy_node (t);
TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
return t;
}
switch (TREE_CODE (t))
{
case ERROR_MARK:
......@@ -1871,40 +1899,8 @@ mapcar (t, func)
TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
return t;
case SAVE_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;
case MODIFY_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
case MIN_EXPR:
case MAX_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case BIT_AND_EXPR:
case BIT_ANDTC_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case LT_EXPR:
case LE_EXPR:
case GT_EXPR:
case GE_EXPR:
case EQ_EXPR:
case NE_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
case COMPOUND_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
......@@ -1913,6 +1909,8 @@ mapcar (t, func)
case SCOPE_REF:
case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR:
case COMPOUND_EXPR:
case MODIFY_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
......@@ -1933,16 +1931,14 @@ mapcar (t, func)
TREE_OPERAND (t, 2) = NULL_TREE;
return t;
case CONVERT_EXPR:
case SAVE_EXPR:
case ADDR_EXPR:
case INDIRECT_REF:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
case NOP_EXPR:
case COMPONENT_REF:
case CLEANUP_POINT_EXPR:
case NON_LVALUE_EXPR:
case THROW_EXPR:
case STMT_EXPR:
t = copy_node (t);
TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
......@@ -2009,19 +2005,19 @@ mapcar (t, func)
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;
case RTL_EXPR:
t = copy_node (t);
TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
return t;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
return build_ptrmemfunc_type
(mapcar (TYPE_PTRMEMFUNC_FN_TYPE (t), func));
/* else fall through */
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' not call
`report_error_function'. That could cause an infinite loop. */
default:
sorry ("initializer contains unrecognized tree code");
return error_mark_node;
default:
my_friendly_abort (19990815);
}
my_friendly_abort (107);
/* NOTREACHED */
......
......@@ -197,6 +197,7 @@ require_complete_type_in_void (expr)
case EXIT_EXPR: /* have no return */
case LOOP_EXPR: /* have no return */
case BIND_EXPR: /* have no return */
case STMT_EXPR: /* have no return */
case THROW_EXPR: /* have no return */
case MODIFY_EXPR: /* sometimes this has a void type, but that's ok */
case CONVERT_EXPR: /* sometimes has a void type */
......@@ -6801,12 +6802,6 @@ c_expand_return (retval)
return;
}
if (processing_template_decl)
{
add_tree (build_min_nt (RETURN_STMT, retval));
return;
}
if (dtor_label)
{
if (retval)
......
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