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]

C++ PATCH: fix order of vtable group under the new ABI



Under the new ABI, primary and secondary vtables are laid out
contiguously.  Virtual base vtables have to follow primary base
vtables; we were getting that wrong.  Here's the fix.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-03-22  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
	(CANONICAL_BINFO): New macro.
	(BINFO_NEW_VTABLE_MARKED): Use it.
	(SET_BINFO_NEW_VTABLE_MARKED): Likewise.
	(CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
	* class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
	not TREE_TYPE.
	(build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(build_secondary_vtable): Likewise.
	(dfs_finish_vtbls): Likewise.
	(dfs_accumulate_vtbl_inits): Likewise.
	(accumulate_vtbl_inits): New function.
	(finish_vtbls): Make sure that virtual bases come after
	non-virtual bases in the vtable group.
	(record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
	(finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	* search.c (struct vbase_info): Move definition.
	(marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(unmarked_new_vtable_p): Likewise.
	(dfs_mark_vtable_path): Remove.
	(dfs_mark_new_vtable): Remove.
	(dfs_unmark_new_vtable): Likewise.
	(dfs_clear_search_slot): Likewise.
	(dfs_find_vbases):  Adjust usage of BINFO_NEW_VTABLE_MARKED.
	(dfs_clear_vbase_slots): Likewise.
	(init_vbase_pointers): LIkewise.
	
Index: testsuite/g++.old-deja/g++.abi/vtable.C
===================================================================
RCS file: vtable.C
diff -N vtable.C
*** /dev/null	Tue May  5 13:32:27 1998
--- vtable.C	Wed Mar 22 13:37:11 2000
***************
*** 0 ****
--- 1,82 ----
+ // Test various aspects of vtable layout.
+ // Special g++ Options: -fno-strict-aliasing
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+ 
+ #if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
+ 
+ struct S0
+ {
+   virtual void h ()
+   {
+   }
+ 
+   int k;
+ };
+ 
+ 
+ struct S1 
+ {
+   virtual void f () 
+   {
+   }
+ 
+   int i;
+ };
+ 
+ struct S2 : virtual public S0
+ {
+   virtual void g ()
+   {
+   }
+ 
+   int j;
+ };
+ 
+ struct S3 
+ {
+   virtual void k () 
+   {
+   }
+ 
+   int l;
+ };
+ 
+ struct S4 : public virtual S1, public S2, public S3
+ {
+ };
+ 
+ inline void* vtable (void *object)
+ {
+   // The vptr is always the first part of the object.
+   return * (void **) object;
+ }
+ 
+ int main ()
+ {
+   // The vtable layout order for S4 should consist of S4's primary
+   // vtable (shared with S2), followed by the vtable for S3 (because
+   // it is a non-virtual base).  Then, these should be followed by the
+   // the vtables for S1 and S0, which are virtual.
+   S4 s4;
+   S0 *s0 = &s4;
+   S1 *s1 = &s4;
+   S2 *s2 = &s4;
+   S3 *s3 = &s4;
+   
+   if (vtable (&s4) != vtable (s2))
+     return 1;
+     if (vtable (s2) >= vtable (s3))
+     return 2;
+   if (vtable (s3) >= vtable (s1))
+     return 3;
+   if (vtable (s1) >= vtable (s0))
+     return 4;
+ }
+ 
+ #else /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
+ 
+ int main () 
+ {
+ }
+ 
+ #endif /* !(defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100) */
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.277
diff -c -p -r1.277 class.c
*** class.c	2000/03/22 05:39:34	1.277
--- class.c	2000/03/22 21:37:15
*************** static tree dfs_search_base_offsets PARA
*** 161,166 ****
--- 161,167 ----
  static int layout_conflict_p PARAMS ((tree, varray_type));
  static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
  static void layout_empty_base PARAMS ((tree, tree, varray_type));
+ static void accumulate_vtbl_inits PARAMS ((tree, tree));
  
  /* Variables shared between class.c and call.c.  */
  
*************** dfs_build_vbase_offset_vtbl_entries (bin
*** 276,282 ****
  
        /* Remember the index to the vbase offset for this virtual
  	 base.  */
!       vbase = BINFO_FOR_VBASE (TREE_TYPE (binfo), TREE_PURPOSE (list));
        if (!TREE_VALUE (list))
  	BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
        else
--- 277,283 ----
  
        /* Remember the index to the vbase offset for this virtual
  	 base.  */
!       vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
        if (!TREE_VALUE (list))
  	BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
        else
*************** build_primary_vtable (binfo, type)
*** 1072,1078 ****
      {
        tree offset;
  
!       if (BINFO_NEW_VTABLE_MARKED (binfo))
  	/* We have already created a vtable for this base, so there's
  	   no need to do it again.  */
  	return 0;
--- 1073,1079 ----
      {
        tree offset;
  
!       if (BINFO_NEW_VTABLE_MARKED (binfo, type))
  	/* We have already created a vtable for this base, so there's
  	   no need to do it again.  */
  	return 0;
*************** build_primary_vtable (binfo, type)
*** 1106,1112 ****
    TYPE_BINFO_VIRTUALS (type) = virtuals;
  
    binfo = TYPE_BINFO (type);
!   SET_BINFO_NEW_VTABLE_MARKED (binfo);
    return 1;
  }
  
--- 1107,1113 ----
    TYPE_BINFO_VIRTUALS (type) = virtuals;
  
    binfo = TYPE_BINFO (type);
!   SET_BINFO_NEW_VTABLE_MARKED (binfo, type);
    return 1;
  }
  
*************** build_secondary_vtable (binfo, for_type)
*** 1147,1160 ****
  						  current_class_type),
  			170);
  
!   if (BINFO_NEW_VTABLE_MARKED (binfo))
      /* We already created a vtable for this base.  There's no need to
         do it again.  */
      return 0;
  
    /* Remember that we've created a vtable for this BINFO, so that we
       don't try to do so again.  */
!   SET_BINFO_NEW_VTABLE_MARKED (binfo);
    
    /* Make fresh virtual list, so we can smash it later.  */
    BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
--- 1148,1161 ----
  						  current_class_type),
  			170);
  
!   if (BINFO_NEW_VTABLE_MARKED (binfo, current_class_type))
      /* We already created a vtable for this base.  There's no need to
         do it again.  */
      return 0;
  
    /* Remember that we've created a vtable for this BINFO, so that we
       don't try to do so again.  */
!   SET_BINFO_NEW_VTABLE_MARKED (binfo, current_class_type);
    
    /* Make fresh virtual list, so we can smash it later.  */
    BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo));
*************** dfs_finish_vtbls (binfo, data)
*** 2760,2772 ****
       tree binfo;
       void *data;
  {
    if (!BINFO_PRIMARY_MARKED_P (binfo)
        && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
!       && BINFO_NEW_VTABLE_MARKED (binfo))
      initialize_vtable (binfo, 
! 		       build_vtbl_initializer (binfo, (tree) data));
  
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
    SET_BINFO_MARKED (binfo);
  
    return NULL_TREE;
--- 2761,2775 ----
       tree binfo;
       void *data;
  {
+   tree t = (tree) data;
+ 
    if (!BINFO_PRIMARY_MARKED_P (binfo)
        && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
!       && BINFO_NEW_VTABLE_MARKED (binfo, t))
      initialize_vtable (binfo, 
! 		       build_vtbl_initializer (binfo, t));
  
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
    SET_BINFO_MARKED (binfo);
  
    return NULL_TREE;
*************** dfs_accumulate_vtbl_inits (binfo, data)
*** 2781,2795 ****
       tree binfo;
       void *data;
  {
    if (!BINFO_PRIMARY_MARKED_P (binfo)
        && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
!       && BINFO_NEW_VTABLE_MARKED (binfo))
      {
-       tree l;
-       tree t;
- 
-       l = (tree) data;
-       t = TREE_PURPOSE (l);
  
        /* If this is a secondary vtable, record its location.  */
        if (binfo != TYPE_BINFO (t))
--- 2784,2799 ----
       tree binfo;
       void *data;
  {
+   tree l;
+   tree t;
+ 
+   l = (tree) data;
+   t = TREE_PURPOSE (l);
+ 
    if (!BINFO_PRIMARY_MARKED_P (binfo)
        && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
!       && BINFO_NEW_VTABLE_MARKED (binfo, t))
      {
  
        /* If this is a secondary vtable, record its location.  */
        if (binfo != TYPE_BINFO (t))
*************** dfs_accumulate_vtbl_inits (binfo, data)
*** 2807,2825 ****
  				 size_int (list_length (TREE_VALUE (l)))));
  	}
  
!       /* Add the initializers for this vtable to the initailizers for
  	 the other vtables we've already got.  */
        TREE_VALUE (l) 
  	= chainon (TREE_VALUE (l),
  		   build_vtbl_initializer (binfo, t));
      }
  
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
!   SET_BINFO_MARKED (binfo);
  
    return NULL_TREE;
  }
  
  /* Create all the necessary vtables for T and its base classes.  */
  
  static void
--- 2811,2844 ----
  				 size_int (list_length (TREE_VALUE (l)))));
  	}
  
!       /* Add the initializers for this vtable to the initializers for
  	 the other vtables we've already got.  */
        TREE_VALUE (l) 
  	= chainon (TREE_VALUE (l),
  		   build_vtbl_initializer (binfo, t));
      }
  
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
  
    return NULL_TREE;
  }
  
+ /* Add the vtbl initializers for BINFO (and its non-primary,
+    non-virtual bases) to the list of INITS.  */
+ 
+ static void
+ accumulate_vtbl_inits (binfo, inits)
+      tree binfo;
+      tree inits;
+ {
+   /* Walk the BINFO and its bases.  */
+   dfs_walk_real (binfo,
+ 		 dfs_accumulate_vtbl_inits,
+ 		 NULL, 
+ 		 dfs_skip_vbases,
+ 		 inits);
+ }
+ 
  /* Create all the necessary vtables for T and its base classes.  */
  
  static void
*************** finish_vtbls (t)
*** 2829,2854 ****
    if (merge_primary_and_secondary_vtables_p ())
      {
        tree list;
  
        /* Under the new ABI, we lay out the primary and secondary
  	 vtables in one contiguous vtable.  The primary vtable is
! 	 first, followed by the secondary vtables as encountered in a
! 	 pre-order depth-first left-to-right traversal.  */
        list = build_tree_list (t, NULL_TREE);
!       dfs_walk_real (TYPE_BINFO (t), 
! 		     dfs_accumulate_vtbl_inits,
! 		     NULL, 
! 		     dfs_unmarked_real_bases_queue_p, 
! 		     list);
        if (TYPE_BINFO_VTABLE (t))
  	initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
      }
    else
!     dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls, 
! 	      dfs_unmarked_real_bases_queue_p, t);
! 
!   dfs_walk (TYPE_BINFO (t), dfs_unmark, 
! 	    dfs_marked_real_bases_queue_p, t);
  }
  
  /* True if we should override the given BASE_FNDECL with the given
--- 2848,2878 ----
    if (merge_primary_and_secondary_vtables_p ())
      {
        tree list;
+       tree vbase;
  
        /* Under the new ABI, we lay out the primary and secondary
  	 vtables in one contiguous vtable.  The primary vtable is
! 	 first, followed by the non-virtual secondary vtables in
! 	 inheritance graph order.  */
        list = build_tree_list (t, NULL_TREE);
!       accumulate_vtbl_inits (TYPE_BINFO (t), list);
!       /* Then come the virtual bases, also in inheritance graph
! 	 order.  */
!       for (vbase = CLASSTYPE_VBASECLASSES (t);
! 	   vbase;
! 	   vbase = TREE_CHAIN (vbase))
! 	accumulate_vtbl_inits (vbase, list);
! 
        if (TYPE_BINFO_VTABLE (t))
  	initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
      }
    else
!     {
!       dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls, 
! 		dfs_unmarked_real_bases_queue_p, t);
!       dfs_walk (TYPE_BINFO (t), dfs_unmark, 
! 		dfs_marked_real_bases_queue_p, t);
!     }
  }
  
  /* True if we should override the given BASE_FNDECL with the given
*************** record_base_offsets (binfo, base_offsets
*** 4142,4158 ****
       tree binfo;
       varray_type *base_offsets;
  {
-   int virtual_p;
- 
-   /* If BINFO is virtual, we still want to mention its offset in
-      BASE_OFFSETS.  */
-   virtual_p = TREE_VIA_VIRTUAL (binfo);
-   TREE_VIA_VIRTUAL (binfo) = 0;
    dfs_walk (binfo,
  	    dfs_record_base_offsets,
  	    dfs_skip_vbases,
  	    base_offsets);
-   TREE_VIA_VIRTUAL (binfo) = virtual_p;
  }
  
  /* Returns non-NULL if there is already an entry in DATA (which is
--- 4166,4175 ----
*************** finish_struct_1 (t)
*** 5308,5314 ****
  	    }
  	  build_primary_vtable (NULL_TREE, t);
  	}
!       else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
  	/* Here we know enough to change the type of our virtual
  	   function table, but we will wait until later this function.  */
  	build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
--- 5325,5331 ----
  	    }
  	  build_primary_vtable (NULL_TREE, t);
  	}
!       else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
  	/* Here we know enough to change the type of our virtual
  	   function table, but we will wait until later this function.  */
  	build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.424
diff -c -p -r1.424 cp-tree.h
*** cp-tree.h	2000/03/22 01:32:09	1.424
--- cp-tree.h	2000/03/22 21:37:19
*************** struct lang_type
*** 1566,1575 ****
     (also distinct from the copies in the TYPE_BINFO hierarchy.)  */
  #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
  
! /* The BINFO (if any) for the virtual baseclass T of the class C.  */
  #define BINFO_FOR_VBASE(T, C) \
    (binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
  
  /* Number of direct baseclasses of NODE.  */
  #define CLASSTYPE_N_BASECLASSES(NODE) \
    (BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
--- 1566,1584 ----
     (also distinct from the copies in the TYPE_BINFO hierarchy.)  */
  #define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases)
  
! /* The BINFO (if any) for the virtual baseclass T of the class C from
!    the CLASSTYPE_VBASECLASSES list.  */
  #define BINFO_FOR_VBASE(T, C) \
    (binfo_member (T, CLASSTYPE_VBASECLASSES (C)))
  
+ /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
+    BINFO_FOR_VBASE.  C is the most derived class for the hierarchy
+    containing BINFO.  */
+ #define CANONICAL_BINFO(BINFO, C)		\
+   (TREE_VIA_VIRTUAL (BINFO) 			\
+    ? BINFO_FOR_VBASE (BINFO_TYPE (BINFO), C) 	\
+    : BINFO)
+ 
  /* Number of direct baseclasses of NODE.  */
  #define CLASSTYPE_N_BASECLASSES(NODE) \
    (BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
*************** struct lang_type
*** 1704,1714 ****
  #define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1))
  #define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0))
  
! /* Nonzero means that this class has a new vtable.  */
! #define BINFO_NEW_VTABLE_MARKED(NODE) \
!   (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):TREE_LANG_FLAG_4(NODE))
! #define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1))
! #define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0))
  
  /* Nonzero means this class has done dfs_pushdecls.  */
  #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
--- 1713,1726 ----
  #define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1))
  #define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0))
  
! /* Nonzero means B (a BINFO) needs a new vtable.  B is part of the
!    hierarchy dominated by C.  */
! #define BINFO_NEW_VTABLE_MARKED(B, C) \
!   (TREE_LANG_FLAG_4 (CANONICAL_BINFO (B, C)))
! #define SET_BINFO_NEW_VTABLE_MARKED(B, C) \
!   (BINFO_NEW_VTABLE_MARKED (B, C) = 1)
! #define CLEAR_BINFO_NEW_VTABLE_MARKED(B, C) \
!   (BINFO_NEW_VTABLE_MARKED (B, C) = 0)
  
  /* Nonzero means this class has done dfs_pushdecls.  */
  #define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.165
diff -c -p -r1.165 search.c
*** search.c	2000/03/22 01:32:09	1.165
--- search.c	2000/03/22 21:37:21
*************** pop_stack_level (stack)
*** 76,81 ****
--- 76,90 ----
  #define search_level stack_level
  static struct search_level *search_stack;
  
+ struct vbase_info 
+ {
+   /* The class dominating the hierarchy.  */
+   tree type;
+   tree decl_ptr;
+   tree inits;
+   tree vbase_types;
+ };
+ 
  static tree next_baselink PARAMS ((tree));
  static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
  static tree lookup_field_1 PARAMS ((tree, tree));
*************** unmarked_vtable_pathp (binfo, data) 
*** 2537,2553 ****
  static tree 
  marked_new_vtablep (binfo, data) 
       tree binfo;
!      void *data ATTRIBUTE_UNUSED;
  {
!   return BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE; 
  }
  
  static tree
  unmarked_new_vtablep (binfo, data) 
       tree binfo;
!      void *data ATTRIBUTE_UNUSED;
  { 
!   return !BINFO_NEW_VTABLE_MARKED (binfo) ? binfo : NULL_TREE; 
  }
  
  static tree
--- 2546,2566 ----
  static tree 
  marked_new_vtablep (binfo, data) 
       tree binfo;
!      void *data;
  {
!   struct vbase_info *vi = (struct vbase_info *) data;
! 
!   return BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE; 
  }
  
  static tree
  unmarked_new_vtablep (binfo, data) 
       tree binfo;
!      void *data;
  { 
!   struct vbase_info *vi = (struct vbase_info *) data;
! 
!   return !BINFO_NEW_VTABLE_MARKED (binfo, vi->type) ? binfo : NULL_TREE; 
  }
  
  static tree
*************** dfs_vtable_path_unmark (binfo, data)
*** 2614,2644 ****
    return NULL_TREE;
  }
  
- #if 0
- static void
- dfs_mark_vtable_path (binfo) tree binfo;
- { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
- 
- static void
- dfs_mark_new_vtable (binfo) tree binfo;
- { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
- 
- static void
- dfs_unmark_new_vtable (binfo) tree binfo;
- { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
- 
- static void
- dfs_clear_search_slot (binfo) tree binfo;
- { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
- #endif
  
- struct vbase_info 
- {
-   tree decl_ptr;
-   tree inits;
-   tree vbase_types;
- };
- 
  /*  Attach to the type of the virtual base class, the pointer to the
      virtual base class.  */
  
--- 2627,2633 ----
*************** dfs_find_vbases (binfo, data)
*** 2668,2674 ****
  	}
      }
    SET_BINFO_VTABLE_PATH_MARKED (binfo);
!   SET_BINFO_NEW_VTABLE_MARKED (binfo);
  
    return NULL_TREE;
  }
--- 2657,2663 ----
  	}
      }
    SET_BINFO_VTABLE_PATH_MARKED (binfo);
!   SET_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
  
    return NULL_TREE;
  }
*************** dfs_init_vbase_pointers (binfo, data)
*** 2737,2748 ****
  static tree
  dfs_clear_vbase_slots (binfo, data)
       tree binfo;
!      void *data ATTRIBUTE_UNUSED;
  {
    tree type = BINFO_TYPE (binfo);
    CLASSTYPE_SEARCH_SLOT (type) = 0;
    CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
    return NULL_TREE;
  }
  
--- 2726,2739 ----
  static tree
  dfs_clear_vbase_slots (binfo, data)
       tree binfo;
!      void *data;
  {
    tree type = BINFO_TYPE (binfo);
+   struct vbase_info *vi = (struct vbase_info *) data;
+ 
    CLASSTYPE_SEARCH_SLOT (type) = 0;
    CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
!   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, vi->type);
    return NULL_TREE;
  }
  
*************** init_vbase_pointers (type, decl_ptr)
*** 2760,2765 ****
--- 2751,2757 ----
  
        /* Find all the virtual base classes, marking them for later
  	 initialization.  */
+       vi.type = type;
        vi.decl_ptr = decl_ptr;
        vi.vbase_types = CLASSTYPE_VBASECLASSES (type);
        vi.inits = NULL_TREE;
*************** init_vbase_pointers (type, decl_ptr)
*** 2773,2779 ****
  		     marked_vtable_pathp,
  		     &vi);
  
!       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
        flag_this_is_variable = old_flag;
        return vi.inits;
      }
--- 2765,2771 ----
  		     marked_vtable_pathp,
  		     &vi);
  
!       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
        flag_this_is_variable = old_flag;
        return vi.inits;
      }
*************** expand_indirect_vtbls_init (binfo, decl_
*** 3088,3099 ****
      {
        tree vbases = CLASSTYPE_VBASECLASSES (type);
        struct vbase_info vi;
        vi.decl_ptr = decl_ptr;
        vi.vbase_types = vbases;
  
        dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
        fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
!       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, 0);
      }
  }
  
--- 3080,3092 ----
      {
        tree vbases = CLASSTYPE_VBASECLASSES (type);
        struct vbase_info vi;
+       vi.type = type;
        vi.decl_ptr = decl_ptr;
        vi.vbase_types = vbases;
  
        dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep, &vi);
        fixup_all_virtual_upcast_offsets (type, vi.decl_ptr);
!       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep, &vi);
      }
  }
  

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