X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=c93c67c196e17ff7f247a2df604a3723dbd998df;hb=779610287a11b207e958e31a29f0dd9ea5459e39;hp=be4c17016716e70abdc05218dfa0de1c7d2821e5;hpb=1fcda4a666f4537f4a330281984f94bc7baca8c4;p=cparser diff --git a/ast2firm.c b/ast2firm.c index be4c170..c93c67c 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -1,21 +1,6 @@ /* * This file is part of cparser. - * Copyright (C) 2007-2009 Matthias Braun - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * Copyright (C) 2012 Matthias Braun */ #include @@ -23,7 +8,6 @@ #include #include #include -#include #include #include @@ -37,6 +21,7 @@ #include "adt/util.h" #include "jump_target.h" #include "symbol_t.h" +#include "symbol_table.h" #include "token_t.h" #include "type_t.h" #include "ast_t.h" @@ -45,8 +30,8 @@ #include "diagnostic.h" #include "lang_features.h" #include "types.h" -#include "type_hash.h" #include "mangle.h" +#include "unicode.h" #include "walk.h" #include "warning.h" #include "printer.h" @@ -151,11 +136,8 @@ static void enqueue_inner_function(entity_t *entity) static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos) { const entity_t *entity = get_irg_loc_description(irg, pos); - - if (entity != NULL) { - position_t const *const pos = &entity->base.pos; - warningf(WARN_UNINITIALIZED, pos, "'%N' might be used uninitialized", entity); - } + if (entity) + warningf(WARN_UNINITIALIZED, &entity->base.pos, "'%N' might be used uninitialized", entity); return new_r_Unknown(irg, mode); } @@ -211,9 +193,7 @@ static unsigned decide_modulo_shift(unsigned type_size) { if (architecture_modulo_shift == 0) return 0; - if (type_size < architecture_modulo_shift) - return architecture_modulo_shift; - return type_size; + return MAX(type_size, architecture_modulo_shift); } static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind) @@ -253,12 +233,6 @@ static void init_atomic_modes(void) } } -ir_mode *get_atomic_mode(atomic_type_kind_t kind) -{ - assert(kind <= ATOMIC_TYPE_LAST); - return atomic_modes[kind]; -} - static ir_node *get_vla_size(array_type_t *const type) { ir_node *size_node = type->size_node; @@ -352,6 +326,8 @@ static type_t *get_parameter_type(type_t *orig_type) return type; } +static ir_type *get_ir_type(type_t *type); + static ir_type *create_method_type(const function_type_t *function_type, bool for_closure) { type_t *return_type = skip_typeref(function_type->return_type); @@ -500,10 +476,12 @@ static ir_type *get_signed_int_type_for_bit_size(ir_type *base_tp, mode = s_modes[size]; if (mode == NULL) { - char name[32]; + ir_mode *base_mode = get_type_mode(base_tp); + unsigned modulo_shift = get_mode_modulo_shift(base_mode); + char name[32]; snprintf(name, sizeof(name), "bf_I%u", size); - mode = new_int_mode(name, irma_twos_complement, size, 1, 0); + mode = new_int_mode(name, irma_twos_complement, size, 1, modulo_shift); s_modes[size] = mode; } @@ -532,10 +510,12 @@ static ir_type *get_unsigned_int_type_for_bit_size(ir_type *base_tp, mode = u_modes[size]; if (mode == NULL) { - char name[32]; + ir_mode *base_mode = get_type_mode(base_tp); + unsigned modulo_shift = get_mode_modulo_shift(base_mode); + char name[32]; snprintf(name, sizeof(name), "bf_U%u", size); - mode = new_int_mode(name, irma_twos_complement, size, 0, 0); + mode = new_int_mode(name, irma_twos_complement, size, 0, modulo_shift); u_modes[size] = mode; } @@ -615,15 +595,15 @@ static ir_type *create_compound_type(compound_type_t *const type, bool const inc symbol_t *symbol = entry->base.symbol; type_t *entry_type = entry->declaration.type; - ident *ident; + ident *member_id; if (symbol == NULL) { /* anonymous bitfield member, skip */ if (entry->compound_member.bitfield) continue; assert(is_type_compound(entry_type)); - ident = id_unique("anon.%u"); + member_id = id_unique("anon.%u"); } else { - ident = new_id_from_str(symbol->string); + member_id = new_id_from_str(symbol->string); } dbg_info *dbgi = get_dbg_info(&entry->base.pos); @@ -634,7 +614,7 @@ static ir_type *create_compound_type(compound_type_t *const type, bool const inc } else { entry_irtype = get_ir_type(entry_type); } - ir_entity *entity = new_d_entity(irtype, ident, entry_irtype, dbgi); + ir_entity *entity = new_d_entity(irtype, member_id, entry_irtype, dbgi); set_entity_offset(entity, entry->compound_member.offset); set_entity_offset_bits_remainder(entity, @@ -694,7 +674,7 @@ static ir_type *get_ir_type_incomplete(type_t *type) } } -ir_type *get_ir_type(type_t *type) +static ir_type *get_ir_type(type_t *type) { type = skip_typeref(type); @@ -2172,10 +2152,10 @@ static ir_node *handle_assume_compare(dbg_info *dbi, } expression_t *con = NULL; - if (is_local_variable(op1) && is_constant_expression(op2) == EXPR_CLASS_CONSTANT) { + if (is_local_variable(op1) && is_constant_expression(op2) != EXPR_CLASS_VARIABLE) { var = op1->reference.entity; con = op2; - } else if (is_constant_expression(op1) == EXPR_CLASS_CONSTANT && is_local_variable(op2)) { + } else if (is_constant_expression(op1) != EXPR_CLASS_VARIABLE && is_local_variable(op2)) { relation = get_inversed_relation(relation); var = op2->reference.entity; con = op1; @@ -2218,14 +2198,17 @@ static ir_node *handle_assume(expression_t const *const expr) static ir_node *create_cast(unary_expression_t const *const expr) { + type_t *const from_type = skip_typeref(expr->value->base.type); + ir_node *value = is_type_complex(from_type) + ? expression_to_complex(expr->value).real + : expression_to_value(expr->value); + type_t *const type = skip_typeref(expr->base.type); if (is_type_void(type)) return NULL; - ir_node *value = expression_to_value(expr->value); - dbg_info *const dbgi = get_dbg_info(&expr->base.pos); - type_t *const from_type = skip_typeref(expr->value->base.type); - ir_mode *const mode = get_ir_mode_storage(type); + dbg_info *const dbgi = get_dbg_info(&expr->base.pos); + ir_mode *const mode = get_ir_mode_storage(type); /* check for conversion from / to __based types */ if (is_type_pointer(type) && is_type_pointer(from_type)) { const variable_t *from_var = from_type->pointer.base_variable; @@ -2455,7 +2438,7 @@ static void compare_to_control_flow(expression_t const *const expr, ir_node *con /* set branch prediction info based on __builtin_expect */ if (is_builtin_expect(expr) && is_Cond(cond)) { call_argument_t *const argument = expr->call.arguments->next; - if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) { + if (is_constant_expression(argument->expression) != EXPR_CLASS_VARIABLE) { bool const cnst = fold_constant_to_bool(argument->expression); cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE; set_Cond_jmp_pred(cond, pred); @@ -2655,9 +2638,10 @@ static ir_node *compound_literal_addr(compound_literal_expression_t const *const type_t *type = expression->type; initializer_t *initializer = expression->initializer; - if (expression->global_scope || - ((type->base.qualifiers & TYPE_QUALIFIER_CONST) - && is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT)) { + if (expression->global_scope || ( + type->base.qualifiers & TYPE_QUALIFIER_CONST && + is_constant_initializer(initializer) != EXPR_CLASS_VARIABLE + )) { ir_entity *entity = create_initializer_entity(dbgi, initializer, type); return create_symconst(dbgi, entity); } else { @@ -2702,28 +2686,31 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression) return get_type_size_node(type); } -static entity_t *get_expression_entity(const expression_t *expression) -{ - if (expression->kind != EXPR_REFERENCE) - return NULL; +static unsigned get_object_alignment(expression_t const *expr); - return expression->reference.entity; +static unsigned get_address_alignment(expression_t const *const expr) +{ + if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) { + return get_object_alignment(expr->unary.value); + } else { + type_t *const type = skip_typeref(expr->base.type); + assert(is_type_pointer(type)); + return get_type_alignment(type->pointer.points_to); + } } -static unsigned get_cparser_entity_alignment(const entity_t *entity) +static unsigned get_object_alignment(expression_t const *const expr) { - switch (entity->kind) { - case DECLARATION_KIND_CASES: - return entity->declaration.alignment; - case ENTITY_STRUCT: - case ENTITY_UNION: - return entity->compound.alignment; - case ENTITY_TYPEDEF: - return entity->typedefe.alignment; - default: - break; + entity_t *ent; + switch (expr->kind) { + case EXPR_ARRAY_ACCESS: return get_address_alignment(expr->array_access.array_ref); + case EXPR_UNARY_DEREFERENCE: return get_address_alignment(expr->unary.value); + case EXPR_REFERENCE: ent = expr->reference.entity; break; + case EXPR_SELECT: ent = expr->select.compound_entry; break; + default: return get_type_alignment(expr->base.type); } - return 0; + assert(is_declaration(ent)); + return ent->declaration.alignment; } /** @@ -2731,20 +2718,9 @@ static unsigned get_cparser_entity_alignment(const entity_t *entity) */ static ir_node *alignof_to_firm(const typeprop_expression_t *expression) { - unsigned alignment = 0; - - const expression_t *tp_expression = expression->tp_expression; - if (tp_expression != NULL) { - entity_t *entity = get_expression_entity(tp_expression); - if (entity != NULL) { - alignment = get_cparser_entity_alignment(entity); - } - } - - if (alignment == 0) { - type_t *type = expression->type; - alignment = get_type_alignment(type); - } + unsigned const alignment = expression->tp_expression + ? get_object_alignment(expression->tp_expression) + : get_type_alignment(expression->type); dbg_info *dbgi = get_dbg_info(&expression->base.pos); ir_mode *mode = get_ir_mode_storage(expression->base.type); @@ -2756,7 +2732,7 @@ static void init_ir_types(void); ir_tarval *fold_constant_to_tarval(const expression_t *expression) { - assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT); + assert(is_constant_expression(expression) >= EXPR_CLASS_CONSTANT); bool constant_folding_old = constant_folding; constant_folding = true; @@ -2782,7 +2758,7 @@ ir_tarval *fold_constant_to_tarval(const expression_t *expression) static complex_constant fold_complex_constant(const expression_t *expression) { - assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT); + assert(is_constant_expression(expression) >= EXPR_CLASS_CONSTANT); bool constant_folding_old = constant_folding; constant_folding = true; @@ -3156,7 +3132,7 @@ static ir_node *builtin_constant_to_firm( const builtin_constant_expression_t *expression) { ir_mode *const mode = get_ir_mode_storage(expression->base.type); - bool const v = is_constant_expression(expression->value) == EXPR_CLASS_CONSTANT; + bool const v = is_constant_expression(expression->value) != EXPR_CLASS_VARIABLE; return create_Const_from_bool(mode, v); } @@ -3210,7 +3186,9 @@ static ir_node *expression_to_value(expression_t const *const expr) switch (expr->kind) { case EXPR_UNARY_CAST: - if (is_type_atomic(skip_typeref(expr->base.type), ATOMIC_TYPE_BOOL)) { + if (!is_type_atomic(skip_typeref(expr->base.type), ATOMIC_TYPE_BOOL)) + return create_cast(&expr->unary); + /* FALLTHROUGH */ case EXPR_BINARY_EQUAL: case EXPR_BINARY_GREATER: case EXPR_BINARY_GREATEREQUAL: @@ -3225,16 +3203,14 @@ static ir_node *expression_to_value(expression_t const *const expr) case EXPR_BINARY_LOGICAL_AND: case EXPR_BINARY_LOGICAL_OR: case EXPR_BINARY_NOTEQUAL: - case EXPR_UNARY_NOT:; - jump_target true_target; - jump_target false_target; - init_jump_target(&true_target, NULL); - init_jump_target(&false_target, NULL); - expression_to_control_flow(expr, &true_target, &false_target); - return control_flow_to_1_0(expr, &true_target, &false_target); - } else { - return create_cast(&expr->unary); - } + case EXPR_UNARY_NOT: { + jump_target true_target; + jump_target false_target; + init_jump_target(&true_target, NULL); + init_jump_target(&false_target, NULL); + expression_to_control_flow(expr, &true_target, &false_target); + return control_flow_to_1_0(expr, &true_target, &false_target); + } case EXPR_BINARY_ADD: case EXPR_BINARY_BITWISE_AND: @@ -3326,9 +3302,9 @@ static void complex_equality_evaluation(const binary_expression_t *binexpr, jump_target *const true_target, jump_target *const false_target, ir_relation relation); -static complex_value create_complex_condition_evaluation( - const expression_t *const expression, jump_target *const true_target, - jump_target *const false_target); +static complex_value complex_to_control_flow(const expression_t *expression, + jump_target *true_target, + jump_target *false_target); /** * create a short-circuit expression evaluation that tries to construct @@ -3395,23 +3371,24 @@ static ir_node *expression_to_control_flow(expression_t const *const expr, jump_ if (is_type_atomic(skip_typeref(expr->base.type), ATOMIC_TYPE_BOOL)) { expression_to_control_flow(expr->unary.value, true_target, false_target); return NULL; - } else { - default:; - type_t *const type = skip_typeref(expr->base.type); - if (is_type_complex(type)) { - create_complex_condition_evaluation(expr, true_target, false_target); - return NULL; - } - - dbg_info *const dbgi = get_dbg_info(&expr->base.pos); - ir_mode *const mode = get_ir_mode_arithmetic(type); - ir_node *const val = create_conv(dbgi, expression_to_value(expr), mode); - ir_node *const left = val; - ir_node *const right = new_Const(get_mode_null(get_irn_mode(val))); - ir_relation const relation = ir_relation_unordered_less_greater; - compare_to_control_flow(expr, left, right, relation, true_target, false_target); - return val; } + /* FALLTHROUGH */ + default: { + type_t *const type = skip_typeref(expr->base.type); + if (is_type_complex(type)) { + complex_to_control_flow(expr, true_target, false_target); + return NULL; + } + + dbg_info *const dbgi = get_dbg_info(&expr->base.pos); + ir_mode *const mode = get_ir_mode_arithmetic(type); + ir_node *const val = create_conv(dbgi, expression_to_value(expr), mode); + ir_node *const left = val; + ir_node *const right = new_Const(get_mode_null(get_irn_mode(val))); + ir_relation const relation = ir_relation_unordered_less_greater; + compare_to_control_flow(expr, left, right, relation, true_target, false_target); + return val; + } } } @@ -3435,37 +3412,37 @@ static void store_complex(dbg_info *dbgi, ir_node *addr, type_t *type, complex_value value) { value = complex_conv_to_storage(dbgi, value, type); - ir_graph *irg = current_ir_graph; - ir_type *irtype = get_ir_type(type); - ir_node *mem = get_store(); - ir_node *nomem = get_irg_no_mem(irg); - ir_mode *mode = get_complex_mode_storage(type); - ir_node *real = create_conv(dbgi, value.real, mode); - ir_node *imag = create_conv(dbgi, value.imag, mode); - ir_node *storer = new_d_Store(dbgi, mem, addr, real, cons_floats); - ir_node *memr = new_Proj(storer, mode_M, pn_Store_M); - ir_mode *mode_uint = atomic_modes[ATOMIC_TYPE_UINT]; - ir_node *one = new_Const(get_mode_one(mode_uint)); - ir_node *in[1] = { one }; - ir_entity *arrent = get_array_element_entity(irtype); - ir_node *addri = new_d_Sel(dbgi, nomem, addr, 1, in, arrent); - ir_node *storei = new_d_Store(dbgi, memr, addri, imag, cons_floats); - ir_node *memi = new_Proj(storei, mode_M, pn_Store_M); + ir_graph *const irg = current_ir_graph; + ir_type *const irtype = get_ir_type(type); + ir_node *const mem = get_store(); + ir_node *const nomem = get_irg_no_mem(irg); + ir_mode *const mode = get_complex_mode_storage(type); + ir_node *const real = create_conv(dbgi, value.real, mode); + ir_node *const imag = create_conv(dbgi, value.imag, mode); + ir_node *const storer = new_d_Store(dbgi, mem, addr, real, cons_floats); + ir_node *const memr = new_Proj(storer, mode_M, pn_Store_M); + ir_mode *const muint = atomic_modes[ATOMIC_TYPE_UINT]; + ir_node *const one = new_Const(get_mode_one(muint)); + ir_node *const in[1] = { one }; + ir_entity *const arrent = get_array_element_entity(irtype); + ir_node *const addri = new_d_Sel(dbgi, nomem, addr, 1, in, arrent); + ir_node *const storei = new_d_Store(dbgi, memr, addri, imag, cons_floats); + ir_node *const memi = new_Proj(storei, mode_M, pn_Store_M); set_store(memi); } static ir_node *complex_to_memory(dbg_info *dbgi, type_t *type, complex_value value) { - ir_graph *irg = current_ir_graph; - ir_type *frame_type = get_irg_frame_type(irg); - ident *id = id_unique("cmplex_tmp.%u"); - ir_type *irtype = get_ir_type(type); - ir_entity *tmp_storage = new_entity(frame_type, id, irtype); + ir_graph *const irg = current_ir_graph; + ir_type *const frame_type = get_irg_frame_type(irg); + ident *const id = id_unique("cmplex_tmp.%u"); + ir_type *const irtype = get_ir_type(type); + ir_entity *const tmp_storage = new_entity(frame_type, id, irtype); + ir_node *const frame = get_irg_frame(irg); + ir_node *const nomem = get_irg_no_mem(irg); + ir_node *const addr = new_simpleSel(nomem, frame, tmp_storage); set_entity_compiler_generated(tmp_storage, 1); - ir_node *frame = get_irg_frame(irg); - ir_node *nomem = get_irg_no_mem(irg); - ir_node *addr = new_simpleSel(nomem, frame, tmp_storage); store_complex(dbgi, addr, type, value); return addr; } @@ -3494,11 +3471,11 @@ static complex_value complex_deref_address(dbg_info *const dbgi, if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE) flags |= cons_volatile; - ir_mode *const mode = get_complex_mode_storage(type); - ir_node *const memory = get_store(); - ir_node *const load = new_d_Load(dbgi, memory, addr, mode, flags); - ir_node *const load_mem = new_Proj(load, mode_M, pn_Load_M); - ir_node *const load_res = new_Proj(load, mode, pn_Load_res); + ir_mode *const mode = get_complex_mode_storage(type); + ir_node *const memory = get_store(); + ir_node *const load = new_d_Load(dbgi, memory, addr, mode, flags); + ir_node *const load_mem = new_Proj(load, mode_M, pn_Load_M); + ir_node *const load_res = new_Proj(load, mode, pn_Load_res); ir_type *const irtype = get_ir_type(type); ir_mode *const mode_uint = atomic_modes[ATOMIC_TYPE_UINT]; @@ -3533,10 +3510,9 @@ static complex_value complex_reference_to_firm(const reference_expression_t *ref static complex_value complex_select_to_firm(const select_expression_t *select) { - dbg_info *dbgi = get_dbg_info(&select->base.pos); - ir_node *addr = select_addr(select); - type_t *type = skip_typeref(select->base.type); - assert(is_type_complex(type)); + dbg_info *const dbgi = get_dbg_info(&select->base.pos); + ir_node *const addr = select_addr(select); + type_t *const type = skip_typeref(select->base.type); return complex_deref_address(dbgi, type, addr, cons_none); } @@ -3574,21 +3550,19 @@ static complex_value get_complex_from_lvalue(const expression_t *expression, static complex_value complex_cast_to_firm(const unary_expression_t *expression) { - const expression_t *value = expression->value; - dbg_info *dbgi = get_dbg_info(&expression->base.pos); - type_t *from_type = skip_typeref(value->base.type); - type_t *to_type = skip_typeref(expression->base.type); - ir_mode *mode = get_complex_mode_storage(to_type); - - assert(is_type_complex(to_type)); + const expression_t *const value = expression->value; + dbg_info *const dbgi = get_dbg_info(&expression->base.pos); + type_t *const from_type = skip_typeref(value->base.type); + type_t *const to_type = skip_typeref(expression->base.type); + ir_mode *const mode = get_complex_mode_storage(to_type); if (is_type_complex(from_type)) { complex_value cvalue = expression_to_complex(value); return complex_conv(dbgi, cvalue, mode); } else { - ir_node *value_node = expression_to_value(value); - ir_node *zero = new_Const(get_mode_null(mode)); - ir_node *casted = create_conv(dbgi, value_node, mode); + ir_node *const value_node = expression_to_value(value); + ir_node *const zero = new_Const(get_mode_null(mode)); + ir_node *const casted = create_conv(dbgi, value_node, mode); return (complex_value) { casted, zero }; } } @@ -3683,12 +3657,10 @@ static void set_complex_value_for_expression(dbg_info *dbgi, complex_value value, ir_node *addr) { - type_t *type = skip_typeref(expression->base.type); - assert(is_type_complex(type)); - - ir_mode *mode = get_complex_mode_storage(type); - ir_node *real = create_conv(dbgi, value.real, mode); - ir_node *imag = create_conv(dbgi, value.imag, mode); + type_t *const type = skip_typeref(expression->base.type); + ir_mode *const mode = get_complex_mode_storage(type); + ir_node *const real = create_conv(dbgi, value.real, mode); + ir_node *const imag = create_conv(dbgi, value.imag, mode); if (expression->kind == EXPR_REFERENCE) { const reference_expression_t *ref = &expression->reference; @@ -3828,13 +3800,25 @@ static void complex_equality_evaluation(const binary_expression_t *binexpr, set_unreachable_now(); } -static complex_value create_complex_condition_evaluation( +static complex_value complex_to_control_flow( const expression_t *const expression, jump_target *const true_target, jump_target *const false_target) { jump_target extra_target; init_jump_target(&extra_target, NULL); complex_value value = expression_to_complex(expression); + if (is_Const(value.real) && is_Const(value.imag)) { + ir_tarval *tv_real = get_Const_tarval(value.real); + ir_tarval *tv_imag = get_Const_tarval(value.imag); + if (tarval_is_null(tv_real) && tarval_is_null(tv_imag)) { + jump_to_target(false_target); + } else { + jump_to_target(true_target); + } + set_unreachable_now(); + return value; + } + dbg_info *const dbgi = get_dbg_info(&expression->base.pos); type_t *const type = expression->base.type; ir_mode *const mode = get_complex_mode_arithmetic(type); @@ -3865,23 +3849,6 @@ static complex_value create_complex_condition_evaluation( static complex_value complex_conditional_to_firm( const conditional_expression_t *const expression) { - /* first try to fold a constant condition */ - if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) { - bool val = fold_constant_to_bool(expression->condition); - if (val) { - expression_t *true_expression = expression->true_expression; - if (true_expression == NULL) { - /* we will evaluate true_expression a second time here, but in - * this case it is harmless since constant expression have no - * side effects */ - true_expression = expression->condition; - } - return expression_to_complex(true_expression); - } else { - return expression_to_complex(expression->false_expression); - } - } - jump_target true_target; jump_target false_target; init_jump_target(&true_target, NULL); @@ -3890,17 +3857,19 @@ static complex_value complex_conditional_to_firm( memset(&cond_val, 0, sizeof(cond_val)); if (expression->true_expression == NULL) { assert(is_type_complex(skip_typeref(expression->condition->base.type))); - cond_val - = create_complex_condition_evaluation(expression->condition, - &true_target, &false_target); + cond_val = complex_to_control_flow(expression->condition, + &true_target, &false_target); } else { expression_to_control_flow(expression->condition, &true_target, &false_target); } - complex_value val; + complex_value val; memset(&val, 0, sizeof(val)); - jump_target exit_target; + jump_target exit_target; init_jump_target(&exit_target, NULL); + type_t *const type = skip_typeref(expression->base.type); + ir_mode *const mode = get_complex_mode_arithmetic(type); + dbg_info *const dbgi = get_dbg_info(&expression->base.pos); if (enter_jump_target(&true_target)) { if (expression->true_expression) { @@ -3909,19 +3878,18 @@ static complex_value complex_conditional_to_firm( assert(cond_val.real != NULL); val = cond_val; } + val = complex_conv(dbgi, val, mode); jump_to_target(&exit_target); } - type_t *const type = skip_typeref(expression->base.type); if (enter_jump_target(&false_target)) { complex_value false_val = expression_to_complex(expression->false_expression); + false_val = complex_conv(dbgi, false_val, mode); jump_to_target(&exit_target); if (val.real != NULL) { ir_node *const inr[] = { val.real, false_val.real }; ir_node *const ini[] = { val.imag, false_val.imag }; - dbg_info *const dbgi = get_dbg_info(&expression->base.pos); - ir_mode *const mode = get_complex_mode_arithmetic(type); ir_node *const block = exit_target.block; val.real = new_rd_Phi(dbgi, block, lengthof(inr), inr, mode); val.imag = new_rd_Phi(dbgi, block, lengthof(ini), ini, mode); @@ -3933,9 +3901,7 @@ static complex_value complex_conditional_to_firm( if (!enter_jump_target(&exit_target)) { set_cur_block(new_Block(0, NULL)); assert(!is_type_void(type)); - ir_mode *mode = get_complex_mode_arithmetic(type); - val.real = new_Unknown(mode); - val.imag = val.real; + val.real = val.imag = new_Bad(mode); } return val; } @@ -3943,7 +3909,7 @@ static complex_value complex_conditional_to_firm( static void create_local_declarations(entity_t*); static complex_value compound_statement_to_firm_complex( - compound_statement_t *compound) + const compound_statement_t *compound) { create_local_declarations(compound->scope.entities); @@ -3969,10 +3935,19 @@ static complex_value compound_statement_to_firm_complex( return result; } +static complex_value complex_assign_to_firm(const binary_expression_t *expr) +{ + dbg_info *const dbgi = get_dbg_info(&expr->base.pos); + complex_value const value = expression_to_complex(expr->right); + ir_node *const addr = expression_to_addr(expr->left); + set_complex_value_for_expression(dbgi, expr->left, value, addr); + return value; +} + static complex_value complex_statement_expression_to_firm( const statement_expression_t *const expr) { - statement_t *statement = expr->statement; + const statement_t *const statement = expr->statement; assert(statement->kind == STATEMENT_COMPOUND); return compound_statement_to_firm_complex(&statement->compound); @@ -4026,14 +4001,8 @@ static complex_value expression_to_complex(const expression_t *expression) return complex_negate_to_firm(&expression->unary); case EXPR_UNARY_COMPLEMENT: return complex_complement_to_firm(&expression->unary); - case EXPR_BINARY_ASSIGN: { - const binary_expression_t *binexpr = &expression->binary; - dbg_info *dbgi = get_dbg_info(&binexpr->base.pos); - complex_value value = expression_to_complex(binexpr->right); - ir_node *addr = expression_to_addr(binexpr->left); - set_complex_value_for_expression(dbgi, binexpr->left, value, addr); - return value; - } + case EXPR_BINARY_ASSIGN: + return complex_assign_to_firm(&expression->binary); case EXPR_LITERAL_CASES: return complex_literal_to_firm(&expression->literal); case EXPR_CALL: @@ -4042,11 +4011,9 @@ static complex_value expression_to_complex(const expression_t *expression) return complex_conditional_to_firm(&expression->conditional); case EXPR_STATEMENT: return complex_statement_expression_to_firm(&expression->statement); - default: - break; + panic("unexpected complex expression"); } - panic("complex expression not implemented yet"); } @@ -4741,12 +4708,12 @@ static void create_variable_initializer(entity_t *entity) && get_entity_owner(irentity) != get_tls_type()) { add_entity_linkage(irentity, IR_LINKAGE_CONSTANT); } - ir_initializer_t *initializer = create_initializer_compound(2); + ir_initializer_t *complex_init = create_initializer_compound(2); ir_initializer_t *reali = create_initializer_const(real); - set_initializer_compound_value(initializer, 0, reali); + set_initializer_compound_value(complex_init, 0, reali); ir_initializer_t *imagi = create_initializer_const(imag); - set_initializer_compound_value(initializer, 1, imagi); - set_entity_initializer(irentity, initializer); + set_initializer_compound_value(complex_init, 1, imagi); + set_entity_initializer(irentity, complex_init); } return; } else if (!is_type_scalar(init_type)) { @@ -4955,7 +4922,7 @@ static ir_node *expression_statement_to_firm(expression_statement_t *statement) type_t *type = skip_typeref(expression->base.type); if (is_type_complex(type)) { expression_to_complex(expression); - return NULL; /* TODO */ + return NULL; } else { return expression_to_value(statement->expression); } @@ -5173,7 +5140,7 @@ static ir_node *do_while_statement_to_firm(do_while_statement_t *statement) expression_t *const cond = statement->condition; /* Avoid an explicit body block in case of do ... while (0);. */ - if (is_constant_expression(cond) == EXPR_CLASS_CONSTANT && !fold_constant_to_bool(cond)) { + if (is_constant_expression(cond) != EXPR_CLASS_VARIABLE && !fold_constant_to_bool(cond)) { /* do ... while (0);. */ statement_to_firm(statement->body); jump_to_target(&continue_target); @@ -5229,7 +5196,7 @@ static ir_node *for_statement_to_firm(for_statement_t *statement) /* Create the condition. */ expression_t *const cond = statement->condition; - if (cond && (is_constant_expression(cond) != EXPR_CLASS_CONSTANT || !fold_constant_to_bool(cond))) { + if (cond && (is_constant_expression(cond) == EXPR_CLASS_VARIABLE || !fold_constant_to_bool(cond))) { jump_target body_target; init_jump_target(&body_target, NULL); expression_to_control_flow(cond, &body_target, &break_target); @@ -5677,9 +5644,8 @@ static int count_local_variables(const entity_t *entity, for (; entity != end; entity = entity->base.next) { if ((entity->kind == ENTITY_VARIABLE || entity->kind == ENTITY_PARAMETER) && !var_needs_entity(&entity->variable)) { - ++count; - if (is_type_complex(skip_typeref(entity->declaration.type))) - ++count; + type_t *type = skip_typeref(entity->declaration.type); + count += is_type_complex(type) ? 2 : 1; } } return count; @@ -5919,32 +5885,6 @@ static void create_function(entity_t *entity) irg_finalize_cons(irg); - /* finalize the frame type */ - ir_type *frame_type = get_irg_frame_type(irg); - int n = get_compound_n_members(frame_type); - int align_all = 4; - int offset = 0; - for (int i = 0; i < n; ++i) { - ir_entity *member = get_compound_member(frame_type, i); - ir_type *entity_type = get_entity_type(member); - - int align = get_type_alignment_bytes(entity_type); - if (align > align_all) - align_all = align; - int misalign = 0; - if (align > 0) { - misalign = offset % align; - if (misalign > 0) { - offset += align - misalign; - } - } - - set_entity_offset(member, offset); - offset += get_type_size_bytes(entity_type); - } - set_type_size_bytes(frame_type, offset); - set_type_alignment_bytes(frame_type, align_all); - irg_verify(irg, VERIFY_ENFORCE_SSA); current_vararg_entity = old_current_vararg_entity; current_function = old_current_function;