This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[csl-hpux-branch]: Virtual destructor position


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]