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_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 /** Create an expression of the correct type that references the specified
parameter slot. parameter slot.

View file

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

View file

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

View file

@ -239,7 +239,6 @@ convert_op (int op)
case IFB: return "<IFB>"; case IFB: return "<IFB>";
case IFAE: return "<IFAE>"; case IFAE: return "<IFAE>";
case IFA: return "<IFA>"; case IFA: return "<IFA>";
case 'C': return "=";
case 'M': return "<MOVE>"; case 'M': return "<MOVE>";
default: default:
return 0; return 0;
@ -552,6 +551,17 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
return sblock; 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 * static sblock_t *
expr_cast (sblock_t *sblock, expr_t *e, operand_t **op) 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 '.': case '.':
sblock = expr_deref (sblock, e, op); sblock = expr_deref (sblock, e, op);
break; break;
case 'A':
sblock = expr_alias (sblock, e, op);
break;
case 'C': case 'C':
sblock = expr_cast (sblock, e, op); sblock = expr_cast (sblock, e, op);
break; break;