Commit a55583e9 by Mark Mitchell Committed by Mark Mitchell

Don't create a separate copy of virtual bases for the CLASSTYPE_VBASECLASSES list.

	Don't create a separate copy of virtual bases for the
	CLASSTYPE_VBASECLASSES list.
	* cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
	(BINFO_FOR_VBASE): Remove.
	(CANONICAL_BINFO): Adjust.
	(binfo_for_vbase): New function.
	* class.c (build_vbase_pointer_fields): Use binfo_for_vbase
	instead of BINFO_FOR_VBASE.
	(build_vbase_pointer): Likewise.
	(build_secondary_vtable): Likewise.
	(dfs_mark_primary_bases): Likewise.
	(mark_primary_bases): Likewise.
	(layout_nonempty_base_or_field): Likewise.
	(dfs_set_offset_for_shared_vbases): Likewise.
	(dfs_set_offset_for_unshared_vbases): Likewise.
	(layout_virtual_bases): Likewise.  Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	(dump_class_hierarchy_r): Use binfo_for_vbase
	instead of BINFO_FOR_VBASE.
	(dump_class_hierarchy): Likewise.
	(finish_vtbls): Likewise.
	(build_vtbl_initializer): Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	(build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
	* decl.c (finish_destructor_body): Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	* init.c (sort_base_init): Use binfo_for_vbase.
	(construct_virtual_bases): Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	(expand_member_init): Use binfo_for_vbase.
	(build_vbase_delete):  Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	* method.c (do_build_copy_constructor): Likewise.
	* rtti.c (get_base_offset): Use binfo_for_vbase.
	(expand_class_desc): Remove #if 0'd code.
	* search.c (struct vbase_info): Remove vbase_types.
	(get_base_distance):  Use binfo_for_vbase.
	(lookup_field_queue_p): Use CANONICAL_BINFO.
	(get_shared_vbase_if_not_primary): Use binfo_for_vbase.
	(get_pure_virtuals): Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	(dfs_find_vbases): Use binfo_for_vbase.
	(dfs_init_vbase_pointers): Likewise.
	(init_vbase_pointers): Don't initialize vi.vbase_types.
	(virtual_context): Use binfo_for_vbase.
	(fixup_all_virtual_upcast_offsets): Adjust for changes to the
	CLASSTYPE_VBASECLASSES list.
	(expand_indirect_vtbls_init): Simplify.
	(dfs_get_vbase_types): Don't replicate virtual bases.
	(find_vbase_instance): Use binfo_for_vbase.
	(binfo_for_vbase): New function.
	* typeck.c (get_delta_difference): Use binfo_for_vbase.

From-SVN: r34040
parent efc9bd41
2000-05-19 Mark Mitchell <mark@codesourcery.com>
Don't create a separate copy of virtual bases for the
CLASSTYPE_VBASECLASSES list.
* cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
(BINFO_FOR_VBASE): Remove.
(CANONICAL_BINFO): Adjust.
(binfo_for_vbase): New function.
* class.c (build_vbase_pointer_fields): Use binfo_for_vbase
instead of BINFO_FOR_VBASE.
(build_vbase_pointer): Likewise.
(build_secondary_vtable): Likewise.
(dfs_mark_primary_bases): Likewise.
(mark_primary_bases): Likewise.
(layout_nonempty_base_or_field): Likewise.
(dfs_set_offset_for_shared_vbases): Likewise.
(dfs_set_offset_for_unshared_vbases): Likewise.
(layout_virtual_bases): Likewise. Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
(dump_class_hierarchy_r): Use binfo_for_vbase
instead of BINFO_FOR_VBASE.
(dump_class_hierarchy): Likewise.
(finish_vtbls): Likewise.
(build_vtbl_initializer): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
(build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
* decl.c (finish_destructor_body): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
* init.c (sort_base_init): Use binfo_for_vbase.
(construct_virtual_bases): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
(expand_member_init): Use binfo_for_vbase.
(build_vbase_delete): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
* method.c (do_build_copy_constructor): Likewise.
* rtti.c (get_base_offset): Use binfo_for_vbase.
(expand_class_desc): Remove #if 0'd code.
* search.c (struct vbase_info): Remove vbase_types.
(get_base_distance): Use binfo_for_vbase.
(lookup_field_queue_p): Use CANONICAL_BINFO.
(get_shared_vbase_if_not_primary): Use binfo_for_vbase.
(get_pure_virtuals): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
(dfs_find_vbases): Use binfo_for_vbase.
(dfs_init_vbase_pointers): Likewise.
(init_vbase_pointers): Don't initialize vi.vbase_types.
(virtual_context): Use binfo_for_vbase.
(fixup_all_virtual_upcast_offsets): Adjust for changes to the
CLASSTYPE_VBASECLASSES list.
(expand_indirect_vtbls_init): Simplify.
(dfs_get_vbase_types): Don't replicate virtual bases.
(find_vbase_instance): Use binfo_for_vbase.
(binfo_for_vbase): New function.
* typeck.c (get_delta_difference): Use binfo_for_vbase.
2000-05-17 Mark Mitchell <mark@codesourcery.com> 2000-05-17 Mark Mitchell <mark@codesourcery.com>
* decl2.c (finish_anon_union): Generalize error messages to handle * decl2.c (finish_anon_union): Generalize error messages to handle
......
...@@ -246,7 +246,7 @@ build_vbase_pointer_fields (rli, empty_p) ...@@ -246,7 +246,7 @@ build_vbase_pointer_fields (rli, empty_p)
{ {
tree other_base_binfo = TREE_VEC_ELT (binfos, j); tree other_base_binfo = TREE_VEC_ELT (binfos, j);
if (! TREE_VIA_VIRTUAL (other_base_binfo) if (! TREE_VIA_VIRTUAL (other_base_binfo)
&& BINFO_FOR_VBASE (basetype, BINFO_TYPE (other_base_binfo))) && binfo_for_vbase (basetype, BINFO_TYPE (other_base_binfo)))
goto got_it; goto got_it;
} }
FORMAT_VBASE_NAME (name, basetype); FORMAT_VBASE_NAME (name, basetype);
...@@ -285,7 +285,7 @@ build_vbase_pointer (exp, type) ...@@ -285,7 +285,7 @@ build_vbase_pointer (exp, type)
/* Find the shared copy of TYPE; that's where the vtable offset /* Find the shared copy of TYPE; that's where the vtable offset
is recorded. */ is recorded. */
vbase = BINFO_FOR_VBASE (type, TREE_TYPE (exp)); vbase = binfo_for_vbase (type, TREE_TYPE (exp));
/* Find the virtual function table pointer. */ /* Find the virtual function table pointer. */
vbase_ptr = build_vfield_ref (exp, TREE_TYPE (exp)); vbase_ptr = build_vfield_ref (exp, TREE_TYPE (exp));
/* Compute the location where the offset will lie. */ /* Compute the location where the offset will lie. */
...@@ -841,7 +841,7 @@ build_secondary_vtable (binfo, for_type) ...@@ -841,7 +841,7 @@ build_secondary_vtable (binfo, for_type)
#endif #endif
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
my_friendly_assert (binfo == BINFO_FOR_VBASE (BINFO_TYPE (binfo), my_friendly_assert (binfo == binfo_for_vbase (BINFO_TYPE (binfo),
current_class_type), current_class_type),
170); 170);
...@@ -859,7 +859,7 @@ build_secondary_vtable (binfo, for_type) ...@@ -859,7 +859,7 @@ build_secondary_vtable (binfo, for_type)
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
{ {
tree binfo1 = BINFO_FOR_VBASE (BINFO_TYPE (binfo), for_type); tree binfo1 = binfo_for_vbase (BINFO_TYPE (binfo), for_type);
/* XXX - This should never happen, if it does, the caller should /* XXX - This should never happen, if it does, the caller should
ensure that the binfo is from for_type's binfos, not from any ensure that the binfo is from for_type's binfos, not from any
...@@ -1694,7 +1694,7 @@ dfs_mark_primary_bases (binfo, data) ...@@ -1694,7 +1694,7 @@ dfs_mark_primary_bases (binfo, data)
tree shared_binfo; tree shared_binfo;
shared_binfo shared_binfo
= BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data); = binfo_for_vbase (BINFO_TYPE (base_binfo), (tree) data);
/* If this virtual base is not already primary somewhere else in /* If this virtual base is not already primary somewhere else in
the hiearchy, then we'll be using this copy. */ the hiearchy, then we'll be using this copy. */
...@@ -1741,7 +1741,7 @@ mark_primary_bases (type) ...@@ -1741,7 +1741,7 @@ mark_primary_bases (type)
if (!TREE_VIA_VIRTUAL (vbases)) if (!TREE_VIA_VIRTUAL (vbases))
continue; continue;
vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbases), type); vbase = binfo_for_vbase (BINFO_TYPE (vbases), type);
if (BINFO_VBASE_PRIMARY_P (vbase)) if (BINFO_VBASE_PRIMARY_P (vbase))
/* This virtual base was already included in the hierarchy, so /* This virtual base was already included in the hierarchy, so
there's nothing to do here. */ there's nothing to do here. */
...@@ -3667,7 +3667,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v) ...@@ -3667,7 +3667,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
a data member. */ a data member. */
if (binfo && flag_new_abi && layout_conflict_p (binfo, v)) if (binfo && flag_new_abi && layout_conflict_p (binfo, v))
{ {
/* Undo the propogate_binfo_offsets call. */ /* Undo the propagate_binfo_offsets call. */
offset = size_diffop (size_zero_node, offset); offset = size_diffop (size_zero_node, offset);
propagate_binfo_offsets (binfo, convert (ssizetype, offset)); propagate_binfo_offsets (binfo, convert (ssizetype, offset));
...@@ -4376,7 +4376,7 @@ dfs_set_offset_for_shared_vbases (binfo, data) ...@@ -4376,7 +4376,7 @@ dfs_set_offset_for_shared_vbases (binfo, data)
/* Update the shared copy. */ /* Update the shared copy. */
tree shared_binfo; tree shared_binfo;
shared_binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), (tree) data); shared_binfo = binfo_for_vbase (BINFO_TYPE (binfo), (tree) data);
BINFO_OFFSET (shared_binfo) = BINFO_OFFSET (binfo); BINFO_OFFSET (shared_binfo) = BINFO_OFFSET (binfo);
} }
...@@ -4399,7 +4399,7 @@ dfs_set_offset_for_unshared_vbases (binfo, data) ...@@ -4399,7 +4399,7 @@ dfs_set_offset_for_unshared_vbases (binfo, data)
tree vbase; tree vbase;
tree offset; tree offset;
vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), t); vbase = binfo_for_vbase (BINFO_TYPE (binfo), t);
offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo)); offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
propagate_binfo_offsets (binfo, offset); propagate_binfo_offsets (binfo, offset);
} }
...@@ -4448,13 +4448,14 @@ layout_virtual_bases (t, base_offsets) ...@@ -4448,13 +4448,14 @@ layout_virtual_bases (t, base_offsets)
{ {
tree vbase; tree vbase;
if (!TREE_VIA_VIRTUAL (vbases))
continue;
if (flag_new_abi) if (flag_new_abi)
vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbases), t); {
if (!TREE_VIA_VIRTUAL (vbases))
continue;
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
}
else else
vbase = vbases; vbase = TREE_VALUE (vbases);
if (!BINFO_VBASE_PRIMARY_P (vbase)) if (!BINFO_VBASE_PRIMARY_P (vbase))
{ {
...@@ -4486,9 +4487,15 @@ layout_virtual_bases (t, base_offsets) ...@@ -4486,9 +4487,15 @@ layout_virtual_bases (t, base_offsets)
*base_offsets); *base_offsets);
else else
{ {
tree offset;
offset = ssize_int (CEIL (dsize, BITS_PER_UNIT));
offset = size_diffop (offset,
convert (ssizetype,
BINFO_OFFSET (vbase)));
/* And compute the offset of the virtual base. */ /* And compute the offset of the virtual base. */
propagate_binfo_offsets (vbase, propagate_binfo_offsets (vbase, offset);
ssize_int (CEIL (dsize, BITS_PER_UNIT)));
/* Every virtual baseclass takes a least a UNIT, so that /* Every virtual baseclass takes a least a UNIT, so that
we can take it's address and get something different we can take it's address and get something different
for each base. */ for each base. */
...@@ -4516,10 +4523,6 @@ layout_virtual_bases (t, base_offsets) ...@@ -4516,10 +4523,6 @@ layout_virtual_bases (t, base_offsets)
in get_base_distance depend on the BINFO_OFFSETs being set in get_base_distance depend on the BINFO_OFFSETs being set
correctly. */ correctly. */
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t); dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
for (vbases = CLASSTYPE_VBASECLASSES (t);
vbases;
vbases = TREE_CHAIN (vbases))
dfs_walk (vbases, dfs_set_offset_for_unshared_vbases, NULL, t);
/* If we had empty base classes that protruded beyond the end of the /* If we had empty base classes that protruded beyond the end of the
class, we didn't update DSIZE above; we were hoping to overlay class, we didn't update DSIZE above; we were hoping to overlay
...@@ -4542,7 +4545,7 @@ layout_virtual_bases (t, base_offsets) ...@@ -4542,7 +4545,7 @@ layout_virtual_bases (t, base_offsets)
vbases; vbases;
vbases = TREE_CHAIN (vbases)) vbases = TREE_CHAIN (vbases))
{ {
tree basetype = BINFO_TYPE (vbases); tree basetype = BINFO_TYPE (TREE_VALUE (vbases));
if (get_base_distance (basetype, t, 0, (tree*)0) == -2) if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
basetype, t); basetype, t);
...@@ -6334,7 +6337,7 @@ dump_class_hierarchy_r (t, binfo, indent) ...@@ -6334,7 +6337,7 @@ dump_class_hierarchy_r (t, binfo, indent)
fprintf (stderr, " virtual"); fprintf (stderr, " virtual");
if (BINFO_PRIMARY_MARKED_P (binfo) if (BINFO_PRIMARY_MARKED_P (binfo)
|| (TREE_VIA_VIRTUAL (binfo) || (TREE_VIA_VIRTUAL (binfo)
&& BINFO_VBASE_PRIMARY_P (BINFO_FOR_VBASE (BINFO_TYPE (binfo), && BINFO_VBASE_PRIMARY_P (binfo_for_vbase (BINFO_TYPE (binfo),
t)))) t))))
fprintf (stderr, " primary"); fprintf (stderr, " primary");
fprintf (stderr, "\n"); fprintf (stderr, "\n");
...@@ -6349,12 +6352,7 @@ void ...@@ -6349,12 +6352,7 @@ void
dump_class_hierarchy (t) dump_class_hierarchy (t)
tree t; tree t;
{ {
tree vbase;
dump_class_hierarchy_r (t, TYPE_BINFO (t), 0); dump_class_hierarchy_r (t, TYPE_BINFO (t), 0);
fprintf (stderr, "virtual bases\n");
for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; vbase = TREE_CHAIN (vbase))
dump_class_hierarchy_r (t, vbase, 0);
} }
/* Virtual function table initialization. */ /* Virtual function table initialization. */
...@@ -6383,7 +6381,7 @@ finish_vtbls (t) ...@@ -6383,7 +6381,7 @@ finish_vtbls (t)
{ {
if (!TREE_VIA_VIRTUAL (vbase)) if (!TREE_VIA_VIRTUAL (vbase))
continue; continue;
accumulate_vtbl_inits (BINFO_FOR_VBASE (BINFO_TYPE (vbase), t), accumulate_vtbl_inits (binfo_for_vbase (BINFO_TYPE (vbase), t),
list); list);
} }
...@@ -6554,7 +6552,7 @@ build_vtbl_initializer (binfo, original_binfo, t, rtti_binfo, ...@@ -6554,7 +6552,7 @@ build_vtbl_initializer (binfo, original_binfo, t, rtti_binfo,
for (vbase = CLASSTYPE_VBASECLASSES (t); for (vbase = CLASSTYPE_VBASECLASSES (t);
vbase; vbase;
vbase = TREE_CHAIN (vbase)) vbase = TREE_CHAIN (vbase))
CLEAR_BINFO_VTABLE_PATH_MARKED (vbase); CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
/* Add entries to the vtable for RTTI. */ /* Add entries to the vtable for RTTI. */
inits = chainon (inits, build_rtti_vtbl_entries (binfo, rtti_binfo)); inits = chainon (inits, build_rtti_vtbl_entries (binfo, rtti_binfo));
...@@ -6673,7 +6671,7 @@ build_vbase_offset_vtbl_entries (binfo, vod) ...@@ -6673,7 +6671,7 @@ build_vbase_offset_vtbl_entries (binfo, vod)
/* Find the instance of this virtual base in the complete /* Find the instance of this virtual base in the complete
object. */ object. */
b = BINFO_FOR_VBASE (BINFO_TYPE (vbase), t); b = binfo_for_vbase (BINFO_TYPE (vbase), t);
/* If we've already got an offset for this virtual base, we /* If we've already got an offset for this virtual base, we
don't need another one. */ don't need another one. */
...@@ -6694,7 +6692,7 @@ build_vbase_offset_vtbl_entries (binfo, vod) ...@@ -6694,7 +6692,7 @@ build_vbase_offset_vtbl_entries (binfo, vod)
tree orig_vbase; tree orig_vbase;
/* Find the instance of this virtual base in the type of BINFO. */ /* Find the instance of this virtual base in the type of BINFO. */
orig_vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbase), orig_vbase = binfo_for_vbase (BINFO_TYPE (vbase),
BINFO_TYPE (binfo)); BINFO_TYPE (binfo));
/* The vbase offset had better be the same. */ /* The vbase offset had better be the same. */
......
...@@ -1598,34 +1598,15 @@ struct lang_type ...@@ -1598,34 +1598,15 @@ struct lang_type
/* A chain of BINFOs for the direct and indirect virtual base classes /* A chain of BINFOs for the direct and indirect virtual base classes
that this type uses in a post-order depth-first left-to-right that this type uses in a post-order depth-first left-to-right
order. (In other words, these bases appear in the order that they order. (In other words, these bases appear in the order that they
should be initialized.) should be initialized.) */
These BINFOs are distinct from those in the TYPE_BINFO hierarchy.
So, given:
struct A {};
struct B : public A {};
struct C : virtual public B {};
struct D : virtual public B {};
struct E : public C, public D {};
there will be two copies of `A' and `B' in the TYPE_BINFO hierarchy
for `E'. On the CLASSTYPE_VBASECLASSES list, there will be just
one copy of `B' (distinct from the other two) with its own copy of `A'
(also distinct from the copies in the TYPE_BINFO hierarchy.) */
#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases) #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
/* The BINFO (if any) for the virtual baseclass T of the class C from
the CLASSTYPE_VBASECLASSES list. */
#define BINFO_FOR_VBASE(T, C) \
(binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
/* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
BINFO_FOR_VBASE. C is the most derived class for the hierarchy binfo_for_vbase. C is the most derived class for the hierarchy
containing BINFO. */ containing BINFO. */
#define CANONICAL_BINFO(BINFO, C) \ #define CANONICAL_BINFO(BINFO, C) \
(TREE_VIA_VIRTUAL (BINFO) \ (TREE_VIA_VIRTUAL (BINFO) \
? BINFO_FOR_VBASE (BINFO_TYPE (BINFO), C) \ ? binfo_for_vbase (BINFO_TYPE (BINFO), C) \
: BINFO) : BINFO)
/* Number of direct baseclasses of NODE. */ /* Number of direct baseclasses of NODE. */
...@@ -1718,9 +1699,7 @@ struct lang_type ...@@ -1718,9 +1699,7 @@ struct lang_type
for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
D. In tree.h, this pointer is described as pointing in other D. In tree.h, this pointer is described as pointing in other
direction. There is a different BINFO for each path to a virtual direction. There is a different BINFO for each path to a virtual
base; BINFOs for virtual bases are not shared. In addition, shared base; BINFOs for virtual bases are not shared.
versions of each of the virtual class BINFOs are stored in
CLASSTYPE_VBASECLASSES.
We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
inheritance is indicated by the absence of the other two flags, not inheritance is indicated by the absence of the other two flags, not
...@@ -1760,29 +1739,13 @@ struct lang_type ...@@ -1760,29 +1739,13 @@ struct lang_type
/* Nonzero if this BINFO is a primary base class. /* Nonzero if this BINFO is a primary base class.
In the TYPE_BINFO hierarchy, this flag is never set for a base In the TYPE_BINFO hierarchy, this flag is never set for a base
class of a non-primary virtual base because the copies of a class of a non-primary virtual base. This flag is only valid for
non-primary virtual base that appear in the TYPE_BINFO hierarchy do paths (given by BINFO_INHERITANCE_CHAIN) that really exist in the
not really exist. Instead, it is the BINFOs in the final object. */
CLASSTYPE_VBASECLASSES list that are used. In other words, this
flag is only valid for paths (given by BINFO_INHERITANCE_CHAIN)
that really exist in the final object.
For example, consider:
struct A {};
struct B : public A { };
struct C : virtual public B { void f(); int i; };
`A' is the primary base class for `B'. But, `B' is not a primary
base class for `C'. So, in the copy of `A' that appears in the
TYPE_BINFO hierarcy for `C' does not have BINFO_PRIMARY_MARKED_P
set; the copy in the CLASSTYPE_VBASECLASSES list does have this
set. */
#define BINFO_PRIMARY_MARKED_P(NODE) TREE_LANG_FLAG_5 (NODE) #define BINFO_PRIMARY_MARKED_P(NODE) TREE_LANG_FLAG_5 (NODE)
/* Nonzero if the virtual baseclass with the type given by this BINFO /* Nonzero if the virtual baseclass with the type given by this BINFO
is primary *somewhere* in the hierarchy. This flag is only set on is primary *somewhere* in the hierarchy. */
entries in the CLASSTYPE_VBASECLASSES list. */
#define BINFO_VBASE_PRIMARY_P(NODE) TREE_LANG_FLAG_6 (NODE) #define BINFO_VBASE_PRIMARY_P(NODE) TREE_LANG_FLAG_6 (NODE)
/* Used by various search routines. */ /* Used by various search routines. */
...@@ -4365,6 +4328,7 @@ extern tree marked_vtable_pathp PARAMS ((tree, void *)); ...@@ -4365,6 +4328,7 @@ extern tree marked_vtable_pathp PARAMS ((tree, void *));
extern tree unmarked_vtable_pathp PARAMS ((tree, void *)); extern tree unmarked_vtable_pathp PARAMS ((tree, void *));
extern tree convert_pointer_to_vbase PARAMS ((tree, tree)); extern tree convert_pointer_to_vbase PARAMS ((tree, tree));
extern tree find_vbase_instance PARAMS ((tree, tree)); extern tree find_vbase_instance PARAMS ((tree, tree));
extern tree binfo_for_vbase PARAMS ((tree, tree));
/* in semantics.c */ /* in semantics.c */
extern void finish_expr_stmt PARAMS ((tree)); extern void finish_expr_stmt PARAMS ((tree));
......
...@@ -13863,26 +13863,34 @@ finish_destructor_body () ...@@ -13863,26 +13863,34 @@ finish_destructor_body ()
/* Run destructors for all virtual baseclasses. */ /* Run destructors for all virtual baseclasses. */
if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
{ {
tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); tree vbases;
tree if_stmt = begin_if_stmt (); tree if_stmt;
if_stmt = begin_if_stmt ();
finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node, finish_if_stmt_cond (build (BIT_AND_EXPR, integer_type_node,
current_in_charge_parm, current_in_charge_parm,
integer_two_node), integer_two_node),
if_stmt); if_stmt);
while (vbases) vbases = CLASSTYPE_VBASECLASSES (current_class_type);
/* The CLASSTYPE_VBASECLASSES list is in initialization
order, so we have to march through it in reverse order. */
for (vbases = nreverse (copy_list (vbases));
vbases;
vbases = TREE_CHAIN (vbases))
{ {
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbases))) tree vbase = TREE_VALUE (vbases);
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (vbase)))
{ {
tree vb = get_vbase tree vb = get_vbase
(BINFO_TYPE (vbases), (BINFO_TYPE (vbase),
TYPE_BINFO (current_class_type)); TYPE_BINFO (current_class_type));
finish_expr_stmt finish_expr_stmt
(build_scoped_method_call (build_scoped_method_call
(current_class_ref, vb, base_dtor_identifier, (current_class_ref, vb, base_dtor_identifier,
NULL_TREE)); NULL_TREE));
} }
vbases = TREE_CHAIN (vbases);
} }
finish_then_clause (if_stmt); finish_then_clause (if_stmt);
......
...@@ -537,7 +537,7 @@ sort_base_init (t, rbase_ptr, vbase_ptr) ...@@ -537,7 +537,7 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
this constructor is the top-level constructor called. */ this constructor is the top-level constructor called. */
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
{ {
tree v = BINFO_FOR_VBASE (BINFO_TYPE (binfo), t); tree v = binfo_for_vbase (BINFO_TYPE (binfo), t);
vbases = tree_cons (v, TREE_VALUE (x), vbases); vbases = tree_cons (v, TREE_VALUE (x), vbases);
continue; continue;
} }
...@@ -855,6 +855,7 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) ...@@ -855,6 +855,7 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
tree inner_if_stmt; tree inner_if_stmt;
tree compound_stmt; tree compound_stmt;
tree exp; tree exp;
tree vbase;
/* If there are virtual base classes with destructors, we need to /* If there are virtual base classes with destructors, we need to
emit cleanups to destroy them if an exception is thrown during emit cleanups to destroy them if an exception is thrown during
...@@ -878,21 +879,22 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) ...@@ -878,21 +879,22 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
constructing virtual bases, then we must be the most derived constructing virtual bases, then we must be the most derived
class. Therefore, we don't have to look up the virtual base; class. Therefore, we don't have to look up the virtual base;
we already know where it is. */ we already know where it is. */
vbase = TREE_VALUE (vbases);
exp = build (PLUS_EXPR, exp = build (PLUS_EXPR,
TREE_TYPE (this_ptr), TREE_TYPE (this_ptr),
this_ptr, this_ptr,
fold (build1 (NOP_EXPR, TREE_TYPE (this_ptr), fold (build1 (NOP_EXPR, TREE_TYPE (this_ptr),
BINFO_OFFSET (vbases)))); BINFO_OFFSET (vbase))));
exp = build1 (NOP_EXPR, exp = build1 (NOP_EXPR,
build_pointer_type (BINFO_TYPE (vbases)), build_pointer_type (BINFO_TYPE (vbase)),
exp); exp);
expand_aggr_vbase_init_1 (vbases, this_ref, exp, init_list); expand_aggr_vbase_init_1 (vbase, this_ref, exp, init_list);
finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
finish_then_clause (inner_if_stmt); finish_then_clause (inner_if_stmt);
finish_if_stmt (); finish_if_stmt ();
expand_cleanup_for_base (vbases, flag); expand_cleanup_for_base (vbase, flag);
} }
} }
...@@ -1022,7 +1024,7 @@ expand_member_init (exp, name, init) ...@@ -1022,7 +1024,7 @@ expand_member_init (exp, name, init)
&& ! current_template_parms && ! current_template_parms
&& ! vec_binfo_member (basetype, && ! vec_binfo_member (basetype,
TYPE_BINFO_BASETYPES (type)) TYPE_BINFO_BASETYPES (type))
&& ! BINFO_FOR_VBASE (basetype, type)) && ! binfo_for_vbase (basetype, type))
{ {
if (IDENTIFIER_CLASS_VALUE (name)) if (IDENTIFIER_CLASS_VALUE (name))
goto try_member; goto try_member;
...@@ -3290,8 +3292,9 @@ build_vbase_delete (type, decl) ...@@ -3290,8 +3292,9 @@ build_vbase_delete (type, decl)
while (vbases) while (vbases)
{ {
tree this_addr = convert_force (build_pointer_type (BINFO_TYPE (vbases)), tree this_addr
addr, 0); = convert_force (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))),
addr, 0);
result = tree_cons (NULL_TREE, result = tree_cons (NULL_TREE,
build_delete (TREE_TYPE (this_addr), this_addr, build_delete (TREE_TYPE (this_addr), this_addr,
integer_zero_node, integer_zero_node,
......
...@@ -2262,7 +2262,8 @@ do_build_copy_constructor (fndecl) ...@@ -2262,7 +2262,8 @@ do_build_copy_constructor (fndecl)
for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
t = TREE_CHAIN (t)) t = TREE_CHAIN (t))
current_base_init_list current_base_init_list
= tree_cons (BINFO_TYPE (t), parm, current_base_init_list); = tree_cons (BINFO_TYPE (TREE_VALUE (t)), parm,
current_base_init_list);
for (i = 0; i < n_bases; ++i) for (i = 0; i < n_bases; ++i)
{ {
t = TREE_VEC_ELT (binfos, i); t = TREE_VEC_ELT (binfos, i);
......
...@@ -548,7 +548,7 @@ get_base_offset (binfo, parent) ...@@ -548,7 +548,7 @@ get_base_offset (binfo, parent)
/* Under the new ABI, we store the vtable offset at which /* Under the new ABI, we store the vtable offset at which
the virtual base offset can be found. */ the virtual base offset can be found. */
return convert (sizetype, return convert (sizetype,
BINFO_VPTR_FIELD (BINFO_FOR_VBASE (BINFO_TYPE (binfo), BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (binfo),
parent))); parent)));
} }
...@@ -930,11 +930,6 @@ expand_class_desc (tdecl, type) ...@@ -930,11 +930,6 @@ expand_class_desc (tdecl, type)
int i = CLASSTYPE_N_BASECLASSES (type); int i = CLASSTYPE_N_BASECLASSES (type);
int base_cnt = 0; int base_cnt = 0;
tree binfos = TYPE_BINFO_BASETYPES (type); tree binfos = TYPE_BINFO_BASETYPES (type);
#if 0
/* See code below that used these. */
tree vb = CLASSTYPE_VBASECLASSES (type);
int n_base = i;
#endif
tree base, elems, access, offset, isvir; tree base, elems, access, offset, isvir;
tree elt, elts = NULL_TREE; tree elt, elts = NULL_TREE;
...@@ -1000,39 +995,6 @@ expand_class_desc (tdecl, type) ...@@ -1000,39 +995,6 @@ expand_class_desc (tdecl, type)
elts = tree_cons (NULL_TREE, elt, elts); elts = tree_cons (NULL_TREE, elt, elts);
base_cnt++; base_cnt++;
} }
#if 0
i = n_base;
while (vb)
{
tree b;
access = access_public_node;
while (--i >= 0)
{
b = TREE_VEC_ELT (binfos, i);
if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b))
{
if (TREE_VIA_PUBLIC (b))
access = access_public_node;
else if (TREE_VIA_PROTECTED (b))
access = access_protected_node;
else
access = access_private_node;
break;
}
}
base = build_t_desc (BINFO_TYPE (vb), 1);
offset = BINFO_OFFSET (vb);
isvir = build_int_2 (1, 0);
base_list = tree_cons (NULL_TREE, base, base_list);
isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
acc_list = tree_cons (NULL_TREE, access, acc_list);
off_list = tree_cons (NULL_TREE, offset, off_list);
base_cnt++;
vb = TREE_CHAIN (vb);
}
#endif
name_string = tinfo_name (type); name_string = tinfo_name (type);
......
...@@ -82,7 +82,6 @@ struct vbase_info ...@@ -82,7 +82,6 @@ struct vbase_info
tree type; tree type;
tree decl_ptr; tree decl_ptr;
tree inits; tree inits;
tree vbase_types;
}; };
static tree next_baselink PARAMS ((tree)); static tree next_baselink PARAMS ((tree));
...@@ -491,9 +490,8 @@ get_base_distance (parent, binfo, protect, path_ptr) ...@@ -491,9 +490,8 @@ get_base_distance (parent, binfo, protect, path_ptr)
tree, deal with it. This happens when we are called from tree, deal with it. This happens when we are called from
expand_upcast_fixups. */ expand_upcast_fixups. */
if (rval == -1 && TREE_CODE (parent) == TREE_VEC if (rval == -1 && TREE_CODE (parent) == TREE_VEC
&& parent == BINFO_FOR_VBASE (BINFO_TYPE (parent), type)) && parent == binfo_for_vbase (BINFO_TYPE (parent), type))
{ {
my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827);
new_binfo = parent; new_binfo = parent;
rval = 1; rval = 1;
} }
...@@ -1351,10 +1349,7 @@ lookup_field_queue_p (binfo, data) ...@@ -1351,10 +1349,7 @@ lookup_field_queue_p (binfo, data)
&& hides (lfi->rval_binfo, binfo)) && hides (lfi->rval_binfo, binfo))
return NULL_TREE; return NULL_TREE;
if (TREE_VIA_VIRTUAL (binfo)) return CANONICAL_BINFO (binfo, lfi->type);
return BINFO_FOR_VBASE (BINFO_TYPE (binfo), lfi->type);
else
return binfo;
} }
/* Within the scope of a template class, you can refer to the to the /* Within the scope of a template class, you can refer to the to the
...@@ -2230,7 +2225,7 @@ get_shared_vbase_if_not_primary (binfo, data) ...@@ -2230,7 +2225,7 @@ get_shared_vbase_if_not_primary (binfo, data)
/* This is a non-primary virtual base. If there is no primary /* This is a non-primary virtual base. If there is no primary
version, get the shared version. */ version, get the shared version. */
binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), type); binfo = binfo_for_vbase (BINFO_TYPE (binfo), type);
if (BINFO_VBASE_PRIMARY_P (binfo)) if (BINFO_VBASE_PRIMARY_P (binfo))
return NULL_TREE; return NULL_TREE;
} }
...@@ -2344,7 +2339,7 @@ get_pure_virtuals (type) ...@@ -2344,7 +2339,7 @@ get_pure_virtuals (type)
{ {
tree virtuals; tree virtuals;
for (virtuals = BINFO_VIRTUALS (vbases); for (virtuals = BINFO_VIRTUALS (TREE_VALUE (vbases));
virtuals; virtuals;
virtuals = TREE_CHAIN (virtuals)) virtuals = TREE_CHAIN (virtuals))
{ {
...@@ -2492,7 +2487,7 @@ dfs_find_vbases (binfo, data) ...@@ -2492,7 +2487,7 @@ dfs_find_vbases (binfo, data)
&& CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0) && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
{ {
tree vbase = BINFO_TYPE (base_binfo); tree vbase = BINFO_TYPE (base_binfo);
tree binfo = binfo_member (vbase, vi->vbase_types); tree binfo = binfo_for_vbase (vbase, vi->type);
tree ptr_type = build_pointer_type (vbase); tree ptr_type = build_pointer_type (vbase);
CLASSTYPE_SEARCH_SLOT (vbase) CLASSTYPE_SEARCH_SLOT (vbase)
...@@ -2546,10 +2541,11 @@ dfs_init_vbase_pointers (binfo, data) ...@@ -2546,10 +2541,11 @@ dfs_init_vbase_pointers (binfo, data)
tree ref = build (COMPONENT_REF, TREE_TYPE (fields), tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
build_indirect_ref (this_vbase_ptr, NULL_PTR), fields); build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields))); tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
vi->inits = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)), vi->inits
vi->vbase_types), = tree_cons (binfo_for_vbase (TREE_TYPE (TREE_TYPE (fields)),
build_modify_expr (ref, NOP_EXPR, init), vi->type),
vi->inits); build_modify_expr (ref, NOP_EXPR, init),
vi->inits);
fields = TREE_CHAIN (fields); fields = TREE_CHAIN (fields);
} }
...@@ -2590,7 +2586,6 @@ init_vbase_pointers (type, decl_ptr) ...@@ -2590,7 +2586,6 @@ init_vbase_pointers (type, decl_ptr)
initialization. */ initialization. */
vi.type = type; vi.type = type;
vi.decl_ptr = decl_ptr; vi.decl_ptr = decl_ptr;
vi.vbase_types = CLASSTYPE_VBASECLASSES (type);
vi.inits = NULL_TREE; vi.inits = NULL_TREE;
dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp, &vi); dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp, &vi);
...@@ -2635,7 +2630,7 @@ virtual_context (fndecl, t, vbase) ...@@ -2635,7 +2630,7 @@ virtual_context (fndecl, t, vbase)
/* Not sure if checking path == vbase is necessary here, but just in /* Not sure if checking path == vbase is necessary here, but just in
case it is. */ case it is. */
if (TREE_VIA_VIRTUAL (path) || path == vbase) if (TREE_VIA_VIRTUAL (path) || path == vbase)
return BINFO_FOR_VBASE (BINFO_TYPE (path), t); return binfo_for_vbase (BINFO_TYPE (path), t);
path = BINFO_INHERITANCE_CHAIN (path); path = BINFO_INHERITANCE_CHAIN (path);
} }
} }
...@@ -2646,7 +2641,7 @@ virtual_context (fndecl, t, vbase) ...@@ -2646,7 +2641,7 @@ virtual_context (fndecl, t, vbase)
while (path) while (path)
{ {
if (TREE_VIA_VIRTUAL (path)) if (TREE_VIA_VIRTUAL (path))
return BINFO_FOR_VBASE (BINFO_TYPE (path), t); return binfo_for_vbase (BINFO_TYPE (path), t);
path = BINFO_INHERITANCE_CHAIN (path); path = BINFO_INHERITANCE_CHAIN (path);
} }
return 0; return 0;
...@@ -2873,11 +2868,11 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr) ...@@ -2873,11 +2868,11 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr)
tree vbase_offsets; tree vbase_offsets;
tree addr; tree addr;
vbase = find_vbase_instance (BINFO_TYPE (vbases), type); vbase = find_vbase_instance (TREE_PURPOSE (vbases), type);
vbase_offsets = NULL_TREE; vbase_offsets = NULL_TREE;
addr = convert_pointer_to_vbase (BINFO_TYPE (vbases), decl_ptr); addr = convert_pointer_to_vbase (TREE_PURPOSE (vbases), decl_ptr);
fixup_virtual_upcast_offsets (vbase, fixup_virtual_upcast_offsets (vbase,
TYPE_BINFO (BINFO_TYPE (vbases)), TYPE_BINFO (TREE_PURPOSE (vbases)),
1, 0, addr, decl_ptr, 1, 0, addr, decl_ptr,
type, vbase, &vbase_offsets); type, vbase, &vbase_offsets);
} }
...@@ -2916,11 +2911,9 @@ expand_indirect_vtbls_init (binfo, decl_ptr) ...@@ -2916,11 +2911,9 @@ expand_indirect_vtbls_init (binfo, decl_ptr)
if (TYPE_USES_VIRTUAL_BASECLASSES (type)) if (TYPE_USES_VIRTUAL_BASECLASSES (type))
{ {
tree vbases = CLASSTYPE_VBASECLASSES (type);
struct vbase_info vi; struct vbase_info vi;
vi.type = type; vi.type = type;
vi.decl_ptr = decl_ptr; vi.decl_ptr = decl_ptr;
vi.vbase_types = vbases;
dfs_walk (binfo, dfs_find_vbases, NULL, &vi); dfs_walk (binfo, dfs_find_vbases, NULL, &vi);
fixup_all_virtual_upcast_offsets (type, vi.decl_ptr); fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
...@@ -2940,17 +2933,10 @@ dfs_get_vbase_types (binfo, data) ...@@ -2940,17 +2933,10 @@ dfs_get_vbase_types (binfo, data)
tree type = (tree) data; tree type = (tree) data;
if (TREE_VIA_VIRTUAL (binfo)) if (TREE_VIA_VIRTUAL (binfo))
{ CLASSTYPE_VBASECLASSES (type)
tree new_vbase = make_binfo (size_zero_node, = tree_cons (BINFO_TYPE (binfo),
BINFO_TYPE (binfo), binfo,
BINFO_VTABLE (binfo), CLASSTYPE_VBASECLASSES (type));
BINFO_VIRTUALS (binfo));
unshare_base_binfos (new_vbase);
TREE_VIA_VIRTUAL (new_vbase) = 1;
BINFO_INHERITANCE_CHAIN (new_vbase) = TYPE_BINFO (type);
TREE_CHAIN (new_vbase) = CLASSTYPE_VBASECLASSES (type);
CLASSTYPE_VBASECLASSES (type) = new_vbase;
}
SET_BINFO_MARKED (binfo); SET_BINFO_MARKED (binfo);
return NULL_TREE; return NULL_TREE;
} }
...@@ -3022,7 +3008,7 @@ find_vbase_instance (base, type) ...@@ -3022,7 +3008,7 @@ find_vbase_instance (base, type)
{ {
tree instance; tree instance;
instance = BINFO_FOR_VBASE (base, type); instance = binfo_for_vbase (base, type);
if (!BINFO_VBASE_PRIMARY_P (instance)) if (!BINFO_VBASE_PRIMARY_P (instance))
return instance; return instance;
...@@ -3527,3 +3513,17 @@ binfo_from_vbase (binfo) ...@@ -3527,3 +3513,17 @@ binfo_from_vbase (binfo)
} }
return 0; return 0;
} }
/* Returns the BINFO (if any) for the virtual baseclass T of the class
C from the CLASSTYPE_VBASECLASSES list. */
tree
binfo_for_vbase (basetype, classtype)
tree basetype;
tree classtype;
{
tree binfo;
binfo = purpose_member (basetype, CLASSTYPE_VBASECLASSES (classtype));
return binfo ? TREE_VALUE (binfo) : NULL_TREE;
}
...@@ -5986,11 +5986,10 @@ get_delta_difference (from, to, force) ...@@ -5986,11 +5986,10 @@ get_delta_difference (from, to, force)
if (to == from) if (to == from)
return delta; return delta;
/* Should get_base_distance here, so we can check if any thing along the /* Should get_base_distance here, so we can check if any thing along
path is virtual, and we need to make sure we stay the path is virtual, and we need to make sure we stay inside the
inside the real binfos when going through virtual bases. real binfos when going through virtual bases. Maybe we should
Maybe we should replace virtual bases with replace virtual bases with BINFO_FOR_VBASE ... (mrs) */
binfo_member (...CLASSTYPE_VBASECLASSES...)... (mrs) */
binfo = get_binfo (from, to, 1); binfo = get_binfo (from, to, 1);
if (binfo == error_mark_node) if (binfo == error_mark_node)
{ {
...@@ -6010,7 +6009,7 @@ get_delta_difference (from, to, force) ...@@ -6010,7 +6009,7 @@ get_delta_difference (from, to, force)
return delta; return delta;
if (binfo_from_vbase (binfo)) if (binfo_from_vbase (binfo))
{ {
binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), from); binfo = binfo_for_vbase (BINFO_TYPE (binfo), from);
cp_warning ("pointer to member cast to virtual base `%T' will only work if you are very careful", BINFO_TYPE (binfo)); cp_warning ("pointer to member cast to virtual base `%T' will only work if you are very careful", BINFO_TYPE (binfo));
} }
delta = BINFO_OFFSET (binfo); delta = BINFO_OFFSET (binfo);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment