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