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]

PATCH [cygwin/mingw ]: Don't add stdcall suffix to variadic functions


Hello,

On i386-pe targets, stdcall functions are suffixed with @nn, when nn
is the number of bytes in the parameter list.

The native MS Windoes compiler decorates functions with
empty parameter list, eg

void __stdcall bar ();

as _bar@0


However, for variadic functions, which cannot be handled
as __stdcall because the parameter list is indefinite, it
leaves off the suffix
eg.
void __stdcall foo (int a, ...) 

foo stays as _foo

Currently gcc adds @0 suffix to both types of function

The following patch makes gcc consistent with native compiler.  It also
rationalizes the two functions gen_fastcall_sufffix  and gen_stdcall_suffix
(which are identical except for two statements) into a single function

bootstrapped/regtested i686-pc-mingw32

Changelog

2004-07-15  Danny Smith  <dannysmith@users.sourceforge.net>

	* config/i386/winnt.c (gen_fastcall_or_stdcall_suffix):
	New function combining ...
	(gen_fastcall_suffix): Remove.
	(gen_stdcall_suffix): Remove.
	(i386_pe_encode_section_info): Update calls.

	* config/i386/winnt.c (gen_fastcall_or_stdcall_suffix): Do not
	add suffix or prefix if variadic function decl.

testsuite/ChangeLog

	gcc.dg/attr-stdcall-va.c: New file.

Index: config/i386/winnt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 winnt.c
*** config/i386/winnt.c	30 Jun 2004 05:04:36 -0000	1.68
--- config/i386/winnt.c	15 Jul 2004 06:44:05 -0000
*************** Software Foundation, 59 Temple Place - S
*** 47,54 ****
  */
  
  static tree associated_type (tree);
! static const char * gen_stdcall_suffix (tree);
! static const char * gen_fastcall_suffix (tree);
  static int i386_pe_dllexport_p (tree);
  static int i386_pe_dllimport_p (tree);
  static void i386_pe_mark_dllexport (tree);
--- 47,53 ----
  */
  
  static tree associated_type (tree);
! static const char * gen_fastcall_or_stdcall_suffix (tree, bool);
  static int i386_pe_dllexport_p (tree);
  static int i386_pe_dllimport_p (tree);
  static void i386_pe_mark_dllexport (tree);
*************** i386_pe_mark_dllimport (tree decl)
*** 403,485 ****
    DECL_NON_ADDR_CONST_P (decl) = 1;
  }
  
! /* Return string which is the former assembler name modified with a
!    prefix consisting of FASTCALL_PREFIX and a suffix consisting of an
!    atsign (@) followed by the number of bytes of arguments.  */
  
  static const char *
! gen_fastcall_suffix (tree decl)
  {
    int total = 0;
    const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    char *newsym;
  
!   if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
!     if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
!         == void_type_node)
!       {
! 	tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
! 
! 	/* Quit if we hit an incomplete type.  Error is reported
! 	   by convert_arguments in c-typeck.c or cp/typeck.c.  */
! 	while (TREE_VALUE (formal_type) != void_type_node
! 	       && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))	
! 	  {
! 	    int parm_size
! 	      = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
! 	    /* Must round up to include padding.  This is done the same
! 	       way as in store_one_arg.  */
! 	    parm_size = ((parm_size + PARM_BOUNDARY - 1)
! 			 / PARM_BOUNDARY * PARM_BOUNDARY);
! 	    total += parm_size;
! 	    formal_type = TREE_CHAIN (formal_type);
! 	  }
!       }
! 
!   /* Assume max of 8 base 10 digits in the suffix.  */
!   newsym = xmalloc (1 + strlen (asmname) + 1 + 8 + 1);
!   sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UNIT);
!   return IDENTIFIER_POINTER (get_identifier (newsym));
! }
! 
! /* Return string which is the former assembler name modified with a
!    suffix consisting of an atsign (@) followed by the number of bytes of
!    arguments */
! 
! static const char *
! gen_stdcall_suffix (tree decl)
! {
!   int total = 0;
!   /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
!      of DECL_ASSEMBLER_NAME.  */
!   const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
!   char *newsym;
! 
!   if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
!     if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
!         == void_type_node)
!       {
! 	tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
! 
! 	/* Quit if we hit an incomplete type.  Error is reported
! 	   by convert_arguments in c-typeck.c or cp/typeck.c.  */
! 	while (TREE_VALUE (formal_type) != void_type_node
! 	       && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))	
! 	  {
! 	    int parm_size
! 	      = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
! 	    /* Must round up to include padding.  This is done the same
! 	       way as in store_one_arg.  */
! 	    parm_size = ((parm_size + PARM_BOUNDARY - 1)
! 			 / PARM_BOUNDARY * PARM_BOUNDARY);
! 	    total += parm_size;
! 	    formal_type = TREE_CHAIN (formal_type);
! 	  }
!       }
  
    /* Assume max of 8 base 10 digits in the suffix.  */
!   newsym = xmalloc (strlen (asmname) + 1 + 8 + 1);
!   sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
    return IDENTIFIER_POINTER (get_identifier (newsym));
  }
  
--- 402,450 ----
    DECL_NON_ADDR_CONST_P (decl) = 1;
  }
  
! /* Return string which is the former assembler modified with a
!    suffix consisting of an atsign (@) followed by the number of
!    bytes of arguments.  If fastcall is true, also prefix the symbol
!    with FASTCALL_PREFIX.  */
  
  static const char *
! gen_fastcall_or_stdcall_suffix (tree decl, bool fastcall)
  {
    int total = 0;
    const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
    char *newsym;
+   char *p;
+   tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
  
!   if (formal_type)
!     {
!       /* For compatibility with MS compiler do not add @0 suffix
!          to variadic functions.  */ 
!       if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
!         return asmname;
! 
!       /* Quit if we hit an incomplete type.  Error is reported
! 	 by convert_arguments in c-typeck.c or cp/typeck.c.  */
!       while (TREE_VALUE (formal_type) != void_type_node
! 	     && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))	
! 	{
! 	  int parm_size
! 	    = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
! 	  /* Must round up to include padding.  This is done the same
! 	     way as in store_one_arg.  */
! 	  parm_size = ((parm_size + PARM_BOUNDARY - 1)
! 		       / PARM_BOUNDARY * PARM_BOUNDARY);
! 	  total += parm_size;
! 	  formal_type = TREE_CHAIN (formal_type);
! 	}
!     }
  
    /* Assume max of 8 base 10 digits in the suffix.  */
!   newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
!   p = newsym;
!   if (fastcall)
!     *p++ = FASTCALL_PREFIX;
!   sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
    return IDENTIFIER_POINTER (get_identifier (newsym));
  }
  
*************** i386_pe_encode_section_info (tree decl, 
*** 495,503 ****
        if (GET_CODE (rtlname) == MEM)
  	rtlname = XEXP (rtlname, 0);
        if (lookup_attribute ("stdcall", type_attributes))
! 	XSTR (rtlname, 0) = gen_stdcall_suffix (decl);
        else if (lookup_attribute ("fastcall", type_attributes))
! 	XSTR (rtlname, 0) = gen_fastcall_suffix (decl);
      }
  
    /* Mark the decl so we can tell from the rtl whether the object is
--- 460,468 ----
        if (GET_CODE (rtlname) == MEM)
  	rtlname = XEXP (rtlname, 0);
        if (lookup_attribute ("stdcall", type_attributes))
! 	XSTR (rtlname, 0) = gen_fastcall_or_stdcall_suffix (decl, false);
        else if (lookup_attribute ("fastcall", type_attributes))
! 	XSTR (rtlname, 0) =  gen_fastcall_or_stdcall_suffix (decl, true);
      }
  
    /* Mark the decl so we can tell from the rtl whether the object is
*** /dev/null	Thu Jul 15 17:15:49 2004
--- testsuite/gcc.dg/attr-stdcall-va.c	Thu Jul 15 16:53:17 2004
***************
*** 0 ****
--- 1,20 ----
+ /* Test that variadic functions do not get stdcall suffix.  */
+ /* { dg-do compile { target i?86-*-cygwin* i?86-*-mingw* } } */
+ 
+ void __attribute__((__stdcall__)) foo (void)
+ { }
+ 
+ void __attribute__((__stdcall__)) fee (int a, ...)
+ { }
+ 
+ void __attribute__((__fastcall__)) boo (void)
+ { }
+ 
+ void __attribute__((__fastcall__)) bee (int a, ...)
+ { }
+ 
+ 
+ /* { dg-final { scan-assembler "_foo@0;" } } */
+ /* { dg-final { scan-assembler "_fee;" } } */
+ /* { dg-final { scan-assembler "@boo@0;" } } */
+ /* { dg-final { scan-assembler "_bee;" } } */

Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


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