+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
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,
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);
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");
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;
/* 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;
}
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
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);
/* 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))
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);