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 REAL_TYPE _C_DBL
59 #define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
61 #define DECL_MODE(TYPE) *(TYPE)
62 #define TYPE_MODE(TYPE) *(TYPE)
66 #define get_inner_array_type(TYPE) ((TYPE) + 1)
68 /* Some ports (eg ARM) allow the structure size boundary to be
69 selected at compile-time. We override the normal definition with
70 one that has a constant value for this compilation. */
71 #undef STRUCTURE_SIZE_BOUNDARY
72 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
75 atoi (const char* str
)
79 while (isdigit (*str
))
80 res
*= 10, res
+= (*str
++ - '0');
86 return the size of an object specified by type
90 objc_sizeof_type (const char* type
)
92 /* Skip the variable name if any */
95 for (type
++; *type
++ != '"';)
105 return sizeof(Class
);
117 return sizeof(unsigned char);
121 return sizeof(short);
125 return sizeof(unsigned short);
133 return sizeof(unsigned int);
141 return sizeof(unsigned long);
145 return sizeof(long long);
149 return sizeof(unsigned long long);
153 return sizeof(float);
157 return sizeof(double);
166 return sizeof(char*);
171 int len
= atoi(type
+1);
172 while (isdigit(*++type
));
173 return len
*objc_aligned_size (type
);
179 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
181 int startByte
, endByte
;
183 position
= atoi (type
+ 1);
184 while (isdigit (*++type
));
185 size
= atoi (type
+ 1);
187 startByte
= position
/ BITS_PER_UNIT
;
188 endByte
= (position
+ size
) / BITS_PER_UNIT
;
189 return endByte
- startByte
;
194 struct objc_struct_layout layout
;
197 objc_layout_structure (type
, &layout
);
198 while (objc_layout_structure_next_member (&layout
))
200 objc_layout_finish_structure (&layout
, &size
, NULL
);
208 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
209 while (*type
!= _C_UNION_E
)
211 /* Skip the variable name if any */
214 for (type
++; *type
++ != '"';)
217 max_size
= MAX (max_size
, objc_sizeof_type (type
));
218 type
= objc_skip_typespec (type
);
225 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
233 Return the alignment of an object specified by type
237 objc_alignof_type(const char* type
)
239 /* Skip the variable name if any */
242 for (type
++; *type
++ != '"';)
247 return __alignof__(id
);
251 return __alignof__(Class
);
255 return __alignof__(SEL
);
259 return __alignof__(char);
263 return __alignof__(unsigned char);
267 return __alignof__(short);
271 return __alignof__(unsigned short);
275 return __alignof__(int);
279 return __alignof__(unsigned int);
283 return __alignof__(long);
287 return __alignof__(unsigned long);
291 return __alignof__(long long);
295 return __alignof__(unsigned long long);
299 return __alignof__(float);
303 return __alignof__(double);
309 return __alignof__(char*);
313 while (isdigit(*++type
)) /* do nothing */;
314 return objc_alignof_type (type
);
318 struct objc_struct_layout layout
;
321 objc_layout_structure (type
, &layout
);
322 while (objc_layout_structure_next_member (&layout
))
324 objc_layout_finish_structure (&layout
, NULL
, &align
);
332 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
333 while (*type
!= _C_UNION_E
)
335 /* Skip the variable name if any */
338 for (type
++; *type
++ != '"';)
341 maxalign
= MAX (maxalign
, objc_alignof_type (type
));
342 type
= objc_skip_typespec (type
);
349 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
356 The aligned size if the size rounded up to the nearest alignment.
360 objc_aligned_size (const char* type
)
364 /* Skip the variable name */
367 for (type
++; *type
++ != '"';)
371 size
= objc_sizeof_type (type
);
372 align
= objc_alignof_type (type
);
374 return ROUND (size
, align
);
378 The size rounded up to the nearest integral of the wordsize, taken
379 to be the size of a void*.
383 objc_promoted_size (const char* type
)
387 /* Skip the variable name */
390 for (type
++; *type
++ != '"';)
394 size
= objc_sizeof_type (type
);
395 wordsize
= sizeof (void*);
397 return ROUND (size
, wordsize
);
401 Skip type qualifiers. These may eventually precede typespecs
402 occurring in method prototype encodings.
406 objc_skip_type_qualifiers (const char* type
)
408 while (*type
== _C_CONST
412 || *type
== _C_BYCOPY
414 || *type
== _C_ONEWAY
415 || *type
== _C_GCINVISIBLE
)
424 Skip one typespec element. If the typespec is prepended by type
425 qualifiers, these are skipped as well.
429 objc_skip_typespec (const char* type
)
431 /* Skip the variable name if any */
434 for (type
++; *type
++ != '"';)
438 type
= objc_skip_type_qualifiers (type
);
443 /* An id may be annotated by the actual type if it is known
444 with the @"ClassName" syntax */
450 while (*++type
!= '"') /* do nothing */;
454 /* The following are one character type codes */
477 /* skip digits, typespec and closing ']' */
479 while(isdigit(*++type
));
480 type
= objc_skip_typespec(type
);
481 if (*type
== _C_ARY_E
)
485 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "bad array type %s\n", type
);
490 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
491 while (isdigit (*++type
)); /* skip position */
492 while (isdigit (*++type
)); /* skip type and size */
496 /* skip name, and elements until closing '}' */
498 while (*type
!= _C_STRUCT_E
&& *type
++ != '=');
499 while (*type
!= _C_STRUCT_E
) { type
= objc_skip_typespec (type
); }
503 /* skip name, and elements until closing ')' */
505 while (*type
!= _C_UNION_E
&& *type
++ != '=');
506 while (*type
!= _C_UNION_E
) { type
= objc_skip_typespec (type
); }
510 /* Just skip the following typespec */
512 return objc_skip_typespec (++type
);
516 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
523 Skip an offset as part of a method encoding. This is prepended by a
524 '+' if the argument is passed in registers.
527 objc_skip_offset (const char* type
)
529 if (*type
== '+') type
++;
530 while(isdigit(*++type
));
535 Skip an argument specification of a method encoding.
538 objc_skip_argspec (const char* type
)
540 type
= objc_skip_typespec (type
);
541 type
= objc_skip_offset (type
);
546 Return the number of arguments that the method MTH expects.
547 Note that all methods need two implicit arguments `self' and
551 method_get_number_of_arguments (struct objc_method
* mth
)
554 const char* type
= mth
->method_types
;
557 type
= objc_skip_argspec (type
);
564 Return the size of the argument block needed on the stack to invoke
565 the method MTH. This may be zero, if all arguments are passed in
570 method_get_sizeof_arguments (struct objc_method
* mth
)
572 const char* type
= objc_skip_typespec (mth
->method_types
);
577 Return a pointer to the next argument of ARGFRAME. type points to
578 the last argument. Typical use of this look like:
582 for (datum = method_get_first_argument (method, argframe, &type);
583 datum; datum = method_get_next_argument (argframe, &type))
585 unsigned flags = objc_get_type_qualifiers (type);
586 type = objc_skip_type_qualifiers (type);
588 [portal encodeData: datum ofType: type];
591 if ((flags & _F_IN) == _F_IN)
592 [portal encodeData: *(char**)datum ofType: ++type];
599 method_get_next_argument (arglist_t argframe
,
602 const char *t
= objc_skip_argspec (*type
);
608 t
= objc_skip_typespec (t
);
611 return argframe
->arg_regs
+ atoi (++t
);
613 return argframe
->arg_ptr
+ atoi (t
);
617 Return a pointer to the value of the first argument of the method
618 described in M with the given argumentframe ARGFRAME. The type
619 is returned in TYPE. type must be passed to successive calls of
620 method_get_next_argument.
623 method_get_first_argument (struct objc_method
* m
,
627 *type
= m
->method_types
;
628 return method_get_next_argument (argframe
, type
);
632 Return a pointer to the ARGth argument of the method
633 M from the frame ARGFRAME. The type of the argument
634 is returned in the value-result argument TYPE
638 method_get_nth_argument (struct objc_method
* m
,
639 arglist_t argframe
, int arg
,
642 const char* t
= objc_skip_argspec (m
->method_types
);
644 if (arg
> method_get_number_of_arguments (m
))
648 t
= objc_skip_argspec (t
);
651 t
= objc_skip_typespec (t
);
654 return argframe
->arg_regs
+ atoi (++t
);
656 return argframe
->arg_ptr
+ atoi (t
);
660 objc_get_type_qualifiers (const char* type
)
668 case _C_CONST
: res
|= _F_CONST
; break;
669 case _C_IN
: res
|= _F_IN
; break;
670 case _C_INOUT
: res
|= _F_INOUT
; break;
671 case _C_OUT
: res
|= _F_OUT
; break;
672 case _C_BYCOPY
: res
|= _F_BYCOPY
; break;
673 case _C_BYREF
: res
|= _F_BYREF
; break;
674 case _C_ONEWAY
: res
|= _F_ONEWAY
; break;
675 case _C_GCINVISIBLE
: res
|= _F_GCINVISIBLE
; break;
683 /* The following three functions can be used to determine how a
684 structure is laid out by the compiler. For example:
686 struct objc_struct_layout layout;
689 objc_layout_structure (type, &layout);
690 while (objc_layout_structure_next_member (&layout))
695 objc_layout_structure_get_info (&layout, &position, &align, &type);
696 printf ("element %d has offset %d, alignment %d\n",
697 i++, position, align);
700 These functions are used by objc_sizeof_type and objc_alignof_type
701 functions to compute the size and alignment of structures. The
702 previous method of computing the size and alignment of a structure
703 was not working on some architectures, particulary on AIX, and in
704 the presence of bitfields inside the structure. */
706 objc_layout_structure (const char *type
,
707 struct objc_struct_layout
*layout
)
711 if (*type
++ != _C_STRUCT_B
)
713 objc_error(nil
, OBJC_ERR_BAD_TYPE
,
714 "record type expected in objc_layout_structure, got %s\n",
718 layout
->original_type
= type
;
720 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
722 while (*ntype
!= _C_STRUCT_E
&& *ntype
!= _C_STRUCT_B
&& *ntype
!= _C_UNION_B
726 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
727 if (*(ntype
- 1) == '=')
731 layout
->prev_type
= NULL
;
732 layout
->record_size
= 0;
733 layout
->record_align
= BITS_PER_UNIT
;
735 layout
->record_align
= MAX (layout
->record_align
, STRUCTURE_SIZE_BOUNDARY
);
740 objc_layout_structure_next_member (struct objc_struct_layout
*layout
)
742 register int known_align
= layout
->record_size
;
743 register int desired_align
= 0;
745 /* The following are used only if the field is a bitfield */
746 register const char *bfld_type
;
747 register int bfld_type_size
, bfld_type_align
, bfld_field_size
;
749 /* The current type without the type qualifiers */
752 /* Add the size of the previous field to the size of the record. */
753 if (layout
->prev_type
)
755 type
= objc_skip_type_qualifiers (layout
->prev_type
);
757 if (*type
!= _C_BFLD
)
758 layout
->record_size
+= objc_sizeof_type (type
) * BITS_PER_UNIT
;
760 /* Get the bitfield's type */
761 for (bfld_type
= type
+ 1;
766 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
767 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
768 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
769 layout
->record_size
+= bfld_field_size
;
773 if (*layout
->type
== _C_STRUCT_E
)
776 /* Skip the variable name if any */
777 if (*layout
->type
== '"')
779 for (layout
->type
++; *layout
->type
++ != '"';)
783 type
= objc_skip_type_qualifiers (layout
->type
);
785 if (*type
!= _C_BFLD
)
786 desired_align
= objc_alignof_type(type
) * BITS_PER_UNIT
;
790 /* Skip the bitfield's offset */
791 for (bfld_type
= type
+ 1; isdigit(*bfld_type
); bfld_type
++)
794 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
795 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
796 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
799 #ifdef BIGGEST_FIELD_ALIGNMENT
800 desired_align
= MIN (desired_align
, BIGGEST_FIELD_ALIGNMENT
);
802 #ifdef ADJUST_FIELD_ALIGN
803 desired_align
= ADJUST_FIELD_ALIGN (type
, desired_align
);
806 /* Record must have at least as much alignment as any field.
807 Otherwise, the alignment of the field within the record
809 #ifndef PCC_BITFIELD_TYPE_MATTERS
810 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
812 if (*type
== _C_BFLD
)
814 /* For these machines, a zero-length field does not
815 affect the alignment of the structure as a whole.
816 It does, however, affect the alignment of the next field
817 within the structure. */
819 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
821 desired_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
823 /* A named bit field of declared type `int'
824 forces the entire structure to have `int' alignment.
825 Q1: How is encoded this thing and how to check for it?
826 Q2: How to determine maximum_field_alignment at runtime? */
828 /* if (DECL_NAME (field) != 0) */
830 int type_align
= bfld_type_align
;
832 if (maximum_field_alignment
!= 0)
833 type_align
= MIN (type_align
, maximum_field_alignment
);
834 else if (DECL_PACKED (field
))
835 type_align
= MIN (type_align
, BITS_PER_UNIT
);
838 layout
->record_align
= MAX (layout
->record_align
, type_align
);
842 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
845 /* Does this field automatically have alignment it needs
846 by virtue of the fields that precede it and the record's
849 if (*type
== _C_BFLD
)
850 layout
->record_size
= atoi (type
+ 1);
851 else if (layout
->record_size
% desired_align
!= 0)
853 /* No, we need to skip space before this field.
854 Bump the cumulative size to multiple of field alignment. */
855 layout
->record_size
= ROUND (layout
->record_size
, desired_align
);
858 /* Jump to the next field in record. */
860 layout
->prev_type
= layout
->type
;
861 layout
->type
= objc_skip_typespec (layout
->type
); /* skip component */
867 void objc_layout_finish_structure (struct objc_struct_layout
*layout
,
871 if (layout
->type
&& *layout
->type
== _C_STRUCT_E
)
873 /* Work out the alignment of the record as one expression and store
874 in the record type. Round it up to a multiple of the record's
877 #if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
878 layout
->record_align
= ROUND_TYPE_ALIGN (layout
->original_type
,
880 layout
->record_align
);
882 layout
->record_align
= MAX (1, layout
->record_align
);
885 #ifdef ROUND_TYPE_SIZE
886 layout
->record_size
= ROUND_TYPE_SIZE (layout
->original_type
,
888 layout
->record_align
);
890 /* Round the size up to be a multiple of the required alignment */
891 layout
->record_size
= ROUND (layout
->record_size
, layout
->record_align
);
897 *size
= layout
->record_size
/ BITS_PER_UNIT
;
899 *align
= layout
->record_align
/ BITS_PER_UNIT
;
903 void objc_layout_structure_get_info (struct objc_struct_layout
*layout
,
904 unsigned int *offset
,
909 *offset
= layout
->record_size
/ BITS_PER_UNIT
;
911 *align
= layout
->record_align
/ BITS_PER_UNIT
;
913 *type
= layout
->prev_type
;