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