Improve Ada unchecked union type printing
authorTom Tromey <tromey@adacore.com>
Tue, 1 Feb 2022 16:46:43 +0000 (09:46 -0700)
committerTom Tromey <tromey@adacore.com>
Fri, 4 Feb 2022 15:19:42 +0000 (08:19 -0700)
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
gdb/testsuite/gdb.ada/unchecked_union.exp
gdb/testsuite/gdb.ada/unchecked_union/unchecked_union.adb

index 5f225ffb6337b15f62609883d9395d3920a19a3a..ca26382e1955bf1ee5077b999da04a637e2ff36e 100644 (file)
@@ -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, "");
index 7fc08e1526dd968c20005c891599d5e1144b5342..6a9caf229cd8c15a81fe5f73ea74e79e08ec813a 100644 (file)
@@ -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"
index 8e7b8efc078aad1e9b8c709c178b69d711666888..42fe3a997b80855013f356f9f2cee24b0e0c42a5 100644 (file)
@@ -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);