OSDN Git Service

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