static ir_node *array_access_addr(const array_access_expression_t *expression)
{
dbg_info *dbgi = get_dbg_info(&expression->expression.source_position);
+ ir_node *base_addr;
+ ir_node *offset;
- ir_node *base_addr = expression_to_firm(expression->array_ref);
- ir_node *offset = expression_to_firm(expression->index);
- offset = create_conv(dbgi, offset, mode_Iu);
+ type_t *type_left = skip_typeref(expression->array_ref->datatype);
+ type_t *type_right = skip_typeref(expression->index->datatype);
+
+ if(type_left->type == TYPE_POINTER || type_left->type == TYPE_ARRAY) {
+ base_addr = expression_to_firm(expression->array_ref);
+ offset = expression_to_firm(expression->index);
+ } else {
+ assert(type_right->type == TYPE_POINTER
+ || type_right->type == TYPE_ARRAY);
+ base_addr = expression_to_firm(expression->index);
+ offset = expression_to_firm(expression->array_ref);
+ }
+ offset = create_conv(dbgi, offset, mode_Iu);
unsigned elem_size = get_type_size(expression->expression.datatype);
ir_node *elem_size_const = new_Const_long(mode_Iu, elem_size);
eat('[');
+ expression_t *index = parse_expression();
+
array_access_expression_t *array_access
= allocate_ast_zero(sizeof(array_access[0]));
- array_access->expression.type = EXPR_ARRAY_ACCESS;
- array_access->array_ref = array_ref;
- array_access->index = parse_expression();
+ array_access->expression.type = EXPR_ARRAY_ACCESS;
+ array_access->array_ref = array_ref;
+ array_access->index = index;
+
+ type_t *type_left = skip_typeref(array_ref->datatype);
+ type_t *type_right = skip_typeref(index->datatype);
- type_t *type = array_ref->datatype;
- if(type != NULL) {
- if(type->type == TYPE_POINTER) {
- pointer_type_t *pointer = (pointer_type_t*) type;
+ if(type_left != NULL && type_right != NULL) {
+ if(type_left->type == TYPE_POINTER) {
+ pointer_type_t *pointer = (pointer_type_t*) type_left;
+ array_access->expression.datatype = pointer->points_to;
+ } else if(type_left->type == TYPE_ARRAY) {
+ array_type_t *array_type = (array_type_t*) type_left;
+ array_access->expression.datatype = array_type->element_type;
+ } else if(type_right->type == TYPE_POINTER) {
+ pointer_type_t *pointer = (pointer_type_t*) type_right;
array_access->expression.datatype = pointer->points_to;
- } else if(type->type == TYPE_ARRAY) {
- array_type_t *array_type = (array_type_t*) type;
+ } else if(type_right->type == TYPE_ARRAY) {
+ array_type_t *array_type = (array_type_t*) type_right;
array_access->expression.datatype = array_type->element_type;
} else {
parser_print_error_prefix();
- fprintf(stderr, "array access on object with non-pointer type ");
- print_type_quoted(type);
+ fprintf(stderr, "array access on object with non-pointer types ");
+ print_type_quoted(type_left);
+ fprintf(stderr, ", ");
+ print_type_quoted(type_right);
fprintf(stderr, "\n");
}
}