[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