X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=6726dc7413c0948177041a6237fd6b33a261edaf;hb=48b7436f2c91934d56b21196de2da3c94b1805cd;hp=2ec9b9634c3c61c5f8861297dfddb8140a7230bc;hpb=62960ad0396cef884afa2970238db902fc6c06f1;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 2ec9b96..6726dc7 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -701,8 +701,15 @@ static ir_node *call_expression_to_firm(const call_expression_t *call) expression_t *function = call->function; ir_node *callee = expression_to_firm(function); - assert(function->datatype->type == TYPE_FUNCTION); - function_type_t *function_type = (function_type_t*) function->datatype; + function_type_t *function_type; + if (function->datatype->type == TYPE_POINTER) { + pointer_type_t *const ptr_type = (pointer_type_t*)function->datatype; + assert(ptr_type->points_to->type == TYPE_FUNCTION); + function_type = (function_type_t*)ptr_type->points_to; + } else { + assert(function->datatype->type == TYPE_FUNCTION); + function_type = (function_type_t*)function->datatype; + } int n_parameters = 0; call_argument_t *argument = call->arguments; @@ -1034,11 +1041,11 @@ static ir_node *create_add(const binary_expression_t *expression) return new_d_Add(dbgi, left, right, mode); } - if(type_left->type == TYPE_POINTER) { - return pointer_arithmetic(left, right, type_left, dbgi, new_d_Add); + if (type_left->type == TYPE_POINTER || type_left->type == TYPE_ARRAY) { + return pointer_arithmetic(left, right, type, dbgi, new_d_Add); } else { - assert(type_right->type == TYPE_POINTER); - return pointer_arithmetic(right, left, type_right, dbgi, new_d_Add); + assert(type_right->type == TYPE_POINTER || type_right->type == TYPE_ARRAY); + return pointer_arithmetic(right, left, type, dbgi, new_d_Add); } } @@ -1322,7 +1329,7 @@ static ir_node *select_to_firm(const select_expression_t *expression) { dbg_info *dbgi = get_dbg_info(&expression->expression.source_position); ir_node *addr = select_addr(expression); - type_t *type = expression->expression.datatype; + type_t *type = skip_typeref(expression->expression.datatype); return deref_address(type, addr, dbgi); } @@ -1528,12 +1535,16 @@ static void if_statement_to_firm(if_statement_t *statement) ir_node *fallthrough_block = new_immBlock(); /* the true (blocks) */ - ir_node *true_block = new_immBlock(); - - statement_to_firm(statement->true_statement); - if(get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(fallthrough_block, jmp); + ir_node *true_block; + if (statement->true_statement != NULL) { + true_block = new_immBlock(); + statement_to_firm(statement->true_statement); + if(get_cur_block() != NULL) { + ir_node *jmp = new_Jmp(); + add_immBlock_pred(fallthrough_block, jmp); + } + } else { + true_block = fallthrough_block; } /* the false (blocks) */ @@ -1583,23 +1594,27 @@ static void while_statement_to_firm(while_statement_t *statement) ir_node *false_block = new_immBlock(); /* the loop body */ - ir_node *body_block = new_immBlock(); - - ir_node *old_continue_label = continue_label; - ir_node *old_break_label = break_label; - continue_label = header_block; - break_label = false_block; + ir_node *body_block; + if (statement->body != NULL) { + ir_node *old_continue_label = continue_label; + ir_node *old_break_label = break_label; + continue_label = header_block; + break_label = false_block; - statement_to_firm(statement->body); + body_block = new_immBlock(); + statement_to_firm(statement->body); - assert(continue_label == header_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; + assert(continue_label == header_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; - if(get_cur_block() != NULL) { - ir_node *jmp = new_Jmp(); - add_immBlock_pred(header_block, jmp); + if(get_cur_block() != NULL) { + ir_node *jmp = new_Jmp(); + add_immBlock_pred(header_block, jmp); + } + } else { + body_block = header_block; } /* create the condition */ @@ -1632,23 +1647,25 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) add_immBlock_pred(body_block, jmp); } - ir_node *old_continue_label = continue_label; - ir_node *old_break_label = break_label; - continue_label = header_block; - break_label = false_block; + if (statement->body != NULL) { + ir_node *old_continue_label = continue_label; + ir_node *old_break_label = break_label; + continue_label = header_block; + break_label = false_block; - statement_to_firm(statement->body); + statement_to_firm(statement->body); - assert(continue_label == header_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; + assert(continue_label == header_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; - if(get_cur_block() == NULL) { - mature_immBlock(header_block); - mature_immBlock(body_block); - mature_immBlock(false_block); - return; + if (get_cur_block() == NULL) { + mature_immBlock(header_block); + mature_immBlock(body_block); + mature_immBlock(false_block); + return; + } } ir_node *body_jmp = new_Jmp(); @@ -1694,23 +1711,27 @@ static void for_statement_to_firm(for_statement_t *statement) ir_node *const false_block = new_immBlock(); /* the loop body */ - ir_node *const body_block = new_immBlock(); - - ir_node *const old_continue_label = continue_label; - ir_node *const old_break_label = break_label; - continue_label = step_block; - break_label = false_block; - - statement_to_firm(statement->body); - - assert(continue_label == step_block); - assert(break_label == false_block); - continue_label = old_continue_label; - break_label = old_break_label; - - if (get_cur_block() != NULL) { - ir_node *const jmp = new_Jmp(); - add_immBlock_pred(step_block, jmp); + ir_node * body_block; + if (statement->body != NULL) { + ir_node *const old_continue_label = continue_label; + ir_node *const old_break_label = break_label; + continue_label = step_block; + break_label = false_block; + + body_block = new_immBlock(); + statement_to_firm(statement->body); + + assert(continue_label == step_block); + assert(break_label == false_block); + continue_label = old_continue_label; + break_label = old_break_label; + + if (get_cur_block() != NULL) { + ir_node *const jmp = new_Jmp(); + add_immBlock_pred(step_block, jmp); + } + } else { + body_block = step_block; } /* create the condition */