Commit 911a71a7 by Mark Mitchell Committed by Mark Mitchell

Allow indirect primary bases.

	* cp-tree.h (struct lang_type): Remove vfield_parent.  Add
	primary_base.
	(CLASSTYPE_VFIELD_PARENT): Remove.
	(CLASSTYPE_PRIMARY_BINFO): Reimplement.
	(BINFO_PRIMARY_BINFO): Remove.
	(CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
	(BINFO_VBASE_PRIMARY_P): Likewise.
	(BINFO_PRIMARY_BASE_OF): New macro.
	(BINFO_INDIRECT_PRIMARY_P): Likewise.
	(get_primary_binfo): New function.
	* decl.c (lang_mark_tree): Make lang_type::primary_base.
	* class.c (vcall_offset_data_s): Rename to ...
	(vtbl_init_data_s): ... this.  Rename primary_p to primary_vtbl_p,
	and add ctor_vtbl_p.
	(get_derived_offset): Use get_primary_binfo.
	(dfs_mark_primary_bases): Adjust handling of virtual primary
	bases.
	(mark_primary_bases): Likewise.
	(set_primary_base): Take a binfo, not an integer, as a
	representation of the primary base.
	(indirect_primary_base_p): Remove.
	(determine_primary_base): Adjust for indirect primary bases.
	(dfs_find_final_overrider): Fix typo in coment.
	(update_vtable_entry_for_fn): Use get_primary_binfo.
	(layout_nonempty_base_or_field): Tweak.
	(build_base_fields): Adjust for new primary base semantics.
	(dfs_propagate_binfo_offsets): Remove.
	(propagate_binfo_offsets): Rewrite.
	(dfs_set_offset_for_shared_vbases): Remove.
	(layout_virtual_bases): Don't use it.
	(layout_class_type): Set CLASSTYPE_SIZE correctly under the new
	ABI.
	(finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
	CLASSTYPE_VFIELD_PARENT.
	(dfs_get_primary_binfo): New function.
	(get_primary_binfo): Likewise.
	(dump_class_hierarchy_r): Tweak printing of primary bases.
	(build_vtbl_initializer): Fix typo in comments.  Use
	vtbl_init_data.
	(build_vcall_and_vbase_vtbl_entries): Likewise.
	(build_vbaes_offset_vtbl_entries): Likewise.
	(dfs_build_vcall_offset_vtbl_entries): Adjust setting of
	BV_VCALL_INDEX to handle indirect primary bases.
	(build_vcall_offset_vtbl_entries): Use vtbl_init_data.
	(build_rtti_vtbl_entries): Likewise.
	* search.c (get_shared_vbase_if_not_primary): Tweak.
	(find_vbase_instance): Likewise.
	(binfo_for_vtable): Simplify.
	* tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
	(make_binfo): Make it have 11 entries.

From-SVN: r35360
parent abe24fb3
2000-07-30 Mark Mitchell <mark@codesourcery.com>
Allow indirect primary bases.
* cp-tree.h (struct lang_type): Remove vfield_parent. Add
primary_base.
(CLASSTYPE_VFIELD_PARENT): Remove.
(CLASSTYPE_PRIMARY_BINFO): Reimplement.
(BINFO_PRIMARY_BINFO): Remove.
(CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
(BINFO_VBASE_PRIMARY_P): Likewise.
(BINFO_PRIMARY_BASE_OF): New macro.
(BINFO_INDIRECT_PRIMARY_P): Likewise.
(get_primary_binfo): New function.
* decl.c (lang_mark_tree): Make lang_type::primary_base.
* class.c (vcall_offset_data_s): Rename to ...
(vtbl_init_data_s): ... this. Rename primary_p to primary_vtbl_p,
and add ctor_vtbl_p.
(get_derived_offset): Use get_primary_binfo.
(dfs_mark_primary_bases): Adjust handling of virtual primary
bases.
(mark_primary_bases): Likewise.
(set_primary_base): Take a binfo, not an integer, as a
representation of the primary base.
(indirect_primary_base_p): Remove.
(determine_primary_base): Adjust for indirect primary bases.
(dfs_find_final_overrider): Fix typo in coment.
(update_vtable_entry_for_fn): Use get_primary_binfo.
(layout_nonempty_base_or_field): Tweak.
(build_base_fields): Adjust for new primary base semantics.
(dfs_propagate_binfo_offsets): Remove.
(propagate_binfo_offsets): Rewrite.
(dfs_set_offset_for_shared_vbases): Remove.
(layout_virtual_bases): Don't use it.
(layout_class_type): Set CLASSTYPE_SIZE correctly under the new
ABI.
(finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
CLASSTYPE_VFIELD_PARENT.
(dfs_get_primary_binfo): New function.
(get_primary_binfo): Likewise.
(dump_class_hierarchy_r): Tweak printing of primary bases.
(build_vtbl_initializer): Fix typo in comments. Use
vtbl_init_data.
(build_vcall_and_vbase_vtbl_entries): Likewise.
(build_vbaes_offset_vtbl_entries): Likewise.
(dfs_build_vcall_offset_vtbl_entries): Adjust setting of
BV_VCALL_INDEX to handle indirect primary bases.
(build_vcall_offset_vtbl_entries): Use vtbl_init_data.
(build_rtti_vtbl_entries): Likewise.
* search.c (get_shared_vbase_if_not_primary): Tweak.
(find_vbase_instance): Likewise.
(binfo_for_vtable): Simplify.
* tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
(make_binfo): Make it have 11 entries.
2000-07-30 Alex Samuel <samuel@codesourcery.com> 2000-07-30 Alex Samuel <samuel@codesourcery.com>
* mangle.c (DECL_TEMPLATE_ID_P): Remove. * mangle.c (DECL_TEMPLATE_ID_P): Remove.
......
...@@ -62,8 +62,10 @@ typedef struct class_stack_node { ...@@ -62,8 +62,10 @@ typedef struct class_stack_node {
splay_tree names_used; splay_tree names_used;
}* class_stack_node_t; }* class_stack_node_t;
typedef struct vcall_offset_data_s typedef struct vtbl_init_data_s
{ {
/* The base for which we're building initializers. */
tree binfo;
/* The binfo for the most-derived type. */ /* The binfo for the most-derived type. */
tree derived; tree derived;
/* The negative-index vtable initializers built up so far. These /* The negative-index vtable initializers built up so far. These
...@@ -72,7 +74,7 @@ typedef struct vcall_offset_data_s ...@@ -72,7 +74,7 @@ typedef struct vcall_offset_data_s
/* The last (i.e., most negative entry in INITS. */ /* The last (i.e., most negative entry in INITS. */
tree* last_init; tree* last_init;
/* The binfo for the virtual base for which we're building /* The binfo for the virtual base for which we're building
initializers. */ vcall offset initializers. */
tree vbase; tree vbase;
/* The functions in vbase for which we have already provided vcall /* The functions in vbase for which we have already provided vcall
offsets. */ offsets. */
...@@ -81,8 +83,11 @@ typedef struct vcall_offset_data_s ...@@ -81,8 +83,11 @@ typedef struct vcall_offset_data_s
tree index; tree index;
/* Nonzero if we are building the initializer for the primary /* Nonzero if we are building the initializer for the primary
vtable. */ vtable. */
int primary_p; int primary_vtbl_p;
} vcall_offset_data; /* Nonzero if we are building the initializer for a construction
vtable. */
int ctor_vtbl_p;
} vtbl_init_data;
/* The stack itself. This is an dynamically resized array. The /* The stack itself. This is an dynamically resized array. The
number of elements allocated is CURRENT_CLASS_STACK_SIZE. */ number of elements allocated is CURRENT_CLASS_STACK_SIZE. */
...@@ -150,15 +155,13 @@ static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *)); ...@@ -150,15 +155,13 @@ static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *)); static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
static void fixup_pending_inline PARAMS ((struct pending_inline *)); static void fixup_pending_inline PARAMS ((struct pending_inline *));
static void fixup_inline_methods PARAMS ((tree)); static void fixup_inline_methods PARAMS ((tree));
static void set_primary_base PARAMS ((tree, int, int *)); static void set_primary_base PARAMS ((tree, tree, int *));
static tree dfs_propagate_binfo_offsets PARAMS ((tree, void *));
static void propagate_binfo_offsets PARAMS ((tree, tree)); static void propagate_binfo_offsets PARAMS ((tree, tree));
static void layout_virtual_bases PARAMS ((tree, varray_type *)); static void layout_virtual_bases PARAMS ((tree, varray_type *));
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *)); static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
static void build_vbase_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *)); static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *)); static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
static void build_vcall_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *)); static void build_vcall_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
static void layout_vtable_decl PARAMS ((tree, int)); static void layout_vtable_decl PARAMS ((tree, int));
static tree dfs_find_final_overrider PARAMS ((tree, void *)); static tree dfs_find_final_overrider PARAMS ((tree, void *));
static tree find_final_overrider PARAMS ((tree, tree, tree)); static tree find_final_overrider PARAMS ((tree, tree, tree));
...@@ -179,9 +182,9 @@ static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int)); ...@@ -179,9 +182,9 @@ static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
static void layout_empty_base PARAMS ((tree, tree, varray_type)); static void layout_empty_base PARAMS ((tree, tree, varray_type));
static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree)); static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
static void set_vindex PARAMS ((tree, tree, int *)); static void set_vindex PARAMS ((tree, tree, int *));
static void build_rtti_vtbl_entries PARAMS ((tree, tree, vcall_offset_data *)); static void build_rtti_vtbl_entries PARAMS ((tree, tree, vtbl_init_data *));
static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree, static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
vcall_offset_data *)); vtbl_init_data *));
static tree dfs_mark_primary_bases PARAMS ((tree, void *)); static tree dfs_mark_primary_bases PARAMS ((tree, void *));
static void mark_primary_bases PARAMS ((tree)); static void mark_primary_bases PARAMS ((tree));
static void clone_constructors_and_destructors PARAMS ((tree)); static void clone_constructors_and_destructors PARAMS ((tree));
...@@ -193,8 +196,8 @@ static void build_vtt PARAMS ((tree)); ...@@ -193,8 +196,8 @@ static void build_vtt PARAMS ((tree));
static tree *build_vtt_inits PARAMS ((tree, tree, int, tree *, tree *)); static tree *build_vtt_inits PARAMS ((tree, tree, int, tree *, tree *));
static tree dfs_build_secondary_vptr_vtt_inits PARAMS ((tree, void *)); static tree dfs_build_secondary_vptr_vtt_inits PARAMS ((tree, void *));
static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *)); static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
static int indirect_primary_base_p PARAMS ((tree, tree));
static tree get_matching_base PARAMS ((tree, tree)); static tree get_matching_base PARAMS ((tree, tree));
static tree dfs_get_primary_binfo PARAMS ((tree, void*));
/* Variables shared between class.c and call.c. */ /* Variables shared between class.c and call.c. */
...@@ -687,7 +690,7 @@ get_derived_offset (binfo, type) ...@@ -687,7 +690,7 @@ get_derived_offset (binfo, type)
tree offset2; tree offset2;
while (!same_type_p (BINFO_TYPE (binfo), type)) while (!same_type_p (BINFO_TYPE (binfo), type))
binfo = BINFO_PRIMARY_BINFO (binfo); binfo = get_primary_binfo (binfo);
offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo)));
return size_binop (MINUS_EXPR, offset1, offset2); return size_binop (MINUS_EXPR, offset1, offset2);
...@@ -1701,19 +1704,14 @@ dfs_mark_primary_bases (binfo, data) ...@@ -1701,19 +1704,14 @@ dfs_mark_primary_bases (binfo, data)
tree binfo; tree binfo;
void *data; void *data;
{ {
int i;
tree base_binfo; tree base_binfo;
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo))) if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
return NULL_TREE; return NULL_TREE;
i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); base_binfo = get_primary_binfo (binfo);
base_binfo = BINFO_BASETYPE (binfo, i);
if (!TREE_VIA_VIRTUAL (base_binfo)) if (TREE_VIA_VIRTUAL (base_binfo))
/* Non-virtual base classes are easy. */
BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
else
{ {
tree shared_binfo; tree shared_binfo;
tree type; tree type;
...@@ -1723,7 +1721,7 @@ dfs_mark_primary_bases (binfo, data) ...@@ -1723,7 +1721,7 @@ dfs_mark_primary_bases (binfo, 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. */
if (!BINFO_VBASE_PRIMARY_P (shared_binfo)) if (!BINFO_PRIMARY_MARKED_P (shared_binfo))
{ {
/* Make sure the CLASSTYPE_VBASECLASSES list contains the /* Make sure the CLASSTYPE_VBASECLASSES list contains the
primary copy; it's the one that really exists. */ primary copy; it's the one that really exists. */
...@@ -1731,12 +1729,14 @@ dfs_mark_primary_bases (binfo, data) ...@@ -1731,12 +1729,14 @@ dfs_mark_primary_bases (binfo, data)
TREE_VALUE (purpose_member (BINFO_TYPE (base_binfo), TREE_VALUE (purpose_member (BINFO_TYPE (base_binfo),
CLASSTYPE_VBASECLASSES (type))) CLASSTYPE_VBASECLASSES (type)))
= base_binfo; = base_binfo;
BINFO_VBASE_PRIMARY_P (base_binfo) = 1;
BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
} }
else
base_binfo = NULL_TREE;
} }
if (base_binfo)
BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
return NULL_TREE; return NULL_TREE;
} }
...@@ -1774,36 +1774,29 @@ mark_primary_bases (type) ...@@ -1774,36 +1774,29 @@ mark_primary_bases (type)
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_PRIMARY_MARKED_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. */
continue; continue;
/* Temporarily pretend that VBASE is primary so that its bases
will be walked; this is the real copy of VBASE. */
BINFO_PRIMARY_MARKED_P (vbase) = 1;
/* Now, walk its bases. */ /* Now, walk its bases. */
dfs_walk_real (vbase, dfs_mark_primary_bases, NULL, dfs_walk_real (vbase, dfs_mark_primary_bases, NULL,
dfs_skip_nonprimary_vbases_unmarkedp, type); dfs_skip_nonprimary_vbases_unmarkedp, type);
/* VBASE wasn't really primary. */
BINFO_PRIMARY_MARKED_P (vbase) = 0;
} }
} }
/* Make the Ith baseclass of T its primary base. */ /* Make the BINFO the primary base of T. */
static void static void
set_primary_base (t, i, vfuns_p) set_primary_base (t, binfo, vfuns_p)
tree t; tree t;
int i; tree binfo;
int *vfuns_p; int *vfuns_p;
{ {
tree basetype; tree basetype;
CLASSTYPE_VFIELD_PARENT (t) = i; CLASSTYPE_PRIMARY_BINFO (t) = binfo;
basetype = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (t)); basetype = BINFO_TYPE (binfo);
TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype);
TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
TYPE_VFIELD (t) = TYPE_VFIELD (basetype); TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
...@@ -1811,35 +1804,6 @@ set_primary_base (t, i, vfuns_p) ...@@ -1811,35 +1804,6 @@ set_primary_base (t, i, vfuns_p)
*vfuns_p = CLASSTYPE_VSIZE (basetype); *vfuns_p = CLASSTYPE_VSIZE (basetype);
} }
/* Returns true iff BINFO (a direct virtual base of T) is an indirect
primary base. */
static int
indirect_primary_base_p (t, binfo)
tree t;
tree binfo;
{
int i;
for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); ++i)
{
tree type;
tree b;
/* Figure out to which type the Ith base corresponds. */
type = TYPE_BINFO_BASETYPE (t, i);
/* See if any of the primary bases have the same type as BINFO. */
for (b = TYPE_BINFO (type); b; b = TREE_CHAIN (b))
/* If this base is primary, and has the same type as BINFO,
then BINFO is an indirect primary base. */
if (BINFO_PRIMARY_MARKED_P (b)
&& same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
return 1;
}
return 0;
}
/* Determine the primary class for T. */ /* Determine the primary class for T. */
static void static void
...@@ -1848,16 +1812,18 @@ determine_primary_base (t, vfuns_p) ...@@ -1848,16 +1812,18 @@ determine_primary_base (t, vfuns_p)
int *vfuns_p; int *vfuns_p;
{ {
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
tree vbases;
tree type_binfo;
/* If there are no baseclasses, there is certainly no primary base. */ /* If there are no baseclasses, there is certainly no primary base. */
if (n_baseclasses == 0) if (n_baseclasses == 0)
return; return;
*vfuns_p = 0; type_binfo = TYPE_BINFO (t);
for (i = 0; i < n_baseclasses; i++) for (i = 0; i < n_baseclasses; i++)
{ {
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i); tree base_binfo = BINFO_BASETYPE (type_binfo, i);
tree basetype = BINFO_TYPE (base_binfo); tree basetype = BINFO_TYPE (base_binfo);
if (TYPE_CONTAINS_VPTR_P (basetype)) if (TYPE_CONTAINS_VPTR_P (basetype))
...@@ -1876,7 +1842,7 @@ determine_primary_base (t, vfuns_p) ...@@ -1876,7 +1842,7 @@ determine_primary_base (t, vfuns_p)
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t)) if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
{ {
set_primary_base (t, i, vfuns_p); set_primary_base (t, base_binfo, vfuns_p);
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype)); CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
} }
else else
...@@ -1895,60 +1861,93 @@ determine_primary_base (t, vfuns_p) ...@@ -1895,60 +1861,93 @@ determine_primary_base (t, vfuns_p)
CLASSTYPE_VFIELDS (t)); CLASSTYPE_VFIELDS (t));
if (!flag_new_abi && *vfuns_p == 0) if (!flag_new_abi && *vfuns_p == 0)
set_primary_base (t, i, vfuns_p); set_primary_base (t, base_binfo, vfuns_p);
} }
} }
} }
if (!TYPE_VFIELD (t)) if (!TYPE_VFIELD (t))
CLASSTYPE_VFIELD_PARENT (t) = -1; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
/* Mark the indirect primary bases. */
for (vbases = CLASSTYPE_VBASECLASSES (t);
vbases;
vbases = TREE_CHAIN (vbases))
{
tree binfo = TREE_VALUE (vbases);
/* See if this virtual base is an indirect primary base. If so,
it must be either a primary base or an indirect primary base
in one of the direct bases. */
for (i = 0; i < n_baseclasses; ++i)
{
tree basetype;
tree v;
basetype = TYPE_BINFO_BASETYPE (t, i);
for (v = CLASSTYPE_VBASECLASSES (basetype);
v;
v = TREE_CHAIN (v))
{
tree b = TREE_VALUE (v);
if ((BINFO_PRIMARY_MARKED_P (b)
|| BINFO_INDIRECT_PRIMARY_P (b))
&& same_type_p (BINFO_TYPE (b), BINFO_TYPE (binfo)))
{
BINFO_INDIRECT_PRIMARY_P (binfo) = 1;
break;
}
}
/* If we've discovered that this virtual base is an indirect
primary base, then we can move on to the next virtual
base. */
if (BINFO_INDIRECT_PRIMARY_P (binfo))
break;
}
}
/* The new ABI allows for the use of a "nearly-empty" virtual base /* The new ABI allows for the use of a "nearly-empty" virtual base
class as the primary base class if no non-virtual polymorphic class as the primary base class if no non-virtual polymorphic
base can be found. */ base can be found. */
if (flag_new_abi && !CLASSTYPE_HAS_PRIMARY_BASE_P (t)) if (flag_new_abi && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
{ {
/* If not -1, this is the index in TYPE_BINFO_BASETYPEs of the /* If not NULL, this is the best primary base candidate we have
best primary base candidate we have found so far. */ found so far. */
int candidate = -1; tree candidate = NULL_TREE;
tree base_binfo;
/* Loop over the baseclasses. */ /* Loop over the baseclasses. */
for (i = 0; i < n_baseclasses; ++i) for (base_binfo = TYPE_BINFO (t);
base_binfo;
base_binfo = TREE_CHAIN (base_binfo))
{ {
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
tree basetype = BINFO_TYPE (base_binfo); tree basetype = BINFO_TYPE (base_binfo);
if (TREE_VIA_VIRTUAL (base_binfo) if (TREE_VIA_VIRTUAL (base_binfo)
&& CLASSTYPE_NEARLY_EMPTY_P (basetype)) && CLASSTYPE_NEARLY_EMPTY_P (basetype))
{ {
int indirect_primary_p;
/* Figure out whether or not this base is an indirect
primary base. */
indirect_primary_p = indirect_primary_base_p (t, base_binfo);
/* If this is not an indirect primary base, then it's /* If this is not an indirect primary base, then it's
definitely our primary base. */ definitely our primary base. */
if (!indirect_primary_p) if (!BINFO_INDIRECT_PRIMARY_P (base_binfo))
{ {
candidate = i; candidate = base_binfo;
break; break;
} }
/* If this was an indirect primary base, it's still our /* If this was an indirect primary base, it's still our
primary base -- unless there's another nearly-empty primary base -- unless there's another nearly-empty
virtual base that isn't an indirect primary base. */ virtual base that isn't an indirect primary base. */
else if (candidate == -1) else if (!candidate)
candidate = i; candidate = base_binfo;
} }
} }
/* If we've got a primary base, use it. */ /* If we've got a primary base, use it. */
if (candidate != -1) if (candidate)
{ {
set_primary_base (t, candidate, vfuns_p); set_primary_base (t, candidate, vfuns_p);
CLASSTYPE_VFIELDS (t) CLASSTYPE_VFIELDS (t)
= copy_list (CLASSTYPE_VFIELDS (TYPE_BINFO_BASETYPE (t, = copy_list (CLASSTYPE_VFIELDS (BINFO_TYPE (candidate)));
candidate)));
} }
} }
...@@ -2475,9 +2474,10 @@ dfs_find_final_overrider (binfo, data) ...@@ -2475,9 +2474,10 @@ dfs_find_final_overrider (binfo, data)
{ {
tree base; tree base;
/* Assume the path is non-virtual. See if there are any base from /* Assume the path is non-virtual. See if there are any
(but not including) the overrider up to and including the virtual bases from (but not including) the overrider up
base where the function is defined. */ to and including the base where the function is
defined. */
for (base = TREE_CHAIN (path); base; base = TREE_CHAIN (base)) for (base = TREE_CHAIN (path); base; base = TREE_CHAIN (base))
if (TREE_VIA_VIRTUAL (TREE_VALUE (base))) if (TREE_VIA_VIRTUAL (TREE_VALUE (base)))
{ {
...@@ -2612,7 +2612,7 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals) ...@@ -2612,7 +2612,7 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
tree primary_base; tree primary_base;
tree f; tree f;
primary_base = BINFO_PRIMARY_BINFO (b); primary_base = get_primary_binfo (b);
if (!primary_base) if (!primary_base)
break; break;
...@@ -3792,7 +3792,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v) ...@@ -3792,7 +3792,7 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
/* Now that we know where it wil be placed, update its /* Now that we know where it wil be placed, update its
BINFO_OFFSET. */ BINFO_OFFSET. */
offset = byte_position (decl); offset = byte_position (decl);
if (binfo) if (binfo && CLASS_TYPE_P (BINFO_TYPE (binfo)))
propagate_binfo_offsets (binfo, propagate_binfo_offsets (binfo,
convert (ssizetype, offset)); convert (ssizetype, offset));
...@@ -3978,13 +3978,13 @@ build_base_fields (rli, empty_p) ...@@ -3978,13 +3978,13 @@ build_base_fields (rli, empty_p)
{ {
tree base_binfo; tree base_binfo;
base_binfo = BINFO_BASETYPE (TYPE_BINFO (rec), i);
/* Under the new ABI, the primary base was already allocated /* Under the new ABI, the primary base was already allocated
above, so we don't need to allocate it again here. */ above, so we don't need to allocate it again here. */
if (flag_new_abi && i == CLASSTYPE_VFIELD_PARENT (rec)) if (flag_new_abi && base_binfo == CLASSTYPE_PRIMARY_BINFO (rec))
continue; continue;
base_binfo = BINFO_BASETYPE (TYPE_BINFO (rec), i);
/* A primary virtual base class is allocated just like any other /* A primary virtual base class is allocated just like any other
base class, but a non-primary virtual base is allocated base class, but a non-primary virtual base is allocated
later, in layout_virtual_bases. */ later, in layout_virtual_bases. */
...@@ -4486,66 +4486,60 @@ fixup_inline_methods (type) ...@@ -4486,66 +4486,60 @@ fixup_inline_methods (type)
CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE; CLASSTYPE_INLINE_FRIENDS (type) = NULL_TREE;
} }
/* Called from propagate_binfo_offsets via dfs_walk. */
static tree
dfs_propagate_binfo_offsets (binfo, data)
tree binfo;
void *data;
{
tree offset = (tree) data;
/* Update the BINFO_OFFSET for this base. Allow for the case where it
might be negative. */
BINFO_OFFSET (binfo)
= convert (sizetype, size_binop (PLUS_EXPR,
convert (ssizetype, BINFO_OFFSET (binfo)),
offset));
SET_BINFO_MARKED (binfo);
return NULL_TREE;
}
/* Add OFFSET to all base types of BINFO which is a base in the /* Add OFFSET to all base types of BINFO which is a base in the
hierarchy dominated by T. hierarchy dominated by T.
OFFSET, which is a type offset, is number of bytes. OFFSET, which is a type offset, is number of bytes. */
Note that we don't have to worry about having two paths to the
same base type, since this type owns its association list. */
static void static void
propagate_binfo_offsets (binfo, offset) propagate_binfo_offsets (binfo, offset)
tree binfo; tree binfo;
tree offset; tree offset;
{ {
dfs_walk (binfo, int i;
dfs_propagate_binfo_offsets, tree primary_binfo;
dfs_skip_nonprimary_vbases_unmarkedp,
offset);
dfs_walk (binfo,
dfs_unmark,
dfs_skip_nonprimary_vbases_markedp,
NULL);
}
/* Called via dfs_walk from layout_virtual bases. */ /* Update BINFO's offset. */
BINFO_OFFSET (binfo)
= convert (sizetype,
size_binop (PLUS_EXPR,
convert (ssizetype, BINFO_OFFSET (binfo)),
offset));
static tree /* Find the primary base class. */
dfs_set_offset_for_shared_vbases (binfo, data) primary_binfo = get_primary_binfo (binfo);
tree binfo;
void *data; /* Scan all of the bases, pushing the BINFO_OFFSET adjust
{ downwards. */
if (TREE_VIA_VIRTUAL (binfo) && BINFO_PRIMARY_MARKED_P (binfo)) for (i = -1; i < BINFO_N_BASETYPES (binfo); ++i)
{ {
/* Update the shared copy. */ tree base_binfo;
tree shared_binfo;
shared_binfo = binfo_for_vbase (BINFO_TYPE (binfo), (tree) data); /* On the first through the loop, do the primary base. Because
BINFO_OFFSET (shared_binfo) = BINFO_OFFSET (binfo); the primary base need not be an immediate base, we must
} handle the primary base specially. */
if (i == -1)
{
if (!primary_binfo)
continue;
return NULL_TREE; base_binfo = primary_binfo;
}
else
{
base_binfo = BINFO_BASETYPE (binfo, i);
/* Don't do the primary base twice. */
if (base_binfo == primary_binfo)
continue;
}
/* Skip virtual bases that aren't our primary base. */
if (TREE_VIA_VIRTUAL (base_binfo)
&& BINFO_PRIMARY_BASE_OF (base_binfo) != binfo)
continue;
propagate_binfo_offsets (base_binfo, offset);
}
} }
/* Called via dfs_walk from layout_virtual bases. */ /* Called via dfs_walk from layout_virtual bases. */
...@@ -4622,7 +4616,7 @@ layout_virtual_bases (t, base_offsets) ...@@ -4622,7 +4616,7 @@ layout_virtual_bases (t, base_offsets)
else else
vbase = TREE_VALUE (vbases); vbase = TREE_VALUE (vbases);
if (!BINFO_VBASE_PRIMARY_P (vbase)) if (!BINFO_PRIMARY_MARKED_P (vbase))
{ {
/* This virtual base is not a primary base of any class in the /* This virtual base is not a primary base of any class in the
hierarchy, so we have to add space for it. */ hierarchy, so we have to add space for it. */
...@@ -4673,16 +4667,7 @@ layout_virtual_bases (t, base_offsets) ...@@ -4673,16 +4667,7 @@ layout_virtual_bases (t, base_offsets)
} }
} }
/* Make sure that all of the CLASSTYPE_VBASECLASSES have their /* Now, go through the TYPE_BINFO hierarchy, setting the
BINFO_OFFSET set correctly. Those we just allocated certainly
will. The others are primary baseclasses; we walk the hierarchy
to find the primary copies and update the shared copy. */
dfs_walk (TYPE_BINFO (t),
dfs_set_offset_for_shared_vbases,
dfs_unmarked_real_bases_queue_p,
t);
/* Now, go through the TYPE_BINFO hierarchy again, setting the
BINFO_OFFSETs correctly for all non-primary copies of the virtual BINFO_OFFSETs correctly for all non-primary copies of the virtual
bases and their direct and indirect bases. The ambiguity checks bases and their direct and indirect bases. The ambiguity checks
in get_base_distance depend on the BINFO_OFFSETs being set in get_base_distance depend on the BINFO_OFFSETs being set
...@@ -4942,8 +4927,7 @@ layout_class_type (t, empty_p, vfuns_p, ...@@ -4942,8 +4927,7 @@ layout_class_type (t, empty_p, vfuns_p,
CLASSTYPE_SIZE (t) = bitsize_zero_node; CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node; CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
} }
else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t) else if (flag_new_abi)
&& TYPE_HAS_COMPLEX_ASSIGN_REF (t))
{ {
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t); CLASSTYPE_SIZE_UNIT (t) = TYPE_BINFO_SIZE_UNIT (t);
...@@ -5034,7 +5018,7 @@ finish_struct_1 (t) ...@@ -5034,7 +5018,7 @@ finish_struct_1 (t)
make sure we lay it out again. */ make sure we lay it out again. */
TYPE_SIZE (t) = NULL_TREE; TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0; CLASSTYPE_GOT_SEMICOLON (t) = 0;
CLASSTYPE_VFIELD_PARENT (t) = -1; CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
vfuns = 0; vfuns = 0;
CLASSTYPE_RTTI (t) = NULL_TREE; CLASSTYPE_RTTI (t) = NULL_TREE;
...@@ -6472,6 +6456,69 @@ get_vtbl_decl_for_binfo (binfo) ...@@ -6472,6 +6456,69 @@ get_vtbl_decl_for_binfo (binfo)
return decl; return decl;
} }
/* Called from get_primary_binfo via dfs_walk. */
static tree
dfs_get_primary_binfo (binfo, data)
tree binfo;
void *data;
{
tree primary_base = (tree) data;
if (TREE_VIA_VIRTUAL (binfo)
&& same_type_p (TREE_TYPE (binfo), TREE_TYPE (primary_base)))
return binfo;
return NULL_TREE;
}
/* Returns the binfo for the primary base of BINFO. Note that in a
complex hierarchy the resulting BINFO may not actually *be*
primary. In particular if the resulting BINFO is a virtual base,
and it occurs elsewhere in the hierarchy, then this occurrence may
not actually be a primary base in the complete object. Check
BINFO_PRIMARY_MARKED_P to be sure. */
tree
get_primary_binfo (binfo)
tree binfo;
{
tree primary_base;
tree result;
primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
if (!primary_base)
return NULL_TREE;
/* A non-virtual primary base is always a direct base, and easy to
find. */
if (!TREE_VIA_VIRTUAL (primary_base))
{
int i;
/* Scan the direct basetypes until we find a base with the same
type as the primary base. */
for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
{
tree base_binfo = BINFO_BASETYPE (binfo, i);
if (same_type_p (BINFO_TYPE (base_binfo),
BINFO_TYPE (primary_base)))
return base_binfo;
}
/* We should always find the primary base. */
my_friendly_abort (20000729);
}
/* For a primary virtual base, we have to scan the entire hierarchy
rooted at BINFO; the virtual base could be an indirect virtual
base. */
result = dfs_walk (binfo, dfs_get_primary_binfo, NULL, primary_base);
my_friendly_assert (result != NULL_TREE, 20000730);
return result;
}
/* Dump the offsets of all the bases rooted at BINFO (in the hierarchy /* Dump the offsets of all the bases rooted at BINFO (in the hierarchy
dominated by T) to stderr. INDENT should be zero when called from dominated by T) to stderr. INDENT should be zero when called from
the top level; it is incremented recursively. */ the top level; it is incremented recursively. */
...@@ -6493,8 +6540,8 @@ dump_class_hierarchy_r (t, binfo, indent) ...@@ -6493,8 +6540,8 @@ 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_PRIMARY_MARKED_P (binfo_for_vbase (BINFO_TYPE (binfo),
t)))) t))))
fprintf (stderr, " primary"); fprintf (stderr, " primary");
fprintf (stderr, "\n"); fprintf (stderr, "\n");
...@@ -7021,7 +7068,7 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l) ...@@ -7021,7 +7068,7 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
is part of the hierarchy dominated by T. If we're building a is part of the hierarchy dominated by T. If we're building a
construction vtable, the ORIG_BINFO is the binfo we should use to construction vtable, the ORIG_BINFO is the binfo we should use to
find the actual function pointers to put in the vtable. Otherwise, find the actual function pointers to put in the vtable. Otherwise,
ORIG_BINFO should be the same as BINFO. The RTTI_DOMINATOR is the ORIG_BINFO should be the same as BINFO. The RTTI_BINFO is the
BINFO that should be indicated by the RTTI information in the BINFO that should be indicated by the RTTI information in the
vtable; it will be a base class of T, rather than T itself, if we vtable; it will be a base class of T, rather than T itself, if we
are building a construction vtable. are building a construction vtable.
...@@ -7029,7 +7076,14 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l) ...@@ -7029,7 +7076,14 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
The value returned is a TREE_LIST suitable for wrapping in a The value returned is a TREE_LIST suitable for wrapping in a
CONSTRUCTOR to use as the DECL_INITIAL for a vtable. If CONSTRUCTOR to use as the DECL_INITIAL for a vtable. If
NON_FN_ENTRIES_P is not NULL, *NON_FN_ENTRIES_P is set to the NON_FN_ENTRIES_P is not NULL, *NON_FN_ENTRIES_P is set to the
number of non-function entries in the vtable. */ number of non-function entries in the vtable.
It might seem that this function should never be called with a
BINFO for which BINFO_PRIMARY_MARKED_P holds, the vtable for such a
base is always subsumed by a derived class vtable. However, when
we are building construction vtables we do build vtables for
primary bases; we need these while the primary base is being
constructed. */
static tree static tree
build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
...@@ -7040,23 +7094,25 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) ...@@ -7040,23 +7094,25 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
int *non_fn_entries_p; int *non_fn_entries_p;
{ {
tree v; tree v;
tree vfun_inits; tree vfun_inits;
tree vbase; tree vbase;
vcall_offset_data vod; vtbl_init_data vid;
/* Initialize those parts of VOD that matter. */ /* Initialize VID. */
vod.derived = t; vid.binfo = binfo;
vod.inits = NULL_TREE; vid.derived = t;
vod.last_init = &vod.inits; vid.inits = NULL_TREE;
vod.primary_p = (binfo == TYPE_BINFO (t)); vid.last_init = &vid.inits;
vid.primary_vtbl_p = (binfo == TYPE_BINFO (t));
vid.ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
/* The first vbase or vcall offset is at index -3 in the vtable. */ /* The first vbase or vcall offset is at index -3 in the vtable. */
vod.index = ssize_int (-3); vid.index = ssize_int (-3);
/* Add entries to the vtable for RTTI. */ /* Add entries to the vtable for RTTI. */
build_rtti_vtbl_entries (binfo, rtti_binfo, &vod); build_rtti_vtbl_entries (binfo, rtti_binfo, &vid);
/* Add the vcall and vbase offset entries. */ /* Add the vcall and vbase offset entries. */
build_vcall_and_vbase_vtbl_entries (binfo, &vod); build_vcall_and_vbase_vtbl_entries (binfo, &vid);
/* Clear BINFO_VTABLE_PAATH_MARKED; it's set by /* Clear BINFO_VTABLE_PAATH_MARKED; it's set by
build_vbase_offset_vtbl_entries. */ build_vbase_offset_vtbl_entries. */
for (vbase = CLASSTYPE_VBASECLASSES (t); for (vbase = CLASSTYPE_VBASECLASSES (t);
...@@ -7065,7 +7121,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) ...@@ -7065,7 +7121,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)); CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
if (non_fn_entries_p) if (non_fn_entries_p)
*non_fn_entries_p = list_length (vod.inits); *non_fn_entries_p = list_length (vid.inits);
/* Go through all the ordinary virtual functions, building up /* Go through all the ordinary virtual functions, building up
initializers. */ initializers. */
...@@ -7116,32 +7172,32 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p) ...@@ -7116,32 +7172,32 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
vfun_inits = nreverse (vfun_inits); vfun_inits = nreverse (vfun_inits);
/* The negative offset initializers are also in reverse order. */ /* The negative offset initializers are also in reverse order. */
vod.inits = nreverse (vod.inits); vid.inits = nreverse (vid.inits);
/* Chain the two together. */ /* Chain the two together. */
return chainon (vod.inits, vfun_inits); return chainon (vid.inits, vfun_inits);
} }
/* Sets vod->inits to be the initializers for the vbase and vcall /* Sets vid->inits to be the initializers for the vbase and vcall
offsets in BINFO, which is in the hierarchy dominated by T. */ offsets in BINFO, which is in the hierarchy dominated by T. */
static void static void
build_vcall_and_vbase_vtbl_entries (binfo, vod) build_vcall_and_vbase_vtbl_entries (binfo, vid)
tree binfo; tree binfo;
vcall_offset_data *vod; vtbl_init_data *vid;
{ {
tree b; tree b;
/* If this is a derived class, we must first create entries /* If this is a derived class, we must first create entries
corresponding to the primary base class. */ corresponding to the primary base class. */
b = BINFO_PRIMARY_BINFO (binfo); b = get_primary_binfo (binfo);
if (b) if (b)
build_vcall_and_vbase_vtbl_entries (b, vod); build_vcall_and_vbase_vtbl_entries (b, vid);
/* Add the vbase entries for this base. */ /* Add the vbase entries for this base. */
build_vbase_offset_vtbl_entries (binfo, vod); build_vbase_offset_vtbl_entries (binfo, vid);
/* Add the vcall entries for this base. */ /* Add the vcall entries for this base. */
build_vcall_offset_vtbl_entries (binfo, vod); build_vcall_offset_vtbl_entries (binfo, vid);
} }
/* Returns the initializers for the vbase offset entries in the vtable /* Returns the initializers for the vbase offset entries in the vtable
...@@ -7150,9 +7206,9 @@ build_vcall_and_vbase_vtbl_entries (binfo, vod) ...@@ -7150,9 +7206,9 @@ build_vcall_and_vbase_vtbl_entries (binfo, vod)
where the next vbase offset will go. */ where the next vbase offset will go. */
static void static void
build_vbase_offset_vtbl_entries (binfo, vod) build_vbase_offset_vtbl_entries (binfo, vid)
tree binfo; tree binfo;
vcall_offset_data *vod; vtbl_init_data *vid;
{ {
tree vbase; tree vbase;
tree t; tree t;
...@@ -7167,7 +7223,7 @@ build_vbase_offset_vtbl_entries (binfo, vod) ...@@ -7167,7 +7223,7 @@ build_vbase_offset_vtbl_entries (binfo, vod)
if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo))) if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
return; return;
t = vod->derived; t = vid->derived;
/* Go through the virtual bases, adding the offsets. */ /* Go through the virtual bases, adding the offsets. */
for (vbase = TYPE_BINFO (BINFO_TYPE (binfo)); for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
...@@ -7192,10 +7248,10 @@ build_vbase_offset_vtbl_entries (binfo, vod) ...@@ -7192,10 +7248,10 @@ build_vbase_offset_vtbl_entries (binfo, vod)
/* Figure out where we can find this vbase offset. */ /* Figure out where we can find this vbase offset. */
delta = size_binop (MULT_EXPR, delta = size_binop (MULT_EXPR,
vod->index, vid->index,
convert (ssizetype, convert (ssizetype,
TYPE_SIZE_UNIT (vtable_entry_type))); TYPE_SIZE_UNIT (vtable_entry_type)));
if (vod->primary_p) if (vid->primary_vtbl_p)
BINFO_VPTR_FIELD (b) = delta; BINFO_VPTR_FIELD (b) = delta;
if (binfo != TYPE_BINFO (t)) if (binfo != TYPE_BINFO (t))
...@@ -7213,19 +7269,19 @@ build_vbase_offset_vtbl_entries (binfo, vod) ...@@ -7213,19 +7269,19 @@ build_vbase_offset_vtbl_entries (binfo, vod)
} }
/* The next vbase will come at a more negative offset. */ /* The next vbase will come at a more negative offset. */
vod->index = size_binop (MINUS_EXPR, vod->index, ssize_int (1)); vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
/* The initializer is the delta from BINFO to this virtual base. /* The initializer is the delta from BINFO to this virtual base.
The vbase offsets go in reverse inheritance-graph order, and The vbase offsets go in reverse inheritance-graph order, and
we are walking in inheritance graph order so these end up in we are walking in inheritance graph order so these end up in
the right order. */ the right order. */
delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo)); delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo));
*vod->last_init *vid->last_init
= build_tree_list (NULL_TREE, = build_tree_list (NULL_TREE,
fold (build1 (NOP_EXPR, fold (build1 (NOP_EXPR,
vtable_entry_type, vtable_entry_type,
delta))); delta)));
vod->last_init = &TREE_CHAIN (*vod->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
} }
} }
...@@ -7236,7 +7292,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7236,7 +7292,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
tree binfo; tree binfo;
void *data; void *data;
{ {
vcall_offset_data* vod; vtbl_init_data* vid;
tree derived_virtuals; tree derived_virtuals;
tree base_virtuals; tree base_virtuals;
tree binfo_inits; tree binfo_inits;
...@@ -7247,7 +7303,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7247,7 +7303,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
tree primary_binfo; tree primary_binfo;
int i; int i;
vod = (vcall_offset_data *) data; vid = (vtbl_init_data *) data;
binfo_inits = NULL_TREE; binfo_inits = NULL_TREE;
/* We might be a primary base class. Go up the inheritance /* We might be a primary base class. Go up the inheritance
...@@ -7256,8 +7312,21 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7256,8 +7312,21 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
non_primary_binfo = binfo; non_primary_binfo = binfo;
while (BINFO_INHERITANCE_CHAIN (non_primary_binfo)) while (BINFO_INHERITANCE_CHAIN (non_primary_binfo))
{ {
tree b = BINFO_INHERITANCE_CHAIN (non_primary_binfo); tree b;
if (BINFO_PRIMARY_BINFO (b) != non_primary_binfo)
/* If we have reached a virtual base, then it must be the
virtual base for which we are building vcall offsets. In
turn, the virtual base must be a (possibly indirect) primary
base of the class that we are initializing, or we wouldn't
care about its vtable offsets. */
if (TREE_VIA_VIRTUAL (non_primary_binfo))
{
non_primary_binfo = vid->binfo;
break;
}
b = BINFO_INHERITANCE_CHAIN (non_primary_binfo);
if (get_primary_binfo (b) != non_primary_binfo)
break; break;
non_primary_binfo = b; non_primary_binfo = b;
} }
...@@ -7266,7 +7335,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7266,7 +7335,7 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
class. */ class. */
base_virtuals = BINFO_VIRTUALS (binfo); base_virtuals = BINFO_VIRTUALS (binfo);
derived_virtuals = BINFO_VIRTUALS (non_primary_binfo); derived_virtuals = BINFO_VIRTUALS (non_primary_binfo);
primary_binfo = BINFO_PRIMARY_BINFO (binfo); primary_binfo = get_primary_binfo (binfo);
if (primary_binfo) if (primary_binfo)
for (i = 0; i < CLASSTYPE_VSIZE (BINFO_TYPE (primary_binfo)); ++i) for (i = 0; i < CLASSTYPE_VSIZE (BINFO_TYPE (primary_binfo)); ++i)
{ {
...@@ -7289,11 +7358,11 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7289,11 +7358,11 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
signature as FN, then we do not need a second vcall offset. signature as FN, then we do not need a second vcall offset.
Check the list of functions already present in the derived Check the list of functions already present in the derived
class vtable. */ class vtable. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (vod->fns); ++i) for (i = 0; i < VARRAY_ACTIVE_SIZE (vid->fns); ++i)
{ {
tree derived_entry; tree derived_entry;
derived_entry = VARRAY_TREE (vod->fns, i); derived_entry = VARRAY_TREE (vid->fns, i);
if (same_signature_p (BV_FN (derived_entry), fn)) if (same_signature_p (BV_FN (derived_entry), fn))
{ {
BV_VCALL_INDEX (derived_virtuals) BV_VCALL_INDEX (derived_virtuals)
...@@ -7301,42 +7370,35 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7301,42 +7370,35 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
break; break;
} }
} }
if (i != VARRAY_ACTIVE_SIZE (vod->fns)) if (i != VARRAY_ACTIVE_SIZE (vid->fns))
continue; continue;
/* The FN comes from BASE. So, we must caculate the adjustment /* The FN comes from BASE. So, we must caculate the adjustment
from the virtual base that derived from BINFO to BASE. */ from the virtual base that derived from BINFO to BASE. */
base = DECL_CONTEXT (fn); base = DECL_CONTEXT (fn);
base_binfo = get_binfo (base, vod->derived, /*protect=*/0); base_binfo = get_binfo (base, vid->derived, /*protect=*/0);
/* Compute the vcall offset. */ /* Compute the vcall offset. */
*vod->last_init *vid->last_init
= (build_tree_list = (build_tree_list
(NULL_TREE, (NULL_TREE,
fold (build1 (NOP_EXPR, vtable_entry_type, fold (build1 (NOP_EXPR, vtable_entry_type,
size_diffop (BINFO_OFFSET (base_binfo), size_diffop (BINFO_OFFSET (base_binfo),
BINFO_OFFSET (vod->vbase)))))); BINFO_OFFSET (vid->vbase))))));
vod->last_init = &TREE_CHAIN (*vod->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
/* If there is already a vcall index, then we are processing a
construction vtable. The index should be the same as it was
when we processed the vtable for the base class. */
if (BV_VCALL_INDEX (derived_virtuals))
my_friendly_assert (tree_int_cst_equal (BV_VCALL_INDEX
(derived_virtuals),
vod->index),
20000516);
/* Keep track of the vtable index where this vcall offset can be /* Keep track of the vtable index where this vcall offset can be
found. */ found. For a construction vtable, we already made this
else annotation when we build the original vtable. */
BV_VCALL_INDEX (derived_virtuals) = vod->index; if (!vid->ctor_vtbl_p)
BV_VCALL_INDEX (derived_virtuals) = vid->index;
/* The next vcall offset will be found at a more negative /* The next vcall offset will be found at a more negative
offset. */ offset. */
vod->index = size_binop (MINUS_EXPR, vod->index, ssize_int (1)); vid->index = size_binop (MINUS_EXPR, vid->index, ssize_int (1));
/* Keep track of this function. */ /* Keep track of this function. */
VARRAY_PUSH_TREE (vod->fns, derived_virtuals); VARRAY_PUSH_TREE (vid->fns, derived_virtuals);
} }
return NULL_TREE; return NULL_TREE;
...@@ -7344,12 +7406,12 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) ...@@ -7344,12 +7406,12 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data)
/* Adds the initializers for the vcall offset entries in the vtable /* Adds the initializers for the vcall offset entries in the vtable
for BINFO (which is part of the class hierarchy dominated by T) to for BINFO (which is part of the class hierarchy dominated by T) to
VOD->INITS. */ VID->INITS. */
static void static void
build_vcall_offset_vtbl_entries (binfo, vod) build_vcall_offset_vtbl_entries (binfo, vid)
tree binfo; tree binfo;
vcall_offset_data *vod; vtbl_init_data *vid;
{ {
/* Under the old ABI, the adjustments to the `this' pointer were made /* Under the old ABI, the adjustments to the `this' pointer were made
elsewhere. */ elsewhere. */
...@@ -7382,14 +7444,14 @@ build_vcall_offset_vtbl_entries (binfo, vod) ...@@ -7382,14 +7444,14 @@ build_vcall_offset_vtbl_entries (binfo, vod)
in our non-virtual bases vtables. For each base, the entries in our non-virtual bases vtables. For each base, the entries
appear in the same order as in the base; but the bases themselves appear in the same order as in the base; but the bases themselves
appear in reverse depth-first, left-to-right order. */ appear in reverse depth-first, left-to-right order. */
vod->vbase = binfo; vid->vbase = binfo;
VARRAY_TREE_INIT (vod->fns, 32, "fns"); VARRAY_TREE_INIT (vid->fns, 32, "fns");
dfs_walk_real (binfo, dfs_walk_real (binfo,
dfs_build_vcall_offset_vtbl_entries, dfs_build_vcall_offset_vtbl_entries,
NULL, NULL,
dfs_skip_vbases, dfs_skip_vbases,
vod); vid);
VARRAY_FREE (vod->fns); VARRAY_FREE (vid->fns);
} }
/* Return vtbl initializers for the RTTI entries coresponding to the /* Return vtbl initializers for the RTTI entries coresponding to the
...@@ -7397,10 +7459,10 @@ build_vcall_offset_vtbl_entries (binfo, vod) ...@@ -7397,10 +7459,10 @@ build_vcall_offset_vtbl_entries (binfo, vod)
by RTTI_BINFO. */ by RTTI_BINFO. */
static void static void
build_rtti_vtbl_entries (binfo, rtti_binfo, vod) build_rtti_vtbl_entries (binfo, rtti_binfo, vid)
tree binfo; tree binfo;
tree rtti_binfo; tree rtti_binfo;
vcall_offset_data *vod; vtbl_init_data *vid;
{ {
tree b; tree b;
tree t; tree t;
...@@ -7423,7 +7485,7 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod) ...@@ -7423,7 +7485,7 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod)
{ {
tree primary_base; tree primary_base;
primary_base = BINFO_PRIMARY_BINFO (b); primary_base = get_primary_binfo (b);
if (!BINFO_PRIMARY_MARKED_P (primary_base)) if (!BINFO_PRIMARY_MARKED_P (primary_base))
break; break;
b = primary_base; b = primary_base;
...@@ -7459,8 +7521,8 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod) ...@@ -7459,8 +7521,8 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod)
init = build_vtable_entry (offset, NULL_TREE, init, init = build_vtable_entry (offset, NULL_TREE, init,
/*generate_with_vtable_p=*/0); /*generate_with_vtable_p=*/0);
} }
*vod->last_init = build_tree_list (NULL_TREE, init); *vid->last_init = build_tree_list (NULL_TREE, init);
vod->last_init = &TREE_CHAIN (*vod->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
/* Add the offset-to-top entry. It comes earlier in the vtable that /* Add the offset-to-top entry. It comes earlier in the vtable that
the the typeinfo entry. */ the the typeinfo entry. */
...@@ -7470,8 +7532,8 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod) ...@@ -7470,8 +7532,8 @@ build_rtti_vtbl_entries (binfo, rtti_binfo, vod)
we can put it in the vtable. */ we can put it in the vtable. */
init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
TREE_CONSTANT (init) = 1; TREE_CONSTANT (init) = 1;
*vod->last_init = build_tree_list (NULL_TREE, init); *vid->last_init = build_tree_list (NULL_TREE, init);
vod->last_init = &TREE_CHAIN (*vod->last_init); vid->last_init = &TREE_CHAIN (*vid->last_init);
} }
} }
......
...@@ -69,9 +69,8 @@ Boston, MA 02111-1307, USA. */ ...@@ -69,9 +69,8 @@ Boston, MA 02111-1307, USA. */
or FIELD_DECL). or FIELD_DECL).
NEED_TEMPORARY_P (in REF_BIND, BASE_CONV) NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
5: BINFO_PRIMARY_MARKED_P (in BINFO) 5: Unused.
6: BINFO_VBASE_PRIMARY_P (in BINFO) 6: BINFO_ACCESS (in BINFO)
BINFO_ACCESS (in BINFO)
Usage of TYPE_LANG_FLAG_?: Usage of TYPE_LANG_FLAG_?:
0: C_TYPE_FIELDS_READONLY (in RECORD_TYPE or UNION_TYPE). 0: C_TYPE_FIELDS_READONLY (in RECORD_TYPE or UNION_TYPE).
...@@ -100,7 +99,10 @@ Boston, MA 02111-1307, USA. */ ...@@ -100,7 +99,10 @@ Boston, MA 02111-1307, USA. */
DECL_THUNK_P (in a member FUNCTION_DECL) DECL_THUNK_P (in a member FUNCTION_DECL)
Usage of language-independent fields in a language-dependent manner: Usage of language-independent fields in a language-dependent manner:
TREE_USED
This field is BINFO_INDIRECT_PRIMARY_P in a BINFO.
TYPE_ALIAS_SET TYPE_ALIAS_SET
This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so
forth as a substitute for the mark bits provided in `lang_type'. forth as a substitute for the mark bits provided in `lang_type'.
...@@ -1391,8 +1393,8 @@ struct lang_type ...@@ -1391,8 +1393,8 @@ struct lang_type
unsigned dummy : 8; unsigned dummy : 8;
int vsize; int vsize;
int vfield_parent;
tree primary_base;
tree vfields; tree vfields;
tree vbases; tree vbases;
tree tags; tree tags;
...@@ -1562,34 +1564,16 @@ struct lang_type ...@@ -1562,34 +1564,16 @@ struct lang_type
nested member class templates. */ nested member class templates. */
#define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC(NODE)->tags) #define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC(NODE)->tags)
/* If this value is non-negative, it is the index (in the
TYPE_BINFO_BASETYPES) for the base-class whose vtable pointer we
are reusing. For example, in D : B1, B2, PARENT would be 0, if D's
vtable came from B1, 1, if D's vtable came from B2. */
#define CLASSTYPE_VFIELD_PARENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfield_parent)
/* Nonzero if NODE has a primary base class, i.e., a base class with /* Nonzero if NODE has a primary base class, i.e., a base class with
which it shares the virtual fucntion table pointer. */ which it shares the virtual fucntion table pointer. */
#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \ #define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \
(CLASSTYPE_VFIELD_PARENT (NODE) != -1) (CLASSTYPE_PRIMARY_BINFO (NODE) != NULL_TREE)
/* If non-NULL, this is the binfo for the primary base class, i.e., /* If non-NULL, this is the binfo for the primary base class, i.e.,
the base class which contains the virtual function table pointer the base class which contains the virtual function table pointer
for this class. */ for this class. */
#define CLASSTYPE_PRIMARY_BINFO(NODE) \ #define CLASSTYPE_PRIMARY_BINFO(NODE) \
(BINFO_PRIMARY_BINFO (TYPE_BINFO (NODE))) (TYPE_LANG_SPECIFIC (NODE)->primary_base)
/* If non-NULL, this is the binfo for the primary base of BINFO. Note
that in a complex hierarchy the resulting BINFO may not actually
*be* primary. In particular if the resulting BINFO is a virtual
base, and it occurs elsewhere in the hierarchy, then this
occurrence may not actually be a primary base in the complete
object. Check BINFO_PRIMARY_MARKED_P to be sure. */
#define BINFO_PRIMARY_BINFO(NODE) \
(CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (NODE)) \
? BINFO_BASETYPE (NODE, \
CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (NODE))) \
: NULL_TREE)
/* The number of virtual functions present in this class' virtual /* The number of virtual functions present in this class' virtual
function table. */ function table. */
...@@ -1752,11 +1736,8 @@ struct lang_type ...@@ -1752,11 +1736,8 @@ struct lang_type
class of a non-primary virtual base. This flag is only valid for class of a non-primary virtual base. This flag is only valid for
paths (given by BINFO_INHERITANCE_CHAIN) that really exist in the paths (given by BINFO_INHERITANCE_CHAIN) that really exist in the
final object. */ final object. */
#define BINFO_PRIMARY_MARKED_P(NODE) TREE_LANG_FLAG_5 (NODE) #define BINFO_PRIMARY_MARKED_P(NODE) \
(BINFO_PRIMARY_BASE_OF (NODE) != NULL_TREE)
/* Nonzero if the virtual baseclass with the type given by this BINFO
is primary *somewhere* in the hierarchy. */
#define BINFO_VBASE_PRIMARY_P(NODE) TREE_LANG_FLAG_6 (NODE)
/* The index in the VTT where this subobject's sub-VTT can be found. /* The index in the VTT where this subobject's sub-VTT can be found.
NULL_TREE if there is no sub-VTT. */ NULL_TREE if there is no sub-VTT. */
...@@ -1766,10 +1747,21 @@ struct lang_type ...@@ -1766,10 +1747,21 @@ struct lang_type
found. NULL_TREE if there is no secondary vptr in the VTT. */ found. NULL_TREE if there is no secondary vptr in the VTT. */
#define BINFO_VPTR_INDEX(NODE) TREE_VEC_ELT ((NODE), 9) #define BINFO_VPTR_INDEX(NODE) TREE_VEC_ELT ((NODE), 9)
/* The binfo of which NODE is a primary base. (This is different from
BINFO_INHERITANCE_CHAIN for virtual base because a virtual base is
sometimes a primary base for a class for which it is not an
immediate base.) */
#define BINFO_PRIMARY_BASE_OF(NODE) TREE_VEC_ELT ((NODE), 10)
/* Nonzero if this binfo declares a virtual function which is /* Nonzero if this binfo declares a virtual function which is
overridden along a virtual path. */ overridden along a virtual path. */
#define BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P(NODE) TREE_LANG_FLAG_2 (NODE) #define BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P(NODE) TREE_LANG_FLAG_2 (NODE)
/* Nonzero if this binfo is an indirect primary base, i.e. a virtual
base that is a primary base of some of other class in the
hierarchy. */
#define BINFO_INDIRECT_PRIMARY_P(NODE) TREE_USED (NODE)
/* Used by various search routines. */ /* Used by various search routines. */
#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) #define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
...@@ -3844,6 +3836,7 @@ extern void note_name_declared_in_class PARAMS ((tree, tree)); ...@@ -3844,6 +3836,7 @@ extern void note_name_declared_in_class PARAMS ((tree, tree));
extern tree get_vtbl_decl_for_binfo PARAMS ((tree)); extern tree get_vtbl_decl_for_binfo PARAMS ((tree));
extern tree in_charge_arg_for_name PARAMS ((tree)); extern tree in_charge_arg_for_name PARAMS ((tree));
extern tree get_vtt_name PARAMS ((tree)); extern tree get_vtt_name PARAMS ((tree));
extern tree get_primary_binfo PARAMS ((tree));
/* in cvt.c */ /* in cvt.c */
extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree)); extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree));
......
...@@ -15007,6 +15007,7 @@ lang_mark_tree (t) ...@@ -15007,6 +15007,7 @@ lang_mark_tree (t)
&& TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE)) && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))
{ {
ggc_mark (lt); ggc_mark (lt);
ggc_mark_tree (lt->primary_base);
ggc_mark_tree (lt->vfields); ggc_mark_tree (lt->vfields);
ggc_mark_tree (lt->vbases); ggc_mark_tree (lt->vbases);
ggc_mark_tree (lt->tags); ggc_mark_tree (lt->tags);
......
...@@ -2199,7 +2199,7 @@ get_shared_vbase_if_not_primary (binfo, data) ...@@ -2199,7 +2199,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_PRIMARY_MARKED_P (binfo))
return NULL_TREE; return NULL_TREE;
} }
...@@ -2883,7 +2883,7 @@ find_vbase_instance (base, type) ...@@ -2883,7 +2883,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_PRIMARY_MARKED_P (instance))
return instance; return instance;
return dfs_walk (TYPE_BINFO (type), return dfs_walk (TYPE_BINFO (type),
...@@ -3357,21 +3357,9 @@ binfo_for_vtable (var) ...@@ -3357,21 +3357,9 @@ binfo_for_vtable (var)
tree var; tree var;
{ {
tree binfo = TYPE_BINFO (DECL_CONTEXT (var)); tree binfo = TYPE_BINFO (DECL_CONTEXT (var));
tree binfos;
int i;
while (1) while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
{ binfo = get_primary_binfo (binfo);
binfos = BINFO_BASETYPES (binfo);
if (binfos == NULL_TREE)
break;
i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
if (i == -1)
break;
binfo = TREE_VEC_ELT (binfos, i);
}
return binfo; return binfo;
} }
......
...@@ -687,6 +687,7 @@ unshare_base_binfos (binfo) ...@@ -687,6 +687,7 @@ unshare_base_binfos (binfo)
TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo); TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo);
TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo); TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo);
BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
BINFO_PRIMARY_BASE_OF (new_binfo) = NULL_TREE;
unshare_base_binfos (new_binfo); unshare_base_binfos (new_binfo);
} }
} }
...@@ -851,7 +852,7 @@ make_binfo (offset, binfo, vtable, virtuals) ...@@ -851,7 +852,7 @@ make_binfo (offset, binfo, vtable, virtuals)
tree offset, binfo; tree offset, binfo;
tree vtable, virtuals; tree vtable, virtuals;
{ {
tree new_binfo = make_tree_vec (10); tree new_binfo = make_tree_vec (11);
tree type; tree type;
if (TREE_CODE (binfo) == TREE_VEC) if (TREE_CODE (binfo) == TREE_VEC)
......
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