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