mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 09:04:32 +08:00
[multiple changes]
Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com> * class.c (prepare_fresh_vtable): Enable even more complex MI vtable names. Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com> * exception.cc (__check_eh_spec): Optimize a bit. * exception.cc (__cp_pop_exception): Lose handler arg. * except.c (do_pop_exception): Likewise. (push_eh_cleanup): Let the cleanup mechanism supply the handler. (expand_end_catch_block): Likewise. From-SVN: r16895
This commit is contained in:
parent
9fb82071ff
commit
de35891e21
@ -1,3 +1,17 @@
|
||||
Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com>
|
||||
|
||||
* class.c (prepare_fresh_vtable): Enable even more complex MI
|
||||
vtable names.
|
||||
|
||||
Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* exception.cc (__check_eh_spec): Optimize a bit.
|
||||
|
||||
* exception.cc (__cp_pop_exception): Lose handler arg.
|
||||
* except.c (do_pop_exception): Likewise.
|
||||
(push_eh_cleanup): Let the cleanup mechanism supply the handler.
|
||||
(expand_end_catch_block): Likewise.
|
||||
|
||||
Fri Nov 28 01:58:14 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* pt.c (check_explicit_specialization): Complain about using a
|
||||
|
@ -784,7 +784,8 @@ prepare_fresh_vtable (binfo, for_type)
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type) + 1 + i);
|
||||
char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type)
|
||||
+ 1 + i);
|
||||
char *new_buf2;
|
||||
|
||||
sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
|
||||
@ -808,8 +809,34 @@ prepare_fresh_vtable (binfo, for_type)
|
||||
|
||||
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));
|
||||
|
||||
/* We better not run out of stuff to make it unique. */
|
||||
my_friendly_assert (for_type != basetype, 369);
|
||||
if (for_type == basetype)
|
||||
{
|
||||
/* If we run out of basetypes in the path, we have already
|
||||
found created a vtable with that name before, we now
|
||||
resort to tacking on _%d to distinguish them. */
|
||||
int j = 2;
|
||||
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;
|
||||
buf1 = (char *) alloca (i);
|
||||
do {
|
||||
sprintf (buf1, "%s%c%s%c%d",
|
||||
TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,
|
||||
buf2, joiner, j);
|
||||
buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
|
||||
+ strlen (buf1) + 1);
|
||||
sprintf (buf, VTABLE_NAME_FORMAT, buf1);
|
||||
name = get_identifier (buf);
|
||||
|
||||
/* If this name doesn't clash, then we can use it,
|
||||
otherwise we add something different to the name until
|
||||
it is unique. */
|
||||
} while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));
|
||||
|
||||
/* Hey, they really like MI don't they? Increase the 3
|
||||
above to 6, and the 999 to 999999. :-) */
|
||||
my_friendly_assert (j <= 999, 369);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
|
||||
new_buf2 = (char *) alloca (i);
|
||||
|
@ -440,8 +440,7 @@ build_eh_type (exp)
|
||||
if it is, it avoids destroying the object on rethrow. */
|
||||
|
||||
static tree
|
||||
do_pop_exception (handler)
|
||||
tree handler;
|
||||
do_pop_exception ()
|
||||
{
|
||||
tree fn, cleanup;
|
||||
fn = get_identifier ("__cp_pop_exception");
|
||||
@ -456,9 +455,7 @@ do_pop_exception (handler)
|
||||
fn = build_lang_decl
|
||||
(FUNCTION_DECL, fn,
|
||||
build_function_type (void_type_node, tree_cons
|
||||
(NULL_TREE, ptr_type_node, tree_cons
|
||||
(NULL_TREE, boolean_type_node,
|
||||
void_list_node))));
|
||||
(NULL_TREE, ptr_type_node, void_list_node)));
|
||||
DECL_EXTERNAL (fn) = 1;
|
||||
TREE_PUBLIC (fn) = 1;
|
||||
DECL_ARTIFICIAL (fn) = 1;
|
||||
@ -471,8 +468,7 @@ do_pop_exception (handler)
|
||||
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
|
||||
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
|
||||
cleanup = build_function_call (fn, expr_tree_cons
|
||||
(NULL_TREE, cleanup, expr_tree_cons
|
||||
(NULL_TREE, handler, NULL_TREE)));
|
||||
(NULL_TREE, cleanup, NULL_TREE));
|
||||
return cleanup;
|
||||
}
|
||||
|
||||
@ -481,17 +477,15 @@ do_pop_exception (handler)
|
||||
static void
|
||||
push_eh_cleanup ()
|
||||
{
|
||||
/* All cleanups must last longer than normal. */
|
||||
int yes = suspend_momentary ();
|
||||
expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node));
|
||||
resume_momentary (yes);
|
||||
int 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 ();
|
||||
yes = suspend_momentary ();
|
||||
/* All cleanups must last longer than normal. */
|
||||
expand_decl_cleanup (NULL_TREE, do_pop_exception ());
|
||||
resume_momentary (yes);
|
||||
}
|
||||
|
||||
/* call this to start a catch block. Typename is the typename, and identifier
|
||||
@ -657,9 +651,6 @@ expand_end_catch_block ()
|
||||
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||
poplevel (kept_level_p (), 1, 0);
|
||||
|
||||
/* Matches push_eh_cleanup. */
|
||||
expand_eh_region_end (do_pop_exception (boolean_true_node));
|
||||
|
||||
/* Cleanup the EH object. */
|
||||
expand_end_bindings (getdecls (), kept_level_p (), 0);
|
||||
poplevel (kept_level_p (), 1, 0);
|
||||
|
@ -126,17 +126,20 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
|
||||
|
||||
/* Compiler hook to pop an exception that has been finalized. Used by
|
||||
push_eh_cleanup(). P is the info for the exception caught by the
|
||||
current catch block, and HANDLER determines if we've been called from
|
||||
an exception handler; if so, we avoid destroying the object on rethrow. */
|
||||
current catch block. */
|
||||
|
||||
extern "C" void
|
||||
__cp_pop_exception (cp_eh_info *p, bool handler)
|
||||
__cp_pop_exception (cp_eh_info *p)
|
||||
{
|
||||
cp_eh_info **q = &__eh_info;
|
||||
|
||||
--p->handlers;
|
||||
|
||||
if (p->handlers > 0 || (handler && p == *q))
|
||||
/* Don't really pop if there are still active handlers for our exception,
|
||||
or if our exception is being rethrown (i.e. if the active exception is
|
||||
our exception and it is uncaught). */
|
||||
if (p->handlers != 0
|
||||
|| (p == *q && !p->caught))
|
||||
return;
|
||||
|
||||
for (; *q; q = &((*q)->next))
|
||||
@ -198,11 +201,14 @@ __check_eh_spec (int n, const void **spec)
|
||||
catch (...)
|
||||
{
|
||||
// __exception_info is an artificial var pushed into each catch block.
|
||||
p = __exception_info;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (p != __exception_info)
|
||||
{
|
||||
if (__throw_type_match_rtti (spec[i], p->type, p->value))
|
||||
throw;
|
||||
p = __exception_info;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (__throw_type_match_rtti (spec[i], p->type, p->value))
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const type_info &bad_exc = typeid (bad_exception);
|
||||
|
Loading…
Reference in New Issue
Block a user