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 VECTOR_TYPE _C_VECTOR
61 #define TYPE_FIELDS(TYPE) objc_skip_typespec (TYPE)
63 #define DECL_MODE(TYPE) *(TYPE)
64 #define TYPE_MODE(TYPE) *(TYPE)
68 #define get_inner_array_type(TYPE) ((TYPE) + 1)
70 /* Some ports (eg ARM) allow the structure size boundary to be
71 selected at compile-time. We override the normal definition with
72 one that has a constant value for this compilation. */
73 #undef STRUCTURE_SIZE_BOUNDARY
74 #define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
76 /* Some ROUND_TYPE_ALIGN macros use TARGET_foo, and consequently
77 target_flags. Define a dummy entry here to so we don't die. */
79 static int target_flags
= 0;
82 atoi (const char* str
)
86 while (isdigit (*str
))
87 res
*= 10, res
+= (*str
++ - '0');
93 return the size of an object specified by type
97 objc_sizeof_type (const char* type
)
99 /* Skip the variable name if any */
102 for (type
++; *type
++ != '"';)
112 return sizeof(Class
);
124 return sizeof(unsigned char);
128 return sizeof(short);
132 return sizeof(unsigned short);
140 return sizeof(unsigned int);
148 return sizeof(unsigned long);
152 return sizeof(long long);
156 return sizeof(unsigned long long);
160 return sizeof(float);
164 return sizeof(double);
173 return sizeof(char*);
178 int len
= atoi(type
+1);
179 while (isdigit(*++type
));
180 return len
*objc_aligned_size (type
);
186 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
188 int startByte
, endByte
;
190 position
= atoi (type
+ 1);
191 while (isdigit (*++type
));
192 size
= atoi (type
+ 1);
194 startByte
= position
/ BITS_PER_UNIT
;
195 endByte
= (position
+ size
) / BITS_PER_UNIT
;
196 return endByte
- startByte
;
201 struct objc_struct_layout layout
;
204 objc_layout_structure (type
, &layout
);
205 while (objc_layout_structure_next_member (&layout
))
207 objc_layout_finish_structure (&layout
, &size
, NULL
);
215 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
216 while (*type
!= _C_UNION_E
)
218 /* Skip the variable name if any */
221 for (type
++; *type
++ != '"';)
224 max_size
= MAX (max_size
, objc_sizeof_type (type
));
225 type
= objc_skip_typespec (type
);
232 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
240 Return the alignment of an object specified by type
244 objc_alignof_type(const char* type
)
246 /* Skip the variable name if any */
249 for (type
++; *type
++ != '"';)
254 return __alignof__(id
);
258 return __alignof__(Class
);
262 return __alignof__(SEL
);
266 return __alignof__(char);
270 return __alignof__(unsigned char);
274 return __alignof__(short);
278 return __alignof__(unsigned short);
282 return __alignof__(int);
286 return __alignof__(unsigned int);
290 return __alignof__(long);
294 return __alignof__(unsigned long);
298 return __alignof__(long long);
302 return __alignof__(unsigned long long);
306 return __alignof__(float);
310 return __alignof__(double);
316 return __alignof__(char*);
320 while (isdigit(*++type
)) /* do nothing */;
321 return objc_alignof_type (type
);
325 struct objc_struct_layout layout
;
328 objc_layout_structure (type
, &layout
);
329 while (objc_layout_structure_next_member (&layout
))
331 objc_layout_finish_structure (&layout
, NULL
, &align
);
339 while (*type
!= _C_UNION_E
&& *type
++ != '=') /* do nothing */;
340 while (*type
!= _C_UNION_E
)
342 /* Skip the variable name if any */
345 for (type
++; *type
++ != '"';)
348 maxalign
= MAX (maxalign
, objc_alignof_type (type
));
349 type
= objc_skip_typespec (type
);
356 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
363 The aligned size if the size rounded up to the nearest alignment.
367 objc_aligned_size (const char* type
)
371 /* Skip the variable name */
374 for (type
++; *type
++ != '"';)
378 size
= objc_sizeof_type (type
);
379 align
= objc_alignof_type (type
);
381 return ROUND (size
, align
);
385 The size rounded up to the nearest integral of the wordsize, taken
386 to be the size of a void*.
390 objc_promoted_size (const char* type
)
394 /* Skip the variable name */
397 for (type
++; *type
++ != '"';)
401 size
= objc_sizeof_type (type
);
402 wordsize
= sizeof (void*);
404 return ROUND (size
, wordsize
);
408 Skip type qualifiers. These may eventually precede typespecs
409 occurring in method prototype encodings.
413 objc_skip_type_qualifiers (const char* type
)
415 while (*type
== _C_CONST
419 || *type
== _C_BYCOPY
421 || *type
== _C_ONEWAY
422 || *type
== _C_GCINVISIBLE
)
431 Skip one typespec element. If the typespec is prepended by type
432 qualifiers, these are skipped as well.
436 objc_skip_typespec (const char* type
)
438 /* Skip the variable name if any */
441 for (type
++; *type
++ != '"';)
445 type
= objc_skip_type_qualifiers (type
);
450 /* An id may be annotated by the actual type if it is known
451 with the @"ClassName" syntax */
457 while (*++type
!= '"') /* do nothing */;
461 /* The following are one character type codes */
484 /* skip digits, typespec and closing ']' */
486 while(isdigit(*++type
));
487 type
= objc_skip_typespec(type
);
488 if (*type
== _C_ARY_E
)
492 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "bad array type %s\n", type
);
497 /* The new encoding of bitfields is: b 'position' 'type' 'size' */
498 while (isdigit (*++type
)); /* skip position */
499 while (isdigit (*++type
)); /* skip type and size */
503 /* skip name, and elements until closing '}' */
505 while (*type
!= _C_STRUCT_E
&& *type
++ != '=');
506 while (*type
!= _C_STRUCT_E
) { type
= objc_skip_typespec (type
); }
510 /* skip name, and elements until closing ')' */
512 while (*type
!= _C_UNION_E
&& *type
++ != '=');
513 while (*type
!= _C_UNION_E
) { type
= objc_skip_typespec (type
); }
517 /* Just skip the following typespec */
519 return objc_skip_typespec (++type
);
523 objc_error(nil
, OBJC_ERR_BAD_TYPE
, "unknown type %s\n", type
);
530 Skip an offset as part of a method encoding. This is prepended by a
531 '+' if the argument is passed in registers.
534 objc_skip_offset (const char* type
)
536 if (*type
== '+') type
++;
537 while(isdigit(*++type
));
542 Skip an argument specification of a method encoding.
545 objc_skip_argspec (const char* type
)
547 type
= objc_skip_typespec (type
);
548 type
= objc_skip_offset (type
);
553 Return the number of arguments that the method MTH expects.
554 Note that all methods need two implicit arguments `self' and
558 method_get_number_of_arguments (struct objc_method
* mth
)
561 const char* type
= mth
->method_types
;
564 type
= objc_skip_argspec (type
);
571 Return the size of the argument block needed on the stack to invoke
572 the method MTH. This may be zero, if all arguments are passed in
577 method_get_sizeof_arguments (struct objc_method
* mth
)
579 const char* type
= objc_skip_typespec (mth
->method_types
);
584 Return a pointer to the next argument of ARGFRAME. type points to
585 the last argument. Typical use of this look like:
589 for (datum = method_get_first_argument (method, argframe, &type);
590 datum; datum = method_get_next_argument (argframe, &type))
592 unsigned flags = objc_get_type_qualifiers (type);
593 type = objc_skip_type_qualifiers (type);
595 [portal encodeData: datum ofType: type];
598 if ((flags & _F_IN) == _F_IN)
599 [portal encodeData: *(char**)datum ofType: ++type];
606 method_get_next_argument (arglist_t argframe
,
609 const char *t
= objc_skip_argspec (*type
);
615 t
= objc_skip_typespec (t
);
618 return argframe
->arg_regs
+ atoi (++t
);
620 return argframe
->arg_ptr
+ atoi (t
);
624 Return a pointer to the value of the first argument of the method
625 described in M with the given argumentframe ARGFRAME. The type
626 is returned in TYPE. type must be passed to successive calls of
627 method_get_next_argument.
630 method_get_first_argument (struct objc_method
* m
,
634 *type
= m
->method_types
;
635 return method_get_next_argument (argframe
, type
);
639 Return a pointer to the ARGth argument of the method
640 M from the frame ARGFRAME. The type of the argument
641 is returned in the value-result argument TYPE
645 method_get_nth_argument (struct objc_method
* m
,
646 arglist_t argframe
, int arg
,
649 const char* t
= objc_skip_argspec (m
->method_types
);
651 if (arg
> method_get_number_of_arguments (m
))
655 t
= objc_skip_argspec (t
);
658 t
= objc_skip_typespec (t
);
661 return argframe
->arg_regs
+ atoi (++t
);
663 return argframe
->arg_ptr
+ atoi (t
);
667 objc_get_type_qualifiers (const char* type
)
675 case _C_CONST
: res
|= _F_CONST
; break;
676 case _C_IN
: res
|= _F_IN
; break;
677 case _C_INOUT
: res
|= _F_INOUT
; break;
678 case _C_OUT
: res
|= _F_OUT
; break;
679 case _C_BYCOPY
: res
|= _F_BYCOPY
; break;
680 case _C_BYREF
: res
|= _F_BYREF
; break;
681 case _C_ONEWAY
: res
|= _F_ONEWAY
; break;
682 case _C_GCINVISIBLE
: res
|= _F_GCINVISIBLE
; break;
690 /* The following three functions can be used to determine how a
691 structure is laid out by the compiler. For example:
693 struct objc_struct_layout layout;
696 objc_layout_structure (type, &layout);
697 while (objc_layout_structure_next_member (&layout))
702 objc_layout_structure_get_info (&layout, &position, &align, &type);
703 printf ("element %d has offset %d, alignment %d\n",
704 i++, position, align);
707 These functions are used by objc_sizeof_type and objc_alignof_type
708 functions to compute the size and alignment of structures. The
709 previous method of computing the size and alignment of a structure
710 was not working on some architectures, particulary on AIX, and in
711 the presence of bitfields inside the structure. */
713 objc_layout_structure (const char *type
,
714 struct objc_struct_layout
*layout
)
718 if (*type
++ != _C_STRUCT_B
)
720 objc_error(nil
, OBJC_ERR_BAD_TYPE
,
721 "record type expected in objc_layout_structure, got %s\n",
725 layout
->original_type
= type
;
727 /* Skip "<name>=" if any. Avoid embedded structures and unions. */
729 while (*ntype
!= _C_STRUCT_E
&& *ntype
!= _C_STRUCT_B
&& *ntype
!= _C_UNION_B
733 /* If there's a "<name>=", ntype - 1 points to '='; skip the the name */
734 if (*(ntype
- 1) == '=')
738 layout
->prev_type
= NULL
;
739 layout
->record_size
= 0;
740 layout
->record_align
= BITS_PER_UNIT
;
742 layout
->record_align
= MAX (layout
->record_align
, STRUCTURE_SIZE_BOUNDARY
);
747 objc_layout_structure_next_member (struct objc_struct_layout
*layout
)
749 register int known_align
= layout
->record_size
;
750 register int desired_align
= 0;
752 /* The following are used only if the field is a bitfield */
753 register const char *bfld_type
;
754 register int bfld_type_size
, bfld_type_align
, bfld_field_size
;
756 /* The current type without the type qualifiers */
759 /* Add the size of the previous field to the size of the record. */
760 if (layout
->prev_type
)
762 type
= objc_skip_type_qualifiers (layout
->prev_type
);
764 if (*type
!= _C_BFLD
)
765 layout
->record_size
+= objc_sizeof_type (type
) * BITS_PER_UNIT
;
767 /* Get the bitfield's type */
768 for (bfld_type
= type
+ 1;
773 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
774 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
775 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
776 layout
->record_size
+= bfld_field_size
;
780 if (*layout
->type
== _C_STRUCT_E
)
783 /* Skip the variable name if any */
784 if (*layout
->type
== '"')
786 for (layout
->type
++; *layout
->type
++ != '"';)
790 type
= objc_skip_type_qualifiers (layout
->type
);
792 if (*type
!= _C_BFLD
)
793 desired_align
= objc_alignof_type(type
) * BITS_PER_UNIT
;
797 /* Skip the bitfield's offset */
798 for (bfld_type
= type
+ 1; isdigit(*bfld_type
); bfld_type
++)
801 bfld_type_size
= objc_sizeof_type (bfld_type
) * BITS_PER_UNIT
;
802 bfld_type_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
803 bfld_field_size
= atoi (objc_skip_typespec (bfld_type
));
806 #ifdef BIGGEST_FIELD_ALIGNMENT
807 desired_align
= MIN (desired_align
, BIGGEST_FIELD_ALIGNMENT
);
809 #ifdef ADJUST_FIELD_ALIGN
810 desired_align
= ADJUST_FIELD_ALIGN (type
, desired_align
);
813 /* Record must have at least as much alignment as any field.
814 Otherwise, the alignment of the field within the record
816 #ifndef PCC_BITFIELD_TYPE_MATTERS
817 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
819 if (*type
== _C_BFLD
)
821 /* For these machines, a zero-length field does not
822 affect the alignment of the structure as a whole.
823 It does, however, affect the alignment of the next field
824 within the structure. */
826 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
828 desired_align
= objc_alignof_type (bfld_type
) * BITS_PER_UNIT
;
830 /* A named bit field of declared type `int'
831 forces the entire structure to have `int' alignment.
832 Q1: How is encoded this thing and how to check for it?
833 Q2: How to determine maximum_field_alignment at runtime? */
835 /* if (DECL_NAME (field) != 0) */
837 int type_align
= bfld_type_align
;
839 if (maximum_field_alignment
!= 0)
840 type_align
= MIN (type_align
, maximum_field_alignment
);
841 else if (DECL_PACKED (field
))
842 type_align
= MIN (type_align
, BITS_PER_UNIT
);
845 layout
->record_align
= MAX (layout
->record_align
, type_align
);
849 layout
->record_align
= MAX (layout
->record_align
, desired_align
);
852 /* Does this field automatically have alignment it needs
853 by virtue of the fields that precede it and the record's
856 if (*type
== _C_BFLD
)
857 layout
->record_size
= atoi (type
+ 1);
858 else if (layout
->record_size
% desired_align
!= 0)
860 /* No, we need to skip space before this field.
861 Bump the cumulative size to multiple of field alignment. */
862 layout
->record_size
= ROUND (layout
->record_size
, desired_align
);
865 /* Jump to the next field in record. */
867 layout
->prev_type
= layout
->type
;
868 layout
->type
= objc_skip_typespec (layout
->type
); /* skip component */
874 void objc_layout_finish_structure (struct objc_struct_layout
*layout
,
878 if (layout
->type
&& *layout
->type
== _C_STRUCT_E
)
880 /* Work out the alignment of the record as one expression and store
881 in the record type. Round it up to a multiple of the record's
884 #if defined(ROUND_TYPE_ALIGN) && !defined(__sparc__)
885 layout
->record_align
= ROUND_TYPE_ALIGN (layout
->original_type
,
887 layout
->record_align
);
889 layout
->record_align
= MAX (1, layout
->record_align
);
892 #ifdef ROUND_TYPE_SIZE
893 layout
->record_size
= ROUND_TYPE_SIZE (layout
->original_type
,
895 layout
->record_align
);
897 /* Round the size up to be a multiple of the required alignment */
898 layout
->record_size
= ROUND (layout
->record_size
, layout
->record_align
);
904 *size
= layout
->record_size
/ BITS_PER_UNIT
;
906 *align
= layout
->record_align
/ BITS_PER_UNIT
;
910 void objc_layout_structure_get_info (struct objc_struct_layout
*layout
,
911 unsigned int *offset
,
916 *offset
= layout
->record_size
/ BITS_PER_UNIT
;
918 *align
= layout
->record_align
/ BITS_PER_UNIT
;
920 *type
= layout
->prev_type
;