[multiple changes]
authorJason Merrill <jason@gcc.gnu.org>
Wed, 3 Dec 1997 03:37:17 +0000 (22:37 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 3 Dec 1997 03:37:17 +0000 (22:37 -0500)
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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/except.c
gcc/cp/exception.cc

index 7ceb75a00d56aff9f8c17c5d39239f880f5ce167..a91d9e30deb834e76da1677fb277f2cf23e7b5e5 100644 (file)
@@ -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 
index d021fae7dbd0d7d918fc416345a8be46ef29bb3f..9eb619094f186842c887eda60738fa93d2b5d1de 100644 (file)
@@ -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);
index d72c04a7e00606613b0c6ac68aace78e38da9ec5..6e7c876467f617e05a56d5348ee77963a0c865d1 100644 (file)
@@ -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);
index 9c876700574390380296641c4644993fe0f26c46..aa5a46e2b266d8f333c2188a8c3f5468ad2012c7 100644 (file)
@@ -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);