aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-10-12 16:04:24 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-10-12 16:04:24 +0000
commit5b94d9dd86ad94777503632b0732345836af0104 (patch)
treeb6d1d3d25dcd57406ee545bea62de48c980d04e4 /gcc/cp
parentfa91adc640e8ace532fac4077085a9904518b530 (diff)
downloadgcc-5b94d9dd86ad94777503632b0732345836af0104.zip
gcc-5b94d9dd86ad94777503632b0732345836af0104.tar.gz
gcc-5b94d9dd86ad94777503632b0732345836af0104.tar.bz2
class.c (dfs_modify_vtables): Simplify condition.
* 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. From-SVN: r88939
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/class.c64
-rw-r--r--gcc/cp/search.c19
3 files changed, 57 insertions, 33 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5b87487..835f414 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
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.
+
* search.c (struct lookup_base_data_s): New.
(lookup_base_r): Replace with ...
(dfs_lookup_base): ... this.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 5bcec30..b1eec83 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2144,37 +2144,41 @@ static tree
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 (/* 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);
+ 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);
- }
+ /* 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;
}
@@ -2195,7 +2199,7 @@ modify_all_vtables (tree t, tree virtuals)
tree *fnsp;
/* Update all of the vtables. */
- dfs_walk_once (binfo, NULL, dfs_modify_vtables, t);
+ 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
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 9ab861f..b90f192 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1542,7 +1542,12 @@ dfs_walk_all (tree binfo, tree (*pre_fn) (tree, void *),
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
- return post_fn (binfo, data);
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
+
return NULL_TREE;
}
@@ -1588,7 +1593,11 @@ dfs_walk_once_r (tree binfo, tree (*pre_fn) (tree, void *),
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
- return post_fn (binfo, data);
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
return NULL_TREE;
}
@@ -1710,7 +1719,11 @@ dfs_walk_once_accessible_r (tree binfo, bool friends_p, bool once,
skip_bases:
/* Call the post-order walking function. */
if (post_fn)
- return post_fn (binfo, data);
+ {
+ rval = post_fn (binfo, data);
+ gcc_assert (rval != dfs_skip_bases);
+ return rval;
+ }
return NULL_TREE;
}