unsigned int go_field_alignment (tree t) { unsigned int v; v = TYPE_ALIGN (t); #ifdef BIGGEST_FIELD_ALIGNMENT if (v > BIGGEST_FIELD_ALIGNMENT) v = BIGGEST_FIELD_ALIGNMENT; #endif #ifdef ADJUST_FIELD_ALIGN { tree field ATTRIBUTE_UNUSED; field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL, t); v = ADJUST_FIELD_ALIGN (field, v); } #endif return v / BITS_PER_UNIT; }
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout) { register int desired_align = 0; /* The following are used only if the field is a bitfield */ register const char *bfld_type = 0; register int bfld_type_align = 0, bfld_field_size = 0; /* The current type without the type qualifiers */ const char *type; BOOL unionp = layout->original_type[-1] == _C_UNION_B; /* Add the size of the previous field to the size of the record. */ if (layout->prev_type) { type = objc_skip_type_qualifiers (layout->prev_type); if (unionp) layout->record_size = MAX (layout->record_size, objc_sizeof_type (type) * BITS_PER_UNIT); else if (*type != _C_BFLD) layout->record_size += objc_sizeof_type (type) * BITS_PER_UNIT; else { /* Get the bitfield's type */ for (bfld_type = type + 1; isdigit ((unsigned char)*bfld_type); bfld_type++) /* do nothing */; bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT; bfld_field_size = atoi (objc_skip_typespec (bfld_type)); layout->record_size += bfld_field_size; } } if ((unionp && *layout->type == _C_UNION_E) || (!unionp && *layout->type == _C_STRUCT_E)) return NO; /* Skip the variable name if any */ layout->type = objc_skip_variable_name (layout->type); type = objc_skip_type_qualifiers (layout->type); if (*type != _C_BFLD) desired_align = objc_alignof_type (type) * BITS_PER_UNIT; else { desired_align = 1; /* Skip the bitfield's offset */ for (bfld_type = type + 1; isdigit ((unsigned char) *bfld_type); bfld_type++) /* do nothing */; bfld_type_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT; bfld_field_size = atoi (objc_skip_typespec (bfld_type)); } /* The following won't work for vectors. */ #ifdef BIGGEST_FIELD_ALIGNMENT desired_align = MIN (desired_align, BIGGEST_FIELD_ALIGNMENT); #endif #ifdef ADJUST_FIELD_ALIGN desired_align = ADJUST_FIELD_ALIGN (type, desired_align); #endif /* Record must have at least as much alignment as any field. Otherwise, the alignment of the field within the record is meaningless. */ #ifndef HAVE_BITFIELD_TYPE_MATTERS layout->record_align = MAX (layout->record_align, desired_align); #else /* PCC_BITFIELD_TYPE_MATTERS */ if (*type == _C_BFLD) { /* For these machines, a zero-length field does not affect the alignment of the structure as a whole. It does, however, affect the alignment of the next field within the structure. */ if (bfld_field_size) layout->record_align = MAX (layout->record_align, desired_align); else desired_align = objc_alignof_type (bfld_type) * BITS_PER_UNIT; /* A named bit field of declared type `int' forces the entire structure to have `int' alignment. Q1: How is encoded this thing and how to check for it? Q2: How to determine maximum_field_alignment at runtime? */ /* if (DECL_NAME (field) != 0) */ { int type_align = bfld_type_align; #if 0 if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); else if (DECL_PACKED (field)) type_align = MIN (type_align, BITS_PER_UNIT); #endif layout->record_align = MAX (layout->record_align, type_align); } } else layout->record_align = MAX (layout->record_align, desired_align); #endif /* PCC_BITFIELD_TYPE_MATTERS */ /* Does this field automatically have alignment it needs by virtue of the fields that precede it and the record's own alignment? */ if (*type == _C_BFLD) layout->record_size = atoi (type + 1); else if (layout->record_size % desired_align != 0) { /* No, we need to skip space before this field. Bump the cumulative size to multiple of field alignment. */ layout->record_size = ROUND (layout->record_size, desired_align); } /* Jump to the next field in record. */ layout->prev_type = layout->type; layout->type = objc_skip_typespec (layout->type); /* skip component */ return YES; }