Rewrite the existing variant part code

This rewrites the existing variant part code to follow the new model
implemented in the previous patch.  The old variant part code is
removed.

This only affects Rust for the moment.  I tested this using various
version of the Rust compiler, including one that emits old-style enum
debuginfo, exercising the quirks code.

gdb/ChangeLog
2020-04-24  Tom Tromey  <tromey@adacore.com>

	* dwarf2/read.c (struct variant_field): Rewrite.
	(struct variant_part_builder): New.
	(struct nextfield): Remove "variant" field.  Add "offset".
	(struct field_info): Add "current_variant_part" and
	"variant_parts".
	(alloc_discriminant_info): Remove.
	(alloc_rust_variant): New function.
	(quirk_rust_enum): Update.
	(dwarf2_add_field): Set "offset" member.  Don't handle
	DW_TAG_variant_part.
	(offset_map_type): New typedef.
	(convert_variant_range, create_one_variant)
	(create_one_variant_part, create_variant_parts)
	(add_variant_property): New functions.
	(dwarf2_attach_fields_to_type): Call add_variant_property.
	(read_structure_type): Don't handle DW_TAG_variant_part.
	(handle_variant_part, handle_variant): New functions.
	(handle_struct_member_die): Use them.
	(process_structure_scope): Don't handle variant parts.
	* gdbtypes.h (TYPE_FLAG_DISCRIMINATED_UNION): Remove.
	(struct discriminant_info): Remove.
	(enum dynamic_prop_node_kind) <DYN_PROP_DISCRIMINATED>: Remove.
	(struct main_type) <flag_discriminated_union>: Remove.
	* rust-lang.c (rust_enum_p, rust_empty_enum_p): Rewrite.
	(rust_enum_variant): Return int.  Remove "contents".  Rewrite.
	(rust_print_enum, rust_print_struct_def, rust_evaluate_subexp):
	Update.
	* valops.c (value_union_variant): Remove.
	* value.h (value_union_variant): Don't declare.
This commit is contained in:
Tom Tromey
2020-04-24 13:40:31 -06:00
parent b249d2c2c0
commit 9c6a1327ad
6 changed files with 557 additions and 414 deletions

View File

@@ -2233,50 +2233,6 @@ value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
return NULL;
}
/* See value.h. */
int
value_union_variant (struct type *union_type, const gdb_byte *contents)
{
gdb_assert (TYPE_CODE (union_type) == TYPE_CODE_UNION
&& TYPE_FLAG_DISCRIMINATED_UNION (union_type));
struct dynamic_prop *discriminant_prop
= get_dyn_prop (DYN_PROP_DISCRIMINATED, union_type);
gdb_assert (discriminant_prop != nullptr);
struct discriminant_info *info
= (struct discriminant_info *) discriminant_prop->data.baton;
gdb_assert (info != nullptr);
/* If this is a univariant union, just return the sole field. */
if (TYPE_NFIELDS (union_type) == 1)
return 0;
/* This should only happen for univariants, which we already dealt
with. */
gdb_assert (info->discriminant_index != -1);
/* Compute the discriminant. Note that unpack_field_as_long handles
sign extension when necessary, as does the DWARF reader -- so
signed discriminants will be handled correctly despite the use of
an unsigned type here. */
ULONGEST discriminant = unpack_field_as_long (union_type, contents,
info->discriminant_index);
for (int i = 0; i < TYPE_NFIELDS (union_type); ++i)
{
if (i != info->default_index
&& i != info->discriminant_index
&& discriminant == info->discriminants[i])
return i;
}
if (info->default_index == -1)
error (_("Could not find variant corresponding to discriminant %s"),
pulongest (discriminant));
return info->default_index;
}
/* Search through the methods of an object (and its bases) to find a
specified method. Return a reference to the fn_field list METHODS of
overloaded instances defined in the source language. If available