Make initialized variables defs rather than immediate constants.

This commit is contained in:
Bill Currie 2011-03-30 19:58:09 +09:00
parent 7dbd2ec172
commit 8e18c76bde
3 changed files with 24 additions and 14 deletions

View file

@ -439,17 +439,17 @@ initialize_def (symbol_t *sym, type_t *type, expr_t *init, defspace_t *space,
sym->type = type;
if (!sym->table)
symtab_addsymbol (current_symtab, sym);
if (storage == st_global && init && is_scalar (type)) {
sym->sy_type = sy_const;
memset (&sym->s.value, 0, sizeof (&sym->s.value));
if (init->type != ex_value) { //FIXME arrays/structs
error (0, "non-constant initializier");
} else {
sym->s.value = init->e.value;
convert_value (&sym->s.value, sym->type);
}
return;
}
// if (storage == st_global && init && is_scalar (type)) {
// sym->sy_type = sy_const;
// memset (&sym->s.value, 0, sizeof (&sym->s.value));
// if (init->type != ex_value) { //FIXME arrays/structs
// error (0, "non-constant initializier");
// } else {
// sym->s.value = init->e.value;
// convert_value (&sym->s.value, sym->type);
// }
// return;
// }
if (sym->s.def && sym->s.def->external) {
//FIXME this really is not the right way
relocs = sym->s.def->relocs;

View file

@ -598,7 +598,9 @@ int
is_constant (expr_t *e)
{
if (e->type == ex_nil || e->type == ex_value
|| (e->type == ex_symbol && e->e.symbol->sy_type == sy_const))
|| (e->type == ex_symbol && e->e.symbol->sy_type == sy_const)
|| (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
&& e->e.symbol->s.def->constant))
return 1;
return 0;
}
@ -670,6 +672,10 @@ expr_float (expr_t *e)
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_const
&& e->e.symbol->type->type == ev_float)
return e->e.symbol->s.value.v.float_val;
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
&& e->e.symbol->s.def->constant
&& is_float (e->e.symbol->s.def->type))
return D_FLOAT (e->e.symbol->s.def);
internal_error (e, "not a float constant");
}
@ -750,6 +756,10 @@ expr_integer (expr_t *e)
&& (e->e.symbol->type->type == ev_integer
|| is_enum (e->e.symbol->type)))
return e->e.symbol->s.value.v.integer_val;
if (e->type == ex_symbol && e->e.symbol->sy_type == sy_var
&& e->e.symbol->s.def->constant
&& is_integral (e->e.symbol->s.def->type))
return D_INT (e->e.symbol->s.def);
internal_error (e, "not an integer constant");
}

View file

@ -133,7 +133,7 @@ case_label_expr (switch_block_t *switch_block, expr_t *value)
if (!type_assignable (type, get_type (value)))
return error (value, "type mismatch in case label");
if (is_integral (type) && is_integral (val_type)) {
// do nothing
value = new_integer_expr (expr_integer (value));
debug (value, "integeral label used in integral switch");
} else if (is_integral (type) && is_float (val_type)) {
warning (value, "float label used in integral switch");
@ -142,7 +142,7 @@ case_label_expr (switch_block_t *switch_block, expr_t *value)
debug (value, "integeral label used in float switch");
value = new_float_expr (expr_integer (value));
} else if (is_float (type) && is_float (val_type)) {
// do nothing
value = new_float_expr (expr_float (value));
debug (value, "float label used in float switch");
}
}