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