tm.texi: Remove DEFAULT_VTABLE_THUNKS.

gcc:
	* 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.
cp:
	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.

From-SVN: r44227
This commit is contained in:
Nathan Sidwell 2001-07-21 09:42:21 +00:00 committed by Nathan Sidwell
parent f4653d9278
commit c4372ef4c6
27 changed files with 115 additions and 633 deletions

View File

@ -1,3 +1,21 @@
2001-07-21 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.
2001-07-20 Bruce Korb <bkorb@gnu.org>
* fixinc/fixincl.c(test_for_changes): force unsigned char comparisons

View File

@ -36,11 +36,6 @@ Boston, MA 02111-1307, USA. */
#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2"
#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 \

View File

@ -33,10 +33,6 @@ Boston, MA 02111-1307, USA. */
{ "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

View File

@ -884,19 +884,6 @@ do { \
`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 */

View File

@ -312,18 +312,6 @@ extern int target_flags;
`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. */

View File

@ -150,10 +150,6 @@ is built with the --enable-threads configure-time option.} \
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. */

View File

@ -66,9 +66,6 @@ Boston, MA 02111-1307, USA. */
#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

View File

@ -416,18 +416,6 @@ while (0)
/* 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 */

View File

@ -79,11 +79,6 @@ Boston, MA 02111-1307, USA. */
#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

View File

@ -40,10 +40,6 @@ Boston, MA 02111-1307, USA. */
#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

View File

@ -295,11 +295,6 @@ do { \
/* 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. */

View File

@ -1321,9 +1321,6 @@ do { \
#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)

View File

@ -69,11 +69,6 @@ Boston, MA 02111-1307, USA. */
#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. */

View File

@ -32,11 +32,6 @@ Boston, MA 02111-1307, USA. */
#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

View File

@ -26,9 +26,6 @@ Boston, MA 02111-1307, USA. */
/* 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

View File

@ -1,3 +1,44 @@
2001-07-21 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>
Remove old-abi remnants. Remove comments about old abi

View File

@ -4307,7 +4307,7 @@ build_over_call (cand, args, flags)
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));
fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn));
TREE_TYPE (fn) = t;
}
else if (DECL_INLINE (fn))

View File

@ -543,37 +543,16 @@ build_vtbl_ref (instance, idx)
}
/* 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. */
virtual function corresponding to IDX. */
tree
build_vfn_ref (ptr_to_instptr, instance, idx)
tree *ptr_to_instptr, instance;
build_vfn_ref (instance, idx)
tree 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 aref;
}
/* Return the name of the virtual function table (as an IDENTIFIER_NODE)
@ -8019,16 +7998,12 @@ build_rtti_vtbl_entries (binfo, vid)
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);
}
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
@ -8045,54 +8020,18 @@ build_vtable_entry (delta, vcall_index, entry)
tree vcall_index;
tree entry;
{
if (flag_vtable_thunks)
tree fn = TREE_OPERAND (entry, 0);
if ((!integer_zerop (delta) || vcall_index != NULL_TREE)
&& fn != abort_fndecl)
{
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;
entry = make_thunk (entry, delta, vcall_index);
entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
TREE_READONLY (entry) = 1;
#ifdef GATHER_STATISTICS
n_vtable_entries += 1;
#endif
return entry;
TREE_CONSTANT (entry) = 1;
}
#ifdef GATHER_STATISTICS
n_vtable_entries += 1;
#endif
return entry;
}

View File

@ -552,15 +552,12 @@ enum cp_tree_index
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,
@ -594,8 +591,7 @@ extern tree cp_global_trees[CPTI_MAX];
#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. */
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]
@ -671,20 +667,14 @@ extern tree cp_global_trees[CPTI_MAX];
/* 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]
@ -1031,11 +1021,6 @@ extern int warn_reorder;
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
@ -1180,11 +1165,9 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* 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)))
(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))))
@ -2555,9 +2538,11 @@ extern int flag_new_for_scope;
ptrdiff_t __delta;
};
(As the vtable is always the first thing in the object, we don't
need an offset to it.) If the function is virtual, then PFN is one
plus twice the index into the vtable; otherwise, it is just a
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
@ -3087,8 +3072,7 @@ extern tree error_mark_list;
/* 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)
#define vfunc_ptr_type_node vtable_entry_type
/* For building calls to `delete'. */
@ -3156,7 +3140,7 @@ extern varray_type local_classes;
#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 VTABLE_NAME_PREFIX "__vt_"
#define VFIELD_BASE "$vf"
#define VFIELD_NAME "_vptr$"
#define VFIELD_NAME_FORMAT "_vptr$%s"
@ -3178,7 +3162,7 @@ extern varray_type local_classes;
#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 VTABLE_NAME_PREFIX "__vt_"
#define VFIELD_BASE ".vf"
#define VFIELD_NAME "_vptr."
#define VFIELD_NAME_FORMAT "_vptr.%s"
@ -3207,7 +3191,7 @@ extern varray_type local_classes;
#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_PREFIX "__vt_"
#define VTABLE_NAME_P(ID_NODE) \
(!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \
sizeof (VTABLE_NAME) - 1))
@ -3247,9 +3231,7 @@ extern varray_type local_classes;
#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"
@ -3592,7 +3574,7 @@ extern tree perform_implicit_conversion PARAMS ((tree, tree));
/* 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 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));
@ -4106,7 +4088,6 @@ extern tree convert_pointer_to_vbase PARAMS ((tree, tree));
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));

View File

@ -162,28 +162,13 @@ tree error_mark_list;
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;
@ -6304,14 +6289,11 @@ initialize_predefined_identifiers ()
{ "__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_DELTA_NAME, &delta_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 },
@ -6334,15 +6316,9 @@ initialize_predefined_identifiers ()
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 ();
@ -6487,41 +6463,16 @@ init_decl_processing ()
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);
{
/* 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);
}
vtable_entry_type = build_pointer_type (vfunc_type);
}
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
vtbl_type_node

View File

@ -189,11 +189,6 @@ int warn_long_long = 1;
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. */
@ -2247,12 +2242,9 @@ mark_vtable_entries (decl)
for (; entries; entries = TREE_CHAIN (entries))
{
tree fnaddr;
tree fnaddr = TREE_VALUE (entries);
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. */

View File

@ -950,13 +950,8 @@ dump_decl (t, flags)
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>");
my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
dump_type (DECL_CONTEXT (t), flags);
break;
}
/* else fall through */
@ -1918,16 +1913,9 @@ dump_expr (t, flags)
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
tree idx = build_component_ref (t, pfn_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))
if (integer_zerop (idx))
{
/* A NULL pointer-to-member constant. */
output_add_string (scratch_buffer, "((");

View File

@ -182,14 +182,6 @@ initialize_vtbl_ptrs (addr)
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]:

View File

@ -113,7 +113,6 @@ build_headof (exp)
tree exp;
{
tree type = TREE_TYPE (exp);
tree aref;
tree offset;
tree index;
@ -133,12 +132,7 @@ build_headof (exp)
/* The offset-to-top field is at index -2 from 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);
offset = build_vtbl_ref (build_indirect_ref (exp, NULL), index);
type = build_qualified_type (ptr_type_node,
CP_TYPE_QUALS (TREE_TYPE (exp)));
@ -227,7 +221,7 @@ get_tinfo_decl_dynamic (exp)
/* The RTTI information is at index -1. */
index = integer_minus_one_node;
t = build_vfn_ref ((tree *) 0, exp, index);
t = build_vfn_ref (exp, index);
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
return t;
}

View File

@ -86,18 +86,12 @@ struct vbase_info
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 *));
@ -474,16 +468,6 @@ get_base_distance (parent, binfo, protect, path_ptr)
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;
@ -2332,290 +2316,6 @@ dfs_unmark (binfo, data)
return NULL_TREE;
}
/* 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.
This adds type to the vbase_types list in reverse dfs order.
Ordering is very important, so don't change it. */

View File

@ -2858,7 +2858,7 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function)))
{
tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl;
tree fntype, idx, e1, delta, delta2, e2, e3, vtbl;
tree instance, basetype;
tree instance_ptr = *instance_ptrptr;
@ -2940,26 +2940,8 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
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);
e2 = 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);

View File

@ -1320,19 +1320,6 @@ The ordering of the component words of floating point values stored in
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