X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/5e54886116dd58d05183a465350c127f65fa4460..a528763af3357cc4292e9e80602c6f652fc34983:/gdb/valops.c diff --git a/gdb/valops.c b/gdb/valops.c index b30f4b0b48..684b224cc8 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -32,6 +32,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include "gdb_string.h" +/* Default to coercing float to double in function calls only when there is + no prototype. Otherwise on targets where the debug information is incorrect + for either the prototype or non-prototype case, we can force it by defining + COERCE_FLOAT_TO_DOUBLE in the target configuration file. */ + +#ifndef COERCE_FLOAT_TO_DOUBLE +#define COERCE_FLOAT_TO_DOUBLE (param_type == NULL) +#endif + /* Local functions. */ static int typecmp PARAMS ((int staticp, struct type *t1[], value_ptr t2[])); @@ -57,7 +66,9 @@ static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr)); /* Flag for whether we want to abandon failed expression evals by default. */ +#if 0 static int auto_abandon = 0; +#endif /* Find the address of function name NAME in the inferior. */ @@ -187,11 +198,11 @@ value_cast (type, arg2) COERCE_VARYING_ARRAY (arg2, type2); code2 = TYPE_CODE (type2); - if (code1 == TYPE_CODE_COMPLEX) - return cast_into_complex (type, arg2); - if (code1 == TYPE_CODE_BOOL) + if (code1 == TYPE_CODE_COMPLEX) + return cast_into_complex (type, arg2); + if (code1 == TYPE_CODE_BOOL || code1 == TYPE_CODE_CHAR) code1 = TYPE_CODE_INT; - if (code2 == TYPE_CODE_BOOL) + if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR) code2 = TYPE_CODE_INT; scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT @@ -407,12 +418,13 @@ value_assign (toval, fromval) if (!toval->modifiable) error ("Left operand of assignment is not a modifiable lvalue."); - COERCE_ARRAY (fromval); COERCE_REF (toval); type = VALUE_TYPE (toval); if (VALUE_LVAL (toval) != lval_internalvar) fromval = value_cast (type, fromval); + else + COERCE_ARRAY (fromval); CHECK_TYPEDEF (type); /* If TOVAL is a special machine register requiring conversion @@ -439,7 +451,7 @@ value_assign (toval, fromval) { case lval_internalvar: set_internalvar (VALUE_INTERNALVAR (toval), fromval); - return VALUE_INTERNALVAR (toval)->value; + return value_copy (VALUE_INTERNALVAR (toval)->value); case lval_internalvar_component: set_internalvar_component (VALUE_INTERNALVAR (toval), @@ -460,7 +472,7 @@ value_assign (toval, fromval) + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - if (len > sizeof (LONGEST)) + if (len > (int) sizeof (LONGEST)) error ("Can't handle bitfields which don't fit in a %d bit word.", sizeof (LONGEST) * HOST_CHAR_BIT); @@ -485,7 +497,7 @@ value_assign (toval, fromval) char buffer[sizeof (LONGEST)]; int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval)); - if (len > sizeof (LONGEST)) + if (len > (int) sizeof (LONGEST)) error ("Can't handle bitfields in registers larger than %d bits.", sizeof (LONGEST) * HOST_CHAR_BIT); @@ -614,7 +626,7 @@ Can't handle bitfield which doesn't fit in a single register."); /* If the field does not entirely fill a LONGEST, then zero the sign bits. If the field is signed, and is negative, then sign extend. */ if ((VALUE_BITSIZE (toval) > 0) - && (VALUE_BITSIZE (toval) < 8 * sizeof (LONGEST))) + && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST))) { LONGEST fieldval = value_as_long (fromval); LONGEST valmask = (((unsigned LONGEST) 1) << VALUE_BITSIZE (toval)) - 1; @@ -886,10 +898,16 @@ value_arg_coerce (arg, param_type) if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) type = builtin_type_int; break; - case TYPE_CODE_FLT: - if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) - type = builtin_type_double; - break; + case TYPE_CODE_FLT: + /* coerce float to double, unless the function prototype specifies float */ + if (COERCE_FLOAT_TO_DOUBLE) + { + if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) + type = builtin_type_double; + else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double)) + type = builtin_type_long_double; + } + break; case TYPE_CODE_FUNC: type = lookup_pointer_type (type); break; @@ -1059,7 +1077,7 @@ call_function_by_hand (function, nargs, args) /* Create a call sequence customized for this function and the number of arguments for it. */ - for (i = 0; i < sizeof dummy / sizeof (dummy[0]); i++) + for (i = 0; i < (int) (sizeof (dummy) / sizeof (dummy[0])); i++) store_unsigned_integer (&dummy1[i * REGISTER_SIZE], REGISTER_SIZE, (unsigned LONGEST)dummy[i]); @@ -1137,7 +1155,12 @@ call_function_by_hand (function, nargs, args) if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT || TYPE_CODE (arg_type) == TYPE_CODE_UNION || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY - || TYPE_CODE (arg_type) == TYPE_CODE_STRING) + || TYPE_CODE (arg_type) == TYPE_CODE_STRING + || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING + || TYPE_CODE (arg_type) == TYPE_CODE_SET + || (TYPE_CODE (arg_type) == TYPE_CODE_FLT + && TYPE_LENGTH (arg_type) > 8) + ) && REG_STRUCT_HAS_ADDR (using_gcc, arg_type)) { CORE_ADDR addr; @@ -1338,7 +1361,7 @@ value_array (lowbound, highbound, elemvec) { int nelem; int idx; - int typelength; + unsigned int typelength; value_ptr val; struct type *rangetype; struct type *arraytype; @@ -1361,6 +1384,23 @@ value_array (lowbound, highbound, elemvec) } } + rangetype = create_range_type ((struct type *) NULL, builtin_type_int, + lowbound, highbound); + arraytype = create_array_type ((struct type *) NULL, + VALUE_TYPE (elemvec[0]), rangetype); + + if (!current_language->c_style_arrays) + { + val = allocate_value (arraytype); + for (idx = 0; idx < nelem; idx++) + { + memcpy (VALUE_CONTENTS_RAW (val) + (idx * typelength), + VALUE_CONTENTS (elemvec[idx]), + typelength); + } + return val; + } + /* Allocate space to store the array in the inferior, and then initialize it by copying in each element. FIXME: Is it worth it to create a local buffer in which to collect each value and then write all the @@ -1375,10 +1415,6 @@ value_array (lowbound, highbound, elemvec) /* Create the array type and set up an array value to be evaluated lazily. */ - rangetype = create_range_type ((struct type *) NULL, builtin_type_int, - lowbound, highbound); - arraytype = create_array_type ((struct type *) NULL, - VALUE_TYPE (elemvec[0]), rangetype); val = value_at_lazy (arraytype, addr); return (val); } @@ -1862,7 +1898,7 @@ destructor_name_p (name, type) { char *dname = type_name_no_tag (type); char *cp = strchr (dname, '<'); - int len; + unsigned int len; /* Do not compare the template part for template classes. */ if (cp == NULL) @@ -2155,35 +2191,60 @@ value_slice (array, lowbound, length) value_ptr array; int lowbound, length; { + struct type *slice_range_type, *slice_type, *range_type; + LONGEST lowerbound, upperbound, offset; + value_ptr slice; struct type *array_type; array_type = check_typedef (VALUE_TYPE (array)); COERCE_VARYING_ARRAY (array, array_type); - if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING) - error ("not implemented - bitstring slice"); if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY - && TYPE_CODE (array_type) != TYPE_CODE_STRING) + && TYPE_CODE (array_type) != TYPE_CODE_STRING + && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING) error ("cannot take slice of non-array"); + range_type = TYPE_INDEX_TYPE (array_type); + if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0) + error ("slice from bad array or bitstring"); + if (lowbound < lowerbound || length < 0 + || lowbound + length - 1 > upperbound + /* Chill allows zero-length strings but not arrays. */ + || (current_language->la_language == language_chill + && length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY)) + error ("slice out of range"); + /* FIXME-type-allocation: need a way to free this type when we are + done with it. */ + slice_range_type = create_range_type ((struct type*) NULL, + TYPE_TARGET_TYPE (range_type), + lowerbound, lowerbound + length - 1); + if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING) + { + int i; + slice_type = create_set_type ((struct type*) NULL, slice_range_type); + TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING; + slice = value_zero (slice_type, not_lval); + for (i = 0; i < length; i++) + { + int element = value_bit_index (array_type, + VALUE_CONTENTS (array), + lowbound + i); + if (element < 0) + error ("internal error accessing bitstring"); + else if (element > 0) + { + int j = i % TARGET_CHAR_BIT; + if (BITS_BIG_ENDIAN) + j = TARGET_CHAR_BIT - 1 - j; + VALUE_CONTENTS_RAW (slice)[i / TARGET_CHAR_BIT] |= (1 << j); + } + } + /* We should set the address, bitssize, and bitspos, so the clice + can be used on the LHS, but that may require extensions to + value_assign. For now, just leave as a non_lval. FIXME. */ + } else { - struct type *slice_range_type, *slice_type; - value_ptr slice; - struct type *range_type = TYPE_FIELD_TYPE (array_type,0); struct type *element_type = TYPE_TARGET_TYPE (array_type); - LONGEST lowerbound, upperbound, offset; - - if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0) - error ("slice from bad array"); offset = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type)); - if (lowbound < lowerbound || length < 0 - || lowbound + length - 1 > upperbound) - error ("slice out of range"); - /* FIXME-type-allocation: need a way to free this type when we are - done with it. */ - 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 (array_type); @@ -2199,8 +2260,8 @@ value_slice (array, lowbound, length) VALUE_LVAL (slice) = VALUE_LVAL (array); VALUE_ADDRESS (slice) = VALUE_ADDRESS (array); VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset; - return slice; } + return slice; } /* Assuming chill_varying_type (VARRAY) is true, return an equivalent