#include "walk.h"
#include "warning.h"
#include "printer.h"
+#include "ast2firm.h"
#include "adt/bitfiddle.h"
#include "adt/error.h"
#include "adt/array.h"
[EXPR_LITERAL_INTEGER] = sizeof(literal_expression_t),
[EXPR_LITERAL_FLOATINGPOINT] = sizeof(literal_expression_t),
[EXPR_LITERAL_CHARACTER] = sizeof(string_literal_expression_t),
+ [EXPR_LITERAL_MS_NOOP] = sizeof(literal_expression_t),
[EXPR_STRING_LITERAL] = sizeof(string_literal_expression_t),
[EXPR_COMPOUND_LITERAL] = sizeof(compound_literal_expression_t),
[EXPR_CALL] = sizeof(call_expression_t),
warn_unused_entity(WARN_UNUSED_PARAMETER, scope->entities, NULL);
}
if (is_warn_on(WARN_UNUSED_VARIABLE)) {
- walk_statements(current_function->statement, check_unused_variables,
- NULL);
+ walk_statements(current_function->body, check_unused_variables, NULL);
}
}
return;
if (is_constant_expression(expr) == EXPR_CLASS_CONSTANT) {
- long const val = fold_constant_to_int(expr);
+ ir_tarval *const val = fold_constant_to_tarval(expr);
case_label_statement_t * defaults = NULL;
for (case_label_statement_t *i = switchs->first_case; i != NULL; i = i->next) {
if (i->expression == NULL) {
continue;
}
- if (i->first_case <= val && val <= i->last_case) {
+ if (i->first_case == val || i->last_case == val ||
+ ((tarval_cmp(i->first_case, val) & ir_relation_less_equal)
+ && (tarval_cmp(val, i->last_case) & ir_relation_less_equal))) {
check_reachable((statement_t*)i);
return;
}
environment_push(parameter);
}
- if (function->statement != NULL) {
+ if (function->body != NULL) {
parser_error_multiple_definition(entity, HERE);
eat_block();
} else {
label_anchor = &label_first;
statement_t *const body = parse_compound_statement(false);
- function->statement = body;
+ function->body = body;
first_err = true;
check_labels();
check_declarations();
"third argument of '%Y' must be a constant expression",
call->function->reference.entity->base.symbol);
}
- locality = rw->next;
}
break;
default:
}
statement->case_label.is_bad = true;
} else {
- long const val = fold_constant_to_int(expression);
+ ir_tarval *val = fold_constant_to_tarval(expression);
statement->case_label.first_case = val;
statement->case_label.last_case = val;
}
}
statement->case_label.is_bad = true;
} else {
- long const val = fold_constant_to_int(end_range);
+ ir_tarval *val = fold_constant_to_tarval(end_range);
statement->case_label.last_case = val;
- if (val < statement->case_label.first_case) {
+ if (tarval_cmp(val, statement->case_label.first_case)
+ == ir_relation_less) {
statement->case_label.is_empty_range = true;
warningf(WARN_OTHER, pos, "empty range specified");
}
} else {
label->base.source_position = *pos;
label->statement = statement;
+ label->n_users += 1;
}
eat(':');
{
if (!is_warn_on(WARN_SWITCH_ENUM))
return;
- const type_t *type = skip_typeref(statement->expression->base.type);
+ type_t *type = skip_typeref(statement->expression->base.type);
if (! is_type_enum(type))
return;
- const enum_type_t *enumt = &type->enumt;
+ enum_type_t *enumt = &type->enumt;
/* if we have a default, no warnings */
if (statement->default_label != NULL)
return;
+ determine_enum_values(enumt);
+
/* FIXME: calculation of value should be done while parsing */
/* TODO: quadratic algorithm here. Change to an n log n one */
- long last_value = -1;
- const entity_t *entry = enumt->enume->base.next;
+ const entity_t *entry = enumt->enume->base.next;
for (; entry != NULL && entry->kind == ENTITY_ENUM_VALUE;
entry = entry->base.next) {
- const expression_t *expression = entry->enum_value.value;
- long value = expression != NULL ? fold_constant_to_int(expression) : last_value + 1;
- bool found = false;
- for (const case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) {
+ ir_tarval *value = entry->enum_value.tv;
+ bool found = false;
+ for (const case_label_statement_t *l = statement->first_case; l != NULL;
+ l = l->next) {
if (l->expression == NULL)
continue;
- if (l->first_case <= value && value <= l->last_case) {
+ if (l->first_case == l->last_case && l->first_case != value)
+ continue;
+ if ((tarval_cmp(l->first_case, value) & ir_relation_less_equal)
+ && (tarval_cmp(value, l->last_case) & ir_relation_less_equal)) {
found = true;
break;
}
source_position_t const *const pos = &statement->base.source_position;
warningf(WARN_SWITCH_ENUM, pos, "'%N' not handled in switch", entry);
}
- last_value = value;
}
}
label_t *const label = get_label("while parsing goto");
if (label) {
+ label->n_users += 1;
label->used = true;
statement->gotos.label = label;
continue;
why = WARN_UNUSED_FUNCTION;
- s = entity->function.statement != NULL ? "defined" : "declared";
+ s = entity->function.body != NULL ? "defined" : "declared";
} else {
why = WARN_UNUSED_VARIABLE;
s = "defined";
static void prepare_main_collect2(entity_t *const entity)
{
- PUSH_SCOPE(&entity->function.statement->compound.scope);
+ PUSH_SCOPE(&entity->function.body->compound.scope);
// create call to __main
symbol_t *symbol = symbol_table_insert("__main");
expr_statement->base.source_position = builtin_source_position;
expr_statement->expression.expression = call;
- statement_t *statement = entity->function.statement;
- assert(statement->kind == STATEMENT_COMPOUND);
- compound_statement_t *compounds = &statement->compound;
+ statement_t *const body = entity->function.body;
+ assert(body->kind == STATEMENT_COMPOUND);
+ compound_statement_t *compounds = &body->compound;
expr_statement->base.next = compounds->statements;
compounds->statements = expr_statement;