Add 128-bit integer support to the Rust parser
authorTom Tromey <tromey@adacore.com>
Mon, 27 Mar 2023 19:05:03 +0000 (13:05 -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 Rust parser.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=21185

gdb/rust-lang.c
gdb/rust-parse.c
gdb/testsuite/gdb.base/parse_number.exp
gdb/testsuite/gdb.rust/onetwoeight.exp

index cb128f13f0e86e38ee43ce9d968c67f76f024c53..3ef8fcaa329ee5882d7d528ea423a10edc90872d 100644 (file)
@@ -1607,6 +1607,8 @@ rust_language::language_arch_info (struct gdbarch *gdbarch,
   add (init_integer_type (alloc, 32, 1, "u32"));
   add (init_integer_type (alloc, 64, 0, "i64"));
   add (init_integer_type (alloc, 64, 1, "u64"));
+  add (init_integer_type (alloc, 128, 0, "i128"));
+  add (init_integer_type (alloc, 128, 1, "u128"));
 
   unsigned int length = 8 * builtin->builtin_data_ptr->length ();
   add (init_integer_type (alloc, length, 0, "isize"));
index eca98aa286f8e5413ae64994ce5f3d55303d88da..6c7922de9c746cb8ac8829157cb3a7948a769a98 100644 (file)
@@ -69,7 +69,7 @@ static const char number_regex_text[] =
 #define INT_TEXT 5
 #define INT_TYPE 6
   "(0x[a-fA-F0-9_]+|0o[0-7_]+|0b[01_]+|[0-9][0-9_]*)"
-  "([iu](size|8|16|32|64))?"
+  "([iu](size|8|16|32|64|128))?"
   ")";
 /* The number of subexpressions to allocate space for, including the
    "0th" whole match subexpression.  */
@@ -126,7 +126,7 @@ enum token_type : int
 
 struct typed_val_int
 {
-  ULONGEST val;
+  gdb_mpz val;
   struct type *type;
 };
 
@@ -1007,7 +1007,6 @@ rust_parser::lex_number ()
   /* Parse the number.  */
   if (is_integer)
     {
-      uint64_t value;
       int radix = 10;
       int offset = 0;
 
@@ -1026,14 +1025,22 @@ rust_parser::lex_number ()
            }
        }
 
-      const char *trailer;
-      value = strtoulst (number.c_str () + offset, &trailer, radix);
-      if (*trailer != '\0')
-       error (_("Integer literal is too large"));
-      if (implicit_i32 && value >= ((uint64_t) 1) << 31)
-       type = get_type ("i64");
+      if (!current_int_val.val.set (number.c_str () + offset, radix))
+       {
+         /* Shouldn't be possible.  */
+         error (_("Invalid integer"));
+       }
+      if (implicit_i32)
+       {
+         static gdb_mpz sixty_three_bit = gdb_mpz::pow (2, 63);
+         static gdb_mpz thirty_one_bit = gdb_mpz::pow (2, 31);
+
+         if (current_int_val.val >= sixty_three_bit)
+           type = get_type ("i128");
+         else if (current_int_val.val >= thirty_one_bit)
+           type = get_type ("i64");
+       }
 
-      current_int_val.val = value;
       current_int_val.type = type;
     }
   else
@@ -1556,9 +1563,11 @@ rust_parser::parse_field (operation_up &&lhs)
       break;
 
     case DECIMAL_INTEGER:
-      result = make_operation<rust_struct_anon> (current_int_val.val,
-                                                std::move (lhs));
-      lex ();
+      {
+       int idx = current_int_val.val.as_integer<int> ();
+       result = make_operation<rust_struct_anon> (idx, std::move (lhs));
+       lex ();
+      }
       break;
 
     case INTEGER:
@@ -1659,7 +1668,7 @@ rust_parser::parse_array_type ()
 
   if (current_token != INTEGER && current_token != DECIMAL_INTEGER)
     error (_("integer expected"));
-  ULONGEST val = current_int_val.val;
+  ULONGEST val = current_int_val.val.as_integer<ULONGEST> ();
   lex ();
   require (']');
 
index 07104433a16557bc3fdb05357887a21474bc035b..5dd4fa705e9263a98d7a9267fbc61c7227530abc 100644 (file)
@@ -108,9 +108,10 @@ proc parse_number { lang n } {
            return [list "i32" $n]
        } elseif { [fits_in_type $n 64 s] } {
            return [list "i64" $n]
-       } elseif { [fits_in_type $n 64 u] } {
-           # Note: Interprets MAX_U64 as -1.
-           return [list "i64" $n]
+       } elseif { [fits_in_type $n 128 u] } {
+           return [list "i128" $n]
+       } elseif { [fits_in_type $n 128 u] } {
+           return [list "i128" $n]
        } else {
            # Overflow.
            return [list $re_overflow $re_overflow]
index ef56bcafda262672db06edce70377028ea02b6ca..5ca30712830195b08014d2f0645b684f4267d565 100644 (file)
@@ -64,3 +64,7 @@ gdb_test "print x >> 2" "= 85070591730234615865843651857942052863"
 gdb_test "print/x x & mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0"
 gdb_test "print/x x ^ mask" " = 0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"
 gdb_test "print/x mask | (mask >> 4)" " = 0xffffffffffffffffffffffffffffffff"
+
+gdb_test "print 170141183460469231731687303715884105727" \
+    " = 170141183460469231731687303715884105727"
+gdb_test "ptype 23i128" "type = i128"