diff options
author | Tom Tromey <tromey@adacore.com> | 2020-04-24 13:40:31 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2020-04-24 13:40:31 -0600 |
commit | ef83a141a291474f1364d6c64ee7a207b96b8e19 (patch) | |
tree | ff9631e4ec9fa56f4bd480982b6ed04af5816b8a /gdb/value.c | |
parent | 675127ec647e08ceabc66ec7d3ad560d91deacad (diff) | |
download | binutils-gdb-ef83a141a291474f1364d6c64ee7a207b96b8e19.tar.gz |
Add new variant part code
This patch adds the infrastructure for the new variant part code. At
this point, nothing uses this code. This is done in a separate patch
to make it simpler to review.
I examined a few possible approaches to handling variant parts. In
particular, I considered having a DWARF variant part be a union
(similar to how the Rust code works now); and I considered having type
fields have a flag indicating that they are variants.
Having separate types seemed bad conceptually, because these variants
aren't truly separate -- they rely on the "parent" type. And,
changing how fields worked seemed excessively invasive.
So, in the end I thought the approach taken in this patch was both
simple to implement and understand, without losing generality. The
idea in this patch is that all the fields of a type with variant parts
will be stored in a single field array, just as if they'd all been
listed directly. Then, the variants are attached as a dynamic
property. These control which fields end up in the type that's
constructed during dynamic type resolution.
gdb/ChangeLog
2020-04-24 Tom Tromey <tromey@adacore.com>
* gdbtypes.c (is_dynamic_type_internal): Check for variant parts.
(variant::matches, compute_variant_fields_recurse)
(compute_variant_fields_inner, compute_variant_fields): New
functions.
(resolve_dynamic_struct): Check for DYN_PROP_VARIANT_PARTS.
Use resolved_type after type is made.
(operator==): Add new cases.
* gdbtypes.h (TYPE_HAS_VARIANT_PARTS): New macro.
(struct discriminant_range, struct variant, struct variant_part):
New.
(union dynamic_prop_data) <variant_parts, original_type>: New
members.
(enum dynamic_prop_node_kind) <DYN_PROP_VARIANT_PARTS>: New constant.
(enum dynamic_prop_kind) <PROP_TYPE, PROP_VARIANT_PARTS>: New
constants.
* value.c (unpack_bits_as_long): Now public.
* value.h (unpack_bits_as_long): Declare.
Diffstat (limited to 'gdb/value.c')
-rw-r--r-- | gdb/value.c | 20 |
1 files changed, 3 insertions, 17 deletions
diff --git a/gdb/value.c b/gdb/value.c index 6e2a9ba4fcc..5ae0b32f4fc 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -3090,23 +3090,9 @@ value_fn_field (struct value **arg1p, struct fn_field *f, -/* Unpack a bitfield of the specified FIELD_TYPE, from the object at - VALADDR, and store the result in *RESULT. - The bitfield starts at BITPOS bits and contains BITSIZE bits; if - BITSIZE is zero, then the length is taken from FIELD_TYPE. - - Extracting bits depends on endianness of the machine. Compute the - number of least significant bits to discard. For big endian machines, - we compute the total number of bits in the anonymous object, subtract - off the bit count from the MSB of the object to the MSB of the - bitfield, then the size of the bitfield, which leaves the LSB discard - count. For little endian machines, the discard count is simply the - number of bits from the LSB of the anonymous object to the LSB of the - bitfield. - - If the field is signed, we also do sign extension. */ - -static LONGEST +/* See value.h. */ + +LONGEST unpack_bits_as_long (struct type *field_type, const gdb_byte *valaddr, LONGEST bitpos, LONGEST bitsize) { |