-/* Genericize a CLEANUP_STMT. This just turns into a TRY_FINALLY or
- TRY_CATCH depending on whether it's EH-only. */
-
-static tree
-gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
- void *data ATTRIBUTE_UNUSED)
-{
- tree stmt = *stmt_p;
-
- if (DECL_P (stmt) || TYPE_P (stmt))
- *walk_subtrees = 0;
- else if (TREE_CODE (stmt) == CLEANUP_STMT)
- *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
- void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
-
- return NULL;
-}
-
-static void
-gimplify_cleanup_stmts (tree fndecl)
-{
- walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
-}
-
-/* Entry point for the tree lowering pass. Recursively scan
- *STMT_P and convert it to a GIMPLE tree. */
-
-int
-c_gimplify_stmt (tree *stmt_p)
-{
- tree stmt = *stmt_p;
- tree pre, post;
- int saved_stmts_are_full_exprs_p;
- location_t stmt_locus;
- enum gimplify_status ret;
-
- /* PRE and POST are tree chains that contain the side-effects of the
- gimplified tree. For instance, given the expression tree:
-
- c = ++a * 3 + b++;
-
- After gimplification, the tree will be re-written as:
-
- a = a + 1;
- t1 = a * 3; <-- PRE
- c = t1 + b;
- b = b + 1; <-- POST */
-
- /* Set up context appropriately for handling this statement. */
- saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
- prep_stmt (stmt);
- stmt_locus = input_location;
-
- pre = NULL_TREE;
- post = NULL_TREE;
-
- switch (TREE_CODE (stmt))
- {
- case COMPOUND_STMT:
- stmt = COMPOUND_BODY (stmt);
- ret = GS_OK;
- break;
-
- case FOR_STMT:
- ret = gimplify_for_stmt (&stmt, &pre);
- break;
-
- case WHILE_STMT:
- ret = gimplify_while_stmt (&stmt);
- break;
-
- case DO_STMT:
- ret = gimplify_do_stmt (&stmt);
- break;
-
- case IF_STMT:
- ret = gimplify_if_stmt (&stmt);
- break;
-
- case SWITCH_STMT:
- ret = gimplify_switch_stmt (&stmt);
- break;
-
- case EXPR_STMT:
- ret = gimplify_expr_stmt (&stmt);
- break;
-
- case RETURN_STMT:
- ret = gimplify_return_stmt (&stmt);
- break;
-
- case DECL_STMT:
- ret = gimplify_decl_stmt (&stmt);
- break;
-
- case LABEL_STMT:
- stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
- ret = GS_OK;
- break;
-
- case GOTO_STMT:
- stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
- ret = GS_OK;
- break;
-
- case CASE_LABEL:
- {
- tree label = create_artificial_label ();
- stmt = build (CASE_LABEL_EXPR, void_type_node,
- CASE_LOW (stmt), CASE_HIGH (stmt), label);
- ret = GS_OK;
- }
- break;
-
- case CONTINUE_STMT:
- stmt = build_bc_goto (bc_continue);
- ret = GS_OK;
- break;
-
- case BREAK_STMT:
- stmt = build_bc_goto (bc_break);
- ret = GS_OK;
- break;
-
- case ASM_STMT:
- {
- tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
- ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
- ASM_CLOBBERS (stmt));
- ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
- ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
- stmt = new_stmt;
- ret = GS_OK;
- }
- break;
-
- default:
- if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt))
- {
- ret = GS_OK;
- break;
- }
-
- fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
- debug_tree (stmt);
- abort ();
- break;
- }
-
- switch (ret)
- {
- case GS_ERROR:
- goto cont;
- case GS_OK:
- gimplify_stmt (&stmt);
- break;
- case GS_ALL_DONE:
- break;
- default:
- abort ();
- }
-
- /* PRE and POST now contain a list of statements for all the
- side-effects in STMT. */
-
- append_to_statement_list (stmt, &pre);
- append_to_statement_list (post, &pre);
- annotate_all_with_locus (&pre, stmt_locus);
- cont:
- /* Restore saved state. */
- current_stmt_tree ()->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p;
- *stmt_p = pre;
-
- return GS_ALL_DONE;
-}
-