decl.c (begin_constructor_body, [...]): New fns.
authorJason Merrill <jason@redhat.com>
Thu, 17 Jan 2002 13:07:27 +0000 (08:07 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 17 Jan 2002 13:07:27 +0000 (08:07 -0500)
        * decl.c (begin_constructor_body, begin_destructor_body): New fns.
        (begin_function_body): Call them and keep_next_level.
        * init.c (emit_base_init): Call keep_next_level.
        * semantics.c (setup_vtbl_ptr): Lose.
        * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
        (vtbls_set_up_p): Lose.
        * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
        * method.c (do_build_copy_constructor): Likewise.
        (synthesize_method): Call finish_mem_initializers.
        * parse.y (nodecls): Likewise.

From-SVN: r48948

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/semantics.c

index 793af6d5367ef697c22f9329b1e2d49c5800bddd..abb6417663cfcf42d85aa43a6878f9b1b1765c78 100644 (file)
@@ -1,4 +1,15 @@
-2002-01-16  Jason Merrill  <jason@redhat.com>
+2002-01-17  Jason Merrill  <jason@redhat.com>
+
+       * decl.c (begin_constructor_body, begin_destructor_body): New fns.
+       (begin_function_body): Call them and keep_next_level.
+       * init.c (emit_base_init): Call keep_next_level.
+       * semantics.c (setup_vtbl_ptr): Lose.
+       * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
+       (vtbls_set_up_p): Lose.
+       * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
+       * method.c (do_build_copy_constructor): Likewise.
+       (synthesize_method): Call finish_mem_initializers.
+       * parse.y (nodecls): Likewise.
 
        * error.c (dump_type_suffix): Print the exception specs before
        recursing.
index 88b4cdbfd5065add19066313d8d1f073182eeb39..99f7bf71b7432c7b588f704ff7650321f6cb325c 100644 (file)
@@ -821,7 +821,6 @@ struct cp_language_function
   int returns_null;
   int in_function_try_handler;
   int x_expanding_p;
-  int vtbls_set_up_p;
 
   struct named_label_use_list *x_named_label_uses;
   struct named_label_list *x_named_labels;
@@ -881,11 +880,6 @@ struct cp_language_function
 
 #define current_function_returns_null cp_function_chain->returns_null
 
-/* Nonzero if we have already generated code to initialize virtual
-   function tables in this function.  */
-
-#define vtbls_set_up_p cp_function_chain->vtbls_set_up_p
-
 /* Non-zero if we should generate RTL for functions that we process.
    When this is zero, we just accumulate tree structure, without
    interacting with the back end.  */
index ed163fdece747b3f22e0de1a2767ea02f2dcc2fb..2a4eaeacb43a3ea7a7dce4ddd7422e508d19de59 100644 (file)
@@ -133,7 +133,9 @@ static void mark_lang_function PARAMS ((struct cp_language_function *));
 static void save_function_data PARAMS ((tree));
 static void check_function_type PARAMS ((tree, tree));
 static void destroy_local_var PARAMS ((tree));
+static void begin_constructor_body PARAMS ((void));
 static void finish_constructor_body PARAMS ((void));
+static void begin_destructor_body PARAMS ((void));
 static void finish_destructor_body PARAMS ((void));
 static tree create_array_type_for_decl PARAMS ((tree, tree, tree));
 static tree get_atexit_node PARAMS ((void));
@@ -13931,6 +13933,18 @@ save_function_data (decl)
     }
 }
 
+/* Add a note to mark the beginning of the main body of the constructor.
+   This is used to set up the data structures for the cleanup regions for
+   fully-constructed bases and members.  */
+
+static void
+begin_constructor_body ()
+{
+  tree ctor_stmt = build_stmt (CTOR_STMT);
+  CTOR_BEGIN_P (ctor_stmt) = 1;
+  add_stmt (ctor_stmt);
+}
+
 /* Add a note to mark the end of the main body of the constructor.  This is
    used to end the cleanup regions for fully-constructed bases and
    members.  */
@@ -13946,6 +13960,54 @@ finish_constructor_body ()
   add_stmt (build_stmt (CTOR_STMT));
 }
 
+/* Do all the processing for the beginning of a destructor; set up the
+   vtable pointers and cleanups for bases and members.  */
+
+static void
+begin_destructor_body ()
+{
+  tree if_stmt;
+  tree compound_stmt;
+
+  /* If the dtor is empty, and we know there is not any possible
+     way we could use any vtable entries, before they are possibly
+     set by a base class dtor, we don't have to setup the vtables,
+     as we know that any base class dtor will set up any vtables
+     it needs.  We avoid MI, because one base class dtor can do a
+     virtual dispatch to an overridden function that would need to
+     have a non-related vtable set up, we cannot avoid setting up
+     vtables in that case.  We could change this to see if there
+     is just one vtable.
+
+     ??? In the destructor for a class, the vtables are set
+     appropriately for that class.  There will be no non-related
+     vtables.  jason 2001-12-11.  */
+  if_stmt = begin_if_stmt ();
+
+  /* If it is not safe to avoid setting up the vtables, then
+     someone will change the condition to be boolean_true_node.  
+     (Actually, for now, we do not have code to set the condition
+     appropriately, so we just assume that we always need to
+     initialize the vtables.)  */
+  finish_if_stmt_cond (boolean_true_node, if_stmt);
+  current_vcalls_possible_p = &IF_COND (if_stmt);
+
+  compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+
+  /* Make all virtual function table pointers in non-virtual base
+     classes point to CURRENT_CLASS_TYPE's virtual function
+     tables.  */
+  initialize_vtbl_ptrs (current_class_ptr);
+
+  finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+  finish_then_clause (if_stmt);
+  finish_if_stmt ();
+
+  /* And insert cleanups for our bases and members so that they
+     will be properly destroyed if we throw.  */
+  push_base_cleanups ();
+}
+
 /* At the end of every destructor we generate code to delete the object if
    necessary.  Do that now.  */
 
@@ -13990,8 +14052,23 @@ finish_destructor_body ()
 tree
 begin_function_body ()
 {
-  tree stmt = begin_compound_stmt (0);
+  tree stmt;
+
+  stmt = begin_compound_stmt (0);
   COMPOUND_STMT_BODY_BLOCK (stmt) = 1;
+
+  if (processing_template_decl)
+    /* Do nothing now.  */;
+  else if (DECL_CONSTRUCTOR_P (current_function_decl))
+    begin_constructor_body ();
+  else if (DECL_DESTRUCTOR_P (current_function_decl))
+    begin_destructor_body ();
+
+  /* Always keep the BLOCK node associated with the outermost pair of
+     curly braces of a function.  These are needed for correct
+     operation of dwarfout.c.  */
+  keep_next_level (1);
+
   return stmt;
 }
 
index f159f446e36519678e02bf939d22841f510d59b5..3aaedafdd932c0b77f1c61523edde1cb71300c96 100644 (file)
@@ -668,6 +668,11 @@ emit_base_init (mem_init_list, base_init_list)
   int i;
   int n_baseclasses = BINFO_N_BASETYPES (t_binfo);
 
+  /* We did a keep_next_level (1) in begin_function_body.  We don't want
+     that to apply to any blocks generated for member initializers, so
+     clear it out.  */
+  keep_next_level (0);
+  
   mem_init_list = sort_member_init (t, mem_init_list);
   sort_base_init (t, base_init_list, &rbase_init_list, &vbase_init_list);
 
@@ -748,6 +753,9 @@ emit_base_init (mem_init_list, base_init_list)
       perform_member_init (member, init, from_init_list);
       mem_init_list = TREE_CHAIN (mem_init_list);
     }
+
+  /* And restore it.  */
+  keep_next_level (1);
 }
 
 /* Returns the address of the vtable (i.e., the value that should be
index 288b897c4b71ae17f4e8cd9f18899dcf1fb25ed7..8cb30a81de7d5a9580f656bd6cc0586150d1a5d0 100644 (file)
@@ -624,7 +624,7 @@ do_build_copy_constructor (fndecl)
        }
       member_init_list = nreverse (member_init_list);
       base_init_list = nreverse (base_init_list);
-      setup_vtbl_ptr (member_init_list, base_init_list);
+      emit_base_init (member_init_list, base_init_list);
     }
 }
 
@@ -770,15 +770,13 @@ synthesize_method (fndecl)
       do_build_assign_ref (fndecl);
       need_body = 0;
     }
-  else if (DECL_DESTRUCTOR_P (fndecl))
-    setup_vtbl_ptr (NULL_TREE, NULL_TREE);
-  else
+  else if (DECL_CONSTRUCTOR_P (fndecl))
     {
       tree arg_chain = FUNCTION_FIRST_USER_PARMTYPE (fndecl);
       if (arg_chain != void_list_node)
        do_build_copy_constructor (fndecl);
       else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
-       setup_vtbl_ptr (NULL_TREE, NULL_TREE);
+       finish_mem_initializers (NULL_TREE);
     }
 
   /* If we haven't yet generated the body of the function, just
index 64f3dc1a31e3d3f696b44848e1d5d9e671b3d78e..31fc850d601fbec87709c0c8d32318f4245026cb 100644 (file)
@@ -1765,7 +1765,8 @@ string:
 nodecls:
          /* empty */
                {
-                 setup_vtbl_ptr (NULL_TREE, NULL_TREE);
+                 if (DECL_CONSTRUCTOR_P (current_function_decl))
+                   finish_mem_initializers (NULL_TREE);
                }
        ;
 
index e75b153e0a7bb0e901ab33b374186698bd88c574..0f0d93bbdfce8bcded5217c2162619275556140b 100644 (file)
@@ -7274,7 +7274,7 @@ tsubst_expr (t, args, complain, in_decl)
          = tsubst_initializer_list (TREE_OPERAND (t, 0), args);
        base_init_list
          = tsubst_initializer_list (TREE_OPERAND (t, 1), args);
-       setup_vtbl_ptr (member_init_list, base_init_list);
+       emit_base_init (member_init_list, base_init_list);
        break;
       }
 
index b8a09fd899ad0e19e98da57423bc0a7600ca1de8..eade7004f2fc7bd2cf0ef27c098256a1134f33de 100644 (file)
@@ -1141,90 +1141,11 @@ finish_mem_initializers (init_list)
        }
     }
 
-  setup_vtbl_ptr (member_init_list, base_init_list);
-}
-
-/* Do the initialization work necessary at the beginning of a constructor
-   or destructor.  This means processing member initializers and setting
-   vtable pointers.
-
-   ??? The call to keep_next_level at the end applies to all functions, but
-   should probably go somewhere else.  */
-
-void
-setup_vtbl_ptr (member_init_list, base_init_list)
-     tree member_init_list;
-     tree base_init_list;
-{
-  my_friendly_assert (doing_semantic_analysis_p (), 19990919);
-  my_friendly_assert (!vtbls_set_up_p, 20011220);
-
   if (processing_template_decl)
     add_stmt (build_min_nt (CTOR_INITIALIZER,
                            member_init_list, base_init_list));
-  else if (DECL_CONSTRUCTOR_P (current_function_decl))
-    {
-      tree ctor_stmt;
-
-      /* Mark the beginning of the constructor.  */
-      ctor_stmt = build_stmt (CTOR_STMT);
-      CTOR_BEGIN_P (ctor_stmt) = 1;
-      add_stmt (ctor_stmt);
-         
-      /* And actually initialize the base-classes and members.  */
-      emit_base_init (member_init_list, base_init_list);
-    }
-  else if (DECL_DESTRUCTOR_P (current_function_decl))
-    {
-      tree if_stmt;
-      tree compound_stmt;
-
-      /* If the dtor is empty, and we know there is not any possible
-        way we could use any vtable entries, before they are possibly
-        set by a base class dtor, we don't have to setup the vtables,
-        as we know that any base class dtor will set up any vtables
-        it needs.  We avoid MI, because one base class dtor can do a
-        virtual dispatch to an overridden function that would need to
-        have a non-related vtable set up, we cannot avoid setting up
-        vtables in that case.  We could change this to see if there
-        is just one vtable.
-
-         ??? In the destructor for a class, the vtables are set
-         appropriately for that class.  There will be no non-related
-         vtables.  jason 2001-12-11.  */
-      if_stmt = begin_if_stmt ();
-
-      /* If it is not safe to avoid setting up the vtables, then
-        someone will change the condition to be boolean_true_node.  
-         (Actually, for now, we do not have code to set the condition
-        appropriately, so we just assume that we always need to
-        initialize the vtables.)  */
-      finish_if_stmt_cond (boolean_true_node, if_stmt);
-      current_vcalls_possible_p = &IF_COND (if_stmt);
-
-      compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
-
-      /* Make all virtual function table pointers in non-virtual base
-        classes point to CURRENT_CLASS_TYPE's virtual function
-        tables.  */
-      initialize_vtbl_ptrs (current_class_ptr);
-
-      finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
-      finish_then_clause (if_stmt);
-      finish_if_stmt ();
-
-      /* And insert cleanups for our bases and members so that they
-         will be properly destroyed if we throw.  */
-      push_base_cleanups ();
-    }
-
-  /* Always keep the BLOCK node associated with the outermost pair of
-     curly braces of a function.  These are needed for correct
-     operation of dwarfout.c.  */
-  keep_next_level (1);
-
-  /* The virtual function tables are set up now.  */
-  vtbls_set_up_p = 1;
+  else
+    emit_base_init (member_init_list, base_init_list);
 }
 
 /* Returns the stack of SCOPE_STMTs for the current function.  */