init.c (expand_aggr_vbase_init): Rename to construct_virtual_bases.

* init.c (expand_aggr_vbase_init): Rename to
	construct_virtual_bases.  Conditionalize construction here,
	rather than ...
	(emit_base_init): Here.

From-SVN: r27701
This commit is contained in:
Mark Mitchell 1999-06-22 07:21:50 +00:00 committed by Mark Mitchell
parent 90fb0c2498
commit 69f00f0151
3 changed files with 72 additions and 31 deletions

View file

@ -1,3 +1,10 @@
1999-06-21 Mark Mitchell <mark@codesourcery.com>
* init.c (expand_aggr_vbase_init): Rename to
construct_virtual_bases. Conditionalize construction here,
rather than ...
(emit_base_init): Here.
1999-06-19 Mark Mitchell <mark@codesourcery.com>
* semantics.c (finish_asm_statement): Apply decay conversions to

View file

@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA. */
tree current_base_init_list, current_member_init_list;
static void expand_aggr_vbase_init_1 PROTO((tree, tree, tree, tree));
static void expand_aggr_vbase_init PROTO((tree, tree, tree, tree, tree));
static void construct_virtual_bases PROTO((tree, tree, tree, tree, tree));
static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int));
static void expand_default_init PROTO((tree, tree, tree, tree, int));
static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree,
@ -541,14 +541,13 @@ emit_base_init (t, immediately)
sort_base_init (t, &rbase_init_list, &vbase_init_list);
current_base_init_list = NULL_TREE;
/* First, initialize the virtual base classes, if we are
constructing the most-derived object. */
if (TYPE_USES_VIRTUAL_BASECLASSES (t))
{
tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
expand_start_cond (first_arg, 0);
expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr,
vbase_init_list, first_arg);
expand_end_cond ();
construct_virtual_bases (t, current_class_ref, current_class_ptr,
vbase_init_list, first_arg);
}
/* Now, perform initialization of non-virtual base classes. */
@ -798,38 +797,60 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
free_temp_slots ();
}
/* Initialize this object's virtual base class pointers. This must be
done only at the top-level of the object being constructed.
INIT_LIST is list of initialization for constructor to perform. */
/* Construct the virtual base-classes of THIS_REF (whose address is
THIS_PTR). The object has the indicated TYPE. The construction
actually takes place only if FLAG is non-zero. INIT_LIST is list
of initialization for constructor to perform. */
static void
expand_aggr_vbase_init (binfo, exp, addr, init_list, flag)
tree binfo;
tree exp;
tree addr;
construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
tree type;
tree this_ref;
tree this_ptr;
tree init_list;
tree flag;
{
tree type = BINFO_TYPE (binfo);
tree vbases;
tree result;
if (TYPE_USES_VIRTUAL_BASECLASSES (type))
/* If there are no virtual baseclasses, we shouldn't even be here. */
my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621);
/* First set the pointers in our object that tell us where to find
our virtual baseclasses. */
expand_start_cond (flag, 0);
result = init_vbase_pointers (type, this_ptr);
if (result)
expand_expr_stmt (build_compound_expr (result));
expand_end_cond ();
/* Now, run through the baseclasses, initializing each. */
for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
vbases = TREE_CHAIN (vbases))
{
tree result = init_vbase_pointers (type, addr);
tree vbases;
if (result)
expand_expr_stmt (build_compound_expr (result));
for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
vbases = TREE_CHAIN (vbases))
{
tree tmp = purpose_member (vbases, result);
expand_aggr_vbase_init_1 (vbases, exp,
TREE_OPERAND (TREE_VALUE (tmp), 0),
init_list);
expand_cleanup_for_base (vbases, flag);
}
tree tmp = purpose_member (vbases, result);
/* If there are virtual base classes with destructors, we need to
emit cleanups to destroy them if an exception is thrown during
the construction process. These exception regions (i.e., the
period during which the cleanups must occur) begin from the time
the construction is complete to the end of the function. If we
create a conditional block in which to initialize the
base-classes, then the cleanup region for the virtual base begins
inside a block, and ends outside of that block. This situation
confuses the sjlj exception-handling code. Therefore, we do not
create a single conditional block, but one for each
initialization. (That way the cleanup regions always begin
in the outer block.) We trust the back-end to figure out
that the FLAG will not change across initializations, and
avoid doing multiple tests. */
expand_start_cond (flag, 0);
expand_aggr_vbase_init_1 (vbases, this_ref,
TREE_OPERAND (TREE_VALUE (tmp), 0),
init_list);
expand_end_cond ();
expand_cleanup_for_base (vbases, flag);
}
}

View file

@ -0,0 +1,13 @@
// Build don't link:
// Special g++ Options: -fsjlj-exceptions
// Origin: Donn Terry <donn@interix.com>
struct ios {
virtual ~ios();
};
struct fstreambase : virtual public ios {
fstreambase();
};
fstreambase::fstreambase()
{
}