Rainer Orth <r...@cebitec.uni-bielefeld.de> writes: > <sys/types.h> has > > typedef union { > long double _q; > uint32_t _l[4]; > } upad128_t; > > I already have to provide a _upad128_t replacement for other uses, but > it would really help to support this directly.
I think I have fixed this problem with this patch. This patch looks for the first field in a union which has a usable type, increasing the chances of making the union usable in Go. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline. Ian 2011-05-25 Ian Lance Taylor <i...@google.com> * godump.c (go_format_type): Output the first field with a usable Go type, if any.
Index: gcc/godump.c =================================================================== --- gcc/godump.c (revision 174253) +++ gcc/godump.c (working copy) @@ -685,6 +685,17 @@ go_format_type (struct godump_container field != NULL_TREE; field = TREE_CHAIN (field)) { + struct obstack hold_type_obstack; + bool field_ok; + + if (TREE_CODE (type) == UNION_TYPE) + { + hold_type_obstack = container->type_obstack; + obstack_init (&container->type_obstack); + } + + field_ok = true; + if (DECL_NAME (field) == NULL) { char buf[100]; @@ -711,7 +722,7 @@ go_format_type (struct godump_container if (DECL_BIT_FIELD (field)) { obstack_grow (ob, "INVALID-bit-field", 17); - ret = false; + field_ok = false; } else { @@ -734,7 +745,7 @@ go_format_type (struct godump_container IDENTIFIER_POINTER (name), NO_INSERT); if (slot != NULL) - ret = false; + field_ok = false; obstack_1grow (ob, '_'); go_append_string (ob, name); @@ -743,15 +754,39 @@ go_format_type (struct godump_container { if (!go_format_type (container, TREE_TYPE (field), true, false)) - ret = false; + field_ok = false; } } obstack_grow (ob, "; ", 2); - /* Only output the first field of a union, and hope for - the best. */ + /* Only output the first successful field of a union, and + hope for the best. */ if (TREE_CODE (type) == UNION_TYPE) - break; + { + if (!field_ok && TREE_CHAIN (field) == NULL_TREE) + { + field_ok = true; + ret = false; + } + if (field_ok) + { + unsigned int sz; + + sz = obstack_object_size (&container->type_obstack); + obstack_grow (&hold_type_obstack, + obstack_base (&container->type_obstack), + sz); + } + obstack_free (&container->type_obstack, NULL); + container->type_obstack = hold_type_obstack; + if (field_ok) + break; + } + else + { + if (!field_ok) + ret = false; + } } obstack_1grow (ob, '}'); }