static void genericize_try_block (tree *stmt_p) { tree body = TRY_STMTS (*stmt_p); tree cleanup = TRY_HANDLERS (*stmt_p); gimplify_stmt (&body); if (CLEANUP_P (*stmt_p)) /* A cleanup is an expression, so it doesn't need to be genericized. */; else gimplify_stmt (&cleanup); *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup); }
static void genericize_catch_block (tree *stmt_p) { tree type = HANDLER_TYPE (*stmt_p); tree body = HANDLER_BODY (*stmt_p); gimplify_stmt (&body); /* FIXME should the caught type go in TREE_TYPE? */ *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body); }
static void genericize_eh_spec_block (tree *stmt_p) { tree body = EH_SPEC_STMTS (*stmt_p); tree allowed = EH_SPEC_RAISES (*stmt_p); tree failure = build_call (call_unexpected_node, tree_cons (NULL_TREE, build_exc_ptr (), NULL_TREE)); gimplify_stmt (&body); *stmt_p = gimple_build_eh_filter (body, allowed, failure); }
static void gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p) { tree stmt = *expr_p; tree temp = voidify_wrapper_expr (stmt, NULL); tree body = TREE_OPERAND (stmt, 0); gimplify_stmt (&body); stmt = gimple_build_eh_filter (body, NULL_TREE, build_call (terminate_node, NULL_TREE)); if (temp) { append_to_statement_list (stmt, pre_p); *expr_p = temp; } else *expr_p = stmt; }
static void gimplify_switch_stmt (tree *stmt_p) { tree stmt = *stmt_p; tree break_block, body; location_t stmt_locus = input_location; break_block = begin_bc_block (bc_break); body = SWITCH_STMT_BODY (stmt); if (!body) body = build_empty_stmt (); *stmt_p = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt), SWITCH_STMT_COND (stmt), body, NULL_TREE); SET_EXPR_LOCATION (*stmt_p, stmt_locus); gimplify_stmt (stmt_p); *stmt_p = finish_bc_block (bc_break, break_block, *stmt_p); }
static enum gimplify_status cp_gimplify_omp_for (tree *expr_p) { tree for_stmt = *expr_p; tree cont_block; /* Protect ourselves from recursion. */ if (OMP_FOR_GIMPLIFYING_P (for_stmt)) return GS_UNHANDLED; OMP_FOR_GIMPLIFYING_P (for_stmt) = 1; /* Note that while technically the continue label is enabled too soon here, we should have already diagnosed invalid continues nested within statement expressions within the INIT, COND, or INCR expressions. */ cont_block = begin_bc_block (bc_continue); gimplify_stmt (expr_p); OMP_FOR_BODY (for_stmt) = finish_bc_block (bc_continue, cont_block, OMP_FOR_BODY (for_stmt)); OMP_FOR_GIMPLIFYING_P (for_stmt) = 0; return GS_ALL_DONE; }
/* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of _DECLs if appropriate. Arrange to call the __mf_register function now, and the __mf_unregister function later for each. */ static void mx_register_decls (tree decl, tree *stmt_list) { tree finally_stmts = NULL_TREE; tree_stmt_iterator initially_stmts = tsi_start (*stmt_list); while (decl != NULL_TREE) { if (mf_decl_eligible_p (decl) /* Not already processed. */ && ! mf_marked_p (decl) /* Automatic variable. */ && ! DECL_EXTERNAL (decl) && ! TREE_STATIC (decl)) { tree size = NULL_TREE, variable_name; tree unregister_fncall, unregister_fncall_params; tree register_fncall, register_fncall_params; size = convert (size_type_node, TYPE_SIZE_UNIT (TREE_TYPE (decl))); /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */ unregister_fncall_params = tree_cons (NULL_TREE, convert (ptr_type_node, mf_mark (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), decl))), tree_cons (NULL_TREE, size, tree_cons (NULL_TREE, /* __MF_TYPE_STACK */ build_int_cst (NULL_TREE, 3), NULL_TREE))); /* __mf_unregister (...) */ unregister_fncall = build_function_call_expr (mf_unregister_fndecl, unregister_fncall_params); /* (& VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK, "name") */ variable_name = mf_varname_tree (decl); register_fncall_params = tree_cons (NULL_TREE, convert (ptr_type_node, mf_mark (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), decl))), tree_cons (NULL_TREE, size, tree_cons (NULL_TREE, /* __MF_TYPE_STACK */ build_int_cst (NULL_TREE, 3), tree_cons (NULL_TREE, variable_name, NULL_TREE)))); /* __mf_register (...) */ register_fncall = build_function_call_expr (mf_register_fndecl, register_fncall_params); /* Accumulate the two calls. */ /* ??? Set EXPR_LOCATION. */ gimplify_stmt (®ister_fncall); gimplify_stmt (&unregister_fncall); /* Add the __mf_register call at the current appending point. */ if (tsi_end_p (initially_stmts)) warning (0, "mudflap cannot track %qs in stub function", IDENTIFIER_POINTER (DECL_NAME (decl))); else { tsi_link_before (&initially_stmts, register_fncall, TSI_SAME_STMT); /* Accumulate the FINALLY piece. */ append_to_statement_list (unregister_fncall, &finally_stmts); } mf_mark (decl); } decl = TREE_CHAIN (decl); } /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */ if (finally_stmts != NULL_TREE) { tree t = build2 (TRY_FINALLY_EXPR, void_type_node, *stmt_list, finally_stmts); *stmt_list = NULL; append_to_statement_list (t, stmt_list); } }
static tree gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first) { tree top, entry, exit, cont_block, break_block, stmt_list, t; location_t stmt_locus; stmt_locus = input_location; stmt_list = NULL_TREE; entry = NULL_TREE; break_block = begin_bc_block (bc_break); cont_block = begin_bc_block (bc_continue); /* If condition is zero don't generate a loop construct. */ if (cond && integer_zerop (cond)) { top = NULL_TREE; exit = NULL_TREE; if (cond_is_first) { t = build_bc_goto (bc_break); append_to_statement_list (t, &stmt_list); } } else { /* If we use a LOOP_EXPR here, we have to feed the whole thing back through the main gimplifier to lower it. Given that we have to gimplify the loop body NOW so that we can resolve break/continue stmts, seems easier to just expand to gotos. */ top = build1 (LABEL_EXPR, void_type_node, NULL_TREE); /* If we have an exit condition, then we build an IF with gotos either out of the loop, or to the top of it. If there's no exit condition, then we just build a jump back to the top. */ exit = build_and_jump (&LABEL_EXPR_LABEL (top)); if (cond && !integer_nonzerop (cond)) { t = build_bc_goto (bc_break); exit = build3 (COND_EXPR, void_type_node, cond, exit, t); exit = fold (exit); gimplify_stmt (&exit); if (cond_is_first) { if (incr) { entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); t = build_and_jump (&LABEL_EXPR_LABEL (entry)); } else t = build_bc_goto (bc_continue); append_to_statement_list (t, &stmt_list); } } } gimplify_stmt (&body); gimplify_stmt (&incr); body = finish_bc_block (bc_continue, cont_block, body); append_to_statement_list (top, &stmt_list); append_to_statement_list (body, &stmt_list); append_to_statement_list (incr, &stmt_list); append_to_statement_list (entry, &stmt_list); append_to_statement_list (exit, &stmt_list); annotate_all_with_locus (&stmt_list, stmt_locus); return finish_bc_block (bc_break, break_block, stmt_list); }
static gimple_seq gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first) { gimple top, entry, stmt; gimple_seq stmt_list, body_seq, incr_seq, exit_seq; tree cont_block, break_block; location_t stmt_locus; stmt_locus = input_location; stmt_list = NULL; body_seq = NULL; incr_seq = NULL; exit_seq = NULL; entry = NULL; break_block = begin_bc_block (bc_break); cont_block = begin_bc_block (bc_continue); /* If condition is zero don't generate a loop construct. */ if (cond && integer_zerop (cond)) { top = NULL; if (cond_is_first) { stmt = gimple_build_goto (get_bc_label (bc_break)); gimple_set_location (stmt, stmt_locus); gimple_seq_add_stmt (&stmt_list, stmt); } } else { /* If we use a LOOP_EXPR here, we have to feed the whole thing back through the main gimplifier to lower it. Given that we have to gimplify the loop body NOW so that we can resolve break/continue stmts, seems easier to just expand to gotos. */ top = gimple_build_label (create_artificial_label ()); /* If we have an exit condition, then we build an IF with gotos either out of the loop, or to the top of it. If there's no exit condition, then we just build a jump back to the top. */ if (cond && !integer_nonzerop (cond)) { if (cond != error_mark_node) { gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue); stmt = gimple_build_cond (NE_EXPR, cond, build_int_cst (TREE_TYPE (cond), 0), gimple_label_label (top), get_bc_label (bc_break)); gimple_seq_add_stmt (&exit_seq, stmt); } if (cond_is_first) { if (incr) { entry = gimple_build_label (create_artificial_label ()); stmt = gimple_build_goto (gimple_label_label (entry)); } else stmt = gimple_build_goto (get_bc_label (bc_continue)); gimple_set_location (stmt, stmt_locus); gimple_seq_add_stmt (&stmt_list, stmt); } } else { stmt = gimple_build_goto (gimple_label_label (top)); gimple_seq_add_stmt (&exit_seq, stmt); } } gimplify_stmt (&body, &body_seq); gimplify_stmt (&incr, &incr_seq); body_seq = finish_bc_block (bc_continue, cont_block, body_seq); gimple_seq_add_stmt (&stmt_list, top); gimple_seq_add_seq (&stmt_list, body_seq); gimple_seq_add_seq (&stmt_list, incr_seq); gimple_seq_add_stmt (&stmt_list, entry); gimple_seq_add_seq (&stmt_list, exit_seq); annotate_all_with_location (stmt_list, stmt_locus); return finish_bc_block (bc_break, break_block, stmt_list); }
static tree /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ gimplify_cp_loop (tree cond, tree body, tree incr, tree attrs, bool cond_is_first, tree inner_foreach) /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ { tree top, entry, exit, cont_block, break_block, stmt_list, t; location_t stmt_locus; stmt_locus = input_location; stmt_list = NULL_TREE; entry = NULL_TREE; /* APPLE LOCAL begin C* language */ /* Order of label addition to stack is important for objc's foreach-stmt. */ /* APPLE LOCAL radar 4667060 */ if (inner_foreach == integer_zero_node) { cont_block = begin_bc_block (bc_continue); break_block = begin_bc_block (bc_break); } else { break_block = begin_bc_block (bc_break); cont_block = begin_bc_block (bc_continue); } /* APPLE LOCAL end C* language */ /* If condition is zero don't generate a loop construct. */ if (cond && integer_zerop (cond)) { top = NULL_TREE; exit = NULL_TREE; if (cond_is_first) { t = build_bc_goto (bc_break); append_to_statement_list (t, &stmt_list); } } else { /* If we use a LOOP_EXPR here, we have to feed the whole thing back through the main gimplifier to lower it. Given that we have to gimplify the loop body NOW so that we can resolve break/continue stmts, seems easier to just expand to gotos. */ top = build1 (LABEL_EXPR, void_type_node, NULL_TREE); /* If we have an exit condition, then we build an IF with gotos either out of the loop, or to the top of it. If there's no exit condition, then we just build a jump back to the top. */ exit = build_and_jump (&LABEL_EXPR_LABEL (top)); /* APPLE LOCAL begin for-fsf-4_4 3274130 5295549 */ \ /* Add the attributes to the 'top' label. */ decl_attributes (&LABEL_EXPR_LABEL (top), attrs, 0); /* APPLE LOCAL end for-fsf-4_4 3274130 5295549 */ \ if (cond && !integer_nonzerop (cond)) { t = build_bc_goto (bc_break); exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t); gimplify_stmt (&exit); if (cond_is_first) { if (incr) { entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE); t = build_and_jump (&LABEL_EXPR_LABEL (entry)); } else t = build_bc_goto (bc_continue); append_to_statement_list (t, &stmt_list); } } } /* APPLE LOCAL begin radar 4547045 */ /* Pop foreach's inner loop break label so outer loop's break label becomes target of inner loop body's break statements. */ t = NULL_TREE; gimplify_stmt (&body); gimplify_stmt (&incr); body = finish_bc_block (bc_continue, cont_block, body); /* APPLE LOCAL begin radar 4547045 */ /* Push back inner loop's own 'break' label so rest of code works seemlessly. */ /* APPLE LOCAL radar 4667060 */ append_to_statement_list (top, &stmt_list); append_to_statement_list (body, &stmt_list); append_to_statement_list (incr, &stmt_list); append_to_statement_list (entry, &stmt_list); append_to_statement_list (exit, &stmt_list); annotate_all_with_locus (&stmt_list, stmt_locus); return finish_bc_block (bc_break, break_block, stmt_list); }