[4/6] Add operators and methods to gdb_mpq

Message ID 20230223-submit-gmp-hiding-v1-4-ea6ff9e32716@adacore.com
State New
Headers
Series Make GMP data members private |

Commit Message

Tom Tromey Feb. 23, 2023, 7:48 p.m. UTC
  This adds some operators and methods to gdb_mpq, in preparation for
making its implementation private.

This only adds the operators currently needed by gdb.  More could be
added as necessary.
---
 gdb/gmp-utils.h                     | 72 +++++++++++++++++++++++++++++++++++++
 gdb/unittests/gmp-utils-selftests.c | 34 ++++++++----------
 gdb/valarith.c                      | 18 +++++-----
 gdb/valops.c                        | 13 +++----
 4 files changed, 100 insertions(+), 37 deletions(-)
  

Patch

diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h
index 601d9a6a1ec..dfb61302f6b 100644
--- a/gdb/gmp-utils.h
+++ b/gdb/gmp-utils.h
@@ -245,6 +245,13 @@  struct gdb_mpq
     mpq_canonicalize (val);
   }
 
+  gdb_mpq (long num, long denom)
+  {
+    mpq_init (val);
+    mpq_set_si (val, num, denom);
+    mpq_canonicalize (val);
+  }
+
   /* Copy assignment operator.  */
   gdb_mpq &operator= (const gdb_mpq &from)
   {
@@ -264,6 +271,67 @@  struct gdb_mpq
     return *this;
   }
 
+  gdb_mpq &operator= (double d)
+  {
+    mpq_set_d (val, d);
+    return *this;
+  }
+
+  /* Return the sign of this value.  This returns -1 for a negative
+     value, 0 if the value is 0, and 1 for a positive value.  */
+  int sgn () const
+  { return mpq_sgn (val); }
+
+  gdb_mpq operator+ (const gdb_mpq &other) const
+  {
+    gdb_mpq result;
+    mpq_add (result.val, val, other.val);
+    return result;
+  }
+
+  gdb_mpq operator- (const gdb_mpq &other) const
+  {
+    gdb_mpq result;
+    mpq_sub (result.val, val, other.val);
+    return result;
+  }
+
+  gdb_mpq operator* (const gdb_mpq &other) const
+  {
+    gdb_mpq result;
+    mpq_mul (result.val, val, other.val);
+    return result;
+  }
+
+  gdb_mpq operator/ (const gdb_mpq &other) const
+  {
+    gdb_mpq result;
+    mpq_div (result.val, val, other.val);
+    return result;
+  }
+
+  gdb_mpq &operator*= (const gdb_mpq &other)
+  {
+    mpq_mul (val, val, other.val);
+    return *this;
+  }
+
+  gdb_mpq &operator/= (const gdb_mpq &other)
+  {
+    mpq_div (val, val, other.val);
+    return *this;
+  }
+
+  bool operator== (const gdb_mpq &other) const
+  {
+    return mpq_cmp (val, other.val) == 0;
+  }
+
+  bool operator< (const gdb_mpq &other) const
+  {
+    return mpq_cmp (val, other.val) < 0;
+  }
+
   /* Return a string representing VAL as "<numerator> / <denominator>".  */
   std::string str () const { return gmp_string_printf ("%Qd", val); }
 
@@ -278,6 +346,10 @@  struct gdb_mpq
     return result;
   }
 
+  /* Return this value converted to a host double.  */
+  double as_double () const
+  { return mpq_get_d (val); }
+
   /* 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.
diff --git a/gdb/unittests/gmp-utils-selftests.c b/gdb/unittests/gmp-utils-selftests.c
index 8e028fec88c..384ca2df212 100644
--- a/gdb/unittests/gmp-utils-selftests.c
+++ b/gdb/unittests/gmp-utils-selftests.c
@@ -399,8 +399,8 @@  read_fp_test (int unscaled, const gdb_mpq &scaling_factor,
 
   actual.read_fixed_point ({buf, len}, byte_order, 0, scaling_factor);
 
-  mpq_set_si (expected.val, unscaled, 1);
-  mpq_mul (expected.val, expected.val, scaling_factor.val);
+  expected = gdb_mpq (unscaled, 1);
+  expected *= scaling_factor;
 }
 
 /* Perform various tests of the gdb_mpq::read_fixed_point method.  */
@@ -409,38 +409,37 @@  static void
 gdb_mpq_read_fixed_point ()
 {
   gdb_mpq expected, actual;
-  gdb_mpq scaling_factor;
 
   /* Pick an arbitrary scaling_factor; this operation is trivial enough
      thanks to GMP that the value we use isn't really important.  */
-  mpq_set_ui (scaling_factor.val, 3, 5);
+  gdb_mpq scaling_factor (3, 5);
 
   /* Try a few values, both negative and positive... */
 
   read_fp_test (-256, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
   read_fp_test (-256, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   read_fp_test (-1, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
   read_fp_test (-1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   read_fp_test (0, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
   read_fp_test (0, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   read_fp_test (1, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
   read_fp_test (1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 
   read_fp_test (1025, scaling_factor, BFD_ENDIAN_BIG, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
   read_fp_test (1025, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual);
-  SELF_CHECK (mpq_cmp (actual.val, expected.val) == 0);
+  SELF_CHECK (actual == expected);
 }
 
 /* A helper function which builds a gdb_mpq object from the given
@@ -463,9 +462,7 @@  write_fp_test (int numerator, unsigned int denominator,
   gdb_byte buf[len];
   memset (buf, 0, len);
 
-  gdb_mpq v;
-  mpq_set_si (v.val, numerator, denominator);
-  mpq_canonicalize (v.val);
+  gdb_mpq v (numerator, denominator);
   v.write_fixed_point ({buf, len}, byte_order, 0, scaling_factor);
 
   return extract_unsigned_integer (buf, len, byte_order);
@@ -479,8 +476,7 @@  gdb_mpq_write_fixed_point ()
   /* Pick an arbitrary factor; this operations is sufficiently trivial
      with the use of GMP that the value of this factor is not really
      all that important.  */
-  gdb_mpq scaling_factor;
-  mpq_set_ui (scaling_factor.val, 1, 3);
+  gdb_mpq scaling_factor (1, 3);
 
   gdb_mpq vq;
 
diff --git a/gdb/valarith.c b/gdb/valarith.c
index a6a5f5102a2..f8ce508e825 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -883,43 +883,43 @@  fixed_point_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   switch (op)
     {
     case BINOP_ADD:
-      mpq_add (res.val, v1.val, v2.val);
+      res = v1 + v2;
       val = fixed_point_to_value (res);
       break;
 
     case BINOP_SUB:
-      mpq_sub (res.val, v1.val, v2.val);
+      res = v1 - v2;
       val = fixed_point_to_value (res);
       break;
 
     case BINOP_MIN:
-      val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) < 0 ? v1 : v2);
+      val = fixed_point_to_value (std::min (v1, v2));
       break;
 
     case BINOP_MAX:
-      val = fixed_point_to_value (mpq_cmp (v1.val, v2.val) > 0 ? v1 : v2);
+      val = fixed_point_to_value (std::max (v1, v2));
       break;
 
     case BINOP_MUL:
-      mpq_mul (res.val, v1.val, v2.val);
+      res = v1 * v2;
       val = fixed_point_to_value (res);
       break;
 
     case BINOP_DIV:
-      if (mpq_sgn (v2.val) == 0)
+      if (v2.sgn () == 0)
 	error (_("Division by zero"));
-      mpq_div (res.val, v1.val, v2.val);
+      res = v1 / v2;
       val = fixed_point_to_value (res);
       break;
 
     case BINOP_EQUAL:
       val = value_from_ulongest (language_bool_type (language, gdbarch),
-				 mpq_cmp (v1.val, v2.val) == 0 ? 1 : 0);
+				 v1 == v2 ? 1 : 0);
       break;
 
     case BINOP_LESS:
       val = value_from_ulongest (language_bool_type (language, gdbarch),
-				 mpq_cmp (v1.val, v2.val) < 0 ? 1 : 0);
+				 v1 < v2 ? 1 : 0);
       break;
 
     default:
diff --git a/gdb/valops.c b/gdb/valops.c
index e0936d45cb3..2cef24fc4c5 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -341,11 +341,7 @@  value_to_gdb_mpq (struct value *value)
 
   gdb_mpq result;
   if (is_floating_type (type))
-    {
-      double d = target_float_to_host_double (value->contents ().data (),
-					      type);
-      mpq_set_d (result.val, d);
-    }
+    result = target_float_to_host_double (value->contents ().data (), type);
   else
     {
       gdb_assert (is_integral_type (type)
@@ -357,8 +353,7 @@  value_to_gdb_mpq (struct value *value)
       result = vz;
 
       if (is_fixed_point_type (type))
-	mpq_mul (result.val, result.val,
-		 type->fixed_point_scaling_factor ().val);
+	result *= type->fixed_point_scaling_factor ();
     }
 
   return result;
@@ -386,7 +381,7 @@  value_cast_to_fixed_point (struct type *to_type, struct value *from_val)
   /* Divide that value by the scaling factor to obtain the unscaled
      value, first in rational form, and then in integer form.  */
 
-  mpq_div (vq.val, vq.val, to_type->fixed_point_scaling_factor ().val);
+  vq /= to_type->fixed_point_scaling_factor ();
   gdb_mpz unscaled = vq.get_rounded ();
 
   /* Finally, create the result value, and pack the unscaled value
@@ -559,7 +554,7 @@  value_cast (struct type *type, struct value *arg2)
 
 	  struct value *v = value::allocate (to_type);
 	  target_float_from_host_double (v->contents_raw ().data (),
-					 to_type, mpq_get_d (fp_val.val));
+					 to_type, fp_val.as_double ());
 	  return v;
 	}