aboutsummaryrefslogtreecommitdiff
path: root/gdb/c-exp.y
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/c-exp.y
parenta7e254eca39d54b30100c1a923bcafa417d9af57 (diff)
downloadbinutils-aa220473ba2a00a9392bf5f410bf0e930691d6f1.zip
binutils-aa220473ba2a00a9392bf5f410bf0e930691d6f1.tar.gz
binutils-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/c-exp.y')
-rw-r--r--gdb/c-exp.y61
1 files changed, 46 insertions, 15 deletions
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