/* Build expressions with type checking for CHILL compiler.
- Copyright (C) 1992, 93, 1994, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000
+ Free Software Foundation, Inc.
This file is part of GNU CC.
#include "expr.h"
#include "lex.h"
#include "toplev.h"
-
-extern tree intQI_type_node;
-extern tree intHI_type_node;
-extern tree intSI_type_node;
-extern tree intDI_type_node;
-#if HOST_BITS_PER_WIDE_INT >= 64
-extern tree intTI_type_node;
-#endif
-
-extern tree unsigned_intQI_type_node;
-extern tree unsigned_intHI_type_node;
-extern tree unsigned_intSI_type_node;
-extern tree unsigned_intDI_type_node;
-#if HOST_BITS_PER_WIDE_INT >= 64
-extern tree unsigned_intTI_type_node;
-#endif
+#include "output.h"
/* forward declarations */
-static int chill_l_equivalent PROTO((tree, tree, struct mode_chain*));
-static tree extract_constant_from_buffer PROTO((tree, unsigned char *, int));
-static int expand_constant_to_buffer PROTO((tree, unsigned char *, int));
+static int chill_l_equivalent PARAMS ((tree, tree, struct mode_chain*));
+static tree extract_constant_from_buffer PARAMS ((tree, const unsigned char *, int));
+static int expand_constant_to_buffer PARAMS ((tree, unsigned char *, int));
+static tree build_empty_string PARAMS ((tree));
+static tree make_chill_pointer_type PARAMS ((tree, enum tree_code));
+static unsigned int min_precision PARAMS ((tree, int));
+static tree make_chill_range_type PARAMS ((tree, tree, tree));
+static void apply_chill_array_layout PARAMS ((tree));
+static int field_decl_cmp PARAMS ((tree *, tree*));
+static tree make_chill_struct_type PARAMS ((tree));
+static int apply_chill_field_layout PARAMS ((tree, int *));
\f
/*
* This function checks an array access.
tree
valid_array_index_p (array, idx, error_message, is_varying_lhs)
tree array, idx;
- char *error_message;
+ const char *error_message;
int is_varying_lhs;
{
tree cond, low_limit, high_cond, atype, domain;
{
if (tree_int_cst_equal (cond, boolean_false_node))
return idx; /* condition met at compile time */
- error (error_message); /* condition failed at compile time */
+ error ("%s", error_message); /* condition failed at compile time */
return error_mark_node;
}
else if (range_checking)
The static allocation info is passed by using the parent array's
limits to compute a temp_size, which is passed in the lang_specific
- field of the slice_type.
- */
+ field of the slice_type. */
if (TREE_CODE (array_type) == ARRAY_TYPE)
{
tree domain_type = TYPE_DOMAIN (array_type);
tree domain_min = TYPE_MIN_VALUE (domain_type);
- tree domain_max = fold (build (PLUS_EXPR, domain_type,
- domain_min,
- size_binop (MINUS_EXPR,
- length, integer_one_node)));
+ tree domain_max
+ = fold (build (PLUS_EXPR, domain_type,
+ domain_min,
+ fold (build (MINUS_EXPR, integer_type_node,
+ length, integer_one_node))));
tree index_type = build_chill_range_type (TYPE_DOMAIN (array_type),
domain_min,
domain_max);
SET_CH_NOVELTY (slice_type, CH_NOVELTY (array_type));
- if (TREE_CONSTANT (array) && TREE_CODE (min_value) == INTEGER_CST
- && TREE_CODE (length) == INTEGER_CST)
+ if (TREE_CONSTANT (array) && host_integerp (min_value, 0)
+ && host_integerp (length, 0))
{
- int type_size = int_size_in_bytes (array_type);
- unsigned char *buffer = (unsigned char*) alloca (type_size);
- int delta = int_size_in_bytes (element_type)
- * (TREE_INT_CST_LOW (min_value) - TREE_INT_CST_LOW (domain_min));
- bzero (buffer, type_size);
+ unsigned HOST_WIDE_INT type_size = int_size_in_bytes (array_type);
+ unsigned char *buffer = (unsigned char *) alloca (type_size);
+ int delta = (int_size_in_bytes (element_type)
+ * (tree_low_cst (min_value, 0)
+ - tree_low_cst (domain_min, 0)));
+
+ memset (buffer, 0, type_size);
if (expand_constant_to_buffer (array, buffer, type_size))
{
result = extract_constant_from_buffer (slice_type,
&& tree_int_cst_lt (max_value, min_value))
return build_empty_string (TREE_TYPE (TREE_TYPE (array)));
- return build_chill_slice (array, min_value,
- save_expr (size_binop (PLUS_EXPR,
- size_binop (MINUS_EXPR, max_value, min_value),
- integer_one_node)));
+ return
+ build_chill_slice
+ (array, min_value,
+ save_expr (fold (build (PLUS_EXPR, integer_type_node,
+ fold (build (MINUS_EXPR, integer_type_node,
+ max_value, min_value)),
+ integer_one_node))));
}
-
tree
build_chill_slice_with_length (array, min_value, length)
tree array, min_value, length;
length = integer_one_node;
}
- max_index = size_binop (MINUS_EXPR,
- size_binop (PLUS_EXPR, length, min_value),
- integer_one_node);
+ max_index = fold (build (MINUS_EXPR, integer_type_node,
+ fold (build (PLUS_EXPR, integer_type_node,
+ length, min_value)),
+ integer_one_node));
max_index = convert_to_class (chill_expr_class (min_value), max_index);
min_value = valid_array_index_p (array, min_value,
if (! integer_zerop (TYPE_MIN_VALUE (domain)))
{
/* The C part of the compiler doesn't understand how to do
- arithmetic with dissimilar enum types. So we check compatability
+ arithmetic with dissimilar enum types. So we check compatibility
here, and perform the math in INTEGER_TYPE. */
if (TREE_CODE (TREE_TYPE (idx)) == ENUMERAL_TYPE
&& chill_comptypes (TREE_TYPE (idx), domain, 0))
else if (TREE_CODE (array) == STRING_CST
&& CH_CHARS_TYPE_P (TREE_TYPE (array)))
{
- HOST_WIDE_INT i = TREE_INT_CST_LOW (idx);
+ HOST_WIDE_INT i = tree_low_cst (idx, 0);
+
if (i >= 0 && i < TREE_STRING_LENGTH (array))
- {
- char ch = TREE_STRING_POINTER (array) [i];
- return convert_to_class (class,
- build_int_2 ((unsigned char)ch, 0));
- }
+ return
+ convert_to_class
+ (class,
+ build_int_2
+ ((unsigned char) TREE_STRING_POINTER (array) [i], 0));
}
}
{
case INTEGER_CST:
{
- HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
+ unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (value);
HOST_WIDE_INT hi = TREE_INT_CST_HIGH (value);
for (i = 0; i < size; i++)
{
/* Doesn't work if host and target BITS_PER_UNIT differ. */
unsigned char byte = lo & ((1 << BITS_PER_UNIT) - 1);
+
if (BYTES_BIG_ENDIAN)
buffer[size - i - 1] = byte;
else
buffer[i] = byte;
+
rshift_double (lo, hi, BITS_PER_UNIT, BITS_PER_UNIT * size,
&lo, &hi, 0);
}
tree min_val = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
if (min_val)
{
- if (TREE_CODE (min_val) != INTEGER_CST)
+ if (! host_integerp (min_val, 0))
return 0;
else
- min_index = TREE_INT_CST_LOW (min_val);
+ min_index = tree_low_cst (min_val, 0);
}
}
HOST_WIDE_INT offset;
HOST_WIDE_INT last_index;
tree purpose = TREE_PURPOSE (list);
+
if (purpose)
{
- if (TREE_CODE (purpose) == INTEGER_CST)
- last_index = next_index = TREE_INT_CST_LOW (purpose);
+ if (host_integerp (purpose, 0))
+ last_index = next_index = tree_low_cst (purpose, 0);
else if (TREE_CODE (purpose) == RANGE_EXPR)
{
- next_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 0));
- last_index = TREE_INT_CST_LOW (TREE_OPERAND(purpose, 1));
+ next_index = tree_low_cst (TREE_OPERAND (purpose, 0), 0);
+ last_index = tree_low_cst (TREE_OPERAND (purpose, 1), 0);
}
else
return 0;
{
tree field = TREE_PURPOSE (list);
HOST_WIDE_INT offset;
+
if (field == NULL_TREE || TREE_CODE (field) != FIELD_DECL)
return 0;
+
if (DECL_BIT_FIELD (field))
return 0;
- offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
- / BITS_PER_UNIT;
+
+ offset = int_byte_position (field);
if (!expand_constant_to_buffer (TREE_VALUE (list),
buffer + offset,
buf_size - offset))
static tree
extract_constant_from_buffer (type, buffer, buf_size)
tree type;
- unsigned char *buffer;
+ const unsigned char *buffer;
int buf_size;
{
tree value;
- int size = int_size_in_bytes (type);
- int i;
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ HOST_WIDE_INT i;
+
if (size < 0 || size > buf_size)
return 0;
+
switch (TREE_CODE (type))
{
case INTEGER_TYPE:
value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
if (value)
{
- if (TREE_CODE (value) != INTEGER_CST)
+ if (! host_integerp (value, 0))
return 0;
else
- min_index = TREE_INT_CST_LOW (value);
+ min_index = tree_low_cst (value, 0);
}
+
value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
- if (value == NULL_TREE || TREE_CODE (value) != INTEGER_CST)
+ if (value == NULL_TREE || ! host_integerp (value, 0))
return 0;
else
- max_index = TREE_INT_CST_LOW (value);
+ max_index = tree_low_cst (value, 0);
+
for (cur_index = max_index; cur_index >= min_index; cur_index--)
{
HOST_WIDE_INT offset = (cur_index - min_index) * element_size;
tree field = TYPE_FIELDS (type);
for (; field != NULL_TREE; field = TREE_CHAIN (field))
{
- HOST_WIDE_INT offset
- = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) / BITS_PER_UNIT;
+ HOST_WIDE_INT offset = int_byte_position (field);
+
if (DECL_BIT_FIELD (field))
return 0;
value = extract_constant_from_buffer (TREE_TYPE (field),
case UNION_TYPE:
{
tree longest_variant = NULL_TREE;
- int longest_size = 0;
+ unsigned HOST_WIDE_INT longest_size = 0;
tree field = TYPE_FIELDS (type);
/* This is a kludge. We assume that converting the data to te
for (; field != NULL_TREE; field = TREE_CHAIN (field))
{
- int size = TREE_INT_CST_LOW (size_in_bytes (TREE_TYPE (field)));
+ unsigned HOST_WIDE_INT size
+ = int_size_in_bytes (TREE_TYPE (field));
if (size > longest_size)
{
longest_variant = field;
}
}
+
if (longest_variant == NULL_TREE)
return NULL_TREE;
- return extract_constant_from_buffer (TREE_TYPE (longest_variant), buffer, buf_size);
+
+ return
+ extract_constant_from_buffer (TREE_TYPE (longest_variant),
+ buffer, buf_size);
}
case SET_TYPE:
tree list = NULL_TREE;
int i;
HOST_WIDE_INT min_index, max_index;
+
if (TYPE_DOMAIN (type) == 0)
return 0;
+
value = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
if (value == NULL_TREE)
min_index = 0;
- else if (TREE_CODE (value) != INTEGER_CST)
+
+ else if (! host_integerp (value, 0))
return 0;
else
- min_index = TREE_INT_CST_LOW (value);
+ min_index = tree_low_cst (value, 0);
+
value = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
if (value == NULL_TREE)
max_index = 0;
- else if (TREE_CODE (value) != INTEGER_CST)
+ else if (! host_integerp (value, 0))
return 0;
else
- max_index = TREE_INT_CST_LOW (value);
+ max_index = tree_low_cst (value, 0);
+
for (i = max_index + 1 - min_index; --i >= 0; )
{
- unsigned char byte = (unsigned char)buffer[i / BITS_PER_UNIT];
- unsigned bit_pos = (unsigned)i % (unsigned)BITS_PER_UNIT;
+ unsigned char byte = (unsigned char) buffer[i / BITS_PER_UNIT];
+ unsigned bit_pos = (unsigned) i % (unsigned) BITS_PER_UNIT;
+
if (BYTES_BIG_ENDIAN
? (byte & (1 << (BITS_PER_UNIT - 1 - bit_pos)))
: (byte & (1 << bit_pos)))
if (expr_type_is_discrete && type_is_discrete)
{
/* do an overflow check
- FIXME: is this always neccessary ??? */
+ FIXME: is this always necessary ??? */
/* FIXME: don't do range chacking when target type is PTR.
PTR doesn't have MIN and MAXVALUE. result is sigsegv. */
if (range_checking && type != ptr_type_node)
{
unsigned char *buffer = (unsigned char*) alloca (type_size);
tree value;
- bzero (buffer, type_size);
+ memset (buffer, 0, type_size);
if (!expand_constant_to_buffer (expr, buffer, type_size))
{
error ("not implemented: constant conversion from that kind of expression");
return expr;
}
\f
-/*
- * given a set_type, build an integer array from it that C will grok.
- */
+/* Given a set_type, build an integer array from it that C will grok. */
+
tree
build_array_from_set (type)
tree type;
{
tree bytespint, bit_array_size, int_array_count;
- if (type == NULL_TREE || type == error_mark_node || TREE_CODE (type) != SET_TYPE)
+ if (type == NULL_TREE || type == error_mark_node
+ || TREE_CODE (type) != SET_TYPE)
return error_mark_node;
- bytespint = build_int_2 (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR, 0);
+ /* ??? Should this really be *HOST*?? */
+ bytespint = size_int (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR);
bit_array_size = size_in_bytes (type);
- int_array_count = fold (size_binop (TRUNC_DIV_EXPR, bit_array_size,
- bytespint));
+ int_array_count = size_binop (TRUNC_DIV_EXPR, bit_array_size, bytespint);
if (integer_zerop (int_array_count))
int_array_count = size_one_node;
type = build_array_type (integer_type_node,
tree size;
{
#if 0
- int isize;
+ HOST_WIDE_INT isize;
- if (TREE_CODE (size) != INTEGER_CST
- || (isize = TREE_INT_CST_LOW (size), isize <= 0))
+ if (! host_integerp (size, 1))
{
error ("operand to bin must be a non-negative integer literal");
return error_mark_node;
}
+
+ isize = tree_low_cst (size, 1);
+
if (isize <= TYPE_PRECISION (unsigned_char_type_node))
return unsigned_char_type_node;
if (isize <= TYPE_PRECISION (short_unsigned_type_node))
chill_expand_tuple (type, constructor)
tree type, constructor;
{
- char *name;
+ const char *name;
tree nonreft = type;
if (TYPE_NAME (type) != NULL_TREE)
default:
;
-#if 0
/* Need to handle row modes, instance modes,
association modes, access modes, text modes,
duration modes, absolute time modes, structure modes,
parameterized structure modes */
-#endif
}
return 1;
}
return 0;
if (TYPE_READONLY (mode1) != TYPE_READONLY (mode2))
return 0;
-#if 0
+/*
... other conditions ...;
-#endif
+ */
return 1;
}
{
return chill_l_equivalent (TREE_TYPE (modeM), TREE_TYPE (modeN), 0);
}
-#if 0
+/*
...;
-#endif
+*/
}
return 1;
}
case CH_REFERENCE_CLASS:
if (!CH_IS_REFERENCE_MODE (mode))
return 0;
-#if 0
- /* FIXME! */
+/* FIXME!
if (class.mode is a row mode)
...;
else if (class.mode is not a static mode)
- return 0; /* is this possible? FIXME */
-#endif
+ return 0; is this possible?
+*/
return !CH_IS_BOUND_REFERENCE_MODE(mode)
|| CH_READ_COMPATIBLE (TREE_TYPE (mode), class.mode);
}
/* We temporarily reset the maximum_field_alignment to zero so the
compiler's init data structures can be compatible with the
run-time system, even when we're compiling with -fpack. */
- extern int maximum_field_alignment;
- int save_maximum_field_alignment = maximum_field_alignment;
+ unsigned int save_maximum_field_alignment = maximum_field_alignment;
maximum_field_alignment = 0;
decl1 = build_decl (FIELD_DECL, get_identifier ("__INIT_ENTRY"),
/* Construct, lay out and return the type of pointers to TO_TYPE.
If such a type has already been constructed, reuse it. */
-tree
+static tree
make_chill_pointer_type (to_type, code)
tree to_type;
enum tree_code code; /* POINTER_TYPE or REFERENCE_TYPE */
return t;
}
\f
-tree
+static tree
make_chill_range_type (type, lowval, highval)
tree type, lowval, highval;
{
return itype;
}
+\f
+/* Return the minimum number of bits needed to represent VALUE in a
+ signed or unsigned type, UNSIGNEDP says which. */
+
+static unsigned int
+min_precision (value, unsignedp)
+ tree value;
+ int unsignedp;
+{
+ int log;
+
+ /* If the value is negative, compute its negative minus 1. The latter
+ adjustment is because the absolute value of the largest negative value
+ is one larger than the largest positive value. This is equivalent to
+ a bit-wise negation, so use that operation instead. */
+
+ if (tree_int_cst_sgn (value) < 0)
+ value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
+
+ /* Return the number of bits needed, taking into account the fact
+ that we need one more bit for a signed than unsigned type. */
+
+ if (integer_zerop (value))
+ log = 0;
+ else
+ log = tree_floor_log2 (value);
+
+ return log + 1 + ! unsignedp;
+}
+
tree
layout_chill_range_type (rangetype, must_be_const)
tree rangetype;
{
int binsize;
- /* make a range out of it */
+ /* Make a range out of it */
if (TREE_CODE (highval) != INTEGER_CST)
{
error ("non-constant expression for BIN");
return error_mark_node;
}
- binsize = TREE_INT_CST_LOW (highval);
- if (binsize < 0)
+ else if (tree_int_cst_sgn (highval) < 0)
{
error ("expression for BIN must not be negative");
return error_mark_node;
}
- if (binsize > 32)
+ else if (compare_tree_int (highval, 32) > 0)
{
error ("cannot process BIN (>32)");
return error_mark_node;
}
+
+ binsize = tree_low_cst (highval, 1);
type = ridpointers [(int) RID_RANGE];
lowval = integer_zero_node;
highval = build_int_2 ((1 << binsize) - 1, 0);
}
- if (TREE_CODE (lowval) == ERROR_MARK ||
- TREE_CODE (highval) == ERROR_MARK)
+ if (TREE_CODE (lowval) == ERROR_MARK
+ || TREE_CODE (highval) == ERROR_MARK)
return error_mark_node;
if (!CH_COMPATIBLE_CLASSES (lowval, highval))
&& TREE_CODE (lowval) == INTEGER_CST
&& TREE_CODE (highval) == INTEGER_CST)
{
- /* The logic of this code has been copied from finish_enum
- in c-decl.c. FIXME duplication! */
- int precision = 0;
- HOST_WIDE_INT maxvalue = TREE_INT_CST_LOW (highval);
- HOST_WIDE_INT minvalue = TREE_INT_CST_LOW (lowval);
- if (TREE_INT_CST_HIGH (lowval) >= 0
- ? tree_int_cst_lt (TYPE_MAX_VALUE (unsigned_type_node), highval)
- : (tree_int_cst_lt (lowval, TYPE_MIN_VALUE (integer_type_node))
- || tree_int_cst_lt (TYPE_MAX_VALUE (integer_type_node), highval)))
- precision = TYPE_PRECISION (long_long_integer_type_node);
- else
- {
- if (maxvalue > 0)
- precision = floor_log2 (maxvalue) + 1;
- if (minvalue < 0)
- {
- /* Compute number of bits to represent magnitude of a
- negative value. Add one to MINVALUE since range of
- negative numbers includes the power of two. */
- int negprecision = floor_log2 (-minvalue - 1) + 1;
- if (negprecision > precision)
- precision = negprecision;
- precision += 1; /* room for sign bit */
- }
+ int unsignedp = tree_int_cst_sgn (lowval) >= 0;
+ unsigned int precision = MAX (min_precision (highval, unsignedp),
+ min_precision (lowval, unsignedp));
- if (!precision)
- precision = 1;
- }
- type = type_for_size (precision, minvalue >= 0);
+ type = type_for_size (precision, unsignedp);
}
+
TREE_TYPE (rangetype) = type;
}
else
TYPE_SIZE (rangetype) = TYPE_SIZE (type);
TYPE_SIZE_UNIT (rangetype) = TYPE_SIZE_UNIT (type);
TYPE_ALIGN (rangetype) = TYPE_ALIGN (type);
+ TYPE_USER_ALIGN (rangetype) = TYPE_USER_ALIGN (type);
TREE_UNSIGNED (rangetype) = TREE_UNSIGNED (type);
CH_NOVELTY (rangetype) = CH_NOVELTY (type);
return rangetype;
tree array_type;
{
tree layout, temp, what, element_type;
- int stepsize=0, word, start_bit=0, length, natural_length;
+ HOST_WIDE_INT stepsize = 0;
+ HOST_WIDE_INT word, start_bit = 0, length;
+ HOST_WIDE_INT natural_length;
int stepsize_specified;
int start_bit_error = 0;
int length_error = 0;
&& get_type_precision (TYPE_MIN_VALUE (element_type),
TYPE_MAX_VALUE (element_type)) == 1)
natural_length = 1;
+ else if (host_integerp (TYPE_SIZE (element_type), 1))
+ natural_length = tree_low_cst (TYPE_SIZE (element_type), 1);
else
- natural_length = TREE_INT_CST_LOW (TYPE_SIZE (element_type));
+ natural_length = -1;
if (layout == integer_one_node) /* PACK */
{
temp = TREE_VALUE (layout);
if (TREE_VALUE (temp) != NULL_TREE)
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
- error ("Stepsize in STEP must be an integer constant");
+ if (! host_integerp (TREE_VALUE (temp), 0))
+ error ("stepsize in STEP must be an integer constant");
else
{
- stepsize = TREE_INT_CST_LOW (TREE_VALUE (temp));
- if (stepsize <= 0)
- error ("Stepsize in STEP must be > 0");
+ if (tree_int_cst_sgn (TREE_VALUE (temp)) <= 0)
+ error ("stepsize in STEP must be > 0");
else
stepsize_specified = 1;
+ stepsize = tree_low_cst (TREE_VALUE (temp), 1);
if (stepsize != natural_length)
- sorry ("Stepsize in STEP must be the natural width of "
- "the array element mode");
+ sorry ("stepsize in STEP must be the natural width of the array element mode");
}
}
temp = TREE_PURPOSE (temp);
- if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
- error ("Starting word in POS must be an integer constant");
+ if (! host_integerp (TREE_PURPOSE (temp), 0))
+ error ("starting word in POS must be an integer constant");
else
{
- word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
- if (word < 0)
- error ("Starting word in POS must be >= 0");
- if (word != 0)
- sorry ("Starting word in POS within STEP must be 0");
+ if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
+ error ("starting word in POS must be >= 0");
+ if (! integer_zerop (TREE_PURPOSE (temp)))
+ sorry ("starting word in POS within STEP must be 0");
+
+ word = tree_low_cst (TREE_PURPOSE (temp), 0);
}
length = natural_length;
if (temp != NULL_TREE)
{
int wordsize = TYPE_PRECISION (chill_integer_type_node);
- if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_PURPOSE (temp), 0))
{
- error ("Starting bit in POS must be an integer constant");
+ error ("starting bit in POS must be an integer constant");
start_bit_error = 1;
}
else
{
- start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
- if (start_bit != 0)
- sorry ("Starting bit in POS within STEP must be 0");
- if (start_bit < 0)
+ if (! integer_zerop (TREE_PURPOSE (temp)))
+ sorry ("starting bit in POS within STEP must be 0");
+
+ if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
{
- error ("Starting bit in POS must be >= 0");
+ error ("starting bit in POS must be >= 0");
start_bit = 0;
start_bit_error = 1;
}
- else if (start_bit >= wordsize)
+
+ start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+ if (start_bit >= wordsize)
{
- error ("Starting bit in POS must be < the width of a word");
+ error ("starting bit in POS must be < the width of a word");
start_bit = 0;
start_bit_error = 1;
}
what = TREE_PURPOSE (temp);
if (what == integer_zero_node)
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_VALUE (temp), 0))
{
- error ("Length in POS must be an integer constant");
+ error ("length in POS must be an integer constant");
length_error = 1;
}
else
{
- length = TREE_INT_CST_LOW (TREE_VALUE (temp));
+ length = tree_low_cst (TREE_VALUE (temp), 0);
if (length <= 0)
- error ("Length in POS must be > 0");
+ error ("length in POS must be > 0");
}
}
else
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_VALUE (temp), 0))
{
- error ("End bit in POS must be an integer constant");
+ error ("end bit in POS must be an integer constant");
length_error = 1;
}
else
{
- int end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+ HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
+
if (end_bit < start_bit)
{
- error ("End bit in POS must be >= the start bit");
+ error ("end bit in POS must be >= the start bit");
end_bit = wordsize - 1;
length_error = 1;
}
else if (end_bit >= wordsize)
{
- error ("End bit in POS must be < the width of a word");
+ error ("end bit in POS must be < the width of a word");
end_bit = wordsize - 1;
length_error = 1;
}
length = end_bit - start_bit + 1;
}
}
+
if (! length_error && length != natural_length)
- {
- sorry ("The length specified on POS within STEP must be "
- "the natural length of the array element type");
- }
+ sorry ("the length specified on POS within STEP must be the natural length of the array element type");
}
}
if (! length_error && stepsize_specified && stepsize < length)
- error ("Step size in STEP must be >= the length in POS");
+ error ("step size in STEP must be >= the length in POS");
if (length == 1)
TYPE_PACKED (array_type) = 1;
return (long)DECL_NAME (*x) - (long)DECL_NAME (*y);
}
-tree
+static tree
make_chill_struct_type (fieldlist)
tree fieldlist;
{
tree t, x;
- if (TREE_UNION_ELEM (fieldlist))
- t = make_node (UNION_TYPE);
- else
- t = make_node (RECORD_TYPE);
+
+ t = make_node (TREE_UNION_ELEM (fieldlist) ? UNION_TYPE : RECORD_TYPE);
+
/* Install struct as DECL_CONTEXT of each field decl. */
for (x = fieldlist; x; x = TREE_CHAIN (x))
- {
- DECL_CONTEXT (x) = t;
- DECL_FIELD_SIZE (x) = 0;
- }
+ DECL_CONTEXT (x) = t;
/* Delete all duplicate fields from the fieldlist */
for (x = fieldlist; x && TREE_CHAIN (x);)
return t;
}
-/* decl is a FIELD_DECL.
- DECL_INIT (decl) is (NULL_TREE, integer_one_node, integer_zero_node, tree_list),
- meaning (default, pack, nopack, POS (...) ).
+/* DECL is a FIELD_DECL.
+ DECL_INIT (decl) is
+ (NULL_TREE, integer_one_node, integer_zero_node, tree_list)
+ meaning
+ (default, pack, nopack, POS (...) ).
+
The return value is a boolean: 1 if POS specified, 0 if not */
+
static int
apply_chill_field_layout (decl, next_struct_offset)
tree decl;
- int* next_struct_offset;
+ int *next_struct_offset;
{
- tree layout, type, temp, what;
- int word = 0, wordsize, start_bit, offset, length, natural_length;
+ tree layout = DECL_INITIAL (decl);
+ tree type = TREE_TYPE (decl);
+ tree temp, what;
+ HOST_WIDE_INT word = 0;
+ HOST_WIDE_INT wordsize, start_bit, offset, length, natural_length;
int pos_error = 0;
- int is_discrete;
+ int is_discrete = discrete_type_p (type);
- type = TREE_TYPE (decl);
- is_discrete = discrete_type_p (type);
if (is_discrete)
- natural_length = get_type_precision (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+ natural_length
+ = get_type_precision (TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+ else if (host_integerp (TYPE_SIZE (type), 1))
+ natural_length = tree_low_cst (TYPE_SIZE (type), 1);
else
- natural_length = TREE_INT_CST_LOW (TYPE_SIZE (type));
+ natural_length = -1;
- layout = DECL_INITIAL (decl);
if (layout == integer_zero_node) /* NOPACK */
{
- DECL_PACKED (decl) = 0;
*next_struct_offset += natural_length;
return 0; /* not POS */
}
if (layout == integer_one_node) /* PACK */
{
if (is_discrete)
- DECL_BIT_FIELD (decl) = 1;
+ {
+ DECL_BIT_FIELD (decl) = 1;
+ DECL_SIZE (decl) = bitsize_int (natural_length);
+ }
else
{
- DECL_BIT_FIELD (decl) = 0;
DECL_ALIGN (decl) = BITS_PER_UNIT;
+ DECL_USER_ALIGN (decl) = 0;
}
+
DECL_PACKED (decl) = 1;
- DECL_FIELD_SIZE (decl) = natural_length;
*next_struct_offset += natural_length;
return 0; /* not POS */
}
natural width of the underlying type. */
temp = TREE_PURPOSE (layout);
- if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_PURPOSE (temp), 0))
{
- error ("Starting word in POS must be an integer constant");
+ error ("starting word in POS must be an integer constant");
pos_error = 1;
}
else
{
- word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
- if (word < 0)
+ if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
{
- error ("Starting word in POS must be >= 0");
+ error ("starting word in POS must be >= 0");
word = 0;
pos_error = 1;
}
+ else
+ word = tree_low_cst (TREE_PURPOSE (temp), 0);
}
wordsize = TYPE_PRECISION (chill_integer_type_node);
temp = TREE_VALUE (temp);
if (temp != NULL_TREE)
{
- if (TREE_CODE (TREE_PURPOSE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_PURPOSE (temp), 0))
{
- error ("Starting bit in POS must be an integer constant");
+ error ("starting bit in POS must be an integer constant");
start_bit = *next_struct_offset - offset;
pos_error = 1;
}
else
{
- start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
- if (start_bit < 0)
+ if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 0)
{
- error ("Starting bit in POS must be >= 0");
+ error ("starting bit in POS must be >= 0");
start_bit = *next_struct_offset - offset;
pos_error = 1;
}
- else if (start_bit >= wordsize)
+
+ start_bit = tree_low_cst (TREE_PURPOSE (temp), 0);
+ if (start_bit >= wordsize)
{
- error ("Starting bit in POS must be < the width of a word");
+ error ("starting bit in POS must be < the width of a word");
start_bit = *next_struct_offset - offset;
pos_error = 1;
}
what = TREE_PURPOSE (temp);
if (what == integer_zero_node)
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_VALUE (temp), 0))
{
- error ("Length in POS must be an integer constant");
+ error ("length in POS must be an integer constant");
pos_error = 1;
}
else
{
- length = TREE_INT_CST_LOW (TREE_VALUE (temp));
- if (length <= 0)
+ if (tree_int_cst_sgn (TREE_VALUE (temp)) < 0)
{
- error ("Length in POS must be > 0");
+ error ("length in POS must be > 0");
length = natural_length;
pos_error = 1;
}
+ else
+ length = tree_low_cst (TREE_VALUE (temp), 0);
+
}
}
else
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+ if (! host_integerp (TREE_VALUE (temp), 0))
{
- error ("End bit in POS must be an integer constant");
+ error ("end bit in POS must be an integer constant");
pos_error = 1;
}
else
{
- int end_bit = TREE_INT_CST_LOW (TREE_VALUE (temp));
+ HOST_WIDE_INT end_bit = tree_low_cst (TREE_VALUE (temp), 0);
+
if (end_bit < start_bit)
{
- error ("End bit in POS must be >= the start bit");
+ error ("end bit in POS must be >= the start bit");
pos_error = 1;
}
else if (end_bit >= wordsize)
{
- error ("End bit in POS must be < the width of a word");
+ error ("end bit in POS must be < the width of a word");
pos_error = 1;
}
else
length = end_bit - start_bit + 1;
}
}
+
if (length != natural_length && ! pos_error)
{
- sorry ("The length specified on POS must be the natural length "
- "of the field type");
+ sorry ("the length specified on POS must be the natural length of the field type");
length = natural_length;
}
}
DECL_PACKED (decl) = 1;
DECL_BIT_FIELD (decl) = is_discrete;
- DECL_FIELD_SIZE (decl) = length;
+
+ if (is_discrete)
+ DECL_SIZE (decl) = bitsize_int (length);
+
*next_struct_offset += natural_length;
return 1; /* was POS */
old_momentary = suspend_momentary ();
- /* Process specified field sizes.
- Set DECL_FIELD_SIZE to the specified size, or 0 if none specified.
- The specified size is found in the DECL_INITIAL.
- Store 0 there, except for ": 0" fields (so we can find them
- and delete them, below). */
-
+ /* Process specified field sizes. */
next_struct_offset = 0;
for (x = fieldlist; x; x = TREE_CHAIN (x))
{
}
if (pos_error)
- error ("If one field has a POS layout, then all fields must have a POS layout");
+ error ("if one field has a POS layout, then all fields must have a POS layout");
/* Now DECL_INITIAL is null on all fields. */
for (x = fieldlist; x; x = TREE_CHAIN (x))
field_array[len++] = x;
- qsort (field_array, len, sizeof (tree), field_decl_cmp);
+ qsort (field_array, len, sizeof (tree),
+ (int (*) PARAMS ((const void *, const void *))) field_decl_cmp);
}
}
TYPE_FIELDS (x) = TYPE_FIELDS (t);
TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
TYPE_ALIGN (x) = TYPE_ALIGN (t);
+ TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
}
resume_momentary (old_momentary);
{
tree oldindex = TYPE_DOMAIN (origin);
new_max = check_range (new_max, new_max, NULL_TREE,
- size_binop (PLUS_EXPR,
- TYPE_MAX_VALUE (oldindex),
- integer_one_node));
+ fold (build (PLUS_EXPR, integer_type_node,
+ TYPE_MAX_VALUE (oldindex),
+ integer_one_node)));
origin = build_string_type (TREE_TYPE (origin), new_max);
}
else if (TREE_CODE (origin) == ARRAY_TYPE)
}
else if (TREE_CODE (origin) == RECORD_TYPE)
{
- error ("parameterised structures not implemented");
+ error ("parameterized structures not implemented");
return error_mark_node;
}
else
{
- error ("invalid parameterised type");
+ error ("invalid parameterized type");
return error_mark_node;
}
}
}
\f
-/* Return nonzero if VALUE is a valid constant-valued expression
- for use in initializing a static variable; one that can be an
- element of a "constant" initializer.
-
- Return null_pointer_node if the value is absolute;
- if it is relocatable, return the variable that determines the relocation.
- We assume that VALUE has been folded as much as possible;
- therefore, we do not need to check for such things as
- arithmetic-combinations of integers. */
-
-tree
-initializer_constant_valid_p (value, endtype)
- tree value;
- tree endtype;
-{
- switch (TREE_CODE (value))
- {
- case CONSTRUCTOR:
- if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
- && TREE_CONSTANT (value))
- return
- initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
- endtype);
-
- return TREE_STATIC (value) ? null_pointer_node : 0;
-
- case INTEGER_CST:
- case REAL_CST:
- case STRING_CST:
- case COMPLEX_CST:
- return null_pointer_node;
-
- case ADDR_EXPR:
- return TREE_OPERAND (value, 0);
-
- case NON_LVALUE_EXPR:
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- case CONVERT_EXPR:
- case NOP_EXPR:
- /* Allow conversions between pointer types. */
- if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow conversions between real types. */
- if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow length-preserving conversions between integer types. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (value))
- == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
- /* Allow conversions between other integer types only if
- explicit value. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
- {
- tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- if (inner == null_pointer_node)
- return null_pointer_node;
- return 0;
- }
-
- /* Allow (int) &foo provided int is as wide as a pointer. */
- if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (value))
- >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
-
- /* Likewise conversions from int to pointers. */
- if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
- && (TYPE_PRECISION (TREE_TYPE (value))
- <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
-
- /* Allow conversions to union types if the value inside is okay. */
- if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
- return initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- return 0;
-
- case PLUS_EXPR:
- if (TREE_CODE (endtype) == INTEGER_TYPE
- && TYPE_PRECISION (endtype) < POINTER_SIZE)
- return 0;
- {
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
- endtype);
- /* If either term is absolute, use the other terms relocation. */
- if (valid0 == null_pointer_node)
- return valid1;
- if (valid1 == null_pointer_node)
- return valid0;
- return 0;
- }
-
- case MINUS_EXPR:
- if (TREE_CODE (endtype) == INTEGER_TYPE
- && TYPE_PRECISION (endtype) < POINTER_SIZE)
- return 0;
- {
- tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
- endtype);
- tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
- endtype);
- /* Win if second argument is absolute. */
- if (valid1 == null_pointer_node)
- return valid0;
- /* Win if both arguments have the same relocation.
- Then the value is absolute. */
- if (valid0 == valid1)
- return null_pointer_node;
- return 0;
- }
- default:
- return 0;
- }
-}
-\f
/* Return an integer type with BITS bits of precision,
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */