encoding.c (STRUCTURE_SIZE_BOUNDARY): Redefine in a way that determines the value...
[gcc.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 }