* ch-exp.y (value_string_element, string_primitive_value,

start_element, left_element, right_element, slice_size,
	lower_element, upper_element, first_element):  Removed.
	(value_string_slice, value_array_slice):  Replaced by ...
	(slice):  New non-terminal, with working slice support.
	(primitive_value_lparen, rparen):  New non-terminals.
	(maybe_tuple_elements):  New non-terminal, to allow empty tuples.
	(idtokentab):  Added "up".

	* value.h (COERCE_VARYING_ARRAY):  New macro.
	* valarith.c (value_subscript):  Use it.
	* valops.c (value_cast):  Likewise.  Also, do nothing if already
	correct type, and allow converting from/to range to/from scalar.

	* valops.c, value.h (varying_to_slice, value_slice):  New functions.
	* eval.c (OP_ARRAY):  Add cast for array element.
	* expression.h (TERNOP_SLICE, TERNOP_SLICE_COUNT):  New exp_opcodes.
	* valops.c (chill_varying_type):  Moved function frp, here ...
	* gdbtypes.c (chill_varying_type), gdbtypes.h: ... to here.
	* parse.c (length_of_subexp, prefixify_subexp):  Add support
	for TERNOP_SLICE, TERNOP_SLICE_COUNT.
	* expprint.c (print_subexp, dump_expression):  Likewise.
	* eval.c (evaluate_subexp):  Likewise.

	* eval.c (evaluate_subexp case MULTI_SUBSCRIPT):  Don't call
	value_x_binop on a Chill varying string.
This commit is contained in:
Per Bothner
1995-02-01 21:02:51 +00:00
parent e1affd5840
commit f91a9e05e0
9 changed files with 395 additions and 149 deletions

View File

@@ -129,6 +129,11 @@ value_cast (type, arg2)
register enum type_code code2;
register int scalar;
if (VALUE_TYPE (arg2) == type)
return arg2;
COERCE_VARYING_ARRAY (arg2);
/* Coerce arrays but not enums. Enums will work as-is
and coercing them would cause an infinite recursion. */
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_ENUM)
@@ -145,7 +150,7 @@ value_cast (type, arg2)
code2 = TYPE_CODE_INT;
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_ENUM);
|| code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
if ( code1 == TYPE_CODE_STRUCT
&& code2 == TYPE_CODE_STRUCT
@@ -164,7 +169,8 @@ value_cast (type, arg2)
}
if (code1 == TYPE_CODE_FLT && scalar)
return value_from_double (type, value_as_double (arg2));
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM)
else if ((code1 == TYPE_CODE_INT || code1 == TYPE_CODE_ENUM
|| code1 == TYPE_CODE_RANGE)
&& (scalar || code2 == TYPE_CODE_PTR))
return value_from_longest (type, value_as_long (arg2));
else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2)))
@@ -194,6 +200,40 @@ value_cast (type, arg2)
VALUE_TYPE (arg2) = type;
return arg2;
}
else if (chill_varying_type (type))
{
struct type *range1, *range2, *eltype1, *eltype2;
value_ptr val;
int count1, count2;
char *valaddr, *valaddr_data;
if (code2 == TYPE_CODE_BITSTRING)
error ("not implemented: converting bitstring to varying type");
if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING)
|| (eltype1 = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1)),
eltype2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)),
(TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2)
/* || TYPE_CODE (eltype1) != TYPE_CODE (eltype2) */ )))
error ("Invalid conversion to varying type");
range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0);
range2 = TYPE_FIELD_TYPE (VALUE_TYPE (arg2), 0);
count1 = TYPE_HIGH_BOUND (range1) - TYPE_LOW_BOUND (range1) + 1;
count2 = TYPE_HIGH_BOUND (range2) - TYPE_LOW_BOUND (range2) + 1;
if (count2 > count1)
error ("target varying type is too small");
val = allocate_value (type);
valaddr = VALUE_CONTENTS_RAW (val);
valaddr_data = valaddr + TYPE_FIELD_BITPOS (type, 1) / 8;
/* Set val's __var_length field to count2. */
store_signed_integer (valaddr, TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)),
count2);
/* Set the __var_data field to count2 elements copied from arg2. */
memcpy (valaddr_data, VALUE_CONTENTS (arg2),
count2 * TYPE_LENGTH (eltype2));
/* Zero the rest of the __var_data field of val. */
memset (valaddr_data + count2 * TYPE_LENGTH (eltype2), '\0',
(count1 - count2) * TYPE_LENGTH (eltype2));
return val;
}
else if (VALUE_LVAL (arg2) == lval_memory)
{
return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
@@ -679,8 +719,9 @@ value_addr (arg1)
VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type));
return arg2;
}
if (VALUE_REPEATED (arg1)
|| TYPE_CODE (type) == TYPE_CODE_ARRAY)
if (current_language->c_style_arrays
&& (VALUE_REPEATED (arg1)
|| TYPE_CODE (type) == TYPE_CODE_ARRAY))
return value_coerce_array (arg1);
if (TYPE_CODE (type) == TYPE_CODE_FUNC)
return value_coerce_function (arg1);
@@ -799,8 +840,9 @@ value_arg_coerce (arg)
arg = value_cast (builtin_type_unsigned_int, arg);
#if 1 /* FIXME: This is only a temporary patch. -fnf */
if (VALUE_REPEATED (arg)
|| TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)
if (current_language->c_style_arrays
&& (VALUE_REPEATED (arg)
|| TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY))
arg = value_coerce_array (arg);
if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FUNC)
arg = value_coerce_function (arg);
@@ -1278,22 +1320,26 @@ value_string (ptr, len)
int len;
{
value_ptr val;
struct type *rangetype;
struct type *stringtype;
struct type *rangetype = create_range_type ((struct type *) NULL,
builtin_type_int, 0, len - 1);
struct type *stringtype
= create_string_type ((struct type *) NULL, rangetype);
CORE_ADDR addr;
if (current_language->c_style_arrays == 0)
{
val = allocate_value (stringtype);
memcpy (VALUE_CONTENTS_RAW (val), ptr, len);
return val;
}
/* Allocate space to store the string in the inferior, and then
copy LEN bytes from PTR in gdb to that address in the inferior. */
addr = allocate_space_in_inferior (len);
write_memory (addr, ptr, len);
/* Create the string type and set up a string value to be evaluated
lazily. */
rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
0, len - 1);
stringtype = create_string_type ((struct type *) NULL, rangetype);
val = value_at_lazy (stringtype, addr);
return (val);
}
@@ -2043,6 +2089,69 @@ f77_value_literal_string (lowbound, highbound, elemvec)
return val;
}
/* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH elements
long, starting at LOWBOUND. The result has the same lower bound as
the original ARRAY. */
value_ptr
value_slice (array, lowbound, length)
value_ptr array;
int lowbound, length;
{
if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_BITSTRING)
error ("not implemented - bitstring slice");
if (TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_ARRAY
&& TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_STRING)
error ("cannot take slice of non-array");
else
{
struct type *slice_range_type, *slice_type;
value_ptr slice;
struct type *range_type = TYPE_FIELD_TYPE (VALUE_TYPE (array), 0);
struct type *element_type = TYPE_TARGET_TYPE (VALUE_TYPE (array));
int lowerbound = TYPE_LOW_BOUND (range_type);
int upperbound = TYPE_HIGH_BOUND (range_type);
int offset = (lowbound - lowerbound) * TYPE_LENGTH (element_type);
if (lowbound < lowerbound || length < 0
|| lowbound + length - 1 > upperbound)
error ("slice out of range");
slice_range_type = create_range_type ((struct type*) NULL,
TYPE_TARGET_TYPE (range_type),
lowerbound,
lowerbound + length - 1);
slice_type = create_array_type ((struct type*) NULL, element_type,
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (VALUE_TYPE (array));
slice = allocate_value (slice_type);
if (VALUE_LAZY (array))
VALUE_LAZY (slice) = 1;
else
memcpy (VALUE_CONTENTS (slice), VALUE_CONTENTS (array) + offset,
TYPE_LENGTH (slice_type));
if (VALUE_LVAL (array) == lval_internalvar)
VALUE_LVAL (slice) = lval_internalvar_component;
else
VALUE_LVAL (slice) = VALUE_LVAL (array);
VALUE_ADDRESS (slice) = VALUE_ADDRESS (array);
VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset;
return slice;
}
}
/* Assuming chill_varying_type (VARRAY) is true, return an equivalent
value as a fixed-length array. */
value_ptr
varying_to_slice (varray)
value_ptr varray;
{
struct type *vtype = VALUE_TYPE (varray);
LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0),
VALUE_CONTENTS (varray)
+ TYPE_FIELD_BITPOS (vtype, 0) / 8);
return value_slice (value_primitive_field (varray, 0, 1, vtype), 0, length);
}
/* Create a value for a substring. We copy data into a local
(NOT inferior's memory) buffer, and then set up an array value.