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)
{ "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 }
};
#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
(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
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
--- /dev/null
+/* 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();
+ }