annotate libobjc/encoding.c @ 120:f93fa5091070

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