unsigned int set_alignment = 0;
static void finalize_record_size PARAMS ((record_layout_info));
-static void compute_record_mode PARAMS ((tree));
static void finalize_type_size PARAMS ((tree));
static void place_union_field PARAMS ((record_layout_info, tree));
+extern void debug_rli PARAMS ((record_layout_info));
\f
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
&& (DECL_ALIGN (decl) == 0
|| (! (code == FIELD_DECL && DECL_PACKED (decl))
&& TYPE_ALIGN (type) > DECL_ALIGN (decl))))
- DECL_ALIGN (decl) = TYPE_ALIGN (type);
+ {
+ DECL_ALIGN (decl) = TYPE_ALIGN (type);
+ DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+ }
/* For fields, set the bit field type and update the alignment. */
if (code == FIELD_DECL)
if (maximum_field_alignment != 0)
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
else if (DECL_PACKED (decl))
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
+ {
+ 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.
tree t;
{
record_layout_info rli
- = (record_layout_info) xmalloc (sizeof (struct record_layout_info));
+ = (record_layout_info) xmalloc (sizeof (struct record_layout_info_s));
rli->t = t;
record_layout_info rli;
tree field;
{
+ unsigned int desired_align;
+
layout_decl (field, 0);
DECL_FIELD_OFFSET (field) = size_zero_node;
DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
- DECL_OFFSET_ALIGN (field) = BIGGEST_ALIGNMENT;
+ SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
+
+ desired_align = DECL_ALIGN (field);
+
+#ifdef BIGGEST_FIELD_ALIGNMENT
+ /* Some targets (i.e. i386) limit union field alignment
+ to a lower boundary than alignment of variables unless
+ it was overridden by attribute aligned. */
+ if (! DECL_USER_ALIGN (field))
+ desired_align =
+ MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
+#endif
/* Union must be at least as aligned as any field requires. */
- rli->record_align = MAX (rli->record_align, DECL_ALIGN (field));
+ rli->record_align = MAX (rli->record_align, desired_align);
#ifdef PCC_BITFIELD_TYPE_MATTERS
/* On the m88000, a bit field of declare type `int' forces the
record as it presently stands. */
unsigned int known_align;
unsigned int actual_align;
+ unsigned int user_align;
/* The type of this field. */
tree type = TREE_TYPE (field);
+ if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
+ return;
+
/* If FIELD is static, then treat it like a separate variable, not
really like a structure field. If it is a FUNCTION_DECL, it's a
method. In both cases, all we do is lay out the decl, and we do
packed field, use the alignment as specified, disregarding what
the type would want. */
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);
+ {
+ desired_align = DECL_ALIGN (field);
+ user_align = DECL_USER_ALIGN (field);
+ }
- /* Some targets (i.e. VMS) limit struct field alignment
- to a lower boundary than alignment of variables. */
#ifdef BIGGEST_FIELD_ALIGNMENT
- desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
+ /* 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. */
+ if (! user_align)
+ desired_align =
+ MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
#endif
#ifdef ADJUST_FIELD_ALIGN
desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
&& ! DECL_PACKED (field)
&& ! integer_zerop (DECL_SIZE (field))
&& host_integerp (DECL_SIZE (field), 1)
- && host_integerp (rli->size, 1)
+ && host_integerp (rli->offset, 1)
&& host_integerp (TYPE_SIZE (type), 1))
{
unsigned int type_align = TYPE_ALIGN (type);
normalize_rli (rli);
DECL_FIELD_OFFSET (field) = rli->offset;
DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
- DECL_OFFSET_ALIGN (field) = rli->offset_align;
+ SET_DECL_OFFSET_ALIGN (field, rli->offset_align);
/* If this field ended up more aligned than we thought it would be (we
approximate this by seeing if its position changed), lay out the field
{
tree unpadded_size, unpadded_size_unit;
- /* Next move any full bytes of bits into the byte size. */
- rli->offset
- = size_binop (PLUS_EXPR, rli->offset,
- convert (sizetype,
- size_binop (TRUNC_DIV_EXPR, rli->bitpos,
- bitsize_unit_node)));
- rli->bitpos = size_binop (TRUNC_MOD_EXPR, rli->bitpos, bitsize_unit_node);
+ /* Now we want just byte and bit offsets, so set the offset alignment
+ to be a byte and then normalize. */
+ rli->offset_align = BITS_PER_UNIT;
+ normalize_rli (rli);
/* Determine the desired alignment. */
#ifdef ROUND_TYPE_ALIGN
#else
TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
#endif
+ TYPE_USER_ALIGN (rli->t) = 1;
- unpadded_size
- = size_binop (PLUS_EXPR, rli->bitpos,
- size_binop (MULT_EXPR, convert (bitsizetype, rli->offset),
- bitsize_unit_node));
-
- unpadded_size_unit
- = size_binop (PLUS_EXPR, rli->offset,
- convert (sizetype,
- size_binop (CEIL_DIV_EXPR, rli->bitpos,
- bitsize_unit_node)));
+ /* Compute the size so far. Be sure to allow for extra bits in the
+ size in bytes. We have guaranteed above that it will be no more
+ than a single byte. */
+ unpadded_size = rli_size_so_far (rli);
+ unpadded_size_unit = rli_size_unit_so_far (rli);
+ if (! integer_zerop (rli->bitpos))
+ 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. */
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, unpaded_size_unit,
+ = ROUND_TYPE_SIZE_UNIT (rli->t, unpadded_size_unit,
TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
#else
TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
if (TYPE_NAME (rli->t))
{
- char *name;
+ const char *name;
if (TREE_CODE (TYPE_NAME (rli->t)) == IDENTIFIER_NODE)
name = IDENTIFIER_POINTER (TYPE_NAME (rli->t));
/* Compute the TYPE_MODE for the TYPE (which is a RECORD_TYPE). */
-static void
+void
compute_record_mode (type)
tree type;
{
/* Must be BLKmode if any field crosses a word boundary,
since extract_bit_field can't handle that in registers. */
if (bitpos / BITS_PER_WORD
- != ((TREE_INT_CST_LOW (DECL_SIZE (field)) + bitpos - 1)
+ != ((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)
/* If this field is the whole struct, remember its mode so
that, say, we can put a double in a class into a DF
register instead of forcing it to live in the stack. */
- if (field == TYPE_FIELDS (type) && TREE_CHAIN (field) == 0)
+ if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
mode = DECL_MODE (field);
#ifdef STRUCT_FORCE_BLK
#endif /* STRUCT_FORCE_BLK */
}
- if (mode != VOIDmode)
- /* We only have one real field; use its mode. */
+ /* If we only have one real field; use its mode. This only applies to
+ RECORD_TYPE. This does not apply to unions. */
+ if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode)
TYPE_MODE (type) = mode;
else
TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
|| (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE
&& TREE_CODE (type) != QUAL_UNION_TYPE
&& TREE_CODE (type) != ARRAY_TYPE)))
- TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+ {
+ TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
+ TYPE_USER_ALIGN (type) = 0;
+ }
/* Do machine-dependent extra alignment. */
#ifdef ROUND_TYPE_ALIGN
tree size = TYPE_SIZE (type);
tree size_unit = TYPE_SIZE_UNIT (type);
unsigned int align = TYPE_ALIGN (type);
+ unsigned int user_align = TYPE_USER_ALIGN (type);
enum machine_mode mode = TYPE_MODE (type);
/* Copy it into all variants. */
TYPE_SIZE (variant) = size;
TYPE_SIZE_UNIT (variant) = size_unit;
TYPE_ALIGN (variant) = align;
+ TYPE_USER_ALIGN (variant) = user_align;
TYPE_MODE (variant) = mode;
}
}
/* Compute the TYPE_MODE for the record. */
compute_record_mode (rli->t);
+ /* Perform any last tweaks to the TYPE_SIZE, etc. */
+ finalize_type_size (rli->t);
+
/* Lay out any static members. This is done now because their type
may use the record's type. */
while (rli->pending_statics)
rli->pending_statics = TREE_CHAIN (rli->pending_statics);
}
- /* Perform any last tweaks to the TYPE_SIZE, etc. */
- finalize_type_size (rli->t);
-
/* Clean up. */
free (rli);
}
layout_type (type)
tree type;
{
- int old;
-
if (type == 0)
abort ();
if (TYPE_SIZE (type))
return;
- /* Make sure all nodes we allocate are not momentary; they must last
- past the current statement. */
- old = suspend_momentary ();
-
- /* Put all our nodes into the same obstack as the type. Also,
- make expressions saveable (this is a no-op for permanent types). */
-
- push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type));
- saveable_allocation ();
-
switch (TREE_CODE (type))
{
case LANG_TYPE:
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
+ case VECTOR_TYPE:
+ {
+ tree subtype;
+
+ subtype = TREE_TYPE (type);
+ TREE_UNSIGNED (type) = TREE_UNSIGNED (subtype);
+ TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
+ TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
+ }
+ break;
+
case VOID_TYPE:
/* This is an incomplete type and so doesn't have a size. */
TYPE_ALIGN (type) = 1;
+ TYPE_USER_ALIGN (type) = 0;
TYPE_MODE (type) = VOIDmode;
break;
tree length;
tree element_size;
- /* If UB is max (lb - 1, x), remove the MAX_EXPR since the
- test for negative below covers it. */
- if (TREE_CODE (ub) == MAX_EXPR
- && TREE_CODE (TREE_OPERAND (ub, 0)) == MINUS_EXPR
- && integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 0), 1))
- && operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 0), 0),
- lb, 0))
- ub = TREE_OPERAND (ub, 1);
- else if (TREE_CODE (ub) == MAX_EXPR
- && TREE_CODE (TREE_OPERAND (ub, 1)) == MINUS_EXPR
- && integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 1), 1))
- && operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 1),
- 0),
- lb, 0))
- ub = TREE_OPERAND (ub, 0);
-
/* The initial subtraction should happen in the original type so
that (possible) negative values are handled appropriately. */
length = size_binop (PLUS_EXPR, size_one_node,
TREE_TYPE (lb),
ub, lb))));
- /* 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);
-
/* Special handling for arrays of bits (for Chill). */
element_size = TYPE_SIZE (element);
- if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element))
+ if (TYPE_PACKED (type) && INTEGRAL_TYPE_P (element)
+ && (integer_zerop (TYPE_MAX_VALUE (element))
+ || integer_onep (TYPE_MAX_VALUE (element)))
+ && host_integerp (TYPE_MIN_VALUE (element), 1))
{
HOST_WIDE_INT maxvalue
- = TREE_INT_CST_LOW (TYPE_MAX_VALUE (element));
+ = tree_low_cst (TYPE_MAX_VALUE (element), 1);
HOST_WIDE_INT minvalue
- = TREE_INT_CST_LOW (TYPE_MIN_VALUE (element));
+ = tree_low_cst (TYPE_MIN_VALUE (element), 1);
if (maxvalue - minvalue == 1
&& (maxvalue == 1 || maxvalue == 0))
TYPE_SIZE (type) = bitsize_int (rounded_size);
TYPE_SIZE_UNIT (type) = size_int (rounded_size / BITS_PER_UNIT);
TYPE_ALIGN (type) = alignment;
+ TYPE_USER_ALIGN (type) = 0;
TYPE_PRECISION (type) = size_in_bits;
}
break;
/* The size may vary in different languages, so the language front end
should fill in the size. */
TYPE_ALIGN (type) = BIGGEST_ALIGNMENT;
+ TYPE_USER_ALIGN (type) = 0;
TYPE_MODE (type) = BLKmode;
break;
&& TREE_CODE (type) != QUAL_UNION_TYPE)
finalize_type_size (type);
- pop_obstacks ();
- resume_momentary (old);
-
/* If this type is created before sizetype has been permanently set,
record it so set_sizetype can fix it up. */
if (! sizetype_set)
early_type_list = tree_cons (NULL_TREE, type, early_type_list);
+
+ /* If an alias set has been set for this aggregate when it was incomplete,
+ force it into alias set 0.
+ This is too conservative, but we cannot call record_component_aliases
+ here because some frontends still change the aggregates after
+ layout_type. */
+ if (AGGREGATE_TYPE_P (type) && TYPE_ALIAS_SET_KNOWN_P (type))
+ TYPE_ALIAS_SET (type) = 0;
}
\f
/* Create and return a type for signed integers of PRECISION bits. */
TYPE_MODE (t) = SImode;
TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode);
+ TYPE_USER_ALIGN (t) = 0;
TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0);
TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0);
TREE_UNSIGNED (t) = 1;
TYPE_NAME (bitsizetype) = get_identifier ("bit_size_type");
/* Show is a sizetype, is a main type, and has no pointers to it. */
- for (i = 0; i < sizeof sizetype_tab / sizeof sizetype_tab[0]; i++)
+ for (i = 0; i < ARRAY_SIZE (sizetype_tab); i++)
{
TYPE_IS_SIZETYPE (sizetype_tab[i]) = 1;
TYPE_MAIN_VARIANT (sizetype_tab[i]) = sizetype_tab[i];