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 /gdb/c-exp.y | |
parent | a7e254eca39d54b30100c1a923bcafa417d9af57 (diff) | |
download | binutils-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.y | 61 |
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 |