This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-hpux-branch]: Virtual destructor position
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 30 Nov 2003 15:52:05 +0000
- Subject: [csl-hpux-branch]: Virtual destructor position
- Organization: Codesourcery LLC
Hi,
I've installed this hpux patch on the csl-hpux-branch. On hpux
virtual destructors behave as if they are declared last in the class.
built & tested on with cross-compiler targeting ia64-hp-hpux11.23,
approved by Mark, with helpful comments from Zack
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
The voices in my head said this was stupid too
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2003-11-30 Nathan Sidwell <nathan@codesourcery.com>
* target.h (gcc_target): Add abi structure.
* target-def.h (TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION): New.
(TARGET_ABI): New.
(TARGET_INITIALIZER): Add TARGET_ABI.
* config/ia64/ia64.c (TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION): Override
on HPUX
* doc/tm.texi (TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION): Document.
* cp/class.c (check_methods): Move virtual destructor to end of
method list, if abi_cxx_vdp_declared_last.
(create_vtable_ptr): Move virtual destructors to end of vtable if
abi_cxx_vdp_last_in_vtable.
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.70
diff -c -3 -p -r1.70 target.h
*** target.h 16 Nov 2003 19:10:05 -0000 1.70
--- target.h 30 Nov 2003 15:45:38 -0000
*************** struct gcc_target
*** 439,444 ****
--- 439,454 ----
STRICT_ARGUMENT_NAMING. */
bool (*pretend_outgoing_varargs_named) (CUMULATIVE_ARGS *ca);
} calls;
+
+ /* Hooks relating to ABI. */
+ struct abi {
+ /* Placement of the virtual dtors. */
+ enum abi_cxx_virtual_dtors_position {
+ abi_cxx_vdp_default,
+ abi_cxx_vdp_last_in_vtable, /* Placed last in vtable. */
+ abi_cxx_vdp_declared_last /* As if they are declared last. */
+ } cxx_virtual_dtors_position;
+ } abi;
};
extern struct gcc_target targetm;
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.62
diff -c -3 -p -r1.62 target-def.h
*** target-def.h 16 Nov 2003 19:10:05 -0000 1.62
--- target-def.h 30 Nov 2003 15:45:39 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 349,354 ****
--- 349,360 ----
TARGET_PRETEND_OUTGOING_VARARGS_NAMED, \
}
+ #define TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION abi_cxx_vdp_default
+
+ #define TARGET_ABI { \
+ TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION, \
+ }
+
/* The whole shebang. */
#define TARGET_INITIALIZER \
{ \
*************** Foundation, 59 Temple Place - Suite 330,
*** 395,400 ****
--- 401,407 ----
TARGET_ASM_FILE_START_APP_OFF, \
TARGET_ASM_FILE_START_FILE_DIRECTIVE, \
TARGET_CALLS, \
+ TARGET_ABI, \
}
#include "hooks.h"
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.266
diff -c -3 -p -r1.266 tm.texi
*** doc/tm.texi 16 Nov 2003 19:10:06 -0000 1.266
--- doc/tm.texi 30 Nov 2003 15:46:07 -0000
*************** defined, then define this hook to return
*** 4502,4507 ****
--- 4502,4523 ----
Otherwise, you should not define this hook.
@end deftypefn
+ @findex abi_cxx_vdp_default
+ @findex abi_cxx_vdp_last_in_vtable
+ @findex abi_cxx_vdp_declared_last
+ @deftypevr {Target Hook} {enum cxx_virtual_dtors_position} TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION
+ Set this hook if the default placement of virtual destructors in the
+ vtable is not correct for the platform C++ ABI. The default is
+ @code{abi_cxx_vdp_default}, which means they are placed in declaration
+ order, just like other virtual functions. If instead they should be
+ treated for all purposes as if they had been declared last in the class,
+ set the hook to @code{abi_cxx_vdp_declared_last}. If they should appear
+ last in the vtable, but not otherwise be treated as having been declared
+ last in the class, use @code{abi_cxx_vdp_last_in_vtable}. (At present,
+ the difference is that @code{abi_cxx_vdp_declared_last} affects the
+ choice of key function, but @code{abi_cxx_vdp_last_in_vtable} does not.)
+ @end deftypevr
+
@node Trampolines
@section Trampolines for Nested Functions
@cindex trampolines for nested functions
Index: config/ia64/ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.c,v
retrieving revision 1.259
diff -c -3 -p -r1.259 ia64.c
*** config/ia64/ia64.c 29 Oct 2003 14:23:45 -0000 1.259
--- config/ia64/ia64.c 30 Nov 2003 15:46:25 -0000
*************** static const struct attribute_spec ia64_
*** 371,376 ****
--- 371,382 ----
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
+ #if TARGET_HPUX
+ /* On HPUX, virtual destructors behave as if they are declared last. */
+ #undef TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION
+ #define TARGET_ABI_CXX_VIRTUAL_DTORS_POSITION abi_cxx_vdp_declared_last
+ #endif
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.582.2.1
diff -c -3 -p -r1.582.2.1 class.c
*** cp/class.c 24 Nov 2003 16:41:26 -0000 1.582.2.1
--- cp/class.c 30 Nov 2003 15:46:42 -0000
*************** static void
*** 3761,3766 ****
--- 3761,3768 ----
check_methods (tree t)
{
tree x;
+ tree dtor = NULL_TREE;
+ tree *last_p = &TYPE_METHODS (t);
for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
{
*************** check_methods (tree t)
*** 3781,3788 ****
--- 3783,3807 ----
if (DECL_PURE_VIRTUAL_P (x))
CLASSTYPE_PURE_VIRTUALS (t)
= tree_cons (NULL_TREE, x, CLASSTYPE_PURE_VIRTUALS (t));
+ if ((targetm.abi.cxx_virtual_dtors_position
+ == abi_cxx_vdp_declared_last)
+ && DECL_DESTRUCTOR_P (x))
+ {
+ my_friendly_assert (!dtor, 20031128);
+ dtor = x;
+ *last_p = TREE_CHAIN (x);
+ }
+ else
+ last_p = &TREE_CHAIN (x);
}
}
+ /* Move the virtual destructor to the end of the method vector, if
+ we should. */
+ if (dtor)
+ {
+ *last_p = dtor;
+ TREE_CHAIN (dtor) = NULL_TREE;
+ }
}
/* FN is a constructor or destructor. Clone the declaration to create
*************** static tree
*** 4250,4257 ****
create_vtable_ptr (tree t, tree* virtuals_p)
{
tree fn;
! /* Collect the virtual functions declared in T. */
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
--- 4269,4278 ----
create_vtable_ptr (tree t, tree* virtuals_p)
{
tree fn;
+ tree trailing_dtors = NULL_TREE;
+ tree first_dtor = NULL_TREE;
! /* Collect the newly declared virtual functions from T, in reverse order. */
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
*************** create_vtable_ptr (tree t, tree* virtual
*** 4261,4269 ****
BV_FN (new_virtual) = fn;
BV_DELTA (new_virtual) = integer_zero_node;
! TREE_CHAIN (new_virtual) = *virtuals_p;
! *virtuals_p = new_virtual;
}
/* If we couldn't find an appropriate base class, create a new field
here. Even if there weren't any new virtual functions, we might need a
--- 4282,4309 ----
BV_FN (new_virtual) = fn;
BV_DELTA (new_virtual) = integer_zero_node;
! if ((targetm.abi.cxx_virtual_dtors_position
! == abi_cxx_vdp_last_in_vtable)
! && DECL_DESTRUCTOR_P (fn))
! {
! if (!trailing_dtors)
! first_dtor = new_virtual;
! TREE_CHAIN (new_virtual) = trailing_dtors;
! trailing_dtors = new_virtual;
! }
! else
! {
! TREE_CHAIN (new_virtual) = *virtuals_p;
! *virtuals_p = new_virtual;
! }
}
+
+ /* If we saved any virtual dtors, prepend them now. */
+ if (trailing_dtors)
+ {
+ TREE_CHAIN (first_dtor) = *virtuals_p;
+ *virtuals_p = trailing_dtors;
+ }
/* If we couldn't find an appropriate base class, create a new field
here. Even if there weren't any new virtual functions, we might need a