1 /* Basic data types for Objective C.
2 Copyright (C) 1998, 2002, 2004, 2005, 2006, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Ovidiu Predescu.
6 This file is part of GCC.
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)
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.
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.
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/>. */
27 #include "objc-private/common.h"
28 #include "objc/objc.h"
34 #include <ctype.h> /* For isdigit. */
37 #include "objc/runtime.h"
38 #include "objc-private/module-abi-8.h"
43 /* gc_typed.h uses the following but doesn't declare them */
45 typedef GC_signed_word signed_word
;
46 #define BITS_PER_WORD (CHAR_BIT * sizeof (word))
50 /* The following functions set up in `mask` the corresponding pointers.
51 The offset is incremented with the size of the type. */
54 ({ typeof (V) __v = (V); typeof (A) __a = (A); \
55 __a * ((__v+__a - 1)/__a); })
57 #define SET_BIT_FOR_OFFSET(mask, offset) \
58 GC_set_bit (mask, offset / sizeof (void *))
62 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
);
64 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
);
68 __objc_gc_setup_array (GC_bitmap mask
, const char *type
, int offset
)
70 int i
, len
= atoi (type
+ 1);
72 while (isdigit (*++type
))
73 /* do nothing */; /* skip the size of the array */
77 for (i
= 0; i
< len
; i
++)
78 __objc_gc_setup_array (mask
, type
, offset
);
82 for (i
= 0; i
< len
; i
++)
83 __objc_gc_setup_struct (mask
, type
, offset
);
87 for (i
= 0; i
< len
; i
++)
88 __objc_gc_setup_union (mask
, type
, offset
);
97 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
)
99 struct objc_struct_layout layout
;
100 unsigned int position
;
103 objc_layout_structure (type
, &layout
);
105 while (objc_layout_structure_next_member (&layout
))
107 BOOL gc_invisible
= NO
;
109 objc_layout_structure_get_info (&layout
, &position
, NULL
, &mtype
);
111 /* Skip the variable name */
114 for (mtype
++; *mtype
++ != '"';)
118 if (*mtype
== _C_GCINVISIBLE
)
124 /* Add to position the offset of this structure */
135 SET_BIT_FOR_OFFSET (mask
, position
);
139 __objc_gc_setup_array (mask
, mtype
, position
);
143 __objc_gc_setup_struct (mask
, mtype
, position
);
147 __objc_gc_setup_union (mask
, mtype
, position
);
157 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
)
159 /* Sub-optimal, quick implementation: assume the union is made of
160 pointers, set up the mask accordingly. */
164 /* Skip the variable name */
167 for (type
++; *type
++ != '"';)
171 size
= objc_sizeof_type (type
);
172 align
= objc_alignof_type (type
);
174 offset
= ROUND (offset
, align
);
175 for (i
= 0; i
< size
; i
+= sizeof (void *))
177 SET_BIT_FOR_OFFSET (mask
, offset
);
178 offset
+= sizeof (void *);
183 /* Iterates over the types in the structure that represents the class
184 encoding and sets the bits in mask according to each ivar type. */
186 __objc_gc_type_description_from_type (GC_bitmap mask
, const char *type
)
188 struct objc_struct_layout layout
;
189 unsigned int offset
, align
;
190 const char *ivar_type
;
192 objc_layout_structure (type
, &layout
);
194 while (objc_layout_structure_next_member (&layout
))
196 BOOL gc_invisible
= NO
;
198 objc_layout_structure_get_info (&layout
, &offset
, &align
, &ivar_type
);
200 /* Skip the variable name */
201 if (*ivar_type
== '"')
203 for (ivar_type
++; *ivar_type
++ != '"';)
207 if (*ivar_type
== _C_GCINVISIBLE
)
213 switch (*ivar_type
) {
220 SET_BIT_FOR_OFFSET (mask
, offset
);
224 __objc_gc_setup_array (mask
, ivar_type
, offset
);
228 __objc_gc_setup_struct (mask
, ivar_type
, offset
);
232 __objc_gc_setup_union (mask
, ivar_type
, offset
);
241 /* Computes in *type the full type encoding of this class including
242 its super classes. '*size' gives the total number of bytes allocated
243 into *type, '*current' the number of bytes used so far by the
246 __objc_class_structure_encoding (Class
class, char **type
, int *size
,
250 struct objc_ivar_list
*ivars
;
259 /* Add the type encodings of the super classes */
260 __objc_class_structure_encoding (class->super_class
, type
, size
, current
);
262 ivars
= class->ivars
;
266 ivar_count
= ivars
->ivar_count
;
268 for (i
= 0; i
< ivar_count
; i
++)
270 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
271 const char *ivar_type
= ivar
->ivar_type
;
272 int len
= strlen (ivar_type
);
274 if (*current
+ len
+ 1 >= *size
)
276 /* Increase the size of the encoding string so that it
277 contains this ivar's type. */
278 *size
= ROUND (*current
+ len
+ 1, 10);
279 *type
= objc_realloc (*type
, *size
);
281 strcat (*type
+ *current
, ivar_type
);
287 /* Allocates the memory that will hold the type description for class
288 and calls the __objc_class_structure_encoding that generates this
291 __objc_generate_gc_type_description (Class
class)
295 int type_size
= 10, current
;
296 char *class_structure_type
;
298 if (! CLS_ISCLASS (class))
301 /* We have to create a mask in which each bit counts for a pointer member.
302 We take into consideration all the non-pointer instance variables and we
303 round them up to the alignment. */
305 /* The number of bits in the mask is the size of an instance in bytes divided
306 by the size of a pointer. */
307 bits_no
= (ROUND (class_getInstanceSize (class), sizeof (void *))
309 size
= ROUND (bits_no
, BITS_PER_WORD
) / BITS_PER_WORD
;
310 mask
= objc_atomic_malloc (size
* sizeof (int));
311 memset (mask
, 0, size
* sizeof (int));
313 class_structure_type
= objc_atomic_malloc (type_size
);
314 *class_structure_type
= current
= 0;
315 __objc_class_structure_encoding (class, &class_structure_type
,
316 &type_size
, ¤t
);
317 if (current
+ 1 == type_size
)
318 class_structure_type
= objc_realloc (class_structure_type
, ++type_size
);
319 strcat (class_structure_type
+ current
, "}");
321 printf ("type description for '%s' is %s\n", class->name
, class_structure_type
);
324 __objc_gc_type_description_from_type (mask
, class_structure_type
);
325 objc_free (class_structure_type
);
328 printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
329 class_structure_type
, class->name
, bits_no
, size
);
332 for (i
= 0; i
< size
; i
++)
333 printf (" %lx", mask
[i
]);
338 class->gc_object_type
= (void *) GC_make_descriptor (mask
, bits_no
);
342 /* Returns YES if type denotes a pointer type, NO otherwise */
344 __objc_ivar_pointer (const char *type
)
346 type
= objc_skip_type_qualifiers (type
);
348 return (*type
== _C_ID
352 || *type
== _C_CHARPTR
353 || *type
== _C_ATOM
);
357 /* Mark the instance variable whose name is given by ivarname as a
358 weak pointer (a pointer hidden to the garbage collector) if
359 gc_invisible is true. If gc_invisible is false it unmarks the
360 instance variable and makes it a normal pointer, visible to the
363 This operation only makes sense on instance variables that are
366 class_ivar_set_gcinvisible (Class
class, const char *ivarname
,
370 struct objc_ivar_list
*ivars
;
372 if (! class || ! ivarname
)
375 ivars
= class->ivars
;
379 ivar_count
= ivars
->ivar_count
;
381 for (i
= 0; i
< ivar_count
; i
++)
383 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
386 if (! ivar
->ivar_name
|| strcmp (ivar
->ivar_name
, ivarname
))
389 assert (ivar
->ivar_type
);
390 type
= ivar
->ivar_type
;
392 /* Skip the variable name */
395 for (type
++; *type
++ != '"';)
399 if (*type
== _C_GCINVISIBLE
)
404 if (gc_invisible
|| ! __objc_ivar_pointer (type
))
405 return; /* The type of the variable already matches the
406 requested gc_invisible type */
408 /* The variable is gc_invisible so we make it gc visible. */
409 new_type
= objc_atomic_malloc (strlen(ivar
->ivar_type
));
410 len
= (type
- ivar
->ivar_type
);
411 memcpy (new_type
, ivar
->ivar_type
, len
);
413 strcat (new_type
, type
+ 1);
414 ivar
->ivar_type
= new_type
;
421 if (! gc_invisible
|| ! __objc_ivar_pointer (type
))
422 return; /* The type of the variable already matches the
423 requested gc_invisible type */
425 /* The variable is gc visible so we make it gc_invisible. */
426 new_type
= objc_malloc (strlen(ivar
->ivar_type
) + 2);
428 /* Copy the variable name. */
429 len
= (type
- ivar
->ivar_type
);
430 memcpy (new_type
, ivar
->ivar_type
, len
);
432 new_type
[len
++] = _C_GCINVISIBLE
;
433 /* Copy the original types. */
434 strcpy (new_type
+ len
, type
);
436 ivar
->ivar_type
= new_type
;
439 __objc_generate_gc_type_description (class);
443 /* Search the instance variable in the superclasses */
444 class_ivar_set_gcinvisible (class->super_class
, ivarname
, gc_invisible
);
447 #else /* !OBJC_WITH_GC */
450 __objc_generate_gc_type_description (Class
class __attribute__ ((__unused__
)))
454 void class_ivar_set_gcinvisible (Class
class __attribute__ ((__unused__
)),
455 const char *ivarname
__attribute__ ((__unused__
)),
456 BOOL gc_invisible
__attribute__ ((__unused__
)))
460 #endif /* OBJC_WITH_GC */