OSDN Git Service

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