1*e4b17023SJohn Marino /* Basic data types for Objective C.
2*e4b17023SJohn Marino Copyright (C) 1998, 2002, 2004, 2005, 2006, 2009, 2010
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Ovidiu Predescu.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino any later version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16*e4b17023SJohn Marino GNU General Public License for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino Under Section 7 of GPL version 3, you are granted additional
19*e4b17023SJohn Marino permissions described in the GCC Runtime Library Exception, version
20*e4b17023SJohn Marino 3.1, as published by the Free Software Foundation.
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino You should have received a copy of the GNU General Public License and
23*e4b17023SJohn Marino a copy of the GCC Runtime Library Exception along with this program;
24*e4b17023SJohn Marino see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino #include "objc-private/common.h"
28*e4b17023SJohn Marino #include "objc/objc.h"
29*e4b17023SJohn Marino
30*e4b17023SJohn Marino #if OBJC_WITH_GC
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino #include "tconfig.h"
33*e4b17023SJohn Marino #include <assert.h>
34*e4b17023SJohn Marino #include <ctype.h> /* For isdigit. */
35*e4b17023SJohn Marino #include <string.h>
36*e4b17023SJohn Marino #include <stdlib.h>
37*e4b17023SJohn Marino #include "objc/runtime.h"
38*e4b17023SJohn Marino #include "objc-private/module-abi-8.h"
39*e4b17023SJohn Marino
40*e4b17023SJohn Marino #include <gc.h>
41*e4b17023SJohn Marino #include <limits.h>
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino /* gc_typed.h uses the following but doesn't declare them */
44*e4b17023SJohn Marino typedef GC_word word;
45*e4b17023SJohn Marino typedef GC_signed_word signed_word;
46*e4b17023SJohn Marino #define BITS_PER_WORD (CHAR_BIT * sizeof (word))
47*e4b17023SJohn Marino
48*e4b17023SJohn Marino #include <gc_typed.h>
49*e4b17023SJohn Marino
50*e4b17023SJohn Marino /* The following functions set up in `mask` the corresponding pointers.
51*e4b17023SJohn Marino The offset is incremented with the size of the type. */
52*e4b17023SJohn Marino
53*e4b17023SJohn Marino #define ROUND(V, A) \
54*e4b17023SJohn Marino ({ typeof (V) __v = (V); typeof (A) __a = (A); \
55*e4b17023SJohn Marino __a * ((__v+__a - 1)/__a); })
56*e4b17023SJohn Marino
57*e4b17023SJohn Marino #define SET_BIT_FOR_OFFSET(mask, offset) \
58*e4b17023SJohn Marino GC_set_bit (mask, offset / sizeof (void *))
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino /* Some prototypes */
61*e4b17023SJohn Marino static void
62*e4b17023SJohn Marino __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset);
63*e4b17023SJohn Marino static void
64*e4b17023SJohn Marino __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset);
65*e4b17023SJohn Marino
66*e4b17023SJohn Marino
67*e4b17023SJohn Marino static void
__objc_gc_setup_array(GC_bitmap mask,const char * type,int offset)68*e4b17023SJohn Marino __objc_gc_setup_array (GC_bitmap mask, const char *type, int offset)
69*e4b17023SJohn Marino {
70*e4b17023SJohn Marino int i, len = atoi (type + 1);
71*e4b17023SJohn Marino
72*e4b17023SJohn Marino while (isdigit (*++type))
73*e4b17023SJohn Marino /* do nothing */; /* skip the size of the array */
74*e4b17023SJohn Marino
75*e4b17023SJohn Marino switch (*type) {
76*e4b17023SJohn Marino case _C_ARY_B:
77*e4b17023SJohn Marino for (i = 0; i < len; i++)
78*e4b17023SJohn Marino __objc_gc_setup_array (mask, type, offset);
79*e4b17023SJohn Marino break;
80*e4b17023SJohn Marino
81*e4b17023SJohn Marino case _C_STRUCT_B:
82*e4b17023SJohn Marino for (i = 0; i < len; i++)
83*e4b17023SJohn Marino __objc_gc_setup_struct (mask, type, offset);
84*e4b17023SJohn Marino break;
85*e4b17023SJohn Marino
86*e4b17023SJohn Marino case _C_UNION_B:
87*e4b17023SJohn Marino for (i = 0; i < len; i++)
88*e4b17023SJohn Marino __objc_gc_setup_union (mask, type, offset);
89*e4b17023SJohn Marino break;
90*e4b17023SJohn Marino
91*e4b17023SJohn Marino default:
92*e4b17023SJohn Marino break;
93*e4b17023SJohn Marino }
94*e4b17023SJohn Marino }
95*e4b17023SJohn Marino
96*e4b17023SJohn Marino static void
__objc_gc_setup_struct(GC_bitmap mask,const char * type,int offset)97*e4b17023SJohn Marino __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset)
98*e4b17023SJohn Marino {
99*e4b17023SJohn Marino struct objc_struct_layout layout;
100*e4b17023SJohn Marino unsigned int position;
101*e4b17023SJohn Marino const char *mtype;
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino objc_layout_structure (type, &layout);
104*e4b17023SJohn Marino
105*e4b17023SJohn Marino while (objc_layout_structure_next_member (&layout))
106*e4b17023SJohn Marino {
107*e4b17023SJohn Marino BOOL gc_invisible = NO;
108*e4b17023SJohn Marino
109*e4b17023SJohn Marino objc_layout_structure_get_info (&layout, &position, NULL, &mtype);
110*e4b17023SJohn Marino
111*e4b17023SJohn Marino /* Skip the variable name */
112*e4b17023SJohn Marino if (*mtype == '"')
113*e4b17023SJohn Marino {
114*e4b17023SJohn Marino for (mtype++; *mtype++ != '"';)
115*e4b17023SJohn Marino /* do nothing */;
116*e4b17023SJohn Marino }
117*e4b17023SJohn Marino
118*e4b17023SJohn Marino if (*mtype == _C_GCINVISIBLE)
119*e4b17023SJohn Marino {
120*e4b17023SJohn Marino gc_invisible = YES;
121*e4b17023SJohn Marino mtype++;
122*e4b17023SJohn Marino }
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino /* Add to position the offset of this structure */
125*e4b17023SJohn Marino position += offset;
126*e4b17023SJohn Marino
127*e4b17023SJohn Marino switch (*mtype) {
128*e4b17023SJohn Marino case _C_ID:
129*e4b17023SJohn Marino case _C_CLASS:
130*e4b17023SJohn Marino case _C_SEL:
131*e4b17023SJohn Marino case _C_PTR:
132*e4b17023SJohn Marino case _C_CHARPTR:
133*e4b17023SJohn Marino case _C_ATOM:
134*e4b17023SJohn Marino if (! gc_invisible)
135*e4b17023SJohn Marino SET_BIT_FOR_OFFSET (mask, position);
136*e4b17023SJohn Marino break;
137*e4b17023SJohn Marino
138*e4b17023SJohn Marino case _C_ARY_B:
139*e4b17023SJohn Marino __objc_gc_setup_array (mask, mtype, position);
140*e4b17023SJohn Marino break;
141*e4b17023SJohn Marino
142*e4b17023SJohn Marino case _C_STRUCT_B:
143*e4b17023SJohn Marino __objc_gc_setup_struct (mask, mtype, position);
144*e4b17023SJohn Marino break;
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino case _C_UNION_B:
147*e4b17023SJohn Marino __objc_gc_setup_union (mask, mtype, position);
148*e4b17023SJohn Marino break;
149*e4b17023SJohn Marino
150*e4b17023SJohn Marino default:
151*e4b17023SJohn Marino break;
152*e4b17023SJohn Marino }
153*e4b17023SJohn Marino }
154*e4b17023SJohn Marino }
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino static void
__objc_gc_setup_union(GC_bitmap mask,const char * type,int offset)157*e4b17023SJohn Marino __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino /* Sub-optimal, quick implementation: assume the union is made of
160*e4b17023SJohn Marino pointers, set up the mask accordingly. */
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino int i, size, align;
163*e4b17023SJohn Marino
164*e4b17023SJohn Marino /* Skip the variable name */
165*e4b17023SJohn Marino if (*type == '"')
166*e4b17023SJohn Marino {
167*e4b17023SJohn Marino for (type++; *type++ != '"';)
168*e4b17023SJohn Marino /* do nothing */;
169*e4b17023SJohn Marino }
170*e4b17023SJohn Marino
171*e4b17023SJohn Marino size = objc_sizeof_type (type);
172*e4b17023SJohn Marino align = objc_alignof_type (type);
173*e4b17023SJohn Marino
174*e4b17023SJohn Marino offset = ROUND (offset, align);
175*e4b17023SJohn Marino for (i = 0; i < size; i += sizeof (void *))
176*e4b17023SJohn Marino {
177*e4b17023SJohn Marino SET_BIT_FOR_OFFSET (mask, offset);
178*e4b17023SJohn Marino offset += sizeof (void *);
179*e4b17023SJohn Marino }
180*e4b17023SJohn Marino }
181*e4b17023SJohn Marino
182*e4b17023SJohn Marino
183*e4b17023SJohn Marino /* Iterates over the types in the structure that represents the class
184*e4b17023SJohn Marino encoding and sets the bits in mask according to each ivar type. */
185*e4b17023SJohn Marino static void
__objc_gc_type_description_from_type(GC_bitmap mask,const char * type)186*e4b17023SJohn Marino __objc_gc_type_description_from_type (GC_bitmap mask, const char *type)
187*e4b17023SJohn Marino {
188*e4b17023SJohn Marino struct objc_struct_layout layout;
189*e4b17023SJohn Marino unsigned int offset, align;
190*e4b17023SJohn Marino const char *ivar_type;
191*e4b17023SJohn Marino
192*e4b17023SJohn Marino objc_layout_structure (type, &layout);
193*e4b17023SJohn Marino
194*e4b17023SJohn Marino while (objc_layout_structure_next_member (&layout))
195*e4b17023SJohn Marino {
196*e4b17023SJohn Marino BOOL gc_invisible = NO;
197*e4b17023SJohn Marino
198*e4b17023SJohn Marino objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type);
199*e4b17023SJohn Marino
200*e4b17023SJohn Marino /* Skip the variable name */
201*e4b17023SJohn Marino if (*ivar_type == '"')
202*e4b17023SJohn Marino {
203*e4b17023SJohn Marino for (ivar_type++; *ivar_type++ != '"';)
204*e4b17023SJohn Marino /* do nothing */;
205*e4b17023SJohn Marino }
206*e4b17023SJohn Marino
207*e4b17023SJohn Marino if (*ivar_type == _C_GCINVISIBLE)
208*e4b17023SJohn Marino {
209*e4b17023SJohn Marino gc_invisible = YES;
210*e4b17023SJohn Marino ivar_type++;
211*e4b17023SJohn Marino }
212*e4b17023SJohn Marino
213*e4b17023SJohn Marino switch (*ivar_type) {
214*e4b17023SJohn Marino case _C_ID:
215*e4b17023SJohn Marino case _C_CLASS:
216*e4b17023SJohn Marino case _C_SEL:
217*e4b17023SJohn Marino case _C_PTR:
218*e4b17023SJohn Marino case _C_CHARPTR:
219*e4b17023SJohn Marino if (! gc_invisible)
220*e4b17023SJohn Marino SET_BIT_FOR_OFFSET (mask, offset);
221*e4b17023SJohn Marino break;
222*e4b17023SJohn Marino
223*e4b17023SJohn Marino case _C_ARY_B:
224*e4b17023SJohn Marino __objc_gc_setup_array (mask, ivar_type, offset);
225*e4b17023SJohn Marino break;
226*e4b17023SJohn Marino
227*e4b17023SJohn Marino case _C_STRUCT_B:
228*e4b17023SJohn Marino __objc_gc_setup_struct (mask, ivar_type, offset);
229*e4b17023SJohn Marino break;
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino case _C_UNION_B:
232*e4b17023SJohn Marino __objc_gc_setup_union (mask, ivar_type, offset);
233*e4b17023SJohn Marino break;
234*e4b17023SJohn Marino
235*e4b17023SJohn Marino default:
236*e4b17023SJohn Marino break;
237*e4b17023SJohn Marino }
238*e4b17023SJohn Marino }
239*e4b17023SJohn Marino }
240*e4b17023SJohn Marino
241*e4b17023SJohn Marino /* Computes in *type the full type encoding of this class including
242*e4b17023SJohn Marino its super classes. '*size' gives the total number of bytes allocated
243*e4b17023SJohn Marino into *type, '*current' the number of bytes used so far by the
244*e4b17023SJohn Marino encoding. */
245*e4b17023SJohn Marino static void
__objc_class_structure_encoding(Class class,char ** type,int * size,int * current)246*e4b17023SJohn Marino __objc_class_structure_encoding (Class class, char **type, int *size,
247*e4b17023SJohn Marino int *current)
248*e4b17023SJohn Marino {
249*e4b17023SJohn Marino int i, ivar_count;
250*e4b17023SJohn Marino struct objc_ivar_list *ivars;
251*e4b17023SJohn Marino
252*e4b17023SJohn Marino if (! class)
253*e4b17023SJohn Marino {
254*e4b17023SJohn Marino strcat (*type, "{");
255*e4b17023SJohn Marino (*current)++;
256*e4b17023SJohn Marino return;
257*e4b17023SJohn Marino }
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino /* Add the type encodings of the super classes */
260*e4b17023SJohn Marino __objc_class_structure_encoding (class->super_class, type, size, current);
261*e4b17023SJohn Marino
262*e4b17023SJohn Marino ivars = class->ivars;
263*e4b17023SJohn Marino if (! ivars)
264*e4b17023SJohn Marino return;
265*e4b17023SJohn Marino
266*e4b17023SJohn Marino ivar_count = ivars->ivar_count;
267*e4b17023SJohn Marino
268*e4b17023SJohn Marino for (i = 0; i < ivar_count; i++)
269*e4b17023SJohn Marino {
270*e4b17023SJohn Marino struct objc_ivar *ivar = &(ivars->ivar_list[i]);
271*e4b17023SJohn Marino const char *ivar_type = ivar->ivar_type;
272*e4b17023SJohn Marino int len = strlen (ivar_type);
273*e4b17023SJohn Marino
274*e4b17023SJohn Marino if (*current + len + 1 >= *size)
275*e4b17023SJohn Marino {
276*e4b17023SJohn Marino /* Increase the size of the encoding string so that it
277*e4b17023SJohn Marino contains this ivar's type. */
278*e4b17023SJohn Marino *size = ROUND (*current + len + 1, 10);
279*e4b17023SJohn Marino *type = objc_realloc (*type, *size);
280*e4b17023SJohn Marino }
281*e4b17023SJohn Marino strcat (*type + *current, ivar_type);
282*e4b17023SJohn Marino *current += len;
283*e4b17023SJohn Marino }
284*e4b17023SJohn Marino }
285*e4b17023SJohn Marino
286*e4b17023SJohn Marino
287*e4b17023SJohn Marino /* Allocates the memory that will hold the type description for class
288*e4b17023SJohn Marino and calls the __objc_class_structure_encoding that generates this
289*e4b17023SJohn Marino value. */
290*e4b17023SJohn Marino void
__objc_generate_gc_type_description(Class class)291*e4b17023SJohn Marino __objc_generate_gc_type_description (Class class)
292*e4b17023SJohn Marino {
293*e4b17023SJohn Marino GC_bitmap mask;
294*e4b17023SJohn Marino int bits_no, size;
295*e4b17023SJohn Marino int type_size = 10, current;
296*e4b17023SJohn Marino char *class_structure_type;
297*e4b17023SJohn Marino
298*e4b17023SJohn Marino if (! CLS_ISCLASS (class))
299*e4b17023SJohn Marino return;
300*e4b17023SJohn Marino
301*e4b17023SJohn Marino /* We have to create a mask in which each bit counts for a pointer member.
302*e4b17023SJohn Marino We take into consideration all the non-pointer instance variables and we
303*e4b17023SJohn Marino round them up to the alignment. */
304*e4b17023SJohn Marino
305*e4b17023SJohn Marino /* The number of bits in the mask is the size of an instance in bytes divided
306*e4b17023SJohn Marino by the size of a pointer. */
307*e4b17023SJohn Marino bits_no = (ROUND (class_getInstanceSize (class), sizeof (void *))
308*e4b17023SJohn Marino / sizeof (void *));
309*e4b17023SJohn Marino size = ROUND (bits_no, BITS_PER_WORD) / BITS_PER_WORD;
310*e4b17023SJohn Marino mask = objc_atomic_malloc (size * sizeof (int));
311*e4b17023SJohn Marino memset (mask, 0, size * sizeof (int));
312*e4b17023SJohn Marino
313*e4b17023SJohn Marino class_structure_type = objc_atomic_malloc (type_size);
314*e4b17023SJohn Marino *class_structure_type = current = 0;
315*e4b17023SJohn Marino __objc_class_structure_encoding (class, &class_structure_type,
316*e4b17023SJohn Marino &type_size, ¤t);
317*e4b17023SJohn Marino if (current + 1 == type_size)
318*e4b17023SJohn Marino class_structure_type = objc_realloc (class_structure_type, ++type_size);
319*e4b17023SJohn Marino strcat (class_structure_type + current, "}");
320*e4b17023SJohn Marino #ifdef DEBUG
321*e4b17023SJohn Marino printf ("type description for '%s' is %s\n", class->name, class_structure_type);
322*e4b17023SJohn Marino #endif
323*e4b17023SJohn Marino
324*e4b17023SJohn Marino __objc_gc_type_description_from_type (mask, class_structure_type);
325*e4b17023SJohn Marino objc_free (class_structure_type);
326*e4b17023SJohn Marino
327*e4b17023SJohn Marino #ifdef DEBUG
328*e4b17023SJohn Marino printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
329*e4b17023SJohn Marino class_structure_type, class->name, bits_no, size);
330*e4b17023SJohn Marino {
331*e4b17023SJohn Marino int i;
332*e4b17023SJohn Marino for (i = 0; i < size; i++)
333*e4b17023SJohn Marino printf (" %lx", mask[i]);
334*e4b17023SJohn Marino }
335*e4b17023SJohn Marino puts ("");
336*e4b17023SJohn Marino #endif
337*e4b17023SJohn Marino
338*e4b17023SJohn Marino class->gc_object_type = (void *) GC_make_descriptor (mask, bits_no);
339*e4b17023SJohn Marino }
340*e4b17023SJohn Marino
341*e4b17023SJohn Marino
342*e4b17023SJohn Marino /* Returns YES if type denotes a pointer type, NO otherwise */
343*e4b17023SJohn Marino static inline BOOL
__objc_ivar_pointer(const char * type)344*e4b17023SJohn Marino __objc_ivar_pointer (const char *type)
345*e4b17023SJohn Marino {
346*e4b17023SJohn Marino type = objc_skip_type_qualifiers (type);
347*e4b17023SJohn Marino
348*e4b17023SJohn Marino return (*type == _C_ID
349*e4b17023SJohn Marino || *type == _C_CLASS
350*e4b17023SJohn Marino || *type == _C_SEL
351*e4b17023SJohn Marino || *type == _C_PTR
352*e4b17023SJohn Marino || *type == _C_CHARPTR
353*e4b17023SJohn Marino || *type == _C_ATOM);
354*e4b17023SJohn Marino }
355*e4b17023SJohn Marino
356*e4b17023SJohn Marino
357*e4b17023SJohn Marino /* Mark the instance variable whose name is given by ivarname as a
358*e4b17023SJohn Marino weak pointer (a pointer hidden to the garbage collector) if
359*e4b17023SJohn Marino gc_invisible is true. If gc_invisible is false it unmarks the
360*e4b17023SJohn Marino instance variable and makes it a normal pointer, visible to the
361*e4b17023SJohn Marino garbage collector.
362*e4b17023SJohn Marino
363*e4b17023SJohn Marino This operation only makes sense on instance variables that are
364*e4b17023SJohn Marino pointers. */
365*e4b17023SJohn Marino void
class_ivar_set_gcinvisible(Class class,const char * ivarname,BOOL gc_invisible)366*e4b17023SJohn Marino class_ivar_set_gcinvisible (Class class, const char *ivarname,
367*e4b17023SJohn Marino BOOL gc_invisible)
368*e4b17023SJohn Marino {
369*e4b17023SJohn Marino int i, ivar_count;
370*e4b17023SJohn Marino struct objc_ivar_list *ivars;
371*e4b17023SJohn Marino
372*e4b17023SJohn Marino if (! class || ! ivarname)
373*e4b17023SJohn Marino return;
374*e4b17023SJohn Marino
375*e4b17023SJohn Marino ivars = class->ivars;
376*e4b17023SJohn Marino if (! ivars)
377*e4b17023SJohn Marino return;
378*e4b17023SJohn Marino
379*e4b17023SJohn Marino ivar_count = ivars->ivar_count;
380*e4b17023SJohn Marino
381*e4b17023SJohn Marino for (i = 0; i < ivar_count; i++)
382*e4b17023SJohn Marino {
383*e4b17023SJohn Marino struct objc_ivar *ivar = &(ivars->ivar_list[i]);
384*e4b17023SJohn Marino const char *type;
385*e4b17023SJohn Marino
386*e4b17023SJohn Marino if (! ivar->ivar_name || strcmp (ivar->ivar_name, ivarname))
387*e4b17023SJohn Marino continue;
388*e4b17023SJohn Marino
389*e4b17023SJohn Marino assert (ivar->ivar_type);
390*e4b17023SJohn Marino type = ivar->ivar_type;
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino /* Skip the variable name */
393*e4b17023SJohn Marino if (*type == '"')
394*e4b17023SJohn Marino {
395*e4b17023SJohn Marino for (type++; *type++ != '"';)
396*e4b17023SJohn Marino /* do nothing */;
397*e4b17023SJohn Marino }
398*e4b17023SJohn Marino
399*e4b17023SJohn Marino if (*type == _C_GCINVISIBLE)
400*e4b17023SJohn Marino {
401*e4b17023SJohn Marino char *new_type;
402*e4b17023SJohn Marino size_t len;
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino if (gc_invisible || ! __objc_ivar_pointer (type))
405*e4b17023SJohn Marino return; /* The type of the variable already matches the
406*e4b17023SJohn Marino requested gc_invisible type */
407*e4b17023SJohn Marino
408*e4b17023SJohn Marino /* The variable is gc_invisible so we make it gc visible. */
409*e4b17023SJohn Marino new_type = objc_atomic_malloc (strlen(ivar->ivar_type));
410*e4b17023SJohn Marino len = (type - ivar->ivar_type);
411*e4b17023SJohn Marino memcpy (new_type, ivar->ivar_type, len);
412*e4b17023SJohn Marino new_type[len] = 0;
413*e4b17023SJohn Marino strcat (new_type, type + 1);
414*e4b17023SJohn Marino ivar->ivar_type = new_type;
415*e4b17023SJohn Marino }
416*e4b17023SJohn Marino else
417*e4b17023SJohn Marino {
418*e4b17023SJohn Marino char *new_type;
419*e4b17023SJohn Marino size_t len;
420*e4b17023SJohn Marino
421*e4b17023SJohn Marino if (! gc_invisible || ! __objc_ivar_pointer (type))
422*e4b17023SJohn Marino return; /* The type of the variable already matches the
423*e4b17023SJohn Marino requested gc_invisible type */
424*e4b17023SJohn Marino
425*e4b17023SJohn Marino /* The variable is gc visible so we make it gc_invisible. */
426*e4b17023SJohn Marino new_type = objc_malloc (strlen(ivar->ivar_type) + 2);
427*e4b17023SJohn Marino
428*e4b17023SJohn Marino /* Copy the variable name. */
429*e4b17023SJohn Marino len = (type - ivar->ivar_type);
430*e4b17023SJohn Marino memcpy (new_type, ivar->ivar_type, len);
431*e4b17023SJohn Marino /* Add '!'. */
432*e4b17023SJohn Marino new_type[len++] = _C_GCINVISIBLE;
433*e4b17023SJohn Marino /* Copy the original types. */
434*e4b17023SJohn Marino strcpy (new_type + len, type);
435*e4b17023SJohn Marino
436*e4b17023SJohn Marino ivar->ivar_type = new_type;
437*e4b17023SJohn Marino }
438*e4b17023SJohn Marino
439*e4b17023SJohn Marino __objc_generate_gc_type_description (class);
440*e4b17023SJohn Marino return;
441*e4b17023SJohn Marino }
442*e4b17023SJohn Marino
443*e4b17023SJohn Marino /* Search the instance variable in the superclasses */
444*e4b17023SJohn Marino class_ivar_set_gcinvisible (class->super_class, ivarname, gc_invisible);
445*e4b17023SJohn Marino }
446*e4b17023SJohn Marino
447*e4b17023SJohn Marino #else /* !OBJC_WITH_GC */
448*e4b17023SJohn Marino
449*e4b17023SJohn Marino void
__objc_generate_gc_type_description(Class class)450*e4b17023SJohn Marino __objc_generate_gc_type_description (Class class __attribute__ ((__unused__)))
451*e4b17023SJohn Marino {
452*e4b17023SJohn Marino }
453*e4b17023SJohn Marino
class_ivar_set_gcinvisible(Class class,const char * ivarname,BOOL gc_invisible)454*e4b17023SJohn Marino void class_ivar_set_gcinvisible (Class class __attribute__ ((__unused__)),
455*e4b17023SJohn Marino const char *ivarname __attribute__ ((__unused__)),
456*e4b17023SJohn Marino BOOL gc_invisible __attribute__ ((__unused__)))
457*e4b17023SJohn Marino {
458*e4b17023SJohn Marino }
459*e4b17023SJohn Marino
460*e4b17023SJohn Marino #endif /* OBJC_WITH_GC */
461