This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
MS-style bit-field placement
- To: gcc-patches at gcc dot gnu dot org
- Subject: MS-style bit-field placement
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 14 Apr 2001 11:53:59 -0300
- Organization: GCC Team, Red Hat
Here's a patch that makes GCC capable of placing bit-fields exactly
like Microsoft compilers do. Or so it seems to me.
I'm a little bit unsure about whether to separate the three key
behaviors into different #defines, or to just have a single macro to
enable them all. Opinions? Ok to install?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* tree.h (record_layout_info_s): Added prev_field.
* stor-layout.c (start_record_layout): Zero out prev_field.
(place_field): Use it for BITFIELD_SAME_TYPE_SIZE,
ZERO_SIZED_BITFIELD_AFFECTS_STRUCT_ALIGNMENT and
ZERO_SIZED_BITFIELD_WORKS_AFTER_NONZERO_BITFIELD.
* tm.texi: Document the new macros.
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.236
diff -u -p -r1.236 tree.h
--- gcc/tree.h 2001/04/13 21:10:15 1.236
+++ gcc/tree.h 2001/04/14 14:51:31
@@ -2113,6 +2113,8 @@ typedef struct record_layout_info_s
unsigned int record_align;
/* The alignment of the record so far, not including padding, in bits. */
unsigned int unpacked_align;
+ /* The previous field layed out. */
+ tree prev_field;
/* The static variables (i.e., class variables, as opposed to
instance variables) encountered in T. */
tree pending_statics;
Index: gcc/tm.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tm.texi,v
retrieving revision 1.178
diff -u -p -r1.178 tm.texi
--- gcc/tm.texi 2001/04/13 01:42:38 1.178
+++ gcc/tm.texi 2001/04/14 14:51:33
@@ -1118,6 +1118,24 @@ get from @code{PCC_BITFIELD_TYPE_MATTERS
Like PCC_BITFIELD_TYPE_MATTERS except that its effect is limited to
aligning a bitfield within the structure.
+@findex BITFIELD_SAME_TYPE_SIZE
+@item BITFIELD_SAME_TYPE_SIZE
+If defined to non-zero, a bitfield won't share the same storage unit
+with the previous bitfield if their underlying types have different
+sizes. In this case, the bitfield will be aligned to the highest
+alignment of the underlying types of itself and of the previous
+bitfield.
+
+@findex ZERO_SIZED_BITFIELD_WORKS_AFTER_NONZERO_BITFIELD
+@item ZERO_SIZED_BITFIELDS_WORKS_AFTER_NONZERO_BITFIELD
+If defined to non-zero, a zero-sized bitfield will be disregarded unless
+it follows a non-zero-sized bitfield.
+
+@findex ZERO_SIZED_BITFIELD_AFFECTS_STRUCT_ALIGNMENT
+@item ZERO_SIZED_BITFIELDS_AFFECTS_STRUCT_ALIGNMENT
+If defined to non-zero, a zero-sized bitfield will affect alignment of
+the whole struct, even if it is unnamed.
+
@findex MEMBER_TYPE_FORCES_BLK
@item MEMBER_TYPE_FORCES_BLK (@var{field})
Return 1 if a structure or array containing @var{field} should be accessed using
Index: gcc/stor-layout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stor-layout.c,v
retrieving revision 1.96
diff -u -p -r1.96 stor-layout.c
--- gcc/stor-layout.c 2001/03/23 16:59:56 1.96
+++ gcc/stor-layout.c 2001/04/14 14:51:33
@@ -475,6 +475,7 @@ start_record_layout (t)
rli->offset = size_zero_node;
rli->bitpos = bitsize_zero_node;
+ rli->prev_field = 0;
rli->pending_statics = 0;
rli->packed_maybe_necessary = 0;
@@ -702,6 +703,7 @@ place_field (rli, field)
else if (TREE_CODE (rli->t) != RECORD_TYPE)
{
place_union_field (rli, field);
+ rli->prev_field = field;
return;
}
@@ -747,6 +749,28 @@ 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 ZERO_SIZED_BITFIELD_AFFECTS_STRUCT_ALIGNMENT
+ if (ZERO_SIZED_BITFIELD_AFFECTS_STRUCT_ALIGNMENT
+ && type != error_mark_node
+ && DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (TYPE_SIZE (type))
+ && integer_zerop (DECL_SIZE (field)))
+ {
+#ifdef ZERO_SIZED_BITFIELD_WORKS_AFTER_NONZERO_BITFIELD
+ if (ZERO_SIZED_BITFIELD_WORKS_AFTER_NONZERO_BITFIELD
+ && ! (rli->prev_field
+ && DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && ! integer_zerop (DECL_SIZE (rli->prev_field))))
+ desired_align = 1;
+ else
+#endif
+ {
+ rli->record_align = MAX (rli->record_align, desired_align);
+ rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+ }
+ }
+ else
+#endif
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
&& DECL_BIT_FIELD_TYPE (field)
@@ -899,6 +923,41 @@ place_field (rli, field)
}
#endif
+#ifdef BITFIELD_SAME_TYPE_SIZE
+ if (BITFIELD_SAME_TYPE_SIZE
+ && TREE_CODE (field) == FIELD_DECL
+ && type != error_mark_node
+ && ! DECL_PACKED (field)
+ && rli->prev_field
+ && host_integerp (DECL_SIZE (field), 1)
+ && host_integerp (rli->offset, 1)
+ && host_integerp (TYPE_SIZE (type), 1)
+ && host_integerp (TYPE_SIZE (TREE_TYPE (rli->prev_field)), 1)
+ && ((DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+ || (DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (DECL_SIZE (field))))
+ && ! simple_cst_equal (TYPE_SIZE (type),
+ TYPE_SIZE (TREE_TYPE (rli->prev_field))))
+ {
+ unsigned int type_align = TYPE_ALIGN (type);
+
+ if (rli->prev_field
+ && DECL_BIT_FIELD_TYPE (rli->prev_field)
+ /* If the previous bit-field is zero-sized, we've already
+ accounted for its alignment needs (or ignored it, if
+ appropriate) while placing it. */
+ && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+ type_align = MAX (type_align,
+ TYPE_ALIGN (TREE_TYPE (rli->prev_field)));
+
+ if (maximum_field_alignment != 0)
+ type_align = MIN (type_align, maximum_field_alignment);
+
+ rli->bitpos = round_up (rli->bitpos, type_align);
+ }
+#endif
+
/* Offset so far becomes the position of this field after normalizing. */
normalize_rli (rli);
DECL_FIELD_OFFSET (field) = rli->offset;
@@ -950,6 +1009,8 @@ place_field (rli, field)
rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
normalize_rli (rli);
}
+
+ rli->prev_field = field;
}
/* Assuming that all the fields have been laid out, this function uses
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me