On 12/13/20 4:55 PM, Nikhil Benesch wrote:
There are a few more hurdles before this patch is ready for commit. The
changes to godump.c deserve new test cases. [...]

Updated patch attached, as promised, and is ready for review.

gcc/:
        * godump.c (go_output_typedef): Suppress typedefs whose name
        matches the tag of the underlying struct, union, or enum.
        Output declarations for enums that do not appear in typedefs.
gcc/testsuite:
        * gcc.misc-tests/godump-1.c: Add test cases.

I don't have write access, so whoever reviews, please commit if approved.

Nikhil
diff --git a/gcc/godump.c b/gcc/godump.c
index 033b2c59f3c..ff3a4a9c52c 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -1155,15 +1155,25 @@ go_output_typedef (class godump_container *container, 
tree decl)
     {
       void **slot;
       const char *type;
+      tree original_type;

       type = IDENTIFIER_POINTER (DECL_NAME (decl));
+      original_type = DECL_ORIGINAL_TYPE (decl);
+
+      /* Suppress typedefs where the type name matches the underlying
+        struct/union/enum tag. This way we'll emit the struct definition
+        instead of an invalid recursive type.  */
+      if (TYPE_IDENTIFIER (original_type) != NULL
+         && IDENTIFIER_POINTER (TYPE_IDENTIFIER (original_type)) == type)
+       return;
+
       /* If type defined already, skip.  */
       slot = htab_find_slot (container->type_hash, type, INSERT);
       if (*slot != NULL)
        return;
       *slot = CONST_CAST (void *, (const void *) type);

-      if (!go_format_type (container, DECL_ORIGINAL_TYPE (decl), true, false,
+      if (!go_format_type (container, original_type, true, false,
                           NULL, false))
        {
          fprintf (go_dump_file, "// ");
@@ -1187,7 +1197,9 @@ go_output_typedef (class godump_container *container, 
tree decl)

       container->decls_seen.add (decl);
     }
-  else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+  else if ((RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
+           || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+          && TYPE_NAME (TREE_TYPE (decl)) != NULL)
     {
        void **slot;
        const char *type;
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c 
b/gcc/testsuite/gcc.misc-tests/godump-1.c
index 96c25863374..d37ab0b5af4 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -396,6 +396,15 @@ typedef enum { ET1, ET2 } et_t;
 /* { dg-final { scan-file godump-1.out "(?n)^const _ET1 = 0$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^const _ET2 = 1$" } } */

+typedef enum e_t_idem_v1 { ETIV1 } e_t_idem_v1;
+/* { dg-final { scan-file godump-1.out "(?n)^type _e_t_idem_v1 u?int\[0-9\]*$" 
} } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETIV1 = 0$" } } */
+
+typedef enum e_t_idem_v2 e_t_idem_v2;
+enum e_t_idem_v2 { ETIV2 };
+/* { dg-final { scan-file godump-1.out "(?n)^type _e_t_idem_v2 u?int\[0-9\]*$" 
} } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETIV2 = 0$" } } */
+
 enum { ETV1, ETV2 } et_v1;
 /* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 u?int\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^const _ETV1 = 0$" } } */
@@ -477,6 +486,13 @@ struct s_fwd v_fwd;
 struct s_fwd { };
 /* { dg-final { scan-file godump-1.out "(?n)^type _s_fwd struct \{ \}$" } } */

+typedef struct s_t_idem_v1 {} s_t_idem_v1;
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_t_idem_v1 struct \{ \}$" 
} } */
+
+typedef struct s_t_idem_v2 s_t_idem_v2;
+struct s_t_idem_v2 { };
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_t_idem_v2 struct \{ \}$" 
} } */
+
 /*** nested structs ***/
 typedef struct { struct { uint8_t ca[3]; } s; uint32_t i; } tsn;
 /* { dg-final { scan-file godump-1.out "(?n)^type _tsn struct \{ s struct \{ 
ca \\\[2\\+1\\\]uint8; \}; i uint32; \}$" } } */
@@ -756,6 +772,13 @@ typedef union { } tue;
 union { } ue;
 /* { dg-final { scan-file godump-1.out "(?n)^var _ue struct \{ \}$" } } */

+typedef union u_t_idem_v1 { } u_t_idem_v1;
+/* { dg-final { scan-file godump-1.out "(?n)^type _u_t_idem_v1 struct \{ \}$" 
} } */
+
+typedef union u_t_idem_v2 u_t_idem_v2;
+union u_t_idem_v2 { };
+/* { dg-final { scan-file godump-1.out "(?n)^type _u_t_idem_v2 struct \{ \}$" 
} } */
+
 typedef union { uint8_t c; uint64_t l; } tu1;
 /* { dg-final { scan-file godump-1.out "(?n)^type _tu1 struct \{ c uint8; 
Godump_0_pad \\\[.\\\]byte; Godump_1_align \\\[0\\\]u?int64; \}$" } } */

Reply via email to