xref: /netbsd-src/external/gpl3/gcc/dist/libobjc/gc.c (revision b1e838363e3c6fc78a55519254d99869742dd33c)
14fee23f9Smrg /* Basic data types for Objective C.
2*b1e83836Smrg    Copyright (C) 1998-2022 Free Software Foundation, Inc.
34fee23f9Smrg    Contributed by Ovidiu Predescu.
44fee23f9Smrg 
54fee23f9Smrg This file is part of GCC.
64fee23f9Smrg 
74fee23f9Smrg GCC is free software; you can redistribute it and/or modify
84fee23f9Smrg it under the terms of the GNU General Public License as published by
94fee23f9Smrg the Free Software Foundation; either version 3, or (at your option)
104fee23f9Smrg any later version.
114fee23f9Smrg 
124fee23f9Smrg GCC is distributed in the hope that it will be useful,
134fee23f9Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
144fee23f9Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154fee23f9Smrg GNU General Public License for more details.
164fee23f9Smrg 
174fee23f9Smrg Under Section 7 of GPL version 3, you are granted additional
184fee23f9Smrg permissions described in the GCC Runtime Library Exception, version
194fee23f9Smrg 3.1, as published by the Free Software Foundation.
204fee23f9Smrg 
214fee23f9Smrg You should have received a copy of the GNU General Public License and
224fee23f9Smrg a copy of the GCC Runtime Library Exception along with this program;
234fee23f9Smrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
244fee23f9Smrg <http://www.gnu.org/licenses/>.  */
254fee23f9Smrg 
2648fb7bfaSmrg #include "objc-private/common.h"
274fee23f9Smrg #include "objc/objc.h"
284fee23f9Smrg 
294fee23f9Smrg #if OBJC_WITH_GC
304fee23f9Smrg 
3148fb7bfaSmrg #include "tconfig.h"
3248fb7bfaSmrg #include <assert.h>
3348fb7bfaSmrg #include <ctype.h> /* For isdigit.  */
3448fb7bfaSmrg #include <string.h>
3548fb7bfaSmrg #include <stdlib.h>
3648fb7bfaSmrg #include "objc/runtime.h"
3748fb7bfaSmrg #include "objc-private/module-abi-8.h"
3848fb7bfaSmrg 
39b17d1066Smrg #include <gc/gc.h>
404fee23f9Smrg #include <limits.h>
414fee23f9Smrg 
424fee23f9Smrg /* gc_typed.h uses the following but doesn't declare them */
434fee23f9Smrg typedef GC_word word;
444fee23f9Smrg typedef GC_signed_word signed_word;
454fee23f9Smrg #define BITS_PER_WORD (CHAR_BIT * sizeof (word))
464fee23f9Smrg 
47b17d1066Smrg #include <gc/gc_typed.h>
484fee23f9Smrg 
494fee23f9Smrg /* The following functions set up in `mask` the corresponding pointers.
504fee23f9Smrg    The offset is incremented with the size of the type.  */
514fee23f9Smrg 
524fee23f9Smrg #define ROUND(V, A) \
534fee23f9Smrg   ({ typeof (V) __v = (V); typeof (A) __a = (A); \
544fee23f9Smrg      __a * ((__v+__a - 1)/__a); })
554fee23f9Smrg 
564fee23f9Smrg #define SET_BIT_FOR_OFFSET(mask, offset) \
574fee23f9Smrg   GC_set_bit (mask, offset / sizeof (void *))
584fee23f9Smrg 
594fee23f9Smrg /* Some prototypes */
604fee23f9Smrg static void
614fee23f9Smrg __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
624fee23f9Smrg static void
634fee23f9Smrg __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
644fee23f9Smrg 
654fee23f9Smrg 
664fee23f9Smrg static void
__objc_gc_setup_array(GC_bitmap mask,const char * type,int offset)674fee23f9Smrg __objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
684fee23f9Smrg {
694fee23f9Smrg   int i, len = atoi (type + 1);
704fee23f9Smrg 
714fee23f9Smrg   while (isdigit (*++type))
724fee23f9Smrg     /* do nothing */;		/* skip the size of the array */
734fee23f9Smrg 
744fee23f9Smrg   switch (*type) {
754fee23f9Smrg   case _C_ARY_B:
764fee23f9Smrg     for (i = 0; i < len; i++)
774fee23f9Smrg       __objc_gc_setup_array (mask, type, offset);
784fee23f9Smrg     break;
794fee23f9Smrg 
804fee23f9Smrg   case _C_STRUCT_B:
814fee23f9Smrg     for (i = 0; i < len; i++)
824fee23f9Smrg       __objc_gc_setup_struct (mask, type, offset);
834fee23f9Smrg     break;
844fee23f9Smrg 
854fee23f9Smrg   case _C_UNION_B:
864fee23f9Smrg     for (i = 0; i < len; i++)
874fee23f9Smrg       __objc_gc_setup_union (mask, type, offset);
884fee23f9Smrg     break;
894fee23f9Smrg 
904fee23f9Smrg   default:
914fee23f9Smrg     break;
924fee23f9Smrg   }
934fee23f9Smrg }
944fee23f9Smrg 
954fee23f9Smrg static void
__objc_gc_setup_struct(GC_bitmap mask,const char * type,int offset)964fee23f9Smrg __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
974fee23f9Smrg {
984fee23f9Smrg   struct objc_struct_layout layout;
994fee23f9Smrg   unsigned int position;
1004fee23f9Smrg   const char *mtype;
1014fee23f9Smrg 
1024fee23f9Smrg   objc_layout_structure (type, &layout);
1034fee23f9Smrg 
1044fee23f9Smrg   while (objc_layout_structure_next_member (&layout))
1054fee23f9Smrg     {
1064fee23f9Smrg       BOOL gc_invisible = NO;
1074fee23f9Smrg 
1084fee23f9Smrg       objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
1094fee23f9Smrg 
1104fee23f9Smrg       /* Skip the variable name */
1114fee23f9Smrg       if (*mtype == '"')
1124fee23f9Smrg 	{
1134fee23f9Smrg 	  for (mtype++; *mtype++ != '"';)
1144fee23f9Smrg 	    /* do nothing */;
1154fee23f9Smrg 	}
1164fee23f9Smrg 
1174fee23f9Smrg       if (*mtype == _C_GCINVISIBLE)
1184fee23f9Smrg 	{
1194fee23f9Smrg 	  gc_invisible = YES;
1204fee23f9Smrg 	  mtype++;
1214fee23f9Smrg 	}
1224fee23f9Smrg 
1234fee23f9Smrg       /* Add to position the offset of this structure */
1244fee23f9Smrg       position += offset;
1254fee23f9Smrg 
1264fee23f9Smrg       switch (*mtype) {
1274fee23f9Smrg       case _C_ID:
1284fee23f9Smrg       case _C_CLASS:
1294fee23f9Smrg       case _C_SEL:
1304fee23f9Smrg       case _C_PTR:
1314fee23f9Smrg       case _C_CHARPTR:
1324fee23f9Smrg       case _C_ATOM:
1334fee23f9Smrg 	if (! gc_invisible)
1344fee23f9Smrg 	  SET_BIT_FOR_OFFSET (mask, position);
1354fee23f9Smrg 	break;
1364fee23f9Smrg 
1374fee23f9Smrg       case _C_ARY_B:
1384fee23f9Smrg 	__objc_gc_setup_array (mask, mtype, position);
1394fee23f9Smrg 	break;
1404fee23f9Smrg 
1414fee23f9Smrg       case _C_STRUCT_B:
1424fee23f9Smrg 	__objc_gc_setup_struct (mask, mtype, position);
1434fee23f9Smrg 	break;
1444fee23f9Smrg 
1454fee23f9Smrg       case _C_UNION_B:
1464fee23f9Smrg 	__objc_gc_setup_union (mask, mtype, position);
1474fee23f9Smrg 	break;
1484fee23f9Smrg 
1494fee23f9Smrg       default:
1504fee23f9Smrg         break;
1514fee23f9Smrg       }
1524fee23f9Smrg     }
1534fee23f9Smrg }
1544fee23f9Smrg 
1554fee23f9Smrg static void
__objc_gc_setup_union(GC_bitmap mask,const char * type,int offset)1564fee23f9Smrg __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
1574fee23f9Smrg {
1584fee23f9Smrg   /* Sub-optimal, quick implementation: assume the union is made of
1594fee23f9Smrg      pointers, set up the mask accordingly. */
1604fee23f9Smrg 
1614fee23f9Smrg   int i, size, align;
1624fee23f9Smrg 
1634fee23f9Smrg   /* Skip the variable name */
1644fee23f9Smrg   if (*type == '"')
1654fee23f9Smrg     {
1664fee23f9Smrg       for (type++; *type++ != '"';)
1674fee23f9Smrg 	/* do nothing */;
1684fee23f9Smrg     }
1694fee23f9Smrg 
1704fee23f9Smrg   size = objc_sizeof_type (type);
1714fee23f9Smrg   align = objc_alignof_type (type);
1724fee23f9Smrg 
1734fee23f9Smrg   offset = ROUND (offset, align);
1744fee23f9Smrg   for (i = 0; i < size; i += sizeof (void *))
1754fee23f9Smrg     {
1764fee23f9Smrg       SET_BIT_FOR_OFFSET (mask, offset);
1774fee23f9Smrg       offset += sizeof (void *);
1784fee23f9Smrg     }
1794fee23f9Smrg }
1804fee23f9Smrg 
1814fee23f9Smrg 
1824fee23f9Smrg /* Iterates over the types in the structure that represents the class
1834fee23f9Smrg    encoding and sets the bits in mask according to each ivar type.  */
1844fee23f9Smrg static void
__objc_gc_type_description_from_type(GC_bitmap mask,const char * type)1854fee23f9Smrg __objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
1864fee23f9Smrg {
1874fee23f9Smrg   struct objc_struct_layout layout;
1884fee23f9Smrg   unsigned int offset, align;
1894fee23f9Smrg   const char *ivar_type;
1904fee23f9Smrg 
1914fee23f9Smrg   objc_layout_structure (type, &layout);
1924fee23f9Smrg 
1934fee23f9Smrg   while (objc_layout_structure_next_member (&layout))
1944fee23f9Smrg     {
1954fee23f9Smrg       BOOL gc_invisible = NO;
1964fee23f9Smrg 
1974fee23f9Smrg       objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
1984fee23f9Smrg 
1994fee23f9Smrg       /* Skip the variable name */
2004fee23f9Smrg       if (*ivar_type == '"')
2014fee23f9Smrg 	{
2024fee23f9Smrg 	  for (ivar_type++; *ivar_type++ != '"';)
2034fee23f9Smrg 	    /* do nothing */;
2044fee23f9Smrg 	}
2054fee23f9Smrg 
2064fee23f9Smrg       if (*ivar_type == _C_GCINVISIBLE)
2074fee23f9Smrg 	{
2084fee23f9Smrg 	  gc_invisible = YES;
2094fee23f9Smrg 	  ivar_type++;
2104fee23f9Smrg 	}
2114fee23f9Smrg 
2124fee23f9Smrg       switch (*ivar_type) {
2134fee23f9Smrg       case _C_ID:
2144fee23f9Smrg       case _C_CLASS:
2154fee23f9Smrg       case _C_SEL:
2164fee23f9Smrg       case _C_PTR:
2174fee23f9Smrg       case _C_CHARPTR:
2184fee23f9Smrg         if (! gc_invisible)
2194fee23f9Smrg           SET_BIT_FOR_OFFSET (mask, offset);
2204fee23f9Smrg 	break;
2214fee23f9Smrg 
2224fee23f9Smrg       case _C_ARY_B:
2234fee23f9Smrg 	__objc_gc_setup_array (mask, ivar_type, offset);
2244fee23f9Smrg 	break;
2254fee23f9Smrg 
2264fee23f9Smrg       case _C_STRUCT_B:
2274fee23f9Smrg 	__objc_gc_setup_struct (mask, ivar_type, offset);
2284fee23f9Smrg 	break;
2294fee23f9Smrg 
2304fee23f9Smrg       case _C_UNION_B:
2314fee23f9Smrg 	__objc_gc_setup_union (mask, ivar_type, offset);
2324fee23f9Smrg 	break;
2334fee23f9Smrg 
2344fee23f9Smrg       default:
2354fee23f9Smrg         break;
2364fee23f9Smrg       }
2374fee23f9Smrg     }
2384fee23f9Smrg }
2394fee23f9Smrg 
2404fee23f9Smrg /* Computes in *type the full type encoding of this class including
2414fee23f9Smrg    its super classes. '*size' gives the total number of bytes allocated
2424fee23f9Smrg    into *type, '*current' the number of bytes used so far by the
2434fee23f9Smrg    encoding. */
2444fee23f9Smrg static void
__objc_class_structure_encoding(Class class,char ** type,int * size,int * current)2454fee23f9Smrg __objc_class_structure_encoding (Class class, char **type, int *size,
2464fee23f9Smrg                                  int *current)
2474fee23f9Smrg {
2484fee23f9Smrg   int i, ivar_count;
2494fee23f9Smrg   struct objc_ivar_list *ivars;
2504fee23f9Smrg 
2514fee23f9Smrg   if (! class)
2524fee23f9Smrg     {
2534fee23f9Smrg       strcat (*type, "{");
2544fee23f9Smrg       (*current)++;
2554fee23f9Smrg       return;
2564fee23f9Smrg     }
2574fee23f9Smrg 
2584fee23f9Smrg   /* Add the type encodings of the super classes */
2594fee23f9Smrg   __objc_class_structure_encoding (class->super_class, type, size, current);
2604fee23f9Smrg 
2614fee23f9Smrg   ivars = class->ivars;
2624fee23f9Smrg   if (! ivars)
2634fee23f9Smrg     return;
2644fee23f9Smrg 
2654fee23f9Smrg   ivar_count = ivars->ivar_count;
2664fee23f9Smrg 
2674fee23f9Smrg   for (i = 0; i < ivar_count; i++)
2684fee23f9Smrg     {
2694fee23f9Smrg       struct objc_ivar *ivar = &(ivars->ivar_list[i]);
2704fee23f9Smrg       const char *ivar_type = ivar->ivar_type;
2714fee23f9Smrg       int len = strlen (ivar_type);
2724fee23f9Smrg 
2734fee23f9Smrg       if (*current + len + 1 >= *size)
2744fee23f9Smrg         {
2754fee23f9Smrg           /* Increase the size of the encoding string so that it
2764fee23f9Smrg              contains this ivar's type. */
2774fee23f9Smrg           *size = ROUND (*current + len + 1, 10);
2784fee23f9Smrg           *type = objc_realloc (*type, *size);
2794fee23f9Smrg         }
2804fee23f9Smrg       strcat (*type + *current, ivar_type);
2814fee23f9Smrg       *current += len;
2824fee23f9Smrg     }
2834fee23f9Smrg }
2844fee23f9Smrg 
2854fee23f9Smrg 
2864fee23f9Smrg /* Allocates the memory that will hold the type description for class
2874fee23f9Smrg    and calls the __objc_class_structure_encoding that generates this
2884fee23f9Smrg    value. */
2894fee23f9Smrg void
__objc_generate_gc_type_description(Class class)2904fee23f9Smrg __objc_generate_gc_type_description (Class class)
2914fee23f9Smrg {
2924fee23f9Smrg   GC_bitmap mask;
2934fee23f9Smrg   int bits_no, size;
2944fee23f9Smrg   int type_size = 10, current;
2954fee23f9Smrg   char *class_structure_type;
2964fee23f9Smrg 
2974fee23f9Smrg   if (! CLS_ISCLASS (class))
2984fee23f9Smrg     return;
2994fee23f9Smrg 
3004fee23f9Smrg   /* We have to create a mask in which each bit counts for a pointer member.
3014fee23f9Smrg      We take into consideration all the non-pointer instance variables and we
3024fee23f9Smrg      round them up to the alignment. */
3034fee23f9Smrg 
3044fee23f9Smrg   /* The number of bits in the mask is the size of an instance in bytes divided
3054fee23f9Smrg      by the size of a pointer. */
30648fb7bfaSmrg   bits_no = (ROUND (class_getInstanceSize (class), sizeof (void *))
3074fee23f9Smrg              / sizeof (void *));
3084fee23f9Smrg   size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
3094fee23f9Smrg   mask = objc_atomic_malloc (size * sizeof (int));
3104fee23f9Smrg   memset (mask, 0, size * sizeof (int));
3114fee23f9Smrg 
3124fee23f9Smrg   class_structure_type = objc_atomic_malloc (type_size);
3134fee23f9Smrg   *class_structure_type = current = 0;
3144fee23f9Smrg   __objc_class_structure_encoding (class, &class_structure_type,
3154fee23f9Smrg                                    &type_size, &current);
3164fee23f9Smrg   if (current + 1 == type_size)
3174fee23f9Smrg     class_structure_type = objc_realloc (class_structure_type, ++type_size);
3184fee23f9Smrg   strcat (class_structure_type + current, "}");
3194fee23f9Smrg #ifdef DEBUG
3204fee23f9Smrg   printf ("type description for '%s' is %s\n", class->name, class_structure_type);
3214fee23f9Smrg #endif
3224fee23f9Smrg 
3234fee23f9Smrg   __objc_gc_type_description_from_type (mask, class_structure_type);
3244fee23f9Smrg   objc_free (class_structure_type);
3254fee23f9Smrg 
3264fee23f9Smrg #ifdef DEBUG
3274fee23f9Smrg   printf ("  mask for '%s', type '%s' (bits %d, mask size %d) is:",
3284fee23f9Smrg 	  class_structure_type, class->name, bits_no, size);
3294fee23f9Smrg   {
3304fee23f9Smrg     int i;
3314fee23f9Smrg     for (i = 0; i < size; i++)
3324fee23f9Smrg       printf (" %lx", mask[i]);
3334fee23f9Smrg   }
3344fee23f9Smrg   puts ("");
3354fee23f9Smrg #endif
3364fee23f9Smrg 
3374fee23f9Smrg   class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no);
3384fee23f9Smrg }
3394fee23f9Smrg 
3404fee23f9Smrg 
3414fee23f9Smrg /* Returns YES if type denotes a pointer type, NO otherwise */
3424fee23f9Smrg static inline BOOL
__objc_ivar_pointer(const char * type)3434fee23f9Smrg __objc_ivar_pointer (const char *type)
3444fee23f9Smrg {
3454fee23f9Smrg   type = objc_skip_type_qualifiers (type);
3464fee23f9Smrg 
3474fee23f9Smrg   return (*type == _C_ID
3484fee23f9Smrg           || *type == _C_CLASS
3494fee23f9Smrg           || *type == _C_SEL
3504fee23f9Smrg           || *type == _C_PTR
3514fee23f9Smrg           || *type == _C_CHARPTR
3524fee23f9Smrg           || *type == _C_ATOM);
3534fee23f9Smrg }
3544fee23f9Smrg 
3554fee23f9Smrg 
3564fee23f9Smrg /* Mark the instance variable whose name is given by ivarname as a
3574fee23f9Smrg    weak pointer (a pointer hidden to the garbage collector) if
3584fee23f9Smrg    gc_invisible is true. If gc_invisible is false it unmarks the
3594fee23f9Smrg    instance variable and makes it a normal pointer, visible to the
3604fee23f9Smrg    garbage collector.
3614fee23f9Smrg 
3624fee23f9Smrg    This operation only makes sense on instance variables that are
3634fee23f9Smrg    pointers.  */
3644fee23f9Smrg void
class_ivar_set_gcinvisible(Class class,const char * ivarname,BOOL gc_invisible)3654fee23f9Smrg class_ivar_set_gcinvisible (Class class, const char *ivarname,
3664fee23f9Smrg                             BOOL gc_invisible)
3674fee23f9Smrg {
3684fee23f9Smrg   int i, ivar_count;
3694fee23f9Smrg   struct objc_ivar_list *ivars;
3704fee23f9Smrg 
3714fee23f9Smrg   if (! class || ! ivarname)
3724fee23f9Smrg     return;
3734fee23f9Smrg 
3744fee23f9Smrg   ivars = class->ivars;
3754fee23f9Smrg   if (! ivars)
3764fee23f9Smrg     return;
3774fee23f9Smrg 
3784fee23f9Smrg   ivar_count = ivars->ivar_count;
3794fee23f9Smrg 
3804fee23f9Smrg   for (i = 0; i < ivar_count; i++)
3814fee23f9Smrg     {
3824fee23f9Smrg       struct objc_ivar *ivar = &(ivars->ivar_list[i]);
3834fee23f9Smrg       const char *type;
3844fee23f9Smrg 
3854fee23f9Smrg       if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
3864fee23f9Smrg 	continue;
3874fee23f9Smrg 
3884fee23f9Smrg       assert (ivar->ivar_type);
3894fee23f9Smrg       type = ivar->ivar_type;
3904fee23f9Smrg 
3914fee23f9Smrg       /* Skip the variable name */
3924fee23f9Smrg       if (*type == '"')
3934fee23f9Smrg 	{
3944fee23f9Smrg 	  for (type++; *type++ != '"';)
3954fee23f9Smrg 	    /* do nothing */;
3964fee23f9Smrg 	}
3974fee23f9Smrg 
3984fee23f9Smrg       if (*type == _C_GCINVISIBLE)
3994fee23f9Smrg 	{
4004fee23f9Smrg 	  char *new_type;
4014fee23f9Smrg 	  size_t len;
4024fee23f9Smrg 
4034fee23f9Smrg 	  if (gc_invisible || ! __objc_ivar_pointer (type))
4044fee23f9Smrg 	    return;	/* The type of the variable already matches the
4054fee23f9Smrg 			   requested gc_invisible type */
4064fee23f9Smrg 
4074fee23f9Smrg 	  /* The variable is gc_invisible so we make it gc visible.  */
4084fee23f9Smrg 	  new_type = objc_atomic_malloc (strlen(ivar->ivar_type));
4094fee23f9Smrg 	  len = (type - ivar->ivar_type);
4104fee23f9Smrg 	  memcpy (new_type, ivar->ivar_type, len);
4114fee23f9Smrg 	  new_type[len] = 0;
4124fee23f9Smrg 	  strcat (new_type, type + 1);
4134fee23f9Smrg 	  ivar->ivar_type = new_type;
4144fee23f9Smrg 	}
4154fee23f9Smrg       else
4164fee23f9Smrg 	{
4174fee23f9Smrg 	  char *new_type;
4184fee23f9Smrg 	  size_t len;
4194fee23f9Smrg 
4204fee23f9Smrg 	  if (! gc_invisible || ! __objc_ivar_pointer (type))
4214fee23f9Smrg 	    return;	/* The type of the variable already matches the
4224fee23f9Smrg 			   requested gc_invisible type */
4234fee23f9Smrg 
4244fee23f9Smrg 	  /* The variable is gc visible so we make it gc_invisible.  */
4254fee23f9Smrg 	  new_type = objc_malloc (strlen(ivar->ivar_type) + 2);
42648fb7bfaSmrg 
42748fb7bfaSmrg 	  /* Copy the variable name.  */
4284fee23f9Smrg 	  len = (type - ivar->ivar_type);
4294fee23f9Smrg 	  memcpy (new_type, ivar->ivar_type, len);
43048fb7bfaSmrg 	  /* Add '!'.  */
43148fb7bfaSmrg 	  new_type[len++] = _C_GCINVISIBLE;
43248fb7bfaSmrg 	  /* Copy the original types.  */
43348fb7bfaSmrg 	  strcpy (new_type + len, type);
43448fb7bfaSmrg 
4354fee23f9Smrg 	  ivar->ivar_type = new_type;
4364fee23f9Smrg 	}
4374fee23f9Smrg 
4384fee23f9Smrg       __objc_generate_gc_type_description (class);
4394fee23f9Smrg       return;
4404fee23f9Smrg     }
4414fee23f9Smrg 
4424fee23f9Smrg   /* Search the instance variable in the superclasses */
4434fee23f9Smrg   class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
4444fee23f9Smrg }
4454fee23f9Smrg 
4464fee23f9Smrg #else /* !OBJC_WITH_GC */
4474fee23f9Smrg 
4484fee23f9Smrg void
__objc_generate_gc_type_description(Class class)4494fee23f9Smrg __objc_generate_gc_type_description (Class class __attribute__ ((__unused__)))
4504fee23f9Smrg {
4514fee23f9Smrg }
4524fee23f9Smrg 
class_ivar_set_gcinvisible(Class class,const char * ivarname,BOOL gc_invisible)4534fee23f9Smrg void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)),
4544fee23f9Smrg 				 const char *ivarname __attribute__ ((__unused__)),
4554fee23f9Smrg 				 BOOL gc_invisible __attribute__ ((__unused__)))
4564fee23f9Smrg {
4574fee23f9Smrg }
4584fee23f9Smrg 
4594fee23f9Smrg #endif /* OBJC_WITH_GC */
460