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