1 /* Encoding of types for Objective C.
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 Author: Kresten Krab Thorup
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 /* As a special exception, if you link this library with files
23 compiled with GCC to produce an executable, this does not cause
24 the resulting executable to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
31 ({ typeof(X) __x = (X), __y = (Y); \
32 (__x > __y ? __x : __y); })
35 ({ typeof(X) __x = (X), __y = (Y); \
36 (__x < __y ? __x : __y); })
39 ({ typeof(V) __v=(V); typeof(A) __a=(A); \
40 __a*((__v+__a-1)/__a); })
44 atoi (const char* str)
48 while (isdigit (*str))
49 res *= 10, res += (*str++ - '0');
55 return the size of an object specified by type
59 objc_sizeof_type(const char* type)
67 return sizeof(Class*);
79 return sizeof(unsigned char);
87 return sizeof(unsigned short);
95 return sizeof(unsigned int);
103 return sizeof(unsigned long);
109 return sizeof(char*);
114 int len = atoi(type+1);
115 while (isdigit(*++type));
116 return len*objc_aligned_size (type);
124 while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
125 while (*type != _C_STRUCT_E);
127 align = objc_alignof_type (type); /* padd to alignment */
128 acc_size += ROUND (acc_size, align);
129 acc_size += objc_sizeof_type (type); /* add component size */
130 type = objc_skip_typespec (type); /* skip component */
138 while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
139 while (*type != _C_UNION_E)
141 max_size = MAX (max_size, objc_sizeof_type (type));
142 type = objc_skip_typespec (type);
154 Return the alignment of an object specified by type
158 objc_alignof_type(const char* type)
162 return __alignof__(id);
166 return __alignof__(Class*);
170 return __alignof__(SEL);
174 return __alignof__(char);
178 return __alignof__(unsigned char);
182 return __alignof__(short);
186 return __alignof__(unsigned short);
190 return __alignof__(int);
194 return __alignof__(unsigned int);
198 return __alignof__(long);
202 return __alignof__(unsigned long);
207 return __alignof__(char*);
211 while (isdigit(*++type)) /* do nothing */;
212 return objc_alignof_type (type);
216 struct { int x; double y; } fooalign;
217 while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
218 if (*type != _C_STRUCT_E)
219 return MAX (objc_alignof_type (type), __alignof__ (fooalign));
221 return __alignof__ (fooalign);
227 while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
228 while (*type != _C_UNION_E)
230 maxalign = MAX (maxalign, objc_alignof_type (type));
231 type = objc_skip_typespec (type);
242 The aligned size if the size rounded up to the nearest alignment.
246 objc_aligned_size (const char* type)
248 int size = objc_sizeof_type (type);
249 int align = objc_alignof_type (type);
250 return ROUND (size, align);
254 The size rounded up to the nearest integral of the wordsize, taken
255 to be the size of a void*.
259 objc_promoted_size (const char* type)
261 int size = objc_sizeof_type (type);
262 int wordsize = sizeof (void*);
264 return ROUND (size, wordsize);
268 Skip type qualifiers. These may eventually precede typespecs
269 occuring in method prototype encodings.
273 objc_skip_type_qualifiers (const char* type)
275 while (*type == _C_CONST
279 || *type == _C_BYCOPY
280 || *type == _C_ONEWAY)
289 Skip one typespec element. If the typespec is prepended by type
290 qualifiers, these are skipped as well.
294 objc_skip_typespec (const char* type)
296 type = objc_skip_type_qualifiers (type);
301 /* An id may be annotated by the actual type if it is known
302 with the @"ClassName" syntax */
308 while (*++type != '"') /* do nothing */;
312 /* The following are one character type codes */
332 /* skip digits, typespec and closing ']' */
334 while(isdigit(*++type));
335 type = objc_skip_typespec(type);
336 if (*type == _C_ARY_E)
342 /* skip name, and elements until closing '}' */
344 while (*type != _C_STRUCT_E && *type++ != '=');
345 while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
349 /* skip name, and elements until closing ')' */
351 while (*type != _C_UNION_E && *type++ != '=');
352 while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
356 /* Just skip the following typespec */
358 return objc_skip_typespec (++type);
366 Skip an offset as part of a method encoding. This is prepended by a
367 '+' if the argument is passed in registers.
370 objc_skip_offset (const char* type)
372 if (*type == '+') type++;
373 while(isdigit(*++type));
378 Skip an argument specification of a method encoding.
381 objc_skip_argspec (const char* type)
383 type = objc_skip_typespec (type);
384 type = objc_skip_offset (type);
389 Return the number of arguments that the method MTH expects.
390 Note that all methods need two implicit arguments `self' and
394 method_get_number_of_arguments (struct objc_method* mth)
397 const char* type = mth->method_types;
400 type = objc_skip_argspec (type);
407 Return the size of the argument block needed on the stack to invoke
408 the method MTH. This may be zero, if all arguments are passed in
413 method_get_sizeof_arguments (struct objc_method* mth)
415 const char* type = objc_skip_typespec (mth->method_types);
420 Return a pointer to the next argument of ARGFRAME. type points to
421 the last argument. Typical use of this look like:
425 for (datum = method_get_first_argument (method, argframe, &type);
426 datum; datum = method_get_next_argument (argframe, &type))
428 unsigned flags = objc_get_type_qualifiers (type);
429 type = objc_skip_type_qualifiers (type);
431 [portal encodeData: datum ofType: type];
434 if ((flags & _F_IN) == _F_IN)
435 [portal encodeData: *(char**)datum ofType: ++type];
442 method_get_next_argument (arglist_t argframe,
445 const char *t = objc_skip_argspec (*type);
451 t = objc_skip_typespec (t);
454 return argframe->arg_regs + atoi (++t);
456 return argframe->arg_ptr + atoi (t);
460 Return a pointer to the value of the first argument of the method
461 described in M with the given argumentframe ARGFRAME. The type
462 is returned in TYPE. type must be passed to successive calls of
463 method_get_next_argument.
466 method_get_first_argument (struct objc_method* m,
470 *type = m->method_types;
471 return method_get_next_argument (argframe, type);
475 Return a pointer to the ARGth argument of the method
476 M from the frame ARGFRAME. The type of the argument
477 is returned in the value-result argument TYPE
481 method_get_nth_argument (struct objc_method* m,
482 arglist_t argframe, int arg,
485 const char* t = objc_skip_argspec (m->method_types);
487 if (arg > method_get_number_of_arguments (m))
491 t = objc_skip_argspec (t);
494 t = objc_skip_typespec (t);
497 return argframe->arg_regs + atoi (++t);
499 return argframe->arg_ptr + atoi (t);
503 objc_get_type_qualifiers (const char* type)
511 case _C_CONST: res |= _F_CONST; break;
512 case _C_IN: res |= _F_IN; break;
513 case _C_INOUT: res |= _F_INOUT; break;
514 case _C_OUT: res |= _F_OUT; break;
515 case _C_BYCOPY: res |= _F_BYCOPY; break;
516 case _C_ONEWAY: res |= _F_ONEWAY; break;