diff options
author | Stu Grossman <grossman@cygnus> | 1996-02-17 00:07:35 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1996-02-17 00:07:35 +0000 |
commit | aa220473ba2a00a9392bf5f410bf0e930691d6f1 (patch) | |
tree | 10a518b364b1fef3cb5acc1f503cadea617de9da | |
parent | a7e254eca39d54b30100c1a923bcafa417d9af57 (diff) | |
download | gdb-aa220473ba2a00a9392bf5f410bf0e930691d6f1.zip gdb-aa220473ba2a00a9392bf5f410bf0e930691d6f1.tar.gz 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.
-rw-r--r-- | gdb/ChangeLog | 53 | ||||
-rw-r--r-- | gdb/c-exp.y | 61 | ||||
-rwxr-xr-x | gdb/configure | 67 | ||||
-rw-r--r-- | gdb/configure.in | 13 | ||||
-rw-r--r-- | gdb/f-exp.y | 2 | ||||
-rw-r--r-- | gdb/findvar.c | 37 | ||||
-rw-r--r-- | gdb/m2-exp.y | 2 | ||||
-rw-r--r-- | gdb/parse.c | 2 | ||||
-rw-r--r-- | gdb/parser-defs.h | 2 | ||||
-rw-r--r-- | gdb/valops.c | 45 | ||||
-rw-r--r-- | gdb/values.c | 31 |
11 files changed, 250 insertions, 65 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1310795..8114a0a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,56 @@ +Thu Feb 16 16:02:03 1996 Stu Grossman (grossman@cygnus.com) + + * 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. + Fri Feb 16 14:00:54 1996 Fred Fish <fnf@cygnus.com> * bcache.c, bcache.h: New files to implement a byte cache. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index f6bd88f..9070a05 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -119,8 +119,11 @@ yyerror PARAMS ((char *)); struct { LONGEST val; struct type *type; - } typed_val; - double dval; + } typed_val_int; + struct { + DOUBLEST dval; + struct type *type; + } typed_val_float; struct symbol *sym; struct type *tval; struct stoken sval; @@ -152,8 +155,8 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *)); %type <tval> ptype %type <lval> array_mod -%token <typed_val> INT -%token <dval> FLOAT +%token <typed_val_int> INT +%token <typed_val_float> FLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -183,7 +186,7 @@ parse_number PARAMS ((char *, int, int, YYSTYPE *)); /* Special type cases, put in to allow the parser to distinguish different legal basetypes. */ -%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD +%token SIGNED_KEYWORD LONG SHORT INT_KEYWORD CONST_KEYWORD VOLATILE_KEYWORD DOUBLE_KEYWORD %token <voidval> VARIABLE @@ -473,8 +476,8 @@ exp : NAME_OR_INT { YYSTYPE val; parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val); write_exp_elt_opcode (OP_LONG); - write_exp_elt_type (val.typed_val.type); - write_exp_elt_longcst ((LONGEST)val.typed_val.val); + write_exp_elt_type (val.typed_val_int.type); + write_exp_elt_longcst ((LONGEST)val.typed_val_int.val); write_exp_elt_opcode (OP_LONG); } ; @@ -482,8 +485,8 @@ exp : NAME_OR_INT exp : FLOAT { write_exp_elt_opcode (OP_DOUBLE); - write_exp_elt_type (builtin_type_double); - write_exp_elt_dblcst ($1); + write_exp_elt_type ($1.type); + write_exp_elt_dblcst ($1.dval); write_exp_elt_opcode (OP_DOUBLE); } ; @@ -806,6 +809,10 @@ typebase /* Implements (approximately): (type-qualifier)* type-specifier */ { $$ = builtin_type_short; } | UNSIGNED SHORT INT_KEYWORD { $$ = builtin_type_unsigned_short; } + | DOUBLE_KEYWORD + { $$ = builtin_type_double; } + | LONG DOUBLE_KEYWORD + { $$ = builtin_type_long_double; } | STRUCT name { $$ = lookup_struct (copy_name ($2), expression_context_block); } @@ -926,8 +933,30 @@ parse_number (p, len, parsed_float, putithere) if (parsed_float) { + char c; + /* It's a float since it contains a point or an exponent. */ - putithere->dval = atof (p); + + if (sizeof (putithere->typed_val_float.dval) <= sizeof (float)) + sscanf (p, "%g", &putithere->typed_val_float.dval); + else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double)) + sscanf (p, "%lg", &putithere->typed_val_float.dval); + else + sscanf (p, "%Lg", &putithere->typed_val_float.dval); + + /* See if it has `f' or `l' suffix (float or long double). */ + + c = tolower (p[len - 1]); + + if (c == 'f') + putithere->typed_val_float.type = builtin_type_float; + else if (c == 'l') + putithere->typed_val_float.type = builtin_type_long_double; + else if (isdigit (c) || c == '.') + putithere->typed_val_float.type = builtin_type_double; + else + return ERROR; + return FLOAT; } @@ -1064,18 +1093,18 @@ parse_number (p, len, parsed_float, putithere) signed_type = builtin_type_long_long; } - putithere->typed_val.val = n; + putithere->typed_val_int.val = n; /* If the high bit of the worked out type is set then this number has to be unsigned. */ if (unsigned_p || (n & high_bit)) { - putithere->typed_val.type = unsigned_type; + putithere->typed_val_int.type = unsigned_type; } else { - putithere->typed_val.type = signed_type; + putithere->typed_val_int.type = signed_type; } return INT; @@ -1175,8 +1204,8 @@ yylex () else if (c == '\'') error ("Empty character constant."); - yylval.typed_val.val = c; - yylval.typed_val.type = builtin_type_char; + yylval.typed_val_int.val = c; + yylval.typed_val_int.type = builtin_type_char; c = *lexptr++; if (c != '\'') @@ -1409,6 +1438,8 @@ yylex () return SIGNED_KEYWORD; if (STREQN (tokstart, "sizeof", 6)) return SIZEOF; + if (STREQN (tokstart, "double", 6)) + return DOUBLE_KEYWORD; break; case 5: if (current_language->la_language == language_cplus diff --git a/gdb/configure b/gdb/configure index 826bea7..7d074cc 100755 --- a/gdb/configure +++ b/gdb/configure @@ -1295,6 +1295,39 @@ EOF fi + +echo $ac_n "checking for long double""... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_c_long_double'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <<EOF +#line 1305 "configure" +#include "confdefs.h" + +int main() { return 0; } +int t() { +long double foo; +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + ac_cv_c_long_double=yes +else + rm -rf conftest* + ac_cv_c_long_double=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_c_long_double" 1>&6 +if test $ac_cv_c_long_double = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_LONG_DOUBLE 1 +EOF + +fi + for ac_func in valloc getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 @@ -1302,7 +1335,7 @@ if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 1306 "configure" +#line 1339 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -1354,7 +1387,7 @@ else ac_cv_func_mmap=no else cat > conftest.$ac_ext <<EOF -#line 1358 "configure" +#line 1391 "configure" #include "confdefs.h" /* Thanks to Mike Haertel and Jim Avera for this test. */ @@ -1588,7 +1621,7 @@ test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h cat > conftest.$ac_ext <<EOF -#line 1592 "configure" +#line 1625 "configure" #include "confdefs.h" #include <$x_direct_test_include> EOF @@ -1651,7 +1684,7 @@ rm -f conftest* ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <<EOF -#line 1655 "configure" +#line 1688 "configure" #include "confdefs.h" int main() { return 0; } @@ -1770,7 +1803,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lICE $LIBS" cat > conftest.$ac_ext <<EOF -#line 1774 "configure" +#line 1807 "configure" #include "confdefs.h" int main() { return 0; } @@ -1814,7 +1847,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <<EOF -#line 1818 "configure" +#line 1851 "configure" #include "confdefs.h" int main() { return 0; } @@ -1849,7 +1882,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <<EOF -#line 1853 "configure" +#line 1886 "configure" #include "confdefs.h" int main() { return 0; } @@ -1889,7 +1922,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <<EOF -#line 1893 "configure" +#line 1926 "configure" #include "confdefs.h" int main() { return 0; } @@ -1928,7 +1961,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <<EOF -#line 1932 "configure" +#line 1965 "configure" #include "confdefs.h" int main() { return 0; } @@ -2033,7 +2066,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2037 "configure" +#line 2070 "configure" #include "confdefs.h" #include <tclInt.h> EOF @@ -2090,7 +2123,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext <<EOF -#line 2094 "configure" +#line 2127 "configure" #include "confdefs.h" #include <stdio.h> @@ -2250,7 +2283,7 @@ else ac_cv_c_tclib="-l$installedtcllibroot" else cat > conftest.$ac_ext <<EOF -#line 2254 "configure" +#line 2287 "configure" #include "confdefs.h" Tcl_AppInit() @@ -2366,7 +2399,7 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 2370 "configure" +#line 2403 "configure" #include "confdefs.h" #include <tk.h> EOF @@ -2430,7 +2463,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext <<EOF -#line 2434 "configure" +#line 2467 "configure" #include "confdefs.h" #include <stdio.h> @@ -2611,7 +2644,7 @@ else ac_cv_c_tklib="-l$installedtklibroot" else cat > conftest.$ac_ext <<EOF -#line 2615 "configure" +#line 2648 "configure" #include "confdefs.h" Tcl_AppInit() @@ -2658,7 +2691,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <<EOF -#line 2662 "configure" +#line 2695 "configure" #include "confdefs.h" int main() { return 0; } @@ -2696,7 +2729,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <<EOF -#line 2700 "configure" +#line 2733 "configure" #include "confdefs.h" int main() { return 0; } diff --git a/gdb/configure.in b/gdb/configure.in index 71b8288..f560def 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -57,6 +57,19 @@ if test $gdb_have_fpregset_t = yes; then AC_DEFINE(HAVE_FPREGSET_T) fi +dnl See if compiler supports "long double" type. Can't use AC_C_LONG_DOUBLE +dnl because autoconf complains about cross-compilation issues. However, this +dnl code uses the same variables as the macro for compatibility. + +AC_MSG_CHECKING(for long double) +AC_CACHE_VAL(ac_cv_c_long_double, +[AC_TRY_COMPILE(, [long double foo;], +ac_cv_c_long_double=yes, ac_cv_c_long_double=no)]) +AC_MSG_RESULT($ac_cv_c_long_double) +if test $ac_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE) +fi + AC_FUNC_MMAP dnl Handle optional features that can be enabled. diff --git a/gdb/f-exp.y b/gdb/f-exp.y index 6b6aa98..b50094a 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -122,7 +122,7 @@ void yyerror PARAMS ((char *)); LONGEST val; struct type *type; } typed_val; - double dval; + DOUBLEST dval; struct symbol *sym; struct type *tval; struct stoken sval; diff --git a/gdb/findvar.c b/gdb/findvar.c index fd3a532..f0f46d6 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" @@ -228,7 +228,7 @@ store_address (addr, len, val) 3. We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever we want to call it which is long double where available. */ -double +DOUBLEST extract_floating (addr, len) PTR addr; int len; @@ -247,6 +247,13 @@ extract_floating (addr, len) SWAP_FLOATING (&retval, sizeof (retval)); return retval; } + else if (len == sizeof (long double)) + { + long double retval; + memcpy (&retval, addr, sizeof (retval)); + SWAP_FLOATING (&retval, sizeof (retval)); + return retval; + } else { error ("Can't deal with a floating point number of %d bytes.", len); @@ -257,7 +264,7 @@ void store_floating (addr, len, val) PTR addr; int len; - double val; + DOUBLEST val; { if (len == sizeof (float)) { @@ -267,6 +274,13 @@ store_floating (addr, len, val) } else if (len == sizeof (double)) { + double doubleval = val; + + SWAP_FLOATING (&doubleval, sizeof (doubleval)); + memcpy (addr, &doubleval, sizeof (doubleval)); + } + else if (len == sizeof (long double)) + { SWAP_FLOATING (&val, sizeof (val)); memcpy (addr, &val, sizeof (val)); } @@ -971,6 +985,7 @@ symbol_read_needs_frame (sym) case LOC_BLOCK: case LOC_CONST_BYTES: + case LOC_UNRESOLVED: case LOC_OPTIMIZED_OUT: return 0; } @@ -1098,6 +1113,17 @@ read_var_value (var, frame) } break; + case LOC_UNRESOLVED: + { + struct minimal_symbol *msym; + + msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL); + if (msym == NULL) + return 0; + addr = SYMBOL_VALUE_ADDRESS (msym); + } + break; + case LOC_OPTIMIZED_OUT: VALUE_LVAL (v) = not_lval; VALUE_OPTIMIZED_OUT (v) = 1; @@ -1126,11 +1152,14 @@ value_from_register (type, regnum, frame) CORE_ADDR addr; int optim; value_ptr v = allocate_value (type); - int len = TYPE_LENGTH (type); char *value_bytes = 0; int value_bytes_copied = 0; int num_storage_locs; enum lval_type lval; + int len; + + CHECK_TYPEDEF (type); + len = TYPE_LENGTH (type); VALUE_REGNO (v) = regnum; diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 9ec896f..35f7423 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -136,7 +136,7 @@ static struct block *modblock=0; { LONGEST lval; unsigned LONGEST ulval; - double dval; + DOUBLEST dval; struct symbol *sym; struct type *tval; struct stoken sval; diff --git a/gdb/parse.c b/gdb/parse.c index 316ab53..7d458c1 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -215,7 +215,7 @@ write_exp_elt_longcst (expelt) void write_exp_elt_dblcst (expelt) - double expelt; + DOUBLEST expelt; { union exp_element tmp; diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index c9c5b46..9e7b1c7 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -95,7 +95,7 @@ extern void write_exp_elt_sym PARAMS ((struct symbol *)); extern void write_exp_elt_longcst PARAMS ((LONGEST)); -extern void write_exp_elt_dblcst PARAMS ((double)); +extern void write_exp_elt_dblcst PARAMS ((DOUBLEST)); extern void write_exp_elt_type PARAMS ((struct type *)); 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); } diff --git a/gdb/values.c b/gdb/values.c index 991d374..b1776ae 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -239,14 +239,6 @@ record_latest_value (val) { int i; - /* Check error now if about to store an invalid float. We return -1 - to the caller, but allow them to continue, e.g. to print it as "Nan". */ - if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT) - { - unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i); - if (i) return -1; /* Indicate value not saved in history */ - } - /* We don't want this value to have anything to do with the inferior anymore. In particular, "set $1 = 50" should not affect the variable from which the value was taken, and fast watchpoints should be able to assume that @@ -560,11 +552,11 @@ value_as_long (val) return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val)); } -double +DOUBLEST value_as_double (val) register value_ptr val; { - double foo; + DOUBLEST foo; int inv; foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv); @@ -655,7 +647,7 @@ unpack_long (type, valaddr) the returned double is OK to use. Argument is in target format, result is in host format. */ -double +DOUBLEST unpack_double (type, valaddr, invp) struct type *type; char *valaddr; @@ -1268,7 +1260,7 @@ value_from_longest (type, num) value_ptr value_from_double (type, num) struct type *type; - double num; + DOUBLEST num; { register value_ptr val = allocate_value (type); struct type *base_type = check_typedef (type); @@ -1350,6 +1342,14 @@ value_being_returned (valtype, retbuf, struct_return) )) #endif +/* Some fundamental types (such as long double) are returned on the stack for + certain architectures. This macro should return true for any type besides + struct, union or array that gets returned on the stack. */ + +#ifndef RETURN_VALUE_ON_STACK +#define RETURN_VALUE_ON_STACK(TYPE) 0 +#endif + /* Return true if the function specified is using the structure returning convention on this machine to return arguments, or 0 if it is using the value returning convention. FUNCTION is the value representing @@ -1370,9 +1370,10 @@ using_struct_return (function, funcaddr, value_type, gcc_p) if (code == TYPE_CODE_ERROR) error ("Function return type unknown."); - if (code == TYPE_CODE_STRUCT || - code == TYPE_CODE_UNION || - code == TYPE_CODE_ARRAY) + if (code == TYPE_CODE_STRUCT + || code == TYPE_CODE_UNION + || code == TYPE_CODE_ARRAY + || RETURN_VALUE_ON_STACK (value_type)) return USE_STRUCT_CONVENTION (gcc_p, value_type); return 0; |