/* C-compiler utilities for types and variables storage layout
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
static void finalize_record_size PARAMS ((record_layout_info));
static void finalize_type_size PARAMS ((tree));
static void place_union_field PARAMS ((record_layout_info, tree));
+#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
static int excess_unit_span PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT, HOST_WIDE_INT,
tree));
+#endif
static unsigned int update_alignment_for_field
PARAMS ((record_layout_info, tree,
unsigned int));
{
/* Strip any simple arithmetic from EXPR to see if it has an underlying
SAVE_EXPR. */
- while (TREE_CODE_CLASS (TREE_CODE (expr)) == '1'
- || (TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
- && TREE_CONSTANT (TREE_OPERAND (expr, 1))))
- expr = TREE_OPERAND (expr, 0);
+ expr = skip_simple_arithmetic (expr);
if (TREE_CODE (expr) == SAVE_EXPR)
pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
variable_size (size)
tree size;
{
+ tree save;
+
/* If the language-processor is to take responsibility for variable-sized
items (e.g., languages which have elaboration procedures like Ada),
just return SIZE unchanged. Likewise for self-referential sizes and
|| contains_placeholder_p (size))
return size;
- size = save_expr (size);
+ if (TREE_CODE (size) == MINUS_EXPR && integer_onep (TREE_OPERAND (size, 1)))
+ /* If this is the upper bound of a C array, leave the minus 1 outside
+ the SAVE_EXPR so it can be folded away. */
+ TREE_OPERAND (size, 0) = save = save_expr (TREE_OPERAND (size, 0));
+ else
+ size = save = save_expr (size);
/* If an array with a variable number of elements is declared, and
the elements require destruction, we will emit a cleanup for the
`unsaved', i.e., all SAVE_EXPRs are recalculated. However, we do
not wish to do that here; the array-size is the same in both
places. */
- if (TREE_CODE (size) == SAVE_EXPR)
- SAVE_EXPR_PERSISTENT_P (size) = 1;
+ if (TREE_CODE (save) == SAVE_EXPR)
+ SAVE_EXPR_PERSISTENT_P (save) = 1;
if ((*lang_hooks.decls.global_bindings_p) ())
{
}
if (immediate_size_expand)
- /* NULL_RTX is not defined; neither is the rtx type.
- Also, we would like to pass const0_rtx here, but don't have it. */
- expand_expr (size, expand_expr (integer_zero_node, NULL_RTX, VOIDmode, 0),
- VOIDmode, 0);
+ expand_expr (save, const0_rtx, VOIDmode, 0);
else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
/* The front-end doesn't want us to keep a list of the expressions
that determine sizes for variable size objects. */
;
else
- put_pending_size (size);
+ put_pending_size (save);
return size;
}
int limit;
{
if (TREE_CODE (size) != INTEGER_CST
+ || TREE_OVERFLOW (size)
/* What we really want to say here is that the size can fit in a
host integer, but we know there's no way we'd find a mode for
this many bits, so there's no point in doing the precise test. */
|| compare_tree_int (size, 1000) > 0)
return BLKmode;
else
- return mode_for_size (TREE_INT_CST_LOW (size), class, limit);
+ return mode_for_size (tree_low_cst (size, 1), class, limit);
}
/* Similar, but never return BLKmode; return the narrowest mode that
return mode;
}
+/* Return the alignment of MODE. This will be bounded by 1 and
+ BIGGEST_ALIGNMENT. */
+
+unsigned int
+get_mode_alignment (mode)
+ enum machine_mode mode;
+{
+ unsigned int alignment;
+
+ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
+ alignment = GET_MODE_UNIT_SIZE (mode);
+ else
+ alignment = GET_MODE_SIZE (mode);
+
+ /* Extract the LSB of the size. */
+ alignment = alignment & -alignment;
+ alignment *= BITS_PER_UNIT;
+
+ alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment));
+ return alignment;
+}
+
/* Return the value of VALUE, rounded up to a multiple of DIVISOR.
This can only be applied to objects of a sizetype. */
return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg);
}
\f
+/* Subroutine of layout_decl: Force alignment required for the data type.
+ But if the decl itself wants greater alignment, don't override that. */
+
+static inline void
+do_type_align (tree type, tree decl)
+{
+ if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
+ {
+ DECL_ALIGN (decl) = TYPE_ALIGN (type);
+ DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+ }
+}
+
/* Set the size, mode and alignment of a ..._DECL node.
TYPE_DECL does need this for C++.
Note that LABEL_DECL and CONST_DECL nodes do not need this,
{
tree type = TREE_TYPE (decl);
enum tree_code code = TREE_CODE (decl);
+ rtx rtl = NULL_RTX;
if (code == CONST_DECL)
return;
&& code != TYPE_DECL && code != FIELD_DECL)
abort ();
+ rtl = DECL_RTL_IF_SET (decl);
+
if (type == error_mark_node)
type = void_type_node;
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
- else
+ else if (DECL_SIZE_UNIT (decl) == 0)
DECL_SIZE_UNIT (decl)
= convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
- /* Force alignment required for the data type.
- But if the decl itself wants greater alignment, don't override that.
- Likewise, if the decl is packed, don't override it. */
- if (! (code == FIELD_DECL && DECL_BIT_FIELD (decl))
- && (DECL_ALIGN (decl) == 0
- || (! (code == FIELD_DECL && DECL_PACKED (decl))
- && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
+ if (code != FIELD_DECL)
+ /* For non-fields, update the alignment from the type. */
+ do_type_align (type, decl);
+ else
+ /* For fields, it's a bit more complicated... */
{
- DECL_ALIGN (decl) = TYPE_ALIGN (type);
- DECL_USER_ALIGN (decl) = 0;
- }
+ if (DECL_BIT_FIELD (decl))
+ {
+ DECL_BIT_FIELD_TYPE (decl) = type;
- /* For fields, set the bit field type and update the alignment. */
- if (code == FIELD_DECL)
- {
- DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
- if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ /* A zero-length bit-field affects the alignment of the next
+ field. */
+ if (integer_zerop (DECL_SIZE (decl))
+ && ! DECL_PACKED (decl)
+ && ! (*targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (decl)))
+ {
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ if (PCC_BITFIELD_TYPE_MATTERS)
+ do_type_align (type, decl);
+ else
+#endif
+ {
+#ifdef EMPTY_FIELD_BOUNDARY
+ if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
+ {
+ DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
+ DECL_USER_ALIGN (decl) = 0;
+ }
+#endif
+ }
+ }
+
+ /* See if we can use an ordinary integer mode for a bit-field.
+ Conditions are: a fixed size that is correct for another mode
+ and occupying a complete byte or bytes on proper boundary. */
+ if (TYPE_SIZE (type) != 0
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
+ {
+ enum machine_mode xmode
+ = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
+
+ if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
+ {
+ DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
+ DECL_ALIGN (decl));
+ DECL_MODE (decl) = xmode;
+ DECL_BIT_FIELD (decl) = 0;
+ }
+ }
+
+ /* Turn off DECL_BIT_FIELD if we won't need it set. */
+ if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
+ && known_align >= TYPE_ALIGN (type)
+ && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
+ DECL_BIT_FIELD (decl) = 0;
+ }
+ else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
+ /* Don't touch DECL_ALIGN. For other packed fields, go ahead and
+ round up; we'll reduce it again below. */;
+ else
+ do_type_align (type, decl);
/* If the field is of variable size, we can't misalign it since we
have no way to make a temporary to align the result. But this
isn't an issue if the decl is not addressable. Likewise if it
is of unknown size. */
- else if (DECL_PACKED (decl)
- && (DECL_NONADDRESSABLE_P (decl)
- || DECL_SIZE_UNIT (decl) == 0
- || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
- {
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
- DECL_USER_ALIGN (decl) = 0;
- }
- }
-
- /* See if we can use an ordinary integer mode for a bit-field.
- Conditions are: a fixed size that is correct for another mode
- and occupying a complete byte or bytes on proper boundary. */
- if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
- && TYPE_SIZE (type) != 0
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
- {
- enum machine_mode xmode
- = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
-
- if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
+ if (DECL_PACKED (decl)
+ && !DECL_USER_ALIGN (decl)
+ && (DECL_NONADDRESSABLE_P (decl)
+ || DECL_SIZE_UNIT (decl) == 0
+ || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
+
+ /* Should this be controlled by DECL_USER_ALIGN, too? */
+ if (maximum_field_alignment != 0)
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ if (! DECL_USER_ALIGN (decl))
{
- DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
- DECL_ALIGN (decl));
- DECL_MODE (decl) = xmode;
- DECL_BIT_FIELD (decl) = 0;
+ /* Some targets (i.e. i386, VMS) limit struct field alignment
+ to a lower boundary than alignment of variables unless
+ it was overridden by attribute aligned. */
+#ifdef BIGGEST_FIELD_ALIGNMENT
+ DECL_ALIGN (decl)
+ = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
+#endif
+#ifdef ADJUST_FIELD_ALIGN
+ DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
+#endif
}
}
- /* Turn off DECL_BIT_FIELD if we won't need it set. */
- if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
- && TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
- && known_align >= TYPE_ALIGN (type)
- && DECL_ALIGN (decl) >= TYPE_ALIGN (type)
- && DECL_SIZE_UNIT (decl) != 0)
- DECL_BIT_FIELD (decl) = 0;
-
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
if (size != 0 && TREE_CODE (size) == INTEGER_CST
&& compare_tree_int (size, larger_than_size) > 0)
{
- unsigned int size_as_int = TREE_INT_CST_LOW (size);
+ int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
warning_with_decl (decl, "size of `%s' is %d bytes", size_as_int);
larger_than_size);
}
}
+
+ /* If the RTL was already set, update its mode and mem attributes. */
+ if (rtl)
+ {
+ PUT_MODE (rtl, DECL_MODE (decl));
+ SET_DECL_RTL (decl, 0);
+ set_mem_attributes (rtl, decl, 1);
+ SET_DECL_RTL (decl, rtl);
+ }
}
\f
/* Hook for a front-end function that can modify the record layout as needed
declaration, for example) use it -- otherwise, start with a
one-byte alignment. */
rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
- rli->unpacked_align = rli->unpadded_align = rli->record_align;
+ rli->unpacked_align = rli->record_align;
rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
if (! TYPE_PACKED (t))
- rli->record_align = MAX (rli->record_align, STRUCTURE_SIZE_BOUNDARY);
+ rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
#endif
rli->offset = size_zero_node;
print_node_brief (stderr, "\noffset", rli->offset, 0);
print_node_brief (stderr, " bitpos", rli->bitpos, 0);
- fprintf (stderr, "\naligns: rec = %u, unpack = %u, unpad = %u, off = %u\n",
- rli->record_align, rli->unpacked_align, rli->unpadded_align,
+ fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
+ rli->record_align, rli->unpacked_align,
rli->offset_align);
if (rli->packed_maybe_necessary)
fprintf (stderr, "packed may be necessary\n");
tree type = TREE_TYPE (field);
/* True if the field was explicitly aligned by the user. */
bool user_align;
+ bool is_bitfield;
- /* Lay out the field so we know what alignment it needs. For a
- packed field, use the alignment as specified, disregarding what
- the type would want. */
+ /* Lay out the field so we know what alignment it needs. */
+ layout_decl (field, known_align);
desired_align = DECL_ALIGN (field);
user_align = DECL_USER_ALIGN (field);
- layout_decl (field, known_align);
- if (! DECL_PACKED (field))
- {
- desired_align = DECL_ALIGN (field);
- user_align = DECL_USER_ALIGN (field);
- }
- /* Some targets (i.e. i386, VMS) limit struct field alignment
- to a lower boundary than alignment of variables unless
- it was overridden by attribute aligned. */
-#ifdef BIGGEST_FIELD_ALIGNMENT
- if (!user_align)
- desired_align
- = MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
-#endif
-
-#ifdef ADJUST_FIELD_ALIGN
- if (!user_align)
- desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
-#endif
+ is_bitfield = (type != error_mark_node
+ && DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (TYPE_SIZE (type)));
/* 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)))
+ if (is_bitfield && (* targetm.ms_bitfield_layout_p) (rli->t))
{
/* Here, the alignment of the underlying type of a bitfield can
affect the alignment of a record; even a zero-sized field
type_align = MIN (type_align, maximum_field_alignment);
rli->record_align = MAX (rli->record_align, type_align);
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
- rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
}
- 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)))
+ else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
{
- /* A zero-length bit-field affects the alignment of the next
- field. */
- if (!DECL_PACKED (field) && integer_zerop (DECL_SIZE (field)))
- {
- desired_align = TYPE_ALIGN (type);
-#ifdef ADJUST_FIELD_ALIGN
- desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
-#endif
- }
-
/* Named bit-fields cause the entire structure to have the
alignment implied by their type. */
if (DECL_NAME (field) != 0)
rli->record_align = MAX (rli->record_align, desired_align);
rli->record_align = MAX (rli->record_align, type_align);
- rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
if (warn_packed)
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
user_align |= TYPE_USER_ALIGN (type);
}
}
- else
#endif
+ else
{
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));
}
TYPE_USER_ALIGN (rli->t) |= user_align;
DECL_SIZE_UNIT (field), rli->offset));
}
+#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
/* A bitfield of SIZE with a required access alignment of ALIGN is allocated
at BYTE_OFFSET / BIT_OFFSET. Return nonzero if the field would span more
units of alignment than the underlying TYPE. */
> ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
/ align));
}
+#endif
/* RLI contains information about the layout of a RECORD_TYPE. FIELD
is a FIELD_DECL to be added after those fields already present in
if (warn_packed && DECL_PACKED (field))
{
- if (known_align > TYPE_ALIGN (type))
+ if (known_align >= TYPE_ALIGN (type))
{
if (TYPE_ALIGN (type) > desired_align)
{
used in the record, and any additional adjacent long bitfields are
packed into the same chunk of 32 bits. However, if the size
changes, a new field of that size is allocated.) In an unpacked
- record, this is the same as using alignment, but not eqivalent
+ record, this is the same as using alignment, but not equivalent
when packing.
- Note: for compatability, we use the type size, not the type alignment
+ Note: for compatibility, we use the type size, not the type alignment
to determine alignment, since that matches the documentation */
if ((* targetm.ms_bitfield_layout_p) (rli->t)
if (DECL_BIT_FIELD_TYPE (field)
&& !integer_zerop (DECL_SIZE (field))
&& !integer_zerop (DECL_SIZE (rli->prev_field))
+ && host_integerp (DECL_SIZE (rli->prev_field), 0)
+ && host_integerp (TYPE_SIZE (type), 0)
&& simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (rli->prev_field))) )
+ TYPE_SIZE (TREE_TYPE (rli->prev_field))))
{
/* We're in the middle of a run of equal type size fields; make
sure we realign if we run out of bits. (Not decl size,
type size!) */
- int bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
- tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
+ HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
if (rli->remaining_in_alignment < bitsize)
{
/* out of bits; bump up to next 'word'. */
rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
- rli->bitpos = size_binop (PLUS_EXPR,
- type_size,
- DECL_FIELD_BIT_OFFSET(rli->prev_field));
+ rli->bitpos
+ = size_binop (PLUS_EXPR, TYPE_SIZE (type),
+ DECL_FIELD_BIT_OFFSET (rli->prev_field));
rli->prev_field = field;
- rli->remaining_in_alignment = TREE_INT_CST_LOW (type_size);
+ rli->remaining_in_alignment
+ = tree_low_cst (TYPE_SIZE (type), 0);
}
+
rli->remaining_in_alignment -= bitsize;
}
else
if (!integer_zerop (DECL_SIZE (rli->prev_field)))
{
- tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
- rli->bitpos = size_binop (PLUS_EXPR,
- type_size,
- DECL_FIELD_BIT_OFFSET(rli->prev_field));
+ tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));
+
+ rli->bitpos
+ = size_binop (PLUS_EXPR, type_size,
+ DECL_FIELD_BIT_OFFSET (rli->prev_field));
}
else
- {
- /* We "use up" size zero fields; the code below should behave
- as if the prior field was not a bitfield. */
- prev_saved = NULL;
- }
+ /* We "use up" size zero fields; the code below should behave
+ as if the prior field was not a bitfield. */
+ prev_saved = NULL;
/* Cause a new bitfield to be captured, either this time (if
currently a bitfield) or next time we see one. */
if (!DECL_BIT_FIELD_TYPE(field)
|| integer_zerop (DECL_SIZE (field)))
- {
- rli->prev_field = NULL;
- }
+ rli->prev_field = NULL;
}
+
normalize_rli (rli);
}
if (!DECL_BIT_FIELD_TYPE (field)
|| ( prev_saved != NULL
? !simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (prev_saved)))
- : !integer_zerop (DECL_SIZE (field)) ))
+ TYPE_SIZE (TREE_TYPE (prev_saved)))
+ : !integer_zerop (DECL_SIZE (field)) ))
{
- unsigned int type_align = 8; /* Never below 8 for compatability */
+ /* Never smaller than a byte for compatibility. */
+ unsigned int type_align = BITS_PER_UNIT;
/* (When not a bitfield), we could be seeing a flex array (with
no DECL_SIZE). Since we won't be using remaining_in_alignment
until we see a bitfield (and come by here again) we just skip
calculating it. */
-
- if (DECL_SIZE (field) != NULL)
- rli->remaining_in_alignment
- = TREE_INT_CST_LOW (TYPE_SIZE(TREE_TYPE(field)))
- - TREE_INT_CST_LOW (DECL_SIZE (field));
+ if (DECL_SIZE (field) != NULL
+ && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
+ && host_integerp (DECL_SIZE (field), 0))
+ rli->remaining_in_alignment
+ = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 0)
+ - tree_low_cst (DECL_SIZE (field), 0);
/* Now align (conventionally) for the new type. */
if (!DECL_PACKED(field))
- type_align = MAX(TYPE_ALIGN (type), type_align);
+ type_align = MAX(TYPE_ALIGN (type), type_align);
if (prev_saved
&& DECL_BIT_FIELD_TYPE (prev_saved)
type_align = MIN (type_align, maximum_field_alignment);
rli->bitpos = round_up (rli->bitpos, type_align);
+
/* If we really aligned, don't allow subsequent bitfields
to undo that. */
rli->prev_field = NULL;
rli->offset
= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
rli->bitpos = bitsize_zero_node;
- rli->offset_align = MIN (rli->offset_align, DECL_ALIGN (field));
+ rli->offset_align = MIN (rli->offset_align, desired_align);
}
else
{
/* Assuming that all the fields have been laid out, this function uses
RLI to compute the final TYPE_SIZE, TYPE_ALIGN, etc. for the type
- inidicated by RLI. */
+ indicated by RLI. */
static void
finalize_record_size (rli)
unpadded_size_unit
= size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
- /* Record the un-rounded size in the binfo node. But first we check
- the size of TYPE_BINFO to make sure that BINFO_SIZE is available. */
- if (TYPE_BINFO (rli->t) && TREE_VEC_LENGTH (TYPE_BINFO (rli->t)) > 6)
- {
- TYPE_BINFO_SIZE (rli->t) = unpadded_size;
- TYPE_BINFO_SIZE_UNIT (rli->t) = unpadded_size_unit;
- }
-
- /* Round the size up to be a multiple of the required alignment */
-#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, unpadded_size,
- TYPE_ALIGN (rli->t));
- TYPE_SIZE_UNIT (rli->t)
- = ROUND_TYPE_SIZE_UNIT (rli->t, unpadded_size_unit,
- TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
-#else
+ /* Round the size up to be a multiple of the required alignment */
TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
TYPE_SIZE_UNIT (rli->t) = round_up (unpadded_size_unit,
TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
-#endif
if (warn_padded && TREE_CONSTANT (unpadded_size)
&& simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
#endif
-#ifdef ROUND_TYPE_SIZE
- unpacked_size = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
- rli->unpacked_align);
-#else
unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align);
-#endif
-
if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
{
TYPE_PACKED (rli->t) = 0;
if (bitpos / BITS_PER_WORD
!= ((tree_low_cst (DECL_SIZE (field), 1) + bitpos - 1)
/ BITS_PER_WORD)
- /* But there is no problem if the field is entire words. */
- && tree_low_cst (DECL_SIZE (field), 1) % BITS_PER_WORD != 0)
+ /* But there is no problem if the field is entire words
+ or bigger than a word. */
+ && ! (tree_low_cst (DECL_SIZE (field), 1) % BITS_PER_WORD == 0
+ || compare_tree_int (DECL_SIZE (field), BITS_PER_WORD) > 0))
return;
/* If this field is the whole struct, remember its mode so
if (TYPE_SIZE (type) != 0)
{
-#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (type)
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
- TYPE_SIZE_UNIT (type)
- = ROUND_TYPE_SIZE_UNIT (type, TYPE_SIZE_UNIT (type),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
-#else
TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
TYPE_SIZE_UNIT (type)
= round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type) / BITS_PER_UNIT);
-#endif
}
/* Evaluate nonconstant sizes only once, either now or as soon as safe. */
element_size = integer_one_node;
}
+ /* If neither bound is a constant and sizetype is signed, make
+ sure the size is never negative. We should really do this
+ if *either* bound is non-constant, but this is the best
+ compromise between C and Ada. */
+ if (! TREE_UNSIGNED (sizetype)
+ && TREE_CODE (TYPE_MIN_VALUE (index)) != INTEGER_CST
+ && TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
+ length = size_binop (MAX_EXPR, length, size_zero_node);
+
TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
convert (bitsizetype, length));
TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
#endif
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
-
-#ifdef ROUND_TYPE_SIZE
- if (TYPE_SIZE (type) != 0)
- {
- tree tmp
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
-
- /* If the rounding changed the size of the type, remove any
- pre-calculated TYPE_SIZE_UNIT. */
- if (simple_cst_equal (TYPE_SIZE (type), tmp) != 1)
- TYPE_SIZE_UNIT (type) = NULL;
-
- TYPE_SIZE (type) = tmp;
- }
-#endif
-
TYPE_MODE (type) = BLKmode;
if (TYPE_SIZE (type) != 0
#ifdef MEMBER_TYPE_FORCES_BLK
#endif
unsigned int alignment
= set_alignment ? set_alignment : SET_WORD_SIZE;
- int size_in_bits
- = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1);
- int rounded_size
+ HOST_WIDE_INT size_in_bits
+ = (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+ - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1);
+ HOST_WIDE_INT rounded_size
= ((size_in_bits + alignment - 1) / alignment) * alignment;
if (rounded_size > (int) alignment)