Support enums in expressions that support scalar types.

This commit is contained in:
Bill Currie 2011-03-03 10:36:43 +09:00
parent c12211d8bb
commit 848994323e

View file

@ -53,6 +53,8 @@ static __attribute__ ((used)) const char rcsid[] =
#include "type.h"
#include "qc-parse.h"
typedef expr_t *(*operation_t) (int op, expr_t *e, expr_t *e1, expr_t *e2);
static expr_t *
cf_cast_expr (type_t *type, expr_t *e)
{
@ -824,25 +826,40 @@ do_op_compound (int op, expr_t *e, expr_t *e1, expr_t *e2)
return error (e1, "invalid operand for compound");
}
static operation_t *do_op[ev_type_count];
static expr_t *
do_op_invalid (int op, expr_t *e, expr_t *e1, expr_t *e2)
{
dstring_t *t1 = dstring_newstr ();
dstring_t *t2 = dstring_newstr ();
type_t *t1 = get_type (e1);
type_t *t2 = get_type (e2);
if (is_scalar (t1) && is_scalar (t2)) {
// one or both expressions are an enum, and the other is one of
// int, float or short. Treat the enum as the other type, or as
// the default type if both are enum.
etype_t t;
if (!is_enum (t1))
t = t1->type;
else if (!is_enum (t2))
t = t2->type;
else
t = type_default->type;
return do_op[t][t] (op, e, e1, e2);
} else {
dstring_t *enc1 = dstring_newstr ();
dstring_t *enc2 = dstring_newstr ();
print_type_str (t1, get_type (e1));
print_type_str (t2, get_type (e2));
print_type_str (enc1, t1);
print_type_str (enc2, t2);
//print_expr (e);
e1 = error (e1, "invalid operands for binary %s: %s %s",
get_op_string (op), t1->str, t2->str);
dstring_delete (t1);
dstring_delete (t2);
return e1;
//print_expr (e);
e1 = error (e1, "invalid operands for binary %s: %s %s",
get_op_string (op), enc1->str, enc2->str);
dstring_delete (enc1);
dstring_delete (enc2);
return e1;
}
}
typedef expr_t *(*operation_t) (int op, expr_t *e, expr_t *e1, expr_t *e2);
static operation_t op_void[ev_type_count] = {
do_op_invalid, // ev_void
do_op_invalid, // ev_string
@ -1099,6 +1116,6 @@ fold_constants (expr_t *e)
if (t1 < 0 || t1 >= ev_type_count || t2 < 0 || t2 >= ev_type_count
|| !do_op[t1] || !do_op[t1][t2])
internal_error (e, 0);
internal_error (e, "invalid type");
return do_op[t1][t2] (op, e, e1, e2);
}