From 480157863bac93e56f97f93d5d90818a47debbf6 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 1 Feb 2022 09:46:43 -0700 Subject: [PATCH] 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. --- gdb/ada-typeprint.c | 59 ++++++++++--------- gdb/testsuite/gdb.ada/unchecked_union.exp | 6 +- .../unchecked_union/unchecked_union.adb | 6 +- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/gdb/ada-typeprint.c b/gdb/ada-typeprint.c index 5f225ffb633..ca26382e195 100644 --- a/gdb/ada-typeprint.c +++ b/gdb/ada-typeprint.c @@ -506,6 +506,35 @@ Huh: 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 discriminant is contained in OUTER_TYPE, print its components on STREAM. 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, const struct type_print_options *flags) { - int i; struct type *var_type, *par_type; struct type *discr_type; @@ -538,21 +566,8 @@ print_variant_clauses (struct type *type, int field_num, if (par_type != NULL) var_type = par_type; - for (i = 0; i < var_type->num_fields (); i += 1) - { - 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); - } + print_variant_clauses (var_type, discr_type, outer_type, stream, show, + level + 4, flags); } /* 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"); else { - int i; - fprintf_filtered (stream, "record (?) is\n%*scase ? is", level + 4, ""); - for (i = 0; i < type->num_fields (); i += 1) - { - 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, ";"); - } + print_variant_clauses (type, nullptr, type, stream, show, level + 8, flags); fprintf_filtered (stream, "\n%*send case;\n%*send record", level + 4, "", level, ""); diff --git a/gdb/testsuite/gdb.ada/unchecked_union.exp b/gdb/testsuite/gdb.ada/unchecked_union.exp index 7fc08e1526d..6a9caf229cd 100644 --- a/gdb/testsuite/gdb.ada/unchecked_union.exp +++ b/gdb/testsuite/gdb.ada/unchecked_union.exp @@ -30,10 +30,14 @@ proc multi_line_string {str} { } set inner_string { case ? is - when ? => + when 0 => small: range 0 .. 255; + second: range 0 .. 255; when ? => + bval: range 0 .. 255; + when others => large: range 255 .. 510; + more: range 255 .. 510; end case; } set inner_full "type = record (?) is\n${inner_string}end record" diff --git a/gdb/testsuite/gdb.ada/unchecked_union/unchecked_union.adb b/gdb/testsuite/gdb.ada/unchecked_union/unchecked_union.adb index 8e7b8efc078..42fe3a997b8 100644 --- a/gdb/testsuite/gdb.ada/unchecked_union/unchecked_union.adb +++ b/gdb/testsuite/gdb.ada/unchecked_union/unchecked_union.adb @@ -17,14 +17,18 @@ with System; with Pck; use Pck; procedure Foo is - type Key is (Alpha, Omega); + type Key is (Alpha, Beta, Omega); type Inner(Disc : Key := Omega) is record case Disc is when Alpha => Small : Integer range 0..255; + Second : Integer range 0..255; + when Beta => + Bval : Integer range 0..255; when others => Large : Integer range 255..510; + More : Integer range 255..510; end case; end record; pragma Unchecked_Union (Inner); -- 2.30.2