/* C-compiler utilities for types and variables storage layout
- Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include "tree.h"
#include "flags.h"
+#include "except.h"
#include "function.h"
#define CEIL(x,y) (((x) + (y) - 1) / (y))
The value is measured in bits. */
int maximum_field_alignment;
-/* If non-zero, the alignment of a bitsting or (power-)set value, in bits.
+/* If non-zero, the alignment of a bitstring or (power-)set value, in bits.
May be overridden by front-ends. */
int set_alignment = 0;
-#define GET_MODE_ALIGNMENT(MODE) \
- MIN (BIGGEST_ALIGNMENT, \
- MAX (1, (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT)))
-
static enum machine_mode smallest_mode_for_size PROTO((unsigned int,
enum mode_class));
static tree layout_record PROTO((tree));
return chain;
}
-/* Given a size SIZE that isn't constant, return a SAVE_EXPR
+void
+put_pending_sizes (chain)
+ tree chain;
+{
+ if (pending_sizes)
+ abort ();
+
+ pending_sizes = chain;
+}
+
+/* Given a size SIZE that may not be a constant, return a SAVE_EXPR
to serve as the actual size-expression for a type or decl. */
tree
/* 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. */
- if (global_bindings_p () < 0 || contains_placeholder_p (size))
+ if (TREE_CONSTANT (size)
+ || global_bindings_p () < 0 || contains_placeholder_p (size))
return size;
size = save_expr (size);
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);
- else if (flag_pack_struct)
+ else if (DECL_PACKED (decl))
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
}
if (DECL_BIT_FIELD (decl)
&& TYPE_SIZE (type) != 0
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
{
register enum machine_mode xmode
= mode_for_size (TREE_INT_CST_LOW (DECL_SIZE (decl)), MODE_INT, 1);
}
}
+ /* Turn off DECL_BIT_FIELD if we won't need it set. */
+ if (DECL_BIT_FIELD (decl) && TYPE_MODE (type) == BLKmode
+ && known_align % TYPE_ALIGN (type) == 0
+ && DECL_SIZE (decl) != 0
+ && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST
+ || (TREE_INT_CST_LOW (DECL_SIZE (decl)) % BITS_PER_UNIT) == 0)
+ && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
+ 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));
and VAR_SIZE is a tree expression.
If VAR_SIZE is null, the size is just CONST_SIZE.
Naturally we try to avoid using VAR_SIZE. */
- register int const_size = 0;
+ register HOST_WIDE_INT const_size = 0;
register tree var_size = 0;
/* Once we start using VAR_SIZE, this is the maximum alignment
that we know VAR_SIZE has. */
In both cases, all we do is lay out the decl,
and we do it *after* the record is laid out. */
- if (TREE_STATIC (field))
+ if (TREE_CODE (field) == VAR_DECL)
{
pending_statics = tree_cons (NULL_TREE, field, pending_statics);
continue;
#ifdef BIGGEST_FIELD_ALIGNMENT
desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
#endif
+#ifdef ADJUST_FIELD_ALIGN
+ desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
+#endif
/* Record must have at least as much alignment as any field.
Otherwise, the alignment of the field within the record
int type_align = TYPE_ALIGN (TREE_TYPE (field));
if (maximum_field_alignment != 0)
type_align = MIN (type_align, maximum_field_alignment);
- else if (flag_pack_struct)
+ else if (TYPE_PACKED (rec))
type_align = MIN (type_align, BITS_PER_UNIT);
record_align = MAX (record_align, type_align);
&& TREE_TYPE (field) != error_mark_node
&& DECL_BIT_FIELD_TYPE (field)
&& !DECL_PACKED (field)
- /* If #pragma pack is in effect, turn off this feature. */
&& maximum_field_alignment == 0
- && !flag_pack_struct
&& !integer_zerop (DECL_SIZE (field)))
{
int type_align = TYPE_ALIGN (TREE_TYPE (field));
register tree dsize = DECL_SIZE (field);
int field_size = TREE_INT_CST_LOW (dsize);
- /* A bit field may not span the unit of alignment of its type.
- Advance to next boundary if necessary. */
- /* ??? There is some uncertainty here as to what
- should be done if type_align is less than the width of the type.
- That can happen because the width exceeds BIGGEST_ALIGNMENT
- or because it exceeds maximum_field_alignment. */
- if (const_size / type_align
- != (const_size + field_size - 1) / type_align)
+ /* A bit field may not span more units of alignment of its type
+ than its type itself. Advance to next boundary if necessary. */
+ if (((const_size + field_size) / type_align - const_size / type_align)
+ > TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (field))) / type_align)
const_size = CEIL (const_size, type_align) * type_align;
}
#endif
if (maximum_field_alignment != 0)
type_align = MIN (type_align, maximum_field_alignment);
- else if (flag_pack_struct)
+ else if (TYPE_PACKED (rec))
type_align = MIN (type_align, BITS_PER_UNIT);
/* A bit field may not span the unit of alignment of its type.
if (dsize == 0)
/* Do nothing. */;
else if (TREE_CODE (dsize) == INTEGER_CST
+ && ! TREE_CONSTANT_OVERFLOW (dsize)
&& TREE_INT_CST_HIGH (dsize) == 0
- && TREE_INT_CST_LOW (dsize) + const_size > const_size)
+ && TREE_INT_CST_LOW (dsize) + const_size >= const_size)
/* Use const_size if there's no overflow. */
const_size += TREE_INT_CST_LOW (dsize);
else
{
case LANG_TYPE:
/* This kind of type is the responsibility
- of the languge-specific code. */
+ of the language-specific code. */
abort ();
case INTEGER_TYPE:
case ENUMERAL_TYPE:
+ case CHAR_TYPE:
if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
&& tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
TREE_UNSIGNED (type) = 1;
if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
&& TYPE_SIZE (element))
{
- tree length
- = size_binop (PLUS_EXPR, size_one_node,
- size_binop (MINUS_EXPR, TYPE_MAX_VALUE (index),
- TYPE_MIN_VALUE (index)));
+ tree ub = TYPE_MAX_VALUE (index);
+ tree lb = TYPE_MIN_VALUE (index);
+ tree length;
+
+ /* 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);
+
+ length = size_binop (PLUS_EXPR, size_one_node,
+ size_binop (MINUS_EXPR, 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);
TYPE_SIZE (type) = size_binop (MULT_EXPR, length,
TYPE_SIZE (element));
break;
/* Pascal and Chill types */
- case BOOLEAN_TYPE: /* store one byte/boolean for now. */
+ case BOOLEAN_TYPE: /* store one byte/boolean for now. */
TYPE_MODE (type) = QImode;
TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
TYPE_PRECISION (type) = 1;
TREE_UNSIGNED (type) = 1;
break;
- case CHAR_TYPE:
- TYPE_MODE (type) = QImode;
- TYPE_SIZE (type) = size_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
- TYPE_PRECISION (type) = GET_MODE_BITSIZE (TYPE_MODE (type));
- TYPE_ALIGN (type) = GET_MODE_ALIGNMENT (TYPE_MODE (type));
- break;
-
case SET_TYPE:
if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST
|| TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST)