encoding.c revision 1.1.1.2 1 1.1 mrg /* Encoding of types for Objective C.
2 1.1.1.2 mrg Copyright (C) 1993-2013 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.1.1.2 mrg /* FIXME: This file contains functions that will abort the entire
30 1.1.1.2 mrg program if they fail. Is that really needed ? */
31 1.1.1.2 mrg
32 1.1.1.2 mrg #include "objc-private/common.h"
33 1.1.1.2 mrg #include "objc-private/error.h"
34 1.1 mrg #include "tconfig.h"
35 1.1 mrg #include "coretypes.h"
36 1.1 mrg #include "tm.h"
37 1.1.1.2 mrg #include "objc/runtime.h"
38 1.1.1.2 mrg #include "objc-private/module-abi-8.h" /* For struct objc_method */
39 1.1 mrg #include <stdlib.h>
40 1.1.1.2 mrg #include <ctype.h>
41 1.1.1.2 mrg #include <string.h> /* For memcpy. */
42 1.1 mrg
43 1.1 mrg #undef MAX
44 1.1 mrg #define MAX(X, Y) \
45 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \
46 1.1 mrg (__x > __y ? __x : __y); })
47 1.1 mrg
48 1.1 mrg #undef MIN
49 1.1 mrg #define MIN(X, Y) \
50 1.1 mrg ({ typeof (X) __x = (X), __y = (Y); \
51 1.1 mrg (__x < __y ? __x : __y); })
52 1.1 mrg
53 1.1 mrg #undef ROUND
54 1.1 mrg #define ROUND(V, A) \
55 1.1 mrg ({ typeof (V) __v = (V); typeof (A) __a = (A); \
56 1.1 mrg __a * ((__v+__a - 1)/__a); })
57 1.1 mrg
58 1.1 mrg
59 1.1 mrg /* Various hacks for objc_layout_record. These are used by the target
60 1.1 mrg macros. */
61 1.1 mrg
62 1.1 mrg #define TREE_CODE(TYPE) *(TYPE)
63 1.1 mrg #define TREE_TYPE(TREE) (TREE)
64 1.1 mrg
65 1.1 mrg #define RECORD_TYPE _C_STRUCT_B
66 1.1 mrg #define UNION_TYPE _C_UNION_B
67 1.1 mrg #define QUAL_UNION_TYPE _C_UNION_B
68 1.1 mrg #define ARRAY_TYPE _C_ARY_B
69 1.1 mrg
70 1.1 mrg #define REAL_TYPE _C_DBL
71 1.1 mrg
72 1.1 mrg #define VECTOR_TYPE _C_VECTOR
73 1.1 mrg
74 1.1 mrg #define TYPE_FIELDS(TYPE) ({const char *_field = (TYPE)+1; \
75 1.1 mrg while (*_field != _C_STRUCT_E && *_field != _C_STRUCT_B \
76 1.1 mrg && *_field != _C_UNION_B && *_field++ != '=') \
77 1.1 mrg /* do nothing */; \
78 1.1 mrg _field;})
79 1.1 mrg
80 1.1 mrg #define DECL_MODE(TYPE) *(TYPE)
81 1.1 mrg #define TYPE_MODE(TYPE) *(TYPE)
82 1.1 mrg
83 1.1 mrg #define DFmode _C_DBL
84 1.1 mrg
85 1.1 mrg #define strip_array_types(TYPE) ({const char *_field = (TYPE); \
86 1.1 mrg while (*_field == _C_ARY_B)\
87 1.1 mrg {\
88 1.1 mrg while (isdigit ((unsigned char)*++_field))\
89 1.1 mrg ;\
90 1.1 mrg }\
91 1.1 mrg _field;})
92 1.1 mrg
93 1.1 mrg /* Some ports (eg ARM) allow the structure size boundary to be
94 1.1 mrg selected at compile-time. We override the normal definition with
95 1.1 mrg one that has a constant value for this compilation. */
96 1.1 mrg #ifndef BITS_PER_UNIT
97 1.1 mrg #define BITS_PER_UNIT 8
98 1.1 mrg #endif
99 1.1 mrg #undef STRUCTURE_SIZE_BOUNDARY
100 1.1 mrg #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
101 1.1 mrg
102 1.1 mrg /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
103 1.1 mrg target_flags. Define a dummy entry here to so we don't die.
104 1.1 mrg We have to rename it because target_flags may already have been
105 1.1 mrg declared extern. */
106 1.1 mrg #define target_flags not_target_flags
107 1.1 mrg static int __attribute__ ((__unused__)) not_target_flags = 0;
108 1.1 mrg
109 1.1 mrg /* Some ROUND_TYPE_ALIGN use ALTIVEC_VECTOR_MODE (rs6000 darwin).
110 1.1 mrg Define a dummy ALTIVEC_VECTOR_MODE so it will not die. */
111 1.1 mrg #undef ALTIVEC_VECTOR_MODE
112 1.1 mrg #define ALTIVEC_VECTOR_MODE(MODE) (0)
113 1.1 mrg
114 1.1.1.2 mrg /* Replace TARGET_VSX, TARGET_ALTIVEC, and TARGET_64BIT with constants based on
115 1.1.1.2 mrg the current switches, rather than looking in the options structure. */
116 1.1.1.2 mrg #ifdef _ARCH_PPC
117 1.1.1.2 mrg #undef TARGET_VSX
118 1.1.1.2 mrg #undef TARGET_ALTIVEC
119 1.1.1.2 mrg #undef TARGET_64BIT
120 1.1.1.2 mrg
121 1.1.1.2 mrg #ifdef __VSX__
122 1.1.1.2 mrg #define TARGET_VSX 1
123 1.1.1.2 mrg #else
124 1.1.1.2 mrg #define TARGET_VSX 0
125 1.1.1.2 mrg #endif
126 1.1.1.2 mrg
127 1.1.1.2 mrg #ifdef __ALTIVEC__
128 1.1.1.2 mrg #define TARGET_ALTIVEC 1
129 1.1.1.2 mrg #else
130 1.1.1.2 mrg #define TARGET_ALTIVEC 0
131 1.1.1.2 mrg #endif
132 1.1.1.2 mrg
133 1.1.1.2 mrg #ifdef _ARCH_PPC64
134 1.1.1.2 mrg #define TARGET_64BIT 1
135 1.1.1.2 mrg #else
136 1.1.1.2 mrg #define TARGET_64BIT 0
137 1.1.1.2 mrg #endif
138 1.1.1.2 mrg #endif
139 1.1.1.2 mrg
140 1.1.1.2 mrg /* Furthermore, some (powerpc) targets also use TARGET_ALIGN_NATURAL
141 1.1.1.2 mrg in their alignment macros. Currently[4.5/6], rs6000.h points this
142 1.1.1.2 mrg to a static variable, initialized by target overrides. This is reset
143 1.1.1.2 mrg in linux64.h but not in darwin64.h. The macro is not used by *86*. */
144 1.1.1.2 mrg
145 1.1.1.2 mrg #if __MACH__
146 1.1.1.2 mrg # if __LP64__
147 1.1.1.2 mrg # undef TARGET_ALIGN_NATURAL
148 1.1.1.2 mrg # define TARGET_ALIGN_NATURAL 1
149 1.1.1.2 mrg # endif
150 1.1.1.2 mrg
151 1.1.1.2 mrg /* On Darwin32, we need to recurse until we find the starting stuct type. */
152 1.1.1.2 mrg static int
153 1.1.1.2 mrg _darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec)
154 1.1.1.2 mrg {
155 1.1.1.2 mrg const char *_stp , *_fields = TYPE_FIELDS (struc);
156 1.1.1.2 mrg if (!_fields)
157 1.1.1.2 mrg return MAX (comp, spec);
158 1.1.1.2 mrg _stp = strip_array_types (_fields);
159 1.1.1.2 mrg if (TYPE_MODE(_stp) == _C_COMPLEX)
160 1.1.1.2 mrg _stp++;
161 1.1.1.2 mrg switch (TYPE_MODE(_stp))
162 1.1.1.2 mrg {
163 1.1.1.2 mrg case RECORD_TYPE:
164 1.1.1.2 mrg case UNION_TYPE:
165 1.1.1.2 mrg return MAX (MAX (comp, spec), objc_alignof_type (_stp) * BITS_PER_UNIT);
166 1.1.1.2 mrg break;
167 1.1.1.2 mrg case DFmode:
168 1.1.1.2 mrg case _C_LNG_LNG:
169 1.1.1.2 mrg case _C_ULNG_LNG:
170 1.1.1.2 mrg return MAX (MAX (comp, spec), 64);
171 1.1.1.2 mrg break;
172 1.1.1.2 mrg
173 1.1.1.2 mrg default:
174 1.1.1.2 mrg return MAX (comp, spec);
175 1.1.1.2 mrg break;
176 1.1.1.2 mrg }
177 1.1.1.2 mrg }
178 1.1.1.2 mrg
179 1.1.1.2 mrg /* See comment below. */
180 1.1.1.2 mrg #define darwin_rs6000_special_round_type_align(S,C,S2) \
181 1.1.1.2 mrg (_darwin_rs6000_special_round_type_align ((char*)(S), (int)(C), (int)(S2)))
182 1.1.1.2 mrg #endif
183 1.1 mrg
184 1.1 mrg /* FIXME: while this file has no business including tm.h, this
185 1.1 mrg definitely has no business defining this macro but it
186 1.1 mrg is only way around without really rewritting this file,
187 1.1.1.2 mrg should look after the branch of 3.4 to fix this. */
188 1.1 mrg #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
189 1.1.1.2 mrg ({ const char *_fields = TYPE_FIELDS (STRUCT); \
190 1.1 mrg ((_fields != 0 \
191 1.1 mrg && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
192 1.1 mrg ? MAX (MAX (COMPUTED, SPECIFIED), 64) \
193 1.1 mrg : MAX (COMPUTED, SPECIFIED));})
194 1.1 mrg
195 1.1.1.2 mrg
196 1.1.1.2 mrg /* Skip a variable name, enclosed in quotes ("). */
197 1.1.1.2 mrg static inline
198 1.1.1.2 mrg const char *
199 1.1.1.2 mrg objc_skip_variable_name (const char *type)
200 1.1 mrg {
201 1.1.1.2 mrg /* Skip the variable name if any. */
202 1.1 mrg if (*type == '"')
203 1.1 mrg {
204 1.1.1.2 mrg /* FIXME: How do we know we won't read beyond the end of the
205 1.1.1.2 mrg string. Here and in the rest of the file! */
206 1.1.1.2 mrg /* Skip '"'. */
207 1.1.1.2 mrg type++;
208 1.1.1.2 mrg /* Skip to the next '"'. */
209 1.1.1.2 mrg while (*type != '"')
210 1.1.1.2 mrg type++;
211 1.1.1.2 mrg /* Skip '"'. */
212 1.1.1.2 mrg type++;
213 1.1 mrg }
214 1.1 mrg
215 1.1.1.2 mrg return type;
216 1.1.1.2 mrg }
217 1.1.1.2 mrg
218 1.1.1.2 mrg int
219 1.1.1.2 mrg objc_sizeof_type (const char *type)
220 1.1.1.2 mrg {
221 1.1.1.2 mrg type = objc_skip_variable_name (type);
222 1.1.1.2 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.1.1.2 mrg case _C_LNG_DBL:
289 1.1.1.2 mrg return sizeof (long double);
290 1.1.1.2 mrg break;
291 1.1.1.2 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.1.1.2 mrg case _C_VECTOR:
312 1.1.1.2 mrg {
313 1.1.1.2 mrg /* Skip the '!'. */
314 1.1.1.2 mrg type++;
315 1.1.1.2 mrg /* Skip the '['. */
316 1.1.1.2 mrg type++;
317 1.1.1.2 mrg
318 1.1.1.2 mrg /* The size in bytes is the following number. */
319 1.1.1.2 mrg int size = atoi (type);
320 1.1.1.2 mrg return size;
321 1.1.1.2 mrg }
322 1.1.1.2 mrg break;
323 1.1.1.2 mrg
324 1.1 mrg case _C_BFLD:
325 1.1 mrg {
326 1.1.1.2 mrg /* The GNU encoding of bitfields is: b 'position' 'type'
327 1.1.1.2 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.1 mrg startByte = position / BITS_PER_UNIT;
337 1.1 mrg endByte = (position + size) / BITS_PER_UNIT;
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.1.1.2 mrg
408 1.1.1.2 mrg case _C_LNG_DBL:
409 1.1.1.2 mrg return sizeof (_Complex long double);
410 1.1.1.2 mrg break;
411 1.1 mrg
412 1.1 mrg default:
413 1.1 mrg {
414 1.1.1.2 mrg /* FIXME: Is this so bad that we have to abort the
415 1.1.1.2 mrg entire program ? (it applies to all the other
416 1.1.1.2 mrg _objc_abort calls in this file).
417 1.1.1.2 mrg */
418 1.1.1.2 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.1.1.2 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.1.1.2 mrg type = objc_skip_variable_name (type);
436 1.1.1.2 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.1.1.2 mrg case _C_LNG_DBL:
503 1.1.1.2 mrg return __alignof__ (long double);
504 1.1.1.2 mrg break;
505 1.1.1.2 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.1.1.2 mrg case _C_VECTOR:
518 1.1.1.2 mrg {
519 1.1.1.2 mrg /* Skip the '!'. */
520 1.1.1.2 mrg type++;
521 1.1.1.2 mrg /* Skip the '['. */
522 1.1.1.2 mrg type++;
523 1.1.1.2 mrg
524 1.1.1.2 mrg /* Skip the size. */
525 1.1.1.2 mrg while (isdigit ((unsigned char)*type))
526 1.1.1.2 mrg type++;
527 1.1.1.2 mrg
528 1.1.1.2 mrg /* Skip the ','. */
529 1.1.1.2 mrg type++;
530 1.1.1.2 mrg
531 1.1.1.2 mrg /* The alignment in bytes is the following number. */
532 1.1.1.2 mrg return atoi (type);
533 1.1.1.2 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.1.1.2 mrg
602 1.1.1.2 mrg case _C_LNG_DBL:
603 1.1.1.2 mrg return __alignof__ (_Complex long double);
604 1.1.1.2 mrg break;
605 1.1 mrg
606 1.1 mrg default:
607 1.1 mrg {
608 1.1.1.2 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.1.1.2 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.1.1.2 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.1.1.2 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.1.2 mrg inline
647 1.1.1.2 mrg const char *
648 1.1 mrg objc_skip_type_qualifiers (const char *type)
649 1.1 mrg {
650 1.1 mrg while (*type == _C_CONST
651 1.1 mrg || *type == _C_IN
652 1.1 mrg || *type == _C_INOUT
653 1.1 mrg || *type == _C_OUT
654 1.1 mrg || *type == _C_BYCOPY
655 1.1 mrg || *type == _C_BYREF
656 1.1 mrg || *type == _C_ONEWAY
657 1.1 mrg || *type == _C_GCINVISIBLE)
658 1.1 mrg {
659 1.1 mrg type += 1;
660 1.1 mrg }
661 1.1 mrg return type;
662 1.1 mrg }
663 1.1 mrg
664 1.1.1.2 mrg inline
665 1.1 mrg const char *
666 1.1 mrg objc_skip_typespec (const char *type)
667 1.1 mrg {
668 1.1.1.2 mrg type = objc_skip_variable_name (type);
669 1.1 mrg type = objc_skip_type_qualifiers (type);
670 1.1 mrg
671 1.1 mrg switch (*type) {
672 1.1 mrg
673 1.1 mrg case _C_ID:
674 1.1 mrg /* An id may be annotated by the actual type if it is known
675 1.1 mrg with the @"ClassName" syntax */
676 1.1 mrg
677 1.1 mrg if (*++type != '"')
678 1.1 mrg return type;
679 1.1 mrg else
680 1.1 mrg {
681 1.1 mrg while (*++type != '"')
682 1.1 mrg /* do nothing */;
683 1.1 mrg return type + 1;
684 1.1 mrg }
685 1.1 mrg
686 1.1 mrg /* The following are one character type codes */
687 1.1 mrg case _C_CLASS:
688 1.1 mrg case _C_SEL:
689 1.1 mrg case _C_CHR:
690 1.1 mrg case _C_UCHR:
691 1.1 mrg case _C_CHARPTR:
692 1.1 mrg case _C_ATOM:
693 1.1 mrg case _C_SHT:
694 1.1 mrg case _C_USHT:
695 1.1 mrg case _C_INT:
696 1.1 mrg case _C_UINT:
697 1.1 mrg case _C_LNG:
698 1.1 mrg case _C_BOOL:
699 1.1 mrg case _C_ULNG:
700 1.1 mrg case _C_LNG_LNG:
701 1.1 mrg case _C_ULNG_LNG:
702 1.1 mrg case _C_FLT:
703 1.1 mrg case _C_DBL:
704 1.1.1.2 mrg case _C_LNG_DBL:
705 1.1 mrg case _C_VOID:
706 1.1 mrg case _C_UNDEF:
707 1.1 mrg return ++type;
708 1.1 mrg break;
709 1.1 mrg
710 1.1 mrg case _C_COMPLEX:
711 1.1 mrg return type + 2;
712 1.1 mrg break;
713 1.1 mrg
714 1.1 mrg case _C_ARY_B:
715 1.1 mrg /* skip digits, typespec and closing ']' */
716 1.1 mrg while (isdigit ((unsigned char)*++type))
717 1.1 mrg ;
718 1.1 mrg type = objc_skip_typespec (type);
719 1.1 mrg if (*type == _C_ARY_E)
720 1.1 mrg return ++type;
721 1.1 mrg else
722 1.1 mrg {
723 1.1.1.2 mrg _objc_abort ("bad array type %s\n", type);
724 1.1.1.2 mrg return 0;
725 1.1.1.2 mrg }
726 1.1.1.2 mrg
727 1.1.1.2 mrg case _C_VECTOR:
728 1.1.1.2 mrg /* Skip '!' */
729 1.1.1.2 mrg type++;
730 1.1.1.2 mrg /* Skip '[' */
731 1.1.1.2 mrg type++;
732 1.1.1.2 mrg /* Skip digits (size) */
733 1.1.1.2 mrg while (isdigit ((unsigned char)*type))
734 1.1.1.2 mrg type++;
735 1.1.1.2 mrg /* Skip ',' */
736 1.1.1.2 mrg type++;
737 1.1.1.2 mrg /* Skip digits (alignment) */
738 1.1.1.2 mrg while (isdigit ((unsigned char)*type))
739 1.1.1.2 mrg type++;
740 1.1.1.2 mrg /* Skip typespec. */
741 1.1.1.2 mrg type = objc_skip_typespec (type);
742 1.1.1.2 mrg /* Skip closing ']'. */
743 1.1.1.2 mrg if (*type == _C_ARY_E)
744 1.1.1.2 mrg return ++type;
745 1.1.1.2 mrg else
746 1.1.1.2 mrg {
747 1.1.1.2 mrg _objc_abort ("bad vector type %s\n", type);
748 1.1 mrg return 0;
749 1.1 mrg }
750 1.1 mrg
751 1.1 mrg case _C_BFLD:
752 1.1.1.2 mrg /* The GNU encoding of bitfields is: b 'position' 'type'
753 1.1.1.2 mrg 'size'. */
754 1.1 mrg while (isdigit ((unsigned char)*++type))
755 1.1 mrg ; /* skip position */
756 1.1 mrg while (isdigit ((unsigned char)*++type))
757 1.1 mrg ; /* skip type and size */
758 1.1 mrg return type;
759 1.1 mrg
760 1.1 mrg case _C_STRUCT_B:
761 1.1 mrg /* skip name, and elements until closing '}' */
762 1.1 mrg
763 1.1 mrg while (*type != _C_STRUCT_E && *type++ != '=')
764 1.1 mrg ;
765 1.1 mrg while (*type != _C_STRUCT_E)
766 1.1 mrg {
767 1.1 mrg type = objc_skip_typespec (type);
768 1.1 mrg }
769 1.1 mrg return ++type;
770 1.1 mrg
771 1.1 mrg case _C_UNION_B:
772 1.1 mrg /* skip name, and elements until closing ')' */
773 1.1 mrg
774 1.1 mrg while (*type != _C_UNION_E && *type++ != '=')
775 1.1 mrg ;
776 1.1 mrg while (*type != _C_UNION_E)
777 1.1 mrg {
778 1.1 mrg type = objc_skip_typespec (type);
779 1.1 mrg }
780 1.1 mrg return ++type;
781 1.1 mrg
782 1.1 mrg case _C_PTR:
783 1.1 mrg /* Just skip the following typespec */
784 1.1 mrg
785 1.1 mrg return objc_skip_typespec (++type);
786 1.1 mrg
787 1.1 mrg default:
788 1.1 mrg {
789 1.1.1.2 mrg _objc_abort ("unknown type %s\n", type);
790 1.1 mrg return 0;
791 1.1 mrg }
792 1.1 mrg }
793 1.1 mrg }
794 1.1 mrg
795 1.1.1.2 mrg inline
796 1.1.1.2 mrg const char *
797 1.1 mrg objc_skip_offset (const char *type)
798 1.1 mrg {
799 1.1.1.2 mrg /* The offset is prepended by a '+' if the argument is passed in
800 1.1.1.2 mrg registers. PS: The compiler stopped generating this '+' in
801 1.1.1.2 mrg version 3.4. */
802 1.1 mrg if (*type == '+')
803 1.1 mrg type++;
804 1.1.1.2 mrg
805 1.1.1.2 mrg /* Some people claim that on some platforms, where the stack grows
806 1.1.1.2 mrg backwards, the compiler generates negative offsets (??). Skip a
807 1.1.1.2 mrg '-' for such a negative offset. */
808 1.1.1.2 mrg if (*type == '-')
809 1.1.1.2 mrg type++;
810 1.1.1.2 mrg
811 1.1.1.2 mrg /* Skip the digits that represent the offset. */
812 1.1.1.2 mrg while (isdigit ((unsigned char) *type))
813 1.1.1.2 mrg type++;
814 1.1.1.2 mrg
815 1.1 mrg return type;
816 1.1 mrg }
817 1.1 mrg
818 1.1 mrg const char *
819 1.1 mrg objc_skip_argspec (const char *type)
820 1.1 mrg {
821 1.1 mrg type = objc_skip_typespec (type);
822 1.1 mrg type = objc_skip_offset (type);
823 1.1 mrg return type;
824 1.1 mrg }
825 1.1 mrg
826 1.1.1.2 mrg char *
827 1.1.1.2 mrg method_copyReturnType (struct objc_method *method)
828 1.1 mrg {
829 1.1.1.2 mrg if (method == NULL)
830 1.1.1.2 mrg return 0;
831 1.1.1.2 mrg else
832 1.1 mrg {
833 1.1.1.2 mrg char *returnValue;
834 1.1.1.2 mrg size_t returnValueSize;
835 1.1.1.2 mrg
836 1.1.1.2 mrg /* Determine returnValueSize. */
837 1.1.1.2 mrg {
838 1.1.1.2 mrg /* Find the end of the first argument. We want to return the
839 1.1.1.2 mrg first argument spec, plus 1 byte for the \0 at the end. */
840 1.1.1.2 mrg const char *type = method->method_types;
841 1.1.1.2 mrg if (*type == '\0')
842 1.1.1.2 mrg return NULL;
843 1.1.1.2 mrg type = objc_skip_argspec (type);
844 1.1.1.2 mrg returnValueSize = type - method->method_types + 1;
845 1.1.1.2 mrg }
846 1.1.1.2 mrg
847 1.1.1.2 mrg /* Copy the first argument into returnValue. */
848 1.1.1.2 mrg returnValue = malloc (sizeof (char) * returnValueSize);
849 1.1.1.2 mrg memcpy (returnValue, method->method_types, returnValueSize);
850 1.1.1.2 mrg returnValue[returnValueSize - 1] = '\0';
851 1.1.1.2 mrg
852 1.1.1.2 mrg return returnValue;
853 1.1 mrg }
854 1.1 mrg }
855 1.1 mrg
856 1.1.1.2 mrg char *
857 1.1.1.2 mrg method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
858 1.1 mrg {
859 1.1.1.2 mrg if (method == NULL)
860 1.1.1.2 mrg return 0;
861 1.1.1.2 mrg else
862 1.1.1.2 mrg {
863 1.1.1.2 mrg char *returnValue;
864 1.1.1.2 mrg const char *returnValueStart;
865 1.1.1.2 mrg size_t returnValueSize;
866 1.1 mrg
867 1.1.1.2 mrg /* Determine returnValueStart and returnValueSize. */
868 1.1 mrg {
869 1.1.1.2 mrg const char *type = method->method_types;
870 1.1.1.2 mrg
871 1.1.1.2 mrg /* Skip the first argument (return type). */
872 1.1.1.2 mrg type = objc_skip_argspec (type);
873 1.1.1.2 mrg
874 1.1.1.2 mrg /* Now keep skipping arguments until we get to
875 1.1.1.2 mrg argumentNumber. */
876 1.1.1.2 mrg while (argumentNumber > 0)
877 1.1 mrg {
878 1.1.1.2 mrg /* We are supposed to skip an argument, but the string is
879 1.1.1.2 mrg finished. This means we were asked for a non-existing
880 1.1.1.2 mrg argument. */
881 1.1.1.2 mrg if (*type == '\0')
882 1.1.1.2 mrg return NULL;
883 1.1.1.2 mrg
884 1.1.1.2 mrg type = objc_skip_argspec (type);
885 1.1.1.2 mrg argumentNumber--;
886 1.1 mrg }
887 1.1.1.2 mrg
888 1.1.1.2 mrg /* If the argument does not exist, return NULL. */
889 1.1.1.2 mrg if (*type == '\0')
890 1.1.1.2 mrg return NULL;
891 1.1.1.2 mrg
892 1.1.1.2 mrg returnValueStart = type;
893 1.1.1.2 mrg type = objc_skip_argspec (type);
894 1.1.1.2 mrg returnValueSize = type - returnValueStart + 1;
895 1.1 mrg }
896 1.1.1.2 mrg
897 1.1.1.2 mrg /* Copy the argument into returnValue. */
898 1.1.1.2 mrg returnValue = malloc (sizeof (char) * returnValueSize);
899 1.1.1.2 mrg memcpy (returnValue, returnValueStart, returnValueSize);
900 1.1.1.2 mrg returnValue[returnValueSize - 1] = '\0';
901 1.1 mrg
902 1.1.1.2 mrg return returnValue;
903 1.1.1.2 mrg }
904 1.1.1.2 mrg }
905 1.1 mrg
906 1.1.1.2 mrg void method_getReturnType (struct objc_method * method, char *returnValue,
907 1.1.1.2 mrg size_t returnValueSize)
908 1.1.1.2 mrg {
909 1.1.1.2 mrg if (returnValue == NULL || returnValueSize == 0)
910 1.1.1.2 mrg return;
911 1.1 mrg
912 1.1.1.2 mrg /* Zero the string; we'll then write the argument type at the
913 1.1.1.2 mrg beginning of it, if needed. */
914 1.1.1.2 mrg memset (returnValue, 0, returnValueSize);
915 1.1 mrg
916 1.1.1.2 mrg if (method == NULL)
917 1.1.1.2 mrg return;
918 1.1 mrg else
919 1.1.1.2 mrg {
920 1.1.1.2 mrg size_t argumentTypeSize;
921 1.1.1.2 mrg
922 1.1.1.2 mrg /* Determine argumentTypeSize. */
923 1.1.1.2 mrg {
924 1.1.1.2 mrg /* Find the end of the first argument. We want to return the
925 1.1.1.2 mrg first argument spec. */
926 1.1.1.2 mrg const char *type = method->method_types;
927 1.1.1.2 mrg if (*type == '\0')
928 1.1.1.2 mrg return;
929 1.1.1.2 mrg type = objc_skip_argspec (type);
930 1.1.1.2 mrg argumentTypeSize = type - method->method_types;
931 1.1.1.2 mrg if (argumentTypeSize > returnValueSize)
932 1.1.1.2 mrg argumentTypeSize = returnValueSize;
933 1.1.1.2 mrg }
934 1.1.1.2 mrg /* Copy the argument at the beginning of the string. */
935 1.1.1.2 mrg memcpy (returnValue, method->method_types, argumentTypeSize);
936 1.1.1.2 mrg }
937 1.1 mrg }
938 1.1 mrg
939 1.1.1.2 mrg void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
940 1.1.1.2 mrg char *returnValue, size_t returnValueSize)
941 1.1 mrg {
942 1.1.1.2 mrg if (returnValue == NULL || returnValueSize == 0)
943 1.1.1.2 mrg return;
944 1.1 mrg
945 1.1.1.2 mrg /* Zero the string; we'll then write the argument type at the
946 1.1.1.2 mrg beginning of it, if needed. */
947 1.1.1.2 mrg memset (returnValue, 0, returnValueSize);
948 1.1 mrg
949 1.1.1.2 mrg if (method == NULL)
950 1.1.1.2 mrg return;
951 1.1.1.2 mrg else
952 1.1.1.2 mrg {
953 1.1.1.2 mrg const char *returnValueStart;
954 1.1.1.2 mrg size_t argumentTypeSize;
955 1.1 mrg
956 1.1.1.2 mrg /* Determine returnValueStart and argumentTypeSize. */
957 1.1.1.2 mrg {
958 1.1.1.2 mrg const char *type = method->method_types;
959 1.1 mrg
960 1.1.1.2 mrg /* Skip the first argument (return type). */
961 1.1.1.2 mrg type = objc_skip_argspec (type);
962 1.1 mrg
963 1.1.1.2 mrg /* Now keep skipping arguments until we get to
964 1.1.1.2 mrg argumentNumber. */
965 1.1.1.2 mrg while (argumentNumber > 0)
966 1.1.1.2 mrg {
967 1.1.1.2 mrg /* We are supposed to skip an argument, but the string is
968 1.1.1.2 mrg finished. This means we were asked for a non-existing
969 1.1.1.2 mrg argument. */
970 1.1.1.2 mrg if (*type == '\0')
971 1.1.1.2 mrg return;
972 1.1.1.2 mrg
973 1.1.1.2 mrg type = objc_skip_argspec (type);
974 1.1.1.2 mrg argumentNumber--;
975 1.1.1.2 mrg }
976 1.1.1.2 mrg
977 1.1.1.2 mrg /* If the argument does not exist, it's game over. */
978 1.1.1.2 mrg if (*type == '\0')
979 1.1.1.2 mrg return;
980 1.1.1.2 mrg
981 1.1.1.2 mrg returnValueStart = type;
982 1.1.1.2 mrg type = objc_skip_argspec (type);
983 1.1.1.2 mrg argumentTypeSize = type - returnValueStart;
984 1.1.1.2 mrg if (argumentTypeSize > returnValueSize)
985 1.1.1.2 mrg argumentTypeSize = returnValueSize;
986 1.1.1.2 mrg }
987 1.1.1.2 mrg /* Copy the argument at the beginning of the string. */
988 1.1.1.2 mrg memcpy (returnValue, returnValueStart, argumentTypeSize);
989 1.1.1.2 mrg }
990 1.1.1.2 mrg }
991 1.1 mrg
992 1.1.1.2 mrg unsigned int
993 1.1.1.2 mrg method_getNumberOfArguments (struct objc_method *method)
994 1.1.1.2 mrg {
995 1.1.1.2 mrg if (method == NULL)
996 1.1.1.2 mrg return 0;
997 1.1 mrg else
998 1.1.1.2 mrg {
999 1.1.1.2 mrg unsigned int i = 0;
1000 1.1.1.2 mrg const char *type = method->method_types;
1001 1.1.1.2 mrg while (*type)
1002 1.1.1.2 mrg {
1003 1.1.1.2 mrg type = objc_skip_argspec (type);
1004 1.1.1.2 mrg i += 1;
1005 1.1.1.2 mrg }
1006 1.1.1.2 mrg
1007 1.1.1.2 mrg if (i == 0)
1008 1.1.1.2 mrg {
1009 1.1.1.2 mrg /* This could only happen if method_types is invalid; in
1010 1.1.1.2 mrg that case, return 0. */
1011 1.1.1.2 mrg return 0;
1012 1.1.1.2 mrg }
1013 1.1.1.2 mrg else
1014 1.1.1.2 mrg {
1015 1.1.1.2 mrg /* Remove the return type. */
1016 1.1.1.2 mrg return (i - 1);
1017 1.1.1.2 mrg }
1018 1.1.1.2 mrg }
1019 1.1 mrg }
1020 1.1 mrg
1021 1.1 mrg unsigned
1022 1.1 mrg objc_get_type_qualifiers (const char *type)
1023 1.1 mrg {
1024 1.1 mrg unsigned res = 0;
1025 1.1 mrg BOOL flag = YES;
1026 1.1 mrg
1027 1.1 mrg while (flag)
1028 1.1 mrg switch (*type++)
1029 1.1 mrg {
1030 1.1.1.2 mrg case _C_CONST: res |= _F_CONST; break;
1031 1.1.1.2 mrg case _C_IN: res |= _F_IN; break;
1032 1.1.1.2 mrg case _C_INOUT: res |= _F_INOUT; break;
1033 1.1.1.2 mrg case _C_OUT: res |= _F_OUT; break;
1034 1.1.1.2 mrg case _C_BYCOPY: res |= _F_BYCOPY; break;
1035 1.1.1.2 mrg case _C_BYREF: res |= _F_BYREF; break;
1036 1.1.1.2 mrg case _C_ONEWAY: res |= _F_ONEWAY; break;
1037 1.1 mrg case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1038 1.1 mrg default: flag = NO;
1039 1.1 mrg }
1040 1.1 mrg
1041 1.1 mrg return res;
1042 1.1 mrg }
1043 1.1 mrg
1044 1.1 mrg /* The following three functions can be used to determine how a
1045 1.1 mrg structure is laid out by the compiler. For example:
1046 1.1 mrg
1047 1.1 mrg struct objc_struct_layout layout;
1048 1.1 mrg int i;
1049 1.1 mrg
1050 1.1 mrg objc_layout_structure (type, &layout);
1051 1.1 mrg while (objc_layout_structure_next_member (&layout))
1052 1.1 mrg {
1053 1.1 mrg int position, align;
1054 1.1 mrg const char *type;
1055 1.1 mrg
1056 1.1 mrg objc_layout_structure_get_info (&layout, &position, &align, &type);
1057 1.1 mrg printf ("element %d has offset %d, alignment %d\n",
1058 1.1 mrg i++, position, align);
1059 1.1 mrg }
1060 1.1 mrg
1061 1.1 mrg These functions are used by objc_sizeof_type and objc_alignof_type
1062 1.1 mrg functions to compute the size and alignment of structures. The
1063 1.1 mrg previous method of computing the size and alignment of a structure
1064 1.1 mrg was not working on some architectures, particulary on AIX, and in
1065 1.1.1.2 mrg the presence of bitfields inside the structure. */
1066 1.1 mrg void
1067 1.1 mrg objc_layout_structure (const char *type,
1068 1.1.1.2 mrg struct objc_struct_layout *layout)
1069 1.1 mrg {
1070 1.1 mrg const char *ntype;
1071 1.1 mrg
1072 1.1 mrg if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1073 1.1 mrg {
1074 1.1.1.2 mrg _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1075 1.1.1.2 mrg type);
1076 1.1 mrg }
1077 1.1 mrg
1078 1.1 mrg type ++;
1079 1.1 mrg layout->original_type = type;
1080 1.1 mrg
1081 1.1 mrg /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1082 1.1 mrg ntype = type;
1083 1.1 mrg while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1084 1.1 mrg && *ntype++ != '=')
1085 1.1 mrg /* do nothing */;
1086 1.1 mrg
1087 1.1 mrg /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1088 1.1 mrg if (*(ntype - 1) == '=')
1089 1.1 mrg type = ntype;
1090 1.1 mrg
1091 1.1 mrg layout->type = type;
1092 1.1 mrg layout->prev_type = NULL;
1093 1.1 mrg layout->record_size = 0;
1094 1.1 mrg layout->record_align = BITS_PER_UNIT;
1095 1.1 mrg
1096 1.1 mrg layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1097 1.1 mrg }
1098 1.1 mrg
1099 1.1 mrg BOOL
1100 1.1 mrg objc_layout_structure_next_member (struct objc_struct_layout *layout)
1101 1.1 mrg {
1102 1.1 mrg register int desired_align = 0;
1103 1.1 mrg
1104 1.1 mrg /* The following are used only if the field is a bitfield */
1105 1.1 mrg register const char *bfld_type = 0;
1106 1.1 mrg register int bfld_type_align = 0, bfld_field_size = 0;
1107 1.1 mrg
1108 1.1 mrg /* The current type without the type qualifiers */
1109 1.1 mrg const char *type;
1110 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1111 1.1 mrg
1112 1.1 mrg /* Add the size of the previous field to the size of the record. */
1113 1.1 mrg if (layout->prev_type)
1114 1.1 mrg {
1115 1.1 mrg type = objc_skip_type_qualifiers (layout->prev_type);
1116 1.1 mrg if (unionp)
1117 1.1 mrg layout->record_size = MAX (layout->record_size,
1118 1.1 mrg objc_sizeof_type (type) * BITS_PER_UNIT);
1119 1.1 mrg
1120 1.1 mrg else if (*type != _C_BFLD)
1121 1.1 mrg layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
1122 1.1 mrg else {
1123 1.1 mrg /* Get the bitfield's type */
1124 1.1 mrg for (bfld_type = type + 1;
1125 1.1 mrg isdigit ((unsigned char)*bfld_type);
1126 1.1 mrg bfld_type++)
1127 1.1 mrg /* do nothing */;
1128 1.1 mrg
1129 1.1 mrg bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1130 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1131 1.1 mrg layout->record_size += bfld_field_size;
1132 1.1 mrg }
1133 1.1 mrg }
1134 1.1 mrg
1135 1.1 mrg if ((unionp && *layout->type == _C_UNION_E)
1136 1.1 mrg || (!unionp && *layout->type == _C_STRUCT_E))
1137 1.1 mrg return NO;
1138 1.1 mrg
1139 1.1 mrg /* Skip the variable name if any */
1140 1.1.1.2 mrg layout->type = objc_skip_variable_name (layout->type);
1141 1.1 mrg type = objc_skip_type_qualifiers (layout->type);
1142 1.1 mrg
1143 1.1 mrg if (*type != _C_BFLD)
1144 1.1 mrg desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
1145 1.1 mrg else
1146 1.1 mrg {
1147 1.1 mrg desired_align = 1;
1148 1.1 mrg /* Skip the bitfield's offset */
1149 1.1 mrg for (bfld_type = type + 1;
1150 1.1 mrg isdigit ((unsigned char) *bfld_type);
1151 1.1 mrg bfld_type++)
1152 1.1 mrg /* do nothing */;
1153 1.1 mrg
1154 1.1 mrg bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1155 1.1 mrg bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1156 1.1 mrg }
1157 1.1 mrg
1158 1.1.1.2 mrg /* The following won't work for vectors. */
1159 1.1 mrg #ifdef BIGGEST_FIELD_ALIGNMENT
1160 1.1 mrg desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1161 1.1 mrg #endif
1162 1.1 mrg #ifdef ADJUST_FIELD_ALIGN
1163 1.1 mrg desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
1164 1.1 mrg #endif
1165 1.1 mrg
1166 1.1 mrg /* Record must have at least as much alignment as any field.
1167 1.1 mrg Otherwise, the alignment of the field within the record
1168 1.1 mrg is meaningless. */
1169 1.1 mrg #ifndef PCC_BITFIELD_TYPE_MATTERS
1170 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1171 1.1 mrg #else /* PCC_BITFIELD_TYPE_MATTERS */
1172 1.1 mrg if (*type == _C_BFLD)
1173 1.1 mrg {
1174 1.1 mrg /* For these machines, a zero-length field does not
1175 1.1 mrg affect the alignment of the structure as a whole.
1176 1.1 mrg It does, however, affect the alignment of the next field
1177 1.1 mrg within the structure. */
1178 1.1 mrg if (bfld_field_size)
1179 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1180 1.1 mrg else
1181 1.1 mrg desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1182 1.1 mrg
1183 1.1 mrg /* A named bit field of declared type `int'
1184 1.1 mrg forces the entire structure to have `int' alignment.
1185 1.1 mrg Q1: How is encoded this thing and how to check for it?
1186 1.1 mrg Q2: How to determine maximum_field_alignment at runtime? */
1187 1.1 mrg
1188 1.1 mrg /* if (DECL_NAME (field) != 0) */
1189 1.1 mrg {
1190 1.1 mrg int type_align = bfld_type_align;
1191 1.1 mrg #if 0
1192 1.1 mrg if (maximum_field_alignment != 0)
1193 1.1 mrg type_align = MIN (type_align, maximum_field_alignment);
1194 1.1 mrg else if (DECL_PACKED (field))
1195 1.1 mrg type_align = MIN (type_align, BITS_PER_UNIT);
1196 1.1 mrg #endif
1197 1.1 mrg
1198 1.1 mrg layout->record_align = MAX (layout->record_align, type_align);
1199 1.1 mrg }
1200 1.1 mrg }
1201 1.1 mrg else
1202 1.1 mrg layout->record_align = MAX (layout->record_align, desired_align);
1203 1.1 mrg #endif /* PCC_BITFIELD_TYPE_MATTERS */
1204 1.1 mrg
1205 1.1 mrg /* Does this field automatically have alignment it needs
1206 1.1 mrg by virtue of the fields that precede it and the record's
1207 1.1 mrg own alignment? */
1208 1.1 mrg
1209 1.1 mrg if (*type == _C_BFLD)
1210 1.1 mrg layout->record_size = atoi (type + 1);
1211 1.1 mrg else if (layout->record_size % desired_align != 0)
1212 1.1 mrg {
1213 1.1 mrg /* No, we need to skip space before this field.
1214 1.1 mrg Bump the cumulative size to multiple of field alignment. */
1215 1.1 mrg layout->record_size = ROUND (layout->record_size, desired_align);
1216 1.1 mrg }
1217 1.1 mrg
1218 1.1 mrg /* Jump to the next field in record. */
1219 1.1 mrg
1220 1.1 mrg layout->prev_type = layout->type;
1221 1.1 mrg layout->type = objc_skip_typespec (layout->type); /* skip component */
1222 1.1 mrg
1223 1.1 mrg return YES;
1224 1.1 mrg }
1225 1.1 mrg
1226 1.1 mrg void objc_layout_finish_structure (struct objc_struct_layout *layout,
1227 1.1 mrg unsigned int *size,
1228 1.1 mrg unsigned int *align)
1229 1.1 mrg {
1230 1.1 mrg BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1231 1.1 mrg if (layout->type
1232 1.1 mrg && ((!unionp && *layout->type == _C_STRUCT_E)
1233 1.1 mrg || (unionp && *layout->type == _C_UNION_E)))
1234 1.1 mrg {
1235 1.1 mrg /* Work out the alignment of the record as one expression and store
1236 1.1 mrg in the record type. Round it up to a multiple of the record's
1237 1.1 mrg alignment. */
1238 1.1 mrg #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1239 1.1 mrg layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1240 1.1 mrg 1,
1241 1.1 mrg layout->record_align);
1242 1.1 mrg #else
1243 1.1 mrg layout->record_align = MAX (1, layout->record_align);
1244 1.1 mrg #endif
1245 1.1 mrg
1246 1.1 mrg #ifdef ROUND_TYPE_SIZE
1247 1.1 mrg layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
1248 1.1 mrg layout->record_size,
1249 1.1 mrg layout->record_align);
1250 1.1 mrg #else
1251 1.1 mrg /* Round the size up to be a multiple of the required alignment */
1252 1.1 mrg layout->record_size = ROUND (layout->record_size, layout->record_align);
1253 1.1 mrg #endif
1254 1.1 mrg
1255 1.1 mrg layout->type = NULL;
1256 1.1 mrg }
1257 1.1 mrg if (size)
1258 1.1 mrg *size = layout->record_size / BITS_PER_UNIT;
1259 1.1 mrg if (align)
1260 1.1 mrg *align = layout->record_align / BITS_PER_UNIT;
1261 1.1 mrg }
1262 1.1 mrg
1263 1.1 mrg void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1264 1.1 mrg unsigned int *offset,
1265 1.1 mrg unsigned int *align,
1266 1.1 mrg const char **type)
1267 1.1 mrg {
1268 1.1 mrg if (offset)
1269 1.1 mrg *offset = layout->record_size / BITS_PER_UNIT;
1270 1.1 mrg if (align)
1271 1.1 mrg *align = layout->record_align / BITS_PER_UNIT;
1272 1.1 mrg if (type)
1273 1.1 mrg *type = layout->prev_type;
1274 1.1 mrg }
1275