if(get_cur_block() == NULL)
return;
- ir_type *func_irtype = get_ir_type(current_function_decl->type);
+ dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+ ir_type *func_irtype = get_ir_type(current_function_decl->type);
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
ir_node *in[1];
int in_len;
if(get_method_n_ress(func_irtype) > 0) {
ir_type *res_type = get_method_res_type(func_irtype, 0);
- if(statement->return_value != NULL) {
- ir_node *node = expression_to_firm(statement->return_value);
+ if(statement->value != NULL) {
+ ir_node *node = expression_to_firm(statement->value);
node = do_strict_conv(dbgi, node);
in[0] = node;
} else {
in_len = 1;
} else {
/* build return_value for its side effects */
- if(statement->return_value != NULL) {
- expression_to_firm(statement->return_value);
+ if(statement->value != NULL) {
+ expression_to_firm(statement->value);
}
in_len = 0;
}
static void switch_statement_to_firm(const switch_statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
ir_node *expression = expression_to_firm(statement->expression);
ir_node *cond = new_d_Cond(dbgi, expression);
static void case_label_to_firm(const case_label_statement_t *statement)
{
- dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+ dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
add_immBlock_pred(block, proj);
mature_immBlock(block);
- if(statement->label_statement != NULL) {
- statement_to_firm(statement->label_statement);
+ if(statement->statement != NULL) {
+ statement_to_firm(statement->statement);
}
}
set_cur_block(block);
keep_alive(block);
- if(statement->label_statement != NULL) {
- statement_to_firm(statement->label_statement);
+ if(statement->statement != NULL) {
+ statement_to_firm(statement->statement);
}
}
case STATEMENT_LABEL: {
const label_statement_t *const label_stmt = &stmt->label;
- count += count_decls_in_stmts(label_stmt->label_statement);
+ if(label_stmt->statement != NULL) {
+ count += count_decls_in_stmts(label_stmt->statement);
+ }
break;
}
case STATEMENT_CASE_LABEL: {
const case_label_statement_t *label = &stmt->case_label;
count += count_decls_in_expression(label->expression);
- count += count_decls_in_stmts(label->label_statement);
+ if(label->statement != NULL) {
+ count += count_decls_in_stmts(label->statement);
+ }
break;
}
case STATEMENT_RETURN: {
const return_statement_t *ret_stmt = &stmt->returns;
- count += count_decls_in_expression(ret_stmt->return_value);
+ count += count_decls_in_expression(ret_stmt->value);
break;
}
}
label->used = true;
if (label->source_position.input_name == NULL) {
print_in_function();
- errorf(goto_statement->statement.source_position,
- "label '%Y' used but not defined", label->symbol);
+ errorf(goto_statement->base.source_position,
+ "label '%Y' used but not defined", label->symbol);
}
}
goto_first = goto_last = NULL;
if (! label->used) {
print_in_function();
- warningf(label_statement->statement.source_position,
+ warningf(label_statement->base.source_position,
"label '%Y' defined but not used", label->symbol);
}
}
static expression_t *parse_string_const(void)
{
expression_t *cnst = allocate_expression_zero(EXPR_STRING_LITERAL);
- cnst->base.type = type_string;
+ cnst->base.type = type_char_ptr;
cnst->string.value = parse_string_literals();
return cnst;
case T___builtin_alloca:
return make_function_1_type(type_void_ptr, type_size_t);
case T___builtin_nan:
- return make_function_1_type(type_double, type_string);
+ return make_function_1_type(type_double, type_char_ptr);
case T___builtin_nanf:
- return make_function_1_type(type_float, type_string);
+ return make_function_1_type(type_float, type_char_ptr);
case T___builtin_nand:
- return make_function_1_type(type_long_double, type_string);
+ return make_function_1_type(type_long_double, type_char_ptr);
case T___builtin_va_end:
return make_function_1_type(type_void, type_valist);
default:
}
expression_t *expression = allocate_expression_zero(EXPR_FUNCTION);
- expression->base.type = type_string;
+ expression->base.type = type_char_ptr;
return expression;
}
}
expression_t *expression = allocate_expression_zero(EXPR_PRETTY_FUNCTION);
- expression->base.type = type_string;
+ expression->base.type = type_char_ptr;
return expression;
}
"case label not within a switch statement");
}
}
- statement->case_label.label_statement = parse_statement();
+ statement->case_label.statement = parse_statement();
return statement;
}
const case_label_statement_t *def_label = find_default_label(current_switch);
if (def_label != NULL) {
errorf(HERE, "multiple default labels in one switch");
- errorf(def_label->statement.source_position,
+ errorf(def_label->base.source_position,
"this is the first default label");
} else {
/* link all cases into the switch statement */
errorf(statement->base.source_position,
"'default' label not within a switch statement");
}
- statement->label.label_statement = parse_statement();
+ statement->label.statement = parse_statement();
return statement;
}
label->source_position = token.source_position;
}
- label_statement_t *label_statement = allocate_ast_zero(sizeof(label[0]));
+ statement_t *statement = allocate_statement_zero(STATEMENT_LABEL);
- label_statement->statement.kind = STATEMENT_LABEL;
- label_statement->statement.source_position = token.source_position;
- label_statement->label = label;
+ statement->base.source_position = token.source_position;
+ statement->label.label = label;
eat(':');
if(token.type == '}') {
/* TODO only warn? */
errorf(HERE, "label at end of compound statement");
- return (statement_t*) label_statement;
+ return statement;
} else {
if (token.type == ';') {
/* eat an empty statement here, to avoid the warning about an empty
* a }. */
next_token();
} else {
- label_statement->label_statement = parse_statement();
+ statement->label.statement = parse_statement();
}
}
/* remember the labels's in a list for later checking */
if (label_last == NULL) {
- label_first = label_statement;
+ label_first = &statement->label;
} else {
- label_last->next = label_statement;
+ label_last->next = &statement->label;
}
- label_last = label_statement;
+ label_last = &statement->label;
- return (statement_t*) label_statement;
+ return statement;
}
/**
{
eat(T_if);
- if_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.kind = STATEMENT_IF;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_IF);
+ statement->base.source_position = token.source_position;
expect('(');
- statement->condition = parse_expression();
+ statement->ifs.condition = parse_expression();
expect(')');
- statement->true_statement = parse_statement();
+ statement->ifs.true_statement = parse_statement();
if(token.type == T_else) {
next_token();
- statement->false_statement = parse_statement();
+ statement->ifs.false_statement = parse_statement();
}
- return (statement_t*) statement;
+ return statement;
}
/**
{
eat(T_switch);
- switch_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.kind = STATEMENT_SWITCH;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_SWITCH);
+ statement->base.source_position = token.source_position;
expect('(');
expression_t *const expr = parse_expression();
if (is_type_integer(type)) {
type = promote_integer(type);
} else if (is_type_valid(type)) {
- errorf(expr->base.source_position, "switch quantity is not an integer, but '%T'", type);
+ errorf(expr->base.source_position,
+ "switch quantity is not an integer, but '%T'", type);
type = type_error_type;
}
- statement->expression = create_implicit_cast(expr, type);
+ statement->switchs.expression = create_implicit_cast(expr, type);
expect(')');
switch_statement_t *rem = current_switch;
- current_switch = statement;
- statement->body = parse_statement();
- current_switch = rem;
+ current_switch = &statement->switchs;
+ statement->switchs.body = parse_statement();
+ current_switch = rem;
- if (warning.switch_default && find_default_label(statement) == NULL) {
- warningf(statement->statement.source_position, "switch has no default case");
+ if (warning.switch_default
+ && find_default_label(&statement->switchs) == NULL) {
+ warningf(statement->base.source_position, "switch has no default case");
}
- return (statement_t*) statement;
+ return statement;
}
static statement_t *parse_loop_body(statement_t *const loop)
{
statement_t *const rem = current_loop;
current_loop = loop;
+
statement_t *const body = parse_statement();
+
current_loop = rem;
return body;
}
{
eat(T_while);
- while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.kind = STATEMENT_WHILE;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_WHILE);
+ statement->base.source_position = token.source_position;
expect('(');
- statement->condition = parse_expression();
+ statement->whiles.condition = parse_expression();
expect(')');
- statement->body = parse_loop_body((statement_t*)statement);
+ statement->whiles.body = parse_loop_body(statement);
- return (statement_t*) statement;
+ return statement;
}
/**
{
eat(T_do);
- do_while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.kind = STATEMENT_DO_WHILE;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_DO_WHILE);
+
+ statement->base.source_position = token.source_position;
+
+ statement->do_while.body = parse_loop_body(statement);
- statement->body = parse_loop_body((statement_t*)statement);
expect(T_while);
expect('(');
- statement->condition = parse_expression();
+ statement->do_while.condition = parse_expression();
expect(')');
expect(';');
- return (statement_t*) statement;
+ return statement;
}
/**
{
eat(T_for);
- for_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
- statement->statement.kind = STATEMENT_FOR;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_FOR);
+ statement->base.source_position = token.source_position;
expect('(');
int top = environment_top();
scope_t *last_scope = scope;
- set_scope(&statement->scope);
+ set_scope(&statement->fors.scope);
if(token.type != ';') {
if(is_declaration_specifier(&token, false)) {
parse_declaration(record_declaration);
} else {
- statement->initialisation = parse_expression();
+ statement->fors.initialisation = parse_expression();
expect(';');
}
} else {
}
if(token.type != ';') {
- statement->condition = parse_expression();
+ statement->fors.condition = parse_expression();
}
expect(';');
if(token.type != ')') {
- statement->step = parse_expression();
+ statement->fors.step = parse_expression();
}
expect(')');
- statement->body = parse_loop_body((statement_t*)statement);
+ statement->fors.body = parse_loop_body(statement);
- assert(scope == &statement->scope);
+ assert(scope == &statement->fors.scope);
set_scope(last_scope);
environment_pop_to(top);
- return (statement_t*) statement;
+ return statement;
}
/**
declaration_t *label = get_label(symbol);
- goto_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-
- statement->statement.kind = STATEMENT_GOTO;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_GOTO);
+ statement->base.source_position = token.source_position;
- statement->label = label;
+ statement->gotos.label = label;
/* remember the goto's in a list for later checking */
if (goto_last == NULL) {
- goto_first = statement;
+ goto_first = &statement->gotos;
} else {
- goto_last->next = statement;
+ goto_last->next = &statement->gotos;
}
- goto_last = statement;
+ goto_last = &statement->gotos;
expect(';');
- return (statement_t*) statement;
+ return statement;
}
/**
{
eat(T_return);
- return_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-
- statement->statement.kind = STATEMENT_RETURN;
- statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_RETURN);
+ statement->base.source_position = token.source_position;
expression_t *return_value = NULL;
if(token.type != ';') {
if(is_type_atomic(return_type, ATOMIC_TYPE_VOID)
&& !is_type_atomic(return_value_type, ATOMIC_TYPE_VOID)) {
- warningf(statement->statement.source_position,
- "'return' with a value, in function returning void");
+ warningf(statement->base.source_position,
+ "'return' with a value, in function returning void");
return_value = NULL;
} else {
type_t *const res_type = semantic_assign(return_type,
return_value, "'return'");
if (res_type == NULL) {
- errorf(statement->statement.source_position,
- "cannot return something of type '%T' in function returning '%T'",
- return_value->base.type, return_type);
+ errorf(statement->base.source_position,
+ "cannot return something of type '%T' in function returning '%T'",
+ return_value->base.type, return_type);
} else {
return_value = create_implicit_cast(return_value, res_type);
}
if (return_value->base.kind == EXPR_UNARY_TAKE_ADDRESS) {
const expression_t *expression = return_value->unary.value;
if (is_local_variable(expression)) {
- warningf(statement->statement.source_position,
- "function returns address of local variable");
+ warningf(statement->base.source_position,
+ "function returns address of local variable");
}
}
} else {
if(!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
- warningf(statement->statement.source_position,
- "'return' without value, in function returning non-void");
+ warningf(statement->base.source_position,
+ "'return' without value, in function returning non-void");
}
}
- statement->return_value = return_value;
+ statement->returns.value = return_value;
- return (statement_t*) statement;
+ return statement;
}
/**
*/
static statement_t *parse_compound_statement(void)
{
- compound_statement_t *const compound_statement
- = allocate_ast_zero(sizeof(compound_statement[0]));
- compound_statement->statement.kind = STATEMENT_COMPOUND;
- compound_statement->statement.source_position = token.source_position;
+ statement_t *statement = allocate_statement_zero(STATEMENT_COMPOUND);
+
+ statement->base.source_position = token.source_position;
eat('{');
int top = environment_top();
scope_t *last_scope = scope;
- set_scope(&compound_statement->scope);
+ set_scope(&statement->compound.scope);
statement_t *last_statement = NULL;
while(token.type != '}' && token.type != T_EOF) {
- statement_t *statement = parse_statement();
- if(statement == NULL)
+ statement_t *sub_statement = parse_statement();
+ if(sub_statement == NULL)
continue;
if(last_statement != NULL) {
- last_statement->base.next = statement;
+ last_statement->base.next = sub_statement;
} else {
- compound_statement->statements = statement;
+ statement->compound.statements = sub_statement;
}
- while(statement->base.next != NULL)
- statement = statement->base.next;
+ while(sub_statement->base.next != NULL)
+ sub_statement = sub_statement->base.next;
- last_statement = statement;
+ last_statement = sub_statement;
}
if(token.type == '}') {
next_token();
} else {
- errorf(compound_statement->statement.source_position, "end of file while looking for closing '}'");
+ errorf(statement->base.source_position,
+ "end of file while looking for closing '}'");
}
- assert(scope == &compound_statement->scope);
+ assert(scope == &statement->compound.scope);
set_scope(last_scope);
environment_pop_to(top);
- return (statement_t*) compound_statement;
+ return statement;
}
/**