static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
static rtx do_store_flag PROTO((tree, rtx, enum machine_mode, int));
static tree defer_cleanups_to PROTO((tree));
+extern void (*interim_eh_hook) PROTO((tree));
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
= tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
/* That's it for this cleanup. */
TREE_OPERAND (exp, 2) = 0;
+ (*interim_eh_hook) (NULL_TREE);
}
return RTL_EXPR_RTL (exp);
/* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
+ (*interim_eh_hook) (NULL_TREE);
}
return temp;
}
case TARGET_EXPR:
{
+ int need_exception_region = 0;
/* Something needs to be initialized, but we didn't know
where that thing was when building the tree. For example,
it could be the return value of a function, or a parameter
tree slot = TREE_OPERAND (exp, 0);
tree exp1;
+ rtx temp;
if (TREE_CODE (slot) != VAR_DECL)
abort ();
cleanups_this_call = tree_cons (NULL_TREE,
TREE_OPERAND (exp, 2),
cleanups_this_call);
+ need_exception_region = 1;
}
}
}
/* Mark it as expanded. */
TREE_OPERAND (exp, 1) = NULL_TREE;
- return expand_expr (exp1, target, tmode, modifier);
+ temp = expand_expr (exp1, target, tmode, modifier);
+
+ if (need_exception_region)
+ (*interim_eh_hook) (NULL_TREE);
+
+ return temp;
}
case INIT_EXPR:
while (cleanups_this_call != old_cleanups)
{
+ (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
{
while (cleanups_this_call != old_cleanups)
{
+ (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
expand_expr (TREE_VALUE (cleanups_this_call), const0_rtx, VOIDmode, 0);
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
cleanup list whenever an empty list is required. */
static tree empty_cleanup_list;
#endif
+
+extern void (*interim_eh_hook) PROTO((tree));
\f
/* Functions and data structures for expanding case statements. */
= temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
/* If this block has a cleanup, it belongs in stack_block_stack. */
stack_block_stack = thisblock;
+ (*interim_eh_hook) (NULL_TREE);
}
return 1;
}
expand_cleanups (TREE_VALUE (tail), dont_do);
else
{
+ (*interim_eh_hook) (TREE_VALUE (tail));
+
/* Cleanups may be run multiple times. For example,
when exiting a binding contour, we expand the
cleanups associated with that contour. When a goto
void (*incomplete_decl_finalize_hook) () = 0;
+/* Pointer to function for interim exception handling implementation.
+ This interface will change, and it is only here until a better interface
+ replaces it. */
+
+void (*interim_eh_hook) PROTO((tree));
+
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
+
+/* This is the default interim_eh_hook function. */
+
+void
+interim_eh (finalization)
+ tree finalization;
+{
+ /* Don't do anything by default. */
+}
\f
static int need_error_newline;
decl_printable_name = decl_name;
lang_expand_expr = (struct rtx_def *(*)()) do_abort;
+ interim_eh_hook = interim_eh;
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;