Turn value_contents_eq into a method

This changes value_contents_eq to be a method of value.  It also
converts the static function value_contents_bits_eq into a private
method.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
Tom Tromey 2023-01-31 14:11:48 -07:00
parent 82ca8f7201
commit 02744ba9a2
7 changed files with 102 additions and 93 deletions

View File

@ -199,9 +199,9 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
if (check_typedef (v0->type ())->length ()
!= check_typedef (v1->type ())->length ())
break;
if (!value_contents_eq (v0, v0->embedded_offset (),
v1, v1->embedded_offset (),
check_typedef (v0->type ())->length ()))
if (!v0->contents_eq (v0->embedded_offset (),
v1, v1->embedded_offset (),
check_typedef (v0->type ())->length ()))
break;
}

View File

@ -271,7 +271,7 @@ public:
elt_off_prev);
repeated = ((value_entirely_available (e_prev)
&& value_entirely_available (e_val)
&& value_contents_eq (e_prev, e_val))
&& e_prev->contents_eq (e_val))
|| (value_entirely_unavailable (e_prev)
&& value_entirely_unavailable (e_val)));
}
@ -378,7 +378,7 @@ private:
return ((value_entirely_available (e_val1)
&& value_entirely_available (e_val2)
&& value_contents_eq (e_val1, e_val2))
&& e_val1->contents_eq (e_val2))
|| (value_entirely_unavailable (e_val1)
&& value_entirely_unavailable (e_val2)));
}

View File

@ -983,8 +983,8 @@ register_changed_p (int regnum, readonly_detached_regcache *prev_regs,
gdb_assert (prev_value != NULL);
gdb_assert (this_value != NULL);
auto ret = !value_contents_eq (prev_value, 0, this_value, 0,
register_size (gdbarch, regnum));
auto ret = !prev_value->contents_eq (0, this_value, 0,
register_size (gdbarch, regnum));
release_value (prev_value);
release_value (this_value);

View File

@ -585,7 +585,7 @@ read_frame_arg (const frame_print_options &fp_opts,
if (entryval->lazy ())
entryval->fetch_lazy ();
if (value_contents_eq (val, 0, entryval, 0, type->length ()))
if (val->contents_eq (0, entryval, 0, type->length ()))
{
/* Initialize it just to avoid a GCC false warning. */
struct value *val_deref = NULL, *entryval_deref;
@ -610,9 +610,9 @@ read_frame_arg (const frame_print_options &fp_opts,
/* If the reference addresses match but dereferenced
content does not match print them. */
if (val != val_deref
&& value_contents_eq (val_deref, 0,
entryval_deref, 0,
type_deref->length ()))
&& val_deref->contents_eq (0,
entryval_deref, 0,
type_deref->length ()))
val_equal = 1;
}
catch (const gdb_exception_error &except)

View File

@ -2029,7 +2029,7 @@ value_print_array_elements (struct value *val, struct ui_file *stream,
bit_stride);
bool repeated = ((available
&& value_entirely_available (rep_elt)
&& value_contents_eq (element, rep_elt))
&& element->contents_eq (rep_elt))
|| (unavailable
&& value_entirely_unavailable (rep_elt)));
if (!repeated)

View File

@ -648,29 +648,28 @@ find_first_range_overlap_and_match (struct ranges_and_idx *rp1,
with LENGTH bits of VAL2's contents starting at OFFSET2 bits.
Return true if the available bits match. */
static bool
value_contents_bits_eq (const struct value *val1, int offset1,
const struct value *val2, int offset2,
int length)
bool
value::contents_bits_eq (int offset1, const struct value *val2, int offset2,
int length) const
{
/* Each array element corresponds to a ranges source (unavailable,
optimized out). '1' is for VAL1, '2' for VAL2. */
struct ranges_and_idx rp1[2], rp2[2];
/* See function description in value.h. */
gdb_assert (!val1->m_lazy && !val2->m_lazy);
gdb_assert (!m_lazy && !val2->m_lazy);
/* We shouldn't be trying to compare past the end of the values. */
gdb_assert (offset1 + length
<= val1->m_enclosing_type->length () * TARGET_CHAR_BIT);
<= m_enclosing_type->length () * TARGET_CHAR_BIT);
gdb_assert (offset2 + length
<= val2->m_enclosing_type->length () * TARGET_CHAR_BIT);
memset (&rp1, 0, sizeof (rp1));
memset (&rp2, 0, sizeof (rp2));
rp1[0].ranges = &val1->m_unavailable;
rp1[0].ranges = &m_unavailable;
rp2[0].ranges = &val2->m_unavailable;
rp1[1].ranges = &val1->m_optimized_out;
rp1[1].ranges = &m_optimized_out;
rp2[1].ranges = &val2->m_optimized_out;
while (length > 0)
@ -698,7 +697,7 @@ value_contents_bits_eq (const struct value *val1, int offset1,
}
/* Compare the available/valid contents. */
if (memcmp_with_bit_offsets (val1->m_contents.get (), offset1,
if (memcmp_with_bit_offsets (m_contents.get (), offset1,
val2->m_contents.get (), offset2, l) != 0)
return false;
@ -710,26 +709,28 @@ value_contents_bits_eq (const struct value *val1, int offset1,
return true;
}
/* See value.h. */
bool
value_contents_eq (const struct value *val1, LONGEST offset1,
const struct value *val2, LONGEST offset2,
LONGEST length)
value::contents_eq (LONGEST offset1,
const struct value *val2, LONGEST offset2,
LONGEST length) const
{
return value_contents_bits_eq (val1, offset1 * TARGET_CHAR_BIT,
val2, offset2 * TARGET_CHAR_BIT,
length * TARGET_CHAR_BIT);
return contents_bits_eq (offset1 * TARGET_CHAR_BIT,
val2, offset2 * TARGET_CHAR_BIT,
length * TARGET_CHAR_BIT);
}
/* See value.h. */
bool
value_contents_eq (const struct value *val1, const struct value *val2)
value::contents_eq (const struct value *val2) const
{
ULONGEST len1 = check_typedef (val1->enclosing_type ())->length ();
ULONGEST len1 = check_typedef (enclosing_type ())->length ();
ULONGEST len2 = check_typedef (val2->enclosing_type ())->length ();
if (len1 != len2)
return false;
return value_contents_eq (val1, 0, val2, 0, len1);
return contents_eq (0, val2, 0, len1);
}
/* The value-history records all the values printed by print commands

View File

@ -395,6 +395,66 @@ public:
it. */
void fetch_lazy ();
/* Compare LENGTH bytes of this value's contents starting at OFFSET1
with LENGTH bytes of VAL2's contents starting at OFFSET2.
Note that "contents" refers to the whole value's contents
(value_contents_all), without any embedded offset adjustment. For
example, to compare a complete object value with itself, including
its enclosing type chunk, you'd do:
int len = check_typedef (val->enclosing_type ())->length ();
val->contents_eq (0, val, 0, len);
Returns true iff the set of available/valid contents match.
Optimized-out contents are equal to optimized-out contents, and are
not equal to non-optimized-out contents.
Unavailable contents are equal to unavailable contents, and are not
equal to non-unavailable contents.
For example, if 'x's represent an unavailable byte, and 'V' and 'Z'
represent different available/valid bytes, in a value with length
16:
offset: 0 4 8 12 16
contents: xxxxVVVVxxxxVVZZ
then:
val->contents_eq(0, val, 8, 6) => true
val->contents_eq(0, val, 4, 4) => false
val->contents_eq(0, val, 8, 8) => false
val->contents_eq(4, val, 12, 2) => true
val->contents_eq(4, val, 12, 4) => true
val->contents_eq(3, val, 4, 4) => true
If 'x's represent an unavailable byte, 'o' represents an optimized
out byte, in a value with length 8:
offset: 0 4 8
contents: xxxxoooo
then:
val->contents_eq(0, val, 2, 2) => true
val->contents_eq(4, val, 6, 2) => true
val->contents_eq(0, val, 4, 4) => true
We only know whether a value chunk is unavailable or optimized out
if we've tried to read it. As this routine is used by printing
routines, which may be printing values in the value history, long
after the inferior is gone, it works with const values. Therefore,
this routine must not be called with lazy values. */
bool contents_eq (LONGEST offset1, const struct value *val2, LONGEST offset2,
LONGEST length) const;
/* An overload of contents_eq that compares the entirety of both
values. */
bool contents_eq (const struct value *val2) const;
/* Type of value; either not an lval, or one of the various
different possible kinds of lval. */
@ -599,6 +659,17 @@ public: /* Temporary */
yet. If CHECK_SIZE is true, then apply the usual max-value-size
checks. */
void allocate_contents (bool check_size);
private:
/* Helper function for value_contents_eq. The only difference is that
this function is bit rather than byte based.
Compare LENGTH bits of this value's contents starting at OFFSET1
bits with LENGTH bits of VAL2's contents starting at OFFSET2
bits. Return true if the available bits match. */
bool contents_bits_eq (int offset1, const struct value *val2, int offset2,
int length) const;
};
/* Returns value_type or value_enclosing_type depending on
@ -833,69 +904,6 @@ extern void mark_value_bytes_unavailable (struct value *value,
extern void mark_value_bits_unavailable (struct value *value,
LONGEST offset, ULONGEST length);
/* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with
LENGTH bytes of VAL2's contents starting at OFFSET2.
Note that "contents" refers to the whole value's contents
(value_contents_all), without any embedded offset adjustment. For
example, to compare a complete object value with itself, including
its enclosing type chunk, you'd do:
int len = check_typedef (val->enclosing_type ())->length ();
value_contents_eq (val, 0, val, 0, len);
Returns true iff the set of available/valid contents match.
Optimized-out contents are equal to optimized-out contents, and are
not equal to non-optimized-out contents.
Unavailable contents are equal to unavailable contents, and are not
equal to non-unavailable contents.
For example, if 'x's represent an unavailable byte, and 'V' and 'Z'
represent different available/valid bytes, in a value with length
16:
offset: 0 4 8 12 16
contents: xxxxVVVVxxxxVVZZ
then:
value_contents_eq(val, 0, val, 8, 6) => true
value_contents_eq(val, 0, val, 4, 4) => false
value_contents_eq(val, 0, val, 8, 8) => false
value_contents_eq(val, 4, val, 12, 2) => true
value_contents_eq(val, 4, val, 12, 4) => true
value_contents_eq(val, 3, val, 4, 4) => true
If 'x's represent an unavailable byte, 'o' represents an optimized
out byte, in a value with length 8:
offset: 0 4 8
contents: xxxxoooo
then:
value_contents_eq(val, 0, val, 2, 2) => true
value_contents_eq(val, 4, val, 6, 2) => true
value_contents_eq(val, 0, val, 4, 4) => true
We only know whether a value chunk is unavailable or optimized out
if we've tried to read it. As this routine is used by printing
routines, which may be printing values in the value history, long
after the inferior is gone, it works with const values. Therefore,
this routine must not be called with lazy values. */
extern bool value_contents_eq (const struct value *val1, LONGEST offset1,
const struct value *val2, LONGEST offset2,
LONGEST length);
/* An overload of value_contents_eq that compares the entirety of both
values. */
extern bool value_contents_eq (const struct value *val1,
const struct value *val2);
/* Read LENGTH addressable memory units starting at MEMADDR into BUFFER,
which is (or will be copied to) VAL's contents buffer offset by
BIT_OFFSET bits. Marks value contents ranges as unavailable if