Implement alias expressions (finally).

Alias expressions are like cast expressions, but never do any conversions.
This commit is contained in:
Bill Currie 2011-03-03 11:06:10 +09:00
parent 59f520f4e7
commit 45de7327dc
4 changed files with 29 additions and 6 deletions

View File

@ -497,6 +497,8 @@ expr_t *new_this_expr (void);
*/
expr_t *new_ret_expr (struct type_s *type);
expr_t *new_alias_expr (struct type_s *type, expr_t *expr);
/** Create an expression of the correct type that references the specified
parameter slot.

View File

@ -86,6 +86,7 @@ get_op_string (int op)
case 'r': return "<return>";
case 's': return "<state>";
case 'c': return "<call>";
case 'A': return "<alias>";
case 'C': return "<cast>";
case 'M': return "<move>";
default:

View File

@ -802,18 +802,25 @@ new_this_expr (void)
return new_symbol_expr (sym);
}
expr_t *
new_alias_expr (type_t *type, expr_t *expr)
{
expr_t *alias;
alias = new_unary_expr ('A', expr);
alias->e.expr.type = type;
return alias;
}
static expr_t *
param_expr (const char *name, type_t *type)
{
symbol_t *sym;
expr_t *sym_expr;
expr_t *cast;
sym = make_symbol (name, &type_param, 0, st_extern);
sym_expr = new_symbol_expr (sym);
cast = new_unary_expr ('C', sym_expr);
cast->e.expr.type = type;
return cast;
return new_alias_expr (type, sym_expr);
}
expr_t *
@ -2313,7 +2320,7 @@ is_lvalue (expr_t *e)
return 1;
if (e->type == ex_uexpr && e->e.expr.op == '.')
return 1;
if (e->type == ex_uexpr && e->e.expr.op == 'C') //FIXME really need alias
if (e->type == ex_uexpr && e->e.expr.op == 'A')
return is_lvalue (e->e.expr.e1);
return 0;
}

View File

@ -239,7 +239,6 @@ convert_op (int op)
case IFB: return "<IFB>";
case IFAE: return "<IFAE>";
case IFA: return "<IFA>";
case 'C': return "=";
case 'M': return "<MOVE>";
default:
return 0;
@ -552,6 +551,17 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
return sblock;
}
static sblock_t *
expr_alias (sblock_t *sblock, expr_t *e, operand_t **op)
{
operand_t *src = 0;
sblock = statement_subexpr (sblock, e->e.expr.e1, &src);
src->type = low_level_type (e->e.expr.type);
*op = src;
return sblock;
}
static sblock_t *
expr_cast (sblock_t *sblock, expr_t *e, operand_t **op)
{
@ -586,6 +596,9 @@ expr_uexpr (sblock_t *sblock, expr_t *e, operand_t **op)
case '.':
sblock = expr_deref (sblock, e, op);
break;
case 'A':
sblock = expr_alias (sblock, e, op);
break;
case 'C':
sblock = expr_cast (sblock, e, op);
break;