gcc/ChangeLog.mk
================

Sun Jul  4 13:18:23 1999  Mumit Khan  <khan@xraylith.wisc.edu>

	* i386/cygwin.h (PCC_BITFIELD_TYPE_MATTERS): Fix typo and 
	define to be 1.
	(GROUP_BITFIELDS_BY_ALIGN): Define.

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.
	* c-common.c (attrs): Add A_NATIVE, A_GCC_PACK to enum.
	(init_attributes): Set them up.
	(decl_attributes): Parse them, setting flag_native_struct.
	* c-decl.c (start_struct): Propigate TYPE_NATIVE.
	* stor-layout.c (layout_record): Honor GROUP_BITFIELDS_BY_ALIGN.
	(layout_union): Likewise.
	* toplev.c (lang_independent_options): Add native-struct and
	gcc-struct flags.
	(flag_native_struct): Initialize.
	* config/i386/i386-interix.h (PCC_BITFIELD_TYPE_TEST): remove.
	* config/alpha/alpha-interix.h (PCC_BITFIELD_TYPE_TEST): remove.

gcc/cp/ChangeLog.mk
====================

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): Propigate TYPE_NATIVE.
 
Index: gcc-2.95.2/gcc/c-common.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/c-common.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 c-common.c
--- gcc-2.95.2/gcc/c-common.c	1999/11/05 01:09:41	1.1.1.1
+++ gcc-2.95.2/gcc/c-common.c	1999/11/05 06:24:52
@@ -54,7 +54,9 @@ int skip_evaluation;
 enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
 	    A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
 	    A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
-	    A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS};
+	    A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS,
+	    A_NATIVE, A_GCC_PACK,
+	    };
 
 enum format_type { printf_format_type, scanf_format_type,
 		   strftime_format_type };
@@ -377,6 +379,8 @@ static void
 init_attributes ()
 {
   add_attribute (A_PACKED, "packed", 0, 0, 0);
+  add_attribute (A_NATIVE, "native_struct", 0, 0, 0);
+  add_attribute (A_GCC_PACK, "gcc_struct", 0, 0, 0);
   add_attribute (A_NOCOMMON, "nocommon", 0, 0, 1);
   add_attribute (A_COMMON, "common", 0, 0, 1);
   add_attribute (A_NORETURN, "noreturn", 0, 0, 1);
@@ -500,6 +504,24 @@ decl_attributes (node, attributes, prefi
 	    DECL_PACKED (decl) = 1;
 	  /* We can't set DECL_PACKED for a VAR_DECL, because the bit is
 	     used for DECL_REGISTER.  It wouldn't mean anything anyway.  */
+	  else
+	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+	  break;
+
+	case A_NATIVE:
+	  /* It only applies to the whole struct */
+	  if (is_type)
+	    TYPE_NATIVE (type) = 1;
+	  /* it doesn't mean anything to variables */
+	  else
+	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+	  break;
+
+	case A_GCC_PACK:
+	  /* It only applies to the whole struct */
+	  if (is_type)
+	    TYPE_NATIVE (type) = 0;
+	  /* it doesn't mean anything to variables */
 	  else
 	    warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
 	  break;
Index: gcc-2.95.2/gcc/c-decl.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/c-decl.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 c-decl.c
--- gcc-2.95.2/gcc/c-decl.c	1999/11/05 05:54:33	1.2
+++ gcc-2.95.2/gcc/c-decl.c	1999/11/05 06:24:53
@@ -5743,6 +5743,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 ((code == UNION_TYPE ? "redefinition of `union %s'"
 		: "redefinition of `struct %s'"),
@@ -5757,6 +5758,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-2.95.2/gcc/flags.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/flags.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 flags.h
--- gcc-2.95.2/gcc/flags.h	1999/11/05 01:09:42	1.1.1.1
+++ gcc-2.95.2/gcc/flags.h	1999/11/05 06:24:53
@@ -447,6 +447,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-2.95.2/gcc/stor-layout.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/stor-layout.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 stor-layout.c
--- gcc-2.95.2/gcc/stor-layout.c	1999/11/05 01:09:45	1.1.1.1
+++ gcc-2.95.2/gcc/stor-layout.c	1999/11/05 06:24:53
@@ -333,6 +333,26 @@ layout_decl (decl, known_align)
    The return value is a list of static members of the record.
    They still need to be laid out.  */
 
+/* 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
+
 static tree
 layout_record (rec)
      tree rec;
@@ -351,6 +371,7 @@ layout_record (rec)
   /* Once we start using VAR_SIZE, this is the maximum alignment
      that we know VAR_SIZE has.  */
   register int var_align = BITS_PER_UNIT;
+  int last_align = -1;
 
 #ifdef STRUCTURE_SIZE_BOUNDARY
   /* Packed structures don't need to have minimum size.  */
@@ -402,35 +423,111 @@ layout_record (rec)
 
 #ifndef PCC_BITFIELD_TYPE_MATTERS
       record_align = MAX (record_align, desired_align);
-#else
+#else /* [ */
       if (PCC_BITFIELD_TYPE_MATTERS && TREE_TYPE (field) != error_mark_node
 	  && DECL_BIT_FIELD_TYPE (field)
 	  && ! integer_zerop (TYPE_SIZE (TREE_TYPE (field))))
 	{
-	  /* 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
-	     within the structure.  */
-	  if (! integer_zerop (DECL_SIZE (field)))
-	    record_align = MAX ((int)record_align, desired_align);
-	  else if (! DECL_PACKED (field))
-	    desired_align = TYPE_ALIGN (TREE_TYPE (field));
-	  /* A named bit field of declared type `int'
-	     forces the entire structure to have `int' alignment.  */
-	  if (DECL_NAME (field) != 0)
+#ifdef GROUP_BITFIELDS_BY_ALIGN
+	  if (!GROUP_BITFIELDS_BY_ALIGN)
+#endif
 	    {
-	      int type_align = TYPE_ALIGN (TREE_TYPE (field));
-	      if (maximum_field_alignment != 0)
-		type_align = MIN (type_align, maximum_field_alignment);
-	      else if (DECL_PACKED (field))
-		type_align = MIN (type_align, BITS_PER_UNIT);
+	      /* 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
+		 within the structure.  */
+	      if (! integer_zerop (DECL_SIZE (field)))
+		record_align = MAX ((int)record_align, desired_align);
+	      else if (! DECL_PACKED (field))
+		desired_align = TYPE_ALIGN (TREE_TYPE (field));
+	      /* A named bit field of declared type e.g. `int'
+		 forces the entire structure to have `int' alignment.  */
+	      if (DECL_NAME (field) != 0)
+		{
+		  int type_align = TYPE_ALIGN (TREE_TYPE (field));
+		  if (maximum_field_alignment != 0)
+		    type_align = MIN (type_align, maximum_field_alignment);
+		  else if (DECL_PACKED (field))
+		    type_align = MIN (type_align, BITS_PER_UNIT);
 
-	      record_align = MAX ((int)record_align, type_align);
+		  record_align = MAX ((int)record_align, type_align);
+		}
+	    }
+#ifdef GROUP_BITFIELDS_BY_ALIGN /* [ */
+	  else 
+	    {
+	      /* For these, a zero size bitfield is only meaningful when
+		 immediately following another bitfield.  If if 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)) && last_align == -1) 
+		{
+		  /* Completely ignore it */
+		  desired_align = 1;
+	        }
+	      else 
+		{
+		  int type_align;
+		  int proposed_record_align;
+
+		  proposed_record_align 
+		      = type_align 
+		      = TYPE_ALIGN (TREE_TYPE (field));
+
+		  /* 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);
+
+		  record_align = MAX ((int)record_align, proposed_record_align);
+
+		  /* We only change alignment if it changes; else leave things
+		     alone. */
+		  if (last_align != type_align)
+		      desired_align = MAX(last_align,type_align);
+
+		  /* Zero size resets the "saw bitfield" state. */
+		  if (integer_zerop (DECL_SIZE (field)))
+		      last_align = -1;
+		  else
+		      last_align = type_align;
+		}
 	    }
+#endif /* ] */
 	}
       else
-	record_align = MAX ((int)record_align, desired_align);
+	{
+#ifdef GROUP_BITFIELDS_BY_ALIGN
+	  /* Note: 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 (last_align != -1) 
+	     desired_align = MAX(desired_align, last_align);
+	  last_align = -1;
 #endif
+	  record_align = MAX ((int)record_align, desired_align);
+	}
+#endif  /* ] */
 
       /* Does this field automatically have alignment it needs
 	 by virtue of the fields that precede it and the record's
@@ -636,12 +733,23 @@ layout_union (rec)
 
       /* Union must be at least as aligned as any field requires.  */
 
-      union_align = MAX (union_align, DECL_ALIGN (field));
+#ifdef GROUP_BITFIELDS_BY_ALIGN
+      /* However, bitfields don't count in this case */
+      if (!GROUP_BITFIELDS_BY_ALIGN
+	  || !DECL_BIT_FIELD_TYPE (field))
+#endif
+          union_align = MAX (union_align, DECL_ALIGN (field));
 
 #ifdef PCC_BITFIELD_TYPE_MATTERS
       /* On the m88000, a bit field of declare type `int'
-	 forces the entire union to have `int' alignment.  */
-      if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field))
+	 forces the entire union to have `int' alignment.
+	 However, if GROUP_BITFIELDS_BY_ALIGN is true, we don't
+	 do this. */
+      if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field)
+#ifdef GROUP_BITFIELDS_BY_ALIGN
+         && !GROUP_BITFIELDS_BY_ALIGN
+#endif
+      )
 	union_align = MAX (union_align, TYPE_ALIGN (TREE_TYPE (field)));
 #endif
 
Index: gcc-2.95.2/gcc/toplev.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/toplev.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 toplev.c
--- gcc-2.95.2/gcc/toplev.c	1999/11/05 01:09:45	1.1.1.1
+++ gcc-2.95.2/gcc/toplev.c	1999/11/05 06:24:53
@@ -731,9 +731,15 @@ int flag_gnu_linker = 0;
 int flag_gnu_linker = 1;
 #endif
 
-/* 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;
@@ -957,6 +963,10 @@ lang_independent_options f_options[] =
    "Do the full regmove optimization pass"},
   {"pack-struct", &flag_pack_struct, 1,
    "Pack structure members together without holes" },
+  {"native-struct", &flag_native_struct, 1,
+   "Pack structure members consistent with some other (native) compiler" },
+  {"gcc-struct", &flag_native_struct, 0,
+   "Pack structure members using gcc default rules" },
   {"stack-check", &flag_stack_check, 1,
    "Insert stack checking code into the program" },
   {"argument-alias", &flag_argument_noalias, 0,
Index: gcc-2.95.2/gcc/tree.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/tree.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 tree.h
--- gcc-2.95.2/gcc/tree.h	1999/11/05 01:09:45	1.1.1.1
+++ gcc-2.95.2/gcc/tree.h	1999/11/05 06:24:53
@@ -875,10 +875,15 @@ struct tree_block
    the same way that the first union alternative would be passed.  */
 #define TYPE_TRANSPARENT_UNION(NODE) (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)
+
 struct tree_type
 {
   char common[sizeof (struct tree_common)];
@@ -900,6 +905,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 lang_flag_0 : 1;
@@ -909,7 +915,7 @@ struct tree_type
   unsigned lang_flag_4 : 1;
   unsigned lang_flag_5 : 1;
   unsigned lang_flag_6 : 1;
-  /* room for 3 more bits */
+  /* room for 2 more bits */
 
   unsigned int align;
   union tree_node *pointer_to;
Index: gcc-2.95.2/gcc/config/alpha/alpha-interix.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/config/alpha/alpha-interix.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 alpha-interix.h
--- gcc-2.95.2/gcc/config/alpha/alpha-interix.h	1999/11/05 01:09:49	1.1.1.1
+++ gcc-2.95.2/gcc/config/alpha/alpha-interix.h	1999/11/05 06:24:53
@@ -206,7 +206,6 @@ while (0)
 #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)
 
 /* DWARF2 Unwinding doesn't work with exception handling yet. */
Index: gcc-2.952.2/gcc/config/i386/cygwin.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/config/i386/cygwin.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 cygwin.h
--- gcc-2.952.2/gcc/config/i386/cygwin.h	1999/11/05 01:09:55	1.1.1.1
+++ gcc-2.952.2/gcc/config/i386/cygwin.h	1999/11/05 06:24:53
@@ -515,8 +515,9 @@ extern void i386_pe_asm_file_end STDIO_P
 #define BIGGEST_ALIGNMENT 128
 
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
-#undef PCC_BITFIELDS_TYPE_MATTERS
-#define PCC_BITFIELDS_TYPE_MATTERS 0
+#undef PCC_BITFIELD_TYPE_MATTERS
+#define PCC_BITFIELD_TYPE_MATTERS 1
+#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
 
 /* Enable alias attribute support.  */
 #ifndef SET_ASM_OP
Index: gcc-2.95.2/gcc/config/i386/i386-interix.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/config/i386/i386-interix.h,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 i386-interix.h
--- gcc-2.95.2/gcc/config/i386/i386-interix.h	1999/11/05 01:09:55	1.1.1.1
+++ gcc-2.95.2/gcc/config/i386/i386-interix.h	1999/11/05 06:24:53
@@ -412,7 +412,6 @@ while (0)
 #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)
 
 /* The following two flags are usually "off" for i386, because some non-gnu
Index: gcc-2.95.2/gcc/cp/decl.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/decl.c,v
retrieving revision 1.4
diff -u -3 -p -r1.4 decl.c
--- gcc-2.95.2/gcc/cp/decl.c	1999/07/04 18:09:40	1.4
+++ gcc-2.95.2/gcc/cp/decl.c	1999/07/04 18:14:05
@@ -12713,6 +12713,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;
 	}
Index: gcc-2.95.2/gcc/cp/pt.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95.2/gcc/cp/pt.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 pt.c
--- gcc-2.95.2/gcc/cp/pt.c	1999/06/14 21:22:33	1.2
+++ gcc-2.95.2/gcc/cp/pt.c	1999/07/04 18:14:05
@@ -4878,6 +4878,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_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */
   if (ANON_AGGR_TYPE_P (pattern))
