aboutsummaryrefslogtreecommitdiff
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
parenta7e254eca39d54b30100c1a923bcafa417d9af57 (diff)
downloadgdb-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/ChangeLog53
-rw-r--r--gdb/c-exp.y61
-rwxr-xr-xgdb/configure67
-rw-r--r--gdb/configure.in13
-rw-r--r--gdb/f-exp.y2
-rw-r--r--gdb/findvar.c37
-rw-r--r--gdb/m2-exp.y2
-rw-r--r--gdb/parse.c2
-rw-r--r--gdb/parser-defs.h2
-rw-r--r--gdb/valops.c45
-rw-r--r--gdb/values.c31
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;