1 /* Basic data types for Objective C.
2 Copyright (C) 1998, 2002, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
3 Contributed by Ovidiu Predescu.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 #include "objc/objc.h"
28 #include "objc/encoding.h"
39 /* gc_typed.h uses the following but doesn't declare them */
41 typedef GC_signed_word signed_word
;
42 #define BITS_PER_WORD (CHAR_BIT * sizeof (word))
46 /* The following functions set up in `mask` the corresponding pointers.
47 The offset is incremented with the size of the type. */
50 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
51 __a * ((__v+__a - 1)/__a); })
53 #define SET_BIT_FOR_OFFSET(mask, offset) \
54 GC_set_bit (mask, offset / sizeof (void *))
58 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
);
60 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
);
64 __objc_gc_setup_array (GC_bitmap mask
, const char *type
, int offset
)
66 int i
, len
= atoi (type
+ 1);
68 while (isdigit (*++type
))
69 /* do nothing */; /* skip the size of the array */
73 for (i
= 0; i
< len
; i
++)
74 __objc_gc_setup_array (mask
, type
, offset
);
78 for (i
= 0; i
< len
; i
++)
79 __objc_gc_setup_struct (mask
, type
, offset
);
83 for (i
= 0; i
< len
; i
++)
84 __objc_gc_setup_union (mask
, type
, offset
);
93 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
)
95 struct objc_struct_layout layout
;
96 unsigned int position
;
99 objc_layout_structure (type
, &layout
);
101 while (objc_layout_structure_next_member (&layout
))
103 BOOL gc_invisible
= NO
;
105 objc_layout_structure_get_info (&layout
, &position
, NULL
, &mtype
);
107 /* Skip the variable name */
110 for (mtype
++; *mtype
++ != '"';)
114 if (*mtype
== _C_GCINVISIBLE
)
120 /* Add to position the offset of this structure */
131 SET_BIT_FOR_OFFSET (mask
, position
);
135 __objc_gc_setup_array (mask
, mtype
, position
);
139 __objc_gc_setup_struct (mask
, mtype
, position
);
143 __objc_gc_setup_union (mask
, mtype
, position
);
153 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
)
155 /* Sub-optimal, quick implementation: assume the union is made of
156 pointers, set up the mask accordingly. */
160 /* Skip the variable name */
163 for (type
++; *type
++ != '"';)
167 size
= objc_sizeof_type (type
);
168 align
= objc_alignof_type (type
);
170 offset
= ROUND (offset
, align
);
171 for (i
= 0; i
< size
; i
+= sizeof (void *))
173 SET_BIT_FOR_OFFSET (mask
, offset
);
174 offset
+= sizeof (void *);
179 /* Iterates over the types in the structure that represents the class
180 encoding and sets the bits in mask according to each ivar type. */
182 __objc_gc_type_description_from_type (GC_bitmap mask
, const char *type
)
184 struct objc_struct_layout layout
;
185 unsigned int offset
, align
;
186 const char *ivar_type
;
188 objc_layout_structure (type
, &layout
);
190 while (objc_layout_structure_next_member (&layout
))
192 BOOL gc_invisible
= NO
;
194 objc_layout_structure_get_info (&layout
, &offset
, &align
, &ivar_type
);
196 /* Skip the variable name */
197 if (*ivar_type
== '"')
199 for (ivar_type
++; *ivar_type
++ != '"';)
203 if (*ivar_type
== _C_GCINVISIBLE
)
209 switch (*ivar_type
) {
216 SET_BIT_FOR_OFFSET (mask
, offset
);
220 __objc_gc_setup_array (mask
, ivar_type
, offset
);
224 __objc_gc_setup_struct (mask
, ivar_type
, offset
);
228 __objc_gc_setup_union (mask
, ivar_type
, offset
);
237 /* Computes in *type the full type encoding of this class including
238 its super classes. '*size' gives the total number of bytes allocated
239 into *type, '*current' the number of bytes used so far by the
242 __objc_class_structure_encoding (Class
class, char **type
, int *size
,
246 struct objc_ivar_list
*ivars
;
255 /* Add the type encodings of the super classes */
256 __objc_class_structure_encoding (class->super_class
, type
, size
, current
);
258 ivars
= class->ivars
;
262 ivar_count
= ivars
->ivar_count
;
264 for (i
= 0; i
< ivar_count
; i
++)
266 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
267 const char *ivar_type
= ivar
->ivar_type
;
268 int len
= strlen (ivar_type
);
270 if (*current
+ len
+ 1 >= *size
)
272 /* Increase the size of the encoding string so that it
273 contains this ivar's type. */
274 *size
= ROUND (*current
+ len
+ 1, 10);
275 *type
= objc_realloc (*type
, *size
);
277 strcat (*type
+ *current
, ivar_type
);
283 /* Allocates the memory that will hold the type description for class
284 and calls the __objc_class_structure_encoding that generates this
287 __objc_generate_gc_type_description (Class
class)
291 int type_size
= 10, current
;
292 char *class_structure_type
;
294 if (! CLS_ISCLASS (class))
297 /* We have to create a mask in which each bit counts for a pointer member.
298 We take into consideration all the non-pointer instance variables and we
299 round them up to the alignment. */
301 /* The number of bits in the mask is the size of an instance in bytes divided
302 by the size of a pointer. */
303 bits_no
= (ROUND (class_get_instance_size (class), sizeof (void *))
305 size
= ROUND (bits_no
, BITS_PER_WORD
) / BITS_PER_WORD
;
306 mask
= objc_atomic_malloc (size
* sizeof (int));
307 memset (mask
, 0, size
* sizeof (int));
309 class_structure_type
= objc_atomic_malloc (type_size
);
310 *class_structure_type
= current
= 0;
311 __objc_class_structure_encoding (class, &class_structure_type
,
312 &type_size
, ¤t
);
313 if (current
+ 1 == type_size
)
314 class_structure_type
= objc_realloc (class_structure_type
, ++type_size
);
315 strcat (class_structure_type
+ current
, "}");
317 printf ("type description for '%s' is %s\n", class->name
, class_structure_type
);
320 __objc_gc_type_description_from_type (mask
, class_structure_type
);
321 objc_free (class_structure_type
);
324 printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
325 class_structure_type
, class->name
, bits_no
, size
);
328 for (i
= 0; i
< size
; i
++)
329 printf (" %lx", mask
[i
]);
334 class->gc_object_type
= (void *) GC_make_descriptor (mask
, bits_no
);
338 /* Returns YES if type denotes a pointer type, NO otherwise */
340 __objc_ivar_pointer (const char *type
)
342 type
= objc_skip_type_qualifiers (type
);
344 return (*type
== _C_ID
348 || *type
== _C_CHARPTR
349 || *type
== _C_ATOM
);
353 /* Mark the instance variable whose name is given by ivarname as a
354 weak pointer (a pointer hidden to the garbage collector) if
355 gc_invisible is true. If gc_invisible is false it unmarks the
356 instance variable and makes it a normal pointer, visible to the
359 This operation only makes sense on instance variables that are
362 class_ivar_set_gcinvisible (Class
class, const char *ivarname
,
366 struct objc_ivar_list
*ivars
;
368 if (! class || ! ivarname
)
371 ivars
= class->ivars
;
375 ivar_count
= ivars
->ivar_count
;
377 for (i
= 0; i
< ivar_count
; i
++)
379 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
382 if (! ivar
->ivar_name
|| strcmp (ivar
->ivar_name
, ivarname
))
385 assert (ivar
->ivar_type
);
386 type
= ivar
->ivar_type
;
388 /* Skip the variable name */
391 for (type
++; *type
++ != '"';)
395 if (*type
== _C_GCINVISIBLE
)
400 if (gc_invisible
|| ! __objc_ivar_pointer (type
))
401 return; /* The type of the variable already matches the
402 requested gc_invisible type */
404 /* The variable is gc_invisible so we make it gc visible. */
405 new_type
= objc_atomic_malloc (strlen(ivar
->ivar_type
));
406 len
= (type
- ivar
->ivar_type
);
407 memcpy (new_type
, ivar
->ivar_type
, len
);
409 strcat (new_type
, type
+ 1);
410 ivar
->ivar_type
= new_type
;
417 if (! gc_invisible
|| ! __objc_ivar_pointer (type
))
418 return; /* The type of the variable already matches the
419 requested gc_invisible type */
421 /* The variable is gc visible so we make it gc_invisible. */
422 new_type
= objc_malloc (strlen(ivar
->ivar_type
) + 2);
423 len
= (type
- ivar
->ivar_type
);
424 memcpy (new_type
, ivar
->ivar_type
, len
);
426 strcat (new_type
, "!");
427 strcat (new_type
, type
);
428 ivar
->ivar_type
= new_type
;
431 __objc_generate_gc_type_description (class);
435 /* Search the instance variable in the superclasses */
436 class_ivar_set_gcinvisible (class->super_class
, ivarname
, gc_invisible
);
439 #else /* !OBJC_WITH_GC */
442 __objc_generate_gc_type_description (Class
class __attribute__ ((__unused__
)))
446 void class_ivar_set_gcinvisible (Class
class __attribute__ ((__unused__
)),
447 const char *ivarname
__attribute__ ((__unused__
)),
448 BOOL gc_invisible
__attribute__ ((__unused__
)))
452 #endif /* OBJC_WITH_GC */