encoding.c revision 1.15 1 1.1 mrg /* Encoding of types for Objective C.
2 1.15 mrg Copyright (C) 1993-2024 Free Software Foundation, Inc.
3 1.1 mrg Contributed by Kresten Krab Thorup
4 1.1 mrg Bitfield support by Ovidiu Predescu
5 1.1 mrg
6 1.1 mrg This file is part of GCC.
7 1.1 mrg
8 1.1 mrg GCC is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
11 1.1 mrg any later version.
12 1.1 mrg
13 1.1 mrg GCC is distributed in the hope that it will be useful,
14 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 mrg GNU General Public License for more details.
17 1.1 mrg
18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
19 1.1 mrg permissions described in the GCC Runtime Library Exception, version
20 1.1 mrg 3.1, as published by the Free Software Foundation.
21 1.1 mrg
22 1.1 mrg You should have received a copy of the GNU General Public License and
23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 1.1 mrg <http://www.gnu.org/licenses/>. */
26 1.1 mrg
27 1.1 mrg /* FIXME: This file has no business including tm.h. */
28 1.1 mrg
29 1.3 mrg /* FIXME: This file contains functions that will abort the entire
30 1.3 mrg program if they fail. Is that really needed ? */
31 1.3 mrg
32 1.7 mrg #include "config.h"
33 1.3 mrg #include "objc-private/common.h"
34 1.3 mrg #include "objc-private/error.h"
35 1.1 mrg #include "tconfig.h"
36 1.1 mrg #include "coretypes.h"
37 1.1 mrg #include "tm.h"
38 1.3 mrg #include "objc/runtime.h"
39 1.3 mrg #include "objc-private/module-abi-8.h" /* For struct objc_method */
40 1.1 mrg #include <stdlib.h>
41 1.3 mrg #include <ctype.h>
42 1.3 mrg #include <string.h> /* For memcpy. */
43 1.1 mrg
44 1.1 mrg #undef MAX
45 1.1 mrg #define MAX(X, Y) \
46 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \
47 1.1 mrg (__x > __y ? __x : __y); })
48 1.1 mrg
49 1.1 mrg #undef MIN
50 1.1 mrg #define MIN(X, Y) \
51 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \
52 1.1 mrg (__x < __y ? __x : __y); })
53 1.1 mrg
54 1.1 mrg #undef ROUND
55 1.1 mrg #define ROUND(V, A) \
56 1.1 mrg ({ typeof (V) __v = (V); typeof (A) __a = (A); \
57 1.1 mrg __a * ((__v+__a - 1)/__a); })
58 1.1 mrg
59 1.1 mrg
60 1.1 mrg /* Various hacks for objc_layout_record. These are used by the target
61 1.1 mrg macros. */
62 1.1 mrg
63 1.1 mrg #define TREE_CODE(TYPE) *(TYPE)
64 1.1 mrg #define TREE_TYPE(TREE) (TREE)
65 1.1 mrg
66 1.1 mrg #define RECORD_TYPE _C_STRUCT_B
67 1.1 mrg #define UNION_TYPE _C_UNION_B
68 1.1 mrg #define QUAL_UNION_TYPE _C_UNION_B
69 1.1 mrg #define ARRAY_TYPE _C_ARY_B
70 1.15 mrg #define RECORD_OR_UNION_TYPE_P(TYPE) \
71 1.15 mrg ((TREE_CODE (TYPE) == RECORD_TYPE) \
72 1.15 mrg || (TREE_CODE (TYPE) == UNION_TYPE) \
73 1.15 mrg || (TREE_CODE (TYPE) == QUAL_UNION_TYPE))
74 1.15 mrg #define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
75 1.1 mrg
76 1.1 mrg #define REAL_TYPE _C_DBL
77 1.1 mrg
78 1.1 mrg #define VECTOR_TYPE _C_VECTOR
79 1.1 mrg
80 1.1 mrg #define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \
81 1.1 mrg while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
82 1.1 mrg && *_field != _C_UNION_B && *_field++ != '=') \
83 1.1 mrg /* do nothing */; \
84 1.1 mrg _field;})
85 1.1 mrg
86 1.1 mrg #define DECL_MODE(TYPE) *(TYPE)
87 1.1 mrg #define TYPE_MODE(TYPE) *(TYPE)
88 1.1 mrg
89 1.12 mrg #undef DFmode
90 1.1 mrg #define DFmode _C_DBL
91 1.1 mrg
92 1.1 mrg #define strip_array_types(TYPE) ({const char *_field = (TYPE); \
93 1.1 mrg while (*_field == _C_ARY_B)\
94 1.1 mrg {\
95 1.1 mrg while (isdigit ((unsigned char)*++_field))\
96 1.1 mrg ;\
97 1.1 mrg }\
98 1.1 mrg _field;})
99 1.1 mrg
100 1.1 mrg /* Some ports (eg ARM) allow the structure size boundary to be
101 1.1 mrg selected at compile-time. We override the normal definition with
102 1.1 mrg one that has a constant value for this compilation. */
103 1.1 mrg #undef STRUCTURE_SIZE_BOUNDARY
104 1.7 mrg #define STRUCTURE_SIZE_BOUNDARY (__CHAR_BIT__ * sizeof (struct{char a;}))
105 1.1 mrg
106 1.1 mrg /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
107 1.1 mrg target_flags. Define a dummy entry here to so we don't die.
108 1.1 mrg We have to rename it because target_flags may already have been
109 1.1 mrg declared extern. */
110 1.1 mrg #define target_flags not_target_flags
111 1.1 mrg static int __attribute__ ((__unused__)) not_target_flags = 0;
112 1.1 mrg
113 1.1 mrg /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
114 1.1 mrg Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */
115 1.1 mrg #undef ALTIVEC_VECTOR_MODE
116 1.1 mrg #define ALTIVEC_VECTOR_MODE(MODE) (0)
117 1.1 mrg
118 1.3 mrg /* Replace TARGET_VSX, TARGET_ALTIVEC, and TARGET_64BIT with constants based on
119 1.3 mrg the current switches, rather than looking in the options structure. */
120 1.3 mrg #ifdef _ARCH_PPC
121 1.3 mrg #undef TARGET_VSX
122 1.3 mrg #undef TARGET_ALTIVEC
123 1.3 mrg #undef TARGET_64BIT
124 1.3 mrg
125 1.3 mrg #ifdef __VSX__
126 1.3 mrg #define TARGET_VSX 1
127 1.3 mrg #else
128 1.3 mrg #define TARGET_VSX 0
129 1.3 mrg #endif
130 1.3 mrg
131 1.3 mrg #ifdef __ALTIVEC__
132 1.3 mrg #define TARGET_ALTIVEC 1
133 1.3 mrg #else
134 1.3 mrg #define TARGET_ALTIVEC 0
135 1.3 mrg #endif
136 1.3 mrg
137 1.3 mrg #ifdef _ARCH_PPC64
138 1.3 mrg #define TARGET_64BIT 1
139 1.3 mrg #else
140 1.3 mrg #define TARGET_64BIT 0
141 1.3 mrg #endif
142 1.3 mrg #endif
143 1.3 mrg
144 1.3 mrg /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
145 1.3 mrg in their alignment macros. Currently[4.5/6], rs6000.h points this
146 1.3 mrg to a static variable, initialized by target overrides. This is reset
147 1.3 mrg in linux64.h but not in darwin64.h. The macro is not used by *86*. */
148 1.3 mrg
149 1.3 mrg #if __MACH__
150 1.3 mrg # if __LP64__
151 1.3 mrg # undef TARGET_ALIGN_NATURAL
152 1.3 mrg # define TARGET_ALIGN_NATURAL 1
153 1.3 mrg # endif
154 1.3 mrg /* On Darwin32, we need to recurse until we find the starting stuct type. */
155 1.3 mrg static int
156 1.3 mrg _darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec)
157 1.3 mrg {
158 1.3 mrg const char *_stp , *_fields = TYPE_FIELDS (struc);
159 1.3 mrg if (!_fields)
160 1.3 mrg return MAX (comp, spec);
161 1.3 mrg _stp = strip_array_types (_fields);
162 1.3 mrg if (TYPE_MODE(_stp) == _C_COMPLEX)
163 1.3 mrg _stp++;
164 1.3 mrg switch (TYPE_MODE(_stp))
165 1.3 mrg {
166 1.3 mrg case RECORD_TYPE:
167 1.3 mrg case UNION_TYPE:
168 1.7 mrg return MAX (MAX (comp, spec), objc_alignof_type (_stp) * __CHAR_BIT__);
169 1.3 mrg break;
170 1.13 mrg case DFmode:
171 1.3 mrg case _C_LNG_LNG:
172 1.3 mrg case _C_ULNG_LNG:
173 1.3 mrg return MAX (MAX (comp, spec), 64);
174 1.3 mrg break;
175 1.3 mrg
176 1.3 mrg default:
177 1.3 mrg return MAX (comp, spec);
178 1.3 mrg break;
179 1.3 mrg }
180 1.3 mrg }
181 1.3 mrg
182 1.3 mrg /* See comment below. */
183 1.3 mrg #define darwin_rs6000_special_round_type_align(S,C,S2) \
184 1.3 mrg (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
185 1.3 mrg #endif
186 1.1 mrg
187 1.1 mrg /* FIXME: while this file has no business including tm.h, this
188 1.1 mrg definitely has no business defining this macro but it
189 1.1 mrg is only way around without really rewritting this file,
190 1.3 mrg should look after the branch of 3.4 to fix this. */
191 1.1 mrg #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
192 1.3 mrg ({ const char *_fields = TYPE_FIELDS (STRUCT); \
193 1.1 mrg ((_fields != 0 \
194 1.1 mrg && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
195 1.1 mrg ? MAX (MAX (COMPUTED, SPECIFIED), 64) \
196 1.1 mrg : MAX (COMPUTED, SPECIFIED));})
197 1.1 mrg
198 1.6 mrg #define rs6000_special_adjust_field_align_p(FIELD, COMPUTED) 0
199 1.1 mrg
200 1.3 mrg /* Skip a variable name, enclosed in quotes ("). */
201 1.3 mrg static inline
202 1.3 mrg const char *
203 1.3 mrg objc_skip_variable_name (const char *type)
204 1.1 mrg {
205 1.3 mrg /* Skip the variable name if any. */
206 1.1 mrg if (*type == '"')
207 1.1 mrg {
208 1.3 mrg /* FIXME: How do we know we won't read beyond the end of the
209 1.3 mrg string. Here and in the rest of the file! */
210 1.3 mrg /* Skip '"'. */
211 1.3 mrg type++;
212 1.3 mrg /* Skip to the next '"'. */
213 1.3 mrg while (*type != '"')
214 1.3 mrg type++;
215 1.3 mrg /* Skip '"'. */
216 1.3 mrg type++;
217 1.1 mrg }
218 1.1 mrg
219 1.3 mrg return type;
220 1.3 mrg }
221 1.3 mrg
222 1.3 mrg int
223 1.3 mrg objc_sizeof_type (const char *type)
224 1.3 mrg {
225 1.3 mrg type = objc_skip_variable_name (type);
226 1.3 mrg
227 1.1 mrg switch (*type) {
228 1.1 mrg case _C_BOOL:
229 1.1 mrg return sizeof (_Bool);
230 1.1 mrg break;
231 1.1 mrg
232 1.1 mrg case _C_ID:
233 1.1 mrg return sizeof (id);
234 1.1 mrg break;
235 1.1 mrg
236 1.1 mrg case _C_CLASS:
237 1.1 mrg return sizeof (Class);
238 1.1 mrg break;
239 1.1 mrg
240 1.1 mrg case _C_SEL:
241 1.1 mrg return sizeof (SEL);
242 1.1 mrg break;
243 1.1 mrg
244 1.1 mrg case _C_CHR:
245 1.1 mrg return sizeof (char);
246 1.1 mrg break;
247 1.1 mrg
248 1.1 mrg case _C_UCHR:
249 1.1 mrg return sizeof (unsigned char);
250 1.1 mrg break;
251 1.1 mrg
252 1.1 mrg case _C_SHT:
253 1.1 mrg return sizeof (short);
254 1.1 mrg break;
255 1.1 mrg
256 1.1 mrg case _C_USHT:
257 1.1 mrg return sizeof (unsigned short);
258 1.1 mrg break;
259 1.1 mrg
260 1.1 mrg case _C_INT:
261 1.1 mrg return sizeof (int);
262 1.1 mrg break;
263 1.1 mrg
264 1.1 mrg case _C_UINT:
265 1.1 mrg return sizeof (unsigned int);
266 1.1 mrg break;
267 1.1 mrg
268 1.1 mrg case _C_LNG:
269 1.1 mrg return sizeof (long);
270 1.1 mrg break;
271 1.1 mrg
272 1.1 mrg case _C_ULNG:
273 1.1 mrg return sizeof (unsigned long);
274 1.1 mrg break;
275 1.1 mrg
276 1.1 mrg case _C_LNG_LNG:
277 1.1 mrg return sizeof (long long);
278 1.1 mrg break;
279 1.1 mrg
280 1.1 mrg case _C_ULNG_LNG:
281 1.1 mrg return sizeof (unsigned long long);
282 1.1 mrg break;
283 1.1 mrg
284 1.1 mrg case _C_FLT:
285 1.1 mrg return sizeof (float);
286 1.1 mrg break;
287 1.1 mrg
288 1.1 mrg case _C_DBL:
289 1.1 mrg return sizeof (double);
290 1.1 mrg break;
291 1.1 mrg
292 1.3 mrg case _C_LNG_DBL:
293 1.3 mrg return sizeof (long double);
294 1.3 mrg break;
295 1.3 mrg
296 1.1 mrg case _C_VOID:
297 1.1 mrg return sizeof (void);
298 1.1 mrg break;
299 1.1 mrg
300 1.1 mrg case _C_PTR:
301 1.1 mrg case _C_ATOM:
302 1.1 mrg case _C_CHARPTR:
303 1.1 mrg return sizeof (char *);
304 1.1 mrg break;
305 1.1 mrg
306 1.1 mrg case _C_ARY_B:
307 1.1 mrg {
308 1.1 mrg int len = atoi (type + 1);
309 1.1 mrg while (isdigit ((unsigned char)*++type))
310 1.1 mrg ;
311 1.1 mrg return len * objc_aligned_size (type);
312 1.1 mrg }
313 1.1 mrg break;
314 1.1 mrg
315 1.3 mrg case _C_VECTOR:
316 1.3 mrg {
317 1.3 mrg /* Skip the '!'. */
318 1.3 mrg type++;
319 1.3 mrg /* Skip the '['. */
320 1.3 mrg type++;
321 1.3 mrg
322 1.3 mrg /* The size in bytes is the following number. */
323 1.3 mrg int size = atoi (type);
324 1.3 mrg return size;
325 1.3 mrg }
326 1.3 mrg break;
327 1.3 mrg
328 1.1 mrg case _C_BFLD:
329 1.1 mrg {
330 1.3 mrg /* The GNU encoding of bitfields is: b 'position' 'type'
331 1.3 mrg 'size'. */
332 1.1 mrg int position, size;
333 1.1 mrg int startByte, endByte;
334 1.1 mrg
335 1.1 mrg position = atoi (type + 1);
336 1.1 mrg while (isdigit ((unsigned char)*++type))
337 1.1 mrg ;
338 1.1 mrg size = atoi (type + 1);
339 1.1 mrg
340 1.7 mrg startByte = position / __CHAR_BIT__;
341 1.7 mrg endByte = (position + size) / __CHAR_BIT__;
342 1.1 mrg return endByte - startByte;
343 1.1 mrg }
344 1.1 mrg
345 1.1 mrg case _C_UNION_B:
346 1.1 mrg case _C_STRUCT_B:
347 1.1 mrg {
348 1.1 mrg struct objc_struct_layout layout;
349 1.1 mrg unsigned int size;
350 1.1 mrg
351 1.1 mrg objc_layout_structure (type, &layout);
352 1.1 mrg while (objc_layout_structure_next_member (&layout))
353 1.1 mrg /* do nothing */ ;
354 1.1 mrg objc_layout_finish_structure (&layout, &size, NULL);
355 1.1 mrg
356 1.1 mrg return size;
357 1.1 mrg }
358 1.1 mrg
359 1.1 mrg case _C_COMPLEX:
360 1.1 mrg {
361 1.1 mrg type++; /* Skip after the 'j'. */
362 1.1 mrg switch (*type)
363 1.1 mrg {
364 1.1 mrg case _C_CHR:
365 1.1 mrg return sizeof (_Complex char);
366 1.1 mrg break;
367 1.1 mrg
368 1.1 mrg case _C_UCHR:
369 1.1 mrg return sizeof (_Complex unsigned char);
370 1.1 mrg break;
371 1.1 mrg
372 1.1 mrg case _C_SHT:
373 1.1 mrg return sizeof (_Complex short);
374 1.1 mrg break;
375 1.1 mrg
376 1.1 mrg case _C_USHT:
377 1.1 mrg return sizeof (_Complex unsigned short);
378 1.1 mrg break;
379 1.1 mrg
380 1.1 mrg case _C_INT:
381 1.1 mrg return sizeof (_Complex int);
382 1.1 mrg break;
383 1.1 mrg
384 1.1 mrg case _C_UINT:
385 1.1 mrg return sizeof (_Complex unsigned int);
386 1.1 mrg break;
387 1.1 mrg
388 1.1 mrg case _C_LNG:
389 1.1 mrg return sizeof (_Complex long);
390 1.1 mrg break;
391 1.1 mrg
392 1.1 mrg case _C_ULNG:
393 1.1 mrg return sizeof (_Complex unsigned long);
394 1.1 mrg break;
395 1.1 mrg
396 1.1 mrg case _C_LNG_LNG:
397 1.1 mrg return sizeof (_Complex long long);
398 1.1 mrg break;
399 1.1 mrg
400 1.1 mrg case _C_ULNG_LNG:
401 1.1 mrg return sizeof (_Complex unsigned long long);
402 1.1 mrg break;
403 1.1 mrg
404 1.1 mrg case _C_FLT:
405 1.1 mrg return sizeof (_Complex float);
406 1.1 mrg break;
407 1.1 mrg
408 1.1 mrg case _C_DBL:
409 1.1 mrg return sizeof (_Complex double);
410 1.1 mrg break;
411 1.3 mrg
412 1.3 mrg case _C_LNG_DBL:
413 1.3 mrg return sizeof (_Complex long double);
414 1.3 mrg break;
415 1.1 mrg
416 1.1 mrg default:
417 1.1 mrg {
418 1.3 mrg /* FIXME: Is this so bad that we have to abort the
419 1.3 mrg entire program ? (it applies to all the other
420 1.3 mrg _objc_abort calls in this file).
421 1.3 mrg */
422 1.3 mrg _objc_abort ("unknown complex type %s\n", type);
423 1.1 mrg return 0;
424 1.1 mrg }
425 1.1 mrg }
426 1.1 mrg }
427 1.1 mrg
428 1.1 mrg default:
429 1.1 mrg {
430 1.3 mrg _objc_abort ("unknown type %s\n", type);
431 1.1 mrg return 0;
432 1.1 mrg }
433 1.1 mrg }
434 1.1 mrg }
435 1.1 mrg
436 1.1 mrg int
437 1.1 mrg objc_alignof_type (const char *type)
438 1.1 mrg {
439 1.3 mrg type = objc_skip_variable_name (type);
440 1.3 mrg
441 1.1 mrg switch (*type) {
442 1.1 mrg case _C_BOOL:
443 1.1 mrg return __alignof__ (_Bool);
444 1.1 mrg break;
445 1.1 mrg
446 1.1 mrg case _C_ID:
447 1.1 mrg return __alignof__ (id);
448 1.1 mrg break;
449 1.1 mrg
450 1.1 mrg case _C_CLASS:
451 1.1 mrg return __alignof__ (Class);
452 1.1 mrg break;
453 1.1 mrg
454 1.1 mrg case _C_SEL:
455 1.1 mrg return __alignof__ (SEL);
456 1.1 mrg break;
457 1.1 mrg
458 1.1 mrg case _C_CHR:
459 1.1 mrg return __alignof__ (char);
460 1.1 mrg break;
461 1.1 mrg
462 1.1 mrg case _C_UCHR:
463 1.1 mrg return __alignof__ (unsigned char);
464 1.1 mrg break;
465 1.1 mrg
466 1.1 mrg case _C_SHT:
467 1.1 mrg return __alignof__ (short);
468 1.1 mrg break;
469 1.1 mrg
470 1.1 mrg case _C_USHT:
471 1.1 mrg return __alignof__ (unsigned short);
472 1.1 mrg break;
473 1.1 mrg
474 1.1 mrg case _C_INT:
475 1.1 mrg return __alignof__ (int);
476 1.1 mrg break;
477 1.1 mrg
478 1.1 mrg case _C_UINT:
479 1.1 mrg return __alignof__ (unsigned int);
480 1.1 mrg break;
481 1.1 mrg
482 1.1 mrg case _C_LNG:
483 1.1 mrg return __alignof__ (long);
484 1.1 mrg break;
485 1.1 mrg
486 1.1 mrg case _C_ULNG:
487 1.1 mrg return __alignof__ (unsigned long);
488 1.1 mrg break;
489 1.1 mrg
490 1.1 mrg case _C_LNG_LNG:
491 1.1 mrg return __alignof__ (long long);
492 1.1 mrg break;
493 1.1 mrg
494 1.1 mrg case _C_ULNG_LNG:
495 1.1 mrg return __alignof__ (unsigned long long);
496 1.1 mrg break;
497 1.1 mrg
498 1.1 mrg case _C_FLT:
499 1.1 mrg return __alignof__ (float);
500 1.1 mrg break;
501 1.1 mrg
502 1.1 mrg case _C_DBL:
503 1.1 mrg return __alignof__ (double);
504 1.1 mrg break;
505 1.1 mrg
506 1.3 mrg case _C_LNG_DBL:
507 1.3 mrg return __alignof__ (long double);
508 1.3 mrg break;
509 1.3 mrg
510 1.1 mrg case _C_PTR:
511 1.1 mrg case _C_ATOM:
512 1.1 mrg case _C_CHARPTR:
513 1.1 mrg return __alignof__ (char *);
514 1.1 mrg break;
515 1.1 mrg
516 1.1 mrg case _C_ARY_B:
517 1.1 mrg while (isdigit ((unsigned char)*++type))
518 1.1 mrg /* do nothing */;
519 1.1 mrg return objc_alignof_type (type);
520 1.1 mrg
521 1.3 mrg case _C_VECTOR:
522 1.3 mrg {
523 1.3 mrg /* Skip the '!'. */
524 1.3 mrg type++;
525 1.3 mrg /* Skip the '['. */
526 1.3 mrg type++;
527 1.3 mrg
528 1.3 mrg /* Skip the size. */
529 1.3 mrg while (isdigit ((unsigned char)*type))
530 1.3 mrg type++;
531 1.3 mrg
532 1.3 mrg /* Skip the ','. */
533 1.3 mrg type++;
534 1.3 mrg
535 1.3 mrg /* The alignment in bytes is the following number. */
536 1.3 mrg return atoi (type);
537 1.3 mrg }
538 1.1 mrg case _C_STRUCT_B:
539 1.1 mrg case _C_UNION_B:
540 1.1 mrg {
541 1.1 mrg struct objc_struct_layout layout;
542 1.1 mrg unsigned int align;
543 1.1 mrg
544 1.1 mrg objc_layout_structure (type, &layout);
545 1.1 mrg while (objc_layout_structure_next_member (&layout))
546 1.1 mrg /* do nothing */;
547 1.1 mrg objc_layout_finish_structure (&layout, NULL, &align);
548 1.1 mrg
549 1.1 mrg return align;
550 1.1 mrg }
551 1.1 mrg
552 1.1 mrg
553 1.1 mrg case _C_COMPLEX:
554 1.1 mrg {
555 1.1 mrg type++; /* Skip after the 'j'. */
556 1.1 mrg switch (*type)
557 1.1 mrg {
558 1.1 mrg case _C_CHR:
559 1.1 mrg return __alignof__ (_Complex char);
560 1.1 mrg break;
561 1.1 mrg
562 1.1 mrg case _C_UCHR:
563 1.1 mrg return __alignof__ (_Complex unsigned char);
564 1.1 mrg break;
565 1.1 mrg
566 1.1 mrg case _C_SHT:
567 1.1 mrg return __alignof__ (_Complex short);
568 1.1 mrg break;
569 1.1 mrg
570 1.1 mrg case _C_USHT:
571 1.1 mrg return __alignof__ (_Complex unsigned short);
572 1.1 mrg break;
573 1.1 mrg
574 1.1 mrg case _C_INT:
575 1.1 mrg return __alignof__ (_Complex int);
576 1.1 mrg break;
577 1.1 mrg
578 1.1 mrg case _C_UINT:
579 1.1 mrg return __alignof__ (_Complex unsigned int);
580 1.1 mrg break;
581 1.1 mrg
582 1.1 mrg case _C_LNG:
583 1.1 mrg return __alignof__ (_Complex long);
584 1.1 mrg break;
585 1.1 mrg
586 1.1 mrg case _C_ULNG:
587 1.1 mrg return __alignof__ (_Complex unsigned long);
588 1.1 mrg break;
589 1.1 mrg
590 1.1 mrg case _C_LNG_LNG:
591 1.1 mrg return __alignof__ (_Complex long long);
592 1.1 mrg break;
593 1.1 mrg
594 1.1 mrg case _C_ULNG_LNG:
595 1.1 mrg return __alignof__ (_Complex unsigned long long);
596 1.1 mrg break;
597 1.1 mrg
598 1.1 mrg case _C_FLT:
599 1.1 mrg return __alignof__ (_Complex float);
600 1.1 mrg break;
601 1.1 mrg
602 1.1 mrg case _C_DBL:
603 1.1 mrg return __alignof__ (_Complex double);
604 1.1 mrg break;
605 1.3 mrg
606 1.3 mrg case _C_LNG_DBL:
607 1.3 mrg return __alignof__ (_Complex long double);
608 1.3 mrg break;
609 1.1 mrg
610 1.1 mrg default:
611 1.1 mrg {
612 1.3 mrg _objc_abort ("unknown complex type %s\n", type);
613 1.1 mrg return 0;
614 1.1 mrg }
615 1.1 mrg }
616 1.1 mrg }
617 1.1 mrg
618 1.1 mrg default:
619 1.1 mrg {
620 1.3 mrg _objc_abort ("unknown type %s\n", type);
621 1.1 mrg return 0;
622 1.1 mrg }
623 1.1 mrg }
624 1.1 mrg }
625 1.1 mrg
626 1.1 mrg int
627 1.1 mrg objc_aligned_size (const char *type)
628 1.1 mrg {
629 1.1 mrg int size, align;
630 1.1 mrg
631 1.3 mrg type = objc_skip_variable_name (type);
632 1.1 mrg size = objc_sizeof_type (type);
633 1.1 mrg align = objc_alignof_type (type);
634 1.1 mrg
635 1.1 mrg return ROUND (size, align);
636 1.1 mrg }
637 1.1 mrg
638 1.1 mrg int
639 1.1 mrg objc_promoted_size (const char *type)
640 1.1 mrg {
641 1.1 mrg int size, wordsize;
642 1.1 mrg
643 1.3 mrg type = objc_skip_variable_name (type);
644 1.1 mrg size = objc_sizeof_type (type);
645 1.1 mrg wordsize = sizeof (void *);
646 1.1 mrg
647 1.1 mrg return ROUND (size, wordsize);
648 1.1 mrg }
649 1.1 mrg
650 1.1 mrg /*
651 1.1 mrg Skip type qualifiers. These may eventually precede typespecs
652 1.1 mrg occurring in method prototype encodings.
653 1.1 mrg */
654 1.1 mrg
655 1.2 joerg const char *
656 1.1 mrg objc_skip_type_qualifiers (const char *type)
657 1.1 mrg {
658 1.1 mrg while (*type == _C_CONST
659 1.1 mrg || *type == _C_IN
660 1.1 mrg || *type == _C_INOUT
661 1.1 mrg || *type == _C_OUT
662 1.1 mrg || *type == _C_BYCOPY
663 1.1 mrg || *type == _C_BYREF
664 1.1 mrg || *type == _C_ONEWAY
665 1.1 mrg || *type == _C_GCINVISIBLE)
666 1.1 mrg {
667 1.1 mrg type += 1;
668 1.1 mrg }
669 1.1 mrg return type;
670 1.1 mrg }
671 1.1 mrg
672 1.1 mrg const char *
673 1.1 mrg objc_skip_typespec (const char *type)
674 1.1 mrg {
675 1.3 mrg type = objc_skip_variable_name (type);
676 1.1 mrg type = objc_skip_type_qualifiers (type);
677 1.1 mrg
678 1.1 mrg switch (*type) {
679 1.1 mrg
680 1.1 mrg case _C_ID:
681 1.1 mrg /* An id may be annotated by the actual type if it is known
682 1.1 mrg with the @"ClassName" syntax */
683 1.1 mrg
684 1.1 mrg if (*++type != '"')
685 1.1 mrg return type;
686 1.1 mrg else
687 1.1 mrg {
688 1.1 mrg while (*++type != '"')
689 1.1 mrg /* do nothing */;
690 1.1 mrg return type + 1;
691 1.1 mrg }
692 1.1 mrg
693 1.1 mrg /* The following are one character type codes */
694 1.1 mrg case _C_CLASS:
695 1.1 mrg case _C_SEL:
696 1.1 mrg case _C_CHR:
697 1.1 mrg case _C_UCHR:
698 1.1 mrg case _C_CHARPTR:
699 1.1 mrg case _C_ATOM:
700 1.1 mrg case _C_SHT:
701 1.1 mrg case _C_USHT:
702 1.1 mrg case _C_INT:
703 1.1 mrg case _C_UINT:
704 1.1 mrg case _C_LNG:
705 1.1 mrg case _C_BOOL:
706 1.1 mrg case _C_ULNG:
707 1.1 mrg case _C_LNG_LNG:
708 1.1 mrg case _C_ULNG_LNG:
709 1.1 mrg case _C_FLT:
710 1.1 mrg case _C_DBL:
711 1.3 mrg case _C_LNG_DBL:
712 1.1 mrg case _C_VOID:
713 1.1 mrg case _C_UNDEF:
714 1.1 mrg return ++type;
715 1.1 mrg break;
716 1.1 mrg
717 1.1 mrg case _C_COMPLEX:
718 1.1 mrg return type + 2;
719 1.1 mrg break;
720 1.1 mrg
721 1.1 mrg case _C_ARY_B:
722 1.1 mrg /* skip digits, typespec and closing ']' */
723 1.1 mrg while (isdigit ((unsigned char)*++type))
724 1.1 mrg ;
725 1.1 mrg type = objc_skip_typespec (type);
726 1.1 mrg if (*type == _C_ARY_E)
727 1.1 mrg return ++type;
728 1.1 mrg else
729 1.1 mrg {
730 1.3 mrg _objc_abort ("bad array type %s\n", type);
731 1.3 mrg return 0;
732 1.3 mrg }
733 1.3 mrg
734 1.3 mrg case _C_VECTOR:
735 1.3 mrg /* Skip '!' */
736 1.3 mrg type++;
737 1.3 mrg /* Skip '[' */
738 1.3 mrg type++;
739 1.3 mrg /* Skip digits (size) */
740 1.3 mrg while (isdigit ((unsigned char)*type))
741 1.3 mrg type++;
742 1.3 mrg /* Skip ',' */
743 1.3 mrg type++;
744 1.3 mrg /* Skip digits (alignment) */
745 1.3 mrg while (isdigit ((unsigned char)*type))
746 1.3 mrg type++;
747 1.3 mrg /* Skip typespec. */
748 1.3 mrg type = objc_skip_typespec (type);
749 1.3 mrg /* Skip closing ']'. */
750 1.3 mrg if (*type == _C_ARY_E)
751 1.3 mrg return ++type;
752 1.3 mrg else
753 1.3 mrg {
754 1.3 mrg _objc_abort ("bad vector type %s\n", type);
755 1.1 mrg return 0;
756 1.1 mrg }
757 1.1 mrg
758 1.1 mrg case _C_BFLD:
759 1.3 mrg /* The GNU encoding of bitfields is: b 'position' 'type'
760 1.3 mrg 'size'. */
761 1.1 mrg while (isdigit ((unsigned char)*++type))
762 1.1 mrg ; /* skip position */
763 1.1 mrg while (isdigit ((unsigned char)*++type))
764 1.1 mrg ; /* skip type and size */
765 1.1 mrg return type;
766 1.1 mrg
767 1.1 mrg case _C_STRUCT_B:
768 1.1 mrg /* skip name, and elements until closing '}' */
769 1.1 mrg
770 1.1 mrg while (*type != _C_STRUCT_E && *type++ != '=')
771 1.1 mrg ;
772 1.1 mrg while (*type != _C_STRUCT_E)
773 1.1 mrg {
774 1.1 mrg type = objc_skip_typespec (type);
775 1.1 mrg }
776 1.1 mrg return ++type;
777 1.1 mrg
778 1.1 mrg case _C_UNION_B:
779 1.1 mrg /* skip name, and elements until closing ')' */
780 1.1 mrg
781 1.1 mrg while (*type != _C_UNION_E && *type++ != '=')
782 1.1 mrg ;
783 1.1 mrg while (*type != _C_UNION_E)
784 1.1 mrg {
785 1.1 mrg type = objc_skip_typespec (type);
786 1.1 mrg }
787 1.1 mrg return ++type;
788 1.1 mrg
789 1.1 mrg case _C_PTR:
790 1.1 mrg /* Just skip the following typespec */
791 1.1 mrg
792 1.1 mrg return objc_skip_typespec (++type);
793 1.1 mrg
794 1.1 mrg default:
795 1.1 mrg {
796 1.3 mrg _objc_abort ("unknown type %s\n", type);
797 1.1 mrg return 0;
798 1.1 mrg }
799 1.1 mrg }
800 1.1 mrg }
801 1.1 mrg
802 1.1 mrg /*
803 1.1 mrg Skip an offset as part of a method encoding. This is prepended by a
804 1.1 mrg '+' if the argument is passed in registers.
805 1.1 mrg */
806 1.2 joerg const char *
807 1.1 mrg objc_skip_offset (const char *type)
808 1.1 mrg {
809 1.3 mrg /* The offset is prepended by a '+' if the argument is passed in
810 1.3 mrg registers. PS: The compiler stopped generating this '+' in
811 1.3 mrg version 3.4. */
812 1.1 mrg if (*type == '+')
813 1.1 mrg type++;
814 1.3 mrg
815 1.3 mrg /* Some people claim that on some platforms, where the stack grows
816 1.3 mrg backwards, the compiler generates negative offsets (??). Skip a
817 1.3 mrg '-' for such a negative offset. */
818 1.3 mrg if (*type == '-')
819 1.3 mrg type++;
820 1.3 mrg
821 1.3 mrg /* Skip the digits that represent the offset. */
822 1.3 mrg while (isdigit ((unsigned char) *type))
823 1.3 mrg type++;
824 1.3 mrg
825 1.1 mrg return type;
826 1.1 mrg }
827 1.1 mrg
828 1.1 mrg const char *
829 1.1 mrg objc_skip_argspec (const char *type)
830 1.1 mrg {
831 1.1 mrg type = objc_skip_typespec (type);
832 1.1 mrg type = objc_skip_offset (type);
833 1.1 mrg return type;
834 1.1 mrg }
835 1.1 mrg
836 1.3 mrg char *
837 1.3 mrg method_copyReturnType (struct objc_method *method)
838 1.1 mrg {
839 1.3 mrg if (method == NULL)
840 1.3 mrg return 0;
841 1.3 mrg else
842 1.1 mrg {
843 1.3 mrg char *returnValue;
844 1.3 mrg size_t returnValueSize;
845 1.3 mrg
846 1.3 mrg /* Determine returnValueSize. */
847 1.3 mrg {
848 1.3 mrg /* Find the end of the first argument. We want to return the
849 1.3 mrg first argument spec, plus 1 byte for the \0 at the end. */
850 1.3 mrg const char *type = method->method_types;
851 1.3 mrg if (*type == '\0')
852 1.3 mrg return NULL;
853 1.3 mrg type = objc_skip_argspec (type);
854 1.3 mrg returnValueSize = type - method->method_types + 1;
855 1.3 mrg }
856 1.3 mrg
857 1.3 mrg /* Copy the first argument into returnValue. */
858 1.3 mrg returnValue = malloc (sizeof (char) * returnValueSize);
859 1.3 mrg memcpy (returnValue, method->method_types, returnValueSize);
860 1.3 mrg returnValue[returnValueSize - 1] = '\0';
861 1.3 mrg
862 1.3 mrg return returnValue;
863 1.1 mrg }
864 1.1 mrg }
865 1.1 mrg
866 1.3 mrg char *
867 1.3 mrg method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
868 1.3 mrg {
869 1.3 mrg if (method == NULL)
870 1.3 mrg return 0;
871 1.3 mrg else
872 1.3 mrg {
873 1.3 mrg char *returnValue;
874 1.3 mrg const char *returnValueStart;
875 1.3 mrg size_t returnValueSize;
876 1.1 mrg
877 1.3 mrg /* Determine returnValueStart and returnValueSize. */
878 1.3 mrg {
879 1.3 mrg const char *type = method->method_types;
880 1.1 mrg
881 1.3 mrg /* Skip the first argument (return type). */
882 1.3 mrg type = objc_skip_argspec (type);
883 1.1 mrg
884 1.3 mrg /* Now keep skipping arguments until we get to
885 1.3 mrg argumentNumber. */
886 1.3 mrg while (argumentNumber > 0)
887 1.1 mrg {
888 1.3 mrg /* We are supposed to skip an argument, but the string is
889 1.3 mrg finished. This means we were asked for a non-existing
890 1.3 mrg argument. */
891 1.3 mrg if (*type == '\0')
892 1.3 mrg return NULL;
893 1.3 mrg
894 1.3 mrg type = objc_skip_argspec (type);
895 1.3 mrg argumentNumber--;
896 1.1 mrg }
897 1.3 mrg
898 1.3 mrg /* If the argument does not exist, return NULL. */
899 1.3 mrg if (*type == '\0')
900 1.3 mrg return NULL;
901 1.3 mrg
902 1.3 mrg returnValueStart = type;
903 1.3 mrg type = objc_skip_argspec (type);
904 1.3 mrg returnValueSize = type - returnValueStart + 1;
905 1.1 mrg }
906 1.3 mrg
907 1.3 mrg /* Copy the argument into returnValue. */
908 1.3 mrg returnValue = malloc (sizeof (char) * returnValueSize);
909 1.3 mrg memcpy (returnValue, returnValueStart, returnValueSize);
910 1.3 mrg returnValue[returnValueSize - 1] = '\0';
911 1.3 mrg
912 1.3 mrg return returnValue;
913 1.3 mrg }
914 1.3 mrg }
915 1.1 mrg
916 1.3 mrg void method_getReturnType (struct objc_method * method, char *returnValue,
917 1.3 mrg size_t returnValueSize)
918 1.1 mrg {
919 1.3 mrg if (returnValue == NULL || returnValueSize == 0)
920 1.3 mrg return;
921 1.1 mrg
922 1.3 mrg /* Zero the string; we'll then write the argument type at the
923 1.3 mrg beginning of it, if needed. */
924 1.3 mrg memset (returnValue, 0, returnValueSize);
925 1.1 mrg
926 1.3 mrg if (method == NULL)
927 1.3 mrg return;
928 1.3 mrg else
929 1.3 mrg {
930 1.3 mrg size_t argumentTypeSize;
931 1.1 mrg
932 1.3 mrg /* Determine argumentTypeSize. */
933 1.3 mrg {
934 1.3 mrg /* Find the end of the first argument. We want to return the
935 1.3 mrg first argument spec. */
936 1.3 mrg const char *type = method->method_types;
937 1.3 mrg if (*type == '\0')
938 1.3 mrg return;
939 1.3 mrg type = objc_skip_argspec (type);
940 1.3 mrg argumentTypeSize = type - method->method_types;
941 1.3 mrg if (argumentTypeSize > returnValueSize)
942 1.3 mrg argumentTypeSize = returnValueSize;
943 1.3 mrg }
944 1.3 mrg /* Copy the argument at the beginning of the string. */
945 1.3 mrg memcpy (returnValue, method->method_types, argumentTypeSize);
946 1.3 mrg }
947 1.1 mrg }
948 1.1 mrg
949 1.3 mrg void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
950 1.3 mrg char *returnValue, size_t returnValueSize)
951 1.1 mrg {
952 1.3 mrg if (returnValue == NULL || returnValueSize == 0)
953 1.3 mrg return;
954 1.3 mrg
955 1.3 mrg /* Zero the string; we'll then write the argument type at the
956 1.3 mrg beginning of it, if needed. */
957 1.3 mrg memset (returnValue, 0, returnValueSize);
958 1.3 mrg
959 1.3 mrg if (method == NULL)
960 1.3 mrg return;
961 1.3 mrg else
962 1.3 mrg {
963 1.3 mrg const char *returnValueStart;
964 1.3 mrg size_t argumentTypeSize;
965 1.1 mrg
966 1.3 mrg /* Determine returnValueStart and argumentTypeSize. */
967 1.3 mrg {
968 1.3 mrg const char *type = method->method_types;
969 1.1 mrg
970 1.3 mrg /* Skip the first argument (return type). */
971 1.3 mrg type = objc_skip_argspec (type);
972 1.1 mrg
973 1.3 mrg /* Now keep skipping arguments until we get to
974 1.3 mrg argumentNumber. */
975 1.3 mrg while (argumentNumber > 0)
976 1.3 mrg {
977 1.3 mrg /* We are supposed to skip an argument, but the string is
978 1.3 mrg finished. This means we were asked for a non-existing
979 1.3 mrg argument. */
980 1.3 mrg if (*type == '\0')
981 1.3 mrg return;
982 1.1 mrg
983 1.3 mrg type = objc_skip_argspec (type);
984 1.3 mrg argumentNumber--;
985 1.3 mrg }
986 1.1 mrg
987 1.3 mrg /* If the argument does not exist, it's game over. */
988 1.3 mrg if (*type == '\0')
989 1.3 mrg return;
990 1.3 mrg
991 1.3 mrg returnValueStart = type;
992 1.3 mrg type = objc_skip_argspec (type);
993 1.3 mrg argumentTypeSize = type - returnValueStart;
994 1.3 mrg if (argumentTypeSize > returnValueSize)
995 1.3 mrg argumentTypeSize = returnValueSize;
996 1.3 mrg }
997 1.3 mrg /* Copy the argument at the beginning of the string. */
998 1.3 mrg memcpy (returnValue, returnValueStart, argumentTypeSize);
999 1.3 mrg }
1000 1.3 mrg }
1001 1.1 mrg
1002 1.3 mrg unsigned int
1003 1.3 mrg method_getNumberOfArguments (struct objc_method *method)
1004 1.3 mrg {
1005 1.3 mrg if (method == NULL)
1006 1.3 mrg return 0;
1007 1.1 mrg else
1008 1.3 mrg {
1009 1.3 mrg unsigned int i = 0;
1010 1.3 mrg const char *type = method->method_types;
1011 1.3 mrg while (*type)
1012 1.3 mrg {
1013 1.3 mrg type = objc_skip_argspec (type);
1014 1.3 mrg i += 1;
1015 1.3 mrg }
1016 1.3 mrg
1017 1.3 mrg if (i == 0)
1018 1.3 mrg {
1019 1.3 mrg /* This could only happen if method_types is invalid; in
1020 1.3 mrg that case, return 0. */
1021 1.3 mrg return 0;
1022 1.3 mrg }
1023 1.3 mrg else
1024 1.3 mrg {
1025 1.3 mrg /* Remove the return type. */
1026 1.3 mrg return (i - 1);
1027 1.3 mrg }
1028 1.3 mrg }
1029 1.1 mrg }
1030 1.1 mrg
1031 1.1 mrg unsigned
1032 1.1 mrg objc_get_type_qualifiers (const char *type)
1033 1.1 mrg {
1034 1.1 mrg unsigned res = 0;
1035 1.1 mrg BOOL flag = YES;
1036 1.1 mrg
1037 1.1 mrg while (flag)
1038 1.1 mrg switch (*type++)
1039 1.1 mrg {
1040 1.3 mrg case _C_CONST: res |= _F_CONST; break;
1041 1.3 mrg case _C_IN: res |= _F_IN; break;
1042 1.3 mrg case _C_INOUT: res |= _F_INOUT; break;
1043 1.3 mrg case _C_OUT: res |= _F_OUT; break;
1044 1.3 mrg case _C_BYCOPY: res |= _F_BYCOPY; break;
1045 1.3 mrg case _C_BYREF: res |= _F_BYREF; break;
1046 1.3 mrg case _C_ONEWAY: res |= _F_ONEWAY; break;
1047 1.1 mrg case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1048 1.1 mrg default: flag = NO;
1049 1.1 mrg }
1050 1.1 mrg
1051 1.1 mrg return res;
1052 1.1 mrg }
1053 1.1 mrg
1054 1.1 mrg /* The following three functions can be used to determine how a
1055 1.1 mrg structure is laid out by the compiler. For example:
1056 1.1 mrg
1057 1.1 mrg struct objc_struct_layout layout;
1058 1.1 mrg int i;
1059 1.1 mrg
1060 1.1 mrg objc_layout_structure (type, &layout);
1061 1.1 mrg while (objc_layout_structure_next_member (&layout))
1062 1.1 mrg {
1063 1.1 mrg int position, align;
1064 1.1 mrg const char *type;
1065 1.1 mrg
1066 1.1 mrg objc_layout_structure_get_info (&layout, &position, &align, &type);
1067 1.1 mrg printf ("element %d has offset %d, alignment %d\n",
1068 1.1 mrg i++, position, align);
1069 1.1 mrg }
1070 1.1 mrg
1071 1.1 mrg These functions are used by objc_sizeof_type and objc_alignof_type
1072 1.1 mrg functions to compute the size and alignment of structures. The
1073 1.1 mrg previous method of computing the size and alignment of a structure
1074 1.6 mrg was not working on some architectures, particularly on AIX, and in
1075 1.3 mrg the presence of bitfields inside the structure. */
1076 1.1 mrg void
1077 1.1 mrg objc_layout_structure (const char *type,
1078 1.3 mrg struct objc_struct_layout *layout)
1079 1.1 mrg {
1080 1.1 mrg const char *ntype;
1081 1.1 mrg
1082 1.1 mrg if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1083 1.1 mrg {
1084 1.3 mrg _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1085 1.3 mrg type);
1086 1.1 mrg }
1087 1.1 mrg
1088 1.1 mrg type ++;
1089 1.1 mrg layout->original_type = type;
1090 1.1 mrg
1091 1.1 mrg /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1092 1.1 mrg ntype = type;
1093 1.1 mrg while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1094 1.1 mrg && *ntype++ != '=')
1095 1.1 mrg /* do nothing */;
1096 1.1 mrg
1097 1.15 mrg /* If there's a "<name>=", ntype - 1 points to '='; skip the name. */
1098 1.1 mrg if (*(ntype - 1) == '=')
1099 1.1 mrg type = ntype;
1100 1.1 mrg
1101 1.1 mrg layout->type = type;
1102 1.1 mrg layout->prev_type = NULL;
1103 1.1 mrg layout->record_size = 0;
1104 1.7 mrg layout->record_align = __CHAR_BIT__;
1105 1.1 mrg
1106 1.1 mrg layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1107 1.1 mrg }
1108 1.1 mrg
1109 1.1 mrg BOOL
1110 1.1 mrg objc_layout_structure_next_member (struct objc_struct_layout *layout)
1111 1.1 mrg {
1112 1.1 mrg register int desired_align = 0;
1113 1.1 mrg
1114 1.1 mrg /* The following are used only if the field is a bitfield */
1115 1.1 mrg register const char *bfld_type = 0;
1116 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS
1117 1.8 mrg register int bfld_type_align = 0;
1118 1.8 mrg #endif
1119 1.8 mrg register int bfld_field_size = 0;
1120 1.1 mrg
1121 1.1 mrg /* The current type without the type qualifiers */
1122 1.1 mrg const char *type;
1123 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1124 1.1 mrg
1125 1.1 mrg /* Add the size of the previous field to the size of the record. */
1126 1.1 mrg if (layout->prev_type)
1127 1.1 mrg {
1128 1.1 mrg type = objc_skip_type_qualifiers (layout->prev_type);
1129 1.1 mrg if (unionp)
1130 1.1 mrg layout->record_size = MAX (layout->record_size,
1131 1.7 mrg objc_sizeof_type (type) * __CHAR_BIT__);
1132 1.1 mrg
1133 1.1 mrg else if (*type != _C_BFLD)
1134 1.7 mrg layout->record_size += objc_sizeof_type (type) * __CHAR_BIT__;
1135 1.1 mrg else {
1136 1.1 mrg /* Get the bitfield's type */
1137 1.1 mrg for (bfld_type = type + 1;
1138 1.1 mrg isdigit ((unsigned char)*bfld_type);
1139 1.1 mrg bfld_type++)
1140 1.1 mrg /* do nothing */;
1141 1.1 mrg
1142 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS
1143 1.7 mrg bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1144 1.8 mrg #endif
1145 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1146 1.1 mrg layout->record_size += bfld_field_size;
1147 1.1 mrg }
1148 1.1 mrg }
1149 1.1 mrg
1150 1.1 mrg if ((unionp && *layout->type == _C_UNION_E)
1151 1.1 mrg || (!unionp && *layout->type == _C_STRUCT_E))
1152 1.1 mrg return NO;
1153 1.1 mrg
1154 1.1 mrg /* Skip the variable name if any */
1155 1.3 mrg layout->type = objc_skip_variable_name (layout->type);
1156 1.1 mrg type = objc_skip_type_qualifiers (layout->type);
1157 1.1 mrg
1158 1.1 mrg if (*type != _C_BFLD)
1159 1.7 mrg desired_align = objc_alignof_type (type) * __CHAR_BIT__;
1160 1.1 mrg else
1161 1.1 mrg {
1162 1.1 mrg desired_align = 1;
1163 1.1 mrg /* Skip the bitfield's offset */
1164 1.1 mrg for (bfld_type = type + 1;
1165 1.1 mrg isdigit ((unsigned char) *bfld_type);
1166 1.1 mrg bfld_type++)
1167 1.1 mrg /* do nothing */;
1168 1.1 mrg
1169 1.8 mrg #ifdef HAVE_BITFIELD_TYPE_MATTERS
1170 1.7 mrg bfld_type_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1171 1.8 mrg #endif
1172 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1173 1.1 mrg }
1174 1.1 mrg
1175 1.3 mrg /* The following won't work for vectors. */
1176 1.1 mrg #ifdef BIGGEST_FIELD_ALIGNMENT
1177 1.1 mrg desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1178 1.1 mrg #endif
1179 1.1 mrg #ifdef ADJUST_FIELD_ALIGN
1180 1.9 mrg desired_align = ADJUST_FIELD_ALIGN (type, type, desired_align);
1181 1.1 mrg #endif
1182 1.1 mrg
1183 1.1 mrg /* Record must have at least as much alignment as any field.
1184 1.1 mrg Otherwise, the alignment of the field within the record
1185 1.1 mrg is meaningless. */
1186 1.7 mrg #ifndef HAVE_BITFIELD_TYPE_MATTERS
1187 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1188 1.1 mrg #else /* PCC_BITFIELD_TYPE_MATTERS */
1189 1.1 mrg if (*type == _C_BFLD)
1190 1.1 mrg {
1191 1.1 mrg /* For these machines, a zero-length field does not
1192 1.1 mrg affect the alignment of the structure as a whole.
1193 1.1 mrg It does, however, affect the alignment of the next field
1194 1.1 mrg within the structure. */
1195 1.1 mrg if (bfld_field_size)
1196 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1197 1.1 mrg else
1198 1.7 mrg desired_align = objc_alignof_type (bfld_type) * __CHAR_BIT__;
1199 1.1 mrg
1200 1.1 mrg /* A named bit field of declared type `int'
1201 1.1 mrg forces the entire structure to have `int' alignment.
1202 1.1 mrg Q1: How is encoded this thing and how to check for it?
1203 1.1 mrg Q2: How to determine maximum_field_alignment at runtime? */
1204 1.1 mrg
1205 1.1 mrg /* if (DECL_NAME (field) != 0) */
1206 1.1 mrg {
1207 1.1 mrg int type_align = bfld_type_align;
1208 1.1 mrg #if 0
1209 1.1 mrg if (maximum_field_alignment != 0)
1210 1.1 mrg type_align = MIN (type_align, maximum_field_alignment);
1211 1.1 mrg else if (DECL_PACKED (field))
1212 1.7 mrg type_align = MIN (type_align, __CHAR_BIT__);
1213 1.1 mrg #endif
1214 1.1 mrg
1215 1.1 mrg layout->record_align = MAX (layout->record_align, type_align);
1216 1.1 mrg }
1217 1.1 mrg }
1218 1.1 mrg else
1219 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1220 1.1 mrg #endif /* PCC_BITFIELD_TYPE_MATTERS */
1221 1.1 mrg
1222 1.1 mrg /* Does this field automatically have alignment it needs
1223 1.1 mrg by virtue of the fields that precede it and the record's
1224 1.1 mrg own alignment? */
1225 1.1 mrg
1226 1.1 mrg if (*type == _C_BFLD)
1227 1.1 mrg layout->record_size = atoi (type + 1);
1228 1.1 mrg else if (layout->record_size % desired_align != 0)
1229 1.1 mrg {
1230 1.1 mrg /* No, we need to skip space before this field.
1231 1.1 mrg Bump the cumulative size to multiple of field alignment. */
1232 1.1 mrg layout->record_size = ROUND (layout->record_size, desired_align);
1233 1.1 mrg }
1234 1.1 mrg
1235 1.1 mrg /* Jump to the next field in record. */
1236 1.1 mrg
1237 1.1 mrg layout->prev_type = layout->type;
1238 1.1 mrg layout->type = objc_skip_typespec (layout->type); /* skip component */
1239 1.1 mrg
1240 1.1 mrg return YES;
1241 1.1 mrg }
1242 1.1 mrg
1243 1.1 mrg void objc_layout_finish_structure (struct objc_struct_layout *layout,
1244 1.1 mrg unsigned int *size,
1245 1.1 mrg unsigned int *align)
1246 1.1 mrg {
1247 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1248 1.1 mrg if (layout->type
1249 1.1 mrg && ((!unionp && *layout->type == _C_STRUCT_E)
1250 1.1 mrg || (unionp && *layout->type == _C_UNION_E)))
1251 1.1 mrg {
1252 1.1 mrg /* Work out the alignment of the record as one expression and store
1253 1.1 mrg in the record type. Round it up to a multiple of the record's
1254 1.1 mrg alignment. */
1255 1.1 mrg #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1256 1.1 mrg layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1257 1.1 mrg 1,
1258 1.1 mrg layout->record_align);
1259 1.1 mrg #else
1260 1.1 mrg layout->record_align = MAX (1, layout->record_align);
1261 1.1 mrg #endif
1262 1.1 mrg
1263 1.1 mrg /* Round the size up to be a multiple of the required alignment */
1264 1.1 mrg layout->record_size = ROUND (layout->record_size, layout->record_align);
1265 1.1 mrg
1266 1.1 mrg layout->type = NULL;
1267 1.1 mrg }
1268 1.1 mrg if (size)
1269 1.7 mrg *size = layout->record_size / __CHAR_BIT__;
1270 1.1 mrg if (align)
1271 1.7 mrg *align = layout->record_align / __CHAR_BIT__;
1272 1.1 mrg }
1273 1.1 mrg
1274 1.1 mrg void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1275 1.1 mrg unsigned int *offset,
1276 1.1 mrg unsigned int *align,
1277 1.1 mrg const char **type)
1278 1.1 mrg {
1279 1.1 mrg if (offset)
1280 1.7 mrg *offset = layout->record_size / __CHAR_BIT__;
1281 1.1 mrg if (align)
1282 1.7 mrg *align = layout->record_align / __CHAR_BIT__;
1283 1.1 mrg if (type)
1284 1.1 mrg *type = layout->prev_type;
1285 1.1 mrg }
1286