Type *type_complete_struct(Type *type, TypeField *fields, int num_fields) { assert(type->kind == TYPE_COMPLETING); type->kind = TYPE_STRUCT; type->size = 0; type->align = 0; bool nonmodifiable = false; long field_sizes = 0; var new_fields = Buffer <TypeField> .Create(); for (var it = fields; it != fields + num_fields; it++) { assert(IS_POW2(type_alignof(it->type))); if (it->name != null) { it->offset = type->size; new_fields.Add(it); } else { add_type_fields(&new_fields, it->type, type->size); } field_sizes += type_sizeof(it->type); type->align = MAX(type->align, type_alignof(it->type)); type->size = type_sizeof(it->type) + ALIGN_UP(type->size, type_alignof(it->type)); nonmodifiable = it->type->nonmodifiable || nonmodifiable; } type->size = ALIGN_UP(type->size, type->align); type->padding = type->size - field_sizes; type->aggregate.fields = new_fields; type->aggregate.num_fields = new_fields.count; type->nonmodifiable = nonmodifiable; return(type); }
Type *type_complete_union(Type *type, TypeField *fields, int num_fields) { assert(type->kind == TYPE_COMPLETING); type->kind = TYPE_UNION; type->size = 0; type->align = 0; bool nonmodifiable = false; var new_fields = Buffer <TypeField> .Create(); for (var it = fields; it != fields + num_fields; it++) { assert(it->type->kind > TYPE_COMPLETING); if (it->name != null) { it->offset = 0; new_fields.Add(it); } else { add_type_fields(&new_fields, it->type, 0); } type->align = MAX(type->align, type_alignof(it->type)); type->size = MAX(type->size, type_sizeof(it->type)); nonmodifiable = it->type->nonmodifiable || nonmodifiable; } type->size = ALIGN_UP(type->size, type->align); type->aggregate.fields = new_fields; type->aggregate.num_fields = new_fields.count; type->nonmodifiable = nonmodifiable; return(type); }
void add_type_fields(Buffer <TypeField> *fields, Type *type, long offset) //TypeField** { assert(type->kind == TYPE_STRUCT || type->kind == TYPE_UNION); for (var i = 0; i < type->aggregate.num_fields; i++) { TypeField *field = &type->aggregate.fields[i]; fields->Add(new TypeField { name = field->name, type = field->type, offset = (field->offset + offset) }); } }