mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-12 17:37:08 +08:00
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:
parent
f4653d9278
commit
c4372ef4c6
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
103
gcc/cp/class.c
103
gcc/cp/class.c
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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, "((");
|
||||
|
@ -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]:
|
||||
|
@ -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;
|
||||
}
|
||||
|
300
gcc/cp/search.c
300
gcc/cp/search.c
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user