OSDN Git Service

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