mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
[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:
parent
19002116c2
commit
c04f1c0156
4 changed files with 34 additions and 12 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue