OSDN Git Service

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