/* C-compiler utilities for types and variables storage layout
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1996, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GCC.
{
DECL_SIZE (decl) = DECL_SIZE_UNIT (decl) = 0;
DECL_MODE (decl) = VOIDmode;
- DECL_ALIGN (decl) = 0;
+ if (!DECL_USER_ALIGN (decl))
+ DECL_ALIGN (decl) = 0;
SET_DECL_RTL (decl, 0);
layout_decl (decl, 0);
#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
if (! TYPE_PACKED (t))
- rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
+ {
+ unsigned tmp;
+
+ /* #pragma pack overrides STRUCTURE_SIZE_BOUNDARY. */
+ tmp = (unsigned) STRUCTURE_SIZE_BOUNDARY;
+ if (maximum_field_alignment != 0)
+ tmp = MIN (tmp, maximum_field_alignment);
+ rli->record_align = MAX (rli->record_align, tmp);
+ }
#endif
rli->offset = size_zero_node;
if (targetm.ms_bitfield_layout_p (rli->t))
{
tree prev_saved = rli->prev_field;
+ tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;
/* This is a bitfield if it exists. */
if (rli->prev_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))))
+ && simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type)))
{
/* 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,
if (rli->remaining_in_alignment < bitsize)
{
+ HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+
/* out of bits; bump up to next 'word'. */
- rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
rli->bitpos
- = size_binop (PLUS_EXPR, TYPE_SIZE (type),
- DECL_FIELD_BIT_OFFSET (rli->prev_field));
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
rli->prev_field = field;
- rli->remaining_in_alignment
- = tree_low_cst (TYPE_SIZE (type), 1);
+ if (typesize < bitsize)
+ rli->remaining_in_alignment = 0;
+ else
+ rli->remaining_in_alignment = typesize - bitsize;
}
-
- rli->remaining_in_alignment -= bitsize;
+ else
+ rli->remaining_in_alignment -= bitsize;
}
else
{
Note: since the beginning of the field was aligned then
of course the end will be too. No round needed. */
- if (!integer_zerop (DECL_SIZE (rli->prev_field))
- && rli->remaining_in_alignment)
+ if (!integer_zerop (DECL_SIZE (rli->prev_field)))
{
rli->bitpos
= size_binop (PLUS_EXPR, rli->bitpos,
/* 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)))
+ || integer_zerop (DECL_SIZE (field)))
rli->prev_field = NULL;
}
there wasn't. */
if (!DECL_BIT_FIELD_TYPE (field)
- || ( prev_saved != NULL
- ? !simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (prev_saved)))
+ || (prev_saved != NULL
+ ? !simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (prev_type))
: !integer_zerop (DECL_SIZE (field)) ))
{
/* Never smaller than a byte for compatibility. */
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)), 1)
- - tree_low_cst (DECL_SIZE (field), 1);
+ {
+ HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
+ HOST_WIDE_INT typesize
+ = tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 1);
+
+ if (typesize < bitsize)
+ rli->remaining_in_alignment = 0;
+ else
+ rli->remaining_in_alignment = typesize - bitsize;
+ }
/* Now align (conventionally) for the new type. */
type_align = TYPE_ALIGN (TREE_TYPE (field));
if (DECL_SIZE (field) == 0)
/* Do nothing. */;
else if (TREE_CODE (DECL_SIZE (field)) != INTEGER_CST
- || TREE_CONSTANT_OVERFLOW (DECL_SIZE (field)))
+ || TREE_OVERFLOW (DECL_SIZE (field)))
{
rli->offset
= size_binop (PLUS_EXPR, rli->offset,
void
finish_record_layout (record_layout_info rli, int free_p)
{
+ tree variant;
+
/* Compute the final size. */
finalize_record_size (rli);
/* Perform any last tweaks to the TYPE_SIZE, etc. */
finalize_type_size (rli->t);
+ /* Propagate TYPE_PACKED to variants. With C++ templates,
+ handle_packed_attribute is too early to do this. */
+ for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
+ variant = TYPE_NEXT_VARIANT (variant))
+ TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+
/* Lay out any static members. This is done now because their type
may use the record's type. */
while (rli->pending_statics)
case VECTOR_TYPE:
{
int nunits = TYPE_VECTOR_SUBPARTS (type);
- tree nunits_tree = build_int_cst (NULL_TREE, nunits);
tree innertype = TREE_TYPE (type);
gcc_assert (!(nunits & (nunits - 1)));
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
TYPE_SIZE_UNIT (innertype),
- nunits_tree, 0);
+ size_int (nunits), 0);
TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
- nunits_tree, 0);
+ bitsize_int (nunits), 0);
/* Always naturally align vectors. This prevents ABI changes
depending on whether or not native vector modes are supported. */
#else
TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
#endif
+ if (!TYPE_SIZE (element))
+ /* We don't know the size of the underlying element type, so
+ our alignment calculations will be wrong, forcing us to
+ fall back on structural equality. */
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
TYPE_MODE (type) = BLKmode;
if (TYPE_SIZE (type) != 0
&& TREE_CODE (TYPE_SIZE_UNIT (element)) == INTEGER_CST
/* If TYPE_SIZE_UNIT overflowed, then it is certainly larger than
TYPE_ALIGN_UNIT. */
- && !TREE_CONSTANT_OVERFLOW (TYPE_SIZE_UNIT (element))
+ && !TREE_OVERFLOW (TYPE_SIZE_UNIT (element))
&& !integer_zerop (TYPE_SIZE_UNIT (element))
&& compare_tree_int (TYPE_SIZE_UNIT (element),
TYPE_ALIGN_UNIT (element)) < 0)
calculating signed sizes / offsets in bits. However, when
cross-compiling from a 32 bit to a 64 bit host, we are limited to 64 bit
precision. */
- int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
+ int precision = MIN (MIN (oprecision + BITS_PER_UNIT_LOG + 1,
+ MAX_FIXED_MODE_SIZE),
2 * HOST_BITS_PER_WIDE_INT);
tree t;
orig_max = TYPE_MAX_VALUE (sizetype);
- /* Build a new node with the same values, but a different type. */
- new_max = build_int_cst_wide (sizetype,
- TREE_INT_CST_LOW (orig_max),
- TREE_INT_CST_HIGH (orig_max));
-
- /* Now sign extend it using force_fit_type to ensure
- consistency. */
- new_max = force_fit_type (new_max, 0, 0, 0);
+ /* Build a new node with the same values, but a different type.
+ Sign extend it to ensure consistency. */
+ new_max = build_int_cst_wide_type (sizetype,
+ TREE_INT_CST_LOW (orig_max),
+ TREE_INT_CST_HIGH (orig_max));
TYPE_MAX_VALUE (sizetype) = new_max;
}
}
return VOIDmode;
if ((SLOW_BYTE_ACCESS && ! volatilep)
- || (volatilep && !targetm.narrow_volatile_bitfield()))
+ || (volatilep && !targetm.narrow_volatile_bitfield ()))
{
enum machine_mode wide_mode = VOIDmode, tmode;