X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=581b983a5c615527b1b0bae0de218ea9202f188a;hb=643026ae19cfdb8e3c891407f155668768028325;hp=4c013e77d99c6f51fe2d0aade44c6a0a3f41ce9f;hpb=6fd82c81483fd3916912336bbf543d287c69069a;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 4c013e7..581b983 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -201,7 +201,7 @@ static void init_atomic_modes(void) mode_uint = atomic_modes[ATOMIC_TYPE_UINT]; /* there's no real void type in firm */ - atomic_modes[ATOMIC_TYPE_VOID] = mode_int; + atomic_modes[ATOMIC_TYPE_VOID] = atomic_modes[ATOMIC_TYPE_CHAR]; /* initialize pointer modes */ char name[64]; @@ -1596,6 +1596,8 @@ static ir_node *process_builtin_call(const call_expression_t *call) return _expression_to_firm(argument); } case T___builtin_va_end: + /* evaluate the argument of va_end for its side effects */ + _expression_to_firm(call->arguments->expression); return NULL; default: panic("Unsupported builtin found\n"); @@ -2242,10 +2244,14 @@ static ir_node *produce_condition_result(const expression_t *expression, static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi, ir_node *value, type_t *type) { + ir_mode *const mode = get_ir_mode(type_ptrdiff_t); + assert(is_type_pointer(type)); pointer_type_t *const pointer_type = &type->pointer; type_t *const points_to = skip_typeref(pointer_type->points_to); unsigned elem_size = get_type_size_const(points_to); + value = create_conv(dbgi, value, mode); + /* gcc extension: allow arithmetic with void * and function * */ if ((elem_size == 0 && is_type_atomic(points_to, ATOMIC_TYPE_VOID)) || is_type_function(points_to)) { @@ -2256,9 +2262,8 @@ static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi, if (elem_size == 1) return value; - value = create_conv(dbgi, value, mode_int); - ir_node *const cnst = new_Const_long(mode_int, (long)elem_size); - ir_node *const mul = new_d_Mul(dbgi, value, cnst, mode_int); + ir_node *const cnst = new_Const_long(mode, (long)elem_size); + ir_node *const mul = new_d_Mul(dbgi, value, cnst, mode); return mul; } @@ -2389,12 +2394,24 @@ static ir_node *create_lazy_op(const binary_expression_t *expression) long val = fold_constant(expression->left); expression_kind_t ekind = expression->base.kind; assert(ekind == EXPR_BINARY_LOGICAL_AND || ekind == EXPR_BINARY_LOGICAL_OR); - if ((ekind == EXPR_BINARY_LOGICAL_AND && val != 0) || - (ekind == EXPR_BINARY_LOGICAL_OR && val == 0)) { - return produce_condition_result(expression->right, mode, dbgi); + if (ekind == EXPR_BINARY_LOGICAL_AND) { + if (val == 0) { + return new_Const(get_mode_null(mode)); + } } else { - return new_Const(get_mode_one(mode)); + if (val != 0) { + return new_Const(get_mode_one(mode)); + } } + + if (is_constant_expression(expression->right)) { + long const valr = fold_constant(expression->left); + return valr != 0 ? + new_Const(get_mode_one(mode)) : + new_Const(get_mode_null(mode)); + } + + return produce_condition_result(expression->right, mode, dbgi); } return produce_condition_result((const expression_t*) expression, mode, @@ -2496,28 +2513,12 @@ 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->base.source_position); - ir_node *base_addr = expression_to_firm(expression->array_ref); - ir_node *offset = expression_to_firm(expression->index); - - type_t *offset_type = skip_typeref(expression->index->base.type); - ir_mode *mode; - if (is_type_signed(offset_type)) { - mode = get_ir_mode(type_ssize_t); - } else { - mode = get_ir_mode(type_size_t); - } - offset = create_conv(dbgi, offset, mode); - - type_t *ref_type = skip_typeref(expression->array_ref->base.type); - assert(is_type_pointer(ref_type)); - pointer_type_t *pointer_type = &ref_type->pointer; - - ir_node *elem_size_const = get_type_size(pointer_type->points_to); - elem_size_const = create_conv(dbgi, elem_size_const, mode); - ir_node *real_offset = new_d_Mul(dbgi, offset, elem_size_const, - mode); - ir_node *result = new_d_Add(dbgi, base_addr, real_offset, mode_P_data); + dbg_info *dbgi = get_dbg_info(&expression->base.source_position); + ir_node *base_addr = expression_to_firm(expression->array_ref); + ir_node *offset = expression_to_firm(expression->index); + type_t *ref_type = skip_typeref(expression->array_ref->base.type); + ir_node *real_offset = adjust_for_pointer_arithmetic(dbgi, offset, ref_type); + ir_node *result = new_d_Add(dbgi, base_addr, real_offset, mode_P_data); return result; } @@ -2779,13 +2780,17 @@ static ir_node *select_addr(const select_expression_t *expression) entity_t *entry = expression->compound_entry; assert(entry->kind == ENTITY_COMPOUND_MEMBER); assert(entry->declaration.kind == DECLARATION_KIND_COMPOUND_MEMBER); - ir_entity *irentity = entry->compound_member.entity; - - assert(irentity != NULL); - ir_node *sel = new_d_simpleSel(dbgi, new_NoMem(), compound_addr, irentity); - - return sel; + if (constant_folding) { + ir_mode *mode = get_irn_mode(compound_addr); + /* FIXME: here, we need an integer mode with the same number of bits as mode */ + ir_node *ofs = new_Const_long(mode_uint, entry->compound_member.offset); + return new_d_Add(dbgi, compound_addr, ofs, mode); + } else { + ir_entity *irentity = entry->compound_member.entity; + assert(irentity != NULL); + return new_d_simpleSel(dbgi, new_NoMem(), compound_addr, irentity); + } } static ir_node *select_to_firm(const select_expression_t *expression) @@ -2855,6 +2860,7 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex tc = void_type_class; goto make_const; + case ATOMIC_TYPE_WCHAR_T: /* gcc handles this as integer */ case ATOMIC_TYPE_CHAR: /* gcc handles this as integer */ case ATOMIC_TYPE_SCHAR: /* gcc handles this as integer */ case ATOMIC_TYPE_UCHAR: /* gcc handles this as integer */ @@ -2995,17 +3001,18 @@ static ir_node *dereference_addr(const unary_expression_t *const expression) static ir_node *expression_to_addr(const expression_t *expression) { switch(expression->kind) { - case EXPR_REFERENCE: - return reference_addr(&expression->reference); case EXPR_ARRAY_ACCESS: return array_access_addr(&expression->array_access); - case EXPR_SELECT: - return select_addr(&expression->select); case EXPR_CALL: return call_expression_to_firm(&expression->call); - case EXPR_UNARY_DEREFERENCE: { + case EXPR_COMPOUND_LITERAL: + return compound_literal_to_firm(&expression->compound_literal); + case EXPR_REFERENCE: + return reference_addr(&expression->reference); + case EXPR_SELECT: + return select_addr(&expression->select); + case EXPR_UNARY_DEREFERENCE: return dereference_addr(&expression->unary); - } default: break; } @@ -3310,9 +3317,7 @@ static ir_node *create_condition_evaluation(const expression_t *expression, } add_immBlock_pred(true_block, true_proj); - if (false_block != NULL) { - add_immBlock_pred(false_block, false_proj); - } + add_immBlock_pred(false_block, false_proj); set_cur_block(NULL); return cond_expr; @@ -4492,9 +4497,7 @@ static void do_while_statement_to_firm(do_while_statement_t *statement) create_condition_evaluation(statement->condition, body_block, false_block); mature_immBlock(body_block); mature_immBlock(header_block); - if (false_block != NULL) { - mature_immBlock(false_block); - } + mature_immBlock(false_block); set_cur_block(false_block); } @@ -4547,7 +4550,7 @@ static void for_statement_to_firm(for_statement_t *statement) ir_node *const false_block = new_immBlock(); /* the loop body */ - ir_node * body_block; + ir_node *body_block; if (statement->body != NULL) { ir_node *const old_continue_label = continue_label; ir_node *const old_break_label = break_label;