diff options
-rw-r--r-- | gdb/ChangeLog | 82 | ||||
-rw-r--r-- | gdb/ada-exp.y | 24 | ||||
-rw-r--r-- | gdb/ada-lang.c | 6 | ||||
-rw-r--r-- | gdb/ada-lex.l | 14 | ||||
-rw-r--r-- | gdb/breakpoint.c | 3 | ||||
-rw-r--r-- | gdb/c-exp.y | 79 | ||||
-rw-r--r-- | gdb/d-exp.y | 73 | ||||
-rw-r--r-- | gdb/doublest.c | 29 | ||||
-rw-r--r-- | gdb/doublest.h | 2 | ||||
-rw-r--r-- | gdb/eval.c | 11 | ||||
-rw-r--r-- | gdb/expprint.c | 13 | ||||
-rw-r--r-- | gdb/expression.h | 4 | ||||
-rw-r--r-- | gdb/f-exp.y | 29 | ||||
-rw-r--r-- | gdb/go-exp.y | 60 | ||||
-rw-r--r-- | gdb/m2-exp.y | 16 | ||||
-rw-r--r-- | gdb/p-exp.y | 35 | ||||
-rw-r--r-- | gdb/parse.c | 91 | ||||
-rw-r--r-- | gdb/parser-defs.h | 12 | ||||
-rw-r--r-- | gdb/rust-exp.y | 33 | ||||
-rw-r--r-- | gdb/std-operator.def | 11 |
20 files changed, 332 insertions, 295 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2107679..8835572 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,85 @@ +2017-10-25 Ulrich Weigand <uweigand@de.ibm.com> + + * doublest.c (floatformat_from_string): New function. + * doublest.h (floatformat_from_string): Add prototype. + + * std-operator.def (OP_DOUBLE, OP_DECFLOAT): Remove, replace by ... + (OP_FLOAT): ... this. + * expression.h: Do not include "doublest.h". + (union exp_element): Replace doubleconst and decfloatconst by + new element floatconst. + * ada-lang.c (resolve_subexp): Handle OP_FLOAT instead of OP_DOUBLE. + (ada_evaluate_subexp): Likewise. + * eval.c (evaluate_subexp_standard): Handle OP_FLOAT instead of + OP_DOUBLE and OP_DECFLOAT. + * expprint.c (print_subexp_standard): Likewise. + (dump_subexp_body_standard): Likewise. + * breakpoint.c (watchpoint_exp_is_const): Likewise. + + * parse.c: Include "dfp.h". + (write_exp_elt_dblcst, write_exp_elt_decfloatcst): Remove. + (write_exp_elt_floatcst): New function. + (operator_length_standard): Handle OP_FLOAT instead of OP_DOUBLE + and OP_DECFLOAT. + (operator_check_standard): Likewise. + (parse_float): Do not accept suffix. Take type as input. Return bool. + Return target format buffer instead of host DOUBLEST. + Use floatformat_from_string and decimal_from_string to parse + either binary or decimal floating-point types. + (parse_c_float): Remove. + * parser-defs.h: Do not include "doublest.h". + (write_exp_elt_dblcst, write_exp_elt_decfloatcst): Remove. + (write_exp_elt_floatcst): Add prototype. + (parse_float): Update prototype. + (parse_c_float): Remove. + + * c-exp.y: Do not include "dfp.h". + (typed_val_float): Use byte buffer instead of DOUBLEST. + (typed_val_decfloat): Remove. + (DECFLOAT): Remove. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Update to new parse_float interface. + Parse suffixes and determine type before calling parse_float. + Handle decimal and binary FP types the same way. + + * d-exp.y (typed_val_float): Use byte buffer instead of DOUBLEST. + (FLOAT_LITERAL): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Update to new parse_float interface. + Parse suffixes and determine type before calling parse_float. + + * f-exp.y: Replace dval by typed_val_float. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Use parse_float instead of atof. + + * go-exp.y (typed_val_float): Use byte buffer instead of DOUBLEST. + (parse_go_float): Remove. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Call parse_float instead of parse_go_float. + Parse suffixes and determine type before calling parse_float. + + * p-exp.y (typed_val_float): Use byte buffer instead of DOUBLEST. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Update to new parse_float interface. + Parse suffixes and determine type before calling parse_float. + + * m2-exp.y: Replace dval by byte buffer val. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + (parse_number): Call parse_float instead of atof. + + * rust-exp.y (typed_val_float): Use byte buffer instead of DOUBLEST. + (lex_number): Call parse_float instead of strtod. + (ast_dliteral): Use OP_FLOAT instead of OP_DOUBLE. + (convert_ast_to_expression): Handle OP_FLOAT instead of OP_DOUBLE. + Use write_exp_elt_floatcst. + (unit_testing): Remove static variable. + (rust_type): Do not check unit_testing. + (rust_lex_tests): Do not set uint_testing. Set up dummy rust_parser. + + * ada-exp.y (type_float, type_double): Remove. + (typed_val_float): Use byte buffer instead of DOUBLEST. + (FLOAT): Use OP_FLOAT and write_exp_elt_floatcst. + * ada-lex.l (processReal): Use parse_float instead of sscanf. + 2017-10-25 Alan Hayward <alan.hayward@arm.com> * aarch64-tdep.h (enum aarch64_regnum): Remove. diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index 4c1ff7b..3014a31 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -106,10 +106,6 @@ static struct type *type_long (struct parser_state *); static struct type *type_long_long (struct parser_state *); -static struct type *type_float (struct parser_state *); - -static struct type *type_double (struct parser_state *); - static struct type *type_long_double (struct parser_state *); static struct type *type_char (struct parser_state *); @@ -128,7 +124,7 @@ static struct type *type_system_address (struct parser_state *); struct type *type; } typed_val; struct { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; } typed_val_float; struct type *tval; @@ -553,10 +549,10 @@ primary : CHARLIT ; primary : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, $1.type); - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; @@ -1440,18 +1436,6 @@ type_long_long (struct parser_state *par_state) } static struct type * -type_float (struct parser_state *par_state) -{ - return parse_type (par_state)->builtin_float; -} - -static struct type * -type_double (struct parser_state *par_state) -{ - return parse_type (par_state)->builtin_double; -} - -static struct type * type_long_double (struct parser_state *par_state) { return parse_type (par_state)->builtin_long_double; diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 7409496..b8636e6 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -3384,7 +3384,7 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p, break; case OP_LONG: - case OP_DOUBLE: + case OP_FLOAT: case OP_VAR_VALUE: case OP_VAR_MSYM_VALUE: *pos += 4; @@ -10421,7 +10421,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, if (noside == EVAL_NORMAL) arg1 = unwrap_value (arg1); - /* If evaluating an OP_DOUBLE and an EXPECT_TYPE was provided, + /* If evaluating an OP_FLOAT and an EXPECT_TYPE was provided, then we need to perform the conversion manually, because evaluate_subexp_standard doesn't do it. This conversion is necessary in Ada because the different kinds of float/fixed @@ -10429,7 +10429,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, Similarly, we need to perform the conversion from OP_LONG ourselves. */ - if ((op == OP_DOUBLE || op == OP_LONG) && expect_type != NULL) + if ((op == OP_FLOAT || op == OP_LONG) && expect_type != NULL) arg1 = ada_value_cast (expect_type, arg1, noside); return arg1; diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l index fe97352..ce8de69 100644 --- a/gdb/ada-lex.l +++ b/gdb/ada-lex.l @@ -403,16 +403,12 @@ processInt (struct parser_state *par_state, const char *base0, static int processReal (struct parser_state *par_state, const char *num0) { - sscanf (num0, "%" DOUBLEST_SCAN_FORMAT, &yylval.typed_val_float.dval); - - yylval.typed_val_float.type = type_float (par_state); - if (sizeof(DOUBLEST) >= gdbarch_double_bit (parse_gdbarch (par_state)) - / TARGET_CHAR_BIT) - yylval.typed_val_float.type = type_double (par_state); - if (sizeof(DOUBLEST) >= gdbarch_long_double_bit (parse_gdbarch (par_state)) - / TARGET_CHAR_BIT) - yylval.typed_val_float.type = type_long_double (par_state); + yylval.typed_val_float.type = type_long_double (par_state); + bool parsed = parse_float (num0, strlen (num0), + yylval.typed_val_float.type, + yylval.typed_val_float.val); + gdb_assert (parsed); return FLOAT; } diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 32ceea7..e16cfb6 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -10121,8 +10121,7 @@ watchpoint_exp_is_const (const struct expression *exp) case TERNOP_SLICE: case OP_LONG: - case OP_DOUBLE: - case OP_DECFLOAT: + case OP_FLOAT: case OP_LAST: case OP_COMPLEX: case OP_STRING: diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 18c74d8..8eaf7c0 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -48,7 +48,6 @@ #include "charset.h" #include "block.h" #include "cp-support.h" -#include "dfp.h" #include "macroscope.h" #include "objc-lang.h" #include "typeprint.h" @@ -88,13 +87,9 @@ static int type_aggregate_p (struct type *); struct type *type; } typed_val_int; struct { - DOUBLEST dval; - struct type *type; - } typed_val_float; - struct { gdb_byte val[16]; struct type *type; - } typed_val_decfloat; + } typed_val_float; struct type *tval; struct stoken sval; struct typed_stoken tsval; @@ -142,7 +137,6 @@ static void c_print_token (FILE *file, int type, YYSTYPE value); %token <typed_val_int> INT %token <typed_val_float> FLOAT -%token <typed_val_decfloat> DECFLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -749,17 +743,10 @@ exp : NAME_OR_INT exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, $1.type); - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); } - ; - -exp : DECFLOAT - { write_exp_elt_opcode (pstate, OP_DECFLOAT); - write_exp_elt_type (pstate, $1.type); - write_exp_elt_decfloatcst (pstate, $1.val); - write_exp_elt_opcode (pstate, OP_DECFLOAT); } + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -1792,43 +1779,49 @@ parse_number (struct parser_state *par_state, if (parsed_float) { - /* If it ends at "df", "dd" or "dl", take it as type of decimal floating - point. Return DECFLOAT. */ - + /* Handle suffixes for decimal floating-point: "df", "dd" or "dl". */ if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'f') { - putithere->typed_val_decfloat.type + putithere->typed_val_float.type = parse_type (par_state)->builtin_decfloat; - decimal_from_string (putithere->typed_val_decfloat.val, 4, - gdbarch_byte_order (parse_gdbarch (par_state)), - std::string (p, len - 2)); - return DECFLOAT; + len -= 2; } - - if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'd') + else if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'd') { - putithere->typed_val_decfloat.type + putithere->typed_val_float.type = parse_type (par_state)->builtin_decdouble; - decimal_from_string (putithere->typed_val_decfloat.val, 8, - gdbarch_byte_order (parse_gdbarch (par_state)), - std::string (p, len - 2)); - return DECFLOAT; + len -= 2; } - - if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'l') + else if (len >= 2 && p[len - 2] == 'd' && p[len - 1] == 'l') { - putithere->typed_val_decfloat.type + putithere->typed_val_float.type = parse_type (par_state)->builtin_declong; - decimal_from_string (putithere->typed_val_decfloat.val, 16, - gdbarch_byte_order (parse_gdbarch (par_state)), - std::string (p, len - 2)); - return DECFLOAT; + len -= 2; + } + /* Handle suffixes: 'f' for float, 'l' for long double. */ + else if (len >= 1 && tolower (p[len - 1]) == 'f') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_float; + len -= 1; + } + else if (len >= 1 && tolower (p[len - 1]) == 'l') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_long_double; + len -= 1; + } + /* Default type for floating-point literals is double. */ + else + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_double; } - if (! parse_c_float (parse_gdbarch (par_state), p, len, - &putithere->typed_val_float.dval, - &putithere->typed_val_float.type)) - return ERROR; + if (!parse_float (p, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val)) + return ERROR; return FLOAT; } diff --git a/gdb/d-exp.y b/gdb/d-exp.y index 00c9676..0a43bc4 100644 --- a/gdb/d-exp.y +++ b/gdb/d-exp.y @@ -86,7 +86,7 @@ static int type_aggregate_p (struct type *); struct type *type; } typed_val_int; struct { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; } typed_val_float; struct symbol *sym; @@ -540,10 +540,10 @@ PrimaryExpression: write_exp_elt_longcst (pstate, (LONGEST)($1.val)); write_exp_elt_opcode (pstate, OP_LONG); } | FLOAT_LITERAL - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, $1.type); - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } | CHARACTER_LITERAL { struct stoken_vector vec; vec.len = 1; @@ -682,8 +682,6 @@ parse_number (struct parser_state *ps, const char *p, if (parsed_float) { - const char *suffix; - int suffix_len; char *s, *sp; /* Strip out all embedded '_' before passing to parse_float. */ @@ -698,54 +696,51 @@ parse_number (struct parser_state *ps, const char *p, *sp = '\0'; len = strlen (s); - if (! parse_float (s, len, &putithere->typed_val_float.dval, &suffix)) - return ERROR; - - suffix_len = s + len - suffix; - - if (suffix_len == 0) - { - putithere->typed_val_float.type - = parse_d_type (ps)->builtin_double; - } - else if (suffix_len == 1) + /* Check suffix for `i' , `fi' or `li' (idouble, ifloat or ireal). */ + if (len >= 1 && tolower (s[len - 1]) == 'i') { - /* Check suffix for `f', `l', or `i' (float, real, or idouble). */ - if (tolower (*suffix) == 'f') + if (len >= 2 && tolower (s[len - 2]) == 'f') { putithere->typed_val_float.type - = parse_d_type (ps)->builtin_float; + = parse_d_type (ps)->builtin_ifloat; + len -= 2; } - else if (tolower (*suffix) == 'l') + else if (len >= 2 && tolower (s[len - 2]) == 'l') { putithere->typed_val_float.type - = parse_d_type (ps)->builtin_real; + = parse_d_type (ps)->builtin_ireal; + len -= 2; } - else if (tolower (*suffix) == 'i') + else { putithere->typed_val_float.type = parse_d_type (ps)->builtin_idouble; + len -= 1; } - else - return ERROR; } - else if (suffix_len == 2) + /* Check suffix for `f' or `l'' (float or real). */ + else if (len >= 1 && tolower (s[len - 1]) == 'f') { - /* Check suffix for `fi' or `li' (ifloat or ireal). */ - if (tolower (suffix[0]) == 'f' && tolower (suffix[1] == 'i')) - { - putithere->typed_val_float.type - = parse_d_type (ps)->builtin_ifloat; - } - else if (tolower (suffix[0]) == 'l' && tolower (suffix[1] == 'i')) - { - putithere->typed_val_float.type - = parse_d_type (ps)->builtin_ireal; - } - else - return ERROR; + putithere->typed_val_float.type + = parse_d_type (ps)->builtin_float; + len -= 1; } + else if (len >= 1 && tolower (s[len - 1]) == 'l') + { + putithere->typed_val_float.type + = parse_d_type (ps)->builtin_real; + len -= 1; + } + /* Default type if no suffix. */ else + { + putithere->typed_val_float.type + = parse_d_type (ps)->builtin_double; + } + + if (!parse_float (s, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val)) return ERROR; return FLOAT_LITERAL; diff --git a/gdb/doublest.c b/gdb/doublest.c index 27d1c12..fe9fc23 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -866,6 +866,35 @@ floatformat_to_string (const struct floatformat *fmt, floatformat_to_doublest (fmt, in, &doub); return string_printf (host_format.c_str (), doub); } + +/* Parse string STRING into a target floating-number of format FMT and + store it as byte-stream ADDR. Return whether parsing succeeded. */ +bool +floatformat_from_string (const struct floatformat *fmt, gdb_byte *out, + const std::string &in) +{ + DOUBLEST doub; + int n, num; +#ifdef HAVE_LONG_DOUBLE + const char *scan_format = "%Lg%n"; +#else + const char *scan_format = "%lg%n"; +#endif + num = sscanf (in.c_str (), scan_format, &doub, &n); + + /* The sscanf man page suggests not making any assumptions on the effect + of %n on the result, so we don't. + That is why we simply test num == 0. */ + if (num == 0) + return false; + + /* We only accept the whole string. */ + if (in[n]) + return false; + + floatformat_from_doublest (fmt, &doub, out); + return true; +} /* Extract a floating-point number of type TYPE from a target-order byte-stream at ADDR. Returns the value as type DOUBLEST. */ diff --git a/gdb/doublest.h b/gdb/doublest.h index f249352..4b9d6bc 100644 --- a/gdb/doublest.h +++ b/gdb/doublest.h @@ -74,6 +74,8 @@ extern const char *floatformat_mantissa (const struct floatformat *, extern std::string floatformat_to_string (const struct floatformat *fmt, const gdb_byte *in, const char *format = nullptr); +extern bool floatformat_from_string (const struct floatformat *fmt, + gdb_byte *out, const std::string &in); /* Return the floatformat's total size in host bytes. */ @@ -1277,15 +1277,10 @@ evaluate_subexp_standard (struct type *expect_type, return value_from_longest (exp->elts[pc + 1].type, exp->elts[pc + 2].longconst); - case OP_DOUBLE: + case OP_FLOAT: (*pos) += 3; - return value_from_double (exp->elts[pc + 1].type, - exp->elts[pc + 2].doubleconst); - - case OP_DECFLOAT: - (*pos) += 3; - return value_from_decfloat (exp->elts[pc + 1].type, - exp->elts[pc + 2].decfloatconst); + return value_from_contents (exp->elts[pc + 1].type, + exp->elts[pc + 2].floatconst); case OP_ADL_FUNC: case OP_VAR_VALUE: diff --git a/gdb/expprint.c b/gdb/expprint.c index 9e04f24..a99832c 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -105,14 +105,14 @@ print_subexp_standard (struct expression *exp, int *pos, } return; - case OP_DOUBLE: + case OP_FLOAT: { struct value_print_options opts; get_no_prettyformat_print_options (&opts); (*pos) += 3; - value_print (value_from_double (exp->elts[pc + 1].type, - exp->elts[pc + 2].doubleconst), + value_print (value_from_contents (exp->elts[pc + 1].type, + exp->elts[pc + 2].floatconst), stream, &opts); } return; @@ -871,13 +871,14 @@ dump_subexp_body_standard (struct expression *exp, (long) exp->elts[elt + 1].longconst); elt += 3; break; - case OP_DOUBLE: + case OP_FLOAT: fprintf_filtered (stream, "Type @"); gdb_print_host_address (exp->elts[elt].type, stream); fprintf_filtered (stream, " ("); type_print (exp->elts[elt].type, NULL, stream, 0); - fprintf_filtered (stream, "), value %g", - (double) exp->elts[elt + 1].doubleconst); + fprintf_filtered (stream, "), value "); + print_floating (exp->elts[elt + 1].floatconst, + exp->elts[elt].type, stream); elt += 3; break; case OP_VAR_VALUE: diff --git a/gdb/expression.h b/gdb/expression.h index 9e4ddf5..271baa9 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -22,7 +22,6 @@ #include "symtab.h" /* Needed for "struct block" type. */ -#include "doublest.h" /* Needed for DOUBLEST. */ /* Definitions for saved C expressions. */ @@ -66,8 +65,7 @@ union exp_element struct symbol *symbol; struct minimal_symbol *msymbol; LONGEST longconst; - DOUBLEST doubleconst; - gdb_byte decfloatconst[16]; + gdb_byte floatconst[16]; /* Really sizeof (union exp_element) characters (or less for the last element of a string). */ char string; diff --git a/gdb/f-exp.y b/gdb/f-exp.y index 8dcc811..217191a 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -91,7 +91,10 @@ static int match_string_literal (void); LONGEST val; struct type *type; } typed_val; - DOUBLEST dval; + struct { + gdb_byte val[16]; + struct type *type; + } typed_val_float; struct symbol *sym; struct type *tval; struct stoken sval; @@ -122,7 +125,7 @@ static int parse_number (struct parser_state *, const char *, int, %type <tval> ptype %token <typed_val> INT -%token <dval> FLOAT +%token <typed_val_float> FLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -414,12 +417,10 @@ exp : NAME_OR_INT ; exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); - write_exp_elt_type (pstate, - parse_f_type (pstate) - ->builtin_real_s8); - write_exp_elt_dblcst (pstate, $1); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + { write_exp_elt_opcode (pstate, OP_FLOAT); + write_exp_elt_type (pstate, $1.type); + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -647,16 +648,22 @@ parse_number (struct parser_state *par_state, if (parsed_float) { /* It's a float since it contains a point or an exponent. */ - /* [dD] is not understood as an exponent by atof, change it to 'e'. */ + /* [dD] is not understood as an exponent by parse_float, + change it to 'e'. */ char *tmp, *tmp2; tmp = xstrdup (p); for (tmp2 = tmp; *tmp2; ++tmp2) if (*tmp2 == 'd' || *tmp2 == 'D') *tmp2 = 'e'; - putithere->dval = atof (tmp); + + /* FIXME: Should this use different types? */ + putithere->typed_val_float.type = parse_f_type (pstate)->builtin_real_s8; + bool parsed = parse_float (tmp, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val); free (tmp); - return FLOAT; + return parsed? FLOAT : ERROR; } /* Handle base-switching prefixes 0x, 0t, 0d, 0 */ diff --git a/gdb/go-exp.y b/gdb/go-exp.y index 629093a..9beb511 100644 --- a/gdb/go-exp.y +++ b/gdb/go-exp.y @@ -97,7 +97,7 @@ void yyerror (const char *); struct type *type; } typed_val_int; struct { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; } typed_val_float; struct stoken sval; @@ -115,8 +115,6 @@ void yyerror (const char *); /* YYSTYPE gets defined by %union. */ static int parse_number (struct parser_state *, const char *, int, int, YYSTYPE *); -static int parse_go_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t); %} %type <voidval> exp exp1 type_exp start variable lcurly @@ -436,10 +434,10 @@ exp : NAME_OR_INT exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, $1.type); - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -634,24 +632,6 @@ name_not_typename %% -/* Wrapper on parse_c_float to get the type right for Go. */ - -static int -parse_go_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t) -{ - int result = parse_c_float (gdbarch, p, len, d, t); - const struct builtin_type *builtin_types = builtin_type (gdbarch); - const struct builtin_go_type *builtin_go_types = builtin_go_type (gdbarch); - - if (*t == builtin_types->builtin_float) - *t = builtin_go_types->builtin_float32; - else if (*t == builtin_types->builtin_double) - *t = builtin_go_types->builtin_float64; - - return result; -} - /* Take care of parsing a number (anything that starts with a digit). Set yylval and return the token type; update lexptr. LEN is the number of characters in it. */ @@ -688,10 +668,34 @@ parse_number (struct parser_state *par_state, if (parsed_float) { - if (! parse_go_float (parse_gdbarch (par_state), p, len, - &putithere->typed_val_float.dval, - &putithere->typed_val_float.type)) - return ERROR; + const struct builtin_go_type *builtin_go_types + = builtin_go_type (parse_gdbarch (par_state)); + + /* Handle suffixes: 'f' for float32, 'l' for long double. + FIXME: This appears to be an extension -- do we want this? */ + if (len >= 1 && tolower (p[len - 1]) == 'f') + { + putithere->typed_val_float.type + = builtin_go_types->builtin_float32; + len--; + } + else if (len >= 1 && tolower (p[len - 1]) == 'l') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_long_double; + len--; + } + /* Default type for floating-point literals is float64. */ + else + { + putithere->typed_val_float.type + = builtin_go_types->builtin_float64; + } + + if (!parse_float (p, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val)) + return ERROR; return FLOAT; } diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y index 02dc36f..3998d2b 100644 --- a/gdb/m2-exp.y +++ b/gdb/m2-exp.y @@ -82,7 +82,7 @@ static int number_sign = 1; { LONGEST lval; ULONGEST ulval; - DOUBLEST dval; + gdb_byte val[16]; struct symbol *sym; struct type *tval; struct stoken sval; @@ -103,7 +103,7 @@ static int number_sign = 1; %token <lval> INT HEX ERROR %token <ulval> UINT M2_TRUE M2_FALSE CHAR -%token <dval> FLOAT +%token <val> FLOAT /* Both NAME and TYPENAME tokens represent symbols in the input, and both convey their data as strings. @@ -474,12 +474,12 @@ exp : CHAR exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, parse_m2_type (pstate) ->builtin_real); - write_exp_elt_dblcst (pstate, $1); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + write_exp_elt_floatcst (pstate, $1); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -650,7 +650,11 @@ parse_number (int olen) if (p[c] == '.' && base == 10) { /* It's a float since it contains a point. */ - yylval.dval = atof (p); + if (!parse_float (p, len, + parse_m2_type (pstate)->builtin_real, + yylval.val)) + return ERROR; + lexptr += len; return FLOAT; } diff --git a/gdb/p-exp.y b/gdb/p-exp.y index eee4fa9..64e8189 100644 --- a/gdb/p-exp.y +++ b/gdb/p-exp.y @@ -89,7 +89,7 @@ static char *uptok (const char *, int); struct type *type; } typed_val_int; struct { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; } typed_val_float; struct symbol *sym; @@ -511,11 +511,11 @@ exp : NAME_OR_INT exp : FLOAT - { write_exp_elt_opcode (pstate, OP_DOUBLE); + { write_exp_elt_opcode (pstate, OP_FLOAT); write_exp_elt_type (pstate, $1.type); current_type = $1.type; - write_exp_elt_dblcst (pstate, $1.dval); - write_exp_elt_opcode (pstate, OP_DOUBLE); } + write_exp_elt_floatcst (pstate, $1.val); + write_exp_elt_opcode (pstate, OP_FLOAT); } ; exp : variable @@ -854,9 +854,30 @@ parse_number (struct parser_state *par_state, if (parsed_float) { - if (! parse_c_float (parse_gdbarch (par_state), p, len, - &putithere->typed_val_float.dval, - &putithere->typed_val_float.type)) + /* Handle suffixes: 'f' for float, 'l' for long double. + FIXME: This appears to be an extension -- do we want this? */ + if (len >= 1 && tolower (p[len - 1]) == 'f') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_float; + len--; + } + else if (len >= 1 && tolower (p[len - 1]) == 'l') + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_long_double; + len--; + } + /* Default type for floating-point literals is double. */ + else + { + putithere->typed_val_float.type + = parse_type (par_state)->builtin_double; + } + + if (!parse_float (p, len, + putithere->typed_val_float.type, + putithere->typed_val_float.val)) return ERROR; return FLOAT; } diff --git a/gdb/parse.c b/gdb/parse.c index 6bbf25f..a4058c3 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -45,6 +45,7 @@ #include "symfile.h" /* for overlay functions */ #include "inferior.h" #include "doublest.h" +#include "dfp.h" #include "block.h" #include "source.h" #include "objfiles.h" @@ -264,23 +265,13 @@ write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt) } void -write_exp_elt_dblcst (struct parser_state *ps, DOUBLEST expelt) -{ - union exp_element tmp; - - memset (&tmp, 0, sizeof (union exp_element)); - tmp.doubleconst = expelt; - write_exp_elt (ps, &tmp); -} - -void -write_exp_elt_decfloatcst (struct parser_state *ps, gdb_byte expelt[16]) +write_exp_elt_floatcst (struct parser_state *ps, const gdb_byte expelt[16]) { union exp_element tmp; int index; for (index = 0; index < 16; index++) - tmp.decfloatconst[index] = expelt[index]; + tmp.floatconst[index] = expelt[index]; write_exp_elt (ps, &tmp); } @@ -870,8 +861,7 @@ operator_length_standard (const struct expression *expr, int endpos, break; case OP_LONG: - case OP_DOUBLE: - case OP_DECFLOAT: + case OP_FLOAT: case OP_VAR_VALUE: case OP_VAR_MSYM_VALUE: oplen = 4; @@ -1338,69 +1328,23 @@ null_post_parser (struct expression **exp, int void_context_p) } /* Parse floating point value P of length LEN. - Return 0 (false) if invalid, 1 (true) if valid. - The successfully parsed number is stored in D. - *SUFFIX points to the suffix of the number in P. + Return false if invalid, true if valid. + The successfully parsed number is stored in DATA in + target format for floating-point type TYPE. NOTE: This accepts the floating point syntax that sscanf accepts. */ -int -parse_float (const char *p, int len, DOUBLEST *d, const char **suffix) -{ - char *copy; - int n, num; - - copy = (char *) xmalloc (len + 1); - memcpy (copy, p, len); - copy[len] = 0; - - num = sscanf (copy, "%" DOUBLEST_SCAN_FORMAT "%n", d, &n); - xfree (copy); - - /* The sscanf man page suggests not making any assumptions on the effect - of %n on the result, so we don't. - That is why we simply test num == 0. */ - if (num == 0) - return 0; - - *suffix = p + n; - return 1; -} - -/* Parse floating point value P of length LEN, using the C syntax for floats. - Return 0 (false) if invalid, 1 (true) if valid. - The successfully parsed number is stored in *D. - Its type is taken from builtin_type (gdbarch) and is stored in *T. */ - -int -parse_c_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t) +bool +parse_float (const char *p, int len, + const struct type *type, gdb_byte *data) { - const char *suffix; - int suffix_len; - const struct builtin_type *builtin_types = builtin_type (gdbarch); - - if (! parse_float (p, len, d, &suffix)) - return 0; - - suffix_len = p + len - suffix; - - if (suffix_len == 0) - *t = builtin_types->builtin_double; - else if (suffix_len == 1) - { - /* Handle suffixes: 'f' for float, 'l' for long double. */ - if (tolower (*suffix) == 'f') - *t = builtin_types->builtin_float; - else if (tolower (*suffix) == 'l') - *t = builtin_types->builtin_long_double; - else - return 0; - } + if (TYPE_CODE (type) == TYPE_CODE_FLT) + return floatformat_from_string (floatformat_from_type (type), + data, std::string (p, len)); else - return 0; - - return 1; + return decimal_from_string (data, TYPE_LENGTH (type), + gdbarch_byte_order (get_type_arch (type)), + std::string (p, len)); } /* Stuff for maintaining a stack of types. Currently just used by C, but @@ -1808,8 +1752,7 @@ operator_check_standard (struct expression *exp, int pos, { case BINOP_VAL: case OP_COMPLEX: - case OP_DECFLOAT: - case OP_DOUBLE: + case OP_FLOAT: case OP_LONG: case OP_SCOPE: case OP_TYPE: diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h index f7ba7f0..f43fb75 100644 --- a/gdb/parser-defs.h +++ b/gdb/parser-defs.h @@ -23,7 +23,6 @@ #if !defined (PARSER_DEFS_H) #define PARSER_DEFS_H 1 -#include "doublest.h" #include "vec.h" #include "expression.h" @@ -189,9 +188,7 @@ extern void write_exp_elt_sym (struct parser_state *, struct symbol *); extern void write_exp_elt_longcst (struct parser_state *, LONGEST); -extern void write_exp_elt_dblcst (struct parser_state *, DOUBLEST); - -extern void write_exp_elt_decfloatcst (struct parser_state *, gdb_byte *); +extern void write_exp_elt_floatcst (struct parser_state *, const gdb_byte *); extern void write_exp_elt_type (struct parser_state *, struct type *); @@ -270,11 +267,8 @@ extern type_instance_flags follow_type_instance_flags (); extern void null_post_parser (struct expression **, int); -extern int parse_float (const char *p, int len, DOUBLEST *d, - const char **suffix); - -extern int parse_c_float (struct gdbarch *gdbarch, const char *p, int len, - DOUBLEST *d, struct type **t); +extern bool parse_float (const char *p, int len, + const struct type *type, gdb_byte *data); /* During parsing of a C expression, the pointer to the next character is in this variable. */ diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y index 0cb185c..e372a6e 100644 --- a/gdb/rust-exp.y +++ b/gdb/rust-exp.y @@ -54,7 +54,7 @@ struct typed_val_int struct typed_val_float { - DOUBLEST dval; + gdb_byte val[16]; struct type *type; }; @@ -173,10 +173,6 @@ static const char *number_regex_text = static regex_t number_regex; -/* True if we're running unit tests. */ - -static int unit_testing; - /* Obstack for data temporarily allocated during parsing. Points to the obstack in the rust_parser, or to a temporary obstack during unit testing. */ @@ -1068,11 +1064,6 @@ rust_type (const char *name) { struct type *type; - /* When unit testing, we don't bother checking the types, so avoid a - possibly-failing lookup here. */ - if (unit_testing) - return NULL; - type = language_lookup_primitive_type (current_parser->language (), current_parser->arch (), name); @@ -1586,8 +1577,11 @@ lex_number (void) } else { - rustyylval.typed_val_float.dval = strtod (number.c_str (), NULL); rustyylval.typed_val_float.type = type; + bool parsed = parse_float (number.c_str (), number.length (), + rustyylval.typed_val_float.type, + rustyylval.typed_val_float.val); + gdb_assert (parsed); } return is_integer ? (could_be_decimal ? DECIMAL_INTEGER : INTEGER) : FLOAT; @@ -1716,7 +1710,7 @@ ast_dliteral (struct typed_val_float val) { struct rust_op *result = OBSTACK_ZALLOC (work_obstack, struct rust_op); - result->opcode = OP_DOUBLE; + result->opcode = OP_FLOAT; result->left.typed_val_float = val; return result; @@ -2181,11 +2175,11 @@ convert_ast_to_expression (struct parser_state *state, write_exp_elt_opcode (state, OP_LONG); break; - case OP_DOUBLE: - write_exp_elt_opcode (state, OP_DOUBLE); + case OP_FLOAT: + write_exp_elt_opcode (state, OP_FLOAT); write_exp_elt_type (state, operation->left.typed_val_float.type); - write_exp_elt_dblcst (state, operation->left.typed_val_float.dval); - write_exp_elt_opcode (state, OP_DOUBLE); + write_exp_elt_floatcst (state, operation->left.typed_val_float.val); + write_exp_elt_opcode (state, OP_FLOAT); break; case STRUCTOP_STRUCT: @@ -2675,7 +2669,10 @@ rust_lex_tests (void) scoped_restore obstack_holder = make_scoped_restore (&work_obstack, &test_obstack); - unit_testing = 1; + // Set up dummy "parser", so that rust_type works. + struct parser_state ps; + initialize_expout (&ps, 0, &rust_language_defn, target_gdbarch ()); + rust_parser parser (&ps); rust_lex_test_one ("", 0); rust_lex_test_one (" \t \n \r ", 0); @@ -2764,8 +2761,6 @@ rust_lex_tests (void) rust_lex_test_completion (); rust_lex_test_push_back (); - - unit_testing = 0; } #endif /* GDB_SELF_TEST */ diff --git a/gdb/std-operator.def b/gdb/std-operator.def index 344ba25..58ef899 100644 --- a/gdb/std-operator.def +++ b/gdb/std-operator.def @@ -114,9 +114,9 @@ OP (MULTI_SUBSCRIPT) Thus, the operation occupies four exp_elements. */ OP (OP_LONG) -/* OP_DOUBLE is similar but takes a DOUBLEST constant instead of a - long. */ -OP (OP_DOUBLE) +/* OP_FLOAT is similar but takes a floating-point constant encoded in + the target format for the given type instead of a long. */ +OP (OP_FLOAT) /* OP_VAR_VALUE takes one struct block * in the following element, and one struct symbol * in the following exp_element, followed @@ -325,11 +325,6 @@ OP (OP_OBJC_NSSTRING) ":exp" and ":"). */ OP (OP_RANGE) -/* OP_DECFLOAT is followed by a type pointer in the next exp_element - and a dec long constant value in the following exp_element. - Then comes another OP_DECFLOAT. */ -OP (OP_DECFLOAT) - /* OP_ADL_FUNC specifies that the function is to be looked up in an Argument Dependent manner (Koenig lookup). */ OP (OP_ADL_FUNC) |