Commit de35891e by Jason Merrill

[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
parent 9fb82071
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> Fri Nov 28 01:58:14 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (check_explicit_specialization): Complain about using a * pt.c (check_explicit_specialization): Complain about using a
......
...@@ -784,7 +784,8 @@ prepare_fresh_vtable (binfo, for_type) ...@@ -784,7 +784,8 @@ prepare_fresh_vtable (binfo, for_type)
while (1) 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; char *new_buf2;
sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner, sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
...@@ -808,8 +809,34 @@ prepare_fresh_vtable (binfo, for_type) ...@@ -808,8 +809,34 @@ prepare_fresh_vtable (binfo, for_type)
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path)); basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));
/* We better not run out of stuff to make it unique. */ if (for_type == basetype)
my_friendly_assert (for_type != basetype, 369); {
/* 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; i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
new_buf2 = (char *) alloca (i); new_buf2 = (char *) alloca (i);
......
...@@ -440,8 +440,7 @@ build_eh_type (exp) ...@@ -440,8 +440,7 @@ build_eh_type (exp)
if it is, it avoids destroying the object on rethrow. */ if it is, it avoids destroying the object on rethrow. */
static tree static tree
do_pop_exception (handler) do_pop_exception ()
tree handler;
{ {
tree fn, cleanup; tree fn, cleanup;
fn = get_identifier ("__cp_pop_exception"); fn = get_identifier ("__cp_pop_exception");
...@@ -456,9 +455,7 @@ do_pop_exception (handler) ...@@ -456,9 +455,7 @@ do_pop_exception (handler)
fn = build_lang_decl fn = build_lang_decl
(FUNCTION_DECL, fn, (FUNCTION_DECL, fn,
build_function_type (void_type_node, tree_cons build_function_type (void_type_node, tree_cons
(NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node)));
(NULL_TREE, boolean_type_node,
void_list_node))));
DECL_EXTERNAL (fn) = 1; DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1; TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1; DECL_ARTIFICIAL (fn) = 1;
...@@ -471,8 +468,7 @@ do_pop_exception (handler) ...@@ -471,8 +468,7 @@ do_pop_exception (handler)
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */ /* Arrange to do a dynamically scoped cleanup upon exit from this region. */
cleanup = lookup_name (get_identifier ("__exception_info"), 0); cleanup = lookup_name (get_identifier ("__exception_info"), 0);
cleanup = build_function_call (fn, expr_tree_cons cleanup = build_function_call (fn, expr_tree_cons
(NULL_TREE, cleanup, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE));
(NULL_TREE, handler, NULL_TREE)));
return cleanup; return cleanup;
} }
...@@ -481,17 +477,15 @@ do_pop_exception (handler) ...@@ -481,17 +477,15 @@ do_pop_exception (handler)
static void static void
push_eh_cleanup () push_eh_cleanup ()
{ {
/* All cleanups must last longer than normal. */ int yes;
int yes = suspend_momentary ();
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), expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1),
const0_rtx, VOIDmode, EXPAND_NORMAL); const0_rtx, VOIDmode, EXPAND_NORMAL);
/* We don't destroy the exception object on rethrow, so we can't use yes = suspend_momentary ();
the normal cleanup mechanism for it. */ /* All cleanups must last longer than normal. */
expand_eh_region_start (); expand_decl_cleanup (NULL_TREE, do_pop_exception ());
resume_momentary (yes);
} }
/* call this to start a catch block. Typename is the typename, and identifier /* call this to start a catch block. Typename is the typename, and identifier
...@@ -657,9 +651,6 @@ expand_end_catch_block () ...@@ -657,9 +651,6 @@ expand_end_catch_block ()
expand_end_bindings (getdecls (), kept_level_p (), 0); expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 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. */ /* Cleanup the EH object. */
expand_end_bindings (getdecls (), kept_level_p (), 0); expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 0); poplevel (kept_level_p (), 1, 0);
......
...@@ -126,17 +126,20 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) ...@@ -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 /* 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 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 current catch block. */
an exception handler; if so, we avoid destroying the object on rethrow. */
extern "C" void 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; cp_eh_info **q = &__eh_info;
--p->handlers; --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; return;
for (; *q; q = &((*q)->next)) for (; *q; q = &((*q)->next))
...@@ -198,11 +201,14 @@ __check_eh_spec (int n, const void **spec) ...@@ -198,11 +201,14 @@ __check_eh_spec (int n, const void **spec)
catch (...) catch (...)
{ {
// __exception_info is an artificial var pushed into each catch block. // __exception_info is an artificial var pushed into each catch block.
p = __exception_info; if (p != __exception_info)
for (int i = 0; i < n; ++i)
{ {
if (__throw_type_match_rtti (spec[i], p->type, p->value)) p = __exception_info;
throw; 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); const type_info &bad_exc = typeid (bad_exception);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment