target-supports.exp (check_effective_target_arm_dsp): New.
[official-gcc.git] / libobjc / encoding.c
blobbd8b67e0e8b70314b6ac55e7619f661c122594a4
1 /* Encoding of types for Objective C.
2 Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000, 2002, 2004, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Kresten Krab Thorup
5 Bitfield support by Ovidiu Predescu
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
28 /* FIXME: This file has no business including tm.h. */
30 /* FIXME: This file contains functions that will abort the entire
31 program if they fail. Is that really needed ? */
33 #include "objc-private/common.h"
34 #include "objc-private/error.h"
35 #include "tconfig.h"
36 #include "coretypes.h"
37 #include "tm.h"
38 #include "objc/runtime.h"
39 #include "objc-private/module-abi-8.h" /* For struct objc_method */
40 #include <stdlib.h>
41 #include <ctype.h>
42 #include <string.h> /* For memcpy. */
44 #undef MAX
45 #define MAX(X, Y) \
46 ({ typeof (X) __x = (X), __y = (Y); \
47 (__x > __y ? __x : __y); })
49 #undef MIN
50 #define MIN(X, Y) \
51 ({ typeof (X) __x = (X), __y = (Y); \
52 (__x < __y ? __x : __y); })
54 #undef ROUND
55 #define ROUND(V, A) \
56 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
57 __a * ((__v+__a - 1)/__a); })
60 /* Various hacks for objc_layout_record. These are used by the target
61 macros. */
63 #define TREE_CODE(TYPE) *(TYPE)
64 #define TREE_TYPE(TREE) (TREE)
66 #define RECORD_TYPE _C_STRUCT_B
67 #define UNION_TYPE _C_UNION_B
68 #define QUAL_UNION_TYPE _C_UNION_B
69 #define ARRAY_TYPE _C_ARY_B
71 #define REAL_TYPE _C_DBL
73 #define VECTOR_TYPE _C_VECTOR
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;})
81 #define DECL_MODE(TYPE) *(TYPE)
82 #define TYPE_MODE(TYPE) *(TYPE)
84 #define DFmode _C_DBL
86 #define strip_array_types(TYPE) ({const char *_field = (TYPE); \
87 while (*_field == _C_ARY_B)\
89 while (isdigit ((unsigned char)*++_field))\
92 _field;})
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. */
97 #ifndef BITS_PER_UNIT
98 #define BITS_PER_UNIT 8
99 #endif
100 #undef STRUCTURE_SIZE_BOUNDARY
101 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
103 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
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
108 static int __attribute__ ((__unused__)) not_target_flags = 0;
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)
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*. */
120 #if __MACH__
121 # if __LP64__
122 # undef TARGET_ALIGN_NATURAL
123 # define TARGET_ALIGN_NATURAL 1
124 # endif
126 /* On Darwin32, we need to recurse until we find the starting stuct type. */
127 static int
128 _darwin_rs6000_special_round_type_align (const char *struc, int comp, int spec)
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))
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;
148 default:
149 return MAX (comp, spec);
150 break;
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)))
157 #endif
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,
162 should look after the branch of 3.4 to fix this. */
163 #define rs6000_special_round_type_align(STRUCT, COMPUTED, SPECIFIED) \
164 ({ const char *_fields = TYPE_FIELDS (STRUCT); \
165 ((_fields != 0 \
166 && TYPE_MODE (strip_array_types (TREE_TYPE (_fields))) == DFmode) \
167 ? MAX (MAX (COMPUTED, SPECIFIED), 64) \
168 : MAX (COMPUTED, SPECIFIED));})
171 /* Skip a variable name, enclosed in quotes ("). */
172 static inline
173 const char *
174 objc_skip_variable_name (const char *type)
176 /* Skip the variable name if any. */
177 if (*type == '"')
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! */
181 /* Skip '"'. */
182 type++;
183 /* Skip to the next '"'. */
184 while (*type != '"')
185 type++;
186 /* Skip '"'. */
187 type++;
190 return type;
194 objc_sizeof_type (const char *type)
196 type = objc_skip_variable_name (type);
198 switch (*type) {
199 case _C_BOOL:
200 return sizeof (_Bool);
201 break;
203 case _C_ID:
204 return sizeof (id);
205 break;
207 case _C_CLASS:
208 return sizeof (Class);
209 break;
211 case _C_SEL:
212 return sizeof (SEL);
213 break;
215 case _C_CHR:
216 return sizeof (char);
217 break;
219 case _C_UCHR:
220 return sizeof (unsigned char);
221 break;
223 case _C_SHT:
224 return sizeof (short);
225 break;
227 case _C_USHT:
228 return sizeof (unsigned short);
229 break;
231 case _C_INT:
232 return sizeof (int);
233 break;
235 case _C_UINT:
236 return sizeof (unsigned int);
237 break;
239 case _C_LNG:
240 return sizeof (long);
241 break;
243 case _C_ULNG:
244 return sizeof (unsigned long);
245 break;
247 case _C_LNG_LNG:
248 return sizeof (long long);
249 break;
251 case _C_ULNG_LNG:
252 return sizeof (unsigned long long);
253 break;
255 case _C_FLT:
256 return sizeof (float);
257 break;
259 case _C_DBL:
260 return sizeof (double);
261 break;
263 case _C_LNG_DBL:
264 return sizeof (long double);
265 break;
267 case _C_VOID:
268 return sizeof (void);
269 break;
271 case _C_PTR:
272 case _C_ATOM:
273 case _C_CHARPTR:
274 return sizeof (char *);
275 break;
277 case _C_ARY_B:
279 int len = atoi (type + 1);
280 while (isdigit ((unsigned char)*++type))
282 return len * objc_aligned_size (type);
284 break;
286 case _C_VECTOR:
288 /* Skip the '!'. */
289 type++;
290 /* Skip the '['. */
291 type++;
293 /* The size in bytes is the following number. */
294 int size = atoi (type);
295 return size;
297 break;
299 case _C_BFLD:
301 /* The GNU encoding of bitfields is: b 'position' 'type'
302 'size'. */
303 int position, size;
304 int startByte, endByte;
306 position = atoi (type + 1);
307 while (isdigit ((unsigned char)*++type))
309 size = atoi (type + 1);
311 startByte = position / BITS_PER_UNIT;
312 endByte = (position + size) / BITS_PER_UNIT;
313 return endByte - startByte;
316 case _C_UNION_B:
317 case _C_STRUCT_B:
319 struct objc_struct_layout layout;
320 unsigned int size;
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);
327 return size;
330 case _C_COMPLEX:
332 type++; /* Skip after the 'j'. */
333 switch (*type)
335 case _C_CHR:
336 return sizeof (_Complex char);
337 break;
339 case _C_UCHR:
340 return sizeof (_Complex unsigned char);
341 break;
343 case _C_SHT:
344 return sizeof (_Complex short);
345 break;
347 case _C_USHT:
348 return sizeof (_Complex unsigned short);
349 break;
351 case _C_INT:
352 return sizeof (_Complex int);
353 break;
355 case _C_UINT:
356 return sizeof (_Complex unsigned int);
357 break;
359 case _C_LNG:
360 return sizeof (_Complex long);
361 break;
363 case _C_ULNG:
364 return sizeof (_Complex unsigned long);
365 break;
367 case _C_LNG_LNG:
368 return sizeof (_Complex long long);
369 break;
371 case _C_ULNG_LNG:
372 return sizeof (_Complex unsigned long long);
373 break;
375 case _C_FLT:
376 return sizeof (_Complex float);
377 break;
379 case _C_DBL:
380 return sizeof (_Complex double);
381 break;
383 case _C_LNG_DBL:
384 return sizeof (_Complex long double);
385 break;
387 default:
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).
393 _objc_abort ("unknown complex type %s\n", type);
394 return 0;
399 default:
401 _objc_abort ("unknown type %s\n", type);
402 return 0;
408 objc_alignof_type (const char *type)
410 type = objc_skip_variable_name (type);
412 switch (*type) {
413 case _C_BOOL:
414 return __alignof__ (_Bool);
415 break;
417 case _C_ID:
418 return __alignof__ (id);
419 break;
421 case _C_CLASS:
422 return __alignof__ (Class);
423 break;
425 case _C_SEL:
426 return __alignof__ (SEL);
427 break;
429 case _C_CHR:
430 return __alignof__ (char);
431 break;
433 case _C_UCHR:
434 return __alignof__ (unsigned char);
435 break;
437 case _C_SHT:
438 return __alignof__ (short);
439 break;
441 case _C_USHT:
442 return __alignof__ (unsigned short);
443 break;
445 case _C_INT:
446 return __alignof__ (int);
447 break;
449 case _C_UINT:
450 return __alignof__ (unsigned int);
451 break;
453 case _C_LNG:
454 return __alignof__ (long);
455 break;
457 case _C_ULNG:
458 return __alignof__ (unsigned long);
459 break;
461 case _C_LNG_LNG:
462 return __alignof__ (long long);
463 break;
465 case _C_ULNG_LNG:
466 return __alignof__ (unsigned long long);
467 break;
469 case _C_FLT:
470 return __alignof__ (float);
471 break;
473 case _C_DBL:
474 return __alignof__ (double);
475 break;
477 case _C_LNG_DBL:
478 return __alignof__ (long double);
479 break;
481 case _C_PTR:
482 case _C_ATOM:
483 case _C_CHARPTR:
484 return __alignof__ (char *);
485 break;
487 case _C_ARY_B:
488 while (isdigit ((unsigned char)*++type))
489 /* do nothing */;
490 return objc_alignof_type (type);
492 case _C_VECTOR:
494 /* Skip the '!'. */
495 type++;
496 /* Skip the '['. */
497 type++;
499 /* Skip the size. */
500 while (isdigit ((unsigned char)*type))
501 type++;
503 /* Skip the ','. */
504 type++;
506 /* The alignment in bytes is the following number. */
507 return atoi (type);
509 case _C_STRUCT_B:
510 case _C_UNION_B:
512 struct objc_struct_layout layout;
513 unsigned int align;
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);
520 return align;
524 case _C_COMPLEX:
526 type++; /* Skip after the 'j'. */
527 switch (*type)
529 case _C_CHR:
530 return __alignof__ (_Complex char);
531 break;
533 case _C_UCHR:
534 return __alignof__ (_Complex unsigned char);
535 break;
537 case _C_SHT:
538 return __alignof__ (_Complex short);
539 break;
541 case _C_USHT:
542 return __alignof__ (_Complex unsigned short);
543 break;
545 case _C_INT:
546 return __alignof__ (_Complex int);
547 break;
549 case _C_UINT:
550 return __alignof__ (_Complex unsigned int);
551 break;
553 case _C_LNG:
554 return __alignof__ (_Complex long);
555 break;
557 case _C_ULNG:
558 return __alignof__ (_Complex unsigned long);
559 break;
561 case _C_LNG_LNG:
562 return __alignof__ (_Complex long long);
563 break;
565 case _C_ULNG_LNG:
566 return __alignof__ (_Complex unsigned long long);
567 break;
569 case _C_FLT:
570 return __alignof__ (_Complex float);
571 break;
573 case _C_DBL:
574 return __alignof__ (_Complex double);
575 break;
577 case _C_LNG_DBL:
578 return __alignof__ (_Complex long double);
579 break;
581 default:
583 _objc_abort ("unknown complex type %s\n", type);
584 return 0;
589 default:
591 _objc_abort ("unknown type %s\n", type);
592 return 0;
598 objc_aligned_size (const char *type)
600 int size, align;
602 type = objc_skip_variable_name (type);
603 size = objc_sizeof_type (type);
604 align = objc_alignof_type (type);
606 return ROUND (size, align);
610 objc_promoted_size (const char *type)
612 int size, wordsize;
614 type = objc_skip_variable_name (type);
615 size = objc_sizeof_type (type);
616 wordsize = sizeof (void *);
618 return ROUND (size, wordsize);
621 inline
622 const char *
623 objc_skip_type_qualifiers (const char *type)
625 while (*type == _C_CONST
626 || *type == _C_IN
627 || *type == _C_INOUT
628 || *type == _C_OUT
629 || *type == _C_BYCOPY
630 || *type == _C_BYREF
631 || *type == _C_ONEWAY
632 || *type == _C_GCINVISIBLE)
634 type += 1;
636 return type;
639 inline
640 const char *
641 objc_skip_typespec (const char *type)
643 type = objc_skip_variable_name (type);
644 type = objc_skip_type_qualifiers (type);
646 switch (*type) {
648 case _C_ID:
649 /* An id may be annotated by the actual type if it is known
650 with the @"ClassName" syntax */
652 if (*++type != '"')
653 return type;
654 else
656 while (*++type != '"')
657 /* do nothing */;
658 return type + 1;
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:
673 case _C_BOOL:
674 case _C_ULNG:
675 case _C_LNG_LNG:
676 case _C_ULNG_LNG:
677 case _C_FLT:
678 case _C_DBL:
679 case _C_LNG_DBL:
680 case _C_VOID:
681 case _C_UNDEF:
682 return ++type;
683 break;
685 case _C_COMPLEX:
686 return type + 2;
687 break;
689 case _C_ARY_B:
690 /* skip digits, typespec and closing ']' */
691 while (isdigit ((unsigned char)*++type))
693 type = objc_skip_typespec (type);
694 if (*type == _C_ARY_E)
695 return ++type;
696 else
698 _objc_abort ("bad array type %s\n", type);
699 return 0;
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
722 _objc_abort ("bad vector type %s\n", type);
723 return 0;
726 case _C_BFLD:
727 /* The GNU encoding of bitfields is: b 'position' 'type'
728 'size'. */
729 while (isdigit ((unsigned char)*++type))
730 ; /* skip position */
731 while (isdigit ((unsigned char)*++type))
732 ; /* skip type and size */
733 return type;
735 case _C_STRUCT_B:
736 /* skip name, and elements until closing '}' */
738 while (*type != _C_STRUCT_E && *type++ != '=')
740 while (*type != _C_STRUCT_E)
742 type = objc_skip_typespec (type);
744 return ++type;
746 case _C_UNION_B:
747 /* skip name, and elements until closing ')' */
749 while (*type != _C_UNION_E && *type++ != '=')
751 while (*type != _C_UNION_E)
753 type = objc_skip_typespec (type);
755 return ++type;
757 case _C_PTR:
758 /* Just skip the following typespec */
760 return objc_skip_typespec (++type);
762 default:
764 _objc_abort ("unknown type %s\n", type);
765 return 0;
770 inline
771 const char *
772 objc_skip_offset (const char *type)
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. */
777 if (*type == '+')
778 type++;
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++;
786 /* Skip the digits that represent the offset. */
787 while (isdigit ((unsigned char) *type))
788 type++;
790 return type;
793 const char *
794 objc_skip_argspec (const char *type)
796 type = objc_skip_typespec (type);
797 type = objc_skip_offset (type);
798 return type;
801 char *
802 method_copyReturnType (struct objc_method *method)
804 if (method == NULL)
805 return 0;
806 else
808 char *returnValue;
809 size_t returnValueSize;
811 /* Determine returnValueSize. */
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;
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';
827 return returnValue;
831 char *
832 method_copyArgumentType (struct objc_method * method, unsigned int argumentNumber)
834 if (method == NULL)
835 return 0;
836 else
838 char *returnValue;
839 const char *returnValueStart;
840 size_t returnValueSize;
842 /* Determine returnValueStart and returnValueSize. */
844 const char *type = method->method_types;
846 /* Skip the first argument (return type). */
847 type = objc_skip_argspec (type);
849 /* Now keep skipping arguments until we get to
850 argumentNumber. */
851 while (argumentNumber > 0)
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;
859 type = objc_skip_argspec (type);
860 argumentNumber--;
863 /* If the argument does not exist, return NULL. */
864 if (*type == '\0')
865 return NULL;
867 returnValueStart = type;
868 type = objc_skip_argspec (type);
869 returnValueSize = type - returnValueStart + 1;
872 /* Copy the argument into returnValue. */
873 returnValue = malloc (sizeof (char) * returnValueSize);
874 memcpy (returnValue, returnValueStart, returnValueSize);
875 returnValue[returnValueSize - 1] = '\0';
877 return returnValue;
881 void method_getReturnType (struct objc_method * method, char *returnValue,
882 size_t returnValueSize)
884 if (returnValue == NULL || returnValueSize == 0)
885 return;
887 /* Zero the string; we'll then write the argument type at the
888 beginning of it, if needed. */
889 memset (returnValue, 0, returnValueSize);
891 if (method == NULL)
892 return;
893 else
895 size_t argumentTypeSize;
897 /* Determine argumentTypeSize. */
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;
909 /* Copy the argument at the beginning of the string. */
910 memcpy (returnValue, method->method_types, argumentTypeSize);
914 void method_getArgumentType (struct objc_method * method, unsigned int argumentNumber,
915 char *returnValue, size_t returnValueSize)
917 if (returnValue == NULL || returnValueSize == 0)
918 return;
920 /* Zero the string; we'll then write the argument type at the
921 beginning of it, if needed. */
922 memset (returnValue, 0, returnValueSize);
924 if (method == NULL)
925 return;
926 else
928 const char *returnValueStart;
929 size_t argumentTypeSize;
931 /* Determine returnValueStart and argumentTypeSize. */
933 const char *type = method->method_types;
935 /* Skip the first argument (return type). */
936 type = objc_skip_argspec (type);
938 /* Now keep skipping arguments until we get to
939 argumentNumber. */
940 while (argumentNumber > 0)
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;
948 type = objc_skip_argspec (type);
949 argumentNumber--;
952 /* If the argument does not exist, it's game over. */
953 if (*type == '\0')
954 return;
956 returnValueStart = type;
957 type = objc_skip_argspec (type);
958 argumentTypeSize = type - returnValueStart;
959 if (argumentTypeSize > returnValueSize)
960 argumentTypeSize = returnValueSize;
962 /* Copy the argument at the beginning of the string. */
963 memcpy (returnValue, returnValueStart, argumentTypeSize);
967 unsigned int
968 method_getNumberOfArguments (struct objc_method *method)
970 if (method == NULL)
971 return 0;
972 else
974 unsigned int i = 0;
975 const char *type = method->method_types;
976 while (*type)
978 type = objc_skip_argspec (type);
979 i += 1;
982 if (i == 0)
984 /* This could only happen if method_types is invalid; in
985 that case, return 0. */
986 return 0;
988 else
990 /* Remove the return type. */
991 return (i - 1);
996 unsigned
997 objc_get_type_qualifiers (const char *type)
999 unsigned res = 0;
1000 BOOL flag = YES;
1002 while (flag)
1003 switch (*type++)
1005 case _C_CONST: res |= _F_CONST; break;
1006 case _C_IN: res |= _F_IN; break;
1007 case _C_INOUT: res |= _F_INOUT; break;
1008 case _C_OUT: res |= _F_OUT; break;
1009 case _C_BYCOPY: res |= _F_BYCOPY; break;
1010 case _C_BYREF: res |= _F_BYREF; break;
1011 case _C_ONEWAY: res |= _F_ONEWAY; break;
1012 case _C_GCINVISIBLE: res |= _F_GCINVISIBLE; break;
1013 default: flag = NO;
1016 return res;
1019 /* The following three functions can be used to determine how a
1020 structure is laid out by the compiler. For example:
1022 struct objc_struct_layout layout;
1023 int i;
1025 objc_layout_structure (type, &layout);
1026 while (objc_layout_structure_next_member (&layout))
1028 int position, align;
1029 const char *type;
1031 objc_layout_structure_get_info (&layout, &position, &align, &type);
1032 printf ("element %d has offset %d, alignment %d\n",
1033 i++, position, align);
1036 These functions are used by objc_sizeof_type and objc_alignof_type
1037 functions to compute the size and alignment of structures. The
1038 previous method of computing the size and alignment of a structure
1039 was not working on some architectures, particulary on AIX, and in
1040 the presence of bitfields inside the structure. */
1041 void
1042 objc_layout_structure (const char *type,
1043 struct objc_struct_layout *layout)
1045 const char *ntype;
1047 if (*type != _C_UNION_B && *type != _C_STRUCT_B)
1049 _objc_abort ("record (or union) type expected in objc_layout_structure, got %s\n",
1050 type);
1053 type ++;
1054 layout->original_type = type;
1056 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
1057 ntype = type;
1058 while (*ntype != _C_STRUCT_E && *ntype != _C_STRUCT_B && *ntype != _C_UNION_B
1059 && *ntype++ != '=')
1060 /* do nothing */;
1062 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
1063 if (*(ntype - 1) == '=')
1064 type = ntype;
1066 layout->type = type;
1067 layout->prev_type = NULL;
1068 layout->record_size = 0;
1069 layout->record_align = BITS_PER_UNIT;
1071 layout->record_align = MAX (layout->record_align, STRUCTURE_SIZE_BOUNDARY);
1074 BOOL
1075 objc_layout_structure_next_member (struct objc_struct_layout *layout)
1077 register int desired_align = 0;
1079 /* The following are used only if the field is a bitfield */
1080 register const char *bfld_type = 0;
1081 register int bfld_type_align = 0, bfld_field_size = 0;
1083 /* The current type without the type qualifiers */
1084 const char *type;
1085 BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1087 /* Add the size of the previous field to the size of the record. */
1088 if (layout->prev_type)
1090 type = objc_skip_type_qualifiers (layout->prev_type);
1091 if (unionp)
1092 layout->record_size = MAX (layout->record_size,
1093 objc_sizeof_type (type) * BITS_PER_UNIT);
1095 else if (*type != _C_BFLD)
1096 layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT;
1097 else {
1098 /* Get the bitfield's type */
1099 for (bfld_type = type + 1;
1100 isdigit ((unsigned char)*bfld_type);
1101 bfld_type++)
1102 /* do nothing */;
1104 bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1105 bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1106 layout->record_size += bfld_field_size;
1110 if ((unionp && *layout->type == _C_UNION_E)
1111 || (!unionp && *layout->type == _C_STRUCT_E))
1112 return NO;
1114 /* Skip the variable name if any */
1115 layout->type = objc_skip_variable_name (layout->type);
1116 type = objc_skip_type_qualifiers (layout->type);
1118 if (*type != _C_BFLD)
1119 desired_align = objc_alignof_type (type) * BITS_PER_UNIT;
1120 else
1122 desired_align = 1;
1123 /* Skip the bitfield's offset */
1124 for (bfld_type = type + 1;
1125 isdigit ((unsigned char) *bfld_type);
1126 bfld_type++)
1127 /* do nothing */;
1129 bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1130 bfld_field_size = atoi (objc_skip_typespec (bfld_type));
1133 /* The following won't work for vectors. */
1134 #ifdef BIGGEST_FIELD_ALIGNMENT
1135 desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT);
1136 #endif
1137 #ifdef ADJUST_FIELD_ALIGN
1138 desired_align = ADJUST_FIELD_ALIGN (type, desired_align);
1139 #endif
1141 /* Record must have at least as much alignment as any field.
1142 Otherwise, the alignment of the field within the record
1143 is meaningless. */
1144 #ifndef PCC_BITFIELD_TYPE_MATTERS
1145 layout->record_align = MAX (layout->record_align, desired_align);
1146 #else /* PCC_BITFIELD_TYPE_MATTERS */
1147 if (*type == _C_BFLD)
1149 /* For these machines, a zero-length field does not
1150 affect the alignment of the structure as a whole.
1151 It does, however, affect the alignment of the next field
1152 within the structure. */
1153 if (bfld_field_size)
1154 layout->record_align = MAX (layout->record_align, desired_align);
1155 else
1156 desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT;
1158 /* A named bit field of declared type `int'
1159 forces the entire structure to have `int' alignment.
1160 Q1: How is encoded this thing and how to check for it?
1161 Q2: How to determine maximum_field_alignment at runtime? */
1163 /* if (DECL_NAME (field) != 0) */
1165 int type_align = bfld_type_align;
1166 #if 0
1167 if (maximum_field_alignment != 0)
1168 type_align = MIN (type_align, maximum_field_alignment);
1169 else if (DECL_PACKED (field))
1170 type_align = MIN (type_align, BITS_PER_UNIT);
1171 #endif
1173 layout->record_align = MAX (layout->record_align, type_align);
1176 else
1177 layout->record_align = MAX (layout->record_align, desired_align);
1178 #endif /* PCC_BITFIELD_TYPE_MATTERS */
1180 /* Does this field automatically have alignment it needs
1181 by virtue of the fields that precede it and the record's
1182 own alignment? */
1184 if (*type == _C_BFLD)
1185 layout->record_size = atoi (type + 1);
1186 else if (layout->record_size % desired_align != 0)
1188 /* No, we need to skip space before this field.
1189 Bump the cumulative size to multiple of field alignment. */
1190 layout->record_size = ROUND (layout->record_size, desired_align);
1193 /* Jump to the next field in record. */
1195 layout->prev_type = layout->type;
1196 layout->type = objc_skip_typespec (layout->type); /* skip component */
1198 return YES;
1201 void objc_layout_finish_structure (struct objc_struct_layout *layout,
1202 unsigned int *size,
1203 unsigned int *align)
1205 BOOL unionp = layout->original_type[-1] == _C_UNION_B;
1206 if (layout->type
1207 && ((!unionp && *layout->type == _C_STRUCT_E)
1208 || (unionp && *layout->type == _C_UNION_E)))
1210 /* Work out the alignment of the record as one expression and store
1211 in the record type. Round it up to a multiple of the record's
1212 alignment. */
1213 #if defined (ROUND_TYPE_ALIGN) && ! defined (__sparc__)
1214 layout->record_align = ROUND_TYPE_ALIGN (layout->original_type-1,
1216 layout->record_align);
1217 #else
1218 layout->record_align = MAX (1, layout->record_align);
1219 #endif
1221 #ifdef ROUND_TYPE_SIZE
1222 layout->record_size = ROUND_TYPE_SIZE (layout->original_type,
1223 layout->record_size,
1224 layout->record_align);
1225 #else
1226 /* Round the size up to be a multiple of the required alignment */
1227 layout->record_size = ROUND (layout->record_size, layout->record_align);
1228 #endif
1230 layout->type = NULL;
1232 if (size)
1233 *size = layout->record_size / BITS_PER_UNIT;
1234 if (align)
1235 *align = layout->record_align / BITS_PER_UNIT;
1238 void objc_layout_structure_get_info (struct objc_struct_layout *layout,
1239 unsigned int *offset,
1240 unsigned int *align,
1241 const char **type)
1243 if (offset)
1244 *offset = layout->record_size / BITS_PER_UNIT;
1245 if (align)
1246 *align = layout->record_align / BITS_PER_UNIT;
1247 if (type)
1248 *type = layout->prev_type;