1 /* Encoding of types for Objective C.
2 Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kresten Krab Thorup
5 Bitfield support by Ovidiu Predescu
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
28 /* FIXME: This file has no business including tm.h. */
30 /* FIXME: This file contains functions that will abort the entire
31 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
71 #define REAL_TYPE _C_DBL
73 #define VECTOR_TYPE _C_VECTOR
75 #define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \
76 while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
77 && *_field != _C_UNION_B && *_field++ != '=') \
81 #define DECL_MODE(TYPE) *(TYPE)
82 #define TYPE_MODE(TYPE) *(TYPE)
86 #define strip_array_types(TYPE) ({const char *_field = (TYPE); \
87 while (*_field == _C_ARY_B)\
89 while (isdigit ((unsigned char)*++_field))\
94 /* Some ports (eg ARM) allow the structure size boundary to be
95 selected at compile-time. We override the normal definition with
96 one that has a constant value for this compilation. */
98 #define BITS_PER_UNIT 8
100 #undef STRUCTURE_SIZE_BOUNDARY
101 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
103 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
104 target_flags. Define a dummy entry here to so we don't die.
105 We have to rename it because target_flags may already have been
107 #define target_flags not_target_flags
108 static int __attribute__ ((__unused__
)) not_target_flags
= 0;
110 /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
111 Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */
112 #undef ALTIVEC_VECTOR_MODE
113 #define ALTIVEC_VECTOR_MODE(MODE) (0)
115 /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
116 in their alignment macros. Currently[4.5/6], rs6000.h points this
117 to a static variable, initialized by target overrides. This is reset
118 in linux64.h but not in darwin64.h. The macro is not used by *86*. */
122 # undef TARGET_ALIGN_NATURAL
123 # define TARGET_ALIGN_NATURAL 1
126 /* On Darwin32, we need to recurse until we find the starting stuct type. */
128 _darwin_rs6000_special_round_type_align (const char *struc
, int comp
, int spec
)
130 const char *_stp
, *_fields
= TYPE_FIELDS (struc
);
132 return MAX (comp
, spec
);
133 _stp
= strip_array_types (_fields
);
134 if (TYPE_MODE(_stp
) == _C_COMPLEX
)
136 switch (TYPE_MODE(_stp
))
140 return MAX (MAX (comp
, spec
), objc_alignof_type (_stp
) * BITS_PER_UNIT
);
145 return MAX (MAX (comp
, spec
), 64);
149 return MAX (comp
, spec
);
154 /* See comment below. */
155 #define darwin_rs6000_special_round_type_align(S,C,S2) \
156 (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
159 /* FIXME: while this file has no business including tm.h, this
160 definitely has no business defining this macro but it
161 is only way around without really rewritting this file,
162 should look after the branch of 3.4 to fix this. */
163 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
164 ({ const char *_fields = TYPE_FIELDS (STRUCT); \
166 && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
167 ? MAX (MAX (COMPUTED, SPECIFIED), 64) \
168 : MAX (COMPUTED, SPECIFIED));})
171 /* Skip a variable name, enclosed in quotes ("). */
174 objc_skip_variable_name (const char *type
)
176 /* Skip the variable name if any. */
179 /* FIXME: How do we know we won't read beyond the end of the
180 string. Here and in the rest of the file! */
183 /* Skip to the next '"'. */
194 objc_sizeof_type (const char *type
)
196 type
= objc_skip_variable_name (type
);
200 return sizeof (_Bool
);
208 return sizeof (Class
);
216 return sizeof (char);
220 return sizeof (unsigned char);
224 return sizeof (short);
228 return sizeof (unsigned short);
236 return sizeof (unsigned int);
240 return sizeof (long);
244 return sizeof (unsigned long);
248 return sizeof (long long);
252 return sizeof (unsigned long long);
256 return sizeof (float);
260 return sizeof (double);
264 return sizeof (long double);
268 return sizeof (void);
274 return sizeof (char *);
279 int len
= atoi (type
+ 1);
280 while (isdigit ((unsigned char)*++type
))
282 return len
* objc_aligned_size (type
);
293 /* The size in bytes is the following number. */
294 int size
= atoi (type
);
301 /* The GNU encoding of bitfields is: b 'position' 'type'
304 int startByte
, endByte
;
306 position
= atoi (type
+ 1);
307 while (isdigit ((unsigned char)*++type
))
309 size
= atoi (type
+ 1);
311 startByte
= position
/ BITS_PER_UNIT
;
312 endByte
= (position
+ size
) / BITS_PER_UNIT
;
313 return endByte
- startByte
;
319 struct objc_struct_layout layout
;
322 objc_layout_structure (type
, &layout
);
323 while (objc_layout_structure_next_member (&layout
))
325 objc_layout_finish_structure (&layout
, &size
, NULL
);
332 type
++; /* Skip after the 'j'. */
336 return sizeof (_Complex
char);
340 return sizeof (_Complex
unsigned char);
344 return sizeof (_Complex
short);
348 return sizeof (_Complex
unsigned short);
352 return sizeof (_Complex
int);
356 return sizeof (_Complex
unsigned int);
360 return sizeof (_Complex
long);
364 return sizeof (_Complex
unsigned long);
368 return sizeof (_Complex
long long);
372 return sizeof (_Complex
unsigned long long);
376 return sizeof (_Complex
float);
380 return sizeof (_Complex
double);
384 return sizeof (_Complex
long double);
389 /* FIXME: Is this so bad that we have to abort the
390 entire program ? (it applies to all the other
391 _objc_abort calls in this file).
393 _objc_abort ("unknown complex type %s\n", type
);
401 _objc_abort ("unknown type %s\n", type
);
408 objc_alignof_type (const char *type
)
410 type
= objc_skip_variable_name (type
);
414 return __alignof__ (_Bool
);
418 return __alignof__ (id
);
422 return __alignof__ (Class
);
426 return __alignof__ (SEL
);
430 return __alignof__ (char);
434 return __alignof__ (unsigned char);
438 return __alignof__ (short);
442 return __alignof__ (unsigned short);
446 return __alignof__ (int);
450 return __alignof__ (unsigned int);
454 return __alignof__ (long);
458 return __alignof__ (unsigned long);
462 return __alignof__ (long long);
466 return __alignof__ (unsigned long long);
470 return __alignof__ (float);
474 return __alignof__ (double);
478 return __alignof__ (long double);
484 return __alignof__ (char *);
488 while (isdigit ((unsigned char)*++type
))
490 return objc_alignof_type (type
);
500 while (isdigit ((unsigned char)*type
))
506 /* The alignment in bytes is the following number. */
512 struct objc_struct_layout layout
;
515 objc_layout_structure (type
, &layout
);
516 while (objc_layout_structure_next_member (&layout
))
518 objc_layout_finish_structure (&layout
, NULL
, &align
);
526 type
++; /* Skip after the 'j'. */
530 return __alignof__ (_Complex
char);
534 return __alignof__ (_Complex
unsigned char);
538 return __alignof__ (_Complex
short);
542 return __alignof__ (_Complex
unsigned short);
546 return __alignof__ (_Complex
int);
550 return __alignof__ (_Complex
unsigned int);
554 return __alignof__ (_Complex
long);
558 return __alignof__ (_Complex
unsigned long);
562 return __alignof__ (_Complex
long long);
566 return __alignof__ (_Complex
unsigned long long);
570 return __alignof__ (_Complex
float);
574 return __alignof__ (_Complex
double);
578 return __alignof__ (_Complex
long double);
583 _objc_abort ("unknown complex type %s\n", type
);
591 _objc_abort ("unknown type %s\n", type
);
598 objc_aligned_size (const char *type
)
602 type
= objc_skip_variable_name (type
);
603 size
= objc_sizeof_type (type
);
604 align
= objc_alignof_type (type
);
606 return ROUND (size
, align
);
610 objc_promoted_size (const char *type
)
614 type
= objc_skip_variable_name (type
);
615 size
= objc_sizeof_type (type
);
616 wordsize
= sizeof (void *);
618 return ROUND (size
, wordsize
);
623 objc_skip_type_qualifiers (const char *type
)
625 while (*type
== _C_CONST
629 || *type
== _C_BYCOPY
631 || *type
== _C_ONEWAY
632 || *type
== _C_GCINVISIBLE
)
641 objc_skip_typespec (const char *type
)
643 type
= objc_skip_variable_name (type
);
644 type
= objc_skip_type_qualifiers (type
);
649 /* An id may be annotated by the actual type if it is known
650 with the @"ClassName" syntax */
656 while (*++type
!= '"')
661 /* The following are one character type codes */
690 /* skip digits, typespec and closing ']' */
691 while (isdigit ((unsigned char)*++type
))
693 type
= objc_skip_typespec (type
);
694 if (*type
== _C_ARY_E
)
698 _objc_abort ("bad array type %s\n", type
);
707 /* Skip digits (size) */
708 while (isdigit ((unsigned char)*type
))
712 /* Skip digits (alignment) */
713 while (isdigit ((unsigned char)*type
))
716 type
= objc_skip_typespec (type
);
717 /* Skip closing ']'. */
718 if (*type
== _C_ARY_E
)
722 _objc_abort ("bad vector type %s\n", type
);
727 /* The GNU encoding of bitfields is: b 'position' 'type'
729 while (isdigit ((unsigned char)*++type
))
730 ; /* skip position */
731 while (isdigit ((unsigned char)*++type
))
732 ; /* skip type and size */
736 /* skip name, and elements until closing '}' */
738 while (*type
!= _C_STRUCT_E
&& *type
++ != '=')
740 while (*type
!= _C_STRUCT_E
)
742 type
= objc_skip_typespec (type
);
747 /* skip name, and elements until closing ')' */
749 while (*type
!= _C_UNION_E
&& *type
++ != '=')
751 while (*type
!= _C_UNION_E
)
753 type
= objc_skip_typespec (type
);
758 /* Just skip the following typespec */
760 return objc_skip_typespec (++type
);
764 _objc_abort ("unknown type %s\n", type
);
772 objc_skip_offset (const char *type
)
774 /* The offset is prepended by a '+' if the argument is passed in
775 registers. PS: The compiler stopped generating this '+' in
780 /* Some people claim that on some platforms, where the stack grows
781 backwards, the compiler generates negative offsets (??). Skip a
782 '-' for such a negative offset. */
786 /* Skip the digits that represent the offset. */
787 while (isdigit ((unsigned char) *type
))
794 objc_skip_argspec (const char *type
)
796 type
= objc_skip_typespec (type
);
797 type
= objc_skip_offset (type
);
802 method_copyReturnType (struct objc_method
*method
)
809 size_t returnValueSize
;
811 /* Determine returnValueSize. */
813 /* Find the end of the first argument. We want to return the
814 first argument spec, plus 1 byte for the \0 at the end. */
815 const char *type
= method
->method_types
;
818 type
= objc_skip_argspec (type
);
819 returnValueSize
= type
- method
->method_types
+ 1;
822 /* Copy the first argument into returnValue. */
823 returnValue
= malloc (sizeof (char) * returnValueSize
);
824 memcpy (returnValue
, method
->method_types
, returnValueSize
);
825 returnValue
[returnValueSize
- 1] = '\0';
832 method_copyArgumentType (struct objc_method
* method
, unsigned int argumentNumber
)
839 const char *returnValueStart
;
840 size_t returnValueSize
;
842 /* Determine returnValueStart and returnValueSize. */
844 const char *type
= method
->method_types
;
846 /* Skip the first argument (return type). */
847 type
= objc_skip_argspec (type
);
849 /* Now keep skipping arguments until we get to
851 while (argumentNumber
> 0)
853 /* We are supposed to skip an argument, but the string is
854 finished. This means we were asked for a non-existing
859 type
= objc_skip_argspec (type
);
863 /* If the argument does not exist, return NULL. */
867 returnValueStart
= type
;
868 type
= objc_skip_argspec (type
);
869 returnValueSize
= type
- returnValueStart
+ 1;
872 /* Copy the argument into returnValue. */
873 returnValue
= malloc (sizeof (char) * returnValueSize
);
874 memcpy (returnValue
, returnValueStart
, returnValueSize
);
875 returnValue
[returnValueSize
- 1] = '\0';
881 void method_getReturnType (struct objc_method
* method
, char *returnValue
,
882 size_t returnValueSize
)
884 if (returnValue
== NULL
|| returnValueSize
== 0)
887 /* Zero the string; we'll then write the argument type at the
888 beginning of it, if needed. */
889 memset (returnValue
, 0, returnValueSize
);
895 size_t argumentTypeSize
;
897 /* Determine argumentTypeSize. */
899 /* Find the end of the first argument. We want to return the
900 first argument spec. */
901 const char *type
= method
->method_types
;
904 type
= objc_skip_argspec (type
);
905 argumentTypeSize
= type
- method
->method_types
;
906 if (argumentTypeSize
> returnValueSize
)
907 argumentTypeSize
= returnValueSize
;
909 /* Copy the argument at the beginning of the string. */
910 memcpy (returnValue
, method
->method_types
, argumentTypeSize
);
914 void method_getArgumentType (struct objc_method
* method
, unsigned int argumentNumber
,
915 char *returnValue
, size_t returnValueSize
)
917 if (returnValue
== NULL
|| returnValueSize
== 0)
920 /* Zero the string; we'll then write the argument type at the
921 beginning of it, if needed. */
922 memset (returnValue
, 0, returnValueSize
);
928 const char *returnValueStart
;
929 size_t argumentTypeSize
;
931 /* Determine returnValueStart and argumentTypeSize. */
933 const char *type
= method
->method_types
;
935 /* Skip the first argument (return type). */
936 type
= objc_skip_argspec (type
);
938 /* Now keep skipping arguments until we get to
940 while (argumentNumber
> 0)
942 /* We are supposed to skip an argument, but the string is
943 finished. This means we were asked for a non-existing
948 type
= objc_skip_argspec (type
);
952 /* If the argument does not exist, it's game over. */
956 returnValueStart
= type
;
957 type
= objc_skip_argspec (type
);
958 argumentTypeSize
= type
- returnValueStart
;
959 if (argumentTypeSize
> returnValueSize
)
960 argumentTypeSize
= returnValueSize
;
962 /* Copy the argument at the beginning of the string. */
963 memcpy (returnValue
, returnValueStart
, argumentTypeSize
);
968 method_getNumberOfArguments (struct objc_method
*method
)
975 const char *type
= method
->method_types
;
978 type
= objc_skip_argspec (type
);
984 /* This could only happen if method_types is invalid; in
985 that case, return 0. */
990 /* Remove the return type. */
997 method_get_number_of_arguments (struct objc_method
*mth
)
999 return method_getNumberOfArguments (mth
);
1002 /* Return the size of the argument block needed on the stack to invoke
1003 the method MTH. This may be zero, if all arguments are passed in
1006 method_get_sizeof_arguments (struct objc_method
*mth
)
1008 const char *type
= objc_skip_typespec (mth
->method_types
);
1013 Return a pointer to the next argument of ARGFRAME. type points to
1014 the last argument. Typical use of this look like:
1018 for (datum = method_get_first_argument (method, argframe, &type);
1019 datum; datum = method_get_next_argument (argframe, &type))
1021 unsigned flags = objc_get_type_qualifiers (type);
1022 type = objc_skip_type_qualifiers (type);
1023 if (*type != _C_PTR)
1024 [portal encodeData: datum ofType: type];
1027 if ((flags & _F_IN) == _F_IN)
1028 [portal encodeData: *(char **) datum ofType: ++type];
1034 method_get_next_argument (arglist_t argframe
, const char **type
)
1036 const char *t
= objc_skip_argspec (*type
);
1042 t
= objc_skip_typespec (t
);
1045 return argframe
->arg_regs
+ atoi (++t
);
1047 return argframe
->arg_ptr
+ atoi (t
);
1050 /* Return a pointer to the value of the first argument of the method
1051 described in M with the given argumentframe ARGFRAME. The type
1052 is returned in TYPE. type must be passed to successive calls of
1053 method_get_next_argument. */
1055 method_get_first_argument (struct objc_method
*m
,
1059 *type
= m
->method_types
;
1060 return method_get_next_argument (argframe
, type
);
1063 /* Return a pointer to the ARGth argument of the method
1064 M from the frame ARGFRAME. The type of the argument
1065 is returned in the value-result argument TYPE. */
1067 method_get_nth_argument (struct objc_method
*m
,
1068 arglist_t argframe
, int arg
,
1071 const char *t
= objc_skip_argspec (m
->method_types
);
1073 if (arg
> method_get_number_of_arguments (m
))
1077 t
= objc_skip_argspec (t
);
1080 t
= objc_skip_typespec (t
);
1083 return argframe
->arg_regs
+ atoi (++t
);
1085 return argframe
->arg_ptr
+ atoi (t
);
1089 objc_get_type_qualifiers (const char *type
)
1097 case _C_CONST
: res
|= _F_CONST
; break;
1098 case _C_IN
: res
|= _F_IN
; break;
1099 case _C_INOUT
: res
|= _F_INOUT
; break;
1100 case _C_OUT
: res
|= _F_OUT
; break;
1101 case _C_BYCOPY
: res
|= _F_BYCOPY
; break;
1102 case _C_BYREF
: res
|= _F_BYREF
; break;
1103 case _C_ONEWAY
: res
|= _F_ONEWAY
; break;
1104 case _C_GCINVISIBLE
: res
|= _F_GCINVISIBLE
; break;
1111 /* The following three functions can be used to determine how a
1112 structure is laid out by the compiler. For example:
1114 struct objc_struct_layout layout;
1117 objc_layout_structure (type, &layout);
1118 while (objc_layout_structure_next_member (&layout))
1120 int position, align;
1123 objc_layout_structure_get_info (&layout, &position, &align, &type);
1124 printf ("element %d has offset %d, alignment %d\n",
1125 i++, position, align);
1128 These functions are used by objc_sizeof_type and objc_alignof_type
1129 functions to compute the size and alignment of structures. The
1130 previous method of computing the size and alignment of a structure
1131 was not working on some architectures, particulary on AIX, and in
1132 the presence of bitfields inside the structure. */
1134 objc_layout_structure (const char *type
,
1135 struct objc_struct_layout
*layout
)
1139 if (*type
!= _C_UNION_B
&& *type
!= _C_STRUCT_B
)
1141 _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1146 layout
->original_type
= type
;
1148 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1150 while (*ntype
!= _C_STRUCT_E
&& *ntype
!= _C_STRUCT_B
&& *ntype
!= _C_UNION_B
1154 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1155 if (*(ntype
- 1) == '=')
1158 layout
->type
= type
;
1159 layout
->prev_type
= NULL
;
1160 layout
->record_size
= 0;
1161 layout
->record_align
= BITS_PER_UNIT
;
1163 layout
->record_align
= MAX (layout
->record_align
, STRUCTURE_SIZE_BOUNDARY
);
1167 objc_layout_structure_next_member (struct objc_struct_layout
*layout
)
1169 register int desired_align
= 0;
1171 /* The following are used only if the field is a bitfield */
1172 register const char *bfld_type
= 0;
1173 register int bfld_type_align
= 0, bfld_field_size
= 0;
1175 /* The current type without the type qualifiers */
1177 BOOL unionp
= layout
->original_type
[-1] == _C_UNION_B
;
1179 /* Add the size of the previous field to the size of the record. */
1180 if (layout
->prev_type
)
1182 type
= objc_skip_type_qualifiers (layout
->prev_type
);
1184 layout
->record_size
= MAX (layout
->record_size
,
1185 objc_sizeof_type (type
) * BITS_PER_UNIT
);
1187 else if (*type
!= _C_BFLD
)
1188 layout
->record_size
+= objc_sizeof_type (type
) * BITS_PER_UNIT
;
1190 /* Get the bitfield's type */
1191 for (bfld_type
= type
+ 1;
1192 isdigit ((unsigned char)*bfld_type
);
1196 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
1197 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
1198 layout
->record_size
+= bfld_field_size
;
1202 if ((unionp
&& *layout
->type
== _C_UNION_E
)
1203 || (!unionp
&& *layout
->type
== _C_STRUCT_E
))
1206 /* Skip the variable name if any */
1207 layout
->type
= objc_skip_variable_name (layout
->type
);
1208 type
= objc_skip_type_qualifiers (layout
->type
);
1210 if (*type
!= _C_BFLD
)
1211 desired_align
= objc_alignof_type (type
) * BITS_PER_UNIT
;
1215 /* Skip the bitfield's offset */
1216 for (bfld_type
= type
+ 1;
1217 isdigit ((unsigned char) *bfld_type
);
1221 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
1222 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
1225 /* The following won't work for vectors. */
1226 #ifdef BIGGEST_FIELD_ALIGNMENT
1227 desired_align
= MIN (desired_align
, BIGGEST_FIELD_ALIGNMENT
);
1229 #ifdef ADJUST_FIELD_ALIGN
1230 desired_align
= ADJUST_FIELD_ALIGN (type
, desired_align
);
1233 /* Record must have at least as much alignment as any field.
1234 Otherwise, the alignment of the field within the record
1236 #ifndef PCC_BITFIELD_TYPE_MATTERS
1237 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1238 #else /* PCC_BITFIELD_TYPE_MATTERS */
1239 if (*type
== _C_BFLD
)
1241 /* For these machines, a zero-length field does not
1242 affect the alignment of the structure as a whole.
1243 It does, however, affect the alignment of the next field
1244 within the structure. */
1245 if (bfld_field_size
)
1246 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1248 desired_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
1250 /* A named bit field of declared type `int'
1251 forces the entire structure to have `int' alignment.
1252 Q1: How is encoded this thing and how to check for it?
1253 Q2: How to determine maximum_field_alignment at runtime? */
1255 /* if (DECL_NAME (field) != 0) */
1257 int type_align
= bfld_type_align
;
1259 if (maximum_field_alignment
!= 0)
1260 type_align
= MIN (type_align
, maximum_field_alignment
);
1261 else if (DECL_PACKED (field
))
1262 type_align
= MIN (type_align
, BITS_PER_UNIT
);
1265 layout
->record_align
= MAX (layout
->record_align
, type_align
);
1269 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
1270 #endif /* PCC_BITFIELD_TYPE_MATTERS */
1272 /* Does this field automatically have alignment it needs
1273 by virtue of the fields that precede it and the record's
1276 if (*type
== _C_BFLD
)
1277 layout
->record_size
= atoi (type
+ 1);
1278 else if (layout
->record_size
% desired_align
!= 0)
1280 /* No, we need to skip space before this field.
1281 Bump the cumulative size to multiple of field alignment. */
1282 layout
->record_size
= ROUND (layout
->record_size
, desired_align
);
1285 /* Jump to the next field in record. */
1287 layout
->prev_type
= layout
->type
;
1288 layout
->type
= objc_skip_typespec (layout
->type
); /* skip component */
1293 void objc_layout_finish_structure (struct objc_struct_layout
*layout
,
1295 unsigned int *align
)
1297 BOOL unionp
= layout
->original_type
[-1] == _C_UNION_B
;
1299 && ((!unionp
&& *layout
->type
== _C_STRUCT_E
)
1300 || (unionp
&& *layout
->type
== _C_UNION_E
)))
1302 /* Work out the alignment of the record as one expression and store
1303 in the record type. Round it up to a multiple of the record's
1305 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1306 layout
->record_align
= ROUND_TYPE_ALIGN (layout
->original_type
-1,
1308 layout
->record_align
);
1310 layout
->record_align
= MAX (1, layout
->record_align
);
1313 #ifdef ROUND_TYPE_SIZE
1314 layout
->record_size
= ROUND_TYPE_SIZE (layout
->original_type
,
1315 layout
->record_size
,
1316 layout
->record_align
);
1318 /* Round the size up to be a multiple of the required alignment */
1319 layout
->record_size
= ROUND (layout
->record_size
, layout
->record_align
);
1322 layout
->type
= NULL
;
1325 *size
= layout
->record_size
/ BITS_PER_UNIT
;
1327 *align
= layout
->record_align
/ BITS_PER_UNIT
;
1330 void objc_layout_structure_get_info (struct objc_struct_layout
*layout
,
1331 unsigned int *offset
,
1332 unsigned int *align
,
1336 *offset
= layout
->record_size
/ BITS_PER_UNIT
;
1338 *align
= layout
->record_align
/ BITS_PER_UNIT
;
1340 *type
= layout
->prev_type
;