X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=f5e7a5bbbfda7a657977f3185166d176c4542cfd;hb=daf112c92de1ae63e134262745d1f1d5fd955dcb;hp=71dce365c21c0953e4a5519a8383362b1d3f7dea;hpb=5b5eebd2a3f941dcaf51f7260d184b816b7a852e;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 71dce36..f5e7a5b 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -360,7 +360,7 @@ static ir_type *create_struct_type(compound_type_t *type) int offset = 0; declaration_t *entry = type->declaration->context.declarations; for( ; entry != NULL; entry = entry->next) { - if(entry->namespace != NAMESPACE_NORMAL) + if(entry->namespc != NAMESPACE_NORMAL) continue; ident *ident = new_id_from_str(entry->symbol->string); @@ -413,7 +413,7 @@ static ir_type *create_union_type(compound_type_t *type) int size = 0; declaration_t *entry = declaration->context.declarations; for( ; entry != NULL; entry = entry->next) { - if(entry->namespace != NAMESPACE_NORMAL) + if(entry->namespc != NAMESPACE_NORMAL) continue; ident *ident = new_id_from_str(entry->symbol->string); @@ -971,8 +971,8 @@ static ir_node *create_arithmetic_binop(const binary_expression_t *expression, ir_node *left = expression_to_firm(expression->left); ir_node *right = expression_to_firm(expression->right); type_t *type = expression->right->datatype; - /* be careful with the modes, because in asithmetic assign nodes only - * the right operand has the mode of the arithmetic alread */ + /* be careful with the modes, because in arithmetic assign nodes only + * the right operand has the mode of the arithmetic already */ ir_mode *mode = get_ir_mode(type); left = create_conv(dbgi, left, mode); ir_node *res = func(dbgi, left, right, mode); @@ -1041,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); } } @@ -1535,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) */ @@ -1590,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 */ @@ -1639,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(); @@ -1701,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 */ @@ -1943,7 +1957,7 @@ static void case_label_to_firm(const case_label_statement_t *statement) static ir_node *get_label_block(declaration_t *label) { - assert(label->namespace == NAMESPACE_LABEL); + assert(label->namespc == NAMESPACE_LABEL); if(label->declaration_type == DECLARATION_TYPE_LABEL_BLOCK) { return label->v.block; @@ -2040,11 +2054,112 @@ static void statement_to_firm(statement_t *statement) panic("Statement not implemented\n"); } +static int count_local_declarations(const declaration_t * decl, + const declaration_t *const end) +{ + int count = 0; + for (; decl != end; decl = decl->next) { + const type_t *type = skip_typeref(decl->type); + switch (type->type) { + case TYPE_ATOMIC: + case TYPE_ENUM: + case TYPE_POINTER: + if (!decl->address_taken) ++count; + break; + + default: break; + } + } + return count; +} + +static int count_decls_in_stmts(const statement_t *stmt) +{ + int count = 0; + for (; stmt != NULL; stmt = stmt->next) { + switch (stmt->type) { + case STATEMENT_DECLARATION: { + const declaration_statement_t *const decl_stmt = + (const declaration_statement_t*)stmt; + count += count_local_declarations(decl_stmt->declarations_begin, + decl_stmt->declarations_end->next); + break; + } + + case STATEMENT_COMPOUND: { + const compound_statement_t *const comp = + (const compound_statement_t*)stmt; + count += count_decls_in_stmts(comp->statements); + break; + } + + case STATEMENT_IF: { + const if_statement_t *const if_stmt = (const if_statement_t*)stmt; + count += count_decls_in_stmts(if_stmt->true_statement); + count += count_decls_in_stmts(if_stmt->false_statement); + break; + } + + case STATEMENT_SWITCH: { + const switch_statement_t *const switch_stmt = + (const switch_statement_t*)stmt; + count += count_decls_in_stmts(switch_stmt->body); + break; + } + + case STATEMENT_LABEL: { + const label_statement_t *const label_stmt = + (const label_statement_t*)stmt; + count += count_decls_in_stmts(label_stmt->label_statement); + break; + } + + case STATEMENT_WHILE: { + const while_statement_t *const while_stmt = + (const while_statement_t*)stmt; + count += count_decls_in_stmts(while_stmt->body); + break; + } + + case STATEMENT_DO_WHILE: { + const do_while_statement_t *const do_while_stmt = + (const do_while_statement_t*)stmt; + count += count_decls_in_stmts(do_while_stmt->body); + break; + } + + case STATEMENT_FOR: { + const for_statement_t *const for_stmt = + (const for_statement_t*)stmt; + /* TODO initialisation */ + count += count_decls_in_stmts(for_stmt->body); + break; + } + + case STATEMENT_BREAK: + case STATEMENT_CASE_LABEL: + case STATEMENT_CONTINUE: + case STATEMENT_EXPRESSION: + case STATEMENT_GOTO: + case STATEMENT_INVALID: + case STATEMENT_RETURN: + break; + } + } + return count; +} + static int get_function_n_local_vars(declaration_t *declaration) { - (void) declaration; - /* TODO */ - return 30; + int count = 0; + + /* count parameters */ + count += count_local_declarations(declaration->context.declarations, NULL); + + /* count local variables declared in body */ + count += count_decls_in_stmts(declaration->init.statement); + + return count; } static void initialize_function_parameters(declaration_t *declaration) @@ -2186,7 +2301,7 @@ static void context_to_firm(context_t *context) { declaration_t *declaration = context->declarations; for( ; declaration != NULL; declaration = declaration->next) { - if(declaration->namespace != NAMESPACE_NORMAL) + if(declaration->namespc != NAMESPACE_NORMAL) continue; if(declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY || declaration->storage_class == STORAGE_CLASS_TYPEDEF)