Merge native-struct into gcc 3.1

Donn Terry donnte@microsoft.com
Mon Oct 15 09:40:00 GMT 2001


I'm deeply swamped with other things at the moment, but I will take a
look
at the result when I have time, and in particular run the tests that I
have
to confirm the issue of union alignment.   Thanks for doing this.  Yes,
I
remain interested even in my new life, but time to actually do anything
has
been very hard to come by.

Donn

-----Original Message-----
From: Danny Smith [ mailto:danny_r_smith_2001@yahoo.co.nz ] 
Sent: Sunday, October 14, 2001 8:44 PM
To: cygwin-apps
Cc: donn@interix.com
Subject: RFC: Merge native-struct into gcc 3.1


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  <danny_r_smith_2001@yahoo.co.nz> 

	* 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@interix.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  <danny_r_smith_2001@yahoo.co.nz> 

	Merge in Donn Terry native-struct patch 
	Mon Apr 26 12:25:41 1999 Donn Terry (donn@interix.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<T> */



http://briefcase.yahoo.com.au - Yahoo! Briefcase
- Manage your files online.



More information about the Cygwin-apps mailing list