cp-tree.h (dfs_skip_vbases): New function.
* cp-tree.h (dfs_skip_vbases): New function. (find_vbase_instance): Likewise. * class.c (determine_primary_base): Allow a nearly empty base to serve as a primary base class under the new ABI. (get_class_offset_1): Rename to ... (dfs_get_class_offset): ... this. Simplify. Don't issue error messages here. (get_class_offset): Use it. Issue error messages here. (dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to find the right copies of virtual bases. (fixup_vtable_deltas1): Rename to ... (dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual bases as primary bases. (fixup_vtable_deltas): Remove. (override_one_vtable): Handle virtual bases as primary bases. (merge_overrides): Likewise. (finish_struct_1): Likewise. (dump_class_hierarchy): Dump primary-ness of bases as well. * search.c (mark_primary_bases): Use a pre-order traversal to handle primary virtual bases. (dfs_skip_vbases): New fiunction. (expand_upcast_fixups): Adjust to handle primary virtual bases. (fixup_virtual_upcast_offsets): Likewise. (fixup_all_virtual_upcast_offsets): Likewise. (dfs_find_vbase_instances): New function. (find_vbase_instance): Likewise. From-SVN: r31360
This commit is contained in:
parent
e5778b1e84
commit
dd42e13519
@ -1,3 +1,32 @@
|
||||
2000-01-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (dfs_skip_vbases): New function.
|
||||
(find_vbase_instance): Likewise.
|
||||
* class.c (determine_primary_base): Allow a nearly empty base to
|
||||
serve as a primary base class under the new ABI.
|
||||
(get_class_offset_1): Rename to ...
|
||||
(dfs_get_class_offset): ... this. Simplify. Don't issue error
|
||||
messages here.
|
||||
(get_class_offset): Use it. Issue error messages here.
|
||||
(dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to
|
||||
find the right copies of virtual bases.
|
||||
(fixup_vtable_deltas1): Rename to ...
|
||||
(dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual
|
||||
bases as primary bases.
|
||||
(fixup_vtable_deltas): Remove.
|
||||
(override_one_vtable): Handle virtual bases as primary bases.
|
||||
(merge_overrides): Likewise.
|
||||
(finish_struct_1): Likewise.
|
||||
(dump_class_hierarchy): Dump primary-ness of bases as well.
|
||||
* search.c (mark_primary_bases): Use a pre-order traversal to
|
||||
handle primary virtual bases.
|
||||
(dfs_skip_vbases): New fiunction.
|
||||
(expand_upcast_fixups): Adjust to handle primary virtual bases.
|
||||
(fixup_virtual_upcast_offsets): Likewise.
|
||||
(fixup_all_virtual_upcast_offsets): Likewise.
|
||||
(dfs_find_vbase_instances): New function.
|
||||
(find_vbase_instance): Likewise.
|
||||
|
||||
2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
|
||||
|
||||
* lex.c (DIR_SEPARATOR): Delete macro.
|
||||
|
182
gcc/cp/class.c
182
gcc/cp/class.c
@ -82,8 +82,7 @@ static tree get_basefndecls PROTO((tree, tree));
|
||||
static void set_rtti_entry PROTO((tree, tree, tree));
|
||||
static void build_vtable PROTO((tree, tree));
|
||||
static void prepare_fresh_vtable PROTO((tree, tree));
|
||||
static void fixup_vtable_deltas1 PROTO((tree, tree));
|
||||
static void fixup_vtable_deltas PROTO((tree, int, tree));
|
||||
static tree dfs_fixup_vtable_deltas PROTO((tree, void *));
|
||||
static tree dfs_finish_vtbls PROTO((tree, void *));
|
||||
static void finish_vtbls PROTO((tree));
|
||||
static void modify_vtable_entry PROTO((tree, tree, tree));
|
||||
@ -100,7 +99,7 @@ static void merge_overrides PROTO((tree, tree, int, tree));
|
||||
static void override_one_vtable PROTO((tree, tree, tree));
|
||||
static void mark_overriders PROTO((tree, tree));
|
||||
static void check_for_override PROTO((tree, tree));
|
||||
static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree));
|
||||
static tree dfs_get_class_offset PROTO((tree, void *));
|
||||
static tree get_class_offset PROTO((tree, tree, tree, tree));
|
||||
static void modify_one_vtable PROTO((tree, tree, tree));
|
||||
static tree dfs_modify_vtables PROTO((tree, void *));
|
||||
@ -1672,9 +1671,25 @@ determine_primary_base (t, has_virtual_p)
|
||||
if (!TYPE_VFIELD (t))
|
||||
CLASSTYPE_VFIELD_PARENT (t) = -1;
|
||||
|
||||
/* Now that we know what the primary base class is, we can run
|
||||
through the entire hierarchy marking the primary bases for future
|
||||
reference. */
|
||||
/* The new ABI allows for the use of a "nearly-empty" virtual base
|
||||
class as the primary base class if no non-virtual polymorphic
|
||||
base can be found. */
|
||||
if (flag_new_abi && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
||||
for (i = 0; i < n_baseclasses; ++i)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
|
||||
tree basetype = BINFO_TYPE (base_binfo);
|
||||
|
||||
if (TREE_VIA_VIRTUAL (base_binfo)
|
||||
&& CLASSTYPE_NEARLY_EMPTY_P (basetype))
|
||||
{
|
||||
set_primary_base (t, i, has_virtual_p);
|
||||
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the primary base classes at this point. */
|
||||
mark_primary_bases (t);
|
||||
}
|
||||
|
||||
@ -2266,6 +2281,9 @@ overrides (fndecl, base_fndecl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns the BINFO_OFFSET for the base of BINFO that has the same
|
||||
type as CONTEXT. */
|
||||
|
||||
static tree
|
||||
get_class_offset_1 (parent, binfo, context, t, fndecl)
|
||||
tree parent, binfo, context, t, fndecl;
|
||||
@ -2311,14 +2329,37 @@ get_class_offset_1 (parent, binfo, context, t, fndecl)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* Get the offset to the CONTEXT subobject that is related to the
|
||||
given BINFO. */
|
||||
/* Called from get_class_offset via dfs_walk. */
|
||||
|
||||
static tree
|
||||
dfs_get_class_offset (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
tree list = (tree) data;
|
||||
tree context = TREE_TYPE (list);
|
||||
|
||||
if (same_type_p (BINFO_TYPE (binfo), context))
|
||||
{
|
||||
if (TREE_VALUE (list))
|
||||
return error_mark_node;
|
||||
else
|
||||
TREE_VALUE (list) = BINFO_OFFSET (binfo);
|
||||
}
|
||||
|
||||
SET_BINFO_MARKED (binfo);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns the BINFO_OFFSET for the subobject of BINFO that has the
|
||||
type given by CONTEXT. */
|
||||
|
||||
static tree
|
||||
get_class_offset (context, t, binfo, fndecl)
|
||||
tree context, t, binfo, fndecl;
|
||||
{
|
||||
tree first_binfo = binfo;
|
||||
tree list;
|
||||
tree offset;
|
||||
int i;
|
||||
|
||||
@ -2338,11 +2379,28 @@ get_class_offset (context, t, binfo, fndecl)
|
||||
return BINFO_OFFSET (binfo);
|
||||
}
|
||||
|
||||
/* Ok, not found in the less derived binfos, now check the more
|
||||
derived binfos. */
|
||||
offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl);
|
||||
if (offset==0 || TREE_CODE (offset) != INTEGER_CST)
|
||||
my_friendly_abort (999); /* we have to find it. */
|
||||
list = build_tree_list (t, NULL_TREE);
|
||||
TREE_TYPE (list) = context;
|
||||
offset = dfs_walk (TYPE_BINFO (t),
|
||||
dfs_get_class_offset,
|
||||
dfs_unmarked_real_bases_queue_p,
|
||||
list);
|
||||
dfs_walk (TYPE_BINFO (t), dfs_unmark, dfs_marked_real_bases_queue_p, t);
|
||||
|
||||
if (offset == error_mark_node)
|
||||
{
|
||||
error ("every virtual function must have a unique final overrider");
|
||||
cp_error (" found two (or more) `%T' class subobjects in `%T'",
|
||||
context, t);
|
||||
cp_error (" with virtual `%D' from virtual base class", fndecl);
|
||||
offset = integer_zero_node;
|
||||
}
|
||||
else
|
||||
offset = TREE_VALUE (list);
|
||||
|
||||
my_friendly_assert (offset != NULL_TREE, 999);
|
||||
my_friendly_assert (TREE_CODE (offset) == INTEGER_CST, 999);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
@ -2473,9 +2531,6 @@ dfs_modify_vtables (binfo, data)
|
||||
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
|
||||
{
|
||||
tree list = (tree) data;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
binfo = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
|
||||
modify_one_vtable (binfo, TREE_PURPOSE (list), TREE_VALUE (list));
|
||||
}
|
||||
|
||||
@ -2499,13 +2554,23 @@ modify_all_vtables (t, fndecl)
|
||||
|
||||
/* Fixup all the delta entries in this one vtable that need updating. */
|
||||
|
||||
static void
|
||||
fixup_vtable_deltas1 (binfo, t)
|
||||
tree binfo, t;
|
||||
static tree
|
||||
dfs_fixup_vtable_deltas (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
tree virtuals;
|
||||
unsigned HOST_WIDE_INT n;
|
||||
|
||||
tree t = (tree) data;
|
||||
|
||||
while (BINFO_PRIMARY_MARKED_P (binfo))
|
||||
{
|
||||
binfo = BINFO_INHERITANCE_CHAIN (binfo);
|
||||
/* If BINFO is virtual then we'll handle this base later. */
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
|
||||
|
||||
while (virtuals)
|
||||
@ -2559,33 +2624,8 @@ fixup_vtable_deltas1 (binfo, t)
|
||||
++n;
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup all the delta entries in all the direct vtables that need updating.
|
||||
This happens when we have non-overridden virtual functions from a
|
||||
virtual base class, that are at a different offset, in the new
|
||||
hierarchy, because the layout of the virtual bases has changed. */
|
||||
|
||||
static void
|
||||
fixup_vtable_deltas (binfo, init_self, t)
|
||||
tree binfo;
|
||||
int init_self;
|
||||
tree t;
|
||||
{
|
||||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
|
||||
for (i = 0; i < n_baselinks; i++)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
int is_not_base_vtable
|
||||
= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
|
||||
if (! TREE_VIA_VIRTUAL (base_binfo))
|
||||
fixup_vtable_deltas (base_binfo, is_not_base_vtable, t);
|
||||
}
|
||||
/* Should we use something besides CLASSTYPE_VFIELDS? */
|
||||
if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
|
||||
fixup_vtable_deltas1 (binfo, t);
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Here, we already know that they match in every respect.
|
||||
@ -2622,8 +2662,26 @@ override_one_vtable (binfo, old, t)
|
||||
{
|
||||
tree virtuals;
|
||||
tree old_virtuals;
|
||||
tree orig_binfo;
|
||||
tree orig_virtuals;
|
||||
enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED;
|
||||
|
||||
/* Either or both of BINFO or OLD might be primary base classes
|
||||
because merge_overrides is called with a vbase from the class we
|
||||
are definining and the corresponding vbase from one of its direct
|
||||
bases. */
|
||||
orig_binfo = binfo;
|
||||
while (BINFO_PRIMARY_MARKED_P (binfo))
|
||||
{
|
||||
binfo = BINFO_INHERITANCE_CHAIN (binfo);
|
||||
/* If BINFO is virtual, then we'll handle this virtual base when
|
||||
later. */
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
return;
|
||||
}
|
||||
while (BINFO_PRIMARY_MARKED_P (old))
|
||||
old = BINFO_INHERITANCE_CHAIN (old);
|
||||
|
||||
/* If we have already committed to modifying it, then don't try and
|
||||
reuse another vtable. */
|
||||
if (BINFO_NEW_VTABLE_MARKED (binfo))
|
||||
@ -2631,8 +2689,9 @@ override_one_vtable (binfo, old, t)
|
||||
|
||||
virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL);
|
||||
old_virtuals = skip_rtti_stuff (old, BINFO_TYPE (binfo), NULL);
|
||||
orig_virtuals = skip_rtti_stuff (orig_binfo, BINFO_TYPE (binfo), NULL);
|
||||
|
||||
while (virtuals)
|
||||
while (orig_virtuals)
|
||||
{
|
||||
tree fndecl = TREE_VALUE (virtuals);
|
||||
tree old_fndecl = TREE_VALUE (old_virtuals);
|
||||
@ -2705,6 +2764,7 @@ override_one_vtable (binfo, old, t)
|
||||
}
|
||||
virtuals = TREE_CHAIN (virtuals);
|
||||
old_virtuals = TREE_CHAIN (old_virtuals);
|
||||
orig_virtuals = TREE_CHAIN (orig_virtuals);
|
||||
}
|
||||
|
||||
/* Let's reuse the old vtable. */
|
||||
@ -2739,8 +2799,8 @@ merge_overrides (binfo, old, do_self, t)
|
||||
{
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
tree old_base_binfo = TREE_VEC_ELT (old_binfos, i);
|
||||
int is_not_base_vtable
|
||||
= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
|
||||
int is_not_base_vtable
|
||||
= !BINFO_PRIMARY_MARKED_P (base_binfo);
|
||||
if (! TREE_VIA_VIRTUAL (base_binfo))
|
||||
merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t);
|
||||
}
|
||||
@ -4563,9 +4623,15 @@ finish_struct_1 (t)
|
||||
vbases = CLASSTYPE_VBASECLASSES (basetype);
|
||||
while (vbases)
|
||||
{
|
||||
merge_overrides (binfo_member (BINFO_TYPE (vbases),
|
||||
CLASSTYPE_VBASECLASSES (t)),
|
||||
vbases, 1, t);
|
||||
tree vbase;
|
||||
tree basetype_vbase;
|
||||
|
||||
vbase
|
||||
= find_vbase_instance (BINFO_TYPE (vbases), t);
|
||||
basetype_vbase
|
||||
= find_vbase_instance (BINFO_TYPE (vbases), basetype);
|
||||
|
||||
merge_overrides (vbase, basetype_vbase, 1, t);
|
||||
vbases = TREE_CHAIN (vbases);
|
||||
}
|
||||
}
|
||||
@ -4613,11 +4679,14 @@ finish_struct_1 (t)
|
||||
vbases = CLASSTYPE_VBASECLASSES (t);
|
||||
while (vbases)
|
||||
{
|
||||
tree vbase;
|
||||
|
||||
/* We might be able to shorten the amount of work we do by
|
||||
only doing this for vtables that come from virtual bases
|
||||
that have differing offsets, but don't want to miss any
|
||||
entries. */
|
||||
fixup_vtable_deltas (vbases, 1, t);
|
||||
vbase = find_vbase_instance (BINFO_TYPE (vbases), t);
|
||||
dfs_walk (vbase, dfs_fixup_vtable_deltas, dfs_skip_vbases, t);
|
||||
vbases = TREE_CHAIN (vbases);
|
||||
}
|
||||
}
|
||||
@ -6015,10 +6084,11 @@ dump_class_hierarchy (binfo, indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf (stderr, "%*s0x%x (%s) %d\n", indent, "",
|
||||
fprintf (stderr, "%*s0x%x (%s) %d %s\n", indent, "",
|
||||
(unsigned int) binfo,
|
||||
type_as_string (binfo, TS_PLAIN),
|
||||
TREE_INT_CST_LOW (BINFO_OFFSET (binfo)));
|
||||
TREE_INT_CST_LOW (BINFO_OFFSET (binfo)),
|
||||
BINFO_PRIMARY_MARKED_P (binfo) ? "primary" : "");
|
||||
|
||||
for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
|
||||
dump_class_hierarchy (BINFO_BASETYPE (binfo, i), indent + 2);
|
||||
|
@ -3954,8 +3954,10 @@ extern tree dfs_skip_nonprimary_vbases_unmarkedp PROTO((tree, void *));
|
||||
extern tree dfs_skip_nonprimary_vbases_markedp PROTO((tree, void *));
|
||||
extern tree dfs_unmarked_real_bases_queue_p PROTO((tree, void *));
|
||||
extern tree dfs_marked_real_bases_queue_p PROTO((tree, void *));
|
||||
extern tree dfs_skip_vbases PROTO((tree, void *));
|
||||
extern void mark_primary_bases PROTO((tree));
|
||||
extern tree convert_pointer_to_vbase PROTO((tree, tree));
|
||||
extern tree find_vbase_instance PROTO((tree, tree));
|
||||
|
||||
/* in semantics.c */
|
||||
extern void finish_expr_stmt PROTO((tree));
|
||||
|
@ -151,6 +151,7 @@ static int template_self_reference_p PROTO ((tree, tree));
|
||||
static void fixup_all_virtual_upcast_offsets PROTO ((tree, tree));
|
||||
static tree dfs_mark_primary_bases PROTO((tree, void *));
|
||||
static tree get_shared_vbase_if_not_primary PROTO((tree, tree));
|
||||
static tree dfs_find_vbase_instance PROTO((tree, void *));
|
||||
|
||||
/* Allocate a level of searching. */
|
||||
|
||||
@ -2189,9 +2190,14 @@ mark_primary_bases (type)
|
||||
{
|
||||
tree vbase;
|
||||
|
||||
/* Mark the TYPE_BINFO hierarchy. */
|
||||
dfs_walk (TYPE_BINFO (type), dfs_mark_primary_bases,
|
||||
dfs_skip_nonprimary_vbases_unmarkedp, type);
|
||||
/* Mark the TYPE_BINFO hierarchy. We need to mark primary bases in
|
||||
pre-order to deal with primary virtual bases. (The virtual base
|
||||
would be skipped if it were not marked as primary, and that
|
||||
requires getting to dfs_mark_primary_bases before
|
||||
dfs_skip_nonprimary_vbases_unmarkedp has a chance to skip the
|
||||
virtual base.) */
|
||||
dfs_walk_real (TYPE_BINFO (type), dfs_mark_primary_bases, NULL,
|
||||
dfs_skip_nonprimary_vbases_unmarkedp, type);
|
||||
|
||||
/* Now go through the virtual base classes. Any that are not
|
||||
already primary will need to be allocated in TYPE, and so we need
|
||||
@ -2289,6 +2295,20 @@ dfs_marked_real_bases_queue_p (binfo, data)
|
||||
return binfo ? markedp (binfo, NULL) : NULL_TREE;
|
||||
}
|
||||
|
||||
/* A queue function that skips all virtual bases (and their
|
||||
bases). */
|
||||
|
||||
tree
|
||||
dfs_skip_vbases (binfo, data)
|
||||
tree binfo;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
return NULL_TREE;
|
||||
|
||||
return binfo;
|
||||
}
|
||||
|
||||
/* Called via dfs_walk from dfs_get_pure_virtuals. */
|
||||
|
||||
static tree
|
||||
@ -2798,7 +2818,14 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
|
||||
tree vc;
|
||||
tree delta;
|
||||
unsigned HOST_WIDE_INT n;
|
||||
|
||||
|
||||
while (BINFO_PRIMARY_MARKED_P (binfo))
|
||||
{
|
||||
binfo = BINFO_INHERITANCE_CHAIN (binfo);
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
return;
|
||||
}
|
||||
|
||||
delta = purpose_member (vbase, *vbase_offsets);
|
||||
if (! delta)
|
||||
{
|
||||
@ -2925,7 +2952,7 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori
|
||||
tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
|
||||
tree base_binfo = TREE_VEC_ELT (binfos, i);
|
||||
int is_not_base_vtable
|
||||
= i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
|
||||
= !BINFO_PRIMARY_MARKED_P (real_base_binfo);
|
||||
if (! TREE_VIA_VIRTUAL (real_base_binfo))
|
||||
fixup_virtual_upcast_offsets (real_base_binfo, base_binfo,
|
||||
is_not_base_vtable, can_elide, addr,
|
||||
@ -2979,15 +3006,17 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr)
|
||||
;
|
||||
else
|
||||
{
|
||||
tree vbase;
|
||||
tree vbase_offsets;
|
||||
tree addr;
|
||||
|
||||
vbase = find_vbase_instance (BINFO_TYPE (vbases), type);
|
||||
vbase_offsets = NULL_TREE;
|
||||
addr = convert_pointer_to_vbase (TREE_TYPE (vbases), decl_ptr);
|
||||
fixup_virtual_upcast_offsets (vbases,
|
||||
addr = convert_pointer_to_vbase (BINFO_TYPE (vbases), decl_ptr);
|
||||
fixup_virtual_upcast_offsets (vbase,
|
||||
TYPE_BINFO (BINFO_TYPE (vbases)),
|
||||
1, 0, addr, decl_ptr,
|
||||
type, vbases, &vbase_offsets);
|
||||
type, vbase, &vbase_offsets);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3074,6 +3103,43 @@ get_vbase_types (type)
|
||||
CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type));
|
||||
dfs_walk (TYPE_BINFO (type), dfs_vbase_unmark, markedp, 0);
|
||||
}
|
||||
|
||||
/* Called from find_vbase_instance via dfs_walk. */
|
||||
|
||||
static tree
|
||||
dfs_find_vbase_instance (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
tree base = TREE_VALUE ((tree) data);
|
||||
|
||||
if (BINFO_PRIMARY_MARKED_P (binfo)
|
||||
&& same_type_p (BINFO_TYPE (binfo), base))
|
||||
return binfo;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Find the real occurrence of the virtual BASE (a class type) in the
|
||||
hierarchy dominated by TYPE. */
|
||||
|
||||
tree
|
||||
find_vbase_instance (base, type)
|
||||
tree base;
|
||||
tree type;
|
||||
{
|
||||
tree instance;
|
||||
|
||||
instance = BINFO_FOR_VBASE (base, type);
|
||||
if (!BINFO_VBASE_PRIMARY_P (instance))
|
||||
return instance;
|
||||
|
||||
return dfs_walk (TYPE_BINFO (type),
|
||||
dfs_find_vbase_instance,
|
||||
NULL,
|
||||
build_tree_list (type, base));
|
||||
}
|
||||
|
||||
|
||||
/* Debug info for C++ classes can get very large; try to avoid
|
||||
emitting it everywhere.
|
||||
|
Loading…
Reference in New Issue
Block a user