/* 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.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
/* Similar, except passed a tree node. */
enum machine_mode
-mode_for_size_tree (tree size, enum mode_class class, int limit)
+mode_for_size_tree (const_tree size, enum mode_class class, int limit)
{
unsigned HOST_WIDE_INT uhwi;
unsigned int ui;
case MODE_DECIMAL_FLOAT:
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
+ case MODE_FRACT:
+ case MODE_ACCUM:
+ case MODE_UFRACT:
+ case MODE_UACCUM:
+ case MODE_VECTOR_FRACT:
+ case MODE_VECTOR_ACCUM:
+ case MODE_VECTOR_UFRACT:
+ case MODE_VECTOR_UACCUM:
mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
break;
if (code == CONST_DECL)
return;
-
+
gcc_assert (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL
|| code == TYPE_DECL ||code == FIELD_DECL);
-
+
rtl = DECL_RTL_IF_SET (decl);
if (type == error_mark_node)
{
enum machine_mode xmode
= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
+ unsigned int xalign = GET_MODE_ALIGNMENT (xmode);
if (xmode != BLKmode
- && (known_align == 0
- || known_align >= GET_MODE_ALIGNMENT (xmode)))
+ && !(xalign > BITS_PER_UNIT && DECL_PACKED (decl))
+ && (known_align == 0 || known_align >= xalign))
{
- DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
- DECL_ALIGN (decl));
+ DECL_ALIGN (decl) = MAX (xalign, DECL_ALIGN (decl));
DECL_MODE (decl) = xmode;
DECL_BIT_FIELD (decl) = 0;
}
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.
-
- Note that do_type_align may set DECL_USER_ALIGN, so we need to
- check old_user_align instead. */
+ /* If the field is packed and not explicitly aligned, give it the
+ minimum alignment. Note that do_type_align may set
+ DECL_USER_ALIGN, so we need to check old_user_align instead. */
if (packed_p
- && !old_user_align
- && (DECL_NONADDRESSABLE_P (decl)
- || DECL_SIZE_UNIT (decl) == 0
- || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
+ && !old_user_align)
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
if (! packed_p && ! DECL_USER_ALIGN (decl))
int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
- warning (0, "size of %q+D is %d bytes", decl, size_as_int);
+ warning (OPT_Wlarger_than_eq, "size of %q+D is %d bytes", decl, size_as_int);
else
- warning (0, "size of %q+D is larger than %wd bytes",
+ warning (OPT_Wlarger_than_eq, "size of %q+D is larger than %wd bytes",
decl, larger_than_size);
}
}
{
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);
}
\f
-/* Hook for a front-end function that can modify the record layout as needed
- immediately before it is finalized. */
-
-static void (*lang_adjust_rli) (record_layout_info) = 0;
-
-void
-set_lang_adjust_rli (void (*f) (record_layout_info))
-{
- lang_adjust_rli = f;
-}
-
/* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or
QUAL_UNION_TYPE. Return a pointer to a struct record_layout_info which
is to be passed to all other layout functions for this record. It is the
#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;
rli->prev_field = 0;
rli->pending_statics = 0;
rli->packed_maybe_necessary = 0;
+ rli->remaining_in_alignment = 0;
return rli;
}
bit_from_pos (tree offset, tree bitpos)
{
return size_binop (PLUS_EXPR, bitpos,
- size_binop (MULT_EXPR,
+ size_binop (MULT_EXPR,
fold_convert (bitsizetype, offset),
bitsize_unit_node));
}
*poffset
= size_binop (PLUS_EXPR, *poffset,
- size_binop (MULT_EXPR,
+ size_binop (MULT_EXPR,
fold_convert (sizetype, extra_aligns),
size_int (off_align / BITS_PER_UNIT)));
fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
rli->record_align, rli->unpacked_align,
rli->offset_align);
+
+ /* The ms_struct code is the only that uses this. */
+ if (targetm.ms_bitfield_layout_p (rli->t))
+ fprintf (stderr, "remaining in alignment = %u\n", rli->remaining_in_alignment);
+
if (rli->packed_maybe_necessary)
fprintf (stderr, "packed may be necessary\n");
/* Record must have at least as much alignment as any field.
Otherwise, the alignment of the field within the record is
meaningless. */
- if (is_bitfield && targetm.ms_bitfield_layout_p (rli->t))
+ if (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
the type, except that for zero-size bitfields this only
applies if there was an immediately prior, nonzero-size
bitfield. (That's the way it is, experimentally.) */
- if (! integer_zerop (DECL_SIZE (field))
- ? ! DECL_PACKED (field)
- : (rli->prev_field
- && DECL_BIT_FIELD_TYPE (rli->prev_field)
- && ! integer_zerop (DECL_SIZE (rli->prev_field))))
+ if ((!is_bitfield && !DECL_PACKED (field))
+ || (!integer_zerop (DECL_SIZE (field))
+ ? !DECL_PACKED (field)
+ : (rli->prev_field
+ && DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && ! integer_zerop (DECL_SIZE (rli->prev_field)))))
{
unsigned int type_align = TYPE_ALIGN (type);
type_align = MAX (type_align, desired_align);
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));
- /* If we start a new run, make sure we start it properly aligned. */
- if ((!rli->prev_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)))
- || (rli->remaining_in_alignment
- < tree_low_cst (DECL_SIZE (field), 0)))
- && desired_align < type_align)
- desired_align = type_align;
}
}
#ifdef PCC_BITFIELD_TYPE_MATTERS
DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
- /* If this is an ERROR_MARK return *after* having set the
+ /* If this is an ERROR_MARK return *after* having set the
field at the start of the union. This helps when parsing
invalid fields. */
if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK)
return;
}
- else if (TREE_CODE (type) == ERROR_MARK)
+ else if (TREE_CODE (type) == ERROR_MARK)
{
/* Place this field at the current allocation position, so we
maintain monotonicity. */
}
/* Does this field automatically have alignment it needs by virtue
- of the fields that precede it and the record's own alignment? */
- if (known_align < desired_align)
+ of the fields that precede it and the record's own alignment?
+ We already align ms_struct fields, so don't re-align them. */
+ if (known_align < desired_align
+ && !targetm.ms_bitfield_layout_p (rli->t))
{
/* No, we need to skip space before this field.
Bump the cumulative size to multiple of field 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)
- && ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
- || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
+ if (targetm.ms_bitfield_layout_p (rli->t))
{
- /* At this point, either the prior or current are bitfields,
- (possibly both), and we're dealing with MS packing. */
tree prev_saved = rli->prev_field;
+ tree prev_type = prev_saved ? DECL_BIT_FIELD_TYPE (prev_saved) : NULL;
- /* Is the prior field a bitfield? If so, handle "runs" of same
- type size fields. */
- if (rli->prev_field /* necessarily a bitfield if it exists. */)
+ /* This is a bitfield if it exists. */
+ if (rli->prev_field)
{
/* If both are bitfields, nonzero, and the same size, this is
the middle of a run. Zero declared size fields are special
&& !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,
type size!) */
- HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
+ HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 1);
if (rli->remaining_in_alignment < bitsize)
{
- /* If PREV_FIELD is packed, and we haven't lumped
- non-packed bitfields with it, treat this as if PREV_FIELD
- was not a bitfield. This avoids anomalies where a packed
- bitfield with long long base type can take up more
- space than a same-size bitfield with base type short. */
- if (rli->prev_packed)
- rli->prev_field = prev_saved = NULL;
+ HOST_WIDE_INT typesize = tree_low_cst (TYPE_SIZE (type), 1);
+
+ /* out of bits; bump up to next 'word'. */
+ rli->bitpos
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
+ rli->prev_field = field;
+ if (typesize < bitsize)
+ rli->remaining_in_alignment = 0;
else
- {
- /* 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));
- rli->prev_field = field;
- rli->remaining_in_alignment
- = tree_low_cst (TYPE_SIZE (type), 0) - bitsize;
- }
+ rli->remaining_in_alignment = typesize - bitsize;
}
else
rli->remaining_in_alignment -= bitsize;
}
- else if (rli->prev_packed)
- rli->prev_field = prev_saved = NULL;
else
{
/* End of a run: if leaving a run of bitfields of the same type
if (!integer_zerop (DECL_SIZE (rli->prev_field)))
{
- tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));
-
- /* If the desired alignment is greater or equal to TYPE_SIZE,
- we have already adjusted rli->bitpos / rli->offset above.
- */
- if ((unsigned HOST_WIDE_INT) tree_low_cst (type_size, 0)
- > desired_align)
- rli->bitpos
- = size_binop (PLUS_EXPR, type_size,
- DECL_FIELD_BIT_OFFSET (rli->prev_field));
+ rli->bitpos
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
}
else
/* We "use up" size zero fields; the code below should behave
/* 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;
}
- rli->prev_packed = 0;
normalize_rli (rli);
}
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)), 0)
- - tree_low_cst (DECL_SIZE (field), 0);
+ {
+ 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. */
- if (!DECL_PACKED(field))
- type_align = MAX(TYPE_ALIGN (type), type_align);
-
- if (prev_saved
- && DECL_BIT_FIELD_TYPE (prev_saved)
- /* 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 (prev_saved)))
- type_align = MAX (type_align,
- TYPE_ALIGN (TREE_TYPE (prev_saved)));
+ type_align = TYPE_ALIGN (TREE_TYPE (field));
if (maximum_field_alignment != 0)
type_align = MIN (type_align, maximum_field_alignment);
if (known_align != actual_align)
layout_decl (field, actual_align);
- if (DECL_BIT_FIELD_TYPE (field))
- {
- unsigned int type_align = TYPE_ALIGN (type);
- unsigned int mfa = maximum_field_alignment;
-
- if (integer_zerop (DECL_SIZE (field)))
- mfa = initial_max_fld_align * BITS_PER_UNIT;
-
- /* Only the MS bitfields use this. We used to also put any kind of
- packed bit fields into prev_field, but that makes no sense, because
- an 8 bit packed bit field shouldn't impose more restriction on
- following fields than a char field, and the alignment requirements
- are also not fulfilled.
- There is no sane value to set rli->remaining_in_alignment to when
- a packed bitfield in prev_field is unaligned. */
- if (mfa != 0)
- type_align = MIN (type_align, mfa);
- gcc_assert (rli->prev_field
- || actual_align >= type_align || DECL_PACKED (field)
- || integer_zerop (DECL_SIZE (field))
- || !targetm.ms_bitfield_layout_p (rli->t));
- if (rli->prev_field == NULL && actual_align >= type_align
- && !integer_zerop (DECL_SIZE (field)))
- {
- rli->prev_field = field;
- /* rli->remaining_in_alignment has not been set if the bitfield
- has size zero, or if it is a packed bitfield. */
- rli->remaining_in_alignment
- = (tree_low_cst (TYPE_SIZE (TREE_TYPE (field)), 0)
- - tree_low_cst (DECL_SIZE (field), 0));
- rli->prev_packed = DECL_PACKED (field);
-
- }
- else if (rli->prev_field && DECL_PACKED (field))
- {
- HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
-
- if (rli->remaining_in_alignment < bitsize)
- rli->prev_field = NULL;
- else
- rli->remaining_in_alignment -= bitsize;
- }
- }
+ if (rli->prev_field == NULL && DECL_BIT_FIELD_TYPE (field))
+ 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
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,
rli->bitpos = bitsize_zero_node;
rli->offset_align = MIN (rli->offset_align, desired_align);
}
+ else if (targetm.ms_bitfield_layout_p (rli->t))
+ {
+ rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
+
+ /* If we ended a bitfield before the full length of the type then
+ pad the struct out to the full length of the last type. */
+ if ((TREE_CHAIN (field) == NULL
+ || TREE_CODE (TREE_CHAIN (field)) != FIELD_DECL)
+ && DECL_BIT_FIELD_TYPE (field)
+ && !integer_zerop (DECL_SIZE (field)))
+ rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (rli->remaining_in_alignment));
+
+ normalize_rli (rli);
+ }
else
{
rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
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)
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
+ case FIXED_POINT_TYPE:
+ /* TYPE_MODE (type) has been set already. */
+ 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 COMPLEX_TYPE:
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
TYPE_MODE (type)
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)));
/* First, look for a supported vector type. */
if (SCALAR_FLOAT_MODE_P (innermode))
mode = MIN_MODE_VECTOR_FLOAT;
+ else if (SCALAR_FRACT_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_FRACT;
+ else if (SCALAR_UFRACT_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_UFRACT;
+ else if (SCALAR_ACCUM_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_ACCUM;
+ else if (SCALAR_UACCUM_MODE_P (innermode))
+ mode = MIN_MODE_VECTOR_UACCUM;
else
mode = MIN_MODE_VECTOR_INT;
TYPE_MODE (type) = mode;
}
+ TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
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. */
length = size_binop (MAX_EXPR, length, size_zero_node);
TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
- fold_convert (bitsizetype,
+ fold_convert (bitsizetype,
length));
/* If we know the size of the element, calculate the total
#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
if (TYPE_MODE (type) != BLKmode
&& STRICT_ALIGNMENT && TYPE_ALIGN (type) < BIGGEST_ALIGNMENT
- && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type))
- && TYPE_MODE (type) != BLKmode)
+ && TYPE_ALIGN (type) < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
{
TYPE_NO_FORCE_BLK (type) = 1;
TYPE_MODE (type) = BLKmode;
&& 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)
if (TREE_CODE (type) == QUAL_UNION_TYPE)
TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
- if (lang_adjust_rli)
- (*lang_adjust_rli) (rli);
-
/* Finish laying out the record. */
finish_record_layout (rli, /*free_p=*/true);
}
&& TREE_CODE (type) != QUAL_UNION_TYPE)
finalize_type_size (type);
- /* 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;
+ /* We should never see alias sets on incomplete aggregates. And we
+ should not call layout_type on not incomplete aggregates. */
+ if (AGGREGATE_TYPE_P (type))
+ gcc_assert (!TYPE_ALIAS_SET_KNOWN_P (type));
}
\f
/* Create and return a type for signed integers of PRECISION bits. */
return type;
}
\f
+/* Create and return a type for fract of PRECISION bits, UNSIGNEDP,
+ and SATP. */
+
+tree
+make_fract_type (int precision, int unsignedp, int satp)
+{
+ tree type = make_node (FIXED_POINT_TYPE);
+
+ TYPE_PRECISION (type) = precision;
+
+ if (satp)
+ TYPE_SATURATING (type) = 1;
+
+ /* Lay out the type: set its alignment, size, etc. */
+ if (unsignedp)
+ {
+ TYPE_UNSIGNED (type) = 1;
+ TYPE_MODE (type) = mode_for_size (precision, MODE_UFRACT, 0);
+ }
+ else
+ TYPE_MODE (type) = mode_for_size (precision, MODE_FRACT, 0);
+ layout_type (type);
+
+ return type;
+}
+
+/* Create and return a type for accum of PRECISION bits, UNSIGNEDP,
+ and SATP. */
+
+tree
+make_accum_type (int precision, int unsignedp, int satp)
+{
+ tree type = make_node (FIXED_POINT_TYPE);
+
+ TYPE_PRECISION (type) = precision;
+
+ if (satp)
+ TYPE_SATURATING (type) = 1;
+
+ /* Lay out the type: set its alignment, size, etc. */
+ if (unsignedp)
+ {
+ TYPE_UNSIGNED (type) = 1;
+ TYPE_MODE (type) = mode_for_size (precision, MODE_UACCUM, 0);
+ }
+ else
+ TYPE_MODE (type) = mode_for_size (precision, MODE_ACCUM, 0);
+ layout_type (type);
+
+ return type;
+}
+
/* Initialize sizetype and bitsizetype to a reasonable and temporary
value to enable integer types to be created. */
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;
TREE_TYPE (TYPE_CACHED_VALUES (t)) = type;
TYPE_UID (t) = TYPE_UID (sizetype);
TYPE_IS_SIZETYPE (t) = 1;
-
+
/* Replace our original stub sizetype. */
memcpy (sizetype, t, tree_size (sizetype));
TYPE_MAIN_VARIANT (sizetype) = sizetype;
-
+
t = make_node (INTEGER_TYPE);
TYPE_NAME (t) = get_identifier ("bit_size_type");
/* We do want to use bitsizetype's cache, as we will be replacing that
/* Replace our original stub bitsizetype. */
memcpy (bitsizetype, t, tree_size (bitsizetype));
TYPE_MAIN_VARIANT (bitsizetype) = bitsizetype;
-
+
if (TYPE_UNSIGNED (type))
{
fixup_unsigned_type (bitsizetype);
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;
}
}
larger than LARGEST_MODE (usually SImode).
If no mode meets all these conditions, we return VOIDmode.
-
+
If VOLATILEP is false and SLOW_BYTE_ACCESS is false, we return the
smallest mode meeting these conditions.
If VOLATILEP is false and SLOW_BYTE_ACCESS is true, we return the
largest mode (but a mode no wider than UNITS_PER_WORD) that meets
all the conditions.
-
+
If VOLATILEP is true the narrow_volatile_bitfields target hook is used to
decide which of the above modes should be used. */
return VOIDmode;
if ((SLOW_BYTE_ACCESS && ! volatilep)
- || (volatilep && !targetm.narrow_volatile_bitfield()))
+ || (volatilep && !targetm.narrow_volatile_bitfield ()))
{
enum machine_mode wide_mode = VOIDmode, tmode;