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; \}$" } } */