OSDN Git Service

86th Cygnus<->FSF quick merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 May 1996 18:54:10 +0000 (18:54 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 7 May 1996 18:54:10 +0000 (18:54 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11952 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/gxxint.texi

index 4c00b1e..f64da63 100644 (file)
@@ -1,3 +1,41 @@
+Mon May  6 01:23:32 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c (finish_file): Don't try to emit functions that haven't
+       been compiled.
+
+Fri May  3 09:30:13 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c (finish_vtable_vardecl): Oops.
+
+       * decl.c (maybe_push_to_top_level): Do save previous_class_*.
+       Also store the bindings from previous_class_values.
+       (pop_from_top_level): Restore them.
+
+Thu May  2 21:56:49 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl2.c (finish_vtable_vardecl): Only write out vtable if its
+       symbol has been referenced.
+       (finish_file): Re-join synthesis/vtable loop with inline emission
+       loop, disable inlining when an inline is output.
+
+Thu May  2 17:20:02 1996  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (init_exception_processing): Setup saved_in_catch.
+       (push_eh_cleanup): Reset __eh_in_catch.
+       (expand_start_catch_block): Set __eh_in_catch.
+
+Thu May  2 16:21:17 1996  Mike Stump  <mrs@cygnus.com>
+
+       * except.c (push_eh_cleanup): Add tracking for whether or not we
+       have an active exception object.
+       (expand_builtin_throw): Use it to make sure a rethrow without an
+       exception object is caught.
+
+Thu May  2 11:26:41 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * decl.c (maybe_push_to_top_level): Clear out class-level bindings
+       cache.
+
 Wed May  1 11:26:52 1996  Jason Merrill  <jason@yorick.cygnus.com>
 
        * decl2.c (finish_file): Also use sentries for vars with
index 638db4c..c55d904 100644 (file)
@@ -2540,18 +2540,11 @@ build_method_call (instance, name, parms, basetype_path, flags)
                   IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function)));
 
   {
-    int is_constructor;
-    
-    if (TREE_CODE (function) == FUNCTION_DECL)
-      {
-       is_constructor = DECL_CONSTRUCTOR_P (function);
-       function = default_conversion (function);
-      }
-    else
-      {
-       is_constructor = 0;
-       function = default_conversion (function);
-      }
+    int is_constructor
+      = TREE_CODE (function) == FUNCTION_DECL
+       && DECL_CONSTRUCTOR_P (function);
+
+    function = default_conversion (function);
 
     result = build_nt (CALL_EXPR, function, parms, NULL_TREE);
 
index a4b8c80..83ed195 100644 (file)
@@ -1747,9 +1747,9 @@ struct saved_scope {
   int minimal_parse_mode;
   tree last_function_parms;
   tree template_parms;
+  tree previous_class_type, previous_class_values;
 };
 static struct saved_scope *current_saved_scope;
-extern tree prev_class_type;
 
 tree
 store_bindings (names, old_bindings)
@@ -1803,6 +1803,9 @@ maybe_push_to_top_level (pseudo)
   struct binding_level *b = inner_binding_level;
   tree old_bindings = NULL_TREE;
 
+  if (previous_class_type)
+    old_bindings = store_bindings (previous_class_values, old_bindings);
+
   /* Have to include global_binding_level, because class-level decls
      aren't listed anywhere useful.  */
   for (; b; b = b->level_chain)
@@ -1840,6 +1843,8 @@ maybe_push_to_top_level (pseudo)
   s->minimal_parse_mode = minimal_parse_mode;
   s->last_function_parms = last_function_parms;
   s->template_parms = current_template_parms;
+  s->previous_class_type = previous_class_type;
+  s->previous_class_values = previous_class_values;
   current_class_name = current_class_type = NULL_TREE;
   current_function_decl = NULL_TREE;
   class_binding_level = (struct binding_level *)0;
@@ -1850,6 +1855,7 @@ maybe_push_to_top_level (pseudo)
   strict_prototype = strict_prototypes_lang_cplusplus;
   named_labels = NULL_TREE;
   minimal_parse_mode = 0;
+  previous_class_type = previous_class_values = NULL_TREE;
   if (!pseudo)
     current_template_parms = NULL_TREE;
 
@@ -1913,6 +1919,8 @@ pop_from_top_level ()
   minimal_parse_mode = s->minimal_parse_mode;
   last_function_parms = s->last_function_parms;
   current_template_parms = s->template_parms;
+  previous_class_type = s->previous_class_type;
+  previous_class_values = s->previous_class_values;
 
   free (s);
 }
@@ -5839,12 +5847,10 @@ start_decl (declarator, declspecs, initialized, raises)
 
 #if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
   /* Tell the back-end to use or not use .common as appropriate.  If we say
-     -fconserve-space, we want this to save space, at the expense of wrong
-     semantics.  If we say -fno-conserve-space, we want this to produce
-     errors about redefs; to do this we force variables into the data
-     segment.  Common storage is okay for non-public uninitialized data;
-     the linker can't match it with storage from other files, and we may
-     save some disk space.  */
+     -fconserve-space, we want this to save .data space, at the expense of
+     wrong semantics.  If we say -fno-conserve-space, we want this to
+     produce errors about redefs; to do this we force variables into the
+     data segment.  */
   DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
 #endif
 
index 49011d6..667d65b 100644 (file)
@@ -2591,7 +2591,9 @@ finish_vtable_vardecl (prev, vars)
      tree prev, vars;
 {
   if (write_virtuals >= 0
-      && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))
+      && ! DECL_EXTERNAL (vars)
+      && ((TREE_PUBLIC (vars) && ! DECL_WEAK (vars) && ! DECL_ONE_ONLY (vars))
+         || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)))
       && ! TREE_ASM_WRITTEN (vars))
     {
       /* Write it out.  */
@@ -2630,7 +2632,7 @@ finish_vtable_vardecl (prev, vars)
       rest_of_decl_compilation (vars, NULL_PTR, 1, 1);
       return 1;
     }
-  else if (! TREE_USED (vars))
+  else if (! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)))
     /* We don't know what to do with this one yet.  */
     return 0;
 
@@ -3233,30 +3235,17 @@ finish_file ()
                reconsider = 1;
              }
 
+           /* Catch new template instantiations.  */
            if (decl != TREE_VALUE (*p))
-             ;
-           else if (TREE_ASM_WRITTEN (decl)
-                    || (DECL_SAVED_INSNS (decl) == 0
-                        && ! DECL_ARTIFICIAL (decl)))
-             *p = TREE_CHAIN (*p);
-           else
-             p = &TREE_CHAIN (*p);
-         }
-      }
+             continue;
 
-    reconsider = 1;            /* More may be referenced; check again */
-    while (reconsider)
-      {
-       tree *p = &saved_inlines;
-       reconsider = 0;
-
-       while (*p)
-         {
-           tree decl = TREE_VALUE (*p);
-
-           if (TREE_ASM_WRITTEN (decl) || DECL_SAVED_INSNS (decl) == 0)
+           if (TREE_ASM_WRITTEN (decl)
+               || (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl)))
              *p = TREE_CHAIN (*p);
-           else if ((TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+           else if (DECL_INITIAL (decl) == 0)
+             p = &TREE_CHAIN (*p);
+           else if ((TREE_PUBLIC (decl) && ! DECL_WEAK (decl)
+                     && ! DECL_ONE_ONLY (decl))
                     || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
                     || flag_keep_inline_functions)
              {
@@ -3264,6 +3253,11 @@ finish_file ()
                  {
                    DECL_EXTERNAL (decl) = 0;
                    reconsider = 1;
+                   /* We can't inline this function after it's been
+                       emitted, so just disable inlining.  We want a
+                       variant of output_inline_function that doesn't
+                       prevent subsequent integration... */
+                   flag_no_inline = 1;
                    temporary_allocation ();
                    output_inline_function (decl);
                    permanent_allocation (1);
index 41742a7..b530a3b 100644 (file)
@@ -326,6 +326,8 @@ static tree saved_throw_type;
 static tree saved_throw_value;
 /* Holds the cleanup for the value being thrown.  */
 static tree saved_cleanup;
+/* Indicates if we are in a catch clause.  */
+static tree saved_in_catch;
 
 static int throw_used;
 
@@ -754,6 +756,13 @@ init_exception_processing ()
   DECL_COMMON (d) = 1;
   cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
   saved_cleanup = lookup_name (get_identifier ("__eh_cleanup"), 0);
+
+  declspecs = tree_cons (NULL_TREE, get_identifier ("bool"), NULL_TREE);
+  d = get_identifier ("__eh_in_catch");
+  d = start_decl (d, declspecs, 0, NULL_TREE);
+  DECL_COMMON (d) = 1;
+  cp_finish_decl (d, NULL_TREE, NULL_TREE, 1, 0);
+  saved_in_catch = lookup_name (get_identifier ("__eh_in_catch"), 0);
 }
 
 /* call this to begin a block of unwind protection (ie: when an object is
@@ -950,6 +959,9 @@ push_eh_cleanup ()
 
   /* Arrange to do a dynamically scoped cleanup upon exit from this region.  */
   tree cleanup = build_function_call (saved_cleanup, NULL_TREE);
+  cleanup = build (COMPOUND_EXPR, void_type_node, cleanup,
+                  build_modify_expr (saved_in_catch, NOP_EXPR,
+                                     build_modify_expr (saved_throw_type, NOP_EXPR, integer_zero_node)));
   cp_expand_decl_cleanup (NULL_TREE, cleanup);
 
   resume_momentary (yes);
@@ -1045,6 +1057,7 @@ expand_start_catch_block (declspecs, declarator)
       /* Fall into the catch all section. */
     }
 
+  emit_move_insn (DECL_RTL (saved_in_catch), const1_rtx);
   /* This is the starting of something to protect.  */
   emit_label (protect_label_rtx);
 
@@ -1327,6 +1340,13 @@ expand_builtin_throw ()
   top_of_loop = gen_label_rtx ();
   unwind_first = gen_label_rtx ();
 
+  /* These two can be frontend specific.  If wanted, they can go in
+     expand_throw. */
+  /* Do we have a valid object we are throwing? */
+  emit_cmp_insn (DECL_RTL (saved_throw_type), const0_rtx, EQ, NULL_RTX,
+                GET_MODE (DECL_RTL (saved_throw_type)), 0, 0);
+  emit_jump_insn (gen_beq (gotta_call_terminate));
+
   emit_jump (unwind_first);
 
   emit_label (top_of_loop);
@@ -1678,6 +1698,7 @@ expand_throw (exp)
        {
          rtx cleanup_insns;
          tree object;
+
          /* Make a copy of the thrown object.  WP 15.1.5  */
          exp = build_new (NULL_TREE, TREE_TYPE (exp),
                           build_tree_list (NULL_TREE, exp),
index 5fedd5a..69161f9 100644 (file)
@@ -1219,15 +1219,18 @@ All completely constructed temps and local variables are cleaned up in
 all unwinded scopes.  Completely constructed parts of partially
 constructed objects are cleaned up.  This includes partially built
 arrays.  Exception specifications are now handled.  Thrown objects are
-now cleaned up all the time.
+now cleaned up all the time.  We can now tell if we have an active
+exception being thrown or not (__eh_type != 0).  We use this to call
+terminate if someone does a throw; without there being an active
+exception object.  uncaught_exception () works.
 
 The below points out some flaws in g++'s exception handling, as it now
 stands.
 
 Only exact type matching or reference matching of throw types works when
--fno-rtti is used.  Only works on a SPARC (like Suns), i386, arm,
-rs6000, PowerPC, Alpha, mips, VAX, m68k and z8k machines.  Partial support
-is in for all other machines, but a stack unwinder called
+-fno-rtti is used.  Only works on a SPARC (like Suns), SPARClite, i386,
+arm, rs6000, PowerPC, Alpha, mips, VAX, m68k and z8k machines.  Partial
+support is in for all other machines, but a stack unwinder called
 __unwind_function has to be written, and added to libgcc2 for them.  The
 new EH code doesn't rely upon the __unwind_function for C++ code,
 instead it creates per function unwinders right inside the function,