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