%{
#include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
+#include <ctype.h>
#include "expression.h"
#include "value.h"
#include "parser-defs.h"
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;
%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.
/* 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
{ 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);
}
;
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); }
;
exp : SIZEOF '(' type ')' %prec UNARY
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type (builtin_type_int);
+ CHECK_TYPEDEF ($3);
write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
write_exp_elt_opcode (OP_LONG); }
;
{ $$ = 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); }
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
+ {
+#ifdef PRINTF_HAS_LONG_DOUBLE
+ sscanf (p, "%Lg", &putithere->typed_val_float.dval);
+#else
+ /* Scan it into a double, then assign it to the long double.
+ This at least wins with values representable in the range
+ of doubles. */
+ double temp;
+ sscanf (p, "%lg", &temp);
+ putithere->typed_val_float.dval = temp;
+#endif
+ }
+
+ /* 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;
}
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;
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 != '\'')
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