Do not do src->dest copy if register would not be allocated a normal register
[official-gcc.git] / gcc / objc / encoding.c
blobc90e914f5018ce2e60631dc7a29a35aefad33062
1 /* Encoding of types for Objective C.
2 Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, 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. */
28 #include "encoding.h"
30 #define MAX(X, Y) \
31 ({ typeof(X) __x = (X), __y = (Y); \
32 (__x > __y ? __x : __y); })
34 #define MIN(X, Y) \
35 ({ typeof(X) __x = (X), __y = (Y); \
36 (__x < __y ? __x : __y); })
38 #define ROUND(V, A) \
39 ({ typeof(V) __v=(V); typeof(A) __a=(A); \
40 __a*((__v+__a-1)/__a); })
43 static inline int
44 atoi (const char* str)
46 int res = 0;
48 while (isdigit (*str))
49 res *= 10, res += (*str++ - '0');
51 return res;
55 return the size of an object specified by type
58 int
59 objc_sizeof_type(const char* type)
61 switch(*type) {
62 case _C_ID:
63 return sizeof(id);
64 break;
66 case _C_CLASS:
67 return sizeof(Class);
68 break;
70 case _C_SEL:
71 return sizeof(SEL);
72 break;
74 case _C_CHR:
75 return sizeof(char);
76 break;
78 case _C_UCHR:
79 return sizeof(unsigned char);
80 break;
82 case _C_SHT:
83 return sizeof(short);
84 break;
86 case _C_USHT:
87 return sizeof(unsigned short);
88 break;
90 case _C_INT:
91 return sizeof(int);
92 break;
94 case _C_UINT:
95 return sizeof(unsigned int);
96 break;
98 case _C_LNG:
99 return sizeof(long);
100 break;
102 case _C_ULNG:
103 return sizeof(unsigned long);
104 break;
106 case _C_FLT:
107 return sizeof(float);
108 break;
110 case _C_DBL:
111 return sizeof(double);
112 break;
114 case _C_PTR:
115 case _C_ATOM:
116 case _C_CHARPTR:
117 return sizeof(char*);
118 break;
120 case _C_ARY_B:
122 int len = atoi(type+1);
123 while (isdigit(*++type));
124 return len*objc_aligned_size (type);
126 break;
128 case _C_STRUCT_B:
130 int acc_size = 0;
131 int align;
132 while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
133 while (*type != _C_STRUCT_E)
135 align = objc_alignof_type (type); /* padd to alignment */
136 acc_size = ROUND (acc_size, align);
137 acc_size += objc_sizeof_type (type); /* add component size */
138 type = objc_skip_typespec (type); /* skip component */
140 return acc_size;
143 case _C_UNION_B:
145 int max_size = 0;
146 while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
147 while (*type != _C_UNION_E)
149 max_size = MAX (max_size, objc_sizeof_type (type));
150 type = objc_skip_typespec (type);
152 return max_size;
155 default:
156 objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
162 Return the alignment of an object specified by type
166 objc_alignof_type(const char* type)
168 switch(*type) {
169 case _C_ID:
170 return __alignof__(id);
171 break;
173 case _C_CLASS:
174 return __alignof__(Class);
175 break;
177 case _C_SEL:
178 return __alignof__(SEL);
179 break;
181 case _C_CHR:
182 return __alignof__(char);
183 break;
185 case _C_UCHR:
186 return __alignof__(unsigned char);
187 break;
189 case _C_SHT:
190 return __alignof__(short);
191 break;
193 case _C_USHT:
194 return __alignof__(unsigned short);
195 break;
197 case _C_INT:
198 return __alignof__(int);
199 break;
201 case _C_UINT:
202 return __alignof__(unsigned int);
203 break;
205 case _C_LNG:
206 return __alignof__(long);
207 break;
209 case _C_ULNG:
210 return __alignof__(unsigned long);
211 break;
213 case _C_FLT:
214 return __alignof__(float);
215 break;
217 case _C_DBL:
218 return __alignof__(double);
219 break;
221 case _C_PTR:
222 case _C_ATOM:
223 case _C_CHARPTR:
224 return __alignof__(char*);
225 break;
227 case _C_ARY_B:
228 while (isdigit(*++type)) /* do nothing */;
229 return objc_alignof_type (type);
231 case _C_STRUCT_B:
233 struct { int x; double y; } fooalign;
234 while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
235 if (*type != _C_STRUCT_E)
236 return MAX (objc_alignof_type (type), __alignof__ (fooalign));
237 else
238 return __alignof__ (fooalign);
241 case _C_UNION_B:
243 int maxalign = 0;
244 while (*type != _C_UNION_E && *type++ != '=') /* do nothing */;
245 while (*type != _C_UNION_E)
247 maxalign = MAX (maxalign, objc_alignof_type (type));
248 type = objc_skip_typespec (type);
250 return maxalign;
253 default:
254 objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
259 The aligned size if the size rounded up to the nearest alignment.
263 objc_aligned_size (const char* type)
265 int size = objc_sizeof_type (type);
266 int align = objc_alignof_type (type);
267 return ROUND (size, align);
271 The size rounded up to the nearest integral of the wordsize, taken
272 to be the size of a void*.
275 int
276 objc_promoted_size (const char* type)
278 int size = objc_sizeof_type (type);
279 int wordsize = sizeof (void*);
281 return ROUND (size, wordsize);
285 Skip type qualifiers. These may eventually precede typespecs
286 occurring in method prototype encodings.
289 inline const char*
290 objc_skip_type_qualifiers (const char* type)
292 while (*type == _C_CONST
293 || *type == _C_IN
294 || *type == _C_INOUT
295 || *type == _C_OUT
296 || *type == _C_BYCOPY
297 || *type == _C_ONEWAY)
299 type += 1;
301 return type;
306 Skip one typespec element. If the typespec is prepended by type
307 qualifiers, these are skipped as well.
310 const char*
311 objc_skip_typespec (const char* type)
313 type = objc_skip_type_qualifiers (type);
315 switch (*type) {
317 case _C_ID:
318 /* An id may be annotated by the actual type if it is known
319 with the @"ClassName" syntax */
321 if (*++type != '"')
322 return type;
323 else
325 while (*++type != '"') /* do nothing */;
326 return type + 1;
329 /* The following are one character type codes */
330 case _C_CLASS:
331 case _C_SEL:
332 case _C_CHR:
333 case _C_UCHR:
334 case _C_CHARPTR:
335 case _C_ATOM:
336 case _C_SHT:
337 case _C_USHT:
338 case _C_INT:
339 case _C_UINT:
340 case _C_LNG:
341 case _C_ULNG:
342 case _C_FLT:
343 case _C_DBL:
344 case _C_VOID:
345 case _C_UNDEF:
346 return ++type;
347 break;
349 case _C_ARY_B:
350 /* skip digits, typespec and closing ']' */
352 while(isdigit(*++type));
353 type = objc_skip_typespec(type);
354 if (*type == _C_ARY_E)
355 return ++type;
356 else
357 objc_error(nil, OBJC_ERR_BAD_TYPE, "bad array type %s\n", type);
359 case _C_STRUCT_B:
360 /* skip name, and elements until closing '}' */
362 while (*type != _C_STRUCT_E && *type++ != '=');
363 while (*type != _C_STRUCT_E) { type = objc_skip_typespec (type); }
364 return ++type;
366 case _C_UNION_B:
367 /* skip name, and elements until closing ')' */
369 while (*type != _C_UNION_E && *type++ != '=');
370 while (*type != _C_UNION_E) { type = objc_skip_typespec (type); }
371 return ++type;
373 case _C_PTR:
374 /* Just skip the following typespec */
376 return objc_skip_typespec (++type);
378 default:
379 objc_error(nil, OBJC_ERR_BAD_TYPE, "unknown type %s\n", type);
384 Skip an offset as part of a method encoding. This is prepended by a
385 '+' if the argument is passed in registers.
387 inline const char*
388 objc_skip_offset (const char* type)
390 if (*type == '+') type++;
391 while(isdigit(*++type));
392 return type;
396 Skip an argument specification of a method encoding.
398 const char*
399 objc_skip_argspec (const char* type)
401 type = objc_skip_typespec (type);
402 type = objc_skip_offset (type);
403 return type;
407 Return the number of arguments that the method MTH expects.
408 Note that all methods need two implicit arguments `self' and
409 `_cmd'.
412 method_get_number_of_arguments (struct objc_method* mth)
414 int i = 0;
415 const char* type = mth->method_types;
416 while (*type)
418 type = objc_skip_argspec (type);
419 i += 1;
421 return i - 1;
425 Return the size of the argument block needed on the stack to invoke
426 the method MTH. This may be zero, if all arguments are passed in
427 registers.
431 method_get_sizeof_arguments (struct objc_method* mth)
433 const char* type = objc_skip_typespec (mth->method_types);
434 return atoi (type);
438 Return a pointer to the next argument of ARGFRAME. type points to
439 the last argument. Typical use of this look like:
442 char *datum, *type;
443 for (datum = method_get_first_argument (method, argframe, &type);
444 datum; datum = method_get_next_argument (argframe, &type))
446 unsigned flags = objc_get_type_qualifiers (type);
447 type = objc_skip_type_qualifiers (type);
448 if (*type != _C_PTR)
449 [portal encodeData: datum ofType: type];
450 else
452 if ((flags & _F_IN) == _F_IN)
453 [portal encodeData: *(char**)datum ofType: ++type];
459 char*
460 method_get_next_argument (arglist_t argframe,
461 const char **type)
463 const char *t = objc_skip_argspec (*type);
465 if (*t == '\0')
466 return 0;
468 *type = t;
469 t = objc_skip_typespec (t);
471 if (*t == '+')
472 return argframe->arg_regs + atoi (++t);
473 else
474 return argframe->arg_ptr + atoi (t);
478 Return a pointer to the value of the first argument of the method
479 described in M with the given argumentframe ARGFRAME. The type
480 is returned in TYPE. type must be passed to successive calls of
481 method_get_next_argument.
483 char*
484 method_get_first_argument (struct objc_method* m,
485 arglist_t argframe,
486 const char** type)
488 *type = m->method_types;
489 return method_get_next_argument (argframe, type);
493 Return a pointer to the ARGth argument of the method
494 M from the frame ARGFRAME. The type of the argument
495 is returned in the value-result argument TYPE
498 char*
499 method_get_nth_argument (struct objc_method* m,
500 arglist_t argframe, int arg,
501 const char **type)
503 const char* t = objc_skip_argspec (m->method_types);
505 if (arg > method_get_number_of_arguments (m))
506 return 0;
508 while (arg--)
509 t = objc_skip_argspec (t);
511 *type = t;
512 t = objc_skip_typespec (t);
514 if (*t == '+')
515 return argframe->arg_regs + atoi (++t);
516 else
517 return argframe->arg_ptr + atoi (t);
520 unsigned
521 objc_get_type_qualifiers (const char* type)
523 unsigned res = 0;
524 BOOL flag = YES;
526 while (flag)
527 switch (*type++)
529 case _C_CONST: res |= _F_CONST; break;
530 case _C_IN: res |= _F_IN; break;
531 case _C_INOUT: res |= _F_INOUT; break;
532 case _C_OUT: res |= _F_OUT; break;
533 case _C_BYCOPY: res |= _F_BYCOPY; break;
534 case _C_ONEWAY: res |= _F_ONEWAY; break;
535 default: flag = NO;
538 return res;