This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Anonymous struct/union in C
- To: egcs-patches at egcs dot cygnus dot com
- Subject: Anonymous struct/union in C
- From: Mumit Khan <khan at xraylith dot wisc dot EDU>
- Date: Tue, 15 Jun 1999 21:35:42 -0500
I've been sitting on Alastair Houghton's patch to support anonymous
aggregates for a long time, and it's probably a good time to send
if off now that Jason has added anon struct to C++.
It adds the support for the following:
#include <stdio.h>
struct {
struct {
int b1;
int b2;
};
union {
float f1;
int i1;
};
int b3;
} foo = {{31, 17}, {3.2}, 13};
int
main ()
{
int b1 = foo.b1;
int b3 = foo.b3;
return 0;
}
as well as the following:
#include <stdio.h>
struct phone
{
int areacode;
int number;
};
struct person
{
char name[30];
struct phone;
} Jim = {"Jim bob", {53706, 123456}};
int
main ()
{
printf ("Jim's name = %s\n", Jim.name);
printf ("Jim's areacode = %d\n", Jim.areacode);
printf ("Jim's number = %d\n", Jim.number);
return 0;
}
Note that I have NOT added the changes to regenerated files since
I'm basically looking for comments/critiques (ok, and flame) at this
stage.
The change to c-parse.in (component_decl) is pretty self-explanatory.
I've had to remove the field-sorting from c-decl.c (finish_struct)
to avoid lossage when a structure contains anon struct/union AND
has more than 16, the magic number, fields.
No testsuite regressions. I've tested it reasonably well, some on
real code that makes extensive use of anonymous struct/union
struct members. It's been in use by a few windows32 folks as well.
==== patch
Modified version of Alastair Houghton' original patch to
support unnamed/anonymous structs and unions in C.
Sat Jun 12 15:56:40 1999 Alastair J. Houghton <ajh8@doc.ic.ac.uk>
Mumit Khan <khan@xraylith.wisc.edu>
* c-parse.in (component_decl): Support anonymous struct/union.
(%expect): Update.
* c-parse.y: Regenerate.
* c-parse.c: Likewise.
* objc/objc-parse.y: Likewise.
* objc/objc-parse.c: Likewise.
* c-decl.c (finish_struct): Don't sort the fields.
Index: gcc-2.95/gcc/c-parse.in
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95/gcc/c-parse.in,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 c-parse.in
--- gcc-2.95/gcc/c-parse.in 1999/06/10 02:09:53 1.1.1.1
+++ gcc-2.95/gcc/c-parse.in 1999/06/12 04:40:07
@@ -28,10 +28,10 @@ Boston, MA 02111-1307, USA. */
written by AT&T, but I have never seen it. */
ifobjc
-%expect 66
+%expect 73
end ifobjc
ifc
-%expect 51
+%expect 52
/* These are the 23 conflicts you should get in parse.output;
the state numbers may vary if minor changes in the grammar are made.
@@ -1594,12 +1594,21 @@ component_decl:
prefix_attributes = TREE_PURPOSE (declspec_stack);
declspec_stack = TREE_CHAIN (declspec_stack);
resume_momentary ($2); }
- | typed_typespecs
- { if (pedantic)
- pedwarn ("ANSI C forbids member declarations with no members");
- shadow_tag($1);
- $$ = NULL_TREE; }
- | nonempty_type_quals setspecs components
+ | typed_typespecs setspecs save_filename save_lineno maybe_attribute
+ {
+ /* Support for unnamed structs or unions as members of
+ structs or unions (which is [a] useful and [b] supports
+ MS P-SDK). */
+ if (pedantic)
+ pedwarn ("ANSI C doesn't support unnamed structs/unions");
+
+ $$ = grokfield($3, $4, NULL, current_declspecs, NULL_TREE);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2);
+ }
+ | nonempty_type_quals setspecs components
{ $$ = $3;
current_declspecs = TREE_VALUE (declspec_stack);
prefix_attributes = TREE_PURPOSE (declspec_stack);
Index: gcc-2.95/gcc/c-decl.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/gcc-2.95/gcc/c-decl.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 c-decl.c
--- gcc-2.95/gcc/c-decl.c 1999/06/10 02:09:53 1.1.1.1
+++ gcc-2.95/gcc/c-decl.c 1999/06/12 20:38:08
@@ -6043,43 +6045,6 @@ finish_struct (t, fieldlist, attributes)
Store it in this type and in the variants. */
TYPE_FIELDS (t) = fieldlist;
-
- /* If there are lots of fields, sort so we can look through them fast.
- We arbitrarily consider 16 or more elts to be "a lot". */
- {
- int len = 0;
-
- for (x = fieldlist; x; x = TREE_CHAIN (x))
- {
- if (len > 15)
- break;
- len += 1;
- }
- if (len > 15)
- {
- tree *field_array;
- char *space;
-
- len += list_length (x);
- /* Use the same allocation policy here that make_node uses, to
- ensure that this lives as long as the rest of the struct decl.
- All decls in an inline function need to be saved. */
- if (allocation_temporary_p ())
- space = savealloc (sizeof (struct lang_type) + len * sizeof (tree));
- else
- space = oballoc (sizeof (struct lang_type) + len * sizeof (tree));
-
- TYPE_LANG_SPECIFIC (t) = (struct lang_type *) space;
- TYPE_LANG_SPECIFIC (t)->len = len;
-
- field_array = &TYPE_LANG_SPECIFIC (t)->elts[0];
- len = 0;
- for (x = fieldlist; x; x = TREE_CHAIN (x))
- field_array[len++] = x;
-
- qsort (field_array, len, sizeof (tree), field_decl_cmp);
- }
- }
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
Regards,
Mumit