mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 18:14:13 +08:00
Additions to gdb_mpz
In preparation for adding more 128-bit support to gdb, a few additions to gdb_mpz are needed. First, this adds a new 'as_integer_truncate' method. This method works like 'as_integer' but does not require the value to fit in the target type -- it just truncates. Second, gdb_mpz::export_bits is changed to handle the somewhat unusual situation of zero-length types. This can happen for a Rust '()' type; but I think other languages have zero-bit integer types as well. Finally, this adds some operator== overloads.
This commit is contained in:
parent
c53c6186c8
commit
767c4b92bc
@ -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. */
|
||||
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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user