Add methods and operators to gdb_mpz
authorTom Tromey <tromey@adacore.com>
Thu, 23 Feb 2023 14:30:26 +0000 (07:30 -0700)
committerTom Tromey <tromey@adacore.com>
Tue, 14 Mar 2023 14:16:39 +0000 (08:16 -0600)
This adds various methods and operators to gdb_mpz, as a step toward
hiding the implementation.

This only adds the operators that were needed.  Many more could be
added as required.

gdb/ada-lex.l
gdb/dwarf2/read.c
gdb/gmp-utils.h
gdb/unittests/gmp-utils-selftests.c
gdb/valops.c
gdb/value.c

index a5cfb84dcae6640567a508261e51c252b8ffe2a6..69fc14f7107256cc2eb79cb60493ff664c8d7924 100644 (file)
@@ -422,14 +422,14 @@ processInt (struct parser_state *par_state, const char *base0,
       int dig = fromhex (*num0);
       if (dig >= base)
        error (_("Invalid digit `%c' in based literal"), *num0);
-      mpz_mul_ui (result.val, result.val, base);
-      mpz_add_ui (result.val, result.val, dig);
+      result *= base;
+      result += dig;
       ++num0;
     }
 
   while (exp > 0)
     {
-      mpz_mul_ui (result.val, result.val, base);
+      result *= base;
       exp -= 1;
     }
 
@@ -462,8 +462,7 @@ processInt (struct parser_state *par_state, const char *base0,
       return FLOAT;
     }
 
-  gdb_mpz maxval (ULONGEST_MAX);
-  if (mpz_cmp (result.val, maxval.val) > 0)
+  if (result > gdb_mpz (ULONGEST_MAX))
     error (_("Integer literal out of range"));
 
   int int_bits = gdbarch_int_bit (par_state->gdbarch ());
index 7ff090225e055cbe17b6643448235e58ffb7766a..138537cfefd128ad1ed75461e72b12b96c265a3e 100644 (file)
@@ -14746,10 +14746,10 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
                                                   &len);
          if (ptr - blk->data + len <= blk->size)
            {
-             mpz_import (value->val, len,
-                         bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
-                         ? 1 : -1,
-                         1, 0, 0, ptr);
+             value->read (gdb::make_array_view (ptr, len),
+                          bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
+                          ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
+                          true);
              return;
            }
        }
@@ -14760,10 +14760,10 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
   else if (attr->form_is_block ())
     {
       dwarf_block *blk = attr->as_block ();
-      mpz_import (value->val, blk->size,
-                 bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
-                 ? 1 : -1,
-                 1, 0, 0, blk->data);
+      value->read (gdb::make_array_view (blk->data, blk->size),
+                  bfd_big_endian (cu->per_objfile->objfile->obfd.get ())
+                  ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
+                  true);
     }
   else
     *value = gdb_mpz (attr->constant_value (1));
@@ -14815,19 +14815,19 @@ get_dwarf2_unsigned_rational_constant (struct die_info *die,
   gdb_mpz denom (1);
 
   get_dwarf2_rational_constant (die, cu, &num, &denom);
-  if (mpz_sgn (num.val) == -1 && mpz_sgn (denom.val) == -1)
+  if (num < 0 && denom < 0)
     {
-      mpz_neg (num.val, num.val);
-      mpz_neg (denom.val, denom.val);
+      num.negate ();
+      denom.negate ();
     }
-  else if (mpz_sgn (num.val) == -1)
+  else if (num < 0)
     {
       complaint (_("unexpected negative value for DW_AT_GNU_numerator"
                   " in DIE at %s"),
                 sect_offset_str (die->sect_off));
       return;
     }
-  else if (mpz_sgn (denom.val) == -1)
+  else if (denom < 0)
     {
       complaint (_("unexpected negative value for DW_AT_GNU_denominator"
                   " in DIE at %s"),
@@ -14866,10 +14866,7 @@ ada_get_gnat_encoded_number (const char *encoding, int &k, gdb_mpz *result)
     return false;
 
   std::string copy (&encoding[start], k - start);
-  if (mpz_set_str (result->val, copy.c_str (), 10) == -1)
-    return false;
-
-  return true;
+  return result->set (copy.c_str (), 10);
 }
 
 /* Scan two numbers from ENCODING at OFFSET, assuming the string is of
@@ -14949,16 +14946,16 @@ finish_fixed_point_type (struct type *type, const char *suffix,
   else if (attr->name == DW_AT_binary_scale)
     {
       LONGEST scale_exp = attr->constant_value (0);
-      gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
+      gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
 
-      mpz_mul_2exp (num_or_denom->val, num_or_denom->val, std::abs (scale_exp));
+      num_or_denom <<= std::abs (scale_exp);
     }
   else if (attr->name == DW_AT_decimal_scale)
     {
       LONGEST scale_exp = attr->constant_value (0);
-      gdb_mpz *num_or_denom = scale_exp > 0 ? &scale_num : &scale_denom;
+      gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
 
-      mpz_ui_pow_ui (num_or_denom->val, 10, std::abs (scale_exp));
+      num_or_denom = gdb_mpz::pow (10, std::abs (scale_exp));
     }
   else if (attr->name == DW_AT_small)
     {
@@ -14982,10 +14979,7 @@ finish_fixed_point_type (struct type *type, const char *suffix,
                 sect_offset_str (die->sect_off));
     }
 
-  gdb_mpq &scaling_factor = type->fixed_point_info ().scaling_factor;
-  mpz_set (mpq_numref (scaling_factor.val), scale_num.val);
-  mpz_set (mpq_denref (scaling_factor.val), scale_denom.val);
-  mpq_canonicalize (scaling_factor.val);
+  type->fixed_point_info ().scaling_factor = gdb_mpq (scale_num, scale_denom);
 }
 
 /* The gnat-encoding suffix for fixed point.  */
@@ -15066,7 +15060,7 @@ has_zero_over_zero_small_attribute (struct die_info *die,
 
   gdb_mpz num (1), denom (1);
   get_dwarf2_rational_constant (scale_die, cu, &num, &denom);
-  return mpz_sgn (num.val) == 0 && mpz_sgn (denom.val) == 0;
+  return num == 0 && denom == 0;
 }
 
 /* Initialise and return a floating point type of size BITS suitable for
index 3f30b575f72d56baf31aa929a1443c0659282174..75e2273a32220de652d8910654781af47daf75a5 100644 (file)
@@ -89,6 +89,21 @@ struct gdb_mpz
     return *this;
   }
 
+  /* Initialize this value from a string and a base.  Returns true if
+     the string was parsed successfully, false otherwise.  */
+  bool set (const char *str, int base)
+  {
+    return mpz_set_str (val, str, base) != -1;
+  }
+
+  /* Return a new value that is BASE**EXP.  */
+  static gdb_mpz pow (unsigned long base, unsigned long exp)
+  {
+    gdb_mpz result;
+    mpz_ui_pow_ui (result.val, base, exp);
+    return result;
+  }
+
   /* Convert VAL to an integer of the given type.
 
      The return type can signed or unsigned, with no size restriction.  */
@@ -115,6 +130,56 @@ struct gdb_mpz
   /* The destructor.  */
   ~gdb_mpz () { mpz_clear (val); }
 
+  /* Negate this value in place.  */
+  void negate ()
+  {
+    mpz_neg (val, val);
+  }
+
+  gdb_mpz &operator*= (long other)
+  {
+    mpz_mul_si (val, val, other);
+    return *this;
+  }
+
+  gdb_mpz &operator+= (unsigned long other)
+  {
+    mpz_add_ui (val, val, other);
+    return *this;
+  }
+
+  gdb_mpz &operator-= (unsigned long other)
+  {
+    mpz_sub_ui (val, val, other);
+    return *this;
+  }
+
+  gdb_mpz &operator<<= (unsigned long nbits)
+  {
+    mpz_mul_2exp (val, val, nbits);
+    return *this;
+  }
+
+  bool operator> (const gdb_mpz &other) const
+  {
+    return mpz_cmp (val, other.val) > 0;
+  }
+
+  bool operator< (int other) const
+  {
+    return mpz_cmp_si (val, other) < 0;
+  }
+
+  bool operator== (int other) const
+  {
+    return mpz_cmp_si (val, other) == 0;
+  }
+
+  bool operator== (const gdb_mpz &other) const
+  {
+    return mpz_cmp (val, other.val) == 0;
+  }
+
 private:
 
   /* Helper template for constructor and operator=.  */
@@ -166,6 +231,14 @@ struct gdb_mpq
     mpq_swap (val, from.val);
   }
 
+  gdb_mpq (const gdb_mpz &num, const gdb_mpz &denom)
+  {
+    mpq_init (val);
+    mpz_set (mpq_numref (val), num.val);
+    mpz_set (mpq_denref (val), denom.val);
+    mpq_canonicalize (val);
+  }
+
   /* Copy assignment operator.  */
   gdb_mpq &operator= (const gdb_mpq &from)
   {
@@ -179,12 +252,26 @@ struct gdb_mpq
     return *this;
   }
 
+  gdb_mpq &operator= (const gdb_mpz &from)
+  {
+    mpq_set_z (val, from.val);
+    return *this;
+  }
+
   /* Return a string representing VAL as "<numerator> / <denominator>".  */
   std::string str () const { return gmp_string_printf ("%Qd", val); }
 
   /* Return VAL rounded to the nearest integer.  */
   gdb_mpz get_rounded () const;
 
+  /* Return this value as an integer, rounded toward zero.  */
+  gdb_mpz as_integer () const
+  {
+    gdb_mpz result;
+    mpz_tdiv_q (result.val, mpq_numref (val), mpq_denref (val));
+    return result;
+  }
+
   /* Set VAL from the contents of the given byte array (BUF), which
      contains the unscaled value of a fixed point type object.
      The byte size of the data is the size of BUF.
index e2ccd2ca094b3cdd4af3eaa16bbb754b861b193b..8e028fec88c2de0b8905165edbaf4dff37c358fe 100644 (file)
@@ -43,8 +43,8 @@ gdb_mpz_as_integer ()
   /* Start with the smallest LONGEST  */
   l_expected = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1);
 
-  mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1);
-  mpz_neg (v.val, v.val);
+  v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1);
+  v.negate ();
 
   SELF_CHECK (v.as_integer<LONGEST> () == l_expected);
 
@@ -53,13 +53,13 @@ gdb_mpz_as_integer ()
   for (int i = -256; i <= 256; i++)
     {
       l_expected = (LONGEST) i;
-      mpz_set_si (v.val, i);
+      v = i;
       SELF_CHECK (v.as_integer<LONGEST> () == l_expected);
 
       if (i >= 0)
        {
          ul_expected = (ULONGEST) i;
-         mpz_set_ui (v.val, i);
+         v = ul_expected;
          SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected);
        }
     }
@@ -68,16 +68,16 @@ gdb_mpz_as_integer ()
   l_expected = LONGEST_MAX;
   ul_expected = (ULONGEST) l_expected;
 
-  mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1);
-  mpz_sub_ui (v.val, v.val, 1);
+  v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1);
+  v -= 1;
 
   SELF_CHECK (v.as_integer<LONGEST> () == l_expected);
   SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected);
 
   /* Try with ULONGEST_MAX.  */
   ul_expected = ULONGEST_MAX;
-  mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8);
-  mpz_sub_ui (v.val, v.val, 1);
+  v = gdb_mpz::pow (2, sizeof (LONGEST) * 8);
+  v -= 1;
 
   SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected);
 }
@@ -116,9 +116,9 @@ gdb_mpz_as_integer_out_of_range ()
   gdb_mpz v;
 
   /* Try LONGEST_MIN minus 1.  */
-  mpz_ui_pow_ui (v.val, 2, sizeof (LONGEST) * 8 - 1);
-  mpz_neg (v.val, v.val);
-  mpz_sub_ui (v.val, v.val, 1);
+  v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1);
+  v.negate ();
+  v -= 1;
 
   check_as_integer_raises_out_of_range_error<ULONGEST> (v);
   check_as_integer_raises_out_of_range_error<LONGEST> (v);
@@ -131,14 +131,14 @@ gdb_mpz_as_integer_out_of_range ()
 
   /* Try LONGEST_MAX plus 1.  */
   v = LONGEST_MAX;
-  mpz_add_ui (v.val, v.val, 1);
+  v += 1;
 
   SELF_CHECK (v.as_integer<ULONGEST> () == (ULONGEST) LONGEST_MAX + 1);
   check_as_integer_raises_out_of_range_error<LONGEST> (v);
 
   /* Try ULONGEST_MAX plus 1.  */
   v = ULONGEST_MAX;
-  mpz_add_ui (v.val, v.val, 1);
+  v += 1;
 
   check_as_integer_raises_out_of_range_error<ULONGEST> (v);
   check_as_integer_raises_out_of_range_error<LONGEST> (v);
@@ -170,8 +170,8 @@ store_and_read_back (T val, size_t buf_len, enum bfd_endian byte_order,
   store_integer (buf, buf_len, byte_order, val);
 
   /* Pre-initialize ACTUAL to something that's not the expected value.  */
-  mpz_set (actual.val, expected.val);
-  mpz_sub_ui (actual.val, actual.val, 500);
+  actual = expected;
+  actual -= 500;
 
   actual.read ({buf, buf_len}, byte_order, !std::is_signed<T>::value);
 }
@@ -197,10 +197,10 @@ gdb_mpz_read_all_from_small ()
       gdb_mpz expected, actual;
 
       store_and_read_back (l, buf_len, BFD_ENDIAN_BIG, expected, actual);
-      SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+      SELF_CHECK (actual ==  expected);
 
       store_and_read_back (l, buf_len, BFD_ENDIAN_LITTLE, expected, actual);
-      SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+      SELF_CHECK (actual == expected);
     }
 
   /* Do the same as above, but with an unsigned type.  */
@@ -212,10 +212,10 @@ gdb_mpz_read_all_from_small ()
       gdb_mpz expected, actual;
 
       store_and_read_back (ul, buf_len, BFD_ENDIAN_BIG, expected, actual);
-      SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+      SELF_CHECK (actual == expected);
 
       store_and_read_back (ul, buf_len, BFD_ENDIAN_LITTLE, expected, actual);
-      SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+      SELF_CHECK (actual == expected);
     }
 }
 
@@ -232,11 +232,11 @@ gdb_mpz_read_min_max ()
 
   store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   /* Same with LONGEST_MAX.  */
 
@@ -244,11 +244,11 @@ gdb_mpz_read_min_max ()
 
   store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   /* Same with the smallest ULONGEST.  */
 
@@ -256,11 +256,11 @@ gdb_mpz_read_min_max ()
 
   store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   /* Same with ULONGEST_MAX.  */
 
@@ -268,11 +268,11 @@ gdb_mpz_read_min_max ()
 
   store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE,
                       expected, actual);
-  SELF_CHECK (mpz_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 }
 
 /* A helper function which creates a gdb_mpz object from the given
index 3a1b14c3d44c982cf4dcc21fe9ad565b1ec351ec..e0936d45cb372906d70e66e986a3187632731011 100644 (file)
@@ -354,7 +354,7 @@ value_to_gdb_mpq (struct value *value)
       gdb_mpz vz;
       vz.read (value->contents (), type_byte_order (type),
               type->is_unsigned ());
-      mpq_set_z (result.val, vz.val);
+      result = vz;
 
       if (is_fixed_point_type (type))
        mpq_mul (result.val, result.val,
index 9786e4a13231f2879edbde820764fb3e7048083d..5ffc7decee33274f28ae49bcb6a24e6cfd73255f 100644 (file)
@@ -2732,8 +2732,7 @@ unpack_long (struct type *type, const gdb_byte *valaddr)
                             byte_order, nosign,
                             type->fixed_point_scaling_factor ());
 
-       gdb_mpz vz;
-       mpz_tdiv_q (vz.val, mpq_numref (vq.val), mpq_denref (vq.val));
+       gdb_mpz vz = vq.as_integer ();
        return vz.as_integer<LONGEST> ();
       }