X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=f92f870d99d20e2a4ceec3b9c4599c02a27d8a21;hb=6b26906854c2f5423fa3986a0caf3c23b200b553;hp=fe9aa08be948277f07514888a8f1b3506d2b6bee;hpb=58470bf2cd0db88a0dea7d68433283b569a2ba83;p=cparser diff --git a/ast2firm.c b/ast2firm.c index fe9aa08..f92f870 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -897,10 +897,10 @@ static void handle_decl_modifiers(ir_entity *irentity, entity_t *entity) if (is_method_entity(irentity)) { if (modifiers & DM_PURE) { - set_entity_additional_property(irentity, mtp_property_pure); + set_entity_additional_properties(irentity, mtp_property_pure); } if (modifiers & DM_CONST) { - set_entity_additional_property(irentity, mtp_property_const); + add_entity_additional_properties(irentity, mtp_property_const); have_const_functions = true; } } @@ -1884,6 +1884,22 @@ static ir_node *process_builtin_call(const call_expression_t *call) set_store(new_Proj(irn, mode_M, pn_Builtin_M)); return NULL; } + case bk_gnu_builtin_object_size: { + /* determine value of "type" */ + expression_t *type_expression = call->arguments->next->expression; + long type_val = fold_constant_to_int(type_expression); + type_t *type = function_type->function.return_type; + ir_mode *mode = get_ir_mode_arithmetic(type); + ir_tarval *result; + + /* just produce a "I don't know" result */ + if (type_val & 2) + result = new_tarval_from_long(0, mode); + else + result = new_tarval_from_long(-1, mode); + + return new_d_Const(dbgi, result); + } case bk_gnu_builtin_trap: case bk_ms__ud2: { @@ -2508,6 +2524,11 @@ static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node, type_t *from_type, type_t *type) { type = skip_typeref(type); + if (type == type_void) { + /* make sure firm type is constructed */ + (void) get_ir_type(type); + return NULL; + } if (!is_type_scalar(type)) { /* make sure firm type is constructed */ (void) get_ir_type(type); @@ -4228,14 +4249,68 @@ static ir_initializer_t *create_ir_initializer( panic("unknown initializer"); } +/** ANSI C §6.7.8:21: If there are fewer initializers [..] than there + * are elements [...] the remainder of the aggregate shall be initialized + * implicitly the same as objects that have static storage duration. */ +static void create_dynamic_null_initializer(ir_entity *entity, dbg_info *dbgi, + ir_node *base_addr) +{ + /* for unions we must NOT do anything for null initializers */ + ir_type *owner = get_entity_owner(entity); + if (is_Union_type(owner)) { + return; + } + + ir_type *ent_type = get_entity_type(entity); + /* create sub-initializers for a compound type */ + if (is_compound_type(ent_type)) { + unsigned n_members = get_compound_n_members(ent_type); + for (unsigned n = 0; n < n_members; ++n) { + ir_entity *member = get_compound_member(ent_type, n); + ir_node *addr = new_d_simpleSel(dbgi, new_NoMem(), base_addr, + member); + create_dynamic_null_initializer(member, dbgi, addr); + } + return; + } + if (is_Array_type(ent_type)) { + assert(has_array_upper_bound(ent_type, 0)); + long n = get_array_upper_bound_int(ent_type, 0); + for (long i = 0; i < n; ++i) { + ir_tarval *index_tv = new_tarval_from_long(i, mode_uint); + ir_node *cnst = new_d_Const(dbgi, index_tv); + ir_node *in[1] = { cnst }; + ir_entity *arrent = get_array_element_entity(ent_type); + ir_node *addr = new_d_Sel(dbgi, new_NoMem(), base_addr, 1, in, + arrent); + create_dynamic_null_initializer(arrent, dbgi, addr); + } + return; + } + + ir_mode *value_mode = get_type_mode(ent_type); + ir_node *node = new_Const_long(value_mode, 0); + + /* is it a bitfield type? */ + if (is_Primitive_type(ent_type) && + get_primitive_base_type(ent_type) != NULL) { + bitfield_store_to_firm(dbgi, entity, base_addr, node, false); + return; + } + + ir_node *mem = get_store(); + ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none); + ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M); + set_store(proj_m); +} + static void create_dynamic_initializer_sub(ir_initializer_t *initializer, ir_entity *entity, ir_type *type, dbg_info *dbgi, ir_node *base_addr) { switch(get_initializer_kind(initializer)) { - case IR_INITIALIZER_NULL: { - /* NULL is undefined for dynamic initializers */ + case IR_INITIALIZER_NULL: + create_dynamic_null_initializer(entity, dbgi, base_addr); return; - } case IR_INITIALIZER_CONST: { ir_node *node = get_initializer_const_value(initializer); ir_type *ent_type = get_entity_type(entity); @@ -4853,14 +4928,10 @@ static void if_statement_to_firm(if_statement_t *statement) static void while_statement_to_firm(while_statement_t *statement) { - ir_node *jmp = NULL; - if (get_cur_block() != NULL) { - jmp = new_Jmp(); - } - /* create the header block */ ir_node *header_block = new_immBlock(); - if (jmp != NULL) { + if (get_cur_block() != NULL) { + ir_node *const jmp = new_Jmp(); add_immBlock_pred(header_block, jmp); } @@ -4880,7 +4951,7 @@ static void while_statement_to_firm(while_statement_t *statement) break_label = old_break_label; if (get_cur_block() != NULL) { - jmp = new_Jmp(); + ir_node *const jmp = new_Jmp(); add_immBlock_pred(header_block, jmp); } @@ -5105,8 +5176,8 @@ static void switch_statement_to_firm(switch_statement_t *statement) current_switch = statement; /* determine a free number for the default label */ - unsigned long num_cases = 0; - long def_nr = 0; + unsigned long num_cases = 0; + long default_proj_nr = 0; for (case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) { if (l->expression == NULL) { /* default case */ @@ -5114,18 +5185,18 @@ static void switch_statement_to_firm(switch_statement_t *statement) } if (l->last_case >= l->first_case) num_cases += l->last_case - l->first_case + 1; - if (l->last_case > def_nr) - def_nr = l->last_case; + if (l->last_case > default_proj_nr) + default_proj_nr = l->last_case; } - if (def_nr == INT_MAX) { + if (default_proj_nr == INT_MAX) { /* Bad: an overflow will occur, we cannot be sure that the * maximum + 1 is a free number. Scan the values a second * time to find a free number. */ unsigned char *bits = xmalloc((num_cases + 7) >> 3); - memset(bits, 0, (num_cases + 7) >> 3); + memset(bits, 0, (num_cases + 7) >> 3); for (case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) { if (l->expression == NULL) { /* default case */ @@ -5151,11 +5222,15 @@ static void switch_statement_to_firm(switch_statement_t *statement) break; free(bits); - def_nr = i; + default_proj_nr = i; } else { - ++def_nr; + ++default_proj_nr; + } + statement->default_proj_nr = default_proj_nr; + /* safety check: cond might already be folded to a Bad */ + if (cond != NULL && is_Cond(cond)) { + set_Cond_default_proj(cond, default_proj_nr); } - statement->default_proj_nr = def_nr; if (statement->body != NULL) { statement_to_firm(statement->body); @@ -5168,8 +5243,7 @@ static void switch_statement_to_firm(switch_statement_t *statement) if (!saw_default_label && first_block != NULL) { set_cur_block(first_block); - ir_node *const proj = new_d_defaultProj(dbgi, cond, - statement->default_proj_nr); + ir_node *const proj = new_d_Proj(dbgi, cond, mode_X, default_proj_nr); add_immBlock_pred(get_break_label(), proj); } @@ -5210,8 +5284,8 @@ static void case_label_to_firm(const case_label_statement_t *statement) } while (pn++ < end_pn); } else { saw_default_label = true; - proj = new_d_defaultProj(dbgi, current_switch_cond, - current_switch->default_proj_nr); + proj = new_d_Proj(dbgi, current_switch_cond, mode_X, + current_switch->default_proj_nr); add_immBlock_pred(block, proj); } @@ -5727,22 +5801,22 @@ static void handle_decl_modifier_irg(ir_graph_ptr irg, { if (decl_modifiers & DM_RETURNS_TWICE) { /* TRUE if the declaration includes __attribute__((returns_twice)) */ - set_irg_additional_property(irg, mtp_property_returns_twice); + add_irg_additional_properties(irg, mtp_property_returns_twice); } if (decl_modifiers & DM_NORETURN) { /* TRUE if the declaration includes the Microsoft __declspec(noreturn) specifier. */ - set_irg_additional_property(irg, mtp_property_noreturn); + add_irg_additional_properties(irg, mtp_property_noreturn); } if (decl_modifiers & DM_NOTHROW) { /* TRUE if the declaration includes the Microsoft __declspec(nothrow) specifier. */ - set_irg_additional_property(irg, mtp_property_nothrow); + add_irg_additional_properties(irg, mtp_property_nothrow); } if (decl_modifiers & DM_NAKED) { /* TRUE if the declaration includes the Microsoft __declspec(naked) specifier. */ - set_irg_additional_property(irg, mtp_property_naked); + add_irg_additional_properties(irg, mtp_property_naked); } if (decl_modifiers & DM_FORCEINLINE) { /* TRUE if the declaration includes the @@ -5774,7 +5848,7 @@ static void add_function_pointer(ir_type *segment, ir_entity *method, set_entity_ld_ident(ptr, new_id_from_chars("", 0)); set_entity_compiler_generated(ptr, 1); - set_entity_visibility(ptr, ir_visibility_local); + set_entity_visibility(ptr, ir_visibility_private); add_entity_linkage(ptr, IR_LINKAGE_CONSTANT|IR_LINKAGE_HIDDEN_USER); set_atomic_ent_value(ptr, val); }