diff options
-rw-r--r-- | gdb/gmp-utils.c | 10 | ||||
-rw-r--r-- | gdb/gmp-utils.h | 48 |
2 files changed, 52 insertions, 6 deletions
diff --git a/gdb/gmp-utils.c b/gdb/gmp-utils.c index 0afa344..13fa61d 100644 --- a/gdb/gmp-utils.c +++ b/gdb/gmp-utils.c @@ -69,19 +69,21 @@ void gdb_mpz::export_bits (gdb::array_view<gdb_byte> buf, int endian, bool unsigned_p, bool safe) const { - gdb_assert (buf.size () > 0); - int sign = mpz_sgn (m_val); if (sign == 0) { /* Our value is zero, so no need to call mpz_export to do the work, especially since mpz_export's documentation explicitly says that the function is a noop in this case. Just write zero to - BUF ourselves. */ - memset (buf.data (), 0, buf.size ()); + BUF ourselves, if it is non-empty. In some languages, a + zero-bit type can exist and this is also fine. */ + if (buf.size () > 0) + memset (buf.data (), 0, buf.size ()); return; } + gdb_assert (buf.size () > 0); + if (safe) { /* Determine the maximum range of values that our buffer can diff --git a/gdb/gmp-utils.h b/gdb/gmp-utils.h index f294ab6..d05c11e 100644 --- a/gdb/gmp-utils.h +++ b/gdb/gmp-utils.h @@ -119,11 +119,17 @@ struct gdb_mpz return result; } - /* Convert VAL to an integer of the given type. + /* Convert this value to an integer of the given type. The return type can signed or unsigned, with no size restriction. */ template<typename T> T as_integer () const; + /* Convert this value to an integer of the given type. If this + value is too large, it is truncated. + + The return type can signed or unsigned, with no size restriction. */ + template<typename T> T as_integer_truncate () const; + /* Set VAL by importing the number stored in the byte array (BUF), using the given BYTE_ORDER. The size of the data to read is the byte array's size. @@ -312,7 +318,7 @@ struct gdb_mpz return mpz_cmp (m_val, other.m_val) <= 0; } - bool operator< (int other) const + bool operator< (long other) const { return mpz_cmp_si (m_val, other) < 0; } @@ -322,6 +328,28 @@ struct gdb_mpz return mpz_cmp_si (m_val, other) == 0; } + bool operator== (long other) const + { + return mpz_cmp_si (m_val, other) == 0; + } + + bool operator== (unsigned long other) const + { + return mpz_cmp_ui (m_val, other) == 0; + } + + template<typename T, + typename = gdb::Requires< + gdb::And<std::is_integral<T>, + std::integral_constant<bool, + (sizeof (T) > sizeof (long))>> + > + > + bool operator== (T src) + { + return *this == gdb_mpz (src); + } + bool operator== (const gdb_mpz &other) const { return mpz_cmp (m_val, other.m_val) == 0; @@ -612,4 +640,20 @@ gdb_mpz::as_integer () const return result; } +/* See declaration above. */ + +template<typename T> +T +gdb_mpz::as_integer_truncate () const +{ + T result; + + this->export_bits ({(gdb_byte *) &result, sizeof (result)}, + 0 /* endian (0 = native) */, + !std::is_signed<T>::value /* unsigned_p */, + false /* safe */); + + return result; +} + #endif |