This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch for unnamed (anonymous) unions in C
- To: egcs-patches at cygnus dot com, pisa at waltz dot felk dot cvut dot cz
- Subject: Patch for unnamed (anonymous) unions in C
- From: Antonio Mendes de Oliveira Neto <anmendes at splicenet dot com dot br>
- Date: Tue, 01 Dec 1998 01:07:47 -0200
14:00:00 1998/11/30 Antonio M. O. Neto <anmendes@splicenet.com.br>
* gcc/c-decl.c (shadow_tag_warned): Remove warning message from
anonymous unions.
Add function delete_duplicate_fields.
(finish_struct): Remove code for delete_duplicate_fields
Add call for function delete_duplicate_fields
* gcc/c-parse.in and gcc/c-parse.y: Add anonymous unions in
structs
* gcc/objc/objc-parse.y: Add anonymous unions in structs
---------------------------------------------------------------------------
diff -c3p egcs-1.1b-old/gcc/c-decl.c egcs-1.1b/gcc/c-decl.c
*** egcs-1.1b-old/gcc/c-decl.c Mon Aug 17 16:24:59 1998
--- egcs-1.1b/gcc/c-decl.c Mon Nov 30 23:16:57 1998
*************** shadow_tag_warned (declspecs, warned)
*** 3624,3630 ****
if (warned != 1 && code != ENUMERAL_TYPE)
/* Empty unnamed enum OK */
{
! pedwarn ("unnamed struct/union that defines no instances");
warned = 1;
}
}
--- 3624,3630 ----
if (warned != 1 && code != ENUMERAL_TYPE)
/* Empty unnamed enum OK */
{
! pedwarn ("unnamed union that defines no instances");
warned = 1;
}
}
*************** field_decl_cmp (xp, yp)
*** 5723,5728 ****
--- 5723,5773 ----
return 1;
}
+ /* Delete the duplicates fields. This function uses recursives method
for
+ search duplicate fields in anonymous unions inside of structures
+
+ flag : bit 0 = 1 search in anonymous unions
+ bit 1 = 1 searching and 0 steping for next search key
+ */
+ void
+ delete_duplicate_fields(component, field, sfield, flag)
+ tree component;
+ tree field;
+ tree sfield;
+ int flag;
+ {
+ tree x = TYPE_FIELDS (field);
+ tree y = x;
+
+ for (; x; y = x, x = TREE_CHAIN (x))
+ {
+ if (!(flag & 2) && DECL_NAME (x))
+ delete_duplicate_fields(x, sfield, sfield, 2);
+ else
+ {
+ /* Anonymous fields aren't duplicates */
+ if (DECL_NAME (x))
+ if (!strcmp(IDENTIFIER_POINTER (DECL_NAME (component)),
+ IDENTIFIER_POINTER (DECL_NAME (x))) &&
+ component != x)
+ {
+ if (flag & 1)
+ error_with_decl (x, "duplicate member `((anonymous
union))::%s'");
+ else
+ error_with_decl (x, "duplicate member `%s'");
+
+ if (x != y)
+ TREE_CHAIN(y) = TREE_CHAIN (TREE_CHAIN (y));
+ else
+ TYPE_FIELDS (field) = TREE_CHAIN (y);
+ }
+ }
+
+ if (!DECL_NAME (x) && TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+ delete_duplicate_fields(component, TREE_TYPE (x), sfield, flag
| 1);
+ }
+ }
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure.
*************** finish_struct (t, fieldlist, attributes)
*** 5909,5943 ****
/* Now DECL_INITIAL is null on all members. */
- /* Delete all duplicate fields from the fieldlist */
- for (x = fieldlist; x && TREE_CHAIN (x);)
- /* Anonymous fields aren't duplicates. */
- if (DECL_NAME (TREE_CHAIN (x)) == 0)
- x = TREE_CHAIN (x);
- else
- {
- register tree y = fieldlist;
-
- while (1)
- {
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- break;
- if (y == x)
- break;
- y = TREE_CHAIN (y);
- }
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- {
- error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
- TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
- }
- else x = TREE_CHAIN (x);
- }
-
/* Now we have the nearly final fieldlist. Record it,
then lay out the structure or union (including the fields). */
TYPE_FIELDS (t) = fieldlist;
layout_type (t);
--- 5954,5965 ----
/* Now DECL_INITIAL is null on all members. */
/* Now we have the nearly final fieldlist. Record it,
then lay out the structure or union (including the fields). */
TYPE_FIELDS (t) = fieldlist;
+
+ delete_duplicate_fields (fieldlist, t, t, 0);
layout_type (t);
diff -c3p egcs-1.1b-old/gcc/c-parse.in egcs-1.1b/gcc/c-parse.in
*** egcs-1.1b-old/gcc/c-parse.in Mon Jul 06 18:30:09 1998
--- egcs-1.1b/gcc/c-parse.in Mon Nov 30 14:01:51 1998
*************** components:
*** 1591,1597 ****
;
component_declarator:
! save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno
--- 1591,1603 ----
;
component_declarator:
! save_filename save_lineno maybe_attribute
! { if (TREE_CODE (TREE_VALUE (current_declspecs)) == RECORD_TYPE)
! { $$ = NULL_TREE; shadow_tag(current_declspecs); }
! else {
! $$ = grokfield ($1, $2, NULL_TREE,
current_declspecs, NULL_TREE);
! decl_attributes ($$, $3, prefix_attributes); } }
! | save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno
diff -c3p egcs-1.1b-old/gcc/c-parse.y egcs-1.1b/gcc/c-parse.y
*** egcs-1.1b-old/gcc/c-parse.y Thu Sep 03 22:46:49 1998
--- egcs-1.1b/gcc/c-parse.y Mon Nov 30 14:01:55 1998
*************** components:
*** 1404,1410 ****
;
component_declarator:
! save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno
--- 1404,1416 ----
;
component_declarator:
! save_filename save_lineno maybe_attribute
! { if (TREE_CODE (TREE_VALUE (current_declspecs)) == RECORD_TYPE)
! { $$ = NULL_TREE; shadow_tag(current_declspecs); }
! else {
! $$ = grokfield ($1, $2, NULL_TREE,
current_declspecs, NULL_TREE);
! decl_attributes ($$, $3, prefix_attributes); } }
! | save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno
diff -c3p egcs-1.1b-old/gcc/objc/objc-parse.y
egcs-1.1b/gcc/objc/objc-parse.y
*** egcs-1.1b-old/gcc/objc/objc-parse.y Thu Sep 03 22:46:49 1998
--- egcs-1.1b/gcc/objc/objc-parse.y Mon Nov 30 01:04:31 1998
*************** components:
*** 1516,1522 ****
;
component_declarator:
! save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno
--- 1516,1528 ----
;
component_declarator:
! save_filename save_lineno maybe_attribute
! { if (TREE_CODE (TREE_VALUE (current_declspecs)) == RECORD_TYPE)
! { $$ = NULL_TREE; shadow_tag(current_declspecs); }
! else {
! $$ = grokfield ($1, $2, NULL_TREE,
current_declspecs, NULL_TREE);
! decl_attributes ($$, $3, prefix_attributes); } }
! | save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
decl_attributes ($$, $4, prefix_attributes); }
| save_filename save_lineno