static void handle_attribute_aligned(const attribute_t *attribute, entity_t *entity) { int alignment = 32; /* TODO: fill in maximum useful alignment for target machine */ if (attribute->a.arguments) { attribute_argument_t *argument = attribute->a.arguments; alignment = fold_expression_to_int(argument->v.expression); } if (!is_po2(alignment)) { errorf(&attribute->pos, "alignment must be a power of 2 but is %d", alignment); return; } if (alignment <= 0) { errorf(&attribute->pos, "alignment must be bigger than 0 but is %d", alignment); return; } switch (entity->kind) { case DECLARATION_KIND_CASES: entity->declaration.alignment = alignment; break; case ENTITY_STRUCT: case ENTITY_UNION: entity->compound.alignment = MAX(entity->compound.alignment, alignment); break; default: warningf(WARN_OTHER, &attribute->pos, "alignment attribute specification on %N ignored", entity); break; } }
static long get_offsetof_offset(const offsetof_expression_t *expression) { type_t *orig_type = expression->type; long offset = 0; designator_t *designator = expression->designator; for ( ; designator != NULL; designator = designator->next) { type_t *type = skip_typeref(orig_type); if (designator->symbol != NULL) { assert(is_type_compound(type)); symbol_t *symbol = designator->symbol; compound_t *compound = type->compound.compound; entity_t *iter = compound->members.first_entity; for (; iter->base.symbol != symbol; iter = iter->base.next) {} assert(iter->kind == ENTITY_COMPOUND_MEMBER); offset += iter->compound_member.offset; orig_type = iter->declaration.type; } else { expression_t *array_index = designator->array_index; assert(designator->array_index != NULL); assert(is_type_array(type)); long index_long = fold_expression_to_int(array_index); type_t *element_type = type->array.element_type; long element_size = get_type_size(element_type); /* TODO: check for overflow */ offset += index_long * element_size; orig_type = type->array.element_type; } } return offset; }