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