1 /* Encoding of types for Objective C.
2 Copyright (C) 1993-2023 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
4 Bitfield support by Ovidiu Predescu
6 This file is part of GCC.
8 GCC 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 3, or (at your option)
13 GCC 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.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 /* FIXME: This file has no business including tm.h. */
29 /* FIXME: This file contains functions that will abort the entire
30 program if they fail. Is that really needed ? */
33 #include "objc-private/common.h"
34 #include "objc-private/error.h"
36 #include "coretypes.h"
38 #include "objc/runtime.h"
39 #include "objc-private/module-abi-8.h" /* For struct objc_method */
42 #include <string.h> /* For memcpy. */
46 ({ typeof (X) __x = (X), __y = (Y); \
47 (__x > __y ? __x : __y); })
51 ({ typeof (X) __x = (X), __y = (Y); \
52 (__x < __y ? __x : __y); })
56 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
57 __a * ((__v+__a - 1)/__a); })
60 /* Various hacks for objc_layout_record. These are used by the target
63 #define TREE_CODE(TYPE) *(TYPE)
64 #define TREE_TYPE(TREE) (TREE)
66 #define RECORD_TYPE _C_STRUCT_B
67 #define UNION_TYPE _C_UNION_B
68 #define QUAL_UNION_TYPE _C_UNION_B
69 #define ARRAY_TYPE _C_ARY_B
70 #define RECORD_OR_UNION_TYPE_P(TYPE) \
71 ((TREE_CODE (TYPE) == RECORD_TYPE) \
72 || (TREE_CODE (TYPE) == UNION_TYPE) \
73 || (TREE_CODE (TYPE) == QUAL_UNION_TYPE))
74 #define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
76 #define REAL_TYPE _C_DBL
78 #define VECTOR_TYPE _C_VECTOR
80 #define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \
81 while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
82 && *_field != _C_UNION_B && *_field++ != '=') \
86 #define DECL_MODE(TYPE) *(TYPE)
87 #define TYPE_MODE(TYPE) *(TYPE)
92 #define strip_array_types(TYPE) ({const char *_field = (TYPE); \
93 while (*_field == _C_ARY_B)\
95 while (isdigit ((unsigned char)*++_field))\
100 /* Some ports (eg ARM) allow the structure size boundary to be
101 selected at compile-time. We override the normal definition with
102 one that has a constant value for this compilation. */
103 #undef STRUCTURE_SIZE_BOUNDARY
104 #define STRUCTURE_SIZE_BOUNDARY (__CHAR_BIT__ * sizeof (struct{char a;}))
106 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
107 target_flags. Define a dummy entry here to so we don't die.
108 We have to rename it because target_flags may already have been
110 #define target_flags not_target_flags
111 static int __attribute__ ((__unused__
)) not_target_flags
= 0;
113 /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
114 Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */
115 #undef ALTIVEC_VECTOR_MODE
116 #define ALTIVEC_VECTOR_MODE(MODE) (0)
118 /* Replace TARGET_VSX, TARGET_ALTIVEC, and TARGET_64BIT with constants based on
119 the current switches, rather than looking in the options structure. */
122 #undef TARGET_ALTIVEC
132 #define TARGET_ALTIVEC 1
134 #define TARGET_ALTIVEC 0
138 #define TARGET_64BIT 1
140 #define TARGET_64BIT 0
144 /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
145 in their alignment macros. Currently[4.5/6], rs6000.h points this
146 to a static variable, initialized by target overrides. This is reset
147 in linux64.h but not in darwin64.h. The macro is not used by *86*. */
151 # undef TARGET_ALIGN_NATURAL
152 # define TARGET_ALIGN_NATURAL 1
154 /* On Darwin32, we need to recurse until we find the starting stuct type. */
156 _darwin_rs6000_special_round_type_align (const char *struc
, int comp
, int spec
)
158 const char *_stp
, *_fields
= TYPE_FIELDS (struc
);
160 return MAX (comp
, spec
);
161 _stp
= strip_array_types (_fields
);
162 if (TYPE_MODE(_stp
) == _C_COMPLEX
)
164 switch (TYPE_MODE(_stp
))
168 return MAX (MAX (comp
, spec
), objc_alignof_type (_stp
) * __CHAR_BIT__
);
173 return MAX (MAX (comp
, spec
), 64);
177 return MAX (comp
, spec
);
182 /* See comment below. */
183 #define darwin_rs6000_special_round_type_align(S,C,S2) \
184 (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
187 /* FIXME: while this file has no business including tm.h, this
188 definitely has no business defining this macro but it
189 is only way around without really rewritting this file,
190 should look after the branch of 3.4 to fix this. */
191 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
192 ({ const char *_fields = TYPE_FIELDS (STRUCT); \
194 && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
195 ? MAX (MAX (COMPUTED, SPECIFIED), 64) \
196 : MAX (COMPUTED, SPECIFIED));})
198 #define rs6000_special_adjust_field_align_p(FIELD, COMPUTED) 0
200 /* Skip a variable name, enclosed in quotes ("). */
203 objc_skip_variable_name (const char *type
)
205 /* Skip the variable name if any. */
208 /* FIXME: How do we know we won't read beyond the end of the
209 string. Here and in the rest of the file! */
212 /* Skip to the next '"'. */
223 objc_sizeof_type (const char *type
)
225 type
= objc_skip_variable_name (type
);
229 return sizeof (_Bool
);
237 return sizeof (Class
);
245 return sizeof (char);
249 return sizeof (unsigned char);
253 return sizeof (short);
257 return sizeof (unsigned short);
265 return sizeof (unsigned int);
269 return sizeof (long);
273 return sizeof (unsigned long);
277 return sizeof (long long);
281 return sizeof (unsigned long long);
285 return sizeof (float);
289 return sizeof (double);
293 return sizeof (long double);
297 return sizeof (void);
303 return sizeof (char *);
308 int len
= atoi (type
+ 1);
309 while (isdigit ((unsigned char)*++type
))
311 return len
* objc_aligned_size (type
);
322 /* The size in bytes is the following number. */
323 int size
= atoi (type
);
330 /* The GNU encoding of bitfields is: b 'position' 'type'
333 int startByte
, endByte
;
335 position
= atoi (type
+ 1);
336 while (isdigit ((unsigned char)*++type
))
338 size
= atoi (type
+ 1);
340 startByte
= position
/ __CHAR_BIT__
;
341 endByte
= (position
+ size
) / __CHAR_BIT__
;
342 return endByte
- startByte
;
348 struct objc_struct_layout layout
;
351 objc_layout_structure (type
, &layout
);
352 while (objc_layout_structure_next_member (&layout
))
354 objc_layout_finish_structure (&layout
, &size
, NULL
);
361 type
++; /* Skip after the 'j'. */
365 return sizeof (_Complex
char);
369 return sizeof (_Complex
unsigned char);
373 return sizeof (_Complex
short);
377 return sizeof (_Complex
unsigned short);
381 return sizeof (_Complex
int);
385 return sizeof (_Complex
unsigned int);
389 return sizeof (_Complex
long);
393 return sizeof (_Complex
unsigned long);
397 return sizeof (_Complex
long long);
401 return sizeof (_Complex
unsigned long long);
405 return sizeof (_Complex
float);
409 return sizeof (_Complex
double);
413 return sizeof (_Complex
long double);
418 /* FIXME: Is this so bad that we have to abort the
419 entire program ? (it applies to all the other
420 _objc_abort calls in this file).
422 _objc_abort ("unknown complex type %s\n", type
);
430 _objc_abort ("unknown type %s\n", type
);
437 objc_alignof_type (const char *type
)
439 type
= objc_skip_variable_name (type
);
443 return __alignof__ (_Bool
);
447 return __alignof__ (id
);
451 return __alignof__ (Class
);
455 return __alignof__ (SEL
);
459 return __alignof__ (char);
463 return __alignof__ (unsigned char);
467 return __alignof__ (short);
471 return __alignof__ (unsigned short);
475 return __alignof__ (int);
479 return __alignof__ (unsigned int);
483 return __alignof__ (long);
487 return __alignof__ (unsigned long);
491 return __alignof__ (long long);
495 return __alignof__ (unsigned long long);
499 return __alignof__ (float);
503 return __alignof__ (double);
507 return __alignof__ (long double);
513 return __alignof__ (char *);
517 while (isdigit ((unsigned char)*++type
))
519 return objc_alignof_type (type
);
529 while (isdigit ((unsigned char)*type
))
535 /* The alignment in bytes is the following number. */
541 struct objc_struct_layout layout
;
544 objc_layout_structure (type
, &layout
);
545 while (objc_layout_structure_next_member (&layout
))
547 objc_layout_finish_structure (&layout
, NULL
, &align
);
555 type
++; /* Skip after the 'j'. */
559 return __alignof__ (_Complex
char);
563 return __alignof__ (_Complex
unsigned char);
567 return __alignof__ (_Complex
short);
571 return __alignof__ (_Complex
unsigned short);
575 return __alignof__ (_Complex
int);
579 return __alignof__ (_Complex
unsigned int);
583 return __alignof__ (_Complex
long);
587 return __alignof__ (_Complex
unsigned long);
591 return __alignof__ (_Complex
long long);
595 return __alignof__ (_Complex
unsigned long long);
599 return __alignof__ (_Complex
float);
603 return __alignof__ (_Complex
double);
607 return __alignof__ (_Complex
long double);
612 _objc_abort ("unknown complex type %s\n", type
);
620 _objc_abort ("unknown type %s\n", type
);
627 objc_aligned_size (const char *type
)
631 type
= objc_skip_variable_name (type
);
632 size
= objc_sizeof_type (type
);
633 align
= objc_alignof_type (type
);
635 return ROUND (size
, align
);
639 objc_promoted_size (const char *type
)
643 type
= objc_skip_variable_name (type
);
644 size
= objc_sizeof_type (type
);
645 wordsize
= sizeof (void *);
647 return ROUND (size
, wordsize
);
652 objc_skip_type_qualifiers (const char *type
)
654 while (*type
== _C_CONST
658 || *type
== _C_BYCOPY
660 || *type
== _C_ONEWAY
661 || *type
== _C_GCINVISIBLE
)
670 objc_skip_typespec (const char *type
)
672 type
= objc_skip_variable_name (type
);
673 type
= objc_skip_type_qualifiers (type
);
678 /* An id may be annotated by the actual type if it is known
679 with the @"ClassName" syntax */
685 while (*++type
!= '"')
690 /* The following are one character type codes */
719 /* skip digits, typespec and closing ']' */
720 while (isdigit ((unsigned char)*++type
))
722 type
= objc_skip_typespec (type
);
723 if (*type
== _C_ARY_E
)
727 _objc_abort ("bad array type %s\n", type
);
736 /* Skip digits (size) */
737 while (isdigit ((unsigned char)*type
))
741 /* Skip digits (alignment) */
742 while (isdigit ((unsigned char)*type
))
745 type
= objc_skip_typespec (type
);
746 /* Skip closing ']'. */
747 if (*type
== _C_ARY_E
)
751 _objc_abort ("bad vector type %s\n", type
);
756 /* The GNU encoding of bitfields is: b 'position' 'type'
758 while (isdigit ((unsigned char)*++type
))
759 ; /* skip position */
760 while (isdigit ((unsigned char)*++type
))
761 ; /* skip type and size */
765 /* skip name, and elements until closing '}' */
767 while (*type
!= _C_STRUCT_E
&& *type
++ != '=')
769 while (*type
!= _C_STRUCT_E
)
771 type
= objc_skip_typespec (type
);
776 /* skip name, and elements until closing ')' */
778 while (*type
!= _C_UNION_E
&& *type
++ != '=')
780 while (*type
!= _C_UNION_E
)
782 type
= objc_skip_typespec (type
);
787 /* Just skip the following typespec */
789 return objc_skip_typespec (++type
);
793 _objc_abort ("unknown type %s\n", type
);
801 objc_skip_offset (const char *type
)
803 /* The offset is prepended by a '+' if the argument is passed in
804 registers. PS: The compiler stopped generating this '+' in
809 /* Some people claim that on some platforms, where the stack grows
810 backwards, the compiler generates negative offsets (??). Skip a
811 '-' for such a negative offset. */
815 /* Skip the digits that represent the offset. */
816 while (isdigit ((unsigned char) *type
))
823 objc_skip_argspec (const char *type
)
825 type
= objc_skip_typespec (type
);
826 type
= objc_skip_offset (type
);
831 method_copyReturnType (struct objc_method
*method
)
838 size_t returnValueSize
;
840 /* Determine returnValueSize. */
842 /* Find the end of the first argument. We want to return the
843 first argument spec, plus 1 byte for the \0 at the end. */
844 const char *type
= method
->method_types
;
847 type
= objc_skip_argspec (type
);
848 returnValueSize
= type
- method
->method_types
+ 1;
851 /* Copy the first argument into returnValue. */
852 returnValue
= malloc (sizeof (char) * returnValueSize
);
853 memcpy (returnValue
, method
->method_types
, returnValueSize
);
854 returnValue
[returnValueSize
- 1] = '\0';
861 method_copyArgumentType (struct objc_method
* method
, unsigned int argumentNumber
)
868 const char *returnValueStart
;
869 size_t returnValueSize
;
871 /* Determine returnValueStart and returnValueSize. */
873 const char *type
= method
->method_types
;
875 /* Skip the first argument (return type). */
876 type
= objc_skip_argspec (type
);
878 /* Now keep skipping arguments until we get to
880 while (argumentNumber
> 0)
882 /* We are supposed to skip an argument, but the string is
883 finished. This means we were asked for a non-existing
888 type
= objc_skip_argspec (type
);
892 /* If the argument does not exist, return NULL. */
896 returnValueStart
= type
;
897 type
= objc_skip_argspec (type
);
898 returnValueSize
= type
- returnValueStart
+ 1;
901 /* Copy the argument into returnValue. */
902 returnValue
= malloc (sizeof (char) * returnValueSize
);
903 memcpy (returnValue
, returnValueStart
, returnValueSize
);
904 returnValue
[returnValueSize
- 1] = '\0';
910 void method_getReturnType (struct objc_method
* method
, char *returnValue
,
911 size_t returnValueSize
)
913 if (returnValue
== NULL
|| returnValueSize
== 0)
916 /* Zero the string; we'll then write the argument type at the
917 beginning of it, if needed. */
918 memset (returnValue
, 0, returnValueSize
);
924 size_t argumentTypeSize
;
926 /* Determine argumentTypeSize. */
928 /* Find the end of the first argument. We want to return the
929 first argument spec. */
930 const char *type
= method
->method_types
;
933 type
= objc_skip_argspec (type
);
934 argumentTypeSize
= type
- method
->method_types
;
935 if (argumentTypeSize
> returnValueSize
)
936 argumentTypeSize
= returnValueSize
;
938 /* Copy the argument at the beginning of the string. */
939 memcpy (returnValue
, method
->method_types
, argumentTypeSize
);
943 void method_getArgumentType (struct objc_method
* method
, unsigned int argumentNumber
,
944 char *returnValue
, size_t returnValueSize
)
946 if (returnValue
== NULL
|| returnValueSize
== 0)
949 /* Zero the string; we'll then write the argument type at the
950 beginning of it, if needed. */
951 memset (returnValue
, 0, returnValueSize
);
957 const char *returnValueStart
;
958 size_t argumentTypeSize
;
960 /* Determine returnValueStart and argumentTypeSize. */
962 const char *type
= method
->method_types
;
964 /* Skip the first argument (return type). */
965 type
= objc_skip_argspec (type
);
967 /* Now keep skipping arguments until we get to
969 while (argumentNumber
> 0)
971 /* We are supposed to skip an argument, but the string is
972 finished. This means we were asked for a non-existing
977 type
= objc_skip_argspec (type
);
981 /* If the argument does not exist, it's game over. */
985 returnValueStart
= type
;
986 type
= objc_skip_argspec (type
);
987 argumentTypeSize
= type
- returnValueStart
;
988 if (argumentTypeSize
> returnValueSize
)
989 argumentTypeSize
= returnValueSize
;
991 /* Copy the argument at the beginning of the string. */
992 memcpy (returnValue
, returnValueStart
, argumentTypeSize
);
997 method_getNumberOfArguments (struct objc_method
*method
)
1004 const char *type
= method
->method_types
;
1007 type
= objc_skip_argspec (type
);
1013 /* This could only happen if method_types is invalid; in
1014 that case, return 0. */
1019 /* Remove the return type. */
1026 objc_get_type_qualifiers (const char *type
)
1034 case _C_CONST
: res
|= _F_CONST
; break;
1035 case _C_IN
: res
|= _F_IN
; break;
1036 case _C_INOUT
: res
|= _F_INOUT
; break;
1037 case _C_OUT
: res
|= _F_OUT
; break;
1038 case _C_BYCOPY
: res
|= _F_BYCOPY
; break;
1039 case _C_BYREF
: res
|= _F_BYREF
; break;
1040 case _C_ONEWAY
: res
|= _F_ONEWAY
; break;
1041 case _C_GCINVISIBLE
: res
|= _F_GCINVISIBLE
; break;
1048 /* The following three functions can be used to determine how a
1049 structure is laid out by the compiler. For example:
1051 struct objc_struct_layout layout;
1054 objc_layout_structure (type, &layout);
1055 while (objc_layout_structure_next_member (&layout))
1057 int position, align;
1060 objc_layout_structure_get_info (&layout, &position, &align, &type);
1061 printf ("element %d has offset %d, alignment %d\n",
1062 i++, position, align);
1065 These functions are used by objc_sizeof_type and objc_alignof_type
1066 functions to compute the size and alignment of structures. The
1067 previous method of computing the size and alignment of a structure
1068 was not working on some architectures, particularly on AIX, and in
1069 the presence of bitfields inside the structure. */
1071 objc_layout_structure (const char *type
,
1072 struct objc_struct_layout
*layout
)
1076 if (*type
!= _C_UNION_B
&& *type
!= _C_STRUCT_B
)
1078 _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1083 layout
->original_type
= type
;
1085 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1087 while (*ntype
!= _C_STRUCT_E
&& *ntype
!= _C_STRUCT_B
&& *ntype
!= _C_UNION_B
1091 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1092 if (*(ntype
- 1) == '=')
1095 layout
->type
= type
;
1096 layout
->prev_type
= NULL
;
1097 layout
->record_size
= 0;
1098 layout
->record_align
= __CHAR_BIT__
;
1100 layout
->record_align
= MAX (layout
->record_align
, STRUCTURE_SIZE_BOUNDARY
);
1104 objc_layout_structure_next_member (struct objc_struct_layout
*layout
)
1106 register int desired_align
= 0;
1108 /* The following are used only if the field is a bitfield */
1109 register const char *bfld_type
= 0;
1110 register int bfld_type_align
= 0, bfld_field_size
= 0;
1112 /* The current type without the type qualifiers */
1114 BOOL unionp
= layout
->original_type
[-1] == _C_UNION_B
;
1116 /* Add the size of the previous field to the size of the record. */
1117 if (layout
->prev_type
)
1119 type
= objc_skip_type_qualifiers (layout
->prev_type
);
1121 layout
->record_size
= MAX (layout
->record_size
,
1122 objc_sizeof_type (type
) * __CHAR_BIT__
);
1124 else if (*type
!= _C_BFLD
)
1125 layout
->record_size
+= objc_sizeof_type (type
) * __CHAR_BIT__
;
1127 /* Get the bitfield's type */
1128 for (bfld_type
= type
+ 1;
1129 isdigit ((unsigned char)*bfld_type
);
1133 bfld_type_align
= objc_alignof_type (bfld_type
) * __CHAR_BIT__
;
1134 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
1135 layout
->record_size
+= bfld_field_size
;
1139 if ((unionp
&& *layout
->type
== _C_UNION_E
)
1140 || (!unionp
&& *layout
->type
== _C_STRUCT_E
))
1143 /* Skip the variable name if any */
1144 layout
->type
= objc_skip_variable_name (layout
->type
);
1145 type
= objc_skip_type_qualifiers (layout
->type
);
1147 if (*type
!= _C_BFLD
)
1148 desired_align
= objc_alignof_type (type
) * __CHAR_BIT__
;
1152 /* Skip the bitfield's offset */
1153 for (bfld_type
= type
+ 1;
1154 isdigit ((unsigned char) *bfld_type
);
1158 bfld_type_align
= objc_alignof_type (bfld_type
) * __CHAR_BIT__
;
1159 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
1162 /* The following won't work for vectors. */
1163 #ifdef BIGGEST_FIELD_ALIGNMENT
1164 desired_align
= MIN (desired_align
, BIGGEST_FIELD_ALIGNMENT
);
1166 #ifdef ADJUST_FIELD_ALIGN
1167 desired_align
= ADJUST_FIELD_ALIGN (type
, type
, desired_align
);
1170 /* Record must have at least as much alignment as any field.
1171 Otherwise, the alignment of the field within the record
1173 #ifndef HAVE_BITFIELD_TYPE_MATTERS
1174 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1175 #else /* PCC_BITFIELD_TYPE_MATTERS */
1176 if (*type
== _C_BFLD
)
1178 /* For these machines, a zero-length field does not
1179 affect the alignment of the structure as a whole.
1180 It does, however, affect the alignment of the next field
1181 within the structure. */
1182 if (bfld_field_size
)
1183 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1185 desired_align
= objc_alignof_type (bfld_type
) * __CHAR_BIT__
;
1187 /* A named bit field of declared type `int'
1188 forces the entire structure to have `int' alignment.
1189 Q1: How is encoded this thing and how to check for it?
1190 Q2: How to determine maximum_field_alignment at runtime? */
1192 /* if (DECL_NAME (field) != 0) */
1194 int type_align
= bfld_type_align
;
1196 if (maximum_field_alignment
!= 0)
1197 type_align
= MIN (type_align
, maximum_field_alignment
);
1198 else if (DECL_PACKED (field
))
1199 type_align
= MIN (type_align
, __CHAR_BIT__
);
1202 layout
->record_align
= MAX (layout
->record_align
, type_align
);
1206 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1207 #endif /* PCC_BITFIELD_TYPE_MATTERS */
1209 /* Does this field automatically have alignment it needs
1210 by virtue of the fields that precede it and the record's
1213 if (*type
== _C_BFLD
)
1214 layout
->record_size
= atoi (type
+ 1);
1215 else if (layout
->record_size
% desired_align
!= 0)
1217 /* No, we need to skip space before this field.
1218 Bump the cumulative size to multiple of field alignment. */
1219 layout
->record_size
= ROUND (layout
->record_size
, desired_align
);
1222 /* Jump to the next field in record. */
1224 layout
->prev_type
= layout
->type
;
1225 layout
->type
= objc_skip_typespec (layout
->type
); /* skip component */
1230 void objc_layout_finish_structure (struct objc_struct_layout
*layout
,
1232 unsigned int *align
)
1234 BOOL unionp
= layout
->original_type
[-1] == _C_UNION_B
;
1236 && ((!unionp
&& *layout
->type
== _C_STRUCT_E
)
1237 || (unionp
&& *layout
->type
== _C_UNION_E
)))
1239 /* Work out the alignment of the record as one expression and store
1240 in the record type. Round it up to a multiple of the record's
1242 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1243 layout
->record_align
= ROUND_TYPE_ALIGN (layout
->original_type
-1,
1245 layout
->record_align
);
1247 layout
->record_align
= MAX (1, layout
->record_align
);
1250 /* Round the size up to be a multiple of the required alignment */
1251 layout
->record_size
= ROUND (layout
->record_size
, layout
->record_align
);
1253 layout
->type
= NULL
;
1256 *size
= layout
->record_size
/ __CHAR_BIT__
;
1258 *align
= layout
->record_align
/ __CHAR_BIT__
;
1261 void objc_layout_structure_get_info (struct objc_struct_layout
*layout
,
1262 unsigned int *offset
,
1263 unsigned int *align
,
1267 *offset
= layout
->record_size
/ __CHAR_BIT__
;
1269 *align
= layout
->record_align
/ __CHAR_BIT__
;
1271 *type
= layout
->prev_type
;