OSDN Git Service

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