2005-12-11 Andrew Pinski <pinskia@physics.uc.edu>
authorpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 11 Dec 2005 06:59:12 +0000 (06:59 +0000)
committerpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 11 Dec 2005 06:59:12 +0000 (06:59 +0000)
        PR libobjc/25347
        * encoding.c (objc_sizeof_type): Don't handle _C_UNION_B special
        but use the struct layout functions.
        (objc_alignof_type): Likewise.
        (objc_layout_structure): Handle _C_UNION_B also.
        (objc_layout_structure_next_member): Likewise.
        (objc_layout_finish_structure): Likewise.

2005-12-11  Andrew Pinski  <pinskia@physics.uc.edu>

        PR libobjc/25347
        * objc.dg/encode-8.m: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108379 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/objc.dg/encode-8.m [new file with mode: 0644]
libobjc/ChangeLog
libobjc/encoding.c

index 71286b1..21ec14b 100644 (file)
@@ -1,5 +1,10 @@
 2005-12-11  Andrew Pinski  <pinskia@physics.uc.edu>
 
+       PR libobjc/25347
+       * objc.dg/encode-8.m: New test.
+
+2005-12-11  Andrew Pinski  <pinskia@physics.uc.edu>
+
        PR libobjc/25346
        * objc.dg/encode-7.m: New test.
 
diff --git a/gcc/testsuite/objc.dg/encode-8.m b/gcc/testsuite/objc.dg/encode-8.m
new file mode 100644 (file)
index 0000000..947a929
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-options "-fgnu-runtime" } */
+/* { dg-do run } */
+
+#include <objc/encoding.h>
+#include <stdlib.h>
+
+union f
+{
+  char i;
+  double f1;
+  short t;
+};
+
+union g
+{
+  int i;
+};
+
+
+int main(void)
+{
+  if (objc_sizeof_type (@encode (union f)) != sizeof(union f))
+   abort ();
+  if (objc_alignof_type (@encode (union f)) != __alignof__(union f))
+   abort ();
+  if (objc_sizeof_type (@encode (union g)) != sizeof(union g))
+   abort ();
+  if (objc_alignof_type (@encode (union g)) != __alignof__(union g))
+   abort ();
+  return 0;
+}
index 56f1ef8..cb124aa 100644 (file)
@@ -1,5 +1,15 @@
 2005-12-11  Andrew Pinski  <pinskia@physics.uc.edu>
 
+       PR libobjc/25347
+       * encoding.c (objc_sizeof_type): Don't handle _C_UNION_B special
+       but use the struct layout functions.
+       (objc_alignof_type): Likewise.
+       (objc_layout_structure): Handle _C_UNION_B also.
+       (objc_layout_structure_next_member): Likewise.
+       (objc_layout_finish_structure): Likewise.
+
+2005-12-11  Andrew Pinski  <pinskia@physics.uc.edu>
+
        PR libobjc/25346
        * objc/objc-api.h (_C_BOOL): New define.
        * encoding.c (objc_sizeof_type): Handle _C_BOOL.
index 7f6004f..1587c07 100644 (file)
@@ -222,6 +222,7 @@ objc_sizeof_type (const char *type)
       return endByte - startByte;
     }
 
+  case _C_UNION_B:
   case _C_STRUCT_B:
     {
       struct objc_struct_layout layout;
@@ -235,25 +236,6 @@ objc_sizeof_type (const char *type)
       return size;
     }
 
-  case _C_UNION_B:
-    {
-      int max_size = 0;
-      while (*type != _C_UNION_E && *type++ != '=')
-       /* do nothing */;
-      while (*type != _C_UNION_E)
-       {
-         /* Skip the variable name if any */
-         if (*type == '"')
-           {
-             for (type++; *type++ != '"';)
-               /* do nothing */;
-           }
-         max_size = MAX (max_size, objc_sizeof_type (type));
-         type = objc_skip_typespec (type);
-       }
-      return max_size;
-    }
-
   default:
     {
       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
@@ -353,6 +335,7 @@ objc_alignof_type (const char *type)
     return objc_alignof_type (type);
 
   case _C_STRUCT_B:
+  case _C_UNION_B:
     {
       struct objc_struct_layout layout;
       unsigned int align;
@@ -365,25 +348,6 @@ objc_alignof_type (const char *type)
       return align;
     }
 
-  case _C_UNION_B:
-    {
-      int maxalign = 0;
-      while (*type != _C_UNION_E && *type++ != '=')
-       /* do nothing */;
-      while (*type != _C_UNION_E)
-       {
-         /* Skip the variable name if any */
-         if (*type == '"')
-           {
-             for (type++; *type++ != '"';)
-               /* do nothing */;
-           }
-         maxalign = MAX (maxalign, objc_alignof_type (type));
-         type = objc_skip_typespec (type);
-       }
-      return maxalign;
-    }
-
   default:
     {
       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
@@ -762,13 +726,14 @@ objc_layout_structure (const char *type,
 {
   const char *ntype;
 
-  if (*type++ != _C_STRUCT_B)
+  if (*type != _C_UNION_B && *type != _C_STRUCT_B)
     {
       objc_error (nil, OBJC_ERR_BAD_TYPE,
-                 "record type expected in objc_layout_structure, got %s\n",
+                 "record (or union) type expected in objc_layout_structure, got %s\n",
                  type);
     }
 
+  type ++;
   layout->original_type = type;
 
   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
@@ -801,13 +766,17 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
 
   /* The current type without the type qualifiers */
   const char *type;
+  BOOL unionp = layout->original_type[-1] == _C_UNION_B;
 
   /* Add the size of the previous field to the size of the record.  */
   if (layout->prev_type)
     {
       type = objc_skip_type_qualifiers (layout->prev_type);
+      if (unionp)
+        layout->record_size = MAX (layout->record_size,
+                                  objc_sizeof_type (type) * BITS_PER_UNIT);
 
-      if (*type != _C_BFLD)
+      else if (*type != _C_BFLD)
         layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
       else {
         /* Get the bitfield's type */
@@ -823,7 +792,8 @@ objc_layout_structure_next_member (struct objc_struct_layout *layout)
       }
     }
 
-  if (*layout->type == _C_STRUCT_E)
+  if ((unionp && *layout->type == _C_UNION_E)
+      || (!unionp && *layout->type == _C_STRUCT_E))
     return NO;
 
   /* Skip the variable name if any */
@@ -923,7 +893,10 @@ void objc_layout_finish_structure (struct objc_struct_layout *layout,
                                    unsigned int *size,
                                    unsigned int *align)
 {
-  if (layout->type && *layout->type == _C_STRUCT_E)
+  BOOL unionp = layout->original_type[-1] == _C_UNION_B;
+  if (layout->type
+      && ((!unionp && *layout->type == _C_STRUCT_E)
+                 || (unionp && *layout->type == _C_UNION_E)))
     {
       /* Work out the alignment of the record as one expression and store
          in the record type.  Round it up to a multiple of the record's