Commit dd42e135 by Mark Mitchell Committed by Mark Mitchell

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
parent e5778b1e
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> 2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
* lex.c (DIR_SEPARATOR): Delete macro. * lex.c (DIR_SEPARATOR): Delete macro.
......
...@@ -3954,8 +3954,10 @@ extern tree dfs_skip_nonprimary_vbases_unmarkedp PROTO((tree, void *)); ...@@ -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_skip_nonprimary_vbases_markedp PROTO((tree, void *));
extern tree dfs_unmarked_real_bases_queue_p 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_marked_real_bases_queue_p PROTO((tree, void *));
extern tree dfs_skip_vbases PROTO((tree, void *));
extern void mark_primary_bases PROTO((tree)); extern void mark_primary_bases PROTO((tree));
extern tree convert_pointer_to_vbase PROTO((tree, tree)); extern tree convert_pointer_to_vbase PROTO((tree, tree));
extern tree find_vbase_instance PROTO((tree, tree));
/* in semantics.c */ /* in semantics.c */
extern void finish_expr_stmt PROTO((tree)); extern void finish_expr_stmt PROTO((tree));
......
...@@ -151,6 +151,7 @@ static int template_self_reference_p PROTO ((tree, 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 void fixup_all_virtual_upcast_offsets PROTO ((tree, tree));
static tree dfs_mark_primary_bases PROTO((tree, void *)); static tree dfs_mark_primary_bases PROTO((tree, void *));
static tree get_shared_vbase_if_not_primary PROTO((tree, tree)); 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. */ /* Allocate a level of searching. */
...@@ -2189,9 +2190,14 @@ mark_primary_bases (type) ...@@ -2189,9 +2190,14 @@ mark_primary_bases (type)
{ {
tree vbase; tree vbase;
/* Mark the TYPE_BINFO hierarchy. */ /* Mark the TYPE_BINFO hierarchy. We need to mark primary bases in
dfs_walk (TYPE_BINFO (type), dfs_mark_primary_bases, pre-order to deal with primary virtual bases. (The virtual base
dfs_skip_nonprimary_vbases_unmarkedp, type); 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 /* Now go through the virtual base classes. Any that are not
already primary will need to be allocated in TYPE, and so we need 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) ...@@ -2289,6 +2295,20 @@ dfs_marked_real_bases_queue_p (binfo, data)
return binfo ? markedp (binfo, NULL) : NULL_TREE; 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. */ /* Called via dfs_walk from dfs_get_pure_virtuals. */
static tree static tree
...@@ -2798,7 +2818,14 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t, ...@@ -2798,7 +2818,14 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
tree vc; tree vc;
tree delta; tree delta;
unsigned HOST_WIDE_INT n; 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); delta = purpose_member (vbase, *vbase_offsets);
if (! delta) if (! delta)
{ {
...@@ -2925,7 +2952,7 @@ fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, ori ...@@ -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 real_base_binfo = TREE_VEC_ELT (real_binfos, i);
tree base_binfo = TREE_VEC_ELT (binfos, i); tree base_binfo = TREE_VEC_ELT (binfos, i);
int is_not_base_vtable 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)) if (! TREE_VIA_VIRTUAL (real_base_binfo))
fixup_virtual_upcast_offsets (real_base_binfo, base_binfo, fixup_virtual_upcast_offsets (real_base_binfo, base_binfo,
is_not_base_vtable, can_elide, addr, is_not_base_vtable, can_elide, addr,
...@@ -2979,15 +3006,17 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr) ...@@ -2979,15 +3006,17 @@ fixup_all_virtual_upcast_offsets (type, decl_ptr)
; ;
else else
{ {
tree vbase;
tree vbase_offsets; tree vbase_offsets;
tree addr; tree addr;
vbase = find_vbase_instance (BINFO_TYPE (vbases), type);
vbase_offsets = NULL_TREE; vbase_offsets = NULL_TREE;
addr = convert_pointer_to_vbase (TREE_TYPE (vbases), decl_ptr); addr = convert_pointer_to_vbase (BINFO_TYPE (vbases), decl_ptr);
fixup_virtual_upcast_offsets (vbases, fixup_virtual_upcast_offsets (vbase,
TYPE_BINFO (BINFO_TYPE (vbases)), TYPE_BINFO (BINFO_TYPE (vbases)),
1, 0, addr, decl_ptr, 1, 0, addr, decl_ptr,
type, vbases, &vbase_offsets); type, vbase, &vbase_offsets);
} }
} }
...@@ -3074,6 +3103,43 @@ get_vbase_types (type) ...@@ -3074,6 +3103,43 @@ get_vbase_types (type)
CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type)); CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type));
dfs_walk (TYPE_BINFO (type), dfs_vbase_unmark, markedp, 0); 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 /* Debug info for C++ classes can get very large; try to avoid
emitting it everywhere. emitting it everywhere.
......
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