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