summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/stor-layout.c
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
committerobrien <obrien@FreeBSD.org>2002-05-09 20:02:13 +0000
commitc8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch)
tree29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/stor-layout.c
parentc9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff)
downloadFreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip
FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/stor-layout.c')
-rw-r--r--contrib/gcc/stor-layout.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/contrib/gcc/stor-layout.c b/contrib/gcc/stor-layout.c
index 91aa454..2db4675 100644
--- a/contrib/gcc/stor-layout.c
+++ b/contrib/gcc/stor-layout.c
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "expr.h"
#include "toplev.h"
#include "ggc.h"
+#include "target.h"
/* Set to one when set_sizetype has been called. */
static int sizetype_set;
@@ -503,6 +504,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;
@@ -787,8 +789,26 @@ 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. */
+ if ((* targetm.ms_bitfield_layout_p) (rli->t)
+ && type != error_mark_node
+ && DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (TYPE_SIZE (type))
+ && integer_zerop (DECL_SIZE (field)))
+ {
+ if (rli->prev_field
+ && DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+ {
+ rli->record_align = MAX (rli->record_align, desired_align);
+ rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+ }
+ else
+ desired_align = 1;
+ }
+ else
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
+ && ! (* targetm.ms_bitfield_layout_p) (rli->t)
&& DECL_BIT_FIELD_TYPE (field)
&& ! integer_zerop (TYPE_SIZE (type)))
{
@@ -878,6 +898,7 @@ place_field (rli, field)
variable-sized fields, we need not worry about compatibility. */
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS
+ && ! (* targetm.ms_bitfield_layout_p) (rli->t)
&& TREE_CODE (field) == FIELD_DECL
&& type != error_mark_node
&& DECL_BIT_FIELD (field)
@@ -907,6 +928,7 @@ place_field (rli, field)
#ifdef BITFIELD_NBYTES_LIMITED
if (BITFIELD_NBYTES_LIMITED
+ && ! (* targetm.ms_bitfield_layout_p) (rli->t)
&& TREE_CODE (field) == FIELD_DECL
&& type != error_mark_node
&& DECL_BIT_FIELD_TYPE (field)
@@ -940,6 +962,50 @@ place_field (rli, field)
}
#endif
+ /* See the docs for TARGET_MS_BITFIELD_LAYOUT_P for details. */
+ if ((* targetm.ms_bitfield_layout_p) (rli->t)
+ && TREE_CODE (field) == FIELD_DECL
+ && type != error_mark_node
+ && ! DECL_PACKED (field)
+ && rli->prev_field
+ && DECL_SIZE (field)
+ && host_integerp (DECL_SIZE (field), 1)
+ && DECL_SIZE (rli->prev_field)
+ && host_integerp (DECL_SIZE (rli->prev_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)))
+ /* If the previous field was a zero-sized bit-field, either
+ it was ignored, in which case we must ensure the proper
+ alignment of this field here, or it already forced the
+ alignment of this field, in which case forcing the
+ alignment again is harmless. So, do it in both cases. */
+ || (DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && integer_zerop (DECL_SIZE (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);
+ }
+
/* Offset so far becomes the position of this field after normalizing. */
normalize_rli (rli);
DECL_FIELD_OFFSET (field) = rli->offset;
@@ -966,6 +1032,8 @@ place_field (rli, field)
if (known_align != actual_align)
layout_decl (field, actual_align);
+ rli->prev_field = field;
+
/* Now add size of this field to the size of the record. If the size is
not constant, treat the field as being a multiple of bytes and just
adjust the offset, resetting the bit position. Otherwise, apportion the
@@ -1514,8 +1582,13 @@ layout_type (type)
&& (TYPE_MODE (TREE_TYPE (type)) != BLKmode
|| TYPE_NO_FORCE_BLK (TREE_TYPE (type))))
{
- TYPE_MODE (type)
- = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
+ /* One-element arrays get the component type's mode. */
+ if (simple_cst_equal (TYPE_SIZE (type),
+ TYPE_SIZE (TREE_TYPE (type))))
+ TYPE_MODE (type) = TYPE_MODE (TREE_TYPE (type));
+ else
+ TYPE_MODE (type)
+ = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
if (TYPE_MODE (type) != BLKmode
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
OpenPOWER on IntegriCloud