aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2002-01-17 08:07:27 -0500
committerJason Merrill <jason@gcc.gnu.org>2002-01-17 08:07:27 -0500
commitcdd2559cec98c587afc243a2850a329861487013 (patch)
treeb2c6bd1d58c0b1dcac0f229dacc4f67ceb858610 /gcc
parentad6b1795b1171d94d24abb31dfe515d311531794 (diff)
downloadgcc-cdd2559cec98c587afc243a2850a329861487013.zip
gcc-cdd2559cec98c587afc243a2850a329861487013.tar.gz
gcc-cdd2559cec98c587afc243a2850a329861487013.tar.bz2
decl.c (begin_constructor_body, [...]): New fns.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl.c79
-rw-r--r--gcc/cp/init.c8
-rw-r--r--gcc/cp/method.c8
-rw-r--r--gcc/cp/parse.y3
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/semantics.c83
8 files changed, 106 insertions, 96 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 793af6d..abb6417 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 88b4cdb..99f7bf7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ed163fd..2a4eaea 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index f159f44..3aaedaf 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 288b897..8cb30a8 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 64f3dc1..31fc850 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -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);
}
;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e75b153..0f0d93b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b8a09fd..eade700 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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. */