From e49831ba4340688d7685a52099db09d12177945b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 27 Mar 2023 14:26:53 -0600 Subject: [PATCH] Add 128-bit integer support to the Ada parser This adds support for 128-bit integers to the Ada parser. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30188 --- gdb/ada-exp.y | 22 ++++++++-- gdb/ada-lang.c | 2 + gdb/ada-lex.l | 67 +++++++++++------------------- gdb/testsuite/gdb.ada/verylong.exp | 5 +++ 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/gdb/ada-exp.y b/gdb/ada-exp.y index 4095106bb09..3e31d275046 100644 --- a/gdb/ada-exp.y +++ b/gdb/ada-exp.y @@ -68,6 +68,11 @@ static struct parser_state *pstate = NULL; /* The original expression string. */ static const char *original_expr; +/* We don't have a good way to manage non-POD data in Yacc, so store + values here. The storage here is only valid for the duration of + the parse. */ +static std::vector> int_storage; + int yyparse (void); static int yylex (void); @@ -416,9 +421,13 @@ make_tick_completer (struct stoken tok) { LONGEST lval; struct { - LONGEST val; + const gdb_mpz *val; struct type *type; } typed_val; + struct { + LONGEST val; + struct type *type; + } typed_char; struct { gdb_byte val[16]; struct type *type; @@ -433,7 +442,8 @@ make_tick_completer (struct stoken tok) %type aggregate_component_list %type var_or_type type_prefix opt_type_prefix -%token INT NULL_PTR CHARLIT +%token INT NULL_PTR +%token CHARLIT %token FLOAT %token TRUEKEYWORD FALSEKEYWORD %token COLONCOLON @@ -867,7 +877,7 @@ primary : primary TICK_ACCESS tick_arglist : %prec '(' { $$ = 1; } | '(' INT ')' - { $$ = $2.val; } + { $$ = $2.val->as_integer (); } ; type_prefix : @@ -888,7 +898,10 @@ opt_type_prefix : primary : INT - { write_int (pstate, (LONGEST) $1.val, $1.type); } + { + pstate->push_new ($1.type, *$1.val); + ada_wrap (); + } ; primary : CHARLIT @@ -1144,6 +1157,7 @@ ada_parse (struct parser_state *par_state) obstack_init (&temp_parse_space); components.clear (); associations.clear (); + int_storage.clear (); int result = yyparse (); if (!result) diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 2a25d42338e..a3fc88a3488 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -13544,6 +13544,8 @@ public: "long_float", gdbarch_double_format (gdbarch))); add (init_integer_type (alloc, gdbarch_long_long_bit (gdbarch), 0, "long_long_integer")); + add (init_integer_type (alloc, 128, 0, "long_long_long_integer")); + add (init_integer_type (alloc, 128, 1, "unsigned_long_long_long_integer")); add (init_float_type (alloc, gdbarch_long_double_bit (gdbarch), "long_long_float", gdbarch_long_double_format (gdbarch))); diff --git a/gdb/ada-lex.l b/gdb/ada-lex.l index 0634f337cb2..f2af21292f4 100644 --- a/gdb/ada-lex.l +++ b/gdb/ada-lex.l @@ -179,15 +179,15 @@ static int paren_depth; } "'"({GRAPHIC}|\")"'" { - yylval.typed_val.val = yytext[1]; - yylval.typed_val.type = type_for_char (pstate, yytext[1]); + yylval.typed_char.val = yytext[1]; + yylval.typed_char.type = type_for_char (pstate, yytext[1]); return CHARLIT; } "'[\""{HEXDIG}{2,}"\"]'" { ULONGEST v = strtoulst (yytext+3, nullptr, 16); - yylval.typed_val.val = v; - yylval.typed_val.type = type_for_char (pstate, v); + yylval.typed_char.val = v; + yylval.typed_char.type = type_for_char (pstate, v); return CHARLIT; } @@ -462,52 +462,35 @@ processInt (struct parser_state *par_state, const char *base0, return FLOAT; } - if (result > gdb_mpz (ULONGEST_MAX)) - error (_("Integer literal out of range")); + int_storage.emplace_back (new gdb_mpz (std::move (result))); + const gdb_mpz *value = int_storage.back ().get (); int int_bits = gdbarch_int_bit (par_state->gdbarch ()); int long_bits = gdbarch_long_bit (par_state->gdbarch ()); int long_long_bits = gdbarch_long_long_bit (par_state->gdbarch ()); - ULONGEST value = result.as_integer (); - if (fits_in_type (1, value, int_bits, true)) + if (fits_in_type (1, *value, int_bits, true)) yylval.typed_val.type = parse_type (par_state)->builtin_int; - else if (fits_in_type (1, value, long_bits, true)) + else if (fits_in_type (1, *value, long_bits, true)) yylval.typed_val.type = parse_type (par_state)->builtin_long; - else if (fits_in_type (1, value, long_bits, false)) - { - /* We have a number representable as an unsigned integer quantity. - For consistency with the C treatment, we will treat it as an - anonymous modular (unsigned) quantity. Alas, the types are such - that we need to store .val as a signed quantity. Sorry - for the mess, but C doesn't officially guarantee that a simple - assignment does the trick (no, it doesn't; read the reference manual). - */ - yylval.typed_val.type - = builtin_type (par_state->gdbarch ())->builtin_unsigned_long; - if (value & LONGEST_SIGN) - yylval.typed_val.val = - (LONGEST) (value & ~LONGEST_SIGN) - - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1); - else - yylval.typed_val.val = (LONGEST) value; - return INT; - } - else if (fits_in_type (1, value, long_long_bits, true)) + else if (fits_in_type (1, *value, long_bits, false)) + yylval.typed_val.type + = builtin_type (par_state->gdbarch ())->builtin_unsigned_long; + else if (fits_in_type (1, *value, long_long_bits, true)) yylval.typed_val.type = parse_type (par_state)->builtin_long_long; - else if (fits_in_type (1, value, long_long_bits, false)) - { - yylval.typed_val.type - = builtin_type (par_state->gdbarch ())->builtin_unsigned_long_long; - /* See unsigned long case above. */ - if (value & LONGEST_SIGN) - yylval.typed_val.val = - (LONGEST) (value & ~LONGEST_SIGN) - - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1); - else - yylval.typed_val.val = (LONGEST) value; - return INT; - } + else if (fits_in_type (1, *value, long_long_bits, false)) + yylval.typed_val.type + = builtin_type (par_state->gdbarch ())->builtin_unsigned_long_long; + else if (fits_in_type (1, *value, 128, true)) + yylval.typed_val.type + = language_lookup_primitive_type (par_state->language (), + par_state->gdbarch (), + "long_long_long_integer"); + else if (fits_in_type (1, *value, 128, false)) + yylval.typed_val.type + = language_lookup_primitive_type (par_state->language (), + par_state->gdbarch (), + "unsigned_long_long_long_integer"); else error (_("Integer literal out of range")); diff --git a/gdb/testsuite/gdb.ada/verylong.exp b/gdb/testsuite/gdb.ada/verylong.exp index 498ab6d88be..d1fa968015b 100644 --- a/gdb/testsuite/gdb.ada/verylong.exp +++ b/gdb/testsuite/gdb.ada/verylong.exp @@ -36,3 +36,8 @@ gdb_test "print x - x" " = 0" gdb_test "print x - 99 + 1" " = 170141183460469231731687303715884105629" gdb_test "print -x" " = -170141183460469231731687303715884105727" gdb_test "print +x" " = 170141183460469231731687303715884105727" + +gdb_test "print 170141183460469231731687303715884105727" \ + " = 170141183460469231731687303715884105727" +gdb_test "print x = 170141183460469231731687303715884105727" \ + " = true" -- 2.30.2