summaryrefslogtreecommitdiffstats
path: root/gcc/ch/typeck.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ch/typeck.c')
-rw-r--r--gcc/ch/typeck.c259
1 files changed, 153 insertions, 106 deletions
diff --git a/gcc/ch/typeck.c b/gcc/ch/typeck.c
index 2fe1af418f4..9126ede3e3a 100644
--- a/gcc/ch/typeck.c
+++ b/gcc/ch/typeck.c
@@ -46,6 +46,7 @@ static tree extract_constant_from_buffer PARAMS ((tree, const unsigned char *, i
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*));
@@ -243,13 +244,15 @@ build_chill_slice (array, min_value, length)
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));
+ 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)));
+
bzero (buffer, type_size);
if (expand_constant_to_buffer (array, buffer, type_size))
{
@@ -626,13 +629,14 @@ build_chill_array_ref_1 (array, idx)
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));
}
}
@@ -731,16 +735,18 @@ expand_constant_to_buffer (value, buffer, buf_size)
{
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);
}
@@ -770,10 +776,10 @@ expand_constant_to_buffer (value, buffer, buf_size)
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);
}
}
@@ -784,14 +790,15 @@ expand_constant_to_buffer (value, buffer, buf_size)
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;
@@ -816,12 +823,14 @@ expand_constant_to_buffer (value, buffer, buf_size)
{
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_bit_position (field) / BITS_PER_UNIT;
if (!expand_constant_to_buffer (TREE_VALUE (list),
buffer + offset,
buf_size - offset))
@@ -854,10 +863,12 @@ extract_constant_from_buffer (type, buffer, buf_size)
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:
@@ -902,16 +913,18 @@ extract_constant_from_buffer (type, buffer, buf_size)
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;
@@ -933,8 +946,8 @@ extract_constant_from_buffer (type, buffer, buf_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_bit_position (field) / BITS_PER_UNIT;
+
if (DECL_BIT_FIELD (field))
return 0;
value = extract_constant_from_buffer (TREE_TYPE (field),
@@ -953,7 +966,7 @@ extract_constant_from_buffer (type, buffer, buf_size)
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
@@ -966,7 +979,8 @@ extract_constant_from_buffer (type, buffer, buf_size)
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)
{
@@ -974,9 +988,13 @@ extract_constant_from_buffer (type, buffer, buf_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:
@@ -984,26 +1002,32 @@ extract_constant_from_buffer (type, buffer, buf_size)
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)))
@@ -1241,14 +1265,16 @@ build_chill_bin_type (size)
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))
@@ -2500,6 +2526,36 @@ make_chill_range_type (type, lowval, highval)
return itype;
}
+
+/* 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;
@@ -2518,30 +2574,31 @@ layout_chill_range_type (rangetype, must_be_const)
{
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))
@@ -2578,37 +2635,14 @@ layout_chill_range_type (rangetype, must_be_const)
&& 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
@@ -2736,7 +2770,9 @@ apply_chill_array_layout (array_type)
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;
@@ -2757,8 +2793,10 @@ apply_chill_array_layout (array_type)
&& 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 */
{
@@ -2774,31 +2812,32 @@ apply_chill_array_layout (array_type)
temp = TREE_VALUE (layout);
if (TREE_VALUE (temp) != NULL_TREE)
{
- if (TREE_CODE (TREE_VALUE (temp)) != INTEGER_CST)
+ 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)
+ 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");
}
}
temp = TREE_PURPOSE (temp);
- 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");
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");
- if (word != 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;
@@ -2806,23 +2845,25 @@ apply_chill_array_layout (array_type)
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");
start_bit_error = 1;
}
else
{
- start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
- if (start_bit != 0)
+ if (! integer_zerop (TREE_PURPOSE (temp)))
sorry ("Starting bit in POS within STEP must be 0");
- if (start_bit < 0)
+
+ if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 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");
start_bit = 0;
@@ -2836,28 +2877,29 @@ apply_chill_array_layout (array_type)
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");
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");
}
}
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");
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");
@@ -2876,10 +2918,9 @@ apply_chill_array_layout (array_type)
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");
}
}
@@ -3053,8 +3094,10 @@ apply_chill_field_layout (decl, next_struct_offset)
if (is_discrete)
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;
if (layout == integer_zero_node) /* NOPACK */
{
@@ -3082,20 +3125,21 @@ apply_chill_field_layout (decl, next_struct_offset)
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");
pos_error = 1;
}
else
{
- word = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 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);
@@ -3105,7 +3149,7 @@ apply_chill_field_layout (decl, next_struct_offset)
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");
start_bit = *next_struct_offset - offset;
@@ -3113,14 +3157,15 @@ apply_chill_field_layout (decl, next_struct_offset)
}
else
{
- start_bit = TREE_INT_CST_LOW (TREE_PURPOSE (temp));
if (tree_int_cst_sgn (TREE_PURPOSE (temp)) < 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");
start_bit = *next_struct_offset - offset;
@@ -3134,32 +3179,34 @@ apply_chill_field_layout (decl, next_struct_offset)
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");
pos_error = 1;
}
else
{
- length = TREE_INT_CST_LOW (TREE_VALUE (temp));
if (tree_int_cst_sgn (TREE_VALUE (temp)) < 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");
pos_error = 1;
}
else
{
- HOST_WIDE_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)
{
OpenPOWER on IntegriCloud