This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH [cygwin/mingw ]: Don't add stdcall suffix to variadic functions
- From: Danny Smith <danny_smith_0000 at yahoo dot co dot nz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: me at cgf dot cx
- Date: Thu, 15 Jul 2004 18:53:33 +1200 (NZST)
- Subject: 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