OSDN Git Service

2005-12-11 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / libobjc / encoding.c
1 /* Encoding of types for Objective C.
2    Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004
3    Free Software Foundation, Inc.
4    Contributed by Kresten Krab Thorup
5    Bitfield support by Ovidiu Predescu
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 Boston, MA 02110-1301, USA.  */
23
24 /* As a special exception, if you link this library with files
25    compiled with GCC to produce an executable, this does not cause
26    the resulting executable to be covered by the GNU General Public License.
27    This exception does not however invalidate any other reasons why
28    the executable file might be covered by the GNU General Public License.  */
29
30 /* FIXME: This file has no business including tm.h.  */
31
32 #include "tconfig.h"
33 #include "coretypes.h"
34 #include "tm.h"
35 #include "objc/objc-api.h"
36 #include "objc/encoding.h"
37 #include <stdlib.h>
38
39 #undef  MAX
40 #define MAX(X, Y)                    \
41   ({ typeof (X) __x = (X), __y = (Y); \
42      (__x > __y ? __x : __y); })
43
44 #undef  MIN
45 #define MIN(X, Y)                    \
46   ({ typeof (X) __x = (X), __y = (Y); \
47      (__x < __y ? __x : __y); })
48
49 #undef  ROUND
50 #define ROUND(V, A) \
51   ({ typeof (V) __v = (V); typeof (A) __a = (A); \
52      __a * ((__v+__a - 1)/__a); })
53
54
55 /* Various hacks for objc_layout_record. These are used by the target
56    macros. */
57
58 #define TREE_CODE(TYPE) *(TYPE)
59 #define TREE_TYPE(TREE) (TREE)
60
61 #define RECORD_TYPE     _C_STRUCT_B
62 #define UNION_TYPE      _C_UNION_B
63 #define QUAL_UNION_TYPE _C_UNION_B
64 #define ARRAY_TYPE      _C_ARY_B
65
66 #define REAL_TYPE       _C_DBL
67
68 #define VECTOR_TYPE     _C_VECTOR
69
70 #define TYPE_FIELDS(TYPE)     objc_skip_typespec (TYPE)
71
72 #define DECL_MODE(TYPE) *(TYPE)
73 #define TYPE_MODE(TYPE) *(TYPE)
74
75 #define DFmode          _C_DBL
76
77 #define get_inner_array_type(TYPE)      ((TYPE) + 1)
78
79 /* Some ports (eg ARM) allow the structure size boundary to be
80    selected at compile-time.  We override the normal definition with
81    one that has a constant value for this compilation.  */
82 #ifndef BITS_PER_UNIT
83 #define BITS_PER_UNIT 8
84 #endif
85 #undef  STRUCTURE_SIZE_BOUNDARY
86 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
87
88 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
89    target_flags.  Define a dummy entry here to so we don't die.
90    We have to rename it because target_flags may already have been
91    declared extern.  */
92 #define target_flags not_target_flags
93 static int __attribute__ ((__unused__)) not_target_flags = 0;
94
95 /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
96    Define a dummy ALTIVEC_VECTOR_MODE so it will not die.  */
97 #undef ALTIVEC_VECTOR_MODE
98 #define ALTIVEC_VECTOR_MODE(MODE) (0)
99
100
101 /*  FIXME: while this file has no business including tm.h, this
102     definitely has no business defining this macro but it
103     is only way around without really rewritting this file,
104     should look after the branch of 3.4 to fix this.  */
105 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED)    \
106   ((TYPE_FIELDS (STRUCT) != 0                                           \
107     && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode)                      \
108    ? MAX (MAX (COMPUTED, SPECIFIED), 64)                                \
109    : MAX (COMPUTED, SPECIFIED))
110
111 /*
112   return the size of an object specified by type
113 */
114
115 int
116 objc_sizeof_type (const char *type)
117 {
118   /* Skip the variable name if any */
119   if (*type == '"')
120     {
121       for (type++; *type++ != '"';)
122         /* do nothing */;
123     }
124
125   switch (*type) {
126   case _C_BOOL:
127     return sizeof (_Bool);
128     break;
129
130   case _C_ID:
131     return sizeof (id);
132     break;
133
134   case _C_CLASS:
135     return sizeof (Class);
136     break;
137
138   case _C_SEL:
139     return sizeof (SEL);
140     break;
141
142   case _C_CHR:
143     return sizeof (char);
144     break;
145
146   case _C_UCHR:
147     return sizeof (unsigned char);
148     break;
149
150   case _C_SHT:
151     return sizeof (short);
152     break;
153
154   case _C_USHT:
155     return sizeof (unsigned short);
156     break;
157
158   case _C_INT:
159     return sizeof (int);
160     break;
161
162   case _C_UINT:
163     return sizeof (unsigned int);
164     break;
165
166   case _C_LNG:
167     return sizeof (long);
168     break;
169
170   case _C_ULNG:
171     return sizeof (unsigned long);
172     break;
173
174   case _C_LNG_LNG:
175     return sizeof (long long);
176     break;
177
178   case _C_ULNG_LNG:
179     return sizeof (unsigned long long);
180     break;
181
182   case _C_FLT:
183     return sizeof (float);
184     break;
185
186   case _C_DBL:
187     return sizeof (double);
188     break;
189
190   case _C_VOID:
191     return sizeof (void);
192     break;
193
194   case _C_PTR:
195   case _C_ATOM:
196   case _C_CHARPTR:
197     return sizeof (char *);
198     break;
199
200   case _C_ARY_B:
201     {
202       int len = atoi (type + 1);
203       while (isdigit ((unsigned char)*++type))
204         ;
205       return len * objc_aligned_size (type);
206     }
207     break;
208
209   case _C_BFLD:
210     {
211       /* The new encoding of bitfields is: b 'position' 'type' 'size' */
212       int position, size;
213       int startByte, endByte;
214
215       position = atoi (type + 1);
216       while (isdigit ((unsigned char)*++type))
217         ;
218       size = atoi (type + 1);
219
220       startByte = position / BITS_PER_UNIT;
221       endByte = (position + size) / BITS_PER_UNIT;
222       return endByte - startByte;
223     }
224
225   case _C_UNION_B:
226   case _C_STRUCT_B:
227     {
228       struct objc_struct_layout layout;
229       unsigned int size;
230
231       objc_layout_structure (type, &layout);
232       while (objc_layout_structure_next_member (&layout))
233         /* do nothing */ ;
234       objc_layout_finish_structure (&layout, &size, NULL);
235
236       return size;
237     }
238
239   default:
240     {
241       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
242       return 0;
243     }
244   }
245 }
246
247
248 /*
249   Return the alignment of an object specified by type
250 */
251
252 int
253 objc_alignof_type (const char *type)
254 {
255   /* Skip the variable name if any */
256   if (*type == '"')
257     {
258       for (type++; *type++ != '"';)
259         /* do nothing */;
260     }
261   switch (*type) {
262   case _C_BOOL:
263     return __alignof__ (_Bool);
264     break;
265
266   case _C_ID:
267     return __alignof__ (id);
268     break;
269
270   case _C_CLASS:
271     return __alignof__ (Class);
272     break;
273
274   case _C_SEL:
275     return __alignof__ (SEL);
276     break;
277
278   case _C_CHR:
279     return __alignof__ (char);
280     break;
281
282   case _C_UCHR:
283     return __alignof__ (unsigned char);
284     break;
285
286   case _C_SHT:
287     return __alignof__ (short);
288     break;
289
290   case _C_USHT:
291     return __alignof__ (unsigned short);
292     break;
293
294   case _C_INT:
295     return __alignof__ (int);
296     break;
297
298   case _C_UINT:
299     return __alignof__ (unsigned int);
300     break;
301
302   case _C_LNG:
303     return __alignof__ (long);
304     break;
305
306   case _C_ULNG:
307     return __alignof__ (unsigned long);
308     break;
309
310   case _C_LNG_LNG:
311     return __alignof__ (long long);
312     break;
313
314   case _C_ULNG_LNG:
315     return __alignof__ (unsigned long long);
316     break;
317
318   case _C_FLT:
319     return __alignof__ (float);
320     break;
321
322   case _C_DBL:
323     return __alignof__ (double);
324     break;
325
326   case _C_PTR:
327   case _C_ATOM:
328   case _C_CHARPTR:
329     return __alignof__ (char *);
330     break;
331
332   case _C_ARY_B:
333     while (isdigit ((unsigned char)*++type))
334       /* do nothing */;
335     return objc_alignof_type (type);
336
337   case _C_STRUCT_B:
338   case _C_UNION_B:
339     {
340       struct objc_struct_layout layout;
341       unsigned int align;
342
343       objc_layout_structure (type, &layout);
344       while (objc_layout_structure_next_member (&layout))
345         /* do nothing */;
346       objc_layout_finish_structure (&layout, NULL, &align);
347
348       return align;
349     }
350
351   default:
352     {
353       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
354       return 0;
355     }
356   }
357 }
358
359 /*
360   The aligned size if the size rounded up to the nearest alignment.
361 */
362
363 int
364 objc_aligned_size (const char *type)
365 {
366   int size, align;
367
368   /* Skip the variable name */
369   if (*type == '"')
370     {
371       for (type++; *type++ != '"';)
372         /* do nothing */;
373     }
374
375   size = objc_sizeof_type (type);
376   align = objc_alignof_type (type);
377
378   return ROUND (size, align);
379 }
380
381 /*
382   The size rounded up to the nearest integral of the wordsize, taken
383   to be the size of a void *.
384 */
385
386 int
387 objc_promoted_size (const char *type)
388 {
389   int size, wordsize;
390
391   /* Skip the variable name */
392   if (*type == '"')
393     {
394       for (type++; *type++ != '"';)
395         /* do nothing */;
396     }
397
398   size = objc_sizeof_type (type);
399   wordsize = sizeof (void *);
400
401   return ROUND (size, wordsize);
402 }
403
404 /*
405   Skip type qualifiers.  These may eventually precede typespecs
406   occurring in method prototype encodings.
407 */
408
409 inline const char *
410 objc_skip_type_qualifiers (const char *type)
411 {
412   while (*type == _C_CONST
413          || *type == _C_IN
414          || *type == _C_INOUT
415          || *type == _C_OUT
416          || *type == _C_BYCOPY
417          || *type == _C_BYREF
418          || *type == _C_ONEWAY
419          || *type == _C_GCINVISIBLE)
420     {
421       type += 1;
422     }
423   return type;
424 }
425
426
427 /*
428   Skip one typespec element.  If the typespec is prepended by type
429   qualifiers, these are skipped as well.
430 */
431
432 const char *
433 objc_skip_typespec (const char *type)
434 {
435   /* Skip the variable name if any */
436   if (*type == '"')
437     {
438       for (type++; *type++ != '"';)
439         /* do nothing */;
440     }
441
442   type = objc_skip_type_qualifiers (type);
443
444   switch (*type) {
445
446   case _C_ID:
447     /* An id may be annotated by the actual type if it is known
448        with the @"ClassName" syntax */
449
450     if (*++type != '"')
451       return type;
452     else
453       {
454         while (*++type != '"')
455           /* do nothing */;
456         return type + 1;
457       }
458
459     /* The following are one character type codes */
460   case _C_CLASS:
461   case _C_SEL:
462   case _C_CHR:
463   case _C_UCHR:
464   case _C_CHARPTR:
465   case _C_ATOM:
466   case _C_SHT:
467   case _C_USHT:
468   case _C_INT:
469   case _C_UINT:
470   case _C_LNG:
471   case _C_BOOL:
472   case _C_ULNG:
473   case _C_LNG_LNG:
474   case _C_ULNG_LNG:
475   case _C_FLT:
476   case _C_DBL:
477   case _C_VOID:
478   case _C_UNDEF:
479     return ++type;
480     break;
481
482   case _C_ARY_B:
483     /* skip digits, typespec and closing ']' */
484
485     while (isdigit ((unsigned char)*++type))
486       ;
487     type = objc_skip_typespec (type);
488     if (*type == _C_ARY_E)
489       return ++type;
490     else
491       {
492         objc_error (nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
493         return 0;
494       }
495
496   case _C_BFLD:
497     /* The new encoding of bitfields is: b 'position' 'type' 'size' */
498     while (isdigit ((unsigned char)*++type))
499       ; /* skip position */
500     while (isdigit ((unsigned char)*++type))
501       ; /* skip type and size */
502     return type;
503
504   case _C_STRUCT_B:
505     /* skip name, and elements until closing '}'  */
506
507     while (*type != _C_STRUCT_E && *type++ != '=')
508       ;
509     while (*type != _C_STRUCT_E)
510       {
511         type = objc_skip_typespec (type);
512       }
513     return ++type;
514
515   case _C_UNION_B:
516     /* skip name, and elements until closing ')'  */
517
518     while (*type != _C_UNION_E && *type++ != '=')
519       ;
520     while (*type != _C_UNION_E)
521       {
522         type = objc_skip_typespec (type);
523       }
524     return ++type;
525
526   case _C_PTR:
527     /* Just skip the following typespec */
528
529     return objc_skip_typespec (++type);
530
531   default:
532     {
533       objc_error (nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
534       return 0;
535     }
536   }
537 }
538
539 /*
540   Skip an offset as part of a method encoding.  This is prepended by a
541   '+' if the argument is passed in registers.
542 */
543 inline const char *
544 objc_skip_offset (const char *type)
545 {
546   if (*type == '+')
547     type++;
548   while (isdigit ((unsigned char) *++type))
549     ;
550   return type;
551 }
552
553 /*
554   Skip an argument specification of a method encoding.
555 */
556 const char *
557 objc_skip_argspec (const char *type)
558 {
559   type = objc_skip_typespec (type);
560   type = objc_skip_offset (type);
561   return type;
562 }
563
564 /*
565   Return the number of arguments that the method MTH expects.
566   Note that all methods need two implicit arguments `self' and
567   `_cmd'.
568 */
569 int
570 method_get_number_of_arguments (struct objc_method *mth)
571 {
572   int i = 0;
573   const char *type = mth->method_types;
574   while (*type)
575     {
576       type = objc_skip_argspec (type);
577       i += 1;
578     }
579   return i - 1;
580 }
581
582 /*
583   Return the size of the argument block needed on the stack to invoke
584   the method MTH.  This may be zero, if all arguments are passed in
585   registers.
586 */
587
588 int
589 method_get_sizeof_arguments (struct objc_method *mth)
590 {
591   const char *type = objc_skip_typespec (mth->method_types);
592   return atoi (type);
593 }
594
595 /*
596   Return a pointer to the next argument of ARGFRAME.  type points to
597   the last argument.  Typical use of this look like:
598
599   {
600     char *datum, *type;
601     for (datum = method_get_first_argument (method, argframe, &type);
602          datum; datum = method_get_next_argument (argframe, &type))
603       {
604         unsigned flags = objc_get_type_qualifiers (type);
605         type = objc_skip_type_qualifiers (type);
606         if (*type != _C_PTR)
607           [portal encodeData: datum ofType: type];
608         else
609           {
610             if ((flags & _F_IN) == _F_IN)
611               [portal encodeData: *(char **) datum ofType: ++type];
612           }
613       }
614   }
615 */
616
617 char *
618 method_get_next_argument (arglist_t argframe, const char **type)
619 {
620   const char *t = objc_skip_argspec (*type);
621
622   if (*t == '\0')
623     return 0;
624
625   *type = t;
626   t = objc_skip_typespec (t);
627
628   if (*t == '+')
629     return argframe->arg_regs + atoi (++t);
630   else
631     return argframe->arg_ptr + atoi (t);
632 }
633
634 /*
635   Return a pointer to the value of the first argument of the method
636   described in M with the given argumentframe ARGFRAME.  The type
637   is returned in TYPE.  type must be passed to successive calls of
638   method_get_next_argument.
639 */
640 char *
641 method_get_first_argument (struct objc_method *m,
642                            arglist_t argframe,
643                            const char **type)
644 {
645   *type = m->method_types;
646   return method_get_next_argument (argframe, type);
647 }
648
649 /*
650    Return a pointer to the ARGth argument of the method
651    M from the frame ARGFRAME.  The type of the argument
652    is returned in the value-result argument TYPE
653 */
654
655 char *
656 method_get_nth_argument (struct objc_method *m,
657                          arglist_t argframe, int arg,
658                          const char **type)
659 {
660   const char *t = objc_skip_argspec (m->method_types);
661
662   if (arg > method_get_number_of_arguments (m))
663     return 0;
664
665   while (arg--)
666     t = objc_skip_argspec (t);
667
668   *type = t;
669   t = objc_skip_typespec (t);
670
671   if (*t == '+')
672     return argframe->arg_regs + atoi (++t);
673   else
674     return argframe->arg_ptr + atoi (t);
675 }
676
677 unsigned
678 objc_get_type_qualifiers (const char *type)
679 {
680   unsigned res = 0;
681   BOOL flag = YES;
682
683   while (flag)
684     switch (*type++)
685       {
686       case _C_CONST:    res |= _F_CONST; break;
687       case _C_IN:       res |= _F_IN; break;
688       case _C_INOUT:    res |= _F_INOUT; break;
689       case _C_OUT:      res |= _F_OUT; break;
690       case _C_BYCOPY:   res |= _F_BYCOPY; break;
691       case _C_BYREF:  res |= _F_BYREF; break;
692       case _C_ONEWAY:   res |= _F_ONEWAY; break;
693       case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
694       default: flag = NO;
695     }
696
697   return res;
698 }
699
700
701 /* The following three functions can be used to determine how a
702    structure is laid out by the compiler. For example:
703
704   struct objc_struct_layout layout;
705   int i;
706
707   objc_layout_structure (type, &layout);
708   while (objc_layout_structure_next_member (&layout))
709     {
710       int position, align;
711       const char *type;
712
713       objc_layout_structure_get_info (&layout, &position, &align, &type);
714       printf ("element %d has offset %d, alignment %d\n",
715               i++, position, align);
716     }
717
718   These functions are used by objc_sizeof_type and objc_alignof_type
719   functions to compute the size and alignment of structures. The
720   previous method of computing the size and alignment of a structure
721   was not working on some architectures, particulary on AIX, and in
722   the presence of bitfields inside the structure. */
723 void
724 objc_layout_structure (const char *type,
725                            struct objc_struct_layout *layout)
726 {
727   const char *ntype;
728
729   if (*type != _C_UNION_B && *type != _C_STRUCT_B)
730     {
731       objc_error (nil, OBJC_ERR_BAD_TYPE,
732                  "record (or union) type expected in objc_layout_structure, got %s\n",
733                  type);
734     }
735
736   type ++;
737   layout->original_type = type;
738
739   /* Skip "<name>=" if any. Avoid embedded structures and unions. */
740   ntype = type;
741   while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
742          && *ntype++ != '=')
743     /* do nothing */;
744
745   /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
746   if (*(ntype - 1) == '=')
747     type = ntype;
748
749   layout->type = type;
750   layout->prev_type = NULL;
751   layout->record_size = 0;
752   layout->record_align = BITS_PER_UNIT;
753
754   layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
755 }
756
757
758 BOOL
759 objc_layout_structure_next_member (struct objc_struct_layout *layout)
760 {
761   register int desired_align = 0;
762
763   /* The following are used only if the field is a bitfield */
764   register const char *bfld_type = 0;
765   register int bfld_type_size, bfld_type_align = 0, bfld_field_size = 0;
766
767   /* The current type without the type qualifiers */
768   const char *type;
769   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
770
771   /* Add the size of the previous field to the size of the record.  */
772   if (layout->prev_type)
773     {
774       type = objc_skip_type_qualifiers (layout->prev_type);
775       if (unionp)
776         layout->record_size = MAX (layout->record_size,
777                                    objc_sizeof_type (type) * BITS_PER_UNIT);
778
779       else if (*type != _C_BFLD)
780         layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
781       else {
782         /* Get the bitfield's type */
783         for (bfld_type = type + 1;
784              isdigit ((unsigned char)*bfld_type);
785              bfld_type++)
786           /* do nothing */;
787
788         bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
789         bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
790         bfld_field_size = atoi (objc_skip_typespec (bfld_type));
791         layout->record_size += bfld_field_size;
792       }
793     }
794
795   if ((unionp && *layout->type == _C_UNION_E)
796       || (!unionp && *layout->type == _C_STRUCT_E))
797     return NO;
798
799   /* Skip the variable name if any */
800   if (*layout->type == '"')
801     {
802       for (layout->type++; *layout->type++ != '"';)
803         /* do nothing */;
804     }
805
806   type = objc_skip_type_qualifiers (layout->type);
807
808   if (*type != _C_BFLD)
809     desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
810   else
811     {
812       desired_align = 1;
813       /* Skip the bitfield's offset */
814       for (bfld_type = type + 1;
815            isdigit ((unsigned char) *bfld_type);
816            bfld_type++)
817         /* do nothing */;
818
819       bfld_type_size = objc_sizeof_type (bfld_type) * BITS_PER_UNIT;
820       bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
821       bfld_field_size = atoi (objc_skip_typespec (bfld_type));
822     }
823
824 #ifdef BIGGEST_FIELD_ALIGNMENT
825   desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
826 #endif
827 #ifdef ADJUST_FIELD_ALIGN
828   desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
829 #endif
830
831   /* Record must have at least as much alignment as any field.
832      Otherwise, the alignment of the field within the record
833      is meaningless.  */
834 #ifndef PCC_BITFIELD_TYPE_MATTERS
835   layout->record_align = MAX (layout->record_align, desired_align);
836 #else   /* PCC_BITFIELD_TYPE_MATTERS */
837   if (*type == _C_BFLD)
838     {
839       /* For these machines, a zero-length field does not
840          affect the alignment of the structure as a whole.
841          It does, however, affect the alignment of the next field
842          within the structure.  */
843       if (bfld_field_size)
844         layout->record_align = MAX (layout->record_align, desired_align);
845       else
846         desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
847
848       /* A named bit field of declared type `int'
849          forces the entire structure to have `int' alignment.
850          Q1: How is encoded this thing and how to check for it?
851          Q2: How to determine maximum_field_alignment at runtime? */
852
853 /*        if (DECL_NAME (field) != 0) */
854       {
855         int type_align = bfld_type_align;
856 #if 0
857         if (maximum_field_alignment != 0)
858           type_align = MIN (type_align, maximum_field_alignment);
859         else if (DECL_PACKED (field))
860           type_align = MIN (type_align, BITS_PER_UNIT);
861 #endif
862
863         layout->record_align = MAX (layout->record_align, type_align);
864       }
865     }
866   else
867     layout->record_align = MAX (layout->record_align, desired_align);
868 #endif  /* PCC_BITFIELD_TYPE_MATTERS */
869
870   /* Does this field automatically have alignment it needs
871      by virtue of the fields that precede it and the record's
872      own alignment?  */
873
874   if (*type == _C_BFLD)
875     layout->record_size = atoi (type + 1);
876   else if (layout->record_size % desired_align != 0)
877     {
878       /* No, we need to skip space before this field.
879          Bump the cumulative size to multiple of field alignment.  */
880       layout->record_size = ROUND (layout->record_size, desired_align);
881     }
882
883   /* Jump to the next field in record. */
884
885   layout->prev_type = layout->type;
886   layout->type = objc_skip_typespec (layout->type);      /* skip component */
887
888   return YES;
889 }
890
891
892 void objc_layout_finish_structure (struct objc_struct_layout *layout,
893                                    unsigned int *size,
894                                    unsigned int *align)
895 {
896   BOOL unionp = layout->original_type[-1] == _C_UNION_B;
897   if (layout->type
898       && ((!unionp && *layout->type == _C_STRUCT_E)
899           || (unionp && *layout->type == _C_UNION_E)))
900     {
901       /* Work out the alignment of the record as one expression and store
902          in the record type.  Round it up to a multiple of the record's
903          alignment. */
904
905 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
906       layout->record_align = ROUND_TYPE_ALIGN (layout->original_type,
907                                                1,
908                                                layout->record_align);
909 #else
910       layout->record_align = MAX (1, layout->record_align);
911 #endif
912
913 #ifdef ROUND_TYPE_SIZE
914       layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
915                                              layout->record_size,
916                                              layout->record_align);
917 #else
918       /* Round the size up to be a multiple of the required alignment */
919       layout->record_size = ROUND (layout->record_size, layout->record_align);
920 #endif
921
922       layout->type = NULL;
923     }
924   if (size)
925     *size = layout->record_size / BITS_PER_UNIT;
926   if (align)
927     *align = layout->record_align / BITS_PER_UNIT;
928 }
929
930
931 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
932                                      unsigned int *offset,
933                                      unsigned int *align,
934                                      const char **type)
935 {
936   if (offset)
937     *offset = layout->record_size / BITS_PER_UNIT;
938   if (align)
939     *align = layout->record_align / BITS_PER_UNIT;
940   if (type)
941     *type = layout->prev_type;
942 }