Add 128-bit integer support to the Ada parser
authorTom Tromey <tromey@adacore.com>
Mon, 27 Mar 2023 20:26:53 +0000 (14:26 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 17 Apr 2023 16:43:06 +0000 (10:43 -0600)
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
gdb/ada-lang.c
gdb/ada-lex.l
gdb/testsuite/gdb.ada/verylong.exp

index 4095106bb09221798b84d81182277e24f03c244e..3e31d27504684ef3ea31586aadc31b04554e4389 100644 (file)
@@ -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<std::unique_ptr<gdb_mpz>> 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 <lval> aggregate_component_list 
 %type <tval> var_or_type type_prefix opt_type_prefix
 
-%token <typed_val> INT NULL_PTR CHARLIT
+%token <typed_val> INT NULL_PTR
+%token <typed_char> CHARLIT
 %token <typed_val_float> 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<LONGEST> (); }
        ;
 
 type_prefix :
@@ -888,7 +898,10 @@ opt_type_prefix :
 
 
 primary        :       INT
-                       { write_int (pstate, (LONGEST) $1.val, $1.type); }
+                       {
+                         pstate->push_new<long_const_operation> ($1.type, *$1.val);
+                         ada_wrap<ada_wrapped_operation> ();
+                       }
        ;
 
 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)
index 2a25d42338e24615a5596d0e910da8f03a5b8c20..a3fc88a34886b412282916afa8d3e53b4e2b9d9b 100644 (file)
@@ -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)));
index 0634f337cb2b4eae8b2d88a21fbed3ac5e9afab4..f2af21292f415b6065f24ebe8cdf641d683e0e3d 100644 (file)
@@ -179,15 +179,15 @@ static int paren_depth;
                }
 
 <INITIAL>"'"({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;
                }
 
 <INITIAL>"'[\""{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<ULONGEST> ();
-  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"));
 
index 498ab6d88beff3288d0e1bbd62924cade84ac19a..d1fa968015bce3bc677d93768130c19782ce172c 100644 (file)
@@ -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"