Improve Ada unchecked union type printing

Currently, "ptype" of an Ada unchecked union may show a
compiler-generated wrapper structure in its output.  It's more
Ada-like to elide this structure, which is what this patch implements.
It turned out to be simplest to reuse a part of print_variant_clauses
for this.

As this is Ada-specific, and Joel already reviewed it internally, I am
going to check it in.
This commit is contained in:
Tom Tromey 2022-02-01 09:46:43 -07:00
parent 2b53149244
commit 480157863b
3 changed files with 42 additions and 29 deletions

View file

@ -506,6 +506,35 @@ Huh:
return 0; return 0;
} }
/* A helper for print_variant_clauses that prints the members of
VAR_TYPE. DISCR_TYPE is the type of the discriminant (or nullptr
if not available). The discriminant is contained in OUTER_TYPE.
STREAM, LEVEL, SHOW, and FLAGS are the same as for
ada_print_type. */
static void
print_variant_clauses (struct type *var_type, struct type *discr_type,
struct type *outer_type, struct ui_file *stream,
int show, int level,
const struct type_print_options *flags)
{
for (int i = 0; i < var_type->num_fields (); i += 1)
{
fprintf_filtered (stream, "\n%*swhen ", level, "");
if (print_choices (var_type, i, stream, discr_type))
{
if (print_record_field_types (var_type->field (i).type (),
outer_type, stream, show, level,
flags)
<= 0)
fprintf_filtered (stream, " null;");
}
else
print_selected_record_field_types (var_type, outer_type, i, i,
stream, show, level, flags);
}
}
/* Assuming that field FIELD_NUM of TYPE represents variants whose /* Assuming that field FIELD_NUM of TYPE represents variants whose
discriminant is contained in OUTER_TYPE, print its components on STREAM. discriminant is contained in OUTER_TYPE, print its components on STREAM.
LEVEL is the recursion (indentation) level, in case any of the fields LEVEL is the recursion (indentation) level, in case any of the fields
@ -520,7 +549,6 @@ print_variant_clauses (struct type *type, int field_num,
int show, int level, int show, int level,
const struct type_print_options *flags) const struct type_print_options *flags)
{ {
int i;
struct type *var_type, *par_type; struct type *var_type, *par_type;
struct type *discr_type; struct type *discr_type;
@ -538,21 +566,8 @@ print_variant_clauses (struct type *type, int field_num,
if (par_type != NULL) if (par_type != NULL)
var_type = par_type; var_type = par_type;
for (i = 0; i < var_type->num_fields (); i += 1) print_variant_clauses (var_type, discr_type, outer_type, stream, show,
{ level + 4, flags);
fprintf_filtered (stream, "\n%*swhen ", level + 4, "");
if (print_choices (var_type, i, stream, discr_type))
{
if (print_record_field_types (var_type->field (i).type (),
outer_type, stream, show, level + 4,
flags)
<= 0)
fprintf_filtered (stream, " null;");
}
else
print_selected_record_field_types (var_type, outer_type, i, i,
stream, show, level + 4, flags);
}
} }
/* Assuming that field FIELD_NUM of TYPE is a variant part whose /* Assuming that field FIELD_NUM of TYPE is a variant part whose
@ -842,19 +857,9 @@ print_unchecked_union_type (struct type *type, struct ui_file *stream,
fprintf_filtered (stream, "record (?) is null; end record"); fprintf_filtered (stream, "record (?) is null; end record");
else else
{ {
int i;
fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, ""); fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, "");
for (i = 0; i < type->num_fields (); i += 1) print_variant_clauses (type, nullptr, type, stream, show, level + 8, flags);
{
fprintf_filtered (stream, "\n%*swhen ? =>\n%*s", level + 8, "",
level + 12, "");
ada_print_type (type->field (i).type (),
type->field (i).name (),
stream, show - 1, level + 12, flags);
fprintf_filtered (stream, ";");
}
fprintf_filtered (stream, "\n%*send case;\n%*send record", fprintf_filtered (stream, "\n%*send case;\n%*send record",
level + 4, "", level, ""); level + 4, "", level, "");

View file

@ -30,10 +30,14 @@ proc multi_line_string {str} {
} }
set inner_string { case ? is set inner_string { case ? is
when ? => when 0 =>
small: range 0 .. 255; small: range 0 .. 255;
second: range 0 .. 255;
when ? => when ? =>
bval: range 0 .. 255;
when others =>
large: range 255 .. 510; large: range 255 .. 510;
more: range 255 .. 510;
end case; end case;
} }
set inner_full "type = record (?) is\n${inner_string}end record" set inner_full "type = record (?) is\n${inner_string}end record"

View file

@ -17,14 +17,18 @@ with System;
with Pck; use Pck; with Pck; use Pck;
procedure Foo is procedure Foo is
type Key is (Alpha, Omega); type Key is (Alpha, Beta, Omega);
type Inner(Disc : Key := Omega) is record type Inner(Disc : Key := Omega) is record
case Disc is case Disc is
when Alpha => when Alpha =>
Small : Integer range 0..255; Small : Integer range 0..255;
Second : Integer range 0..255;
when Beta =>
Bval : Integer range 0..255;
when others => when others =>
Large : Integer range 255..510; Large : Integer range 255..510;
More : Integer range 255..510;
end case; end case;
end record; end record;
pragma Unchecked_Union (Inner); pragma Unchecked_Union (Inner);