[C++ PATCH]: Remove no-vtable-thunk

Nathan Sidwell nathan@codesourcery.com
Fri Jul 20 10:51:00 GMT 2001


Mark,
this removes all the non-thunk vtable stuff.

We were already ignoring DEFAULT_VTABLE_THUNKS, so there should
be no issue about ripping it out of all the config file.

booted & tested on i686-pc-linux-gnu, ok?

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-07-20  Nathan Sidwell  <nathan@codesourcery.com>

	Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
	* cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
	(CPTI_INDEX_IDENTIFIER): Remove.
	(CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
	(delta2_identifier): Remove.
	(index_identifier): Remove.
	(pfn_or_delta2_identifier): Remove.
	(flag_vtable_thunks): Remove.
	(VTABLE_DELTA2_NAME): Remove.
	(VTABLE_INDEX_NAME): Remove.
	(FNADDR_FROM_VTABLE_ENTRY): Adjust.
	(vfunc_ptr_type_node): Adjust.
	(VTABLE_NAME_PREFIX): Adjust.
	(build_vfn_ref): Lose first parameter.
	(fixup_all_virtual_upcast_offsets): Remove.
	* decl.c (initialize_predefined_identifiers): Remove
	delta2_identifier, index_identifier, pfn_or_delta2_identifier.
	(init_decl_processing): Remove no-vtable-thunk code.
	* decl2.c (flag_vtable_thunks): Remove.
	(mark_vtable_entries): Remove no-vtable-thunk code.
	* error.c (dump_decl): Remove no-vtable-thunk code.
	(dump_expr): Adjust ptr to member function code.
	* init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
	code.
	* rtti.c (build_headof): Remove no-vtable-thunk code.
	(get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
	* search.c (get_base_distance): Remove expand_upcast_fixups case.
	(virtual_context) Remove.
	(expand_upcast_fixups): Remove.
	(fixup_virtual_upcast_offsets): Remove.
	(fixup_all_virtual_upcast_offsets): Remove.
	* typeck.c (get_member_function_from_ptrfunc): Remove
	no-vtable-thunk code.
	* call.c (build_over_call): Adjust call to build_vfn_ref.
	* class.c (build_vfn_ref): Lose first parameter. Remove
	no-vtable-thunk code.
	(build_rtti_vtbl_entries): Remove no-vtable-thunk code.
	(build_vtable_entry): Remove no-vtable-thunk code.

2001-07-20  Nathan Sidwell  <nathan@codesourcery.com>

	* doc/tm.texi: Remove DEFAULT_VTABLE_THUNKS
	* config/freebsd.h: Likewise.
	* config/linux.h: Likewise.
	* config/openbsd.h: Likewise.
	* config/alpha/linux-elf.h: Likewise.
	* config/arm/linux-elf.h: Likewise.
	* config/d30v/d30v.h: Likewise.
	* config/fr30/fr30.h: Likewise.
	* config/ia64/aix.h: Likewise.
	* config/ia64/ia64.h: Likewise.
	* config/mips/linux.h: Likewise.
	* config/pj/pj.h: Likewise.
	* config/rs6000/linux.h: Likewise.
	* config/sparc/linux.h: Likewise.
	* config/sparc/linux64.h: Likewise.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.274
diff -c -3 -p -r1.274 call.c
*** call.c	2001/07/10 10:38:09	1.274
--- call.c	2001/07/20 15:10:59
*************** build_over_call (cand, args, flags)
*** 4307,4313 ****
        if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
  	fn = build_java_interface_fn_ref (fn, *p);
        else
! 	fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
        TREE_TYPE (fn) = t;
      }
    else if (DECL_INLINE (fn))
--- 4307,4313 ----
        if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
  	fn = build_java_interface_fn_ref (fn, *p);
        else
! 	fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn));
        TREE_TYPE (fn) = t;
      }
    else if (DECL_INLINE (fn))
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.394
diff -c -3 -p -r1.394 class.c
*** class.c	2001/07/19 07:22:40	1.394
--- class.c	2001/07/20 15:11:10
*************** build_vtbl_ref (instance, idx)
*** 632,668 ****
  }
  
  /* Given an object INSTANCE, return an expression which yields the
!    virtual function corresponding to INDEX.  There are many special
!    cases for INSTANCE which we take care of here, mainly to avoid
!    creating extra tree nodes when we don't have to.  */
  
  tree
! build_vfn_ref (ptr_to_instptr, instance, idx)
!      tree *ptr_to_instptr, instance;
       tree idx;
  {
    tree aref = build_vtbl_ref (instance, idx);
- 
-   /* When using thunks, there is no extra delta, and we get the pfn
-      directly.  */
-   if (flag_vtable_thunks)
-     return aref;
- 
-   if (ptr_to_instptr)
-     {
-       /* Save the intermediate result in a SAVE_EXPR so we don't have to
- 	 compute each component of the virtual function pointer twice.  */ 
-       if (TREE_CODE (aref) == INDIRECT_REF)
- 	TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0));
- 
-       *ptr_to_instptr
- 	= build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr),
- 		 *ptr_to_instptr,
- 		 cp_convert (ptrdiff_type_node,
- 			     build_component_ref (aref, delta_identifier, NULL_TREE, 0)));
-     }
  
!   return build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
  }
  
  /* Return the name of the virtual function table (as an IDENTIFIER_NODE)
--- 632,647 ----
  }
  
  /* Given an object INSTANCE, return an expression which yields the
!    virtual function corresponding to IDX. */
  
  tree
! build_vfn_ref (instance, idx)
!      tree instance;
       tree idx;
  {
    tree aref = build_vtbl_ref (instance, idx);
  
!   return aref;
  }
  
  /* Return the name of the virtual function table (as an IDENTIFIER_NODE)
*************** build_rtti_vtbl_entries (binfo, vid)
*** 8294,8309 ****
    vid->last_init = &TREE_CHAIN (*vid->last_init);
  
    /* Add the offset-to-top entry.  It comes earlier in the vtable that
!      the the typeinfo 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;
!       *vid->last_init = build_tree_list (NULL_TREE, init);
!       vid->last_init = &TREE_CHAIN (*vid->last_init);
!     }
  }
  
  /* Build an entry in the virtual function table.  DELTA is the offset
--- 8273,8284 ----
    vid->last_init = &TREE_CHAIN (*vid->last_init);
  
    /* Add the offset-to-top entry.  It comes earlier in the vtable that
!      the the typeinfo entry.  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;
!   *vid->last_init = build_tree_list (NULL_TREE, init);
!   vid->last_init = &TREE_CHAIN (*vid->last_init);
  }
  
  /* Build an entry in the virtual function table.  DELTA is the offset
*************** build_vtable_entry (delta, vcall_index, 
*** 8320,8373 ****
       tree vcall_index;
       tree entry;
  {
!   if (flag_vtable_thunks)
!     {
!       tree fn;
! 
!       fn = TREE_OPERAND (entry, 0);
!       if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
! 	  && fn != abort_fndecl)
! 	{
! 	  entry = make_thunk (entry, delta, vcall_index);
! 	  entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
! 	  TREE_READONLY (entry) = 1;
! 	  TREE_CONSTANT (entry) = 1;
! 	}
! #ifdef GATHER_STATISTICS
!       n_vtable_entries += 1;
! #endif
!       return entry;
!     }
!   else
      {
!       tree elems = tree_cons (NULL_TREE, delta,
! 			      tree_cons (NULL_TREE, integer_zero_node,
! 					 build_tree_list (NULL_TREE, entry)));
!       tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
! 
!       /* We don't use vcall offsets when not using vtable thunks.  */
!       my_friendly_assert (vcall_index == NULL_TREE, 20000125);
! 
!       /* DELTA used to be constructed by `size_int' and/or size_binop,
! 	 which caused overflow problems when it was negative.  That should
! 	 be fixed now.  */
! 
!       if (! int_fits_type_p (delta, delta_type_node))
! 	{
! 	  if (flag_huge_objects)
! 	    sorry ("object size exceeds built-in limit for virtual function table implementation");
! 	  else
! 	    sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
! 	}
!       
!       TREE_CONSTANT (entry) = 1;
!       TREE_STATIC (entry) = 1;
        TREE_READONLY (entry) = 1;
! 
  #ifdef GATHER_STATISTICS
!       n_vtable_entries += 1;
  #endif
! 
!       return entry;
!     }
  }
--- 8295,8312 ----
       tree vcall_index;
       tree entry;
  {
!   tree fn = TREE_OPERAND (entry, 0);
!   
!   if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
!       && fn != abort_fndecl)
      {
!       entry = make_thunk (entry, delta, vcall_index);
!       entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
        TREE_READONLY (entry) = 1;
!       TREE_CONSTANT (entry) = 1;
!     }
  #ifdef GATHER_STATISTICS
!   n_vtable_entries += 1;
  #endif
!   return entry;
  }
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.627
diff -c -3 -p -r1.627 cp-tree.h
*** cp-tree.h	2001/07/19 04:27:15	1.627
--- cp-tree.h	2001/07/20 15:11:19
*************** enum cp_tree_index
*** 588,602 ****
      CPTI_COMPLETE_DTOR_IDENTIFIER,
      CPTI_BASE_DTOR_IDENTIFIER,
      CPTI_DELETING_DTOR_IDENTIFIER,
-     CPTI_DELTA2_IDENTIFIER,
      CPTI_DELTA_IDENTIFIER,
      CPTI_IN_CHARGE_IDENTIFIER,
      CPTI_VTT_PARM_IDENTIFIER,
-     CPTI_INDEX_IDENTIFIER,
      CPTI_NELTS_IDENTIFIER,
      CPTI_THIS_IDENTIFIER,
      CPTI_PFN_IDENTIFIER,
-     CPTI_PFN_OR_DELTA2_IDENTIFIER,
      CPTI_VPTR_IDENTIFIER,
      CPTI_STD_IDENTIFIER,
  
--- 588,599 ----
*************** extern tree cp_global_trees[CPTI_MAX];
*** 630,637 ****
  #define wchar_decl_node			cp_global_trees[CPTI_WCHAR_DECL]
  #define vtable_entry_type		cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
  /* The type used to represent an offset by which to adjust the `this'
!    pointer in pointer-to-member types and, when not using vtable
!    thunks, in vtables.  */
  #define delta_type_node			cp_global_trees[CPTI_DELTA_TYPE]
  /* The type used to represent an index into the vtable.  */
  #define vtable_index_type               cp_global_trees[CPTI_VTABLE_INDEX_TYPE]
--- 627,633 ----
  #define wchar_decl_node			cp_global_trees[CPTI_WCHAR_DECL]
  #define vtable_entry_type		cp_global_trees[CPTI_VTABLE_ENTRY_TYPE]
  /* The type used to represent an offset by which to adjust the `this'
!    pointer in pointer-to-member types.  */
  #define delta_type_node			cp_global_trees[CPTI_DELTA_TYPE]
  /* The type used to represent an index into the vtable.  */
  #define vtable_index_type               cp_global_trees[CPTI_VTABLE_INDEX_TYPE]
*************** extern tree cp_global_trees[CPTI_MAX];
*** 707,726 ****
  /* The name of a destructor that destroys virtual base classes, and
     then deletes the entire object.  */
  #define deleting_dtor_identifier        cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER]
- 
- #define delta2_identifier               cp_global_trees[CPTI_DELTA2_IDENTIFIER]
  #define delta_identifier                cp_global_trees[CPTI_DELTA_IDENTIFIER]
  #define in_charge_identifier            cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER]
- 
  /* The name of the parameter that contains a pointer to the VTT to use
     for this subobject constructor or destructor.  */
  #define vtt_parm_identifier             cp_global_trees[CPTI_VTT_PARM_IDENTIFIER]
- 
- #define index_identifier                cp_global_trees[CPTI_INDEX_IDENTIFIER]
  #define nelts_identifier                cp_global_trees[CPTI_NELTS_IDENTIFIER]
  #define this_identifier                 cp_global_trees[CPTI_THIS_IDENTIFIER]
  #define pfn_identifier                  cp_global_trees[CPTI_PFN_IDENTIFIER]
- #define pfn_or_delta2_identifier        cp_global_trees[CPTI_PFN_OR_DELTA2_IDENTIFIER]
  #define vptr_identifier                 cp_global_trees[CPTI_VPTR_IDENTIFIER]
  /* The name of the std namespace.  */
  #define std_identifier                  cp_global_trees[CPTI_STD_IDENTIFIER]
--- 703,716 ----
*************** extern int warn_reorder;
*** 1067,1077 ****
  
  extern int flag_signed_bitfields;
  
- /* True for more efficient but incompatible (not fully tested)
-    vtable implementation (using thunks).
-    0 is old behavior; 1 is new behavior.  */
- extern int flag_vtable_thunks;
- 
  /* INTERFACE_ONLY nonzero means that we are in an "interface"
     section of the compiler.  INTERFACE_UNKNOWN nonzero means
     we cannot trust the value of INTERFACE_ONLY.  If INTERFACE_UNKNOWN
--- 1057,1062 ----
*************** enum languages { lang_c, lang_cplusplus,
*** 1216,1226 ****
  /* Virtual function addresses can be gotten from a virtual function
     table entry using this macro.  */
  #define FNADDR_FROM_VTABLE_ENTRY(ENTRY)					\
!   (!flag_vtable_thunks ?						\
!      TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY))))	\
!    : !DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))				\
!    ? (ENTRY)								\
!    : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0)))
  
  #define FUNCTION_ARG_CHAIN(NODE) \
    (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
--- 1201,1209 ----
  /* Virtual function addresses can be gotten from a virtual function
     table entry using this macro.  */
  #define FNADDR_FROM_VTABLE_ENTRY(ENTRY)					\
!   (DECL_THUNK_P (TREE_OPERAND ((ENTRY), 0))				\
!    : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0))				\
!    ? (ENTRY))
  
  #define FUNCTION_ARG_CHAIN(NODE) \
    (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))))
*************** extern int flag_new_for_scope;
*** 2587,2653 ****
  
  /* A pointer-to-function member type looks like:
  
-    struct {
-      short __delta;
-      short __index;
-      union {
-        P __pfn;
-        short __delta2;
-      } __pfn_or_delta2;
-    };
- 
-    where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the
-    pointer to member.  The fields are used as follows:
- 
-      If __INDEX is -1, then the function to call is non-virtual, and
-      is located at the address given by __PFN.
- 
-      If __INDEX is zero, then this a NULL pointer-to-member.
- 
-      Otherwise, the function to call is virtual.  Then, __DELTA2 gives
-      the offset from an instance of the object to the virtual function
-      table, and __INDEX - 1 is the index into the vtable to use to
-      find the function.
- 
-      The value to use for the THIS parameter is the address of the
-      object plus __DELTA.
- 
-    For example, given:
- 
-      struct B1 {
-        int i;
-      };
- 
-      struct B2 {
-        double d;
-        void f();
-      };
- 
-      struct S : public B1, B2 {};
- 
-    the pointer-to-member for `&S::f' looks like:
- 
-      { 4, -1, { &f__2B2 } };
- 
-    The `4' means that given an `S*' you have to add 4 bytes to get to
-    the address of the `B2*'.  Then, the -1 indicates that this is a
-    non-virtual function.  Of course, `&f__2B2' is the name of that
-    function.
- 
-    (Of course, the exact values may differ depending on the mangling
-    scheme, sizes of types, and such.).
- 
-    Under the new ABI, we do:
- 
       struct {
         __P __pfn;
         ptrdiff_t __delta;
       };
  
!    (We don't need DELTA2, because the vtable is always the first thing
!    in the object.)  If the function is virtual, then PFN is one plus
!    twice the index into the vtable; otherwise, it is just a pointer to
!    the function.
  
     Unfortunately, using the lowest bit of PFN doesn't work in
     architectures that don't impose alignment requirements on function
--- 2570,2586 ----
  
  /* A pointer-to-function member type looks like:
  
       struct {
         __P __pfn;
         ptrdiff_t __delta;
       };
  
!    If __pfn is NULL, it is a NULL pointer-to-member-function.
!    
!    (Because the vtable is always the first thing in the object, we
!    don't need its offset.)  If the function is virtual, then PFN is
!    one plus twice the index into the vtable; otherwise, it is just a
!    pointer to the function.
  
     Unfortunately, using the lowest bit of PFN doesn't work in
     architectures that don't impose alignment requirements on function
*************** extern tree error_mark_list;
*** 3176,3183 ****
  
  /* Node for "pointer to (virtual) function".
     This may be distinct from ptr_type_node so gdb can distinguish them.  */
! #define vfunc_ptr_type_node \
!   (flag_vtable_thunks ? vtable_entry_type : ptr_type_node)
  
  
  /* For building calls to `delete'.  */
--- 3109,3115 ----
  
  /* Node for "pointer to (virtual) function".
     This may be distinct from ptr_type_node so gdb can distinguish them.  */
! #define vfunc_ptr_type_node  vtable_entry_type
  
  
  /* For building calls to `delete'.  */
*************** extern varray_type local_classes;
*** 3245,3251 ****
  #define AUTO_TEMP_NAME "_$tmp_"
  #define AUTO_TEMP_FORMAT "_$tmp_%d"
  #define VTABLE_BASE "$vb"
! #define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt$")
  #define VFIELD_BASE "$vf"
  #define VFIELD_NAME "_vptr$"
  #define VFIELD_NAME_FORMAT "_vptr$%s"
--- 3177,3183 ----
  #define AUTO_TEMP_NAME "_$tmp_"
  #define AUTO_TEMP_FORMAT "_$tmp_%d"
  #define VTABLE_BASE "$vb"
! #define VTABLE_NAME_PREFIX "__vt_"
  #define VFIELD_BASE "$vf"
  #define VFIELD_NAME "_vptr$"
  #define VFIELD_NAME_FORMAT "_vptr$%s"
*************** extern varray_type local_classes;
*** 3267,3273 ****
  #define AUTO_TEMP_NAME "_.tmp_"
  #define AUTO_TEMP_FORMAT "_.tmp_%d"
  #define VTABLE_BASE ".vb"
! #define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt.")
  #define VFIELD_BASE ".vf"
  #define VFIELD_NAME "_vptr."
  #define VFIELD_NAME_FORMAT "_vptr.%s"
--- 3199,3205 ----
  #define AUTO_TEMP_NAME "_.tmp_"
  #define AUTO_TEMP_FORMAT "_.tmp_%d"
  #define VTABLE_BASE ".vb"
! #define VTABLE_NAME_PREFIX "__vt_"
  #define VFIELD_BASE ".vf"
  #define VFIELD_NAME "_vptr."
  #define VFIELD_NAME_FORMAT "_vptr.%s"
*************** extern varray_type local_classes;
*** 3296,3302 ****
  #define AUTO_TEMP_FORMAT "__tmp_%d"
  #define VTABLE_BASE "__vtb"
  #define VTABLE_NAME "__vt_"
! #define VTABLE_NAME_PREFIX (flag_vtable_thunks ? "__vt_" : "_vt_")
  #define VTABLE_NAME_P(ID_NODE) \
    (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
  	     sizeof (VTABLE_NAME) - 1))
--- 3228,3234 ----
  #define AUTO_TEMP_FORMAT "__tmp_%d"
  #define VTABLE_BASE "__vtb"
  #define VTABLE_NAME "__vt_"
! #define VTABLE_NAME_PREFIX "__vt_"
  #define VTABLE_NAME_P(ID_NODE) \
    (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
  	     sizeof (VTABLE_NAME) - 1))
*************** extern varray_type local_classes;
*** 3336,3344 ****
  
  #define VTBL_PTR_TYPE		"__vtbl_ptr_type"
  #define VTABLE_DELTA_NAME	"__delta"
- #define VTABLE_INDEX_NAME	"__index"
  #define VTABLE_PFN_NAME		"__pfn"
- #define VTABLE_DELTA2_NAME	"__delta2"
  
  #define EXCEPTION_CLEANUP_NAME	"exception cleanup"
  
--- 3268,3274 ----
*************** extern tree perform_implicit_conversion 
*** 3690,3696 ****
  /* in class.c */
  extern tree build_vbase_path			PARAMS ((enum tree_code, tree, tree, tree, int));
  extern tree build_vtbl_ref			PARAMS ((tree, tree));
! extern tree build_vfn_ref			PARAMS ((tree *, tree, tree));
  extern tree get_vtable_decl                     PARAMS ((tree, int));
  extern void add_method				PARAMS ((tree, tree, int));
  extern int currently_open_class			PARAMS ((tree));
--- 3620,3626 ----
  /* in class.c */
  extern tree build_vbase_path			PARAMS ((enum tree_code, tree, tree, tree, int));
  extern tree build_vtbl_ref			PARAMS ((tree, tree));
! extern tree build_vfn_ref			PARAMS ((tree, tree));
  extern tree get_vtable_decl                     PARAMS ((tree, int));
  extern void add_method				PARAMS ((tree, tree, int));
  extern int currently_open_class			PARAMS ((tree));
*************** extern tree convert_pointer_to_vbase    
*** 4205,4211 ****
  extern tree find_vbase_instance                 PARAMS ((tree, tree));
  extern tree binfo_for_vbase                     PARAMS ((tree, tree));
  extern tree binfo_via_virtual                   PARAMS ((tree, tree));
- extern void fixup_all_virtual_upcast_offsets    PARAMS ((tree));
  
  /* in semantics.c */
  extern void init_cp_semantics                   PARAMS ((void));
--- 4135,4140 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.802
diff -c -3 -p -r1.802 decl.c
*** decl.c	2001/07/13 20:40:41	1.802
--- decl.c	2001/07/20 15:11:44
*************** tree error_mark_list;
*** 163,190 ****
  
  	tree vtable_entry_type;
  	tree delta_type_node;
- #if 0
-    Old rtti stuff.
- 	tree __baselist_desc_type_node;
- 	tree __i_desc_type_node, __m_desc_type_node;
- 	tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type;
- #endif
  	tree __t_desc_type_node;
- #if 0
- 	tree __tp_desc_type_node;
- #endif
          tree ti_desc_type_node;
  	tree bltn_desc_type_node, ptr_desc_type_node;
  	tree ary_desc_type_node, func_desc_type_node, enum_desc_type_node;
  	tree class_desc_type_node, si_class_desc_type_node, vmi_class_desc_type_node;
  	tree ptm_desc_type_node;
  	tree base_desc_type_node;
- #if 0
-    Not needed yet?  May be needed one day?
- 	tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type;
- 	tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type;
- 	tree __ptmf_desc_array_type, __ptmd_desc_array_type;
- #endif
  
  	tree class_type_node, record_type_node, union_type_node, enum_type_node;
  	tree unknown_type_node;
--- 163,175 ----
*************** initialize_predefined_identifiers ()
*** 6305,6318 ****
      { "__comp_dtor", &complete_dtor_identifier, 1 },
      { "__base_dtor", &base_dtor_identifier, 1 },
      { "__deleting_dtor", &deleting_dtor_identifier, 1 },
-     { VTABLE_DELTA2_NAME, &delta2_identifier, 0 },
-     { VTABLE_DELTA_NAME, &delta_identifier, 0 },
      { IN_CHARGE_NAME, &in_charge_identifier, 0 },
-     { VTABLE_INDEX_NAME, &index_identifier, 0 },
      { "nelts", &nelts_identifier, 0 },
      { THIS_NAME, &this_identifier, 0 },
      { VTABLE_PFN_NAME, &pfn_identifier, 0 },
-     { "__pfn_or_delta2", &pfn_or_delta2_identifier, 0 },
      { "_vptr", &vptr_identifier, 0 },
      { "__vtt_parm", &vtt_parm_identifier, 0 },
      { "std", &std_identifier, 0 },
--- 6290,6300 ----
      { "__comp_dtor", &complete_dtor_identifier, 1 },
      { "__base_dtor", &base_dtor_identifier, 1 },
      { "__deleting_dtor", &deleting_dtor_identifier, 1 },
      { IN_CHARGE_NAME, &in_charge_identifier, 0 },
      { "nelts", &nelts_identifier, 0 },
      { THIS_NAME, &this_identifier, 0 },
+     { VTABLE_DELTA_NAME, &delta_identifier, 0 },
      { VTABLE_PFN_NAME, &pfn_identifier, 0 },
      { "_vptr", &vptr_identifier, 0 },
      { "__vtt_parm", &vtt_parm_identifier, 0 },
      { "std", &std_identifier, 0 },
*************** initialize_predefined_identifiers ()
*** 6335,6349 ****
  void
  init_decl_processing ()
  {
-   tree fields[20];
    tree void_ftype;
    tree void_ftype_ptr;
  
-   /* Check to see that the user did not specify an invalid combination
-      of command-line options.  */
-   if (!flag_vtable_thunks)
-     error ("the ABI requires vtable thunks");
- 
    /* Create all the identifiers we need.  */
    initialize_predefined_identifiers ();
  
--- 6317,6325 ----
*************** init_decl_processing ()
*** 6488,6528 ****
    TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
    TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
  
!   if (flag_vtable_thunks)
!     {
!       /* Make sure we get a unique function type, so we can give
! 	 its pointer type a name.  (This wins for gdb.) */
!       tree vfunc_type = make_node (FUNCTION_TYPE);
!       TREE_TYPE (vfunc_type) = integer_type_node;
!       TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
!       layout_type (vfunc_type);
  
!       vtable_entry_type = build_pointer_type (vfunc_type);
!     }
!   else
!     {
!       vtable_entry_type = make_aggr_type (RECORD_TYPE);
!       fields[0] = build_decl (FIELD_DECL, delta_identifier,
! 			      delta_type_node);
!       fields[1] = build_decl (FIELD_DECL, index_identifier,
! 			      delta_type_node);
!       fields[2] = build_decl (FIELD_DECL, pfn_identifier,
! 			      ptr_type_node);
!       finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2,
! 			   double_type_node);
! 
!       /* Make this part of an invisible union.  */
!       fields[3] = copy_node (fields[2]);
!       TREE_TYPE (fields[3]) = delta_type_node;
!       DECL_NAME (fields[3]) = delta2_identifier;
!       DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node);
!       DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
!       DECL_SIZE_UNIT (fields[3]) = TYPE_SIZE_UNIT (delta_type_node);
!       TREE_UNSIGNED (fields[3]) = 0;
!       TREE_CHAIN (fields[2]) = fields[3];
!       vtable_entry_type = build_qualified_type (vtable_entry_type,
! 						TYPE_QUAL_CONST);
!     }
    record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
  
    vtbl_type_node
--- 6464,6479 ----
    TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
    TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
  
!   {
!     /* Make sure we get a unique function type, so we can give
!        its pointer type a name.  (This wins for gdb.) */
!     tree vfunc_type = make_node (FUNCTION_TYPE);
!     TREE_TYPE (vfunc_type) = integer_type_node;
!     TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
!     layout_type (vfunc_type);
  
!     vtable_entry_type = build_pointer_type (vfunc_type);
!   }
    record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
  
    vtbl_type_node
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.476
diff -c -3 -p -r1.476 decl2.c
*** decl2.c	2001/07/19 06:22:04	1.476
--- decl2.c	2001/07/20 15:11:49
*************** int warn_long_long = 1;
*** 189,199 ****
  
  int warn_ctor_dtor_privacy = 1;
  
- /* True if we want to implement vtables using "thunks".
-    The default is off.  */
- 
- int flag_vtable_thunks = 1;
- 
  /* Nonzero means generate separate instantiation control files and juggle
     them at link time.  */
  
--- 189,194 ----
*************** mark_vtable_entries (decl)
*** 2247,2258 ****
  
    for (; entries; entries = TREE_CHAIN (entries))
      {
!       tree fnaddr;
        tree fn;
! 
!       fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) 
! 		: FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries)));
! 
        if (TREE_CODE (fnaddr) != ADDR_EXPR)
  	/* This entry is an offset: a virtual base class offset, a
  	   virtual call offset, an RTTI offset, etc.  */
--- 2242,2250 ----
  
    for (; entries; entries = TREE_CHAIN (entries))
      {
!       tree fnaddr = TREE_VALUE (entries);
        tree fn;
!       
        if (TREE_CODE (fnaddr) != ADDR_EXPR)
  	/* This entry is an offset: a virtual base class offset, a
  	   virtual call offset, an RTTI offset, etc.  */
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/error.c,v
retrieving revision 1.157
diff -c -3 -p -r1.157 error.c
*** error.c	2001/06/28 12:26:36	1.157
--- error.c	2001/07/20 15:11:51
*************** dump_decl (t, flags)
*** 950,962 ****
        if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
  	{
  	  output_add_string (scratch_buffer, "vtable for ");
! 	  if (TYPE_P (DECL_CONTEXT (t)))
! 	    dump_type (DECL_CONTEXT (t), flags);
! 	  else
! 	    /* This case can arise with -fno-vtable-thunks.  See
! 	       expand_upcast_fixups.  It's not clear what to print
! 	       here.  */
! 	    print_identifier (scratch_buffer, "<unknown type>");
  	  break;
  	}
        /* else fall through */
--- 950,957 ----
        if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
  	{
  	  output_add_string (scratch_buffer, "vtable for ");
! 	  my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
! 	  dump_type (DECL_CONTEXT (t), flags);
  	  break;
  	}
        /* else fall through */
*************** dump_expr (t, flags)
*** 1918,1933 ****
      case CONSTRUCTOR:
        if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
  	{
! 	  tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
  
! 	  if (integer_all_onesp (idx))
! 	    {
! 	      tree pfn = PFN_FROM_PTRMEMFUNC (t);
! 	      dump_unary_op ("&", pfn, flags | TFF_EXPR_IN_PARENS);
! 	      break;
! 	    }
! 	  else if (TREE_CODE (idx) == INTEGER_CST
! 		   && tree_int_cst_equal (idx, integer_zero_node))
  	    {
  	      /* A NULL pointer-to-member constant.  */
  	      output_add_string (scratch_buffer, "((");
--- 1913,1921 ----
      case CONSTRUCTOR:
        if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
  	{
! 	  tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0);
  
! 	  if (integer_zerop (idx))
  	    {
  	      /* A NULL pointer-to-member constant.  */
  	      output_add_string (scratch_buffer, "((");
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.245
diff -c -3 -p -r1.245 init.c
*** init.c	2001/07/10 10:38:10	1.245
--- init.c	2001/07/20 15:11:53
*************** initialize_vtbl_ptrs (addr)
*** 182,195 ****
  		 NULL, dfs_unmarked_real_bases_queue_p, list);
    dfs_walk (TYPE_BINFO (type), dfs_unmark,
  	    dfs_marked_real_bases_queue_p, type);
- 
-   /* If we're not using thunks, we may need to adjust the deltas in
-      the vtable to handle virtual base classes correctly.  When we are
-      using thunks, we either use construction vtables (which are
-      preloaded with the right answers) or nothing (in which case
-      vitual function calls sometimes don't work right.)  */
-   if (TYPE_USES_VIRTUAL_BASECLASSES (type) && !flag_vtable_thunks)
-     fixup_all_virtual_upcast_offsets (addr);
  }
  
  /* [dcl.init]:
--- 182,187 ----
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.115
diff -c -3 -p -r1.115 rtti.c
*** rtti.c	2001/05/22 19:41:55	1.115
--- rtti.c	2001/07/20 15:11:55
*************** build_headof (exp)
*** 113,119 ****
       tree exp;
  {
    tree type = TREE_TYPE (exp);
-   tree aref;
    tree offset;
    tree index;
  
--- 113,118 ----
*************** build_headof (exp)
*** 134,146 ****
       the vptr.  */
    index = build_int_2 (-2, -1);
  
!   aref = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
  
-   if (flag_vtable_thunks)
-     offset = aref;
-   else
-     offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
- 
    type = build_qualified_type (ptr_type_node, 
  			       CP_TYPE_QUALS (TREE_TYPE (exp)));
    return build (PLUS_EXPR, type, exp,
--- 133,140 ----
       the vptr.  */
    index = build_int_2 (-2, -1);
  
!   offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
  
    type = build_qualified_type (ptr_type_node, 
  			       CP_TYPE_QUALS (TREE_TYPE (exp)));
    return build (PLUS_EXPR, type, exp,
*************** get_tinfo_decl_dynamic (exp)
*** 228,234 ****
  
        /* The RTTI information is at index -1.  */
        index = integer_minus_one_node;
!       t = build_vfn_ref ((tree *) 0, exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
      }
--- 222,228 ----
  
        /* The RTTI information is at index -1.  */
        index = integer_minus_one_node;
!       t = build_vfn_ref (exp, index);
        TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
        return t;
      }
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/search.c,v
retrieving revision 1.210
diff -c -3 -p -r1.210 search.c
*** search.c	2001/06/06 21:52:52	1.210
--- search.c	2001/07/20 15:11:56
*************** struct vbase_info 
*** 86,103 ****
  static tree get_vbase_1 PARAMS ((tree, tree, unsigned int *));
  static tree lookup_field_1 PARAMS ((tree, tree));
  static int is_subobject_of_p PARAMS ((tree, tree, tree));
- static tree virtual_context PARAMS ((tree, tree, tree));
  static tree dfs_check_overlap PARAMS ((tree, void *));
  static tree dfs_no_overlap_yet PARAMS ((tree, void *));
  static int get_base_distance_recursive
  	PARAMS ((tree, int, int, int, int *, tree *, tree,
  	       int, int *, int, int));
  static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
- static void expand_upcast_fixups 
- 	PARAMS ((tree, tree, tree, tree, tree, tree, tree *));
- static void fixup_virtual_upcast_offsets
- 	PARAMS ((tree, tree, int, int, tree, tree, tree, tree,
- 	       tree *));
  static tree marked_pushdecls_p PARAMS ((tree, void *));
  static tree unmarked_pushdecls_p PARAMS ((tree, void *));
  static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
--- 86,97 ----
*************** get_base_distance (parent, binfo, protec
*** 476,491 ****
    if (rval && protect && rval_private)
      return -3;
  
-   /* If they gave us the real vbase binfo, which isn't in the main binfo
-      tree, deal with it.  This happens when we are called from
-      expand_upcast_fixups.  */
-   if (rval == -1 && TREE_CODE (parent) == TREE_VEC
-       && parent == binfo_for_vbase (BINFO_TYPE (parent), type))
-     {
-       new_binfo = parent;
-       rval = 1;
-     }
- 
    if (path_ptr)
      *path_ptr = new_binfo;
    return rval;
--- 470,475 ----
*************** init_vbase_pointers (type, decl_ptr)
*** 2435,2723 ****
      }
  
    return 0;
- }
- 
- /* get the virtual context (the vbase that directly contains the
-    DECL_CONTEXT of the FNDECL) that the given FNDECL is declared in,
-    or NULL_TREE if there is none.
- 
-    FNDECL must come from a virtual table from a virtual base to ensure
-    that there is only one possible DECL_CONTEXT.
- 
-    We know that if there is more than one place (binfo) the fndecl that the
-    declared, they all refer to the same binfo.  See get_class_offset_1 for
-    the check that ensures this.  */
- 
- static tree
- virtual_context (fndecl, t, vbase)
-      tree fndecl, t, vbase;
- {
-   tree path;
-   if (get_base_distance (DECL_CONTEXT (fndecl), t, 0, &path) < 0)
-     {
-       /* DECL_CONTEXT can be ambiguous in t.  */
-       if (get_base_distance (DECL_CONTEXT (fndecl), vbase, 0, &path) >= 0)
- 	{
- 	  while (path)
- 	    {
- 	      /* Not sure if checking path == vbase is necessary here, but just in
- 		 case it is.  */
- 	      if (TREE_VIA_VIRTUAL (path) || path == vbase)
- 		return binfo_for_vbase (BINFO_TYPE (path), t);
- 	      path = BINFO_INHERITANCE_CHAIN (path);
- 	    }
- 	}
-       /* This shouldn't happen, I don't want errors! */
-       warning ("recoverable compiler error, fixups for virtual function");
-       return vbase;
-     }
-   while (path)
-     {
-       if (TREE_VIA_VIRTUAL (path))
- 	return binfo_for_vbase (BINFO_TYPE (path), t);
-       path = BINFO_INHERITANCE_CHAIN (path);
-     }
-   return 0;
- }
- 
- /* Fixups upcast offsets for one vtable.
-    Entries may stay within the VBASE given, or
-    they may upcast into a direct base, or
-    they may upcast into a different vbase.
- 
-    We only need to do fixups in case 2 and 3.  In case 2, we add in
-    the virtual base offset to effect an upcast, in case 3, we add in
-    the virtual base offset to effect an upcast, then subtract out the
-    offset for the other virtual base, to effect a downcast into it.
- 
-    This routine mirrors fixup_vtable_deltas in functionality, though
-    this one is runtime based, and the other is compile time based.
-    Conceivably that routine could be removed entirely, and all fixups
-    done at runtime.
- 
-    VBASE_OFFSETS is an association list of virtual bases that contains
-    offset information for the virtual bases, so the offsets are only
-    calculated once.  */
- 
- static void
- expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
- 		      vbase_offsets)
-      tree binfo, addr, orig_addr, vbase, vbase_addr, t, *vbase_offsets;
- {
-   tree virtuals;
-   tree vc;
-   tree delta;
-   HOST_WIDE_INT n;
- 
-   while (BINFO_PRIMARY_P (binfo))
-     {
-       binfo = BINFO_INHERITANCE_CHAIN (binfo);
-       if (TREE_VIA_VIRTUAL (binfo))
- 	return;
-     }
- 
-   delta = purpose_member (vbase, *vbase_offsets);
-   if (! delta)
-     {
-       delta = build (PLUS_EXPR,
- 		     build_pointer_type (BINFO_TYPE (vbase)),
- 		     orig_addr,
- 		     BINFO_OFFSET (vbase));
-       delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr);
-       delta = save_expr (delta);
-       delta = tree_cons (vbase, delta, *vbase_offsets);
-       *vbase_offsets = delta;
-     }
- 
-   for (virtuals = BINFO_VIRTUALS (binfo), n = 0;
-        virtuals;
-        virtuals = TREE_CHAIN (virtuals), ++n)
-     {
-       tree current_fndecl = TREE_VALUE (virtuals);
- 
-       if (current_fndecl
- 	  && current_fndecl != abort_fndecl
- 	  && (vc=virtual_context (current_fndecl, t, vbase)) != vbase)
- 	{
- 	  /* This may in fact need a runtime fixup.  */
- 	  tree idx = build_int_2 (n, 0);
- 	  tree vtbl = BINFO_VTABLE (binfo);
- 	  tree nvtbl = lookup_name (DECL_NAME (vtbl), 0);
- 	  tree aref, ref, naref;
- 	  tree old_delta, new_delta;
- 	  tree init;
- 
- 	  if (nvtbl == NULL_TREE
- 	      || nvtbl == IDENTIFIER_GLOBAL_VALUE (DECL_NAME (vtbl)))
- 	    {
- 	      /* Dup it if it isn't in local scope yet.  */
- 	      nvtbl = build_decl
- 		(VAR_DECL, DECL_NAME (vtbl),
- 		 TYPE_MAIN_VARIANT (TREE_TYPE (vtbl)));
- 	      DECL_ALIGN (nvtbl) = MAX (TYPE_ALIGN (double_type_node),
- 					DECL_ALIGN (nvtbl));
- 	      TREE_READONLY (nvtbl) = 0;
- 	      DECL_ARTIFICIAL (nvtbl) = 1;
- 	      nvtbl = pushdecl (nvtbl);
- 	      init = NULL_TREE;
- 	      cp_finish_decl (nvtbl, init, NULL_TREE,
- 			      LOOKUP_ONLYCONVERTING);
- 
- 	      /* We don't set DECL_VIRTUAL_P and DECL_CONTEXT on nvtbl
- 		 because they wouldn't be useful; everything that wants to
- 		 look at the vtable will look at the decl for the normal
- 		 vtable.  Setting DECL_CONTEXT also screws up
- 		 decl_function_context.  */
- 
- 	      init = build (MODIFY_EXPR, TREE_TYPE (nvtbl),
- 			    nvtbl, vtbl);
- 	      finish_expr_stmt (init);
- 	      /* Update the vtable pointers as necessary.  */
- 	      ref = build_vfield_ref
- 		(build_indirect_ref (addr, NULL),
- 		 DECL_CONTEXT (TYPE_VFIELD (BINFO_TYPE (binfo))));
- 	      finish_expr_stmt
- 		(build_modify_expr (ref, NOP_EXPR, nvtbl));
- 	    }
- 	  assemble_external (vtbl);
- 	  aref = build_array_ref (vtbl, idx);
- 	  naref = build_array_ref (nvtbl, idx);
- 	  old_delta = build_component_ref (aref, delta_identifier,
- 					   NULL_TREE, 0);
- 	  new_delta = build_component_ref (naref, delta_identifier,
- 					   NULL_TREE, 0);
- 
- 	  /* This is a upcast, so we have to add the offset for the
- 	     virtual base.  */
- 	  old_delta = cp_build_binary_op (PLUS_EXPR, old_delta,
- 					  TREE_VALUE (delta));
- 	  if (vc)
- 	    {
- 	      /* If this is set, we need to subtract out the delta
- 		 adjustments for the other virtual base that we
- 		 downcast into.  */
- 	      tree vc_delta = purpose_member (vc, *vbase_offsets);
- 	      if (! vc_delta)
- 		{
- 		  tree vc_addr = convert_pointer_to_real (vc, orig_addr);
- 		  vc_delta = build (PLUS_EXPR,
- 				    build_pointer_type (BINFO_TYPE (vc)),
- 				    orig_addr,
- 				    BINFO_OFFSET (vc));
- 		  vc_delta = build (MINUS_EXPR, ptrdiff_type_node,
- 				    vc_delta, vc_addr);
- 		  vc_delta = save_expr (vc_delta);
- 		  *vbase_offsets = tree_cons (vc, vc_delta, *vbase_offsets);
- 		}
- 	      else
- 		vc_delta = TREE_VALUE (vc_delta);
-    
- 	      /* This is a downcast, so we have to subtract the offset
- 		 for the virtual base.  */
- 	      old_delta = cp_build_binary_op (MINUS_EXPR, old_delta, vc_delta);
- 	    }
- 
- 	  TREE_READONLY (new_delta) = 0;
- 	  TREE_TYPE (new_delta) = 
- 	    cp_build_qualified_type (TREE_TYPE (new_delta),
- 				     CP_TYPE_QUALS (TREE_TYPE (new_delta))
- 				     & ~TYPE_QUAL_CONST);
- 	  finish_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
- 					       old_delta));
- 	}
-     }
- }
- 
- /* Fixup upcast offsets for all direct vtables.  Patterned after
-    expand_direct_vtbls_init.  */
- 
- static void
- fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, orig_addr, type, vbase, vbase_offsets)
-      tree real_binfo, binfo;
-      int init_self, can_elide;
-      tree addr, orig_addr, type, vbase, *vbase_offsets;
- {
-   tree real_binfos = BINFO_BASETYPES (real_binfo);
-   tree binfos = BINFO_BASETYPES (binfo);
-   int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
- 
-   for (i = 0; i < n_baselinks; i++)
-     {
-       tree real_base_binfo = TREE_VEC_ELT (real_binfos, i);
-       tree base_binfo = TREE_VEC_ELT (binfos, i);
-       int is_not_base_vtable
- 	= !BINFO_PRIMARY_P (real_base_binfo);
-       if (! TREE_VIA_VIRTUAL (real_base_binfo))
- 	fixup_virtual_upcast_offsets (real_base_binfo, base_binfo,
- 				      is_not_base_vtable, can_elide, addr,
- 				      orig_addr, type, vbase, vbase_offsets);
-     }
- #if 0
-   /* Before turning this on, make sure it is correct.  */
-   if (can_elide && ! BINFO_MODIFIED (binfo))
-     return;
- #endif
-   /* Should we use something besides CLASSTYPE_VFIELDS? */
-   if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
-     {
-       tree new_addr = convert_pointer_to_real (binfo, addr);
-       expand_upcast_fixups (real_binfo, new_addr, orig_addr, vbase, addr,
- 			    type, vbase_offsets);
-     }
- }
- 
- /* Fixup all the virtual upcast offsets for TYPE.  DECL_PTR is the
-    address of the sub-object being initialized.  */
- 
- void
- fixup_all_virtual_upcast_offsets (decl_ptr)
-      tree decl_ptr;
- {
-   tree if_stmt;
-   tree in_charge_node;
-   tree vbases;
-   tree type;
- 
-   /* Only tweak the vtables if we're in charge.  */
-   in_charge_node = current_in_charge_parm;
-   if (!in_charge_node)
-     /* There's no need for any fixups in this case.  */
-     return;
-   in_charge_node = cp_build_binary_op (EQ_EXPR, 
- 				       in_charge_node, integer_zero_node);
-   if_stmt = begin_if_stmt ();
-   finish_if_stmt_cond (in_charge_node, if_stmt);
-   
-   /* Iterate through the virtual bases, fixing up the upcast offset
-      for each one.  */
-   type = TREE_TYPE (TREE_TYPE (decl_ptr));
-   for (vbases = CLASSTYPE_VBASECLASSES (type);
-        vbases;
-        vbases = TREE_CHAIN (vbases))
-     {
-       if (flag_vtable_thunks)
- 	/* We don't have dynamic thunks yet!  So for now, just fail
- 	   silently.  */
- 	;
-       else
- 	{
- 	  tree vbase;
- 	  tree vbase_offsets;
- 	  tree addr;
- 
- 	  vbase = find_vbase_instance (TREE_PURPOSE (vbases), type);
- 	  vbase_offsets = NULL_TREE;
- 	  addr = convert_pointer_to_vbase (TREE_PURPOSE (vbases), decl_ptr);
- 	  fixup_virtual_upcast_offsets (vbase,
- 					TYPE_BINFO (TREE_PURPOSE (vbases)),
- 					1, 0, addr, decl_ptr,
- 					type, vbase, &vbase_offsets);
- 	}
-     }
- 
-   /* Close out the if-statement.  */
-   finish_then_clause (if_stmt);
-   finish_if_stmt ();
  }
  
  /* get virtual base class types.
--- 2419,2424 ----
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.357
diff -c -3 -p -r1.357 typeck.c
*** typeck.c	2001/07/09 23:46:06	1.357
--- typeck.c	2001/07/20 15:12:00
*************** get_member_function_from_ptrfunc (instan
*** 2858,2864 ****
  
    if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
      {
!       tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl;
        tree instance, basetype;
  
        tree instance_ptr = *instance_ptrptr;
--- 2858,2864 ----
  
    if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
      {
!       tree fntype, idx, e1, delta, delta2, e2, e3, vtbl;
        tree instance, basetype;
  
        tree instance_ptr = *instance_ptrptr;
*************** get_member_function_from_ptrfunc (instan
*** 2940,2965 ****
  	 build_pointer_type (build_pointer_type (vtable_entry_type)),
  	 vtbl, cp_convert (ptrdiff_type_node, delta2));
        vtbl = build_indirect_ref (vtbl, NULL);
!       aref = build_array_ref (vtbl, idx);
  
-       if (! flag_vtable_thunks)
- 	{
- 	  aref = save_expr (aref);
- 	  
- 	  delta = cp_build_binary_op
- 	    (PLUS_EXPR,
- 	     build_conditional_expr (e1,
- 				     build_component_ref (aref,
- 							  delta_identifier,
- 							  NULL_TREE, 0),
- 				     integer_zero_node),
- 	     delta);
- 	}
- 
-       if (flag_vtable_thunks)
- 	e2 = aref;
-       else
- 	e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0);
        TREE_TYPE (e2) = TREE_TYPE (e3);
        e1 = build_conditional_expr (e1, e2, e3);
        
--- 2940,2947 ----
  	 build_pointer_type (build_pointer_type (vtable_entry_type)),
  	 vtbl, cp_convert (ptrdiff_type_node, delta2));
        vtbl = build_indirect_ref (vtbl, NULL);
!       e2 = build_array_ref (vtbl, idx);
  
        TREE_TYPE (e2) = TREE_TYPE (e3);
        e1 = build_conditional_expr (e1, e2, e3);
        
Index: config/freebsd.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/freebsd.h,v
retrieving revision 1.8
diff -c -3 -p -r1.8 freebsd.h
*** freebsd.h	2001/05/22 21:33:36	1.8
--- freebsd.h	2001/07/20 15:12:00
*************** is built with the --enable-threads confi
*** 150,159 ****
     libraries compiled with the native cc.  */
  #undef NO_DOLLAR_IN_LABEL
  
- /* Use more efficient ``thunks'' to implement C++ vtables.  */
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- 
  /* The GNU tools operate better with dwarf2 than stabs.  Since we
     don't have any native tools to be compatible with, default to
     dwarf2.  */
--- 150,155 ----
Index: config/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/linux.h,v
retrieving revision 1.14
diff -c -3 -p -r1.14 linux.h
*** linux.h	2001/06/11 19:51:01	1.14
--- linux.h	2001/07/20 15:12:00
*************** Boston, MA 02111-1307, USA.  */
*** 79,89 ****
  #undef CPLUSPLUS_CPP_SPEC
  #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
  
- #ifndef USE_GNULIBC_1
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- #endif
- 
  #undef	LIB_SPEC
  /* We no longer link with libc_p.a or libg.a by default. If you
     want to profile or debug the GNU/Linux C library, please add
--- 79,84 ----
Index: config/openbsd.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/openbsd.h,v
retrieving revision 1.9
diff -c -3 -p -r1.9 openbsd.h
*** openbsd.h	2001/07/13 18:12:21	1.9
--- openbsd.h	2001/07/20 15:12:00
*************** do {									 \
*** 295,305 ****
  
  /* Storage layout.  */
  
- /* We don't have to worry about binary compatibility with older C++ code,
-    but there is a big known bug with vtable thunks which has not been
-    fixed yet, so DON'T activate it by default.  */
- /* #define DEFAULT_VTABLE_THUNKS 1 */
- 
  
  /* Otherwise, since we support weak, gthr.h erroneously tries to use
     #pragma weak.  */
--- 295,300 ----
Index: config/alpha/linux-elf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/linux-elf.h,v
retrieving revision 1.5
diff -c -3 -p -r1.5 linux-elf.h
*** linux-elf.h	1999/01/11 13:33:53	1.5
--- linux-elf.h	2001/07/20 15:12:00
*************** Boston, MA 02111-1307, USA.  */
*** 37,47 ****
  #endif
  
  #ifndef USE_GNULIBC_1
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- #endif
- 
- #ifndef USE_GNULIBC_1
  #undef LIB_SPEC
  #define LIB_SPEC \
  "%{shared:-lc}%{!shared:%{pthread:-lpthread }%{profile:-lc_p}%{!profile:-lc}} "
--- 37,42 ----
Index: config/arm/linux-elf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/linux-elf.h,v
retrieving revision 1.25
diff -c -3 -p -r1.25 linux-elf.h
*** linux-elf.h	2001/04/16 18:30:36	1.25
--- linux-elf.h	2001/07/20 15:12:00
*************** Boston, MA 02111-1307, USA.  */
*** 33,42 ****
  	{ "marm", "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
  #define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
  
- /* This was defined in linux.h.  Define it here also. */
- #undef  DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS   1
- 
  /* Handle #pragma weak and #pragma pack.  */
  #define HANDLE_SYSV_PRAGMA
  
--- 33,38 ----
Index: config/d30v/d30v.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/d30v/d30v.h,v
retrieving revision 1.25
diff -c -3 -p -r1.25 d30v.h
*** d30v.h	2001/07/09 06:10:00	1.25
--- d30v.h	2001/07/20 15:12:03
*************** do {									\
*** 884,902 ****
     `HOST_FLOAT_WORDS_BIG_ENDIAN' for the host.  */
  #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
  
- /* GNU CC supports two ways of implementing C++ vtables: traditional or with
-    so-called "thunks".  The flag `-fvtable-thunk' chooses between them.  Define
-    this macro to be a C expression for the default value of that flag.  If
-    `DEFAULT_VTABLE_THUNKS' is 0, GNU CC uses the traditional implementation by
-    default.  The "thunk" implementation is more efficient (especially if you
-    have provided an implementation of `ASM_OUTPUT_MI_THUNK', see *Note Function
-    Entry::), but is not binary compatible with code compiled using the
-    traditional implementation.  If you are writing a new ports, define
-    `DEFAULT_VTABLE_THUNKS' to 1.
- 
-    If you do not define this macro, the default for `-fvtable-thunk' is 0.  */
- #define DEFAULT_VTABLE_THUNKS 0
- 
  
  /* Layout of Source Language Data Types */
  
--- 884,889 ----
Index: config/fr30/fr30.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/fr30/fr30.h,v
retrieving revision 1.16
diff -c -3 -p -r1.16 fr30.h
*** fr30.h	2001/07/09 06:10:01	1.16
--- fr30.h	2001/07/20 15:12:04
*************** extern int target_flags;
*** 312,329 ****
     `HOST_FLOAT_WORDS_BIG_ENDIAN' for the host.  */
  #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
  
- /* GNU CC supports two ways of implementing C++ vtables: traditional or with
-    so-called "thunks".  The flag `-fvtable-thunk' chooses between them.  Define
-    this macro to be a C expression for the default value of that flag.  If
-    `DEFAULT_VTABLE_THUNKS' is 0, GNU CC uses the traditional implementation by
-    default.  The "thunk" implementation is more efficient (especially if you
-    have provided an implementation of `ASM_OUTPUT_MI_THUNK', but is not binary
-    compatible with code compiled using the traditional implementation.  If you
-    are writing a new ports, define `DEFAULT_VTABLE_THUNKS' to 1.
- 
-    If you do not define this macro, the default for `-fvtable-thunk' is 0.  */
- #define DEFAULT_VTABLE_THUNKS 1
- 
  /*}}}*/ 
  /*{{{  Layout of Source Language Data Types.  */ 
  
--- 312,317 ----
Index: config/ia64/aix.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/aix.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 aix.h
*** aix.h	2001/07/12 02:55:24	1.1
--- aix.h	2001/07/20 15:12:04
*************** Boston, MA 02111-1307, USA.  */
*** 66,74 ****
  #undef  ENDFILE_SPEC
  #define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
  
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- 
  /* Define this so we can compile MS code for use with WINE.  */
  #define HANDLE_PRAGMA_PACK_PUSH_POP
  
--- 66,71 ----
Index: config/ia64/ia64.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/ia64/ia64.h,v
retrieving revision 1.76
diff -c -3 -p -r1.76 ia64.h
*** ia64.h	2001/07/19 23:26:51	1.76
--- ia64.h	2001/07/20 15:12:05
*************** while (0)
*** 416,433 ****
  /* A code distinguishing the floating point format of the target machine.  */
  #define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
  
- /* GNU CC supports two ways of implementing C++ vtables: traditional or with
-    so-called "thunks".  The flag `-fvtable-thunk' chooses between them.  Define
-    this macro to be a C expression for the default value of that flag.  If
-    `DEFAULT_VTABLE_THUNKS' is 0, GNU CC uses the traditional implementation by
-    default.  The "thunk" implementation is more efficient (especially if you
-    have provided an implementation of `ASM_OUTPUT_MI_THUNK', but is not binary
-    compatible with code compiled using the traditional implementation.  If you
-    are writing a new ports, define `DEFAULT_VTABLE_THUNKS' to 1.
- 
-    If you do not define this macro, the default for `-fvtable-thunk' is 0.  */
- #define DEFAULT_VTABLE_THUNKS 1
- 
  
  /* Layout of Source Language Data Types */
  
--- 416,421 ----
Index: config/mips/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/linux.h,v
retrieving revision 1.21
diff -c -3 -p -r1.21 linux.h
*** linux.h	2001/04/26 16:02:05	1.21
--- linux.h	2001/07/20 15:12:06
*************** Boston, MA 02111-1307, USA.  */
*** 40,49 ****
  #undef HANDLE_SYSV_PRAGMA
  #define HANDLE_SYSV_PRAGMA 1
  
- /* Use more efficient ``thunks'' to implement C++ vtables. */
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- 
  /* Don't assume anything about the header files.  */
  #define NO_IMPLICIT_EXTERN_C
  
--- 40,45 ----
Index: config/pj/pj.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/pj/pj.h,v
retrieving revision 1.11
diff -c -3 -p -r1.11 pj.h
*** pj.h	2001/07/09 06:10:05	1.11
--- pj.h	2001/07/20 15:12:06
*************** do {                                    
*** 1321,1329 ****
  #define INCOMING_RETURN_ADDR_RTX  \
    plus_constant (gen_rtx_REG (Pmode, OPTOP_REG), 4)
  
- /* Use thunks for vtables.  */
- #define DEFAULT_VTABLE_THUNKS 1
- 
  /* Rewrite the rtl to use take advantage of the opstack.  */
  #define MACHINE_DEPENDENT_REORG(INSNS) pj_machine_dependent_reorg(INSNS)
  
--- 1321,1326 ----
Index: config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/linux.h,v
retrieving revision 1.26
diff -c -3 -p -r1.26 linux.h
*** linux.h	2001/06/11 19:39:05	1.26
--- linux.h	2001/07/20 15:12:07
*************** Boston, MA 02111-1307, USA.  */
*** 69,79 ****
  #undef ASM_APP_OFF
  #define ASM_APP_OFF "#NO_APP\n"
  
- #undef DEFAULT_VTABLE_THUNKS
- #ifndef USE_GNULIBC_1
- #define DEFAULT_VTABLE_THUNKS 1
- #endif
- 
  /* Do code reading to identify a signal frame, and set the frame
     state data appropriately.  See unwind-dw2.c for the structs.  */
  
--- 69,74 ----
Index: config/sparc/linux.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sparc/linux.h,v
retrieving revision 1.20
diff -c -3 -p -r1.20 linux.h
*** linux.h	2001/04/16 18:30:47	1.20
--- linux.h	2001/07/20 15:12:07
*************** Boston, MA 02111-1307, USA.  */
*** 32,42 ****
  #define MULTIBYTE_CHARS 1
  #endif
  
- #ifndef USE_GNULIBC_1
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- #endif
- 
  /* Use stabs instead of DWARF debug format.  */
  #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
  
--- 32,37 ----
Index: config/sparc/linux64.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sparc/linux64.h,v
retrieving revision 1.32
diff -c -3 -p -r1.32 linux64.h
*** linux64.h	2001/04/16 18:30:47	1.32
--- linux64.h	2001/07/20 15:12:07
*************** Boston, MA 02111-1307, USA.  */
*** 26,34 ****
  /* Don't assume anything about the header files. */
  #define NO_IMPLICIT_EXTERN_C
  
- #undef DEFAULT_VTABLE_THUNKS
- #define DEFAULT_VTABLE_THUNKS 1
- 
  #include <sparc/sysv4.h>
  
  #undef MD_EXEC_PREFIX
--- 26,31 ----
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/tm.texi,v
retrieving revision 1.36
diff -c -3 -p -r1.36 tm.texi
*** tm.texi	2001/07/19 23:26:51	1.36
--- tm.texi	2001/07/20 15:12:11
*************** The ordering of the component words of f
*** 1320,1338 ****
  memory is controlled by @code{FLOAT_WORDS_BIG_ENDIAN} for the target
  machine and @code{HOST_FLOAT_WORDS_BIG_ENDIAN} for the host.
  
- @findex DEFAULT_VTABLE_THUNKS
- @item DEFAULT_VTABLE_THUNKS
- GCC supports two ways of implementing C++ vtables:  traditional or with
- so-called ``thunks''.  The flag @option{-fvtable-thunk} chooses between them.
- Define this macro to be a C expression for the default value of that flag.
- If @code{DEFAULT_VTABLE_THUNKS} is 0, GCC uses the traditional
- implementation by default.  The ``thunk'' implementation is more efficient
- (especially if you have provided an implementation of
- @code{ASM_OUTPUT_MI_THUNK}, see @ref{Function Entry}), but is not binary
- compatible with code compiled using the traditional implementation.
- If you are writing a new port, define @code{DEFAULT_VTABLE_THUNKS} to 1.
- 
- If you do not define this macro, the default for @option{-fvtable-thunk} is 0.
  @end table
  
  @node Type Layout
--- 1320,1325 ----


More information about the Gcc-patches mailing list