1 /* Encoding of types for Objective C.
2 Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
4 Bitfield support by Ovidiu Predescu
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* As a special exception, if you link this library with files
24 compiled with GCC to produce an executable, this does not cause
25 the resulting executable to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
34 ({ typeof(X) __x = (X), __y = (Y); \
35 (__x > __y ? __x : __y); })
38 ({ typeof(X) __x = (X), __y = (Y); \
39 (__x < __y ? __x : __y); })
42 ({ typeof(V) __v=(V); typeof(A) __a=(A); \
43 __a*((__v+__a-1)/__a); })
46 /* Various hacks for objc_layout_record. These are used by the target
49 #define TREE_CODE(TYPE) *TYPE
50 #define TREE_TYPE(TREE) TREE
52 #define RECORD_TYPE _C_STRUCT_B
53 #define UNION_TYPE _C_UNION_B
54 #define QUAL_UNION_TYPE _C_UNION_B
55 #define ARRAY_TYPE _C_ARY_B
57 #define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
59 #define DECL_MODE(TYPE) *(TYPE)
63 #define get_inner_array_type(TYPE) ((TYPE) + 1)
65 /* Some ports (eg ARM) allow the structure size boundary to be
66 selected at compile-time. We override the normal definition with
67 one that has a constant value for this compilation. */
68 #undef STRUCTURE_SIZE_BOUNDARY
69 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
72 atoi (const char* str
)
76 while (isdigit (*str
))
77 res
*= 10, res
+= (*str
++ - '0');
83 return the size of an object specified by type
87 objc_sizeof_type (const char* type
)
89 /* Skip the variable name if any */
92 for (type
++; *type
++ != '"';)
102 return sizeof(Class
);
114 return sizeof(unsigned char);
118 return sizeof(short);
122 return sizeof(unsigned short);
130 return sizeof(unsigned int);
138 return sizeof(unsigned long);
142 return sizeof(long long);
146 return sizeof(unsigned long long);
150 return sizeof(float);
154 return sizeof(double);
163 return sizeof(char*);
168 int len
= atoi(type
+1);
169 while (isdigit(*++type
));
170 return len
*objc_aligned_size (type
);
176 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
178 int startByte
, endByte
;
180 position
= atoi (type
+ 1);
181 while (isdigit (*++type
));
182 size
= atoi (type
+ 1);
184 startByte
= position
/ BITS_PER_UNIT
;
185 endByte
= (position
+ size
) / BITS_PER_UNIT
;
186 return endByte
- startByte
;
191 struct objc_struct_layout layout
;
194 objc_layout_structure (type
, &layout
);
195 while (objc_layout_structure_next_member (&layout
))
197 objc_layout_finish_structure (&layout
, &size
, NULL
);
205 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
206 while (*type
!= _C_UNION_E
)
208 /* Skip the variable name if any */
211 for (type
++; *type
++ != '"';)
214 max_size
= MAX (max_size
, objc_sizeof_type (type
));
215 type
= objc_skip_typespec (type
);
222 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
230 Return the alignment of an object specified by type
234 objc_alignof_type(const char* type
)
236 /* Skip the variable name if any */
239 for (type
++; *type
++ != '"';)
244 return __alignof__(id
);
248 return __alignof__(Class
);
252 return __alignof__(SEL
);
256 return __alignof__(char);
260 return __alignof__(unsigned char);
264 return __alignof__(short);
268 return __alignof__(unsigned short);
272 return __alignof__(int);
276 return __alignof__(unsigned int);
280 return __alignof__(long);
284 return __alignof__(unsigned long);
288 return __alignof__(long long);
292 return __alignof__(unsigned long long);
296 return __alignof__(float);
300 return __alignof__(double);
306 return __alignof__(char*);
310 while (isdigit(*++type
)) /* do nothing */;
311 return objc_alignof_type (type
);
315 struct objc_struct_layout layout
;
318 objc_layout_structure (type
, &layout
);
319 while (objc_layout_structure_next_member (&layout
))
321 objc_layout_finish_structure (&layout
, NULL
, &align
);
329 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
330 while (*type
!= _C_UNION_E
)
332 /* Skip the variable name if any */
335 for (type
++; *type
++ != '"';)
338 maxalign
= MAX (maxalign
, objc_alignof_type (type
));
339 type
= objc_skip_typespec (type
);
346 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
353 The aligned size if the size rounded up to the nearest alignment.
357 objc_aligned_size (const char* type
)
361 /* Skip the variable name */
364 for (type
++; *type
++ != '"';)
368 size
= objc_sizeof_type (type
);
369 align
= objc_alignof_type (type
);
371 return ROUND (size
, align
);
375 The size rounded up to the nearest integral of the wordsize, taken
376 to be the size of a void*.
380 objc_promoted_size (const char* type
)
384 /* Skip the variable name */
387 for (type
++; *type
++ != '"';)
391 size
= objc_sizeof_type (type
);
392 wordsize
= sizeof (void*);
394 return ROUND (size
, wordsize
);
398 Skip type qualifiers. These may eventually precede typespecs
399 occurring in method prototype encodings.
403 objc_skip_type_qualifiers (const char* type
)
405 while (*type
== _C_CONST
409 || *type
== _C_BYCOPY
411 || *type
== _C_ONEWAY
412 || *type
== _C_GCINVISIBLE
)
421 Skip one typespec element. If the typespec is prepended by type
422 qualifiers, these are skipped as well.
426 objc_skip_typespec (const char* type
)
428 /* Skip the variable name if any */
431 for (type
++; *type
++ != '"';)
435 type
= objc_skip_type_qualifiers (type
);
440 /* An id may be annotated by the actual type if it is known
441 with the @"ClassName" syntax */
447 while (*++type
!= '"') /* do nothing */;
451 /* The following are one character type codes */
474 /* skip digits, typespec and closing ']' */
476 while(isdigit(*++type
));
477 type
= objc_skip_typespec(type
);
478 if (*type
== _C_ARY_E
)
482 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "bad array type %s\n", type
);
487 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
488 while (isdigit (*++type
)); /* skip position */
489 while (isdigit (*++type
)); /* skip type and size */
493 /* skip name, and elements until closing '}' */
495 while (*type
!= _C_STRUCT_E
&& *type
++ != '=');
496 while (*type
!= _C_STRUCT_E
) { type
= objc_skip_typespec (type
); }
500 /* skip name, and elements until closing ')' */
502 while (*type
!= _C_UNION_E
&& *type
++ != '=');
503 while (*type
!= _C_UNION_E
) { type
= objc_skip_typespec (type
); }
507 /* Just skip the following typespec */
509 return objc_skip_typespec (++type
);
513 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
520 Skip an offset as part of a method encoding. This is prepended by a
521 '+' if the argument is passed in registers.
524 objc_skip_offset (const char* type
)
526 if (*type
== '+') type
++;
527 while(isdigit(*++type
));
532 Skip an argument specification of a method encoding.
535 objc_skip_argspec (const char* type
)
537 type
= objc_skip_typespec (type
);
538 type
= objc_skip_offset (type
);
543 Return the number of arguments that the method MTH expects.
544 Note that all methods need two implicit arguments `self' and
548 method_get_number_of_arguments (struct objc_method
* mth
)
551 const char* type
= mth
->method_types
;
554 type
= objc_skip_argspec (type
);
561 Return the size of the argument block needed on the stack to invoke
562 the method MTH. This may be zero, if all arguments are passed in
567 method_get_sizeof_arguments (struct objc_method
* mth
)
569 const char* type
= objc_skip_typespec (mth
->method_types
);
574 Return a pointer to the next argument of ARGFRAME. type points to
575 the last argument. Typical use of this look like:
579 for (datum = method_get_first_argument (method, argframe, &type);
580 datum; datum = method_get_next_argument (argframe, &type))
582 unsigned flags = objc_get_type_qualifiers (type);
583 type = objc_skip_type_qualifiers (type);
585 [portal encodeData: datum ofType: type];
588 if ((flags & _F_IN) == _F_IN)
589 [portal encodeData: *(char**)datum ofType: ++type];
596 method_get_next_argument (arglist_t argframe
,
599 const char *t
= objc_skip_argspec (*type
);
605 t
= objc_skip_typespec (t
);
608 return argframe
->arg_regs
+ atoi (++t
);
610 return argframe
->arg_ptr
+ atoi (t
);
614 Return a pointer to the value of the first argument of the method
615 described in M with the given argumentframe ARGFRAME. The type
616 is returned in TYPE. type must be passed to successive calls of
617 method_get_next_argument.
620 method_get_first_argument (struct objc_method
* m
,
624 *type
= m
->method_types
;
625 return method_get_next_argument (argframe
, type
);
629 Return a pointer to the ARGth argument of the method
630 M from the frame ARGFRAME. The type of the argument
631 is returned in the value-result argument TYPE
635 method_get_nth_argument (struct objc_method
* m
,
636 arglist_t argframe
, int arg
,
639 const char* t
= objc_skip_argspec (m
->method_types
);
641 if (arg
> method_get_number_of_arguments (m
))
645 t
= objc_skip_argspec (t
);
648 t
= objc_skip_typespec (t
);
651 return argframe
->arg_regs
+ atoi (++t
);
653 return argframe
->arg_ptr
+ atoi (t
);
657 objc_get_type_qualifiers (const char* type
)
665 case _C_CONST
: res
|= _F_CONST
; break;
666 case _C_IN
: res
|= _F_IN
; break;
667 case _C_INOUT
: res
|= _F_INOUT
; break;
668 case _C_OUT
: res
|= _F_OUT
; break;
669 case _C_BYCOPY
: res
|= _F_BYCOPY
; break;
670 case _C_BYREF
: res
|= _F_BYREF
; break;
671 case _C_ONEWAY
: res
|= _F_ONEWAY
; break;
672 case _C_GCINVISIBLE
: res
|= _F_GCINVISIBLE
; break;
680 /* The following three functions can be used to determine how a
681 structure is laid out by the compiler. For example:
683 struct objc_struct_layout layout;
686 objc_layout_structure (type, &layout);
687 while (objc_layout_structure_next_member (&layout))
692 objc_layout_structure_get_info (&layout, &position, &align, &type);
693 printf ("element %d has offset %d, alignment %d\n",
694 i++, position, align);
697 These functions are used by objc_sizeof_type and objc_alignof_type
698 functions to compute the size and alignment of structures. The
699 previous method of computing the size and alignment of a structure
700 was not working on some architectures, particulary on AIX, and in
701 the presence of bitfields inside the structure. */
703 objc_layout_structure (const char *type
,
704 struct objc_struct_layout
*layout
)
708 if (*type
++ != _C_STRUCT_B
)
710 objc_error(nil
, OBJC_ERR_BAD_TYPE
,
711 "record type expected in objc_layout_structure, got %s\n",
715 layout
->original_type
= type
;
717 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
719 while (*ntype
!= _C_STRUCT_E
&& *ntype
!= _C_STRUCT_B
&& *ntype
!= _C_UNION_B
723 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
724 if (*(ntype
- 1) == '=')
728 layout
->prev_type
= NULL
;
729 layout
->record_size
= 0;
730 layout
->record_align
= BITS_PER_UNIT
;
732 layout
->record_align
= MAX (layout
->record_align
, STRUCTURE_SIZE_BOUNDARY
);
737 objc_layout_structure_next_member (struct objc_struct_layout
*layout
)
739 register int known_align
= layout
->record_size
;
740 register int desired_align
= 0;
742 /* The following are used only if the field is a bitfield */
743 register const char *bfld_type
;
744 register int bfld_type_size
, bfld_type_align
, bfld_field_size
;
746 /* The current type without the type qualifiers */
749 /* Add the size of the previous field to the size of the record. */
750 if (layout
->prev_type
)
752 type
= objc_skip_type_qualifiers (layout
->prev_type
);
754 if (*type
!= _C_BFLD
)
755 layout
->record_size
+= objc_sizeof_type (type
) * BITS_PER_UNIT
;
757 /* Get the bitfield's type */
758 for (bfld_type
= type
+ 1;
763 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
764 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
765 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
766 layout
->record_size
+= bfld_field_size
;
770 if (*layout
->type
== _C_STRUCT_E
)
773 /* Skip the variable name if any */
774 if (*layout
->type
== '"')
776 for (layout
->type
++; *layout
->type
++ != '"';)
780 type
= objc_skip_type_qualifiers (layout
->type
);
782 if (*type
!= _C_BFLD
)
783 desired_align
= objc_alignof_type(type
) * BITS_PER_UNIT
;
787 /* Skip the bitfield's offset */
788 for (bfld_type
= type
+ 1; isdigit(*bfld_type
); bfld_type
++)
791 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
792 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
793 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
796 #ifdef BIGGEST_FIELD_ALIGNMENT
797 desired_align
= MIN (desired_align
, BIGGEST_FIELD_ALIGNMENT
);
799 #ifdef ADJUST_FIELD_ALIGN
800 desired_align
= ADJUST_FIELD_ALIGN (type
, desired_align
);
803 /* Record must have at least as much alignment as any field.
804 Otherwise, the alignment of the field within the record
806 #ifndef PCC_BITFIELD_TYPE_MATTERS
807 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
809 if (*type
== _C_BFLD
)
811 /* For these machines, a zero-length field does not
812 affect the alignment of the structure as a whole.
813 It does, however, affect the alignment of the next field
814 within the structure. */
816 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
818 desired_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
820 /* A named bit field of declared type `int'
821 forces the entire structure to have `int' alignment.
822 Q1: How is encoded this thing and how to check for it?
823 Q2: How to determine maximum_field_alignment at runtime? */
825 /* if (DECL_NAME (field) != 0) */
827 int type_align
= bfld_type_align
;
829 if (maximum_field_alignment
!= 0)
830 type_align
= MIN (type_align
, maximum_field_alignment
);
831 else if (DECL_PACKED (field
))
832 type_align
= MIN (type_align
, BITS_PER_UNIT
);
835 layout
->record_align
= MAX (layout
->record_align
, type_align
);
839 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
842 /* Does this field automatically have alignment it needs
843 by virtue of the fields that precede it and the record's
846 if (*type
== _C_BFLD
)
847 layout
->record_size
= atoi (type
+ 1);
848 else if (layout
->record_size
% desired_align
!= 0)
850 /* No, we need to skip space before this field.
851 Bump the cumulative size to multiple of field alignment. */
852 layout
->record_size
= ROUND (layout
->record_size
, desired_align
);
855 /* Jump to the next field in record. */
857 layout
->prev_type
= layout
->type
;
858 layout
->type
= objc_skip_typespec (layout
->type
); /* skip component */
864 void objc_layout_finish_structure (struct objc_struct_layout
*layout
,
868 if (layout
->type
&& *layout
->type
== _C_STRUCT_E
)
870 /* Work out the alignment of the record as one expression and store
871 in the record type. Round it up to a multiple of the record's
874 #if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
875 layout
->record_align
= ROUND_TYPE_ALIGN (layout
->original_type
,
877 layout
->record_align
);
879 layout
->record_align
= MAX (1, layout
->record_align
);
882 #ifdef ROUND_TYPE_SIZE
883 layout
->record_size
= ROUND_TYPE_SIZE (layout
->original_type
,
885 layout
->record_align
);
887 /* Round the size up to be a multiple of the required alignment */
888 layout
->record_size
= ROUND (layout
->record_size
, layout
->record_align
);
894 *size
= layout
->record_size
/ BITS_PER_UNIT
;
896 *align
= layout
->record_align
/ BITS_PER_UNIT
;
900 void objc_layout_structure_get_info (struct objc_struct_layout
*layout
,
901 unsigned int *offset
,
906 *offset
= layout
->record_size
/ BITS_PER_UNIT
;
908 *align
= layout
->record_align
/ BITS_PER_UNIT
;
910 *type
= layout
->prev_type
;