[qfcc] Really delay the conversion of nil

Now convert_nil only assigns the nil expression a type, and nil makes
its way down to the statement emission code (where it belongs, really).
Breaks even more things :)
This commit is contained in:
Bill Currie 2020-03-13 17:57:58 +09:00
parent 19002116c2
commit c04f1c0156
4 changed files with 34 additions and 12 deletions

View file

@ -234,6 +234,7 @@ typedef struct expr_s {
ex_value_t *value; ///< constant value
element_chain_t compound; ///< compound initializer
ex_memset_t memset; ///< memset expr params
struct type_s *nil; ///< type for nil if known
} e;
} expr_t;

View file

@ -360,10 +360,11 @@ init_elements (struct def_s *def, expr_t *eles)
} else {
def_t dummy = *def;
for (element = element_chain.head; element; element = element->next) {
if (element->expr) {
c = constant_expr (element->expr);
} else {
c = new_nil_expr ();
if (!element->expr
|| ((c = constant_expr (element->expr))->type == ex_nil)) {
// nil is type agnostic 0 and defspaces are initialized to
// 0 on creation
continue;
}
if (c->type == ex_nil) {
c = convert_nil (c, element->type);

View file

@ -226,6 +226,10 @@ get_type (expr_t *e)
return &type_float;
return &type_integer;
case ex_nil:
if (e->e.nil) {
return e->e.nil;
}
// fall through
case ex_state:
return &type_void;
case ex_block:
@ -1414,8 +1418,7 @@ convert_double (expr_t *e)
expr_t *
convert_nil (expr_t *e, type_t *t)
{
e->type = ex_value;
e->e.value = new_nil_val (t);
e->e.nil = t;
return e;
}
@ -1977,8 +1980,6 @@ return_expr (function_t *f, expr_t *e)
if (e->type == ex_nil) {
t = ret_type;
convert_nil (e, t);
if (e->type == ex_nil)
return error (e, "invalid return type for NIL");
} else {
if (!options.traditional)
return error (e, "void value not ignored as it ought to be");

View file

@ -1149,6 +1149,23 @@ expr_vector_e (sblock_t *sblock, expr_t *e, operand_t **op)
return sblock;
}
static sblock_t *
expr_nil (sblock_t *sblock, expr_t *e, operand_t **op)
{
type_t *nil = e->e.nil;
expr_t *ptr;
if (!is_struct (nil) && !is_array (nil)) {
*op = value_operand (new_nil_val (nil), e);
return sblock;
}
ptr = address_expr (new_temp_def_expr (nil), 0, 0);
expr_file_line (ptr, e);
sblock = statement_subexpr (sblock, ptr, op);
e = expr_file_line (new_memset_expr (ptr, new_integer_expr (0), nil), e);
sblock = statement_slist (sblock, e);
return sblock;
}
static sblock_t *
expr_value (sblock_t *sblock, expr_t *e, operand_t **op)
{
@ -1171,18 +1188,20 @@ statement_subexpr (sblock_t *sblock, expr_t *e, operand_t **op)
expr_symbol,
expr_temp,
expr_vector_e, // ex_vector
0, // ex_nil
expr_nil,
expr_value,
0, // ex_compound
0, // ex_memset
};
if (!e) {
*op = 0;
return sblock;
}
if (e->type > ex_value)
internal_error (e, "bad expression type");
if (e->type > ex_memset)
internal_error (e, "bad sub-expression type");
if (!sfuncs[e->type])
internal_error (e, "unexpected expression type: %s",
internal_error (e, "unexpected sub-expression type: %s",
expr_names[e->type]);
sblock = sfuncs[e->type] (sblock, e, op);