This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] vtable modification
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 12 Oct 2004 17:07:42 +0100
- Subject: [C++ PATCH] vtable modification
- Organization: Codesourcery LLC
The conditional in dfs_modify_vtable was confusing. This simplifies
it and allows some pruning of the heirarchy walk. Of course I tripped
myself up with using dfs_skip_bases in a post-order function, so I
added asserts to catch that in future.
booted & tested on i686-pc-linux-gnu.
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2004-10-12 Nathan Sidwell <nathan@codesourcery.com>
* class.c (dfs_modify_vtables): Simplify condition. Return
dfs_skip_bases as appropriate.
(modify_all_vtables): Walk in pre-order.
* search.c (dfs_walk_all, dfs_walk_once_r,
dfs_walk_once_accessible_r): Assert post order function never
returns dfs_skip_bases.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.683
diff -c -3 -p -r1.683 class.c
*** cp/class.c 11 Oct 2004 15:38:21 -0000 1.683
--- cp/class.c 12 Oct 2004 15:58:11 -0000
*************** static tree
*** 2144,2180 ****
dfs_modify_vtables (tree binfo, void* data)
{
tree t = (tree) data;
! if (/* There's no need to modify the vtable for a non-virtual
! primary base; we're not going to use that vtable anyhow.
! We do still need to do this for virtual primary bases, as they
! could become non-primary in a construction vtable. */
! (!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
! /* Similarly, a base without a vtable needs no modification. */
! && TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo))
! /* Don't do the primary vtable, if it's new. */
! && (!SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
! || CLASSTYPE_HAS_PRIMARY_BASE_P (t)))
! {
! tree virtuals;
! tree old_virtuals;
! unsigned ix;
!
! make_new_vtable (t, binfo);
! /* Now, go through each of the virtual functions in the virtual
! function table for BINFO. Find the final overrider, and
! update the BINFO_VIRTUALS list appropriately. */
! for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
! old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
! virtuals;
! ix++, virtuals = TREE_CHAIN (virtuals),
! old_virtuals = TREE_CHAIN (old_virtuals))
! update_vtable_entry_for_fn (t,
! binfo,
! BV_FN (old_virtuals),
! &virtuals, ix);
! }
return NULL_TREE;
}
--- 2144,2184 ----
dfs_modify_vtables (tree binfo, void* data)
{
tree t = (tree) data;
+ tree virtuals;
+ tree old_virtuals;
+ unsigned ix;
+
+ if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
+ /* A base without a vtable needs no modification, and its bases
+ are uninteresting. */
+ return dfs_skip_bases;
! if (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), t)
! && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
! /* Don't do the primary vtable, if it's new. */
! return NULL_TREE;
!
! if (BINFO_PRIMARY_P (binfo) && !BINFO_VIRTUAL_P (binfo))
! /* There's no need to modify the vtable for a non-virtual primary
! base; we're not going to use that vtable anyhow. We do still
! need to do this for virtual primary bases, as they could become
! non-primary in a construction vtable. */
! return NULL_TREE;
!
! make_new_vtable (t, binfo);
! /* Now, go through each of the virtual functions in the virtual
! function table for BINFO. Find the final overrider, and update
! the BINFO_VIRTUALS list appropriately. */
! for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
! old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
! virtuals;
! ix++, virtuals = TREE_CHAIN (virtuals),
! old_virtuals = TREE_CHAIN (old_virtuals))
! update_vtable_entry_for_fn (t,
! binfo,
! BV_FN (old_virtuals),
! &virtuals, ix);
return NULL_TREE;
}
*************** modify_all_vtables (tree t, tree virtual
*** 2195,2201 ****
tree *fnsp;
/* Update all of the vtables. */
! dfs_walk_once (binfo, NULL, dfs_modify_vtables, t);
/* Add virtual functions not already in our primary vtable. These
will be both those introduced by this class, and those overridden
--- 2199,2205 ----
tree *fnsp;
/* Update all of the vtables. */
! dfs_walk_once (binfo, dfs_modify_vtables, NULL, t);
/* Add virtual functions not already in our primary vtable. These
will be both those introduced by this class, and those overridden
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.330
diff -c -3 -p -r1.330 search.c
*** cp/search.c 11 Oct 2004 16:36:03 -0000 1.330
--- cp/search.c 12 Oct 2004 15:58:15 -0000
*************** dfs_walk_all (tree binfo, tree (*pre_fn)
*** 1532,1538 ****
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! return post_fn (binfo, data);
return NULL_TREE;
}
--- 1532,1543 ----
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! {
! rval = post_fn (binfo, data);
! gcc_assert (rval != dfs_skip_bases);
! return rval;
! }
!
return NULL_TREE;
}
*************** dfs_walk_once_r (tree binfo, tree (*pre_
*** 1578,1584 ****
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! return post_fn (binfo, data);
return NULL_TREE;
}
--- 1583,1593 ----
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! {
! rval = post_fn (binfo, data);
! gcc_assert (rval != dfs_skip_bases);
! return rval;
! }
return NULL_TREE;
}
*************** dfs_walk_once_accessible_r (tree binfo,
*** 1700,1706 ****
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! return post_fn (binfo, data);
return NULL_TREE;
}
--- 1709,1719 ----
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
! {
! rval = post_fn (binfo, data);
! gcc_assert (rval != dfs_skip_bases);
! return rval;
! }
return NULL_TREE;
}