OSDN Git Service

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