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];
panic("Trying to determine size of invalid type");
}
+static ir_node *get_vla_size(array_type_t *const type)
+{
+ ir_node *size_node = type->size_node;
+ if (size_node == NULL) {
+ size_node = expression_to_firm(type->size_expression);
+ type->size_node = size_node;
+ }
+ return size_node;
+}
+
static ir_node *get_type_size(type_t *type)
{
type = skip_typeref(type);
if (is_type_array(type) && type->array.is_vla) {
- ir_node *size_node = type->array.size_node;
- if (size_node == NULL) {
- size_node = expression_to_firm(type->array.size_expression);
- type->array.size_node = size_node;
- }
-
+ ir_node *size_node = get_vla_size(&type->array);
ir_node *elem_size = get_type_size(type->array.element_type);
ir_mode *mode = get_irn_mode(size_node);
ir_node *real_size = new_d_Mul(NULL, size_node, elem_size, mode);
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");
+ panic("unsupported builtin found");
}
}
ir_node *cur_block = get_cur_block();
ir_node *one_block = new_immBlock();
+ set_cur_block(one_block);
ir_node *one = new_Const(get_mode_one(mode));
ir_node *jmp_one = new_d_Jmp(dbgi);
ir_node *zero_block = new_immBlock();
+ set_cur_block(zero_block);
ir_node *zero = new_Const(get_mode_null(mode));
ir_node *jmp_zero = new_d_Jmp(dbgi);
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,
current_ir_graph = old_current_ir_graph;
if (!is_Const(cnst)) {
- panic("couldn't fold constant\n");
+ panic("couldn't fold constant");
}
tarval *tv = get_Const_tarval(cnst);
if (!tarval_is_long(tv)) {
- panic("result of constant folding is not integer\n");
+ panic("result of constant folding is not integer");
}
constant_folding = constant_folding_old;
/* create the true block */
ir_node *true_block = new_immBlock();
+ set_cur_block(true_block);
ir_node *true_val = expression->true_expression != NULL ?
expression_to_firm(expression->true_expression) : NULL;
/* create the false block */
ir_node *false_block = new_immBlock();
+ set_cur_block(false_block);
ir_node *false_val = expression_to_firm(expression->false_expression);
ir_node *false_jmp = new_Jmp();
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;
}
ir_graph *rem = current_ir_graph;
current_ir_graph = current_function;
- ir_node *old_cur_block = get_cur_block();
- ir_node *block = new_immBlock();
- set_cur_block(old_cur_block);
+ ir_node *block = new_immBlock();
label->block = block;
case EXPR_BINARY_LOGICAL_AND: {
const binary_expression_t *binary_expression = &expression->binary;
- ir_node *cur_block = get_cur_block();
ir_node *extra_block = new_immBlock();
- set_cur_block(cur_block);
create_condition_evaluation(binary_expression->left, extra_block,
false_block);
mature_immBlock(extra_block);
case EXPR_BINARY_LOGICAL_OR: {
const binary_expression_t *binary_expression = &expression->binary;
- ir_node *cur_block = get_cur_block();
ir_node *extra_block = new_immBlock();
- set_cur_block(cur_block);
create_condition_evaluation(binary_expression->left, true_block,
extra_block);
mature_immBlock(extra_block);
}
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;
entity_t *const last = statement->declarations_end;
if (entity != NULL) {
for ( ;; entity = entity->base.next) {
- if (is_declaration(entity))
+ if (is_declaration(entity)) {
initialize_local_declaration(entity);
+ } else if (entity->kind == ENTITY_TYPEDEF) {
+ type_t *const type = entity->typedefe.type;
+ if (is_type_array(type) && type->array.is_vla)
+ get_vla_size(&type->array);
+ }
if (entity == last)
break;
}
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();
ir_node *false_block = NULL;
if (statement->false_statement != NULL) {
false_block = new_immBlock();
+ set_cur_block(false_block);
statement_to_firm(statement->false_statement);
if (get_cur_block() != NULL) {
break_label = NULL;
ir_node *body_block = new_immBlock();
+ set_cur_block(body_block);
statement_to_firm(statement->body);
ir_node *false_block = break_label;
continue_label = header_block;
break_label = NULL;
+ set_cur_block(body_block);
statement_to_firm(statement->body);
ir_node *false_block = break_label;
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);
}
/* 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);
}
/* 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);
}
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;
break_label = false_block;
body_block = new_immBlock();
+ set_cur_block(body_block);
statement_to_firm(statement->body);
assert(continue_label == step_block);
static ir_node *get_break_label(void)
{
if (break_label == NULL) {
- ir_node *cur_block = get_cur_block();
break_label = new_immBlock();
- set_cur_block(cur_block);
}
return break_label;
}
ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
ir_node *proj;
- ir_node *old_block = get_nodes_block(current_switch_cond);
ir_node *block = new_immBlock();
- set_cur_block(old_block);
+ set_cur_block(get_nodes_block(current_switch_cond));
if (statement->expression != NULL) {
long pn = statement->first_case;
long end_pn = statement->last_case;
case STATEMENT_LABEL:
label_to_firm(&statement->label);
return;
- case STATEMENT_LOCAL_LABEL:
- /* local labels transform the semantics of labels while parsing
- * they don't need any special treatment here */
- return;
case STATEMENT_GOTO:
goto_to_firm(&statement->gotos);
return;
leave_statement_to_firm(&statement->leave);
return;
}
- panic("Statement not implemented\n");
+ panic("statement not implemented");
}
static int count_local_variables(const entity_t *entity,
*/
static void handle_decl_modifier_irg(ir_graph_ptr irg, decl_modifiers_t decl_modifiers)
{
+ if (decl_modifiers & DM_RETURNS_TWICE) {
+ /* TRUE if the declaration includes __attribute__((returns_twice)) */
+ set_irg_additional_property(irg, mtp_property_returns_twice);
+ }
if (decl_modifiers & DM_NORETURN) {
/* TRUE if the declaration includes the Microsoft
__declspec(noreturn) specifier. */