-
-/* Generate the RTL for STMT, which is a RETURN_STMT. */
-
-void
-genrtl_return_stmt (stmt)
- tree stmt;
-{
- tree expr = RETURN_EXPR (stmt);
-
- emit_line_note (input_filename, lineno);
- if (!expr)
- expand_null_return ();
- else
- {
- expand_start_target_temps ();
- expand_return (expr);
- expand_end_target_temps ();
- }
-}
-
-/* Generate the RTL for T, which is a FOR_STMT. */
-
-void
-genrtl_for_stmt (t)
- tree t;
-{
- tree cond;
- const char *saved_filename;
- int saved_lineno;
-
- if (NEW_FOR_SCOPE_P (t))
- genrtl_do_pushlevel ();
-
- expand_stmt (FOR_INIT_STMT (t));
-
- /* Expand the initialization. */
- emit_nop ();
- emit_line_note (input_filename, lineno);
- expand_start_loop_continue_elsewhere (1);
- genrtl_do_pushlevel ();
- cond = expand_cond (FOR_COND (t));
-
- /* Save the filename and line number so that we expand the FOR_EXPR
- we can reset them back to the saved values. */
- saved_filename = input_filename;
- saved_lineno = lineno;
-
- /* Expand the condition. */
- emit_line_note (input_filename, lineno);
- if (cond)
- expand_exit_loop_if_false (0, cond);
-
- /* Expand the body. */
- genrtl_do_pushlevel ();
- expand_stmt (FOR_BODY (t));
-
- /* Expand the increment expression. */
- input_filename = saved_filename;
- lineno = saved_lineno;
- emit_line_note (input_filename, lineno);
- expand_loop_continue_here ();
- if (FOR_EXPR (t))
- genrtl_expr_stmt (FOR_EXPR (t));
- expand_end_loop ();
-}
-
-/* Build a break statement node and return it. */
-
-tree
-build_break_stmt ()
-{
- return (build_stmt (BREAK_STMT));
-}
-
-/* Generate the RTL for a BREAK_STMT. */
-
-void
-genrtl_break_stmt ()
-{
- emit_line_note (input_filename, lineno);
- if ( ! expand_exit_something ())
- error ("break statement not within loop or switch");
-}
-
-/* Build a continue statement node and return it. */
-
-tree
-build_continue_stmt ()
-{
- return (build_stmt (CONTINUE_STMT));
-}
-
-/* Generate the RTL for a CONTINUE_STMT. */
-
-void
-genrtl_continue_stmt ()
-{
- emit_line_note (input_filename, lineno);
- if (! expand_continue_loop (0))
- 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)
- /* The code is in error, but we don't want expand_end_case to
- crash. */
- cond = boolean_false_node;
-
- emit_line_note (input_filename, lineno);
- expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
- expand_stmt (SWITCH_BODY (t));
- expand_end_case (cond);
-}
-
-/* Create a CASE_LABEL tree node and return it. */
-
-tree
-build_case_label (low_value, high_value, label_decl)
- tree low_value;
- tree high_value;
- tree label_decl;
-{
- return build_stmt (CASE_LABEL, low_value, high_value, label_decl);
-}
-
-
-/* Generate the RTL for a CASE_LABEL. */
-
-void
-genrtl_case_label (case_label)
- tree case_label;
-{
- tree duplicate;
- tree cleanup;
-
- cleanup = last_cleanup_this_contour ();
- if (cleanup)
- {
- static int explained = 0;
- warning_with_decl (TREE_PURPOSE (cleanup),
- "destructor needed for `%#D'");
- warning ("where case label appears here");
- if (!explained)
- {
- warning ("(enclose actions of previous case statements requiring destructors in their own scope.)");
- explained = 1;
- }
- }
-
- add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
- CASE_LABEL_DECL (case_label), &duplicate);
-}
-
-/* Generate the RTL for T, which is a COMPOUND_STMT. */
-
-void
-genrtl_compound_stmt (t)
- tree t;
-{
- expand_stmt (COMPOUND_BODY (t));
-}
-
-/* Generate the RTL for an ASM_STMT. */
-
-void
-genrtl_asm_stmt (cv_qualifier, string, output_operands,
- input_operands, clobbers)
- tree cv_qualifier;
- tree string;
- tree output_operands;
- tree input_operands;
- tree clobbers;
-{
- if (cv_qualifier != NULL_TREE
- && cv_qualifier != ridpointers[(int) RID_VOLATILE])
- {
- warning ("%s qualifier ignored on asm",
- IDENTIFIER_POINTER (cv_qualifier));
- cv_qualifier = NULL_TREE;
- }
-
- emit_line_note (input_filename, lineno);
- if (output_operands != NULL_TREE || input_operands != NULL_TREE
- || clobbers != NULL_TREE)
- c_expand_asm_operands (string, output_operands,
- input_operands,
- clobbers,
- cv_qualifier != NULL_TREE,
- input_filename, lineno);
- else
- expand_asm (string);
-}
-
-/* Generate the RTL for a DECL_CLEANUP. */
-
-void
-genrtl_decl_cleanup (decl, cleanup)
- tree decl;
- tree cleanup;
-{
- if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
- expand_decl_cleanup (decl, cleanup);
-}
-
-/* We're about to expand T, a statement. Set up appropriate context
- for the substitution. */
-
-void
-prep_stmt (t)
- tree t;
-{
- if (!STMT_LINENO_FOR_FN_P (t))
- lineno = STMT_LINENO (t);
- current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
-}
-
-/* Generate the RTL for the statement T, its substatements, and any
- other statements at its nesting level. */
-
-void
-expand_stmt (t)
- tree t;
-{
- while (t && t != error_mark_node)
- {
- int saved_stmts_are_full_exprs_p;
-
- /* Set up context appropriately for handling this statement. */
- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
- prep_stmt (t);
-
- switch (TREE_CODE (t))
- {
- case RETURN_STMT:
- genrtl_return_stmt (t);
- break;
-
- case EXPR_STMT:
- genrtl_expr_stmt (EXPR_STMT_EXPR (t));
- break;
-
- case DECL_STMT:
- genrtl_decl_stmt (t);
- break;
-
- case FOR_STMT:
- genrtl_for_stmt (t);
- break;
-
- case WHILE_STMT:
- genrtl_while_stmt (t);
- break;
-
- case DO_STMT:
- genrtl_do_stmt (t);
- break;
-
- case IF_STMT:
- genrtl_if_stmt (t);
- break;
-
- case COMPOUND_STMT:
- genrtl_compound_stmt (t);
- break;
-
- case BREAK_STMT:
- genrtl_break_stmt ();
- break;
-
- case CONTINUE_STMT:
- genrtl_continue_stmt ();
- break;
-
- case SWITCH_STMT:
- genrtl_switch_stmt (t);
- break;
-
- case CASE_LABEL:
- genrtl_case_label (t);
- break;
-
- case LABEL_STMT:
- expand_label (LABEL_STMT_LABEL (t));
- break;
-
- case GOTO_STMT:
- genrtl_goto_stmt (GOTO_DESTINATION (t));
- break;
-
- case ASM_STMT:
- genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
- ASM_OUTPUTS (t), ASM_INPUTS (t), ASM_CLOBBERS (t));
- break;
-
- case SCOPE_STMT:
- genrtl_scope_stmt (t);
- break;
-
- default:
- if (lang_expand_stmt)
- (*lang_expand_stmt) (t);
- else
- abort ();
- break;
- }
-
- /* Restore saved state. */
- current_stmt_tree ()->stmts_are_full_exprs_p =
- saved_stmts_are_full_exprs_p;
-
- /* Go on to the next statement in this scope. */
- t = TREE_CHAIN (t);
- }
-}
-