Mailing-List: contact cygwin-apps-help AT sourceware DOT cygnus DOT com; run by ezmlm Sender: cygwin-apps-owner AT sourceware DOT cygnus DOT com List-Subscribe: List-Archive: List-Post: List-Help: , Delivered-To: mailing list cygwin-apps AT sources DOT redhat DOT com Date: Tue, 6 Nov 2001 19:22:07 -0500 From: Christopher Faylor To: cygwin-apps AT cygwin DOT com Subject: Re: RFC: Merge native-struct into gcc 3.1 Message-ID: <20011106192207.A8594@redhat.com> Reply-To: cygwin-apps AT cygwin DOT com Mail-Followup-To: cygwin-apps AT cygwin DOT com References: <20011015034402 DOT 13695 DOT qmail AT web14504 DOT mail DOT yahoo DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20011015034402.13695.qmail@web14504.mail.yahoo.com> User-Agent: Mutt/1.3.21i Did this ever go anywhere, Danny? Isn't 3.1 going to be frozen RSN? cgf On Mon, Oct 15, 2001 at 01:44:02PM +1000, Danny Smith wrote: >Appended is merge of Donn's native struct patch into GCC-3.1 > >I have left out the changes to union alignment, because my earlier tests >indicated that MSVC alignmnent in unions was same as GCC's (#ifdef >PCC_BITFIELD_TYPE_MATTERS as in cygwin.h) without patch. Can someone >check that. > >I bootstrapped on mingw, and tested with Donn's test case. >Still some formatting to fix. > >I also have patch against 3.0.2 (prerelease) if you are interested. It is >basically the same as the one Donn submitted two years ago. > >The main difference here is due to change in table-driven attributes in 3.1 > > >ChangeLog gcc > >2001-10-15 Danny Smith > > * attribs.c (c_common_attribute_table) : Add native_struct, > gcc_struc attributes. > (handle_native_struct_attribute): New function. > (handle_gcc_struct_attribute): Likewise. > > Merge in Donn Terry native-struct patch. > Mon Apr 26 12:25:41 1999 Donn Terry (donn AT interix DOT com) > * flags.h (flag_native_struct): New boolean. > * tree.h (TYPE_NATIVE): New macro. > (tree_type): Add native_flag. > (record_layout_info): Add new field. > * c-decl.c (start_struct): Propigate TYPE_NATIVE. > * stor-layout.c (layout_record): Honor GROUP_BITFIELDS_BY_ALIGN. > * toplev.c (lang_independent_options): Add native-struct and > gcc-struct flags. > (flag_native_struct): Initialize. > * config/i386/i386-interix.h, config/alpha/alpha-interix.h > (PCC_BITFIELD_TYPE_TEST): Remove. > (GROUP_BITFIELDS_BY_ALIGN): Add argument to macro. > * config/i386/cygwin.h (GROUP_BITFIELDS_BY_ALIGN): Add argument > to macro. > > >ChangeLog gcc/cp > >2001-10-15 Danny Smith > > Merge in Donn Terry native-struct patch > Mon Apr 26 12:25:41 1999 Donn Terry (donn AT interix DOT com) > * decl.c (xref_tag): Init TYPE_PACKED and TYPE_NATIVE from globals. > * pt.c (instantiate_class_template): Propagate TYPE_NATIVE. > > > >Index: gcc/gcc/attribs.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/attribs.c,v >retrieving revision 1.2 >diff -u -p -r1.2 attribs.c >--- attribs.c 2001/10/02 07:12:20 1.2 >+++ attribs.c 2001/10/15 01:54:08 >@@ -80,6 +80,10 @@ static tree handle_no_limit_stack_attrib > bool *)); > static tree handle_pure_attribute PARAMS ((tree *, tree, tree, int, > bool *)); >+static tree handle_native_struct_attribute PARAMS ((tree *, tree, tree, >int, >+ bool *)); >+static tree handle_gcc_struct_attribute PARAMS ((tree *, tree, tree, int, >+ bool *)); > > /* Table of machine-independent attributes common to all C-like languages. > */ > static const struct attribute_spec c_common_attribute_table[] = >@@ -131,6 +135,10 @@ static const struct attribute_spec c_com > handle_no_limit_stack_attribute }, > { "pure", 0, 0, true, false, false, > handle_pure_attribute }, >+ { "native_struct", 0, 0, false, false, false, >+ handle_native_struct_attribute }, >+ { "gcc_struct", 0, 0, false, false, false, >+ handle_gcc_struct_attribute }, > { NULL, 0, 0, false, false, false, NULL } > }; > >@@ -1102,6 +1110,79 @@ handle_pure_attribute (node, name, args, > > return NULL_TREE; > } >+ >+/* Handle a "native_struct" attribute; arguments as in >+ struct attribute_spec.handler. */ >+ >+static tree >+handle_native_struct_attribute (node, name, args, flags, no_add_attrs) >+ tree *node; >+ tree name; >+ tree args ATTRIBUTE_UNUSED; >+ int flags; >+ bool *no_add_attrs; >+{ >+ tree *type = NULL; >+ if (DECL_P (*node)) >+ { >+ if (TREE_CODE (*node) == TYPE_DECL) >+ type = &TREE_TYPE (*node); >+ } >+ else if (TYPE_P (*node)) >+ type = node; >+ >+ if (type) >+ /* It only applies to the whole struct */ >+ { >+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) >+ *type = build_type_copy (*type); >+ TYPE_NATIVE (*type) = 1; >+ } >+ else >+ { >+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); >+ *no_add_attrs = true; >+ } >+ >+ return NULL_TREE; >+} >+ >+/* Handle a "gcc_struct" attribute; arguments as in >+ struct attribute_spec.handler. */ >+ >+static tree >+handle_gcc_struct_attribute (node, name, args, flags, no_add_attrs) >+ tree *node; >+ tree name; >+ tree args ATTRIBUTE_UNUSED; >+ int flags; >+ bool *no_add_attrs; >+{ >+ tree *type = NULL; >+ if (DECL_P (*node)) >+ { >+ if (TREE_CODE (*node) == TYPE_DECL) >+ type = &TREE_TYPE (*node); >+ } >+ else if (TYPE_P (*node)) >+ type = node; >+ >+ if (type) >+ /* It only applies to the whole struct */ >+ { >+ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) >+ *type = build_type_copy (*type); >+ TYPE_NATIVE (*type) = 0; >+ } >+ else >+ { >+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); >+ *no_add_attrs = true; >+ } >+ >+ return NULL_TREE; >+} >+ > > /* Split SPECS_ATTRS, a list of declspecs and prefix attributes, into two > lists. SPECS_ATTRS may also be just a typespec (eg: RECORD_TYPE). >Index: gcc/gcc/c-decl.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v >retrieving revision 1.254 >diff -u -p -r1.254 c-decl.c >--- c-decl.c 2001/10/11 03:15:18 1.254 >+++ c-decl.c 2001/10/15 01:54:52 >@@ -5359,6 +5359,7 @@ start_struct (code, name) > { > C_TYPE_BEING_DEFINED (ref) = 1; > TYPE_PACKED (ref) = flag_pack_struct; >+ TYPE_NATIVE (ref) = flag_native_struct; > if (TYPE_FIELDS (ref)) > error ("redefinition of `%s %s'", > code == UNION_TYPE ? "union" : "struct", >@@ -5373,6 +5374,7 @@ start_struct (code, name) > pushtag (name, ref); > C_TYPE_BEING_DEFINED (ref) = 1; > TYPE_PACKED (ref) = flag_pack_struct; >+ TYPE_NATIVE (ref) = flag_native_struct; > return ref; > } > >Index: gcc/gcc/flags.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/flags.h,v >retrieving revision 1.68 >diff -u -p -r1.68 flags.h >--- flags.h 2001/10/11 12:43:41 1.68 >+++ flags.h 2001/10/15 01:55:14 >@@ -498,6 +498,9 @@ extern int flag_gnu_linker; > /* Tag all structures with __attribute__(packed) */ > extern int flag_pack_struct; > >+/* Tag all structures with __attribute__(native_struct) */ >+extern int flag_native_struct; >+ > /* This flag is only tested if alias checking is enabled. > 0 if pointer arguments may alias each other. True in C. > 1 if pointer arguments may not alias each other but may alias >Index: gcc/gcc/stor-layout.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v >retrieving revision 1.108 >diff -u -p -r1.108 stor-layout.c >--- stor-layout.c 2001/10/11 03:16:10 1.108 >+++ stor-layout.c 2001/10/15 01:55:32 >@@ -479,6 +479,13 @@ start_record_layout (t) > rli->unpacked_align = rli->unpadded_align = rli->record_align; > rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT); > >+#ifdef GROUP_BITFIELDS_BY_ALIGN >+ rli->group_by_align = GROUP_BITFIELDS_BY_ALIGN(t); >+ >+ /* No prior history of alignment */ >+ rli->last_align = -1; >+#endif >+ > #ifdef STRUCTURE_SIZE_BOUNDARY > /* Packed structures don't need to have minimum size. */ > if (! TYPE_PACKED (t)) >@@ -551,6 +558,27 @@ pos_from_bit (poffset, pbitpos, off_alig > /* Given a pointer to bit and byte offsets and an offset alignment, > normalize the offsets so they are within the alignment. */ > >+/* To repreise: PCC_BITFIELD_TYPE_MATTERS is a flag (which must be a valid >+ expression) to force alignment to follow a different set of alignment >+ rules (more like "other compilers", whatever that means). >+ >+ In some systems, it can be a dynamic test for the "native" flag applied >+ to a structure. In others it may not be. >+ >+ It may also be just part of the solution. The flag >GROUP_BITFIELDS_BY_ALIGN >+ causes structures to be aligned according to additional rules (beyond >+ those of PCC...) (that coincide with Windows alignment). */ >+ >+/* G_B_B_A means that a change in the required alignment of a sequence >+ of bitfields causes the next one to be aligned to whatever alignment >+ it needs. Otherwise with P_B_T_M, bitfields are forced to align only >+ by zero-sized fields. With neither, gcc default alignment (fairly >+ tightly packed), prevails. So noone goes astray, sanity check. */ >+ >+#if defined(GROUP_BITFIELDS_BY_ALIGN) && >!defined(PCC_BITFIELD_TYPE_MATTERS) >+You must define PCC_BITFIELD_TYPE_MATTERS to use GROUP_BITFIELDS_BY_ALIGN >+#endif >+ > void > normalize_offset (poffset, pbitpos, off_align) > tree *poffset, *pbitpos; >@@ -765,11 +793,15 @@ place_field (rli, field) > /* Record must have at least as much alignment as any field. > Otherwise, the alignment of the field within the record is > meaningless. */ >-#ifdef PCC_BITFIELD_TYPE_MATTERS >+#ifdef PCC_BITFIELD_TYPE_MATTERS > if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node > && DECL_BIT_FIELD_TYPE (field) > && ! integer_zerop (TYPE_SIZE (type))) > { >+#ifdef GROUP_BITFIELDS_BY_ALIGN >+ if (!rli->group_by_align) >+#endif >+ { > /* For these machines, a zero-length field does not > affect the alignment of the structure as a whole. > It does, however, affect the alignment of the next field >@@ -796,9 +828,84 @@ place_field (rli, field) > rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type)); > } > } >+#ifdef GROUP_BITFIELDS_BY_ALIGN >+ else >+ { >+ /* For these, a zero size bitfield is only meaningful when >+ immediately following another bitfield. If it follows >+ a non-bitfield, it's COMPLETELY ignored. Just to add >+ to the confusion, a zero size bitfield is NOT considered >+ a prior bitfield for this rule, so two zero-size bitfields >+ in a row cause the second to be ignored. >+ >+ Hey... don't blame me: I'm just trying to do what they >+ did. >+ */ >+ >+ if (DECL_PACKED (field)) >+ { >+ /* Already done */ >+ } >+ else if (integer_zerop (DECL_SIZE (field)) && rli->last_align == -1) > >+ { >+ /* Completely ignore it */ >+ desired_align = 1; >+ } >+ else >+ { >+ int type_align; >+ int proposed_record_align; >+ >+ proposed_record_align = type_align = TYPE_ALIGN (type); >+ >+ /* A zero size forces both field and record alignment, >+ *if* it wasn't ignored above. Non-zero size forces >+ record alignment, too. */ >+ if (integer_zerop (DECL_SIZE (field))) >+ desired_align = type_align; >+ >+ /* Apply ceilings on record alignment */ >+ if (maximum_field_alignment != 0) >+ proposed_record_align = >+ MIN (proposed_record_align, maximum_field_alignment); >+ else if (DECL_PACKED (field)) >+ proposed_record_align = >+ MIN (proposed_record_align, BITS_PER_UNIT); >+ >+ rli->record_align = >+ MAX ((int)rli->record_align, proposed_record_align); >+ >+ if (warn_packed) >+ rli->unpacked_align = >+ MAX (rli->unpacked_align, TYPE_ALIGN (type)); >+ >+ /* We only change alignment if it changes; else leave things >+ alone. */ >+ if (rli->last_align != type_align) >+ desired_align = MAX(rli->last_align,type_align); >+ >+ /* Zero size resets the "saw bitfield" state. */ >+ if (integer_zerop (DECL_SIZE (field))) >+ rli->last_align = -1; >+ else >+ rli->last_align = type_align; >+ } >+ } >+#endif >+ } > else > #endif > { >+#ifdef GROUP_BITFIELDS_BY_ALIGN >+ /* Note: rli->last_align can never be different from -1 unless >+ the GROUP_BITFIELDS_BY_ALIGN stuff is enabled. >+ >+ If the prior field caused an alignment, NOW is when >+ we honor it. */ >+ if (rli->last_align != -1) >+ desired_align = MAX(desired_align, rli->last_align); >+ rli->last_align = -1; >+#endif > rli->record_align = MAX (rli->record_align, desired_align); > rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type)); > rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field)); >Index: gcc/gcc/toplev.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/toplev.c,v >retrieving revision 1.520 >diff -u -p -r1.520 toplev.c >--- toplev.c 2001/10/12 03:34:39 1.520 >+++ toplev.c 2001/10/15 01:56:05 >@@ -828,9 +828,15 @@ int flag_ssa_ccp = 0; > /* Enable ssa aggressive dead code elimination. */ > int flag_ssa_dce = 0; > >-/* Tag all structures with __attribute__(packed). */ >+/* Tag all structures with __attribute__(packed) off. */ > int flag_pack_struct = 0; > >+/* Tag all structures with __attribute__(native_struct) off */ >+#ifndef DEFAULT_NATIVE_STRUCT >+#define DEFAULT_NATIVE_STRUCT 0 >+#endif >+int flag_native_struct = DEFAULT_NATIVE_STRUCT; >+ > /* Emit code to check for stack overflow; also may cause large objects > to be allocated dynamically. */ > int flag_stack_check; >@@ -1126,6 +1132,10 @@ lang_independent_options f_options[] = > N_("Do the full regmove optimization pass") }, > {"pack-struct", &flag_pack_struct, 1, > N_("Pack structure members together without holes") }, >+ {"native-struct", &flag_native_struct, 1, >+ N_("Pack structure members consistent with some other (native) >compiler") }, >+ {"gcc-struct", &flag_native_struct, 0, >+ N_("Pack structure members using gcc default rules") }, > {"stack-check", &flag_stack_check, 1, > N_("Insert stack checking code into the program") }, > {"argument-alias", &flag_argument_noalias, 0, >Index: gcc/gcc/tree.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/tree.h,v >retrieving revision 1.275 >diff -u -p -r1.275 tree.h >--- tree.h 2001/10/11 12:43:43 1.275 >+++ tree.h 2001/10/15 01:56:35 >@@ -1092,10 +1092,15 @@ struct tree_block > #define TYPE_NONALIASED_COMPONENT(NODE) \ > (ARRAY_TYPE_CHECK (NODE)->type.transparent_union_flag) > >-/* Indicated that objects of this type should be laid out in as >+/* Indicates that objects of this type should be laid out in as > compact a way as possible. */ > #define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag) > >+/* Indicates that objects of this type should be layed out as the >+ native compiler does; if a compile line option (or default state) >+ turns this on, then turning it OFF should result in gnu alignment. */ >+#define TYPE_NATIVE(NODE) ((NODE)->type.native_flag) >+ > /* A bounded pointer or bounded reference type (collectively called > indirect types) is represented as a RECORD_TYPE node containing > three pointer fields whose type is the corresponding unbounded >@@ -1172,6 +1177,7 @@ struct tree_type > unsigned needs_constructing_flag : 1; > unsigned transparent_union_flag : 1; > unsigned packed_flag : 1; >+ unsigned native_flag : 1; > unsigned restrict_flag : 1; > unsigned pointer_depth : 2; > >@@ -2267,6 +2273,11 @@ typedef struct record_layout_info_s > instance variables) encountered in T. */ > tree pending_statics; > int packed_maybe_necessary; >+ /* Certain record layouts need to know the alignment of the >+ immediately prior field (essentially to keep like types grouped). */ >+ int group_by_align; >+ /* -1 means no relevant alignment is applicable */ >+ int last_align; > } *record_layout_info; > > extern void set_lang_adjust_rli PARAMS ((void (*) PARAMS >Index: gcc/gcc/config/alpha/alpha-interix.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha-interix.h,v >retrieving revision 1.10 >diff -u -p -r1.10 alpha-interix.h >--- alpha-interix.h 2001/08/09 22:33:21 1.10 >+++ alpha-interix.h 2001/10/15 01:57:21 >@@ -153,9 +153,10 @@ while (0) > #define HOST_PTR_PRINTF "%p" > #define HOST_PTR_AS_INT unsigned long > >-#define PCC_BITFIELD_TYPE_MATTERS 1 >-#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec) >-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec) >+#undef PCC_BITFIELDS_TYPE_MATTERS >+#define PCC_BITFIELDS_TYPE_MATTERS 1 >+#undef GROUP_BITFIELDS_BY_ALIGN >+#define GROUP_BITFIELDS_BY_ALIGN(rec) TYPE_NATIVE(rec) > > /* DWARF2 Unwinding doesn't work with exception handling yet. */ > #undef DWARF2_UNWIND_INFO >Index: gcc/gcc/config/i386/cygwin.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/config/i386/cygwin.h,v >retrieving revision 1.53 >diff -u -p -r1.53 cygwin.h >--- cygwin.h 2001/10/12 13:15:34 1.53 >+++ cygwin.h 2001/10/15 01:57:27 >@@ -453,7 +453,8 @@ extern int i386_pe_dllimport_name_p PARA > /* A bitfield declared as `int' forces `int' alignment for the struct. */ > #undef PCC_BITFIELDS_TYPE_MATTERS > #define PCC_BITFIELDS_TYPE_MATTERS 1 >-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec) >+#undef GROUP_BITFIELDS_BY_ALIGN >+#define GROUP_BITFIELDS_BY_ALIGN(rec) TYPE_NATIVE(rec) > > > /* Enable alias attribute support. */ >Index: gcc/gcc/config/i386/i386-interix.h >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-interix.h,v >retrieving revision 1.17 >diff -u -p -r1.17 i386-interix.h >--- i386-interix.h 2001/08/09 22:33:23 1.17 >+++ i386-interix.h 2001/10/15 01:57:30 >@@ -321,9 +321,11 @@ while (0) > #define HOST_PTR_PRINTF "%p" > #define HOST_PTR_AS_INT unsigned long > >-#define PCC_BITFIELD_TYPE_MATTERS 1 >-#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec) >-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec) >+#undef PCC_BITFIELDS_TYPE_MATTERS >+#define PCC_BITFIELDS_TYPE_MATTERS 1 >+#undef GROUP_BITFIELDS_BY_ALIGN >+#define GROUP_BITFIELDS_BY_ALIGN(rec) TYPE_NATIVE(rec) >+ > > /* The following two flags are usually "off" for i386, because some >non-gnu > tools (for the i386) don't handle them. However, we don't have that >Index: gcc/gcc/cp/decl.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v >retrieving revision 1.819 >diff -u -p -r1.819 decl.c >--- decl.c 2001/10/07 16:50:54 1.819 >+++ decl.c 2001/10/15 01:59:21 >@@ -12659,6 +12659,9 @@ xref_tag (code_type_node, name, globaliz > /* Class types don't nest the way enums do. */ > class_binding_level = (struct binding_level *)0; > #endif >+ TYPE_PACKED (ref) = flag_pack_struct; >+ TYPE_NATIVE (ref) = flag_native_struct; >+ > pushtag (name, ref, globalize); > class_binding_level = old_b; > } >@@ -12724,7 +12727,14 @@ xref_basetypes (code_type_node, name, re > tree base; > > int i, len; >- enum tag_types tag_code = (enum tag_types) tree_low_cst (code_type_node, >1); >+ >+ /* If we are called from the parser, code_type_node will sometimes be a >+ TREE_LIST. This indicates that the user wrote >+ "class __attribute__ ((foo)) bar". Extract the list.value. */ >+ >+ enum tag_types tag_code = (enum tag_types) tree_low_cst ( >+ (TREE_CODE (code_type_node) == TREE_LIST) ? TREE_VALUE (code_type_node) >+ : code_type_node, 1); > > if (tag_code == union_type) > { >Index: gcc/gcc/cp/pt.c >=================================================================== >RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v >retrieving revision 1.553 >diff -u -p -r1.553 pt.c >--- pt.c 2001/10/13 15:00:44 1.553 >+++ pt.c 2001/10/15 02:00:23 >@@ -5021,6 +5021,7 @@ instantiate_class_template (type) > TYPE_USES_VIRTUAL_BASECLASSES (type) > = TYPE_USES_VIRTUAL_BASECLASSES (pattern); > TYPE_PACKED (type) = TYPE_PACKED (pattern); >+ TYPE_NATIVE (type) = TYPE_NATIVE (pattern); > TYPE_ALIGN (type) = TYPE_ALIGN (pattern); > TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern); > TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's >JArray */ > > > >http://briefcase.yahoo.com.au - Yahoo! Briefcase >- Manage your files online. -- cgf AT redhat DOT com Red Hat, Inc. http://sources.redhat.com/ http://www.redhat.com/