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