1 /* Basic data types for Objective C.
2 Copyright (C) 1998 Free Software Foundation, Inc.
3 Contributed by Ovidiu Predescu.
5 This file is part of GNU CC.
7 GNU CC 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 2, or (at your option)
12 GNU CC 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 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with files
23 compiled with GCC to produce an executable, this does not cause
24 the resulting executable to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
39 /* gc_typed.h uses the following but doesn't declare them */
41 typedef GC_signed_word signed_word
;
43 #if BITS_PER_WORD == 32
45 # define modWORDSZ(n) ((n) & 0x1f) /* n mod size of word */
48 #if BITS_PER_WORD == 64
50 # define modWORDSZ(n) ((n) & 0x3f) /* n mod size of word */
53 #define divWORDSZ(n) ((n) >> LOGWL) /* divide n by size of word */
57 /* The following functions set up in `mask` the corresponding pointers.
58 The offset is incremented with the size of the type. */
61 ({ typeof(V) __v=(V); typeof(A) __a=(A); \
62 __a*((__v+__a-1)/__a); })
64 #define SET_BIT_FOR_OFFSET(mask, offset) \
65 GC_set_bit(mask, offset / sizeof (void*))
69 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
);
71 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
);
75 __objc_gc_setup_array (GC_bitmap mask
, const char *type
, int offset
)
77 int i
, len
= atoi(type
+ 1);
79 while (isdigit(*++type
))
80 /* do nothing */; /* skip the size of the array */
84 for (i
= 0; i
< len
; i
++)
85 __objc_gc_setup_array (mask
, type
, offset
);
89 for (i
= 0; i
< len
; i
++)
90 __objc_gc_setup_struct (mask
, type
, offset
);
94 for (i
= 0; i
< len
; i
++)
95 __objc_gc_setup_union (mask
, type
, offset
);
104 __objc_gc_setup_struct (GC_bitmap mask
, const char *type
, int offset
)
106 struct objc_struct_layout layout
;
107 unsigned int position
;
110 objc_layout_structure (type
, &layout
);
112 while (objc_layout_structure_next_member (&layout
))
114 BOOL gc_invisible
= NO
;
116 objc_layout_structure_get_info (&layout
, &position
, NULL
, &mtype
);
118 /* Skip the variable name */
121 for (mtype
++; *mtype
++ != '"';)
125 if (*mtype
== _C_GCINVISIBLE
)
131 /* Add to position the offset of this structure */
142 SET_BIT_FOR_OFFSET(mask
, position
);
146 __objc_gc_setup_array (mask
, mtype
, position
);
150 __objc_gc_setup_struct (mask
, mtype
, position
);
154 __objc_gc_setup_union (mask
, mtype
, position
);
164 __objc_gc_setup_union (GC_bitmap mask
, const char *type
, int offset
)
166 /* Sub-optimal, quick implementation: assume the union is made of
167 pointers, set up the mask accordingly. */
171 /* Skip the variable name */
174 for (type
++; *type
++ != '"';)
178 size
= objc_sizeof_type (type
);
179 align
= objc_alignof_type (type
);
181 offset
= ROUND(offset
, align
);
182 for (i
= 0; i
< size
; i
+= sizeof (void*))
184 SET_BIT_FOR_OFFSET(mask
, offset
);
185 offset
+= sizeof (void*);
190 /* Iterates over the types in the structure that represents the class
191 encoding and sets the bits in mask according to each ivar type. */
193 __objc_gc_type_description_from_type (GC_bitmap mask
, const char *type
)
195 struct objc_struct_layout layout
;
196 unsigned int offset
, align
;
197 const char *ivar_type
;
199 objc_layout_structure (type
, &layout
);
201 while (objc_layout_structure_next_member (&layout
))
203 BOOL gc_invisible
= NO
;
205 objc_layout_structure_get_info (&layout
, &offset
, &align
, &ivar_type
);
207 /* Skip the variable name */
208 if (*ivar_type
== '"')
210 for (ivar_type
++; *ivar_type
++ != '"';)
214 if (*ivar_type
== _C_GCINVISIBLE
)
220 switch (*ivar_type
) {
227 SET_BIT_FOR_OFFSET(mask
, offset
);
231 __objc_gc_setup_array (mask
, ivar_type
, offset
);
235 __objc_gc_setup_struct (mask
, ivar_type
, offset
);
239 __objc_gc_setup_union (mask
, ivar_type
, offset
);
248 /* Computes in *type the full type encoding of this class including
249 its super classes. '*size' gives the total number of bytes allocated
250 into *type, '*current' the number of bytes used so far by the
253 __objc_class_structure_encoding (Class
class, char **type
, int *size
,
257 struct objc_ivar_list
* ivars
;
266 /* Add the type encodings of the super classes */
267 __objc_class_structure_encoding (class->super_class
, type
, size
, current
);
269 ivars
= class->ivars
;
273 ivar_count
= ivars
->ivar_count
;
275 for (i
= 0; i
< ivar_count
; i
++)
277 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
278 const char *ivar_type
= ivar
->ivar_type
;
279 int len
= strlen (ivar_type
);
281 if (*current
+ len
+ 1 >= *size
)
283 /* Increase the size of the encoding string so that it
284 contains this ivar's type. */
285 *size
= ROUND(*current
+ len
+ 1, 10);
286 *type
= objc_realloc (*type
, *size
);
288 strcat (*type
+ *current
, ivar_type
);
294 /* Allocates the memory that will hold the type description for class
295 and calls the __objc_class_structure_encoding that generates this
298 __objc_generate_gc_type_description (Class
class)
302 int type_size
= 10, current
;
303 char *class_structure_type
;
305 if (!CLS_ISCLASS(class))
308 /* We have to create a mask in which each bit counts for a pointer member.
309 We take into consideration all the non-pointer instance variables and we
310 round them up to the alignment. */
312 /* The number of bits in the mask is the size of an instance in bytes divided
313 by the size of a pointer. */
314 bits_no
= (ROUND(class_get_instance_size (class), sizeof(void*))
316 size
= ROUND(bits_no
, BITS_PER_WORD
) / BITS_PER_WORD
;
317 mask
= objc_atomic_malloc (size
* sizeof (int));
318 memset (mask
, 0, size
* sizeof (int));
320 class_structure_type
= objc_atomic_malloc (type_size
);
321 *class_structure_type
= current
= 0;
322 __objc_class_structure_encoding (class, &class_structure_type
,
323 &type_size
, ¤t
);
324 if (current
+ 1 == type_size
)
325 class_structure_type
= objc_realloc (class_structure_type
, ++type_size
);
326 strcat (class_structure_type
+ current
, "}");
327 // printf ("type description for '%s' is %s\n", class->name, class_structure_type);
329 __objc_gc_type_description_from_type (mask
, class_structure_type
);
330 objc_free (class_structure_type
);
334 printf (" mask for '%s', type '%s' (bits %d, mask size %d) is:",
335 class_structure_type
, class->name
, bits_no
, size
);
338 for (i
= 0; i
< size
; i
++)
339 printf (" %lx", mask
[i
]);
344 class->gc_object_type
= (void*)GC_make_descriptor (mask
, bits_no
);
348 /* Returns YES if type denotes a pointer type, NO otherwise */
350 __objc_ivar_pointer (const char *type
)
352 type
= objc_skip_type_qualifiers (type
);
354 return (*type
== _C_ID
358 || *type
== _C_CHARPTR
359 || *type
== _C_ATOM
);
363 /* Mark the instance variable whose name is given by ivarname as a
364 weak pointer (a pointer hidden to the garbage collector) if
365 gc_invisible is true. If gc_invisible is false it unmarks the
366 instance variable and makes it a normal pointer, visible to the
369 This operation only makes sense on instance variables that are
372 class_ivar_set_gcinvisible (Class
class, const char* ivarname
,
376 struct objc_ivar_list
* ivars
;
378 if (!class || !ivarname
)
381 ivars
= class->ivars
;
385 ivar_count
= ivars
->ivar_count
;
387 for (i
= 0; i
< ivar_count
; i
++)
389 struct objc_ivar
*ivar
= &(ivars
->ivar_list
[i
]);
392 if (!ivar
->ivar_name
|| strcmp (ivar
->ivar_name
, ivarname
))
395 assert (ivar
->ivar_type
);
396 type
= ivar
->ivar_type
;
398 /* Skip the variable name */
401 for (type
++; *type
++ != '"';)
405 if (*type
== _C_GCINVISIBLE
)
409 if (gc_invisible
|| !__objc_ivar_pointer (type
))
410 return; /* The type of the variable already matches the
411 requested gc_invisible type */
413 /* The variable is gc_invisible and we have to reverse it */
414 new_type
= objc_atomic_malloc (strlen (ivar
->ivar_type
));
415 strncpy (new_type
, ivar
->ivar_type
,
416 (size_t)(type
- ivar
->ivar_type
));
417 strcat (new_type
, type
+ 1);
418 ivar
->ivar_type
= new_type
;
424 if (!gc_invisible
|| !__objc_ivar_pointer (type
))
425 return; /* The type of the variable already matches the
426 requested gc_invisible type */
428 /* The variable is gc visible and we have to make it gc_invisible */
429 new_type
= objc_malloc (strlen (ivar
->ivar_type
) + 2);
430 strncpy (new_type
, ivar
->ivar_type
,
431 (size_t)(type
- ivar
->ivar_type
));
432 strcat (new_type
, "!");
433 strcat (new_type
, type
);
434 ivar
->ivar_type
= new_type
;
437 __objc_generate_gc_type_description (class);
441 /* Search the instance variable in the superclasses */
442 class_ivar_set_gcinvisible (class->super_class
, ivarname
, gc_invisible
);
445 #else /* !OBJC_WITH_GC */
448 __objc_generate_gc_type_description (Class
class)
452 void class_ivar_set_gcinvisible (Class
class,
453 const char* ivarname
,
458 #endif /* OBJC_WITH_GC */