mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-07 07:46:49 +08:00
exception.cc (struct cp_eh_info): Add handlers field.
* exception.cc (struct cp_eh_info): Add handlers field. (__cp_push_exception): Initialize it. (__cp_pop_exception): Decrement it. Don't pop unless it's 0. (__throw_bad_exception): Remove. * except.c (call_eh_info): Add handlers field. (get_eh_handlers): New fn. (push_eh_cleanup): Increment handlers. Fixes P15031.C, rethrow[45].C From-SVN: r16694
This commit is contained in:
parent
c77289885d
commit
20b9016983
@ -1,3 +1,13 @@
|
||||
Mon Nov 24 12:15:55 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* exception.cc (struct cp_eh_info): Add handlers field.
|
||||
(__cp_push_exception): Initialize it.
|
||||
(__cp_pop_exception): Decrement it. Don't pop unless it's 0.
|
||||
(__throw_bad_exception): Remove.
|
||||
* except.c (call_eh_info): Add handlers field.
|
||||
(get_eh_handlers): New fn.
|
||||
(push_eh_cleanup): Increment handlers.
|
||||
|
||||
Fri Nov 21 12:22:07 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* except.c (expand_start_eh_spec): Use the try/catch code.
|
||||
|
@ -319,7 +319,7 @@ call_eh_info ()
|
||||
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
||||
else
|
||||
{
|
||||
tree t, fields[5];
|
||||
tree t, fields[6];
|
||||
|
||||
/* Declare cp_eh_info * __cp_exception_info (void),
|
||||
as defined in exception.cc. */
|
||||
@ -342,9 +342,11 @@ call_eh_info ()
|
||||
boolean_type_node);
|
||||
fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
|
||||
build_pointer_type (t));
|
||||
fields[5] = build_lang_field_decl
|
||||
(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
|
||||
/* N.B.: The fourth field LEN is expected to be
|
||||
the number of fields - 1, not the total number of fields. */
|
||||
finish_builtin_type (t, "cp_eh_info", fields, 4, ptr_type_node);
|
||||
finish_builtin_type (t, "cp_eh_info", fields, 5, ptr_type_node);
|
||||
t = build_pointer_type (t);
|
||||
|
||||
/* And now the function. */
|
||||
@ -417,6 +419,16 @@ get_eh_caught ()
|
||||
NULL_TREE, 0);
|
||||
}
|
||||
|
||||
/* Returns a reference to whether or not the current exception
|
||||
has been caught. */
|
||||
|
||||
static tree
|
||||
get_eh_handlers ()
|
||||
{
|
||||
return build_component_ref (get_eh_info (), get_identifier ("handlers"),
|
||||
NULL_TREE, 0);
|
||||
}
|
||||
|
||||
/* Build a type value for use at runtime for a type that is matched
|
||||
against by the exception handling system. */
|
||||
|
||||
@ -514,6 +526,9 @@ push_eh_cleanup ()
|
||||
expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node));
|
||||
resume_momentary (yes);
|
||||
|
||||
expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1),
|
||||
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
/* We don't destroy the exception object on rethrow, so we can't use
|
||||
the normal cleanup mechanism for it. */
|
||||
expand_eh_region_start ();
|
||||
|
@ -75,7 +75,11 @@ unexpected ()
|
||||
}
|
||||
|
||||
/* C++-specific state about the current exception.
|
||||
This must match init_exception_processing(). */
|
||||
This must match init_exception_processing().
|
||||
|
||||
Note that handlers and caught are not redundant; when rethrown, an
|
||||
exception can have multiple active handlers and still be considered
|
||||
uncaught. */
|
||||
|
||||
struct cp_eh_info
|
||||
{
|
||||
@ -84,6 +88,7 @@ struct cp_eh_info
|
||||
void (*cleanup)(void *, int);
|
||||
bool caught;
|
||||
cp_eh_info *next;
|
||||
long handlers;
|
||||
};
|
||||
|
||||
/* Language-specific EH info pointer, defined in libgcc2. */
|
||||
@ -113,6 +118,7 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
|
||||
p->value = value;
|
||||
p->type = type;
|
||||
p->cleanup = cleanup;
|
||||
p->handlers = 0;
|
||||
p->caught = false;
|
||||
p->next = __eh_info;
|
||||
__eh_info = p;
|
||||
@ -128,7 +134,9 @@ __cp_pop_exception (cp_eh_info *p, bool handler)
|
||||
{
|
||||
cp_eh_info **q = &__eh_info;
|
||||
|
||||
if (handler && p == *q)
|
||||
--p->handlers;
|
||||
|
||||
if (p->handlers > 0 || (handler && p == *q))
|
||||
return;
|
||||
|
||||
for (; *q; q = &((*q)->next))
|
||||
@ -220,12 +228,6 @@ __throw_bad_typeid (void)
|
||||
throw bad_typeid ();
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
__throw_bad_exception (void)
|
||||
{
|
||||
throw bad_exception ();
|
||||
}
|
||||
|
||||
/* Has the current exception been caught? */
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user