This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch for unnamed (anonymous) unions in C


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






Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]