Commit 35b1567d by Ben Chelf

c-common.h (IF_COND): Added documentation.

	* c-common.h (IF_COND): Added documentation.
	(THEN_CLAUSE): Likewise.
	(ELSE_CLAUSE): Likewise.
	(WHILE_COND): Likewise.
	(WHILE_BODY): Likewise.
	(DO_COND): Likewise.
	(DO_BODY): Likewise.
	(RETURN_EXPR): Likewise.
	(EXPR_STMT_EXPR): Likewise.
	(FOR_INIT_STMT): Likewise.
	(FOR_COND): Likewise.
	(FOR_EXPR): Likewise.
	(FOR_BODY): Likewise.
	(SWITCH_COND): Likewise.
	(SWITCH_BODY): Likewise.
	(CASE_LOW): Likewise.
	(CASE_HIGH): Likewise.
	(GOTO_DESTINATION): Likewise.
	(COMPOUND_BODY): Likewise.
	(ASM_CV_QUAL): Likewise.
	(ASM_STRING): Likewise.
	(ASM_OUTPUTS): Likewise.
	(ASM_INPUTS): Likewise.
	(ASM_CLOBBERS): Likewise.
	(DECL_STMT_DECL): Likewise.
	(STMT_EXPR_STMT): Likewise.
	(LABEL_STMT_LABEL): Likewise.

	* c-common.def: Added documenetion for SRCLOC, EXPR_STMT,
	COMPOUND_STMT, DECL_STMT, IF_STMT, FOR_STMT, WHILE_STMT, DO_STMT,
	RETURN_STMT, BREAK_STMT, CONTINUE_STMT, SWITCH_STMT, GOTO_STMT,
	LABEL_STMT, ASM_STMT, SCOPE_STMT, CASE_LABEL, STMT_EXPR.

	* cp/cp-tree.h (genrtl_try_block): Declare function.
	(genrtl_handler): Likewise.
	(genrtl_catch_block): Likewise.
	(genrtl_ctor_stmt): Likewise.
	(genrtl_subobject): Likewise.
	(genrtl_decl_cleanup): Likewise.
	(genrtl_do_poplevel): Likewise.
	(genrtl_do_pushlevel): Likewise.
	(genrtl_clear_out_block): Likewise.
	(genrtl_goto_stmt): Likewise.
	(genrtl_expr_stmt): Likewise.
	(genrtl_decl_stmt): Likewise.
	(genrtl_if_stmt): Likewise.
	(genrtl_while_stmt): Likewise.
	(genrtl_do_stmt): Likewise.
	(genrtl_return_stmt): Likewise.
	(genrtl_for_stmt): Likewise.
	(genrtl_break_stmt): Likewise.
	(genrtl_continue_stmt): Likewise.
	(genrtl_scope_stmt): Likewise.
	(genrtl_switch_stmt): Likewise.
	(genrtl_case_label): Likewise.
	(genrtl_begin_compound_stmt): Likewise.
	(genrtl_finish_compound_stmt): Likewise.
	(genrtl_compound_stmt): Likewise.
	(genrtl_asm_stmt): Likewise.
	(genrtl_named_return_value): Likewise.
	(genrtl_begin_stmt_expr): Likewise.
	(genrtl_finish_stmt_expr): Likewise.
	(finish_for_stmt): Removed first argument.
	(finish_switch_stmt): Likewise.

	* cp/semantics.c (genrtl_try_block): Define function.
	(genrtl_handler): Likewise.
	(genrtl_catch_block): Likewise.
	(genrtl_ctor_stmt): Likewise.
	(genrtl_subobject): Likewise.
	(genrtl_decl_cleanup): Likewise.
	(genrtl_do_poplevel): Likewise.
	(genrtl_do_pushlevel): Likewise.
	(genrtl_clear_out_block): Likewise.
	(genrtl_goto_stmt): Likewise.
	(genrtl_expr_stmt): Likewise.
	(genrtl_decl_stmt): Likewise.
	(genrtl_if_stmt): Likewise.
	(genrtl_while_stmt): Likewise.
	(genrtl_do_stmt): Likewise.
	(genrtl_return_stmt): Likewise.
	(genrtl_for_stmt): Likewise.
	(genrtl_break_stmt): Likewise.
	(genrtl_continue_stmt): Likewise.
	(genrtl_scope_stmt): Likewise.
	(genrtl_switch_stmt): Likewise.
	(genrtl_case_label): Likewise.
	(genrtl_begin_compound_stmt): Likewise.
	(genrtl_finish_compound_stmt): Likewise.
	(genrtl_compound_stmt): Likewise.
	(genrtl_asm_stmt): Likewise.
	(genrtl_named_return_value): Likewise.
	(genrtl_begin_stmt_expr): Likewise.
	(genrtl_finish_stmt_expr): Likewise.
	(finish_for_stmt): Removed first argument and generate rtl
	specific code.
	(finish_switch_stmt): Likewise.
	(do_poplevel): Removed generate rtl specific code.
	(do_pushlevel): Likewise.
	(add_tree): Likewise.
	(finish_goto_stmt): Likewise.
	(finish_expr_stmt): Likewise.
	(begin_if_stmt): Likewise.
	(finish_if_stmt_cond): Likewise.
	(finish_then_clause): Likewise.
	(begin_else_clause): Likewise.
	(finish_else_clause): Likewise.
	(finish_if_stmt): Likewise.
	(clear_out_block): Likewise.
	(begin_while_stmt): Likewise.
	(finish_while_stmt_cond): Likewise.
	(finish_while_stmt): Likewise.
	(begin_do_stmt): Likewise.
	(finish_do_body): Likewise.
	(finish_do_stmt): Likewise.
	(finish_return_stmt): Likewise.
	(begin_for_stmt): Likewise.
	(finish_for_init_stmt): Likewise.
	(finish_for_cond): Likewise.
	(finish_for_expr): Likewise.
	(finish_break_stmt): Likewise.
	(finish_continue_stmt): Likewise.
	(begin_switch_stmt): Likewise.
	(finish_switch_cond): Likewise.
	(finish_case_label): Likewise.
	(begin_try_block): Likewise.
	(begin_function_try_block): Likewise.
	(finish_try_block): Likewise.
	(finish_cleanup_try_block): Likewise.
	(finish_cleanup): Likewise.
	(finish_function_try_block): Likewise.
	(finish_handler_sequence): Likewise.
	(finish_function_handler_sequence): Likewise.
	(begin_handler): Likewise.
	(finish_handler_parms): Likewise.
	(begin_catch_block): Likewise.
	(finish_handler): Likewise.
	(begin_compound_stmt): Likewise.
	(finish_compound_stmt): Likewise.
	(finish_asm_stmt): Likewise.
	(finish_label_stmt): Likewise.
	(finish_label_decl): Likewise.
	(finish_subobject): Likewise.
	(finish_decl_cleanup): Likewise.
	(finish_named_return_value): Likewise.
	(begin_stmt_expr): Likewise.
	(finish_stmt_expr): Likewise.

	* cp/decl.c (initialize_local_var): Changed call to finish_expr_stmt
	to call genrtl_expr_stmt when appropriate.

	* cp/init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
	begin_compound_expr to call genrtl_begin_stmt_expr and
	genrtl_begin_compound_expr when appropriate.
	(finish_init_stmts): Changed calls to finish_compound_expr and
	finish_stmt_expr to call genrtl_finish_compound_expr and
	genrtl_finish_stmt_expr when appropriate.
	(expand_default_init): Changed call to finish_expr_stmt to call
	genrtl_expr_stmt when appropriate.
	(build_vec_init): Likewise.

	* cp/parse.y (simple_stmt): Removed first argument from call to
	finish_for_stmt. Removed first argument from call to
	finish_switch_stmt.

	* cp/parse.c: Regenerated.

	* cp/pt.c (tsubst_expr): Removed first argument from call to
	finish_for_stmt. Removed first argument from call to
	finish_switch_stmt.

From-SVN: r34597
parent 59f406b7
2000-06-19 Benjamin Chelf <chelf@codesourcery.com>
* c-common.h (IF_COND): Added documentation.
(THEN_CLAUSE): Likewise.
(ELSE_CLAUSE): Likewise.
(WHILE_COND): Likewise.
(WHILE_BODY): Likewise.
(DO_COND): Likewise.
(DO_BODY): Likewise.
(RETURN_EXPR): Likewise.
(EXPR_STMT_EXPR): Likewise.
(FOR_INIT_STMT): Likewise.
(FOR_COND): Likewise.
(FOR_EXPR): Likewise.
(FOR_BODY): Likewise.
(SWITCH_COND): Likewise.
(SWITCH_BODY): Likewise.
(CASE_LOW): Likewise.
(CASE_HIGH): Likewise.
(GOTO_DESTINATION): Likewise.
(COMPOUND_BODY): Likewise.
(ASM_CV_QUAL): Likewise.
(ASM_STRING): Likewise.
(ASM_OUTPUTS): Likewise.
(ASM_INPUTS): Likewise.
(ASM_CLOBBERS): Likewise.
(DECL_STMT_DECL): Likewise.
(STMT_EXPR_STMT): Likewise.
(LABEL_STMT_LABEL): Likewise.
* c-common.def: Added documenetion for SRCLOC, EXPR_STMT,
COMPOUND_STMT, DECL_STMT, IF_STMT, FOR_STMT, WHILE_STMT, DO_STMT,
RETURN_STMT, BREAK_STMT, CONTINUE_STMT, SWITCH_STMT, GOTO_STMT,
LABEL_STMT, ASM_STMT, SCOPE_STMT, CASE_LABEL, STMT_EXPR.
2000-06-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.in (--enable-checking): Update --help doc to reflect
......
......@@ -28,25 +28,60 @@ cp-tree.def in the cp subdir. */
/* A node to remember a source position. */
DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to
obtain the expression. */
DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
/* Used to represent a brace-enclosed block. The operand is
COMPOUND_BODY. */
DEFTREECODE (COMPOUND_STMT, "compound_stmt", 'e', 1)
/* Used to represent a local declaration. The operand is
DECL_STMT_DECL. */
DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1)
/* Represents an 'if' statement. The operands are IF_COND,
THEN_CLAUSE, and ELSE_CLAUSE, respectively. */
DEFTREECODE (IF_STMT, "if_stmt", 'e', 3)
/* Used to represent a `for' statement. The operands are
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
/* Used to represent a 'while' statement. The operands are WHILE_COND
and WHILE_BODY, respectively. */
DEFTREECODE (WHILE_STMT, "while_stmt", 'e', 2)
/* Used to represent a 'do' statement. The operands are DO_BODY and
DO_COND, respectively. */
DEFTREECODE (DO_STMT, "do_stmt", 'e', 2)
/* Used to represent a 'return' statement. The operand is
RETURN_EXPR. */
DEFTREECODE (RETURN_STMT, "return_stmt", 'e', 1)
/* Used to represent a 'break' statement. */
DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
/* Used to represent a 'continue' statement. */
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
/* Used to represent a 'switch' statement. The operands are
SWITCH_COND and SWITCH_BODY, respectively. */
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 2)
/* Used to represent a 'goto' statement. The operand is GOTO_DESTINATION. */
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
/* Used to represent a 'label' statement. The operand is a LABEL_DECL
and can be obtained through the macro LABEL_STMT_LABEL. */
DEFTREECODE (LABEL_STMT, "label_stmt", 'e', 1)
/* Used to represent an inline assembly statement. */
DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
/* A SCOPE_STMT marks the beginning or end of a scope. If
......@@ -56,6 +91,11 @@ DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
this scope. The SCOPE_STMT_BLOCK is the BLOCK containing the
variables declared in this scope. */
DEFTREECODE (SCOPE_STMT, "scope_stmt", 'e', 1)
/* Used to represent a CASE_LABEL. The operands are CASE_LOW and
CASE_HIGH, respectively. If CASE_LOW is NULL_TREE, the label is a
'default' label. If CASE_HIGH is NULL_TREE, the label is a normal case
label. */
DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
/* A STMT_EXPR represents a statement-expression. The
......
......@@ -167,32 +167,79 @@ extern tree simple_type_promotes_to PARAMS ((tree));
/* These macros provide convenient access to the various _STMT nodes
created when parsing template declarations. */
/* IF_STMT accessors. These give access to the condtion of the if
statement, the then block of the if statement, and the else block
of the if stsatement if it exists. */
#define IF_COND(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
#define THEN_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
#define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
/* WHILE_STMT accessors. These give access to the condtion of the
while statement and the body of the while statement, respectively. */
#define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0)
#define WHILE_BODY(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 1)
/* DO_STMT accessors. These give access to the condition of the do
statement and the body of the do statement, respectively. */
#define DO_COND(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 0)
#define DO_BODY(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 1)
/* RETURN_STMT accessor. This gives the expression associated with a
return statement. */
#define RETURN_EXPR(NODE) TREE_OPERAND (RETURN_STMT_CHECK (NODE), 0)
/* EXPR_STMT accessor. This gives the expression associated with an
expression statement. */
#define EXPR_STMT_EXPR(NODE) TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)
/* FOR_STMT accessors. These give access to the init statement,
condition, update expression, and body of the for statement,
respectively. */
#define FOR_INIT_STMT(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 0)
#define FOR_COND(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 1)
#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2)
#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3)
/* SWITCH_STMT accessors. These give access to the condition and body
of the switch statement, respectively. */
#define SWITCH_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0)
#define SWITCH_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1)
/* CASE_LABEL accessors. These give access to the high and low values
of a case label, respectively. */
#define CASE_LOW(NODE) TREE_OPERAND (CASE_LABEL_CHECK (NODE), 0)
#define CASE_HIGH(NODE) TREE_OPERAND (CASE_LABEL_CHECK (NODE), 1)
/* GOTO_STMT accessor. This gives access to the label associated with
a goto statement. */
#define GOTO_DESTINATION(NODE) TREE_OPERAND (GOTO_STMT_CHECK (NODE), 0)
/* COMPOUND_STMT accessor. This gives access to the TREE_LIST of
statements assocated with a compound statement. The result is the
first statement in the list. Succeeding nodes can be acccessed by
calling TREE_CHAIN on a node in the list. */
#define COMPOUND_BODY(NODE) TREE_OPERAND (COMPOUND_STMT_CHECK (NODE), 0)
/* ASM_STMT accessors. ASM_STRING returns a STRING_CST for the
instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and
ASM_CLOBBERS represent the outputs, inputs, and clobbers for the
statement. */
#define ASM_CV_QUAL(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 0)
#define ASM_STRING(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 1)
#define ASM_OUTPUTS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 2)
#define ASM_INPUTS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 3)
#define ASM_CLOBBERS(NODE) TREE_OPERAND (ASM_STMT_CHECK (NODE), 4)
/* DECL_STMT accessor. This gives access to the DECL associated with
the given declaration statement. */
#define DECL_STMT_DECL(NODE) TREE_OPERAND (DECL_STMT_CHECK (NODE), 0)
/* STMT_EXPR accessor. */
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
/* LABEL_STMT accessor. This gives access to the label associated with
the given label statement. */
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND (LABEL_STMT_CHECK (NODE), 0)
/* Nonzero if this SCOPE_STMT is for the beginning of a scope. */
......
2000-06-19 Benjamin Chelf <chelf@cabriolet.stanford.edu>
* cp-tree.h (genrtl_try_block): Declare function.
(genrtl_handler): Likewise.
(genrtl_catch_block): Likewise.
(genrtl_ctor_stmt): Likewise.
(genrtl_subobject): Likewise.
(genrtl_decl_cleanup): Likewise.
(genrtl_do_poplevel): Likewise.
(genrtl_do_pushlevel): Likewise.
(genrtl_clear_out_block): Likewise.
(genrtl_goto_stmt): Likewise.
(genrtl_expr_stmt): Likewise.
(genrtl_decl_stmt): Likewise.
(genrtl_if_stmt): Likewise.
(genrtl_while_stmt): Likewise.
(genrtl_do_stmt): Likewise.
(genrtl_return_stmt): Likewise.
(genrtl_for_stmt): Likewise.
(genrtl_break_stmt): Likewise.
(genrtl_continue_stmt): Likewise.
(genrtl_scope_stmt): Likewise.
(genrtl_switch_stmt): Likewise.
(genrtl_case_label): Likewise.
(genrtl_begin_compound_stmt): Likewise.
(genrtl_finish_compound_stmt): Likewise.
(genrtl_compound_stmt): Likewise.
(genrtl_asm_stmt): Likewise.
(genrtl_named_return_value): Likewise.
(genrtl_begin_stmt_expr): Likewise.
(genrtl_finish_stmt_expr): Likewise.
(finish_for_stmt): Removed first argument.
(finish_switch_stmt): Likewise.
* semantics.c (genrtl_try_block): Define function.
(genrtl_handler): Likewise.
(genrtl_catch_block): Likewise.
(genrtl_ctor_stmt): Likewise.
(genrtl_subobject): Likewise.
(genrtl_decl_cleanup): Likewise.
(genrtl_do_poplevel): Likewise.
(genrtl_do_pushlevel): Likewise.
(genrtl_clear_out_block): Likewise.
(genrtl_goto_stmt): Likewise.
(genrtl_expr_stmt): Likewise.
(genrtl_decl_stmt): Likewise.
(genrtl_if_stmt): Likewise.
(genrtl_while_stmt): Likewise.
(genrtl_do_stmt): Likewise.
(genrtl_return_stmt): Likewise.
(genrtl_for_stmt): Likewise.
(genrtl_break_stmt): Likewise.
(genrtl_continue_stmt): Likewise.
(genrtl_scope_stmt): Likewise.
(genrtl_switch_stmt): Likewise.
(genrtl_case_label): Likewise.
(genrtl_begin_compound_stmt): Likewise.
(genrtl_finish_compound_stmt): Likewise.
(genrtl_compound_stmt): Likewise.
(genrtl_asm_stmt): Likewise.
(genrtl_named_return_value): Likewise.
(genrtl_begin_stmt_expr): Likewise.
(genrtl_finish_stmt_expr): Likewise.
(finish_for_stmt): Removed first argument and generate rtl
specific code.
(finish_switch_stmt): Likewise.
(do_poplevel): Removed generate rtl specific code.
(do_pushlevel): Likewise.
(add_tree): Likewise.
(finish_goto_stmt): Likewise.
(finish_expr_stmt): Likewise.
(begin_if_stmt): Likewise.
(finish_if_stmt_cond): Likewise.
(finish_then_clause): Likewise.
(begin_else_clause): Likewise.
(finish_else_clause): Likewise.
(finish_if_stmt): Likewise.
(clear_out_block): Likewise.
(begin_while_stmt): Likewise.
(finish_while_stmt_cond): Likewise.
(finish_while_stmt): Likewise.
(begin_do_stmt): Likewise.
(finish_do_body): Likewise.
(finish_do_stmt): Likewise.
(finish_return_stmt): Likewise.
(begin_for_stmt): Likewise.
(finish_for_init_stmt): Likewise.
(finish_for_cond): Likewise.
(finish_for_expr): Likewise.
(finish_break_stmt): Likewise.
(finish_continue_stmt): Likewise.
(begin_switch_stmt): Likewise.
(finish_switch_cond): Likewise.
(finish_case_label): Likewise.
(begin_try_block): Likewise.
(begin_function_try_block): Likewise.
(finish_try_block): Likewise.
(finish_cleanup_try_block): Likewise.
(finish_cleanup): Likewise.
(finish_function_try_block): Likewise.
(finish_handler_sequence): Likewise.
(finish_function_handler_sequence): Likewise.
(begin_handler): Likewise.
(finish_handler_parms): Likewise.
(begin_catch_block): Likewise.
(finish_handler): Likewise.
(begin_compound_stmt): Likewise.
(finish_compound_stmt): Likewise.
(finish_asm_stmt): Likewise.
(finish_label_stmt): Likewise.
(finish_label_decl): Likewise.
(finish_subobject): Likewise.
(finish_decl_cleanup): Likewise.
(finish_named_return_value): Likewise.
(begin_stmt_expr): Likewise.
(finish_stmt_expr): Likewise.
* decl.c (initialize_local_var): Changed call to finish_expr_stmt
to call genrtl_expr_stmt when appropriate.
* init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
begin_compound_expr to call genrtl_begin_stmt_expr and
genrtl_begin_compound_expr when appropriate.
(finish_init_stmts): Changed calls to finish_compound_expr and
finish_stmt_expr to call genrtl_finish_compound_expr and
genrtl_finish_stmt_expr when appropriate.
(expand_default_init): Changed call to finish_expr_stmt to call
genrtl_expr_stmt when appropriate.
(build_vec_init): Likewise.
* parse.y (simple_stmt): Removed first argument from call to
finish_for_stmt. Removed first argument from call to
finish_switch_stmt.
* parse.c: Regenerated.
* pt.c (tsubst_expr): Removed first argument from call to
finish_for_stmt. Removed first argument from call to
finish_switch_stmt.
2000-06-16 Benjamin Chelf <chelf@codesourcery.com>
* cp-tree.h (enum cplus_tree_code): Changed __DUMMY to
......
......@@ -4406,12 +4406,12 @@ extern tree begin_for_stmt PARAMS ((void));
extern void finish_for_init_stmt PARAMS ((tree));
extern void finish_for_cond PARAMS ((tree, tree));
extern void finish_for_expr PARAMS ((tree, tree));
extern void finish_for_stmt PARAMS ((tree, tree));
extern void finish_for_stmt PARAMS ((tree));
extern void finish_break_stmt PARAMS ((void));
extern void finish_continue_stmt PARAMS ((void));
extern tree begin_switch_stmt PARAMS ((void));
extern void finish_switch_cond PARAMS ((tree, tree));
extern void finish_switch_stmt PARAMS ((tree, tree));
extern void finish_switch_stmt PARAMS ((tree));
extern void finish_case_label PARAMS ((tree, tree));
extern void finish_goto_stmt PARAMS ((tree));
extern tree begin_try_block PARAMS ((void));
......@@ -4480,6 +4480,40 @@ extern void do_pushlevel PARAMS ((void));
extern tree do_poplevel PARAMS ((void));
extern void finish_mem_initializers PARAMS ((tree));
extern void genrtl_try_block PARAMS ((tree));
extern void genrtl_handler PARAMS ((tree));
extern void genrtl_catch_block PARAMS ((tree));
extern void genrtl_ctor_stmt PARAMS ((tree));
extern void genrtl_subobject PARAMS ((tree));
extern void genrtl_decl_cleanup PARAMS ((tree, tree));
extern tree genrtl_do_poplevel 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));
extern void genrtl_if_stmt PARAMS ((tree));
extern void genrtl_while_stmt PARAMS ((tree));
extern void genrtl_do_stmt PARAMS ((tree));
extern void genrtl_return_stmt PARAMS ((tree));
extern void genrtl_for_stmt PARAMS ((tree));
extern void genrtl_break_stmt PARAMS ((void));
extern void genrtl_continue_stmt PARAMS ((void));
extern void genrtl_scope_stmt PARAMS ((tree));
extern void genrtl_switch_stmt PARAMS ((tree));
extern void genrtl_case_label PARAMS ((tree, tree));
extern tree genrtl_begin_compound_stmt PARAMS ((int));
extern tree genrtl_finish_compound_stmt PARAMS ((int));
extern tree genrtl_compound_stmt PARAMS ((tree));
extern void genrtl_asm_stmt PARAMS ((tree, tree,
tree, tree,
tree));
extern void genrtl_named_return_value PARAMS ((tree,
tree));
extern tree genrtl_begin_stmt_expr PARAMS ((void));
extern tree genrtl_finish_stmt_expr PARAMS ((tree));
/* in spew.c */
extern void init_spew PARAMS ((void));
extern int peekyylex PARAMS ((void));
......
......@@ -7980,7 +7980,10 @@ initialize_local_var (decl, init, flags)
DECL_SOURCE_LINE (decl));
saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p;
stmts_are_full_exprs_p = 1;
if (building_stmt_tree ())
finish_expr_stmt (build_aggr_init (decl, init, flags));
else
genrtl_expr_stmt (build_aggr_init (decl, init, flags));
stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
}
......
......@@ -97,8 +97,15 @@ begin_init_stmts (stmt_expr_p, compound_stmt_p)
tree *stmt_expr_p;
tree *compound_stmt_p;
{
if (building_stmt_tree ())
*stmt_expr_p = begin_stmt_expr ();
else
*stmt_expr_p = genrtl_begin_stmt_expr ();
if (building_stmt_tree ())
*compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/1);
else
*compound_stmt_p = genrtl_begin_compound_stmt (/*has_no_scope=*/1);
}
/* Finish out the statement-expression begun by the previous call to
......@@ -108,9 +115,17 @@ tree
finish_init_stmts (stmt_expr, compound_stmt)
tree stmt_expr;
tree compound_stmt;
{
if (building_stmt_tree ())
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
else
genrtl_finish_compound_stmt (/*has_no_scope=*/1);
if (building_stmt_tree ())
stmt_expr = finish_stmt_expr (stmt_expr);
else
stmt_expr = genrtl_finish_stmt_expr (stmt_expr);
/* To avoid spurious warnings about unused values, we set
TREE_USED. */
......@@ -1297,7 +1312,12 @@ expand_default_init (binfo, true_exp, exp, init, flags)
rval = build_method_call (exp, ctor_name, parms, binfo, flags);
if (TREE_SIDE_EFFECTS (rval))
{
if (building_stmt_tree ())
finish_expr_stmt (rval);
else
genrtl_expr_stmt (rval);
}
}
/* This function is responsible for initializing EXP with INIT
......@@ -2988,7 +3008,7 @@ build_vec_init (decl, base, maxindex, init, from_array)
full-expression. */
if (!building_stmt_tree ())
{
finish_expr_stmt (elt_init);
genrtl_expr_stmt (elt_init);
expand_end_target_temps ();
}
else
......
......@@ -7698,7 +7698,7 @@ case 734:
break;}
case 735:
#line 3297 "parse.y"
{ finish_for_stmt (yyvsp[-3].ttype, yyvsp[-10].ttype); ;
{ finish_for_stmt (yyvsp[-10].ttype); ;
break;}
case 736:
#line 3299 "parse.y"
......@@ -7710,7 +7710,7 @@ case 737:
break;}
case 738:
#line 3303 "parse.y"
{ finish_switch_stmt (yyvsp[-3].ttype, yyvsp[-5].ttype); ;
{ finish_switch_stmt (yyvsp[-5].ttype); ;
break;}
case 739:
#line 3305 "parse.y"
......
......@@ -3294,13 +3294,13 @@ simple_stmt:
xexpr ')'
{ finish_for_expr ($9, $<ttype>2); }
already_scoped_stmt
{ finish_for_stmt ($9, $<ttype>2); }
{ finish_for_stmt ($<ttype>2); }
| SWITCH
{ $<ttype>$ = begin_switch_stmt (); }
'(' condition ')'
{ finish_switch_cond ($4, $<ttype>2); }
implicitly_scoped_stmt
{ finish_switch_stmt ($4, $<ttype>2); }
{ finish_switch_stmt ($<ttype>2); }
| CASE expr_no_commas ':'
{ finish_case_label ($2, NULL_TREE); }
stmt
......
......@@ -7215,7 +7215,7 @@ tsubst_expr (t, args, complain, in_decl)
tmp = tsubst_expr (FOR_EXPR (t), args, complain, in_decl);
finish_for_expr (tmp, stmt);
tsubst_expr (FOR_BODY (t), args, complain, in_decl);
finish_for_stmt (tmp, stmt);
finish_for_stmt (stmt);
}
break;
......@@ -7303,7 +7303,7 @@ tsubst_expr (t, args, complain, in_decl)
val = tsubst_expr (SWITCH_COND (t), args, complain, in_decl);
finish_switch_cond (val, stmt);
tsubst_expr (SWITCH_BODY (t), args, complain, in_decl);
finish_switch_stmt (val, stmt);
finish_switch_stmt (stmt);
}
break;
......
......@@ -87,6 +87,98 @@ static void deferred_type_access_control PARAMS ((void));
substmt = cond; \
} while (0)
/* Finish a scope. */
tree
do_poplevel ()
{
tree block = NULL_TREE;
if (stmts_are_full_exprs_p)
{
tree scope_stmts;
if (!processing_template_decl)
scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
block = poplevel (kept_level_p (), 1, 0);
if (block && !processing_template_decl)
{
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
}
}
return block;
}
/* Begin a new scope. */
void
do_pushlevel ()
{
if (stmts_are_full_exprs_p)
{
pushlevel (0);
if (!processing_template_decl)
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
}
}
/* Helper for generating the RTL at the end of a scope. */
tree
genrtl_do_poplevel ()
{
tree block = NULL_TREE;
if (stmts_are_full_exprs_p)
{
tree scope_stmts;
scope_stmts = NULL_TREE;
block = poplevel (kept_level_p (), 1, 0);
if (block && !processing_template_decl)
{
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
}
}
return block;
}
/* Helper for generating the RTL at the beginning of a scope. */
void
genrtl_do_pushlevel ()
{
emit_line_note (input_filename, lineno);
clear_last_expr ();
if (stmts_are_full_exprs_p)
{
pushlevel (0); // Try to get rid of me.
if (!cfun->x_whole_function_mode_p)
my_friendly_abort (19991129);
}
}
/* Helper for generating the RTL. */
void
genrtl_clear_out_block ()
{
/* If COND wasn't a declaration, clear out the
block we made for it and start a new one here so the
optimization in expand_end_loop will work. */
if (getdecls () == NULL_TREE)
{
genrtl_do_poplevel ();
genrtl_do_pushlevel ();
}
}
/* T is a statement. Add it to the statement-tree. */
void
......@@ -96,13 +188,62 @@ add_tree (t)
/* Add T to the statement-tree. */
TREE_CHAIN (last_tree) = t;
SET_LAST_STMT (t);
/* When we expand a statement-tree, we must know whether or not the
statements are full-expresions. We record that fact here. */
if (building_stmt_tree ())
STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p;
}
/* Finish a goto-statement. */
void
finish_goto_stmt (destination)
tree destination;
{
if (TREE_CODE (destination) == IDENTIFIER_NODE)
destination = lookup_label (destination);
/* We warn about unused labels with -Wunused. That means we have to
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
if (TREE_CODE (destination) != LABEL_DECL)
/* We don't inline calls to functions with computed gotos.
Those functions are typically up to some funny business,
and may be depending on the labels being at particular
addresses, or some such. */
DECL_UNINLINABLE (current_function_decl) = 1;
check_goto (destination);
add_tree (build_min_nt (GOTO_STMT, destination));
}
/* Generate the RTL for DESTINATION, which is a GOTO_STMT. */
void
genrtl_goto_stmt (destination)
tree destination;
{
if (TREE_CODE (destination) == IDENTIFIER_NODE)
destination = lookup_label (destination);
/* We warn about unused labels with -Wunused. That means we have to
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
emit_line_note (input_filename, lineno);
if (TREE_CODE (destination) == LABEL_DECL)
{
label_rtx (destination);
expand_goto (destination);
}
else
expand_computed_goto (destination);
}
/* COND is the condition-expression for an if, while, etc.,
statement. Convert it to a boolean value, if appropriate. */
......@@ -131,10 +272,6 @@ finish_expr_stmt (expr)
{
if (expr != NULL_TREE)
{
if (building_stmt_tree ())
{
/* Do default conversion if safe and possibly important,
in case within ({...}). */
if (!processing_template_decl
&& !stmts_are_full_exprs_p
&& ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
......@@ -150,7 +287,21 @@ finish_expr_stmt (expr)
add_tree (build_min_nt (EXPR_STMT, expr));
}
else
finish_stmt ();
/* This was an expression-statement, so we save the type of the
expression. */
last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE;
}
/* Generate the RTL for EXPR, which is an EXPR_STMT. */
void
genrtl_expr_stmt (expr)
tree expr;
{
if (expr != NULL_TREE)
{
emit_line_note (input_filename, lineno);
......@@ -162,7 +313,6 @@ finish_expr_stmt (expr)
if (stmts_are_full_exprs_p)
expand_end_target_temps ();
}
}
finish_stmt ();
......@@ -171,6 +321,67 @@ finish_expr_stmt (expr)
last_expr_type = expr ? TREE_TYPE (expr) : NULL_TREE;
}
/* Generate the RTL for T, which is a DECL_STMT. */
void
genrtl_decl_stmt (t)
tree t;
{
tree decl;
emit_line_note (input_filename, lineno);
decl = DECL_STMT_DECL (t);
/* If this is a declaration for an automatic local
variable, initialize it. Note that we might also see a
declaration for a namespace-scope object (declared with
`extern'). We don't have to handle the initialization
of those objects here; they can only be declarations,
rather than definitions. */
if (TREE_CODE (decl) == VAR_DECL
&& !TREE_STATIC (decl)
&& !DECL_EXTERNAL (decl))
{
/* Let the back-end know about this variable. */
if (!ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
emit_local_var (decl);
else
expand_anon_union_decl (decl, NULL_TREE,
DECL_ANON_UNION_ELEMS (decl));
}
else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
{
if (DECL_ARTIFICIAL (decl) && ! TREE_USED (decl))
/* Do not emit unused decls. This is not just an
optimization. We really do not want to emit
__PRETTY_FUNCTION__ etc, if they're never used. */
DECL_IGNORED_P (decl) = 1;
else
make_rtl_for_local_static (decl);
}
}
/* Generate the RTL for T, which is an IF_STMT. */
void
genrtl_if_stmt (t)
tree t;
{
tree cond;
genrtl_do_pushlevel ();
cond = maybe_convert_cond (expand_cond (IF_COND (t)));
emit_line_note (input_filename, lineno);
expand_start_cond (cond, 0);
if (THEN_CLAUSE (t))
expand_stmt (THEN_CLAUSE (t));
if (ELSE_CLAUSE (t))
{
expand_start_else ();
expand_stmt (ELSE_CLAUSE (t));
}
expand_end_cond ();
genrtl_do_poplevel ();
finish_stmt ();
}
/* Begin an if-statement. Returns a newly created IF_STMT if
appropriate. */
......@@ -178,17 +389,9 @@ tree
begin_if_stmt ()
{
tree r;
do_pushlevel ();
if (building_stmt_tree ())
{
r = build_min_nt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
add_tree (r);
}
else
r = NULL_TREE;
return r;
}
......@@ -201,14 +404,7 @@ finish_if_stmt_cond (cond, if_stmt)
tree if_stmt;
{
cond = maybe_convert_cond (cond);
if (building_stmt_tree ())
FINISH_COND (cond, if_stmt, IF_COND (if_stmt));
else
{
emit_line_note (input_filename, lineno);
expand_start_cond (cond, 0);
}
}
/* Finish the then-clause of an if-statement, which may be given by
......@@ -218,14 +414,9 @@ tree
finish_then_clause (if_stmt)
tree if_stmt;
{
if (building_stmt_tree ())
{
RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
SET_LAST_STMT (if_stmt);
return if_stmt;
}
else
return NULL_TREE;
}
/* Begin the else-clause of an if-statement. */
......@@ -233,8 +424,6 @@ finish_then_clause (if_stmt)
void
begin_else_clause ()
{
if (!building_stmt_tree ())
expand_start_else ();
}
/* Finish the else-clause of an if-statement, which may be given by
......@@ -244,7 +433,6 @@ void
finish_else_clause (if_stmt)
tree if_stmt;
{
if (building_stmt_tree ())
RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
}
......@@ -253,10 +441,44 @@ finish_else_clause (if_stmt)
void
finish_if_stmt ()
{
if (!building_stmt_tree ())
expand_end_cond ();
do_poplevel ();
finish_stmt ();
}
void
clear_out_block ()
{
/* If COND wasn't a declaration, clear out the
block we made for it and start a new one here so the
optimization in expand_end_loop will work. */
if (getdecls () == NULL_TREE)
{
do_poplevel ();
do_pushlevel ();
}
}
/* Generate the RTL for T, which is a WHILE_STMT. */
void
genrtl_while_stmt (t)
tree t;
{
tree cond;
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop (1);
genrtl_do_pushlevel ();
cond = maybe_convert_cond (expand_cond (WHILE_COND (t)));
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, cond);
genrtl_clear_out_block ();
expand_stmt (WHILE_BODY (t));
genrtl_do_poplevel ();
expand_end_loop ();
finish_stmt ();
}
......@@ -267,22 +489,9 @@ tree
begin_while_stmt ()
{
tree r;
if (building_stmt_tree ())
{
r = build_min_nt (WHILE_STMT, NULL_TREE, NULL_TREE);
add_tree (r);
}
else
{
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop (1);
r = NULL_TREE;
}
do_pushlevel ();
return r;
}
......@@ -295,23 +504,8 @@ finish_while_stmt_cond (cond, while_stmt)
tree while_stmt;
{
cond = maybe_convert_cond (cond);
if (building_stmt_tree ())
FINISH_COND (cond, while_stmt, WHILE_COND (while_stmt));
else
{
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, cond);
}
/* If COND wasn't a declaration, clear out the
block we made for it and start a new one here so the
optimization in expand_end_loop will work. */
if (getdecls () == NULL_TREE)
{
do_poplevel ();
do_pushlevel ();
}
clear_out_block ();
}
/* Finish a while-statement, which may be given by WHILE_STMT. */
......@@ -321,10 +515,28 @@ finish_while_stmt (while_stmt)
tree while_stmt;
{
do_poplevel ();
if (building_stmt_tree ())
RECHAIN_STMTS (while_stmt, WHILE_BODY (while_stmt));
else
finish_stmt ();
}
/* Generate the RTL for T, which is a DO_STMT. */
void
genrtl_do_stmt (t)
tree t;
{
tree cond;
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
expand_stmt (DO_BODY (t));
expand_loop_continue_here ();
cond = maybe_convert_cond (DO_COND (t));
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, cond);
expand_end_loop ();
finish_stmt ();
}
......@@ -335,19 +547,9 @@ finish_while_stmt (while_stmt)
tree
begin_do_stmt ()
{
if (building_stmt_tree ())
{
tree r = build_min_nt (DO_STMT, NULL_TREE, NULL_TREE);
add_tree (r);
return r;
}
else
{
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
return NULL_TREE;
}
}
/* Finish the body of a do-statement, which may be given by DO_STMT. */
......@@ -356,10 +558,7 @@ void
finish_do_body (do_stmt)
tree do_stmt;
{
if (building_stmt_tree ())
RECHAIN_STMTS (do_stmt, DO_BODY (do_stmt));
else
expand_loop_continue_here ();
}
/* Finish a do-statement, which may be given by DO_STMT, and whose
......@@ -371,16 +570,18 @@ finish_do_stmt (cond, do_stmt)
tree do_stmt;
{
cond = maybe_convert_cond (cond);
if (building_stmt_tree ())
DO_COND (do_stmt) = cond;
else
{
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, cond);
expand_end_loop ();
}
finish_stmt ();
}
/* Generate the RTL for EXPR, which is a RETURN_STMT. */
void
genrtl_return_stmt (expr)
tree expr;
{
emit_line_note (input_filename, lineno);
c_expand_return (expr);
finish_stmt ();
}
......@@ -391,10 +592,9 @@ void
finish_return_stmt (expr)
tree expr;
{
if (doing_semantic_analysis_p () && !processing_template_decl)
if (!processing_template_decl)
expr = check_return_expr (expr);
if (doing_semantic_analysis_p () && !processing_template_decl)
if (!processing_template_decl)
{
if (DECL_CONSTRUCTOR_P (current_function_decl) && ctor_label)
{
......@@ -417,15 +617,48 @@ finish_return_stmt (expr)
return;
}
}
if (building_stmt_tree ())
add_tree (build_min_nt (RETURN_STMT, expr));
else
finish_stmt ();
}
/* Generate the RTL for T, which is a FOR_STMT. */
void
genrtl_for_stmt (t)
tree t;
{
tree tmp;
tree cond;
if (flag_new_for_scope > 0)
{
emit_line_note (input_filename, lineno);
c_expand_return (expr);
genrtl_do_pushlevel ();
note_level_for_for ();
}
expand_stmt (FOR_INIT_STMT (t));
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
genrtl_do_pushlevel ();
cond = maybe_convert_cond (expand_cond (FOR_COND (t)));
emit_line_note (input_filename, lineno);
if (cond)
expand_exit_loop_if_false (0, cond);
genrtl_clear_out_block ();
tmp = FOR_EXPR (t);
expand_stmt (FOR_BODY (t));
/* Pop the scope for the body of the loop. */
genrtl_do_poplevel ();
emit_line_note (input_filename, lineno);
expand_loop_continue_here ();
if (tmp)
genrtl_expr_stmt (tmp);
expand_end_loop ();
if (flag_new_for_scope > 0)
genrtl_do_poplevel ();
finish_stmt ();
}
......@@ -436,14 +669,9 @@ begin_for_stmt ()
{
tree r;
if (building_stmt_tree ())
{
r = build_min_nt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
add_tree (r);
}
else
r = NULL_TREE;
if (flag_new_for_scope > 0)
{
......@@ -461,18 +689,8 @@ void
finish_for_init_stmt (for_stmt)
tree for_stmt;
{
if (building_stmt_tree ())
{
if (last_tree != for_stmt)
RECHAIN_STMTS (for_stmt, FOR_INIT_STMT (for_stmt));
}
else
{
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
}
do_pushlevel ();
}
......@@ -485,24 +703,8 @@ finish_for_cond (cond, for_stmt)
tree for_stmt;
{
cond = maybe_convert_cond (cond);
if (building_stmt_tree ())
FINISH_COND (cond, for_stmt, FOR_COND (for_stmt));
else
{
emit_line_note (input_filename, lineno);
if (cond)
expand_exit_loop_if_false (0, cond);
}
/* If the cond wasn't a declaration, clear out the
block we made for it and start a new one here so the
optimization in expand_end_loop will work. */
if (getdecls () == NULL_TREE)
{
do_poplevel ();
do_pushlevel ();
}
clear_out_block ();
}
/* Finish the increment-EXPRESSION in a for-statement, which may be
......@@ -513,7 +715,6 @@ finish_for_expr (expr, for_stmt)
tree expr;
tree for_stmt;
{
if (building_stmt_tree ())
FOR_EXPR (for_stmt) = expr;
}
......@@ -522,40 +723,44 @@ finish_for_expr (expr, for_stmt)
provided. */
void
finish_for_stmt (expr, for_stmt)
tree expr;
finish_for_stmt (for_stmt)
tree for_stmt;
{
/* Pop the scope for the body of the loop. */
do_poplevel ();
if (building_stmt_tree ())
RECHAIN_STMTS (for_stmt, FOR_BODY (for_stmt));
else
{
emit_line_note (input_filename, lineno);
expand_loop_continue_here ();
if (expr)
finish_expr_stmt (expr);
expand_end_loop ();
}
if (flag_new_for_scope > 0)
do_poplevel ();
finish_stmt ();
}
/* Generate the RTL for a BREAK_STMT. */
void
genrtl_break_stmt ()
{
emit_line_note (input_filename, lineno);
if ( ! expand_exit_something ())
cp_error ("break statement not within loop or switch");
}
/* Finish a break-statement. */
void
finish_break_stmt ()
{
emit_line_note (input_filename, lineno);
if (building_stmt_tree ())
add_tree (build_min_nt (BREAK_STMT));
else if ( ! expand_exit_something ())
cp_error ("break statement not within loop or switch");
}
/* Generate the RTL for a CONTINUE_STMT. */
void
genrtl_continue_stmt ()
{
emit_line_note (input_filename, lineno);
if (! expand_continue_loop (0))
cp_error ("continue statement not within a loop");
}
/* Finish a continue-statement. */
......@@ -564,10 +769,61 @@ void
finish_continue_stmt ()
{
emit_line_note (input_filename, lineno);
if (building_stmt_tree ())
add_tree (build_min_nt (CONTINUE_STMT));
else if (! expand_continue_loop (0))
cp_error ("continue statement not within a loop");
}
/* Generate the RTL for T, which is a SCOPE_STMT. */
void
genrtl_scope_stmt (t)
tree t;
{
if (!SCOPE_NO_CLEANUPS_P (t))
{
if (SCOPE_BEGIN_P (t))
expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t),
SCOPE_STMT_BLOCK (t));
else if (SCOPE_END_P (t))
expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
}
else if (!SCOPE_NULLIFIED_P (t))
{
rtx note = emit_note (NULL,
(SCOPE_BEGIN_P (t)
? NOTE_INSN_BLOCK_BEG
: NOTE_INSN_BLOCK_END));
NOTE_BLOCK (note) = SCOPE_STMT_BLOCK (t);
}
}
/* Generate the RTL for T, which is a SWITCH_STMT. */
void
genrtl_switch_stmt (t)
tree t;
{
tree cond;
genrtl_do_pushlevel ();
cond = expand_cond (SWITCH_COND (t));
if (cond != error_mark_node)
{
emit_line_note (input_filename, lineno);
c_expand_start_case (cond);
}
else
/* The code is in error, but we don't want expand_end_case to
crash. */
c_expand_start_case (boolean_false_node);
push_switch ();
expand_stmt (SWITCH_BODY (t));
expand_end_case (cond);
pop_switch ();
genrtl_do_poplevel ();
finish_stmt ();
}
/* Begin a switch-statement. Returns a new SWITCH_STMT if
......@@ -577,17 +833,9 @@ tree
begin_switch_stmt ()
{
tree r;
if (building_stmt_tree ())
{
r = build_min_nt (SWITCH_STMT, NULL_TREE, NULL_TREE);
add_tree (r);
}
else
r = NULL_TREE;
do_pushlevel ();
return r;
}
......@@ -598,8 +846,6 @@ finish_switch_cond (cond, switch_stmt)
tree cond;
tree switch_stmt;
{
if (building_stmt_tree ())
{
if (!processing_template_decl)
{
/* Convert the condition to an integer or enumeration type. */
......@@ -629,17 +875,6 @@ finish_switch_cond (cond, switch_stmt)
}
}
FINISH_COND (cond, switch_stmt, SWITCH_COND (switch_stmt));
}
else if (cond != error_mark_node)
{
emit_line_note (input_filename, lineno);
c_expand_start_case (cond);
}
else
/* The code is in error, but we don't want expand_end_case to
crash. */
c_expand_start_case (boolean_false_node);
push_switch ();
}
......@@ -647,19 +882,25 @@ finish_switch_cond (cond, switch_stmt)
SWITCH_STMT. The COND to switch on is indicated. */
void
finish_switch_stmt (cond, switch_stmt)
tree cond;
finish_switch_stmt (switch_stmt)
tree switch_stmt;
{
if (building_stmt_tree ())
RECHAIN_STMTS (switch_stmt, SWITCH_BODY (switch_stmt));
else
expand_end_case (cond);
pop_switch ();
do_poplevel ();
finish_stmt ();
}
/* Generate the RTL for a CASE_LABEL. */
void
genrtl_case_label (low_value, high_value)
tree low_value;
tree high_value;
{
do_case (low_value, high_value);
}
/* Finish a case-label. */
void
......@@ -667,58 +908,54 @@ finish_case_label (low_value, high_value)
tree low_value;
tree high_value;
{
if (building_stmt_tree ())
{
/* Add a representation for the case label to the statement
tree. */
add_tree (build_min_nt (CASE_LABEL, low_value, high_value));
/* And warn about crossing initializations, etc. */
if (!processing_template_decl)
define_case_label ();
return;
}
do_case (low_value, high_value);
}
/* Finish a goto-statement. */
void
finish_goto_stmt (destination)
tree destination;
{
if (TREE_CODE (destination) == IDENTIFIER_NODE)
destination = lookup_label (destination);
}
/* We warn about unused labels with -Wunused. That means we have to
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
/* Generate the RTL for T, which is a TRY_BLOCK. */
if (building_stmt_tree ())
void genrtl_try_block (t)
tree t;
{
if (CLEANUP_P (t))
{
if (TREE_CODE (destination) != LABEL_DECL)
/* We don't inline calls to functions with computed gotos.
Those functions are typically up to some funny business,
and may be depending on the labels being at particular
addresses, or some such. */
DECL_UNINLINABLE (current_function_decl) = 1;
check_goto (destination);
add_tree (build_min_nt (GOTO_STMT, destination));
expand_eh_region_start ();
expand_stmt (TRY_STMTS (t));
expand_eh_region_end (protect_with_terminate (TRY_HANDLERS (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 (TREE_CODE (destination) == LABEL_DECL)
expand_stmt (TRY_STMTS (t));
if (FN_TRY_BLOCK_P (t))
{
label_rtx (destination);
expand_goto (destination);
end_protect_partials ();
expand_start_all_catch ();
in_function_try_handler = 1;
expand_stmt (TRY_HANDLERS (t));
in_function_try_handler = 0;
expand_end_all_catch ();
}
else
expand_computed_goto (destination);
{
expand_start_all_catch ();
expand_stmt (TRY_HANDLERS (t));
expand_end_all_catch ();
}
}
}
......@@ -728,19 +965,9 @@ finish_goto_stmt (destination)
tree
begin_try_block ()
{
if (building_stmt_tree ())
{
tree r = build_min_nt (TRY_BLOCK, NULL_TREE,
NULL_TREE);
tree r = build_min_nt (TRY_BLOCK, NULL_TREE, NULL_TREE);
add_tree (r);
return r;
}
else
{
emit_line_note (input_filename, lineno);
expand_start_try_stmts ();
return NULL_TREE;
}
}
/* Likewise, for a function-try-block. */
......@@ -748,21 +975,10 @@ begin_try_block ()
tree
begin_function_try_block ()
{
if (building_stmt_tree ())
{
tree r = build_min_nt (TRY_BLOCK, NULL_TREE,
NULL_TREE);
tree r = build_min_nt (TRY_BLOCK, NULL_TREE, NULL_TREE);
FN_TRY_BLOCK_P (r) = 1;
add_tree (r);
return r;
}
else
{
if (! current_function_parms_stored)
store_parm_decls ();
expand_start_early_try_stmts ();
return NULL_TREE;
}
}
/* Finish a try-block, which may be given by TRY_BLOCK. */
......@@ -771,10 +987,7 @@ void
finish_try_block (try_block)
tree try_block;
{
if (building_stmt_tree ())
RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
else
expand_start_all_catch ();
}
/* Finish the body of a cleanup try-block, which may be given by
......@@ -784,7 +997,6 @@ void
finish_cleanup_try_block (try_block)
tree try_block;
{
if (building_stmt_tree ())
RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}
......@@ -796,13 +1008,8 @@ finish_cleanup (cleanup, try_block)
tree cleanup;
tree try_block;
{
if (building_stmt_tree ())
{
TRY_HANDLERS (try_block) = cleanup;
CLEANUP_P (try_block) = 1;
}
else
expand_eh_region_end (protect_with_terminate (cleanup));
}
/* Likewise, for a function-try-block. */
......@@ -811,8 +1018,6 @@ void
finish_function_try_block (try_block)
tree try_block;
{
if (building_stmt_tree ())
{
if (TREE_CHAIN (try_block)
&& TREE_CODE (TREE_CHAIN (try_block)) == CTOR_INITIALIZER)
{
......@@ -823,13 +1028,6 @@ finish_function_try_block (try_block)
}
else
RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}
else
{
end_protect_partials ();
expand_start_all_catch ();
}
in_function_try_handler = 1;
}
......@@ -840,13 +1038,8 @@ void
finish_handler_sequence (try_block)
tree try_block;
{
if (building_stmt_tree ())
{
RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
check_handlers (TRY_HANDLERS (try_block));
}
else
expand_end_all_catch ();
}
/* Likewise, for a function-try-block. */
......@@ -856,14 +1049,28 @@ finish_function_handler_sequence (try_block)
tree try_block;
{
in_function_try_handler = 0;
if (building_stmt_tree ())
{
RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
check_handlers (TRY_HANDLERS (try_block));
}
/* Generate the RTL for T, which is a HANDLER. */
void
genrtl_handler (t)
tree t;
{
genrtl_do_pushlevel ();
expand_stmt (HANDLER_BODY (t));
if (!processing_template_decl)
{
/* 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 ();
}
else
expand_end_all_catch ();
genrtl_do_poplevel ();
}
/* Begin a handler. Returns a HANDLER if appropriate. */
......@@ -872,17 +1079,9 @@ tree
begin_handler ()
{
tree r;
if (building_stmt_tree ())
{
r = build_min_nt (HANDLER, NULL_TREE, NULL_TREE);
add_tree (r);
}
else
r = NULL_TREE;
do_pushlevel ();
return r;
}
......@@ -907,7 +1106,7 @@ finish_handler_parms (decl, handler)
RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
}
}
else if (building_stmt_tree ())
else
blocks = expand_start_catch_block (decl);
if (decl)
......@@ -916,6 +1115,15 @@ finish_handler_parms (decl, handler)
return blocks;
}
/* Generate the RTL for a CATCH_BLOCK. */
void
genrtl_catch_block (type)
tree type;
{
start_catch_handler (type);
}
/* Note the beginning of a handler for TYPE. This function is called
at the point to which control should be transferred when an
appropriately-typed exception is thrown. */
......@@ -924,10 +1132,7 @@ void
begin_catch_block (type)
tree type;
{
if (building_stmt_tree ())
add_tree (build (START_CATCH_STMT, type));
else
start_catch_handler (type);
}
/* Finish a handler, which may be given by HANDLER. The BLOCKs are
......@@ -939,24 +1144,97 @@ finish_handler (blocks, handler)
tree handler;
{
if (!processing_template_decl)
{
if (building_stmt_tree ())
expand_end_catch_block (blocks);
do_poplevel ();
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}
/* Generate the RTL for T, which is a CTOR_STMT. */
void
genrtl_ctor_stmt (t)
tree t;
{
if (CTOR_BEGIN_P (t))
begin_protect_partials ();
else
/* After this point, any exceptions will cause the
destructor to be executed, so we no longer need to worry
about destroying the various subobjects ourselves. */
end_protect_partials ();
}
/* Generate the RTL for the start of a COMPOUND_STMT. */
tree genrtl_begin_compound_stmt (has_no_scope)
int has_no_scope;
{
tree r;
int is_try = 0;
r = NULL_TREE;
last_expr_type = NULL_TREE;
if (!building_stmt_tree ())
if (!has_no_scope)
{
/* 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 ();
genrtl_do_pushlevel ();
if (is_try)
note_level_for_eh ();
}
else
/* Normally, we try hard to keep the BLOCK for a
statement-expression. But, if it's a statement-expression with
a scopeless block, there's nothing to keep, and we don't want
to accidentally keep a block *inside* the scopeless block. */
keep_next_level (0);
/* If this is the outermost block of the function, declare the
variables __FUNCTION__, __PRETTY_FUNCTION__, and so forth. */
if (cfun
&& !current_function_name_declared
&& !has_no_scope)
{
current_function_name_declared = 1;
declare_function_name ();
}
do_poplevel ();
return r;
}
if (building_stmt_tree ())
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
/* Generate the RTL for the end of a COMPOUND_STMT. */
tree genrtl_finish_compound_stmt (has_no_scope)
int has_no_scope;
{
tree r;
tree t;
if (!has_no_scope)
r = genrtl_do_poplevel ();
else
r = NULL_TREE;
/* When we call finish_stmt we will lose LAST_EXPR_TYPE. But, since
the precise purpose of that variable is store the type of the
last expression statement within the last compound statement, we
preserve the value. */
t = last_expr_type;
finish_stmt ();
last_expr_type = t;
return r;
}
/* Generate the RTL for T, which is a COMPOUND_STMT. */
tree
genrtl_compound_stmt (t)
tree t;
{
genrtl_begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
expand_stmt (COMPOUND_BODY (t));
return (genrtl_finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t)));
}
/* Begin a compound-statement. If HAS_NO_SCOPE is non-zero, the
......@@ -970,19 +1248,14 @@ begin_compound_stmt (has_no_scope)
tree r;
int is_try = 0;
if (building_stmt_tree ())
{
r = build_min_nt (COMPOUND_STMT, NULL_TREE);
/* Mark that this block is for a try so that we can yell at
people trying to jump in. */
if (last_tree && TREE_CODE (last_tree) == TRY_BLOCK)
is_try = 1;
add_tree (r);
if (has_no_scope)
COMPOUND_STMT_NO_SCOPE (r) = 1;
}
else
r = NULL_TREE;
last_expr_type = NULL_TREE;
......@@ -1012,7 +1285,6 @@ begin_compound_stmt (has_no_scope)
return r;
}
/* Finish a compound-statement, which may be given by COMPOUND_STMT.
If HAS_NO_SCOPE is non-zero, the compound statement does not define
a scope. */
......@@ -1030,7 +1302,6 @@ finish_compound_stmt (has_no_scope, compound_stmt)
else
r = NULL_TREE;
if (building_stmt_tree ())
RECHAIN_STMTS (compound_stmt, COMPOUND_BODY (compound_stmt));
/* When we call finish_stmt we will lose LAST_EXPR_TYPE. But, since
......@@ -1044,12 +1315,10 @@ finish_compound_stmt (has_no_scope, compound_stmt)
return r;
}
/* Finish an asm-statement, whose components are a CV_QUALIFIER, a
STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some
CLOBBERS. */
/* Generate the RTL for an ASM_STMT. */
void
finish_asm_stmt (cv_qualifier, string, output_operands,
genrtl_asm_stmt (cv_qualifier, string, output_operands,
input_operands, clobbers)
tree cv_qualifier;
tree string;
......@@ -1068,15 +1337,6 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
cv_qualifier = NULL_TREE;
}
if (building_stmt_tree ())
{
tree r = build_min_nt (ASM_STMT, cv_qualifier, string,
output_operands, input_operands,
clobbers);
add_tree (r);
}
else
{
emit_line_note (input_filename, lineno);
if (output_operands != NULL_TREE || input_operands != NULL_TREE
|| clobbers != NULL_TREE)
......@@ -1096,7 +1356,37 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
expand_asm (string);
finish_stmt ();
}
/* Finish an asm-statement, whose components are a CV_QUALIFIER, a
STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some
CLOBBERS. */
void
finish_asm_stmt (cv_qualifier, string, output_operands,
input_operands, clobbers)
tree cv_qualifier;
tree string;
tree output_operands;
tree input_operands;
tree clobbers;
{
tree r;
if (TREE_CHAIN (string))
string = combine_strings (string);
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])
{
cp_warning ("%s qualifier ignored on asm",
IDENTIFIER_POINTER (cv_qualifier));
cv_qualifier = NULL_TREE;
}
r = build_min_nt (ASM_STMT, cv_qualifier, string,
output_operands, input_operands,
clobbers);
add_tree (r);
}
/* Finish a label with the indicated NAME. */
......@@ -1106,11 +1396,7 @@ finish_label_stmt (name)
tree name;
{
tree decl = define_label (input_filename, lineno, name);
if (building_stmt_tree ())
add_tree (build_min_nt (LABEL_STMT, decl));
else if (decl)
expand_label (decl);
}
/* Finish a series of declarations for local labels. G++ allows users
......@@ -1122,7 +1408,6 @@ finish_label_decl (name)
tree name;
{
tree decl = declare_local_label (name);
if (building_stmt_tree ())
add_decl_stmt (decl);
}
......@@ -1140,21 +1425,36 @@ add_decl_stmt (decl)
add_tree (decl_stmt);
}
/* Generate the RTL for a SUBOBJECT. */
void
genrtl_subobject (cleanup)
tree cleanup;
{
add_partial_entry (cleanup);
}
/* We're in a constructor, and have just constructed a a subobject of
*THIS. CLEANUP is code to run if an exception is thrown before the
end of the current function is reached. */
void
finish_subobject (cleanup)
finish_subobject (cleanup)
tree cleanup;
{
tree r = build_min_nt (SUBOBJECT, cleanup);
add_tree (r);
}
/* Generate the RTL for a DECL_CLEANUP. */
void
genrtl_decl_cleanup (decl, cleanup)
tree decl;
tree cleanup;
{
if (building_stmt_tree ())
{
tree r = build_min_nt (SUBOBJECT, cleanup);
add_tree (r);
}
else
add_partial_entry (cleanup);
if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
expand_decl_cleanup (decl, cleanup);
}
/* When DECL goes out of scope, make sure that CLEANUP is executed. */
......@@ -1164,11 +1464,61 @@ finish_decl_cleanup (decl, cleanup)
tree decl;
tree cleanup;
{
if (building_stmt_tree ())
add_tree (build_min_nt (CLEANUP_STMT, decl, cleanup));
else if (!decl
|| (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
expand_decl_cleanup (decl, cleanup);
}
/* Generate the RTL for a RETURN_INIT. */
void
genrtl_named_return_value (return_id, init)
tree return_id, init;
{
tree decl;
/* Clear this out so that finish_named_return_value can set it
again. */
DECL_NAME (DECL_RESULT (current_function_decl)) = NULL_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 ("ISO 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", return_id);
return;
}
}
/* Can't let this happen for constructors. */
if (DECL_CONSTRUCTOR_P (current_function_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)
{
/* Let `cp_finish_decl' know that this initializer is ok. */
DECL_INITIAL (decl) = init;
cp_finish_decl (decl, init, NULL_TREE, 0);
store_return_init (decl);
}
/* Don't use tree-inlining for functions with named return values.
That doesn't work properly because we don't do any translation of
the RETURN_INITs when they are copied. */
DECL_UNINLINABLE (current_function_decl) = 1;
}
/* Bind a name and initialization to the return value of
......@@ -1214,14 +1564,7 @@ finish_named_return_value (return_id, init)
DECL_INITIAL (decl) = init;
if (doing_semantic_analysis_p ())
pushdecl (decl);
if (building_stmt_tree ())
add_tree (build_min_nt (RETURN_INIT, return_id, init));
else
{
cp_finish_decl (decl, init, NULL_TREE, 0);
store_return_init (decl);
}
}
/* Don't use tree-inlining for functions with named return values.
......@@ -1375,6 +1718,7 @@ setup_vtbl_ptr (member_init_list, base_init_list)
vtbls_set_up_p = 1;
}
/* Add a scope-statement to the statement-tree. BEGIN_P indicates
whether this statements opens or closes a scope. PARTIAL_P is true
for a partial scope, i.e, the scope that begins after a label when
......@@ -1418,55 +1762,6 @@ add_scope_stmt (begin_p, partial_p)
return top;
}
/* Begin a new scope. */
void
do_pushlevel ()
{
if (!building_stmt_tree ())
{
emit_line_note (input_filename, lineno);
clear_last_expr ();
}
if (stmts_are_full_exprs_p)
{
pushlevel (0);
if (!building_stmt_tree ()
&& !cfun->x_whole_function_mode_p)
my_friendly_abort (19991129);
if (building_stmt_tree () && !processing_template_decl)
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
}
}
/* Finish a scope. */
tree
do_poplevel ()
{
tree block = NULL_TREE;
if (stmts_are_full_exprs_p)
{
tree scope_stmts;
if (building_stmt_tree () && !processing_template_decl)
scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
else
scope_stmts = NULL_TREE;
block = poplevel (kept_level_p (), 1, 0);
if (block && !processing_template_decl)
{
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
}
}
return block;
}
/* Finish a parenthesized expression EXPR. */
tree
......@@ -1480,6 +1775,21 @@ finish_parenthesized_expr (expr)
return expr;
}
/* The last_tree will be NULL_TREE when entering this function. Unlike
the other genrtl functions, in this function, that state can change
hence the check at the end as in the original version of
begin_stmt_expr. Generate the RTL for the start of a STMT_EXPR. */
tree
genrtl_begin_stmt_expr ()
{
if (! cfun && !last_tree)
begin_stmt_tree (&scope_chain->x_saved_tree);
keep_next_level (1);
return (last_tree != NULL_TREE) ? last_tree : expand_start_stmt_expr();
}
/* Begin a statement-expression. The value returned must be passed to
finish_stmt_expr. */
......@@ -1497,7 +1807,25 @@ begin_stmt_expr ()
statement will be chained onto the tree structure, starting at
last_tree. We return last_tree so that we can later unhook the
compound statement. */
return building_stmt_tree () ? last_tree : expand_start_stmt_expr();
return last_tree;
}
/* Generate the RTL for the end of the STMT_EXPR. */
tree
genrtl_finish_stmt_expr (rtl_expr)
tree rtl_expr;
{
tree result;
rtl_expr = expand_end_stmt_expr (rtl_expr);
result = rtl_expr;
if (! cfun
&& TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE)
finish_stmt_tree (&scope_chain->x_saved_tree);
return result;
}
/* Finish a statement-expression. RTL_EXPR should be the value
......@@ -1511,11 +1839,6 @@ finish_stmt_expr (rtl_expr)
{
tree result;
if (!building_stmt_tree ())
rtl_expr = expand_end_stmt_expr (rtl_expr);
if (building_stmt_tree ())
{
/* If the last thing in the statement-expression was not an
expression-statement, then it has type `void'. */
if (!last_expr_type)
......@@ -1527,9 +1850,6 @@ finish_stmt_expr (rtl_expr)
now saved in the STMT_EXPR. */
SET_LAST_STMT (rtl_expr);
TREE_CHAIN (last_tree) = NULL_TREE;
}
else
result = rtl_expr;
/* If we created a statement-tree for this statement-expression,
remove it now. */
......@@ -2449,146 +2769,63 @@ expand_stmt (t)
switch (TREE_CODE (t))
{
case RETURN_STMT:
finish_return_stmt (RETURN_EXPR (t));
genrtl_return_stmt (RETURN_EXPR (t));
break;
case EXPR_STMT:
finish_expr_stmt (EXPR_STMT_EXPR (t));
genrtl_expr_stmt (EXPR_STMT_EXPR (t));
break;
case DECL_STMT:
{
tree decl;
emit_line_note (input_filename, lineno);
decl = DECL_STMT_DECL (t);
/* If this is a declaration for an automatic local
variable, initialize it. Note that we might also see a
declaration for a namespace-scope object (declared with
`extern'). We don't have to handle the initialization
of those objects here; they can only be declarations,
rather than definitions. */
if (TREE_CODE (decl) == VAR_DECL
&& !TREE_STATIC (decl)
&& !DECL_EXTERNAL (decl))
{
/* Let the back-end know about this variable. */
if (!ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
emit_local_var (decl);
else
expand_anon_union_decl (decl, NULL_TREE,
DECL_ANON_UNION_ELEMS (decl));
}
else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
{
if (DECL_ARTIFICIAL (decl) && ! TREE_USED (decl))
/* Do not emit unused decls. This is not just an
optimization. We really do not want to emit
__PRETTY_FUNCTION__ etc, if they're never used. */
DECL_IGNORED_P (decl) = 1;
else
make_rtl_for_local_static (decl);
}
}
genrtl_decl_stmt (t);
break;
case CLEANUP_STMT:
finish_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
break;
case START_CATCH_STMT:
begin_catch_block (TREE_TYPE (t));
genrtl_catch_block (TREE_TYPE (t));
break;
case CTOR_STMT:
if (CTOR_BEGIN_P (t))
begin_protect_partials ();
else
/* After this point, any exceptions will cause the
destructor to be executed, so we no longer need to worry
about destroying the various subobjects ourselves. */
end_protect_partials ();
genrtl_ctor_stmt (t);
break;
case FOR_STMT:
{
tree tmp;
begin_for_stmt ();
expand_stmt (FOR_INIT_STMT (t));
finish_for_init_stmt (NULL_TREE);
finish_for_cond (expand_cond (FOR_COND (t)), NULL_TREE);
tmp = FOR_EXPR (t);
finish_for_expr (tmp, NULL_TREE);
expand_stmt (FOR_BODY (t));
finish_for_stmt (tmp, NULL_TREE);
}
genrtl_for_stmt (t);
break;
case WHILE_STMT:
{
begin_while_stmt ();
finish_while_stmt_cond (expand_cond (WHILE_COND (t)), NULL_TREE);
expand_stmt (WHILE_BODY (t));
finish_while_stmt (NULL_TREE);
}
genrtl_while_stmt (t);
break;
case DO_STMT:
{
begin_do_stmt ();
expand_stmt (DO_BODY (t));
finish_do_body (NULL_TREE);
finish_do_stmt (DO_COND (t), NULL_TREE);
}
genrtl_do_stmt (t);
break;
case IF_STMT:
begin_if_stmt ();
finish_if_stmt_cond (expand_cond (IF_COND (t)), NULL_TREE);
if (THEN_CLAUSE (t))
{
expand_stmt (THEN_CLAUSE (t));
finish_then_clause (NULL_TREE);
}
if (ELSE_CLAUSE (t))
{
begin_else_clause ();
expand_stmt (ELSE_CLAUSE (t));
finish_else_clause (NULL_TREE);
}
finish_if_stmt ();
genrtl_if_stmt (t);
break;
case COMPOUND_STMT:
begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
expand_stmt (COMPOUND_BODY (t));
rval = finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t),
NULL_TREE);
rval = genrtl_compound_stmt (t);
break;
case BREAK_STMT:
finish_break_stmt ();
genrtl_break_stmt ();
break;
case CONTINUE_STMT:
finish_continue_stmt ();
genrtl_continue_stmt ();
break;
case SWITCH_STMT:
{
tree cond;
begin_switch_stmt ();
cond = expand_cond (SWITCH_COND (t));
finish_switch_cond (cond, NULL_TREE);
expand_stmt (SWITCH_BODY (t));
finish_switch_stmt (cond, NULL_TREE);
}
genrtl_switch_stmt (t);
break;
case CASE_LABEL:
finish_case_label (CASE_LOW (t), CASE_HIGH (t));
genrtl_case_label (CASE_LOW (t), CASE_HIGH (t));
break;
case LABEL_STMT:
......@@ -2596,81 +2833,32 @@ expand_stmt (t)
break;
case GOTO_STMT:
finish_goto_stmt (GOTO_DESTINATION (t));
genrtl_goto_stmt (GOTO_DESTINATION (t));
break;
case ASM_STMT:
finish_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t), ASM_OUTPUTS
(t), ASM_INPUTS (t), ASM_CLOBBERS (t));
genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
ASM_OUTPUTS (t), ASM_INPUTS (t), ASM_CLOBBERS (t));
break;
case TRY_BLOCK:
if (CLEANUP_P (t))
{
expand_eh_region_start ();
expand_stmt (TRY_STMTS (t));
finish_cleanup_try_block (NULL_TREE);
finish_cleanup (TRY_HANDLERS (t), NULL_TREE);
}
else
{
if (FN_TRY_BLOCK_P (t))
begin_function_try_block ();
else
begin_try_block ();
expand_stmt (TRY_STMTS (t));
if (FN_TRY_BLOCK_P (t))
{
finish_function_try_block (NULL_TREE);
expand_stmt (TRY_HANDLERS (t));
finish_function_handler_sequence (NULL_TREE);
}
else
{
finish_try_block (NULL_TREE);
expand_stmt (TRY_HANDLERS (t));
finish_handler_sequence (NULL_TREE);
}
}
genrtl_try_block (t);
break;
case HANDLER:
begin_handler ();
expand_stmt (HANDLER_BODY (t));
finish_handler (NULL_TREE, NULL_TREE);
genrtl_handler (t);
break;
case SUBOBJECT:
finish_subobject (SUBOBJECT_CLEANUP (t));
genrtl_subobject (SUBOBJECT_CLEANUP (t));
break;
case SCOPE_STMT:
if (!SCOPE_NO_CLEANUPS_P (t))
{
if (SCOPE_BEGIN_P (t))
expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t),
SCOPE_STMT_BLOCK (t));
else if (SCOPE_END_P (t))
expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
}
else if (!SCOPE_NULLIFIED_P (t))
{
rtx note = emit_note (NULL,
(SCOPE_BEGIN_P (t)
? NOTE_INSN_BLOCK_BEG
: NOTE_INSN_BLOCK_END));
NOTE_BLOCK (note) = SCOPE_STMT_BLOCK (t);
}
genrtl_scope_stmt (t);
break;
case RETURN_INIT:
/* Clear this out so that finish_named_return_value can set it
again. */
DECL_NAME (DECL_RESULT (current_function_decl)) = NULL_TREE;
finish_named_return_value (TREE_OPERAND (t, 0),
genrtl_named_return_value (TREE_OPERAND (t, 0),
TREE_OPERAND (t, 1));
break;
......
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