static void __objc_gc_setup_union (GC_bitmap mask, const char *type, int offset) { /* Sub-optimal, quick implementation: assume the union is made of pointers, set up the mask accordingly. */ int i, size, align; /* Skip the variable name */ if (*type == '"') { for (type++; *type++ != '"';) /* do nothing */; } size = objc_sizeof_type (type); align = objc_alignof_type (type); offset = ROUND (offset, align); for (i = 0; i < size; i += sizeof (void *)) { SET_BIT_FOR_OFFSET (mask, offset); offset += sizeof (void *); } }
static void __objc_gc_setup_struct (GC_bitmap mask, const char *type, int offset) { struct objc_struct_layout layout; unsigned int position; const char *mtype; objc_layout_structure (type, &layout); while (objc_layout_structure_next_member (&layout)) { BOOL gc_invisible = NO; objc_layout_structure_get_info (&layout, &position, NULL, &mtype); /* Skip the variable name */ if (*mtype == '"') { for (mtype++; *mtype++ != '"';) /* do nothing */; } if (*mtype == _C_GCINVISIBLE) { gc_invisible = YES; mtype++; } /* Add to position the offset of this structure */ position += offset; switch (*mtype) { case _C_ID: case _C_CLASS: case _C_SEL: case _C_PTR: case _C_CHARPTR: case _C_ATOM: if (! gc_invisible) SET_BIT_FOR_OFFSET (mask, position); break; case _C_ARY_B: __objc_gc_setup_array (mask, mtype, position); break; case _C_STRUCT_B: __objc_gc_setup_struct (mask, mtype, position); break; case _C_UNION_B: __objc_gc_setup_union (mask, mtype, position); break; default: break; } } }
/* Iterates over the types in the structure that represents the class encoding and sets the bits in mask according to each ivar type. */ static void __objc_gc_type_description_from_type (GC_bitmap mask, const char *type) { struct objc_struct_layout layout; unsigned int offset, align; const char *ivar_type; objc_layout_structure (type, &layout); while (objc_layout_structure_next_member (&layout)) { BOOL gc_invisible = NO; objc_layout_structure_get_info (&layout, &offset, &align, &ivar_type); /* Skip the variable name */ if (*ivar_type == '"') { for (ivar_type++; *ivar_type++ != '"';) /* do nothing */; } if (*ivar_type == _C_GCINVISIBLE) { gc_invisible = YES; ivar_type++; } switch (*ivar_type) { case _C_ID: case _C_CLASS: case _C_SEL: case _C_PTR: case _C_CHARPTR: if (! gc_invisible) SET_BIT_FOR_OFFSET (mask, offset); break; case _C_ARY_B: __objc_gc_setup_array (mask, ivar_type, offset); break; case _C_STRUCT_B: __objc_gc_setup_struct (mask, ivar_type, offset); break; case _C_UNION_B: __objc_gc_setup_union (mask, ivar_type, offset); break; default: break; } } }
static void __tour_gc_setup_struct(GC_bitmap mask, const char* type, int offset) { struct tour_struct_layout layout; unsigned int position; const char* mtype; tour_layout_structure( type, &layout ); while ( tour_layout_structure_next_member( &layout ) ) { boolean gc_invisible = false; tour_layout_structure_get_info( &layout, &position, NULL, &mtype ); if ( *mtype == '"' ) { for ( mtype ++; *mtype ++ != '"'; ) /* do nothing */; } if ( *mtype == _C_GC_INVISIBLE ) { gc_invisible = true; mtype ++; } position += offset; switch ( *mtype ) { case _C_ID: case _C_CLASS: case _C_SEL: case _C_PTR: case _C_CHARPTR: case _C_ATOM: if ( !gc_invisible ) SET_BIT_FOR_OFFSET(mask, position); break; case _C_ARY_B: __tour_gc_setup_array( mask, mtype, position ); break; case _C_STRUCT_B: __tour_gc_setup_struct( mask, mtype, position ); break; case _C_UNION_B: __tour_gc_setup_union( mask, mtype, position ); break; default: break; } } }
static void __tour_gc_setup_union(GC_bitmap mask, const char* type, int offset) { int i, size, align; if ( *type == '"' ) { for ( type ++; *type ++ != '"'; ) /* do nothing */; } size = tour_sizeof_type( type ); align = tour_alignof_type( type ); offset = ROUND(offset, align); for ( i = 0; i < size; i += sizeof(void *) ) { SET_BIT_FOR_OFFSET( mask, offset ); offset += sizeof(void *); } }