This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] vtable modification


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;
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]