return irtype;
}
+static ir_tarval *fold_constant_to_tarval(expression_t const *);
+
static void determine_enum_values(enum_type_t *const type)
{
ir_mode *const mode = atomic_modes[type->base.akind];
ir_tarval *const one = get_mode_one(mode);
ir_tarval * tv_next = get_mode_null(mode);
- bool constant_folding_old = constant_folding;
- constant_folding = true;
-
enum_t *enume = type->enume;
entity_t *entry = enume->base.next;
for (; entry != NULL; entry = entry->base.next) {
expression_t *const init = entry->enum_value.value;
if (init != NULL) {
- ir_node *const cnst = expression_to_firm(init);
- if (!is_Const(cnst)) {
- panic("couldn't fold constant");
- }
- tv_next = get_Const_tarval(cnst);
+ tv_next = fold_constant_to_tarval(init);
}
assert(entry->enum_value.tv == NULL || entry->enum_value.tv == tv_next);
entry->enum_value.tv = tv_next;
tv_next = tarval_add(tv_next, one);
}
-
- constant_folding = constant_folding_old;
}
static ir_type *create_enum_type(enum_type_t *const type)
ir_type *firm_type = NULL;
switch (type->kind) {
- case TYPE_ERROR:
- /* Happens while constant folding, when there was an error */
- return create_atomic_type(ATOMIC_TYPE_VOID, NULL);
-
case TYPE_ATOMIC:
firm_type = create_atomic_type(type->atomic.akind, type);
break;
firm_type = create_enum_type(&type->enumt);
break;
+ case TYPE_ERROR:
case TYPE_TYPEOF:
case TYPE_TYPEDEF:
break;
return new_d_SymConst(dbgi, mode_P, sym, symconst_addr_ent);
}
+static ir_node *create_Const_from_bool(ir_mode *const mode, bool const v)
+{
+ return new_Const((v ? get_mode_one : get_mode_null)(mode));
+}
+
static ir_node *create_conv_from_b(dbg_info *dbgi, ir_node *value,
ir_mode *dest_mode)
{
if (is_Const(value)) {
- if (is_Const_null(value)) {
- return new_Const(get_mode_null(dest_mode));
- } else {
- return new_Const(get_mode_one(dest_mode));
- }
+ return create_Const_from_bool(dest_mode, !is_Const_null(value));
}
ir_node *cond = new_d_Cond(dbgi, value);
return new_d_Conv(dbgi, value, dest_mode);
}
-static ir_node *create_Const_from_bool(ir_mode *const mode, bool const v)
-{
- return new_Const((v ? get_mode_one : get_mode_null)(mode));
-}
-
/**
* Creates a SymConst node representing a wide string literal.
*
dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
type_t *type = skip_typeref(expression->base.type);
- if (expression->base.kind == EXPR_UNARY_TAKE_ADDRESS)
- return expression_to_addr(expression->value);
-
const expression_t *value = expression->value;
switch(expression->base.kind) {
+ case EXPR_UNARY_TAKE_ADDRESS:
+ return expression_to_addr(value);
+
case EXPR_UNARY_NEGATE: {
ir_node *value_node = expression_to_firm(value);
ir_mode *mode = get_ir_mode_arithmetic(type);
static ir_tarval *fold_constant_to_tarval(const expression_t *expression)
{
- assert(is_type_valid(skip_typeref(expression->base.type)));
+ assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
bool constant_folding_old = constant_folding;
constant_folding = true;
init_ir_types();
- assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
-
ir_graph *old_current_ir_graph = current_ir_graph;
current_ir_graph = get_const_code_irg();
/* this function is only used in parser.c, but it relies on libfirm functionality */
bool constant_is_negative(const expression_t *expression)
{
- assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
ir_tarval *tv = fold_constant_to_tarval(expression);
return tarval_is_negative(tv);
}
long fold_constant_to_int(const expression_t *expression)
{
- if (expression->kind == EXPR_ERROR)
- return 0;
-
ir_tarval *tv = fold_constant_to_tarval(expression);
if (!tarval_is_long(tv)) {
panic("result of constant folding is not integer");
bool fold_constant_to_bool(const expression_t *expression)
{
- if (expression->kind == EXPR_ERROR)
- return false;
ir_tarval *tv = fold_constant_to_tarval(expression);
return !tarval_is_null(tv);
}
return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
}
-static ir_node *error_to_firm(const expression_t *expression)
-{
- ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
- return new_Bad(mode);
-}
-
/**
* creates firm nodes for an expression. The difference between this function
* and expression_to_firm is, that this version might produce mode_b nodes
return label_address_to_firm(&expression->label_address);
case EXPR_ERROR:
- return error_to_firm(expression);
+ break;
}
panic("invalid expression found");
}
set_unreachable_now();
}
-static void goto_to_firm(const goto_statement_t *statement)
-{
- if (!currently_reachable())
- return;
-
- ir_node *block = get_label_block(statement->label);
- ir_node *jmp = new_Jmp();
- add_immBlock_pred(block, jmp);
-
- set_unreachable_now();
-}
-
static void asm_statement_to_firm(const asm_statement_t *statement)
{
bool needs_memory = false;
/**
* Transform a statement.
*/
-static void statement_to_firm(statement_t *statement)
+static void statement_to_firm(statement_t *const stmt)
{
#ifndef NDEBUG
- assert(!statement->base.transformed);
- statement->base.transformed = true;
+ assert(!stmt->base.transformed);
+ stmt->base.transformed = true;
#endif
- switch (statement->kind) {
- case STATEMENT_ERROR:
- panic("error statement found");
- case STATEMENT_EMPTY:
- /* nothing */
- return;
- case STATEMENT_COMPOUND:
- compound_statement_to_firm(&statement->compound);
- return;
- case STATEMENT_RETURN:
- return_statement_to_firm(&statement->returns);
- return;
- case STATEMENT_EXPRESSION:
- expression_statement_to_firm(&statement->expression);
- return;
- case STATEMENT_IF:
- if_statement_to_firm(&statement->ifs);
- return;
- case STATEMENT_WHILE:
- while_statement_to_firm(&statement->whiles);
- return;
- case STATEMENT_DO_WHILE:
- do_while_statement_to_firm(&statement->do_while);
- return;
- case STATEMENT_DECLARATION:
- declaration_statement_to_firm(&statement->declaration);
- return;
- case STATEMENT_BREAK:
- create_jump_statement(statement, get_break_label());
- return;
- case STATEMENT_CONTINUE:
- create_jump_statement(statement, continue_label);
- return;
- case STATEMENT_SWITCH:
- switch_statement_to_firm(&statement->switchs);
- return;
- case STATEMENT_CASE_LABEL:
- case_label_to_firm(&statement->case_label);
- return;
- case STATEMENT_FOR:
- for_statement_to_firm(&statement->fors);
- return;
- case STATEMENT_LABEL:
- label_to_firm(&statement->label);
- return;
- case STATEMENT_COMPUTED_GOTO:
- computed_goto_to_firm(&statement->computed_goto);
- return;
- case STATEMENT_GOTO:
- goto_to_firm(&statement->gotos);
- return;
- case STATEMENT_ASM:
- asm_statement_to_firm(&statement->asms);
- return;
- case STATEMENT_MS_TRY:
- ms_try_statement_to_firm(&statement->ms_try);
- return;
- case STATEMENT_LEAVE:
- leave_statement_to_firm(&statement->leave);
- return;
+ switch (stmt->kind) {
+ case STATEMENT_ASM: asm_statement_to_firm( &stmt->asms); return;
+ case STATEMENT_CASE_LABEL: case_label_to_firm( &stmt->case_label); return;
+ case STATEMENT_COMPOUND: compound_statement_to_firm( &stmt->compound); return;
+ case STATEMENT_COMPUTED_GOTO: computed_goto_to_firm( &stmt->computed_goto); return;
+ case STATEMENT_DECLARATION: declaration_statement_to_firm(&stmt->declaration); return;
+ case STATEMENT_DO_WHILE: do_while_statement_to_firm( &stmt->do_while); return;
+ case STATEMENT_EMPTY: /* nothing */ return;
+ case STATEMENT_EXPRESSION: expression_statement_to_firm( &stmt->expression); return;
+ case STATEMENT_FOR: for_statement_to_firm( &stmt->fors); return;
+ case STATEMENT_IF: if_statement_to_firm( &stmt->ifs); return;
+ case STATEMENT_LABEL: label_to_firm( &stmt->label); return;
+ case STATEMENT_LEAVE: leave_statement_to_firm( &stmt->leave); return;
+ case STATEMENT_MS_TRY: ms_try_statement_to_firm( &stmt->ms_try); return;
+ case STATEMENT_RETURN: return_statement_to_firm( &stmt->returns); return;
+ case STATEMENT_SWITCH: switch_statement_to_firm( &stmt->switchs); return;
+ case STATEMENT_WHILE: while_statement_to_firm( &stmt->whiles); return;
+
+ case STATEMENT_BREAK: create_jump_statement(stmt, get_break_label()); return;
+ case STATEMENT_CONTINUE: create_jump_statement(stmt, continue_label); return;
+ case STATEMENT_GOTO: create_jump_statement(stmt, get_label_block(stmt->gotos.label)); return;
+
+ case STATEMENT_ERROR: panic("error statement found");
}
panic("statement not implemented");
}