annotate libobjc/encoding.c @ 158:494b0b89df80 default tip

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