OSDN Git Service

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