implement 5[a] type array references
authorMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 16:57:32 +0000 (16:57 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 21 Nov 2007 16:57:32 +0000 (16:57 +0000)
[r18510]

ast2firm.c
parser.c

index 84705aa..ec01a7a 100644 (file)
@@ -1259,10 +1259,22 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
 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);
index e151f5e..3233d05 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -2716,25 +2716,37 @@ static expression_t *parse_array_expression(unsigned precedence,
 
        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");
                }
        }