OSDN Git Service

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