From dc9b5a48fa168fd24b4c593a4399b5993cb542b9 Mon Sep 17 00:00:00 2001 From: nathan Date: Sat, 21 Jul 2001 09:42:21 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44227 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 18 +++ gcc/config/alpha/linux-elf.h | 5 - gcc/config/arm/linux-elf.h | 4 - gcc/config/d30v/d30v.h | 13 -- gcc/config/fr30/fr30.h | 12 -- gcc/config/freebsd.h | 4 - gcc/config/ia64/aix.h | 3 - gcc/config/ia64/ia64.h | 12 -- gcc/config/linux.h | 5 - gcc/config/mips/linux.h | 4 - gcc/config/openbsd.h | 5 - gcc/config/pj/pj.h | 3 - gcc/config/rs6000/linux.h | 5 - gcc/config/sparc/linux.h | 5 - gcc/config/sparc/linux64.h | 3 - gcc/cp/ChangeLog | 41 ++++++ gcc/cp/call.c | 2 +- gcc/cp/class.c | 101 +++------------ gcc/cp/cp-tree.h | 47 ++----- gcc/cp/decl.c | 71 ++-------- gcc/cp/decl2.c | 12 +- gcc/cp/error.c | 20 +-- gcc/cp/init.c | 8 -- gcc/cp/rtti.c | 10 +- gcc/cp/search.c | 300 ------------------------------------------- gcc/cp/typeck.c | 22 +--- gcc/doc/tm.texi | 13 -- 27 files changed, 115 insertions(+), 633 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1c3ef5..5421fd0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2001-07-21 Nathan Sidwell + + * 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 * fixinc/fixincl.c(test_for_changes): force unsigned char comparisons diff --git a/gcc/config/alpha/linux-elf.h b/gcc/config/alpha/linux-elf.h index fc07127..6430059 100644 --- a/gcc/config/alpha/linux-elf.h +++ b/gcc/config/alpha/linux-elf.h @@ -37,11 +37,6 @@ Boston, MA 02111-1307, USA. */ #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}} " diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h index acaa71d..4940ae9 100644 --- a/gcc/config/arm/linux-elf.h +++ b/gcc/config/arm/linux-elf.h @@ -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 diff --git a/gcc/config/d30v/d30v.h b/gcc/config/d30v/d30v.h index 6126fea..ba874d8 100644 --- a/gcc/config/d30v/d30v.h +++ b/gcc/config/d30v/d30v.h @@ -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 */ diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h index 833a2cf..9f41a55 100644 --- a/gcc/config/fr30/fr30.h +++ b/gcc/config/fr30/fr30.h @@ -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. */ diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h index 88e0226..56d16c3 100644 --- a/gcc/config/freebsd.h +++ b/gcc/config/freebsd.h @@ -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. */ diff --git a/gcc/config/ia64/aix.h b/gcc/config/ia64/aix.h index 36baf10..cf1f4b0 100644 --- a/gcc/config/ia64/aix.h +++ b/gcc/config/ia64/aix.h @@ -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 diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 7da33a4..5087223 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -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 */ diff --git a/gcc/config/linux.h b/gcc/config/linux.h index dc1a4c7..b6ade99 100644 --- a/gcc/config/linux.h +++ b/gcc/config/linux.h @@ -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 diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h index fc4c237..f89325e 100644 --- a/gcc/config/mips/linux.h +++ b/gcc/config/mips/linux.h @@ -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 diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h index ff1c1ad..147eec6 100644 --- a/gcc/config/openbsd.h +++ b/gcc/config/openbsd.h @@ -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. */ diff --git a/gcc/config/pj/pj.h b/gcc/config/pj/pj.h index 83c9b3e..320d57a 100644 --- a/gcc/config/pj/pj.h +++ b/gcc/config/pj/pj.h @@ -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) diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h index 6e06ecb..5100bb5 100644 --- a/gcc/config/rs6000/linux.h +++ b/gcc/config/rs6000/linux.h @@ -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. */ diff --git a/gcc/config/sparc/linux.h b/gcc/config/sparc/linux.h index 236d0e9..f85409b 100644 --- a/gcc/config/sparc/linux.h +++ b/gcc/config/sparc/linux.h @@ -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 diff --git a/gcc/config/sparc/linux64.h b/gcc/config/sparc/linux64.h index 94b59ee..3481c4b 100644 --- a/gcc/config/sparc/linux64.h +++ b/gcc/config/sparc/linux64.h @@ -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 #undef MD_EXEC_PREFIX diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 10da3ae..ed073c1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,44 @@ +2001-07-21 Nathan Sidwell + + 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 Remove old-abi remnants. Remove comments about old abi diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 7cfbd96..c8c5246 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 99c8638..1667758 100644 --- a/gcc/cp/class.c +++ b/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; - - 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 fn = TREE_OPERAND (entry, 0); + + if ((!integer_zerop (delta) || vcall_index != NULL_TREE) + && fn != abort_fndecl) { - 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; - + TREE_CONSTANT (entry) = 1; + } #ifdef GATHER_STATISTICS - n_vtable_entries += 1; + n_vtable_entries += 1; #endif - - return entry; - } + return entry; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 465ba51..e7005c7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2abddd2..c140af4 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); - - 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); - } + { + /* 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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d2d8ec5..d0f8c43 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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. */ diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 3bb043d..05352c2 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -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, ""); + 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, "(("); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 0cf2847..6dbef0b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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]: diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 6e32ed3..5638eb6 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -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; } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 87157ba..4fac30f 100644 --- a/gcc/cp/search.c +++ b/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. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9db741c..3580373 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 162dc9e..b5d8ba9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -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 -- 2.7.4