i386.c (ix86_attribute_table): Add new attributes ms_struct and gcc_struct.

* config/i386/i386.c (ix86_attribute_table): Add new attributes
	ms_struct and gcc_struct.
	(ix86_handle_struct_attribute): New function.
	(ix86_ms_bitfield_layout_p): Update to take new attributes
	into account.
	* doc/extend.texi: Document new attributes.
	* testsuite/gcc.dg/bf-ms-attrib.c: New test.

From-SVN: r61072
This commit is contained in:
Douglas B Rupp 2003-01-09 05:23:55 +00:00 committed by Douglas Rupp
parent 984179689f
commit fe77449a16
4 changed files with 135 additions and 2 deletions

View file

@ -1,3 +1,13 @@
2003-01-08 Douglas B Rupp <rupp@gnat.com>
* config/i386/i386.c (ix86_attribute_table): Add new attributes
ms_struct and gcc_struct.
(ix86_handle_struct_attribute): New function.
(ix86_ms_bitfield_layout_p): Update to take new attributes
into account.
* doc/extend.texi: Document new attributes.
* testsuite/gcc.dg/bf-ms-attrib.c: New test.
2003-01-08 Danny Smith <dannysmith@users.sourceforge.net>
PR optimization/8750

View file

@ -870,6 +870,7 @@ static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *
static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
static int ix86_value_regno PARAMS ((enum machine_mode));
static bool ix86_ms_bitfield_layout_p PARAMS ((tree));
static tree ix86_handle_struct_attribute PARAMS ((tree *, tree, tree, int, bool *));
static int extended_reg_mentioned_1 PARAMS ((rtx *, void *));
#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
@ -1456,6 +1457,8 @@ const struct attribute_spec ix86_attribute_table[] =
{ "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
{ "shared", 0, 0, true, false, false, ix86_handle_shared_attribute },
#endif
{ "ms_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
{ "gcc_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
@ -14531,11 +14534,52 @@ x86_order_regs_for_local_alloc ()
#define TARGET_USE_MS_BITFIELD_LAYOUT 0
#endif
/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
struct attribute_spec.handler. */
static tree
ix86_handle_struct_attribute (node, name, args, flags, no_add_attrs)
tree *node;
tree name;
tree args ATTRIBUTE_UNUSED;
int flags ATTRIBUTE_UNUSED;
bool *no_add_attrs;
{
tree *type = NULL;
if (DECL_P (*node))
{
if (TREE_CODE (*node) == TYPE_DECL)
type = &TREE_TYPE (*node);
}
else
type = node;
if (!(type && (TREE_CODE (*type) == RECORD_TYPE
|| TREE_CODE (*type) == UNION_TYPE)))
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
else if ((is_attribute_p ("ms_struct", name)
&& lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
|| ((is_attribute_p ("gcc_struct", name)
&& lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
{
warning ("`%s' incompatible attribute ignored",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
return NULL_TREE;
}
static bool
ix86_ms_bitfield_layout_p (record_type)
tree record_type ATTRIBUTE_UNUSED;
tree record_type;
{
return TARGET_USE_MS_BITFIELD_LAYOUT;
return (TARGET_USE_MS_BITFIELD_LAYOUT &&
!lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
|| lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
}
/* Returns an expression indicating where the this parameter is

View file

@ -3212,6 +3212,26 @@ Medium and large model objects may live anywhere in the 32-bit address space
(the compiler will generate @code{seth/add3} instructions to load their
addresses).
@subsection i386 Variable Attributes
Two attributes are currently defined for i386 configurations:
@code{ms_struct} and @code{gcc_struct}
@item ms_struct
@itemx gcc_struct
@cindex @code{ms_struct}
@cindex @code{gcc_struct}
If @code{packed} is used on a structure, or if bit-fields are used
it may be that the Microsoft ABI packs them differently
than GCC would normally pack them. Particularly when moving packed
data between functions compiled with GCC and the native Microsoft compiler
(either via function call or as data in a file), it may be necessary to access
either format.
Currently @option{-m[no-]ms-bitfields} is provided for the Windows X86
compilers to match the native Microsoft compiler.
@end table
To specify multiple attributes, separate them by commas within the
@ -3471,6 +3491,26 @@ If you replaced @code{short_a} with @code{short} in the variable
declaration, the above program would abort when compiled with
@option{-fstrict-aliasing}, which is on by default at @option{-O2} or
above in recent GCC versions.
@subsection i386 Type Attributes
Two attributes are currently defined for i386 configurations:
@code{ms_struct} and @code{gcc_struct}
@item ms_struct
@itemx gcc_struct
@cindex @code{ms_struct}
@cindex @code{gcc_struct}
If @code{packed} is used on a structure, or if bit-fields are used
it may be that the Microsoft ABI packs them differently
than GCC would normally pack them. Particularly when moving packed
data between functions compiled with GCC and the native Microsoft compiler
(either via function call or as data in a file), it may be necessary to access
either format.
Currently @option{-m[no-]ms-bitfields} is provided for the Windows X86
compilers to match the native Microsoft compiler.
@end table
To specify multiple attributes, separate them by commas within the

View file

@ -0,0 +1,39 @@
/* bf-ms-attrib.c */
/* Adapted from Donn Terry <donnte@microsoft.com> testcase
posted to GCC-patches
http://gcc.gnu.org/ml/gcc-patches/2000-08/msg00577.html */
/* { dg-do run { target *-*-interix* } } */
/* We don't want the default "pedantic-errors" in this case, since we're
testing nonstandard stuff to begin with. */
/* { dg-options "-ansi" } */
#include <stdio.h>
struct one_gcc {
int d;
unsigned char a;
unsigned short b:7;
char c;
} __attribute__((__gcc_struct__)) ;
struct one_ms {
int d;
unsigned char a;
unsigned short b:7;
char c;
} __attribute__((__ms_struct__));
main()
{
/* As long as the sizes are as expected, we know attributes are working.
bf-ms-layout.c makes sure the right thing happens when the attribute
is on. */
if (sizeof(struct one_ms) != 12)
abort();
if (sizeof(struct one_gcc) != 8)
abort();
}