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);
/* we're past the last member of the current sub-aggregate, try if we
* can ascend in the type hierarchy and continue with another subobject */
- size_t len = ARR_LEN(path->path);
+ size_t len = ARR_LEN(path->path);
if (len > 1) {
ascend_from_subtype(path);
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)
{
- /* 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. */
+ /* 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)) {
}
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);
static void if_statement_to_firm(if_statement_t *statement)
{
- ir_node *cur_block = get_cur_block();
-
- ir_node *fallthrough_block = NULL;
-
- /* the true (blocks) */
- ir_node *true_block = NULL;
- if (statement->true_statement != NULL) {
- true_block = new_immBlock();
- set_cur_block(true_block);
- statement_to_firm(statement->true_statement);
- if (get_cur_block() != NULL) {
- ir_node *jmp = new_Jmp();
- if (fallthrough_block == NULL)
- fallthrough_block = new_immBlock();
- add_immBlock_pred(fallthrough_block, jmp);
- }
+ /* Create the condition. */
+ ir_node *true_block = NULL;
+ ir_node *false_block = NULL;
+ if (get_cur_block() != NULL) {
+ true_block = new_immBlock();
+ false_block = new_immBlock();
+ create_condition_evaluation(statement->condition, true_block, false_block);
+ mature_immBlock(true_block);
}
- /* the false (blocks) */
- ir_node *false_block = NULL;
+ /* Create the false statement.
+ * Hadle false before true, so if no false statement is present, then the
+ * empty false block is reused as fallthrough block. */
+ ir_node *fallthrough_block = NULL;
if (statement->false_statement != NULL) {
- false_block = new_immBlock();
+ if (false_block != NULL) {
+ mature_immBlock(false_block);
+ }
set_cur_block(false_block);
-
statement_to_firm(statement->false_statement);
if (get_cur_block() != NULL) {
- ir_node *jmp = new_Jmp();
- if (fallthrough_block == NULL)
- fallthrough_block = new_immBlock();
- add_immBlock_pred(fallthrough_block, jmp);
+ fallthrough_block = new_immBlock();
+ add_immBlock_pred(fallthrough_block, new_Jmp());
}
+ } else {
+ fallthrough_block = false_block;
}
- /* create the condition */
- if (cur_block != NULL) {
- if (true_block == NULL || false_block == NULL) {
- if (fallthrough_block == NULL)
- fallthrough_block = new_immBlock();
- if (true_block == NULL)
- true_block = fallthrough_block;
- if (false_block == NULL)
- false_block = fallthrough_block;
+ /* Create the true statement. */
+ set_cur_block(true_block);
+ statement_to_firm(statement->true_statement);
+ if (get_cur_block() != NULL) {
+ if (fallthrough_block == NULL) {
+ fallthrough_block = new_immBlock();
}
-
- set_cur_block(cur_block);
- create_condition_evaluation(statement->condition, true_block,
- false_block);
+ add_immBlock_pred(fallthrough_block, new_Jmp());
}
- mature_immBlock(true_block);
- if (false_block != fallthrough_block && false_block != NULL) {
- mature_immBlock(false_block);
- }
+ /* Handle the block after the if-statement. */
if (fallthrough_block != NULL) {
mature_immBlock(fallthrough_block);
}
-
set_cur_block(fallthrough_block);
}
static void while_statement_to_firm(while_statement_t *statement)
{
- ir_node *jmp = NULL;
+ /* Create the header block */
+ ir_node *const header_block = new_immBlock();
if (get_cur_block() != NULL) {
- jmp = new_Jmp();
+ add_immBlock_pred(header_block, new_Jmp());
}
- /* create the header block */
- ir_node *header_block = new_immBlock();
- if (jmp != NULL) {
- add_immBlock_pred(header_block, jmp);
+ /* Create the condition. */
+ ir_node * body_block;
+ ir_node * false_block;
+ expression_t *const cond = statement->condition;
+ if (is_constant_expression(cond) && fold_constant_to_bool(cond)) {
+ /* Shortcut for while (true). */
+ body_block = header_block;
+ false_block = NULL;
+
+ keep_alive(header_block);
+ keep_all_memory(header_block);
+ } else {
+ body_block = new_immBlock();
+ false_block = new_immBlock();
+
+ set_cur_block(header_block);
+ create_condition_evaluation(cond, body_block, false_block);
+ mature_immBlock(body_block);
}
- /* the loop body */
- ir_node *old_continue_label = continue_label;
- ir_node *old_break_label = break_label;
- continue_label = header_block;
- break_label = NULL;
+ ir_node *const old_continue_label = continue_label;
+ ir_node *const old_break_label = break_label;
+ continue_label = header_block;
+ break_label = false_block;
- ir_node *body_block = new_immBlock();
+ /* Create the loop body. */
set_cur_block(body_block);
statement_to_firm(statement->body);
- ir_node *false_block = break_label;
-
- assert(continue_label == header_block);
- continue_label = old_continue_label;
- break_label = old_break_label;
-
if (get_cur_block() != NULL) {
- jmp = new_Jmp();
- add_immBlock_pred(header_block, jmp);
- }
-
- /* shortcut for while(true) */
- if (is_constant_expression(statement->condition)
- && fold_constant_to_bool(statement->condition) != 0) {
- set_cur_block(header_block);
- ir_node *header_jmp = new_Jmp();
- add_immBlock_pred(body_block, header_jmp);
-
- keep_alive(body_block);
- keep_all_memory(body_block);
- set_cur_block(body_block);
- } else {
- if (false_block == NULL) {
- false_block = new_immBlock();
- }
-
- /* create the condition */
- set_cur_block(header_block);
-
- create_condition_evaluation(statement->condition, body_block,
- false_block);
+ add_immBlock_pred(header_block, new_Jmp());
}
- mature_immBlock(body_block);
mature_immBlock(header_block);
+ assert(false_block == NULL || false_block == break_label);
+ false_block = break_label;
if (false_block != NULL) {
mature_immBlock(false_block);
}
-
set_cur_block(false_block);
+
+ assert(continue_label == header_block);
+ continue_label = old_continue_label;
+ break_label = old_break_label;
}
static void do_while_statement_to_firm(do_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();
/* the loop body */
ir_node *body_block = new_immBlock();
- if (jmp != NULL) {
- add_immBlock_pred(body_block, jmp);
+ if (get_cur_block() != NULL) {
+ add_immBlock_pred(body_block, new_Jmp());
}
ir_node *old_continue_label = continue_label;
if (get_cur_block() != NULL) {
ir_node *body_jmp = new_Jmp();
add_immBlock_pred(header_block, body_jmp);
- mature_immBlock(header_block);
}
if (false_block == NULL) {
}
/* create the condition */
+ mature_immBlock(header_block);
set_cur_block(header_block);
create_condition_evaluation(statement->condition, body_block, false_block);
mature_immBlock(body_block);
- mature_immBlock(header_block);
mature_immBlock(false_block);
set_cur_block(false_block);
static void for_statement_to_firm(for_statement_t *statement)
{
- ir_node *jmp = NULL;
-
/* create declarations */
entity_t *entity = statement->scope.entities;
for ( ; entity != NULL; entity = entity->base.next) {
if (statement->initialisation != NULL) {
expression_to_firm(statement->initialisation);
}
+ }
- jmp = new_Jmp();
+ /* Create the header block */
+ ir_node *const header_block = new_immBlock();
+ if (get_cur_block() != NULL) {
+ add_immBlock_pred(header_block, new_Jmp());
}
+ /* Create the condition. */
+ ir_node *body_block;
+ ir_node *false_block;
+ if (statement->condition != NULL) {
+ body_block = new_immBlock();
+ false_block = new_immBlock();
+
+ set_cur_block(header_block);
+ create_condition_evaluation(statement->condition, body_block, false_block);
+ mature_immBlock(body_block);
+ } else {
+ /* for-ever. */
+ body_block = header_block;
+ false_block = NULL;
- /* create the step block */
- ir_node *const step_block = new_immBlock();
- set_cur_block(step_block);
- if (statement->step != NULL) {
- expression_to_firm(statement->step);
+ keep_alive(header_block);
+ keep_all_memory(header_block);
}
- ir_node *const step_jmp = new_Jmp();
- /* create the header block */
- ir_node *const header_block = new_immBlock();
- set_cur_block(header_block);
- if (jmp != NULL) {
- add_immBlock_pred(header_block, jmp);
+ /* Create the step block, if necessary. */
+ ir_node * step_block = header_block;
+ expression_t *const step = statement->step;
+ if (step != NULL) {
+ step_block = new_immBlock();
}
- add_immBlock_pred(header_block, step_jmp);
-
- /* the false block */
- ir_node *const false_block = new_immBlock();
-
- /* the loop body */
- 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();
- set_cur_block(body_block);
- statement_to_firm(statement->body);
+ ir_node *const old_continue_label = continue_label;
+ ir_node *const old_break_label = break_label;
+ continue_label = step_block;
+ break_label = false_block;
- assert(continue_label == step_block);
- assert(break_label == false_block);
- continue_label = old_continue_label;
- break_label = old_break_label;
+ /* Create the loop body. */
+ set_cur_block(body_block);
+ statement_to_firm(statement->body);
+ if (get_cur_block() != NULL) {
+ add_immBlock_pred(step_block, new_Jmp());
+ }
+ /* Create the step code. */
+ if (step != NULL) {
+ mature_immBlock(step_block);
+ set_cur_block(step_block);
+ expression_to_firm(step);
if (get_cur_block() != NULL) {
- jmp = new_Jmp();
- add_immBlock_pred(step_block, jmp);
+ add_immBlock_pred(header_block, new_Jmp());
}
- } else {
- body_block = step_block;
}
- /* create the condition */
- set_cur_block(header_block);
- if (statement->condition != NULL) {
- create_condition_evaluation(statement->condition, body_block,
- false_block);
- } else {
- keep_alive(header_block);
- keep_all_memory(header_block);
- jmp = new_Jmp();
- add_immBlock_pred(body_block, jmp);
- }
-
- mature_immBlock(body_block);
- mature_immBlock(false_block);
- mature_immBlock(step_block);
mature_immBlock(header_block);
- mature_immBlock(false_block);
-
+ assert(false_block == NULL || false_block == break_label);
+ false_block = break_label;
+ if (false_block != NULL) {
+ mature_immBlock(false_block);
+ }
set_cur_block(false_block);
+
+ assert(continue_label == step_block);
+ continue_label = old_continue_label;
+ break_label = old_break_label;
}
static void create_jump_statement(const statement_t *statement,
set_Cond_default_proj(cond, default_proj_nr);
}
- if (statement->body != NULL) {
- statement_to_firm(statement->body);
- }
+ statement_to_firm(statement->body);
if (get_cur_block() != NULL) {
ir_node *jmp = new_Jmp();
if (statement->is_empty_range)
return;
- dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
-
- ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
-
- ir_node *proj;
ir_node *block = new_immBlock();
+ if (get_cur_block() != NULL) {
+ /* Fallthrough from previous case */
+ add_immBlock_pred(block, new_Jmp());
+ }
+
if (current_switch_cond != NULL) {
set_cur_block(get_nodes_block(current_switch_cond));
+ dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
if (statement->expression != NULL) {
long pn = statement->first_case;
long end_pn = statement->last_case;
assert(pn <= end_pn);
/* create jumps for all cases in the given range */
do {
- proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
+ ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
add_immBlock_pred(block, proj);
} while (pn++ < end_pn);
} else {
saw_default_label = true;
- proj = new_d_Proj(dbgi, current_switch_cond, mode_X,
- current_switch->default_proj_nr);
-
+ ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X,
+ current_switch->default_proj_nr);
add_immBlock_pred(block, proj);
}
}
- if (fallthrough != NULL) {
- add_immBlock_pred(block, fallthrough);
- }
mature_immBlock(block);
set_cur_block(block);
- if (statement->statement != NULL) {
- statement_to_firm(statement->statement);
- }
+ statement_to_firm(statement->statement);
}
static void label_to_firm(const label_statement_t *statement)
keep_alive(block);
keep_all_memory(block);
- if (statement->statement != NULL) {
- statement_to_firm(statement->statement);
- }
+ statement_to_firm(statement->statement);
}
static void goto_to_firm(const goto_statement_t *statement)
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);
}