aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1996-02-17 00:07:35 +0000
committerStu Grossman <grossman@cygnus>1996-02-17 00:07:35 +0000
commitaa220473ba2a00a9392bf5f410bf0e930691d6f1 (patch)
tree10a518b364b1fef3cb5acc1f503cadea617de9da /gdb/valops.c
parenta7e254eca39d54b30100c1a923bcafa417d9af57 (diff)
downloadfsf-binutils-gdb-aa220473ba2a00a9392bf5f410bf0e930691d6f1.zip
fsf-binutils-gdb-aa220473ba2a00a9392bf5f410bf0e930691d6f1.tar.gz
fsf-binutils-gdb-aa220473ba2a00a9392bf5f410bf0e930691d6f1.tar.bz2
* Add native support for long double data type.
* c-exp.y (%union): Change dval to typed_val_float. Use DOUBLEST to store actual data. Change types of INT and FLOAT tokens to typed_val_int and typed_val_float respectively. Create new token DOUBLE_KEYWORD to specify the string `double'. Make production for FLOAT use type determined by parse_number. Add production for "long double" data type. * (parse_number): Use sscanf to parse numbers as float, double or long double depending upon the type of typed_val_float.dval. Also allow user to specify `f' or `l' suffix to explicitly specify float or long double constants. Change typed_val to typed_val_int. * (yylex): Change typed_val to typed_val_int. Also, scan for "double" keyword. * coffread.c (decode_base_type): Add support for T_LNGDBL basic type. * configure, configure.in: Add check for long double support in the host compiler. * defs.h: Define DOUBLEST appropriatly depending on whether HAVE_LONG_DOUBLE (from autoconf) is defined. Also, fix prototypes for functions that handle this type. * expression.h (union exp_element): doubleconst is now type DOUBLEST. * m2-exp.y f-exp.y (%union): dval becomes type DOUBLEST. * findvar.c (extract_floating): Make return value be DOUBLEST. Also, add support for numbers with size of long double. * (store_floating): Arg `val' is now type DOUBLEST. Handle all floating types. * parser-defs.h parse.c (write_exp_elt_dblcst): Arg expelt is now DOUBLEST. * valarith.c (value_binop): Change temp variables v1, v2 and v to type DOUBLEST. Coerce type of result to long double if either op was of that type. * valops.c (value_arg_coerce): If argument type is bigger than double, coerce to long double. * (call_function_by_hand): If REG_STRUCT_HAS_ADDR is defined, and arg type is float and > 8 bytes, then use pointer-to-object calling conventions. * valprint.c (print_floating): Arg doub is now type DOUBLEST. Use appropriate format and precision to print out floating point values. * value.h: Fixup prototypes for value_as_double, value_from_double, and unpack_double to use DOUBLEST. * values.c (record_latest_value): Remove check for invalid floats. Allow history to store them so that people may examine them in hex if they want. * (value_as_double unpack_double): Change return value to DOUBLEST. * (value_from_double): Arg `num' is now DOUBLEST. * (using_struct_return): Use RETURN_VALUE_ON_STACK macro (target specific) to expect certain types to always be returned on the stack.
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index 046d213..e58f233 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -407,12 +407,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
@@ -886,10 +887,18 @@ 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 0
+ if (param_type == 0)
+#endif
+ {
+ 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;
@@ -1139,7 +1148,10 @@ call_function_by_hand (function, nargs, args)
|| TYPE_CODE (arg_type) == TYPE_CODE_ARRAY
|| 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_SET
+ || (TYPE_CODE (arg_type) == TYPE_CODE_FLT
+ && TYPE_LENGTH (arg_type) > 8)
+ )
&& REG_STRUCT_HAS_ADDR (using_gcc, arg_type))
{
CORE_ADDR addr;
@@ -1363,6 +1375,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
@@ -1377,10 +1406,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);
}