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: New ABI RTTI



Under the new ABI, RTTI information goes in negative vtable slots.
(One benefit is that there is then one virtual function at entry zero,
which makes for potentially faster calls to that function.)

This patch implements this change.

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

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

	Put RTTI entries at negative offsets in new ABI.
	* class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
	vbase offset at index -3, not -1.
	(build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
	dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
	(dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
	(build_rtti_vtbl_entries): New function.
	(set_rtti_entry): Remove.
	(build_primary_vtable): Don't use it.
	(build_secondary_vtable): Likewise.
	(start_vtable): Remove.
	(first_vfun_index): New function.
	(set_vindex): Likewise.
	(add_virtual_function): Don't call start_vtable.  Do call
	set_vindex.
	(set_primary_base): Rename parameter.
	(determine_primary_base): Likewise.
	(num_vfun_entries): Don't use skip_rtti_stuff.
	(num_extra_vtbl_entries): Include RTTI information.
	(build_vtbl_initializer): Use build_rtti_vtbl_entries.
	(skip_rtti_stuff): Remove.
	(dfs_modify_vtables): Don't use it.
	(modify_all_vtables): Don't use start_vtable.  Do use set_vindex.
	(layout_nonempty_base_or_field): Update size handling.
	(create_vtable_ptr): Tweak.
	(layout_class_type): Adjust parameter names.
	(finish_struct_1): Simplify.
	* cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
	(skip_rtti_stuff): Remove.
	(first_vfun_index): New function.
	(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
	(dfs_vtable_path_marked_real_bases_queue_p): Remove.
	(marked_vtable_pathp): Declare.
	(unmarked_vtable_pathp): Likewise.
	* error.c (dump_expr): Use first_vfun_index to calculate vtable
	offsets.
	* rtti.c (build_headof): Look for RTTI at negative offsets.
	(get_tinfo_decl_dynamic): Likewise.
	(tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
	here.
	(create_pseudo_type_info): Do it here instead.  Adjust so that
	vptr points at first virtual function.
	* search.c (marked_vtable_pathp): Make it global.
	(unmarked_vtable_pathp): Likewise.
	(dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
	(dfs_vtable_path_marked_real_bases_queue_p): Likewise.
	(dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
	(get_pure_virtuals): Likewise.
	(expand_upcast_fixups): Likewise.
	* tree.c (debug_binfo): Likewise.
	* tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
	negative offset.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.281
diff -c -p -r1.281 class.c
*** class.c	2000/03/27 01:26:17	1.281
--- class.c	2000/03/28 19:08:54
*************** static tree build_vtable_entry PARAMS ((
*** 80,86 ****
  static tree get_vtable_name PARAMS ((tree));
  static tree get_derived_offset PARAMS ((tree, tree));
  static tree get_basefndecls PARAMS ((tree, tree));
- static void set_rtti_entry PARAMS ((tree, tree, tree));
  static int build_primary_vtable PARAMS ((tree, tree));
  static int build_secondary_vtable PARAMS ((tree, tree));
  static tree dfs_finish_vtbls PARAMS ((tree, void *));
--- 80,85 ----
*************** static tree dfs_vcall_offset_queue_p PAR
*** 142,148 ****
  static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
  static tree build_vcall_offset_vtbl_entries PARAMS ((tree, tree));
  static tree dfs_count_virtuals PARAMS ((tree, void *));
- static void start_vtable PARAMS ((tree, int *));
  static void layout_vtable_decl PARAMS ((tree, int));
  static int num_vfun_entries PARAMS ((tree));
  static tree dfs_find_final_overrider PARAMS ((tree, void *));
--- 141,146 ----
*************** static int layout_conflict_p PARAMS ((tr
*** 162,167 ****
--- 160,166 ----
  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));
+ static void set_vindex PARAMS ((tree, tree, int *));
  
  /* Variables shared between class.c and call.c.  */
  
*************** dfs_build_vbase_offset_vtbl_entries (bin
*** 279,285 ****
  	 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
  	{
  	  BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
--- 278,284 ----
  	 base.  */
        vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
        if (!TREE_VALUE (list))
! 	BINFO_VPTR_FIELD (vbase) = build_int_2 (-3, 0);
        else
  	{
  	  BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
*************** build_vbase_offset_vtbl_entries (binfo, 
*** 333,343 ****
    TREE_TYPE (list) = binfo;
    dfs_walk (binfo,
  	    dfs_build_vbase_offset_vtbl_entries,
! 	    dfs_vtable_path_unmarked_real_bases_queue_p,
  	    list);
    dfs_walk (binfo,
  	    dfs_vtable_path_unmark,
! 	    dfs_vtable_path_marked_real_bases_queue_p,
  	    list);
    inits = nreverse (TREE_VALUE (list));
  
--- 332,342 ----
    TREE_TYPE (list) = binfo;
    dfs_walk (binfo,
  	    dfs_build_vbase_offset_vtbl_entries,
! 	    unmarked_vtable_pathp,
  	    list);
    dfs_walk (binfo,
  	    dfs_vtable_path_unmark,
! 	    marked_vtable_pathp,
  	    list);
    inits = nreverse (TREE_VALUE (list));
  
*************** dfs_build_vcall_offset_vtbl_entries (bin
*** 405,413 ****
  
    /* We chain the offsets on in reverse order.  That's correct --
       build_vtbl_initializer will straighten them out.  */
!   for (virtuals = skip_rtti_stuff (binfo,
! 				   BINFO_TYPE (binfo),
! 				   NULL);
         virtuals;
         virtuals = TREE_CHAIN (virtuals))
      {
--- 404,410 ----
  
    /* We chain the offsets on in reverse order.  That's correct --
       build_vtbl_initializer will straighten them out.  */
!   for (virtuals = BINFO_VIRTUALS (binfo);
         virtuals;
         virtuals = TREE_CHAIN (virtuals))
      {
*************** build_vcall_offset_vtbl_entries (binfo, 
*** 486,491 ****
--- 483,564 ----
    return vod.inits;
  }
  
+ /* Return vtbl initializers for the RTTI entries coresponding to the
+    BINFO's vtable.  BINFO is a part of the hierarchy dominated by 
+    T.  */
+ 
+ static tree
+ build_rtti_vtbl_entries (binfo, t)
+      tree binfo;
+      tree t;
+ {
+   tree b;
+   tree basetype;
+   tree inits;
+   tree offset;
+   tree decl;
+   tree init;
+ 
+   basetype = BINFO_TYPE (binfo);
+   inits = NULL_TREE;
+ 
+   /* For a COM object there is no RTTI entry.  */
+   if (CLASSTYPE_COM_INTERFACE (basetype))
+     return inits;
+ 
+   /* To find the complete object, we will first convert to our most
+      primary base, and then add the offset in the vtbl to that value.  */
+   b = binfo;
+   while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b)))
+     b = BINFO_BASETYPE (b, 
+ 			CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (b)));
+   offset = size_diffop (size_zero_node, BINFO_OFFSET (b));
+ 
+   /* Add the offset-to-top entry.  */
+   if (flag_vtable_thunks)
+     {
+       /* Convert the offset to look like a function pointer, so that
+ 	 we can put it in the vtable.  */
+       init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
+       TREE_CONSTANT (init) = 1;
+       inits = tree_cons (NULL_TREE, init, inits);
+     }
+ 
+   /* The second entry is, in the case of the new ABI, the address of
+      the typeinfo object, or, in the case of the old ABI, a function
+      which returns a typeinfo object.  */
+   if (new_abi_rtti_p ())
+     {
+       if (flag_rtti)
+ 	decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0);
+       else
+ 	decl = integer_zero_node;
+ 
+       /* Convert the declaration to a type that can be stored in the
+ 	 vtable.  */
+       init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
+       TREE_CONSTANT (init) = 1;
+     }
+   else
+     {
+       if (flag_rtti)
+ 	decl = get_tinfo_decl (t);
+       else
+ 	decl = abort_fndecl;
+ 
+       /* Convert the declaration to a type that can be stored in the
+ 	 vtable.  */
+       init = build1 (ADDR_EXPR, vfunc_ptr_type_node, decl);
+       TREE_CONSTANT (init) = 1;
+       init = build_vtable_entry (offset, integer_zero_node, init);
+     }
+ 
+   /* Hook the RTTI declaration onto the list.  */
+   inits = tree_cons (NULL_TREE, init, inits);
+ 
+   return inits;
+ }
+ 
  /* Returns a pointer to the virtual base class of EXP that has the
     indicated TYPE.  EXP is of class type, not a pointer type.  */
  
*************** get_derived_offset (binfo, type)
*** 945,991 ****
    return size_binop (MINUS_EXPR, offset1, offset2);
  }
  
- /* Update the rtti info for this class.  */
- 
- static void
- set_rtti_entry (virtuals, offset, type)
-      tree virtuals, offset, type;
- {
-   tree decl;
- 
-   if (CLASSTYPE_COM_INTERFACE (type))
-     return;
- 
-   if (flag_rtti)
-     decl = get_tinfo_decl (type);
-   else if (!new_abi_rtti_p ())
-     /* If someone tries to get RTTI information for a type compiled
-        without RTTI, they're out of luck.  By calling __pure_virtual
-        in this case, we give a small clue as to what went wrong.  We
-        could consider having a __no_typeinfo function as well, for a
-        more specific hint.  */
-     decl = abort_fndecl;
-   else
-     /* For the new-abi, we just point to the type_info object.  */
-     decl = NULL_TREE;
- 
-   if (flag_vtable_thunks)
-     {
-       /* The first slot holds the offset.  */
-       BV_DELTA (virtuals) = offset;
-       BV_VCALL_INDEX (virtuals) = integer_zero_node;
- 
-       /* The next node holds the decl.  */
-       virtuals = TREE_CHAIN (virtuals);
-       offset = ssize_int (0);
-     }
- 
-   /* This slot holds the function to call.  */
-   BV_DELTA (virtuals) = offset;
-   BV_VCALL_INDEX (virtuals) = integer_zero_node;
-   BV_FN (virtuals) = decl;
- }
- 
  /* Create a VAR_DECL for a primary or secondary vtable for
     CLASS_TYPE.  Use NAME for the name of the vtable, and VTABLE_TYPE
     for its type.  */
--- 1018,1023 ----
*************** build_primary_vtable (binfo, type)
*** 1067,1074 ****
    
    if (binfo)
      {
-       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.  */
--- 1099,1104 ----
*************** build_primary_vtable (binfo, type)
*** 1079,1089 ****
        DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
        DECL_SIZE_UNIT (decl)
  	= TYPE_SIZE_UNIT (TREE_TYPE (BINFO_VTABLE (binfo)));
- 
-       /* Now do rtti stuff.  */
-       offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
-       offset = size_diffop (size_zero_node, offset);
-       set_rtti_entry (virtuals, offset, type);
      }
    else
      {
--- 1109,1114 ----
*************** build_secondary_vtable (binfo, for_type)
*** 1171,1180 ****
    else
      offset = BINFO_OFFSET (binfo);
  
-   set_rtti_entry (BINFO_VIRTUALS (binfo),
- 		  size_diffop (size_zero_node, offset),
- 		  for_type);
- 
    /* In the new ABI, secondary vtables are laid out as part of the
       same structure as the primary vtable.  */
    if (merge_primary_and_secondary_vtables_p ())
--- 1196,1201 ----
*************** modify_vtable_entry (t, binfo, fndecl, d
*** 1349,1390 ****
      }
  }
  
! /* Call this function whenever its known that a vtable for T is going
!    to be needed.  It's safe to call it more than once.  *HAS_VIRTUAL_P
!    is initialized to the number of slots that are reserved at the
!    beginning of the vtable for RTTI information.  */
  
  static void
! start_vtable (t, has_virtual_p)
       tree t;
!      int *has_virtual_p;
  {
!   if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t))
!     {
!       /* If we are using thunks, use two slots at the front, one
! 	 for the offset pointer, one for the tdesc pointer.
!          For ARM-style vtables, use the same slot for both.  */
!       if (flag_vtable_thunks)
! 	*has_virtual_p = 2;
!       else
! 	*has_virtual_p = 1;
!     }
  }
  
  /* Add a virtual function to all the appropriate vtables for the class
     T.  DECL_VINDEX(X) should be error_mark_node, if we want to
     allocate a new slot in our table.  If it is error_mark_node, we
     know that no other function from another vtable is overridden by X.
!    HAS_VIRTUAL keeps track of how many virtuals there are in our main
!    vtable for the type, and we build upon the NEW_VIRTUALS list
     and return it.  */
  
  static void
  add_virtual_function (new_virtuals_p, overridden_virtuals_p,
! 		      has_virtual, fndecl, t)
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
!      int *has_virtual;
       tree fndecl;
       tree t; /* Structure type.  */
  {
--- 1370,1421 ----
      }
  }
  
! /* Return the index (in the virtual function table) of the first
!    virtual function.  */
  
+ int
+ first_vfun_index (t)
+      tree t;
+ {
+   /* Under the old ABI, the offset-to-top and RTTI entries are at
+      indices zero and one; under the new ABI, the first virtual
+      function is at index zero.  */
+   if (!CLASSTYPE_COM_INTERFACE (t) && !flag_new_abi)
+     return flag_vtable_thunks ? 2 : 1;
+ 
+   return 0;
+ }
+ 
+ /* Set DECL_VINDEX for DECL.  VINDEX_P is the number of virtual
+    functions present in the vtable so far.  */
+ 
  static void
! set_vindex (t, decl, vfuns_p)
       tree t;
!      tree decl;
!      int *vfuns_p;
  {
!   int vindex;
! 
!   vindex = (*vfuns_p)++;
!   vindex += first_vfun_index (t);
!   DECL_VINDEX (decl) = build_shared_int_cst (vindex);
  }
  
  /* Add a virtual function to all the appropriate vtables for the class
     T.  DECL_VINDEX(X) should be error_mark_node, if we want to
     allocate a new slot in our table.  If it is error_mark_node, we
     know that no other function from another vtable is overridden by X.
!    VFUNS_P keeps track of how many virtuals there are in our
!    main vtable for the type, and we build upon the NEW_VIRTUALS list
     and return it.  */
  
  static void
  add_virtual_function (new_virtuals_p, overridden_virtuals_p,
! 		      vfuns_p, fndecl, t)
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
!      int *vfuns_p;
       tree fndecl;
       tree t; /* Structure type.  */
  {
*************** add_virtual_function (new_virtuals_p, ov
*** 1409,1418 ****
        /* We remember that this was the base sub-object for rtti.  */
        CLASSTYPE_RTTI (t) = t;
  
-       start_vtable (t, has_virtual);
- 
        /* Now assign virtual dispatch information.  */
!       DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++);
        DECL_VIRTUAL_CONTEXT (fndecl) = t;
  
        /* Save the state we've computed on the NEW_VIRTUALS list.  */
--- 1440,1447 ----
        /* We remember that this was the base sub-object for rtti.  */
        CLASSTYPE_RTTI (t) = t;
  
        /* Now assign virtual dispatch information.  */
!       set_vindex (t, fndecl, vfuns_p);
        DECL_VIRTUAL_CONTEXT (fndecl) = t;
  
        /* Save the state we've computed on the NEW_VIRTUALS list.  */
*************** check_bases (t, cant_have_default_ctor_p
*** 1969,1978 ****
  /* Make the Ith baseclass of T its primary base.  */
  
  static void
! set_primary_base (t, i, has_virtual_p)
       tree t;
       int i;
!      int *has_virtual_p;
  {
    tree basetype;
  
--- 1998,2007 ----
  /* Make the Ith baseclass of T its primary base.  */
  
  static void
! set_primary_base (t, i, vfuns_p)
       tree t;
       int i;
!      int *vfuns_p;
  {
    tree basetype;
  
*************** set_primary_base (t, i, has_virtual_p)
*** 1982,1996 ****
    TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
    TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
    CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
!   *has_virtual_p = CLASSTYPE_VSIZE (basetype);
  }
  
  /* Determine the primary class for T.  */
  
  static void
! determine_primary_base (t, has_virtual_p)
       tree t;
!      int *has_virtual_p;
  {
    int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
  
--- 2011,2025 ----
    TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
    TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
    CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
!   *vfuns_p = CLASSTYPE_VSIZE (basetype);
  }
  
  /* Determine the primary class for T.  */
  
  static void
! determine_primary_base (t, vfuns_p)
       tree t;
!      int *vfuns_p;
  {
    int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
  
*************** determine_primary_base (t, has_virtual_p
*** 1998,2004 ****
    if (n_baseclasses == 0)
      return;
  
!   *has_virtual_p = 0;
  
    for (i = 0; i < n_baseclasses; i++)
      {
--- 2027,2033 ----
    if (n_baseclasses == 0)
      return;
  
!   *vfuns_p = 0;
  
    for (i = 0; i < n_baseclasses; i++)
      {
*************** determine_primary_base (t, has_virtual_p
*** 2021,2027 ****
  
  	  if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
  	    {
! 	      set_primary_base (t, i, has_virtual_p);
  	      CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
  	    }
  	  else
--- 2050,2056 ----
  
  	  if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
  	    {
! 	      set_primary_base (t, i, vfuns_p);
  	      CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
  	    }
  	  else
*************** determine_primary_base (t, has_virtual_p
*** 2039,2046 ****
  				 VF_BASETYPE_VALUE (vfields),
  				 CLASSTYPE_VFIELDS (t));
  
! 	      if (*has_virtual_p == 0)
! 		set_primary_base (t, i, has_virtual_p);
  	    }
  	}
      }
--- 2068,2075 ----
  				 VF_BASETYPE_VALUE (vfields),
  				 CLASSTYPE_VFIELDS (t));
  
! 	      if (*vfuns_p == 0)
! 		set_primary_base (t, i, vfuns_p);
  	    }
  	}
      }
*************** determine_primary_base (t, has_virtual_p
*** 2060,2066 ****
  	if (TREE_VIA_VIRTUAL (base_binfo) 
  	    && CLASSTYPE_NEARLY_EMPTY_P (basetype))
  	  {
! 	    set_primary_base (t, i, has_virtual_p);
  	    CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
  	    break;
  	  }
--- 2089,2095 ----
  	if (TREE_VIA_VIRTUAL (base_binfo) 
  	    && CLASSTYPE_NEARLY_EMPTY_P (basetype))
  	  {
! 	    set_primary_base (t, i, vfuns_p);
  	    CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
  	    break;
  	  }
*************** static int
*** 2557,2565 ****
  num_vfun_entries (binfo)
       tree binfo;
  {
!   return list_length (skip_rtti_stuff (binfo,
! 				       BINFO_TYPE (binfo),
! 				       NULL));
  }
  
  /* Called from num_extra_vtbl_entries via dfs_walk.  */
--- 2586,2592 ----
  num_vfun_entries (binfo)
       tree binfo;
  {
!   return list_length (BINFO_VIRTUALS (binfo));
  }
  
  /* Called from num_extra_vtbl_entries via dfs_walk.  */
*************** num_extra_vtbl_entries (binfo)
*** 2609,2615 ****
        entries += vod.offsets;
      }
        
!   return entries ? size_int (entries) : size_zero_node;
  }
  
  /* Returns the offset (in bytes) from the beginning of BINFO's vtable
--- 2636,2654 ----
        entries += vod.offsets;
      }
        
!   /* When laying out COM-compatible classes, there are no RTTI
!      entries.  */
!   if (CLASSTYPE_COM_INTERFACE (type))
!     ;
!   /* When using vtable thunks, there are two RTTI entries: the "offset
!      to top" value and the RTTI entry itself.  */
!   else if (flag_vtable_thunks)
!     entries += 2;
!   /* When not using vtable thunks there is only a single entry.  */
!   else
!     entries += 1;
! 
!   return size_int (entries);
  }
  
  /* Returns the offset (in bytes) from the beginning of BINFO's vtable
*************** build_vtbl_initializer (binfo, t)
*** 2636,2642 ****
  {
    tree v = BINFO_VIRTUALS (binfo);
    tree inits = NULL_TREE;
-   tree type = BINFO_TYPE (binfo);
  
    /* Add entries to the vtable that indicate how to adjust the this
       pointer when calling a virtual function in this class.  */
--- 2675,2680 ----
*************** build_vtbl_initializer (binfo, t)
*** 2645,2693 ****
    /* Add entries to the vtable for offsets to our virtual bases.  */
    inits = chainon (build_vbase_offset_vtbl_entries (binfo, t),
  		   inits);
- 
-   /* Process the RTTI stuff at the head of the list.  If we're not
-      using vtable thunks, then the RTTI entry is just an ordinary
-      function, and we can process it just like the other virtual
-      function entries.  */
-   if (!CLASSTYPE_COM_INTERFACE (type) && flag_vtable_thunks)
-     {
-       tree offset;
-       tree init;
- 
-       /* The first entry is an offset.  */
-       offset = TREE_PURPOSE (v);
-       my_friendly_assert (TREE_CODE (offset) == INTEGER_CST,
- 			  19990727);
- 
-       /* Convert the offset to look like a function pointer, so that
- 	 we can put it in the vtable.  */
-       init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
-       TREE_CONSTANT (init) = 1;
-       inits = tree_cons (NULL_TREE, init, inits);
  
!       v = TREE_CHAIN (v);
!       
!       if (new_abi_rtti_p ())
!         {
!           tree decl = TREE_VALUE (v);
!           
!           if (decl)
!             decl = build_unary_op (ADDR_EXPR, decl, 0);
!           else
!             decl = integer_zero_node;
!           decl = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
!           TREE_CONSTANT (decl) = 1;
!           decl = build_vtable_entry (integer_zero_node, integer_zero_node,
!                                      decl);
!           inits = tree_cons (NULL_TREE, decl, inits);
!           
!           v = TREE_CHAIN (v);
!         }
!       /* In the old abi the second entry (the tdesc pointer) is
! 	 just an ordinary function, so it can be dealt with like the
! 	 virtual functions.  */
!     }
  
    /* Go through all the ordinary virtual functions, building up
       initializers.  */
--- 2683,2691 ----
    /* Add entries to the vtable for offsets to our virtual bases.  */
    inits = chainon (build_vbase_offset_vtbl_entries (binfo, t),
  		   inits);
  
!   /* Add entries to the vtable for RTTI.  */
!   inits = chainon (build_rtti_vtbl_entries (binfo, t), inits);
  
    /* Go through all the ordinary virtual functions, building up
       initializers.  */
*************** find_final_overrider (t, binfo, fn)
*** 3048,3090 ****
    return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
  }
  
- /* Return the BINFO_VIRTUALS list for BINFO, without the RTTI stuff at
-    the front.  If non-NULL, N is set to the number of entries
-    skipped.  */
- 
- tree
- skip_rtti_stuff (binfo, t, n)
-      tree binfo;
-      tree t;
-      HOST_WIDE_INT *n;
- {
-   tree virtuals;
- 
-   if (CLASSTYPE_COM_INTERFACE (t))
-     return 0;
- 
-   if (n)
-     *n = 0;
-   virtuals = BINFO_VIRTUALS (binfo);
-   if (virtuals)
-     {
-       /* We always reserve a slot for the offset/tdesc entry.  */
-       if (n)
- 	++*n;
-       virtuals = TREE_CHAIN (virtuals);
-     }
-   if (flag_vtable_thunks && virtuals)
-     {
-       /* The second slot is reserved for the tdesc pointer when thunks
-          are used.  */
-       if (n)
- 	++*n;
-       virtuals = TREE_CHAIN (virtuals);
-     }
- 
-   return virtuals;
- }
- 
  /* Called via dfs_walk.  Returns BINFO if BINFO has the same type as
     DATA (which is really an _TYPE node).  */
  
--- 3046,3051 ----
*************** dfs_modify_vtables (binfo, data)
*** 3125,3134 ****
        /* 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 (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL),
! 	     old_virtuals = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (binfo)),
! 					     BINFO_TYPE (binfo),
! 					     NULL);
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals),
  	     old_virtuals = TREE_CHAIN (old_virtuals))
--- 3086,3093 ----
        /* 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 (virtuals = BINFO_VIRTUALS (binfo),
! 	     old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals),
  	     old_virtuals = TREE_CHAIN (old_virtuals))
*************** dfs_modify_vtables (binfo, data)
*** 3138,3154 ****
  	  tree overrider;
  	  tree vindex;
  	  tree delta;
! 	  HOST_WIDE_INT vindex_val, i;
  
- 
  	  /* Find the function which originally caused this vtable
  	     entry to be present.  */
  	  fn = BV_FN (old_virtuals);
  	  vindex = DECL_VINDEX (fn);
  	  b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
! 	  fn = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (b)),
! 				BINFO_TYPE (b),
! 				&i);
  	  vindex_val = tree_low_cst (vindex, 0);
  	  while (i < vindex_val)
  	    {
--- 3097,3112 ----
  	  tree overrider;
  	  tree vindex;
  	  tree delta;
! 	  HOST_WIDE_INT vindex_val;
! 	  HOST_WIDE_INT i;
  
  	  /* Find the function which originally caused this vtable
  	     entry to be present.  */
  	  fn = BV_FN (old_virtuals);
  	  vindex = DECL_VINDEX (fn);
  	  b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
! 	  fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b)));
! 	  i = first_vfun_index (BINFO_TYPE (b));
  	  vindex_val = tree_low_cst (vindex, 0);
  	  while (i < vindex_val)
  	    {
*************** dfs_modify_vtables (binfo, data)
*** 3195,3203 ****
     which should therefore be appended to the end of the vtable for T.  */
  
  static tree
! modify_all_vtables (t, has_virtual_p, overridden_virtuals)
       tree t;
!      int *has_virtual_p;
       tree overridden_virtuals;
  {
    tree binfo;
--- 3153,3161 ----
     which should therefore be appended to the end of the vtable for T.  */
  
  static tree
! modify_all_vtables (t, vfuns_p, overridden_virtuals)
       tree t;
!      int *vfuns_p;
       tree overridden_virtuals;
  {
    tree binfo;
*************** modify_all_vtables (t, has_virtual_p, ov
*** 3224,3234 ****
  	  if (BINFO_VIRTUALS (binfo)
  	      && !value_member (fn, BINFO_VIRTUALS (binfo)))
  	    {
- 	      /* We know we need a vtable for this class now.  */
- 	      start_vtable (t, has_virtual_p);
  	      /* Set the vtable index.  */
! 	      DECL_VINDEX (fn) 
! 		= build_shared_int_cst ((*has_virtual_p)++);
  	      /* We don't need to convert to a base class when calling
  		 this function.  */
  	      DECL_VIRTUAL_CONTEXT (fn) = t;
--- 3182,3189 ----
  	  if (BINFO_VIRTUALS (binfo)
  	      && !value_member (fn, BINFO_VIRTUALS (binfo)))
  	    {
  	      /* Set the vtable index.  */
! 	      set_vindex (t, fn, vfuns_p);
  	      /* We don't need to convert to a base class when calling
  		 this function.  */
  	      DECL_VIRTUAL_CONTEXT (fn) = t;
*************** layout_nonempty_base_or_field (rli, decl
*** 4220,4228 ****
        
        /* Now that we know where it wil be placed, update its
  	 BINFO_OFFSET.  */
!       offset = convert (ssizetype, byte_position (decl));
        if (binfo)
! 	propagate_binfo_offsets (binfo, offset);
   
        /* We have to check to see whether or not there is already
  	 something of the same type at the offset we're about to use.
--- 4175,4184 ----
        
        /* Now that we know where it wil be placed, update its
  	 BINFO_OFFSET.  */
!       offset = byte_position (decl);
        if (binfo)
! 	propagate_binfo_offsets (binfo, 
! 				 convert (ssizetype, offset));
   
        /* We have to check to see whether or not there is already
  	 something of the same type at the offset we're about to use.
*************** layout_nonempty_base_or_field (rli, decl
*** 4243,4249 ****
  	{
  	  /* Undo the propogate_binfo_offsets call.  */
  	  offset = size_diffop (size_zero_node, offset);
! 	  propagate_binfo_offsets (binfo, offset);
  	 
  	  /* Strip off the size allocated to this field.  That puts us
  	     at the first place we could have put the field with
--- 4199,4205 ----
  	{
  	  /* Undo the propogate_binfo_offsets call.  */
  	  offset = size_diffop (size_zero_node, offset);
! 	  propagate_binfo_offsets (binfo, convert (ssizetype, offset));
  	 
  	  /* Strip off the size allocated to this field.  That puts us
  	     at the first place we could have put the field with
*************** check_bases_and_members (t, empty_p)
*** 4601,4611 ****
     responsibility to do that.  */
  
  static tree
! create_vtable_ptr (t, empty_p, has_virtual_p, 
  		   new_virtuals_p, overridden_virtuals_p)
       tree t;
       int *empty_p;
!      int *has_virtual_p;
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
--- 4557,4567 ----
     responsibility to do that.  */
  
  static tree
! create_vtable_ptr (t, empty_p, vfuns_p,
  		   new_virtuals_p, overridden_virtuals_p)
       tree t;
       int *empty_p;
!      int *vfuns_p;
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
*************** create_vtable_ptr (t, empty_p, has_virtu
*** 4616,4632 ****
    for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
      if (DECL_VINDEX (fn))
        add_virtual_function (new_virtuals_p, overridden_virtuals_p,
! 			    has_virtual_p, fn, t);
  
!   /* Even if there weren't any new virtual functions, we might need a
       new virtual function table if we're supposed to include vptrs in
       all classes that need them.  */
!   if (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())
!     start_vtable (t, has_virtual_p);
!     
!   /* If we couldn't find an appropriate base class, create a new field
!      here.  */
!   if (*has_virtual_p && !TYPE_VFIELD (t))
      {
        /* We build this decl with vtbl_ptr_type_node, which is a
  	 `vtable_entry_type*'.  It might seem more precise to use
--- 4572,4586 ----
    for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
      if (DECL_VINDEX (fn))
        add_virtual_function (new_virtuals_p, overridden_virtuals_p,
! 			    vfuns_p, fn, t);
  
!   /* If we couldn't find an appropriate base class, create a new field
!      here.  Even if there weren't any new virtual functions, we might need a
       new virtual function table if we're supposed to include vptrs in
       all classes that need them.  */
!   if (!TYPE_VFIELD (t)
!       && (*vfuns_p 
! 	  || (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())))
      {
        /* We build this decl with vtbl_ptr_type_node, which is a
  	 `vtable_entry_type*'.  It might seem more precise to use
*************** end_of_class (t, include_virtuals_p)
*** 4972,4982 ****
     pointer.  */
  
  static void
! layout_class_type (t, empty_p, has_virtual_p, 
  		   new_virtuals_p, overridden_virtuals_p)
       tree t;
       int *empty_p;
!      int *has_virtual_p;
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
--- 4926,4936 ----
     pointer.  */
  
  static void
! layout_class_type (t, empty_p, vfuns_p, 
  		   new_virtuals_p, overridden_virtuals_p)
       tree t;
       int *empty_p;
!      int *vfuns_p;
       tree *new_virtuals_p;
       tree *overridden_virtuals_p;
  {
*************** layout_class_type (t, empty_p, has_virtu
*** 4995,5004 ****
  
    /* If possible, we reuse the virtual function table pointer from one
       of our base classes.  */
!   determine_primary_base (t, has_virtual_p);
  
    /* Create a pointer to our virtual function table.  */
!   vptr = create_vtable_ptr (t, empty_p, has_virtual_p,
  			    new_virtuals_p, overridden_virtuals_p);
  
    /* Under the new ABI, the vptr is always the first thing in the
--- 4949,4958 ----
  
    /* If possible, we reuse the virtual function table pointer from one
       of our base classes.  */
!   determine_primary_base (t, vfuns_p);
  
    /* Create a pointer to our virtual function table.  */
!   vptr = create_vtable_ptr (t, empty_p, vfuns_p,
  			    new_virtuals_p, overridden_virtuals_p);
  
    /* Under the new ABI, the vptr is always the first thing in the
*************** finish_struct_1 (t)
*** 5215,5221 ****
       tree t;
  {
    tree x;
!   int has_virtual;
    /* The NEW_VIRTUALS is a TREE_LIST.  The TREE_VALUE of each node is
       a FUNCTION_DECL.  Each of these functions is a virtual function
       declared in T that does not override any virtual function from a
--- 5169,5175 ----
       tree t;
  {
    tree x;
!   int vfuns;
    /* The NEW_VIRTUALS is a TREE_LIST.  The TREE_VALUE of each node is
       a FUNCTION_DECL.  Each of these functions is a virtual function
       declared in T that does not override any virtual function from a
*************** finish_struct_1 (t)
*** 5246,5252 ****
    TYPE_SIZE (t) = NULL_TREE;
    CLASSTYPE_GOT_SEMICOLON (t) = 0;
    CLASSTYPE_VFIELD_PARENT (t) = -1;
!   has_virtual = 0;
    CLASSTYPE_RTTI (t) = NULL_TREE;
  
    /* Do end-of-class semantic processing: checking the validity of the
--- 5200,5206 ----
    TYPE_SIZE (t) = NULL_TREE;
    CLASSTYPE_GOT_SEMICOLON (t) = 0;
    CLASSTYPE_VFIELD_PARENT (t) = -1;
!   vfuns = 0;
    CLASSTYPE_RTTI (t) = NULL_TREE;
  
    /* Do end-of-class semantic processing: checking the validity of the
*************** finish_struct_1 (t)
*** 5254,5260 ****
    check_bases_and_members (t, &empty);
  
    /* Layout the class itself.  */
!   layout_class_type (t, &empty, &has_virtual,
  		     &new_virtuals, &overridden_virtuals);
  
    /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
--- 5208,5214 ----
    check_bases_and_members (t, &empty);
  
    /* Layout the class itself.  */
!   layout_class_type (t, &empty, &vfuns,
  		     &new_virtuals, &overridden_virtuals);
  
    /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
*************** finish_struct_1 (t)
*** 5278,5284 ****
      }
  
    overridden_virtuals 
!     = modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals));
  
    /* If necessary, create the primary vtable for this class.  */
    if (new_virtuals
--- 5232,5238 ----
      }
  
    overridden_virtuals 
!     = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
  
    /* If necessary, create the primary vtable for this class.  */
    if (new_virtuals
*************** finish_struct_1 (t)
*** 5288,5309 ****
        new_virtuals = nreverse (new_virtuals);
        /* We must enter these virtuals into the table.  */
        if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
! 	{
! 	  if (! CLASSTYPE_COM_INTERFACE (t))
! 	    {
! 	      /* The second slot is for the tdesc pointer when thunks
! 		 are used.  */
! 	      if (flag_vtable_thunks)
! 		new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
! 
! 	      /* The first slot is for the rtti offset.  */
! 	      new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
! 
! 	      set_rtti_entry (new_virtuals,
! 			      convert (ssizetype, integer_zero_node), t);
! 	    }
! 	  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.  */
--- 5242,5248 ----
        new_virtuals = nreverse (new_virtuals);
        /* We must enter these virtuals into the table.  */
        if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
! 	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.  */
*************** finish_struct_1 (t)
*** 5346,5352 ****
  	my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE,
  			    20000116);
  
!       CLASSTYPE_VSIZE (t) = has_virtual;
        /* Entries for virtual functions defined in the primary base are
  	 followed by entries for new functions unique to this class.  */
        TYPE_BINFO_VIRTUALS (t) 
--- 5285,5291 ----
  	my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE,
  			    20000116);
  
!       CLASSTYPE_VSIZE (t) = vfuns;
        /* Entries for virtual functions defined in the primary base are
  	 followed by entries for new functions unique to this class.  */
        TYPE_BINFO_VIRTUALS (t) 
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.428
diff -c -p -r1.428 cp-tree.h
*** cp-tree.h	2000/03/27 01:26:17	1.428
--- cp-tree.h	2000/03/28 19:08:57
*************** struct lang_type
*** 1545,1552 ****
  		     CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (NODE)))	\
     : NULL_TREE)
  
! /* The number of virtual functions defined for this
!    _CLASSTYPE node.  */
  #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize)
  
  /* A chain of BINFOs for the direct and indirect virtual base classes
--- 1545,1552 ----
  		     CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (NODE)))	\
     : NULL_TREE)
  
! /* The number of virtual functions present in this classes virtual
!    function table.  */
  #define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize)
  
  /* A chain of BINFOs for the direct and indirect virtual base classes
*************** extern void push_lang_context			PARAMS (
*** 3685,3692 ****
  extern void pop_lang_context			PARAMS ((void));
  extern tree instantiate_type			PARAMS ((tree, tree, int));
  extern void print_class_statistics		PARAMS ((void));
! extern tree skip_rtti_stuff	                PARAMS ((tree, tree,
! 							 HOST_WIDE_INT *));
  extern void build_self_reference		PARAMS ((void));
  extern void warn_hidden				PARAMS ((tree));
  extern tree get_enclosing_class			PARAMS ((tree));
--- 3685,3691 ----
  extern void pop_lang_context			PARAMS ((void));
  extern tree instantiate_type			PARAMS ((tree, tree, int));
  extern void print_class_statistics		PARAMS ((void));
! extern int first_vfun_index                     PARAMS ((tree));
  extern void build_self_reference		PARAMS ((void));
  extern void warn_hidden				PARAMS ((tree));
  extern tree get_enclosing_class			PARAMS ((tree));
*************** extern tree dfs_skip_nonprimary_vbases_u
*** 4212,4222 ****
  extern tree dfs_skip_nonprimary_vbases_markedp  PARAMS ((tree, void *));
  extern tree dfs_unmarked_real_bases_queue_p     PARAMS ((tree, void *));
  extern tree dfs_marked_real_bases_queue_p       PARAMS ((tree, void *));
- extern tree dfs_vtable_path_unmarked_real_bases_queue_p
-                                                 PARAMS ((tree, void *));
- extern tree dfs_vtable_path_marked_real_bases_queue_p
-                                                 PARAMS ((tree, void *));
  extern tree dfs_skip_vbases                     PARAMS ((tree, void *));
  extern void mark_primary_bases                  PARAMS ((tree));
  extern tree convert_pointer_to_vbase            PARAMS ((tree, tree));
  extern tree find_vbase_instance                 PARAMS ((tree, tree));
--- 4211,4219 ----
  extern tree dfs_skip_nonprimary_vbases_markedp  PARAMS ((tree, void *));
  extern tree dfs_unmarked_real_bases_queue_p     PARAMS ((tree, void *));
  extern tree dfs_marked_real_bases_queue_p       PARAMS ((tree, void *));
  extern tree dfs_skip_vbases                     PARAMS ((tree, void *));
+ extern tree marked_vtable_pathp                 PARAMS ((tree, void *));
+ extern tree unmarked_vtable_pathp               PARAMS ((tree, void *));
  extern void mark_primary_bases                  PARAMS ((tree));
  extern tree convert_pointer_to_vbase            PARAMS ((tree, tree));
  extern tree find_vbase_instance                 PARAMS ((tree, tree));
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.110
diff -c -p -r1.110 error.c
*** error.c	2000/03/25 16:38:49	1.110
--- error.c	2000/03/28 19:08:58
*************** dump_expr (t, flags)
*** 1857,1863 ****
  	      t = TYPE_METHOD_BASETYPE (t);
  	      virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
  	      
! 	      n = tree_low_cst (idx, 0);
  
  	      /* Map vtable index back one, to allow for the null pointer to
  		 member.  */
--- 1857,1863 ----
  	      t = TYPE_METHOD_BASETYPE (t);
  	      virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
  	      
! 	      n = tree_low_cst (idx, 0) - first_vfun_index (t);
  
  	      /* Map vtable index back one, to allow for the null pointer to
  		 member.  */
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.75
diff -c -p -r1.75 rtti.c
*** rtti.c	2000/03/25 18:34:12	1.75
--- rtti.c	2000/03/28 19:08:59
*************** build_headof (exp)
*** 132,137 ****
--- 132,138 ----
    tree type = TREE_TYPE (exp);
    tree aref;
    tree offset;
+   tree index;
  
    my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
    type = TREE_TYPE (type);
*************** build_headof (exp)
*** 151,157 ****
    /* We use this a couple of times below, protect it.  */
    exp = save_expr (exp);
  
!   aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
  
    if (flag_vtable_thunks)
      offset = aref;
--- 152,166 ----
    /* We use this a couple of times below, protect it.  */
    exp = save_expr (exp);
  
!   /* Under the new ABI, the offset-to-top field is at index -2 from
!      the vptr.  */
!   if (new_abi_rtti_p ())
!     index = build_int_2 (-2, -1);
!   /* But under the old ABI, it is at offset zero.  */
!   else
!     index = integer_zero_node;
! 
!   aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), index);
  
    if (flag_vtable_thunks)
      offset = aref;
*************** get_tinfo_decl_dynamic (exp)
*** 230,235 ****
--- 239,245 ----
      {
        /* build reference to type_info from vtable.  */
        tree t;
+       tree index;
  
        if (! flag_rtti)
  	error ("taking dynamic typeid of object with -fno-rtti");
*************** get_tinfo_decl_dynamic (exp)
*** 247,256 ****
  	  exp = build_indirect_ref (exp, NULL_PTR);
  	}
  
!       if (flag_vtable_thunks)
! 	t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
        else
! 	t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
      }
--- 257,271 ----
  	  exp = build_indirect_ref (exp, NULL_PTR);
  	}
  
!       /* The RTTI information is always in the vtable, but it's at
! 	 different indices depending on the ABI.  */
!       if (new_abi_rtti_p ())
! 	index = minus_one_node;
!       else if (flag_vtable_thunks)
! 	index = integer_one_node;
        else
! 	index = integer_zero_node;
!       t = build_vfn_ref ((tree *) 0, exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
      }
*************** tinfo_base_init (desc, target)
*** 1284,1291 ****
    
    if (TINFO_VTABLE_DECL (desc))
      {
!       tree vtbl_ptr = build_unary_op (ADDR_EXPR, TINFO_VTABLE_DECL (desc), 0);
!   
        init = tree_cons (NULL_TREE, vtbl_ptr, init);
      }
    
--- 1298,1304 ----
    
    if (TINFO_VTABLE_DECL (desc))
      {
!       tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
        init = tree_cons (NULL_TREE, vtbl_ptr, init);
      }
    
*************** create_pseudo_type_info VPARAMS((const c
*** 1616,1622 ****
    /* Get the vtable decl. */
    real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
    vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
!   
    /* First field is the pseudo type_info base class. */
    fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
    
--- 1629,1646 ----
    /* Get the vtable decl. */
    real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
    vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
!   vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
! 
!   /* Under the new ABI, we need to point into the middle of the
!      vtable.  */
!   if (vbase_offsets_in_vtable_p ())
!     {
!       vtable_decl = build (PLUS_EXPR, TREE_TYPE (vtable_decl), 
! 			   vtable_decl,
! 			   size_extra_vtbl_entries (TYPE_BINFO (real_type)));
!       TREE_CONSTANT (vtable_decl) = 1;
!     }
! 
    /* First field is the pseudo type_info base class. */
    fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
    
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.167
diff -c -p -r1.167 search.c
*** search.c	2000/03/23 00:41:05	1.167
--- search.c	2000/03/28 19:09:01
*************** static void expand_upcast_fixups 
*** 104,111 ****
  static void fixup_virtual_upcast_offsets
  	PARAMS ((tree, tree, int, int, tree, tree, tree, tree,
  	       tree *));
- static tree marked_vtable_pathp PARAMS ((tree, void *));
- static tree unmarked_vtable_pathp PARAMS ((tree, void *));
  static tree marked_new_vtablep PARAMS ((tree, void *));
  static tree unmarked_new_vtablep PARAMS ((tree, void *));
  static tree marked_pushdecls_p PARAMS ((tree, void *));
--- 104,109 ----
*************** dfs_marked_real_bases_queue_p (binfo, da
*** 2346,2375 ****
    return binfo ? markedp (binfo, NULL) : NULL_TREE;
  }
  
- /* Like dfs_unmarked_real_bases_queue_p but walks only into things
-    that are not BINFO_VTABLE_PATH_MARKED.  */
- 
- tree
- dfs_vtable_path_unmarked_real_bases_queue_p (binfo, data)
-      tree binfo;
-      void *data;
- {
-   binfo = get_shared_vbase_if_not_primary (binfo, data); 
-   return binfo ? unmarked_vtable_pathp (binfo, NULL): NULL_TREE;
- }
- 
- /* Like dfs_unmarked_real_bases_queue_p but walks only into things
-    that are BINFO_VTABLE_PATH_MARKED.  */
- 
- tree
- dfs_vtable_path_marked_real_bases_queue_p (binfo, data)
-      tree binfo;
-      void *data;
- {
-   binfo = get_shared_vbase_if_not_primary (binfo, data); 
-   return binfo ? marked_vtable_pathp (binfo, NULL): NULL_TREE;
- }
- 
  /* A queue function that skips all virtual bases (and their 
     bases).  */
  
--- 2344,2349 ----
*************** dfs_get_pure_virtuals (binfo, data)
*** 2400,2408 ****
      {
        tree virtuals;
        
!       for (virtuals = skip_rtti_stuff (binfo, 
! 				       BINFO_TYPE (binfo), 
! 				       NULL);
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals))
  	if (DECL_PURE_VIRTUAL_P (TREE_VALUE (virtuals)))
--- 2374,2380 ----
      {
        tree virtuals;
        
!       for (virtuals = BINFO_VIRTUALS (binfo);
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals))
  	if (DECL_PURE_VIRTUAL_P (TREE_VALUE (virtuals)))
*************** get_pure_virtuals (type)
*** 2447,2453 ****
      {
        tree virtuals;
  
!       for (virtuals = skip_rtti_stuff (vbases, BINFO_TYPE (vbases), NULL);
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals))
  	{
--- 2419,2425 ----
      {
        tree virtuals;
  
!       for (virtuals = BINFO_VIRTUALS (vbases);
  	   virtuals;
  	   virtuals = TREE_CHAIN (virtuals))
  	{
*************** unmarkedp (binfo, data) 
*** 2527,2533 ****
    return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
  }
  
! static tree
  marked_vtable_pathp (binfo, data) 
       tree binfo;
       void *data ATTRIBUTE_UNUSED;
--- 2499,2505 ----
    return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
  }
  
! tree
  marked_vtable_pathp (binfo, data) 
       tree binfo;
       void *data ATTRIBUTE_UNUSED;
*************** marked_vtable_pathp (binfo, data) 
*** 2535,2541 ****
    return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE; 
  }
  
! static tree
  unmarked_vtable_pathp (binfo, data) 
       tree binfo;
       void *data ATTRIBUTE_UNUSED;
--- 2507,2513 ----
    return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE; 
  }
  
! tree
  unmarked_vtable_pathp (binfo, data) 
       tree binfo;
       void *data ATTRIBUTE_UNUSED;
*************** expand_upcast_fixups (binfo, addr, orig_
*** 2862,2871 ****
        delta = tree_cons (vbase, delta, *vbase_offsets);
        *vbase_offsets = delta;
      }
- 
-   virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
  
!   while (virtuals)
      {
        tree current_fndecl = TREE_VALUE (virtuals);
  
--- 2834,2844 ----
        delta = tree_cons (vbase, delta, *vbase_offsets);
        *vbase_offsets = delta;
      }
  
!   for (virtuals = BINFO_VIRTUALS (binfo), 
! 	 n = first_vfun_index (BINFO_TYPE (binfo));
!        virtuals;
!        virtuals = TREE_CHAIN (virtuals), ++n)
      {
        tree current_fndecl = TREE_VALUE (virtuals);
  
*************** expand_upcast_fixups (binfo, addr, orig_
*** 2956,2963 ****
  	  finish_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
  					       old_delta));
  	}
-       ++n;
-       virtuals = TREE_CHAIN (virtuals);
      }
  }
  
--- 2929,2934 ----
Index: cp/tinfo.cc
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tinfo.cc,v
retrieving revision 1.18
diff -c -p -r1.18 tinfo.cc
*** tinfo.cc	2000/03/21 16:12:24	1.18
--- tinfo.cc	2000/03/28 19:09:02
*************** __dynamic_cast (const void *src_ptr,    
*** 1100,1108 ****
  {
    const void *vtable = *static_cast <const void *const *> (src_ptr);
    const vtable_prefix *prefix =
!       adjust_pointer <vtable_prefix> (vtable, 0);
!   // FIXME: the above offset should be -offsetof (vtable_prefix, origin));
!   // but we don't currently layout vtables correctly.
    const void *whole_ptr =
        adjust_pointer <void> (src_ptr, prefix->whole_object);
    const __class_type_info *whole_type = prefix->whole_type;
--- 1100,1107 ----
  {
    const void *vtable = *static_cast <const void *const *> (src_ptr);
    const vtable_prefix *prefix =
!       adjust_pointer <vtable_prefix> (vtable, 
! 				      -offsetof (vtable_prefix, origin));
    const void *whole_ptr =
        adjust_pointer <void> (src_ptr, prefix->whole_object);
    const __class_type_info *whole_type = prefix->whole_type;
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/tree.c,v
retrieving revision 1.188
diff -c -p -r1.188 tree.c
*** tree.c	2000/03/23 00:41:05	1.188
--- tree.c	2000/03/28 19:09:03
*************** debug_binfo (elem)
*** 925,931 ****
    else
      fprintf (stderr, "no vtable decl yet\n");
    fprintf (stderr, "virtuals:\n");
!   virtuals = skip_rtti_stuff (elem, BINFO_TYPE (elem), &n);
  
    while (virtuals)
      {
--- 925,932 ----
    else
      fprintf (stderr, "no vtable decl yet\n");
    fprintf (stderr, "virtuals:\n");
!   virtuals = BINFO_VIRTUALS (elem);
!   n = first_vfun_index (BINFO_TYPE (elem));
  
    while (virtuals)
      {

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