Bring back convert_name(), but siimplified.

It is now mainly for converting __FILE__ etc, handling expression symbols,
and checking for undefined identifiers.
This commit is contained in:
Bill Currie 2011-02-05 22:32:23 +09:00
parent d03fdc5e67
commit 67957a14df
4 changed files with 71 additions and 1 deletions

View file

@ -507,6 +507,15 @@ expr_t *new_param_expr (struct type_s *type, int num);
*/
expr_t *new_move_expr (expr_t *e1, expr_t *e2, struct type_s *type);
/** Convert a name to an expression of the appropriate type.
Converts the expression in-place. If the exprssion is not a name
expression (ex_name), no converision takes place.
\param e The expression to convert.
*/
void convert_name (expr_t *e);
expr_t *append_expr (expr_t *block, expr_t *e);
void print_expr (expr_t *e);

View file

@ -84,9 +84,60 @@ type_t *ev_types[ev_type_count] = {
&type_invalid,
};
void
convert_name (expr_t *e)
{
symbol_t *sym;
expr_t *new;
if (e->type != ex_symbol)
return;
sym = e->e.symbol;
if (!strcmp (sym->name, "__PRETTY_FUNCTION__")
&& current_func) {
new = new_string_expr (current_func->name);
goto convert;
}
if (!strcmp (sym->name, "__FUNCTION__")
&& current_func) {
new = new_string_expr (current_func->def->name);
goto convert;
}
if (!strcmp (sym->name, "__LINE__")
&& current_func) {
new = new_integer_expr (e->line);
goto convert;
}
if (!strcmp (sym->name, "__FILE__")
&& current_func) {
new = new_string_expr (GETSTR (e->file));
goto convert;
}
if (!sym->table) {
error (e, "%s undefined", sym->name);
sym->type = type_default;
//FIXME need a def
return;
}
if (sym->sy_type == sy_expr) {
new = sym->s.expr;
goto convert;
}
if (sym->sy_type == sy_type)
internal_error (e, "unexpected typedef");
// var, const and func shouldn't need extra handling
return;
convert:
e->type = new->type;
e->e = new->e;
}
type_t *
get_type (expr_t *e)
{
convert_name (e);
switch (e->type) {
case ex_label:
case ex_error:
@ -1185,6 +1236,7 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if (e2->type == ex_error)
return e2;
convert_name (e1);
if (e1->type == ex_block && e1->e.block.is_call
&& has_function_call (e2) && e1->e.block.result) {
e = new_temp_def_expr (get_type (e1->e.block.result));
@ -1194,6 +1246,7 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
if (op == '.')
return field_expr (e1, e2);
convert_name (e2);
if (op == OR || op == AND) {
e1 = test_expr (e1);
e2 = test_expr (e2);
@ -1302,6 +1355,7 @@ unary_expr (int op, expr_t *e)
quat_t q;
const char *s;
convert_name (e);
if (e->type == ex_error)
return e;
switch (op) {
@ -2156,6 +2210,9 @@ assign_expr (expr_t *e1, expr_t *e2)
type_t *t1, *t2, *type;
expr_t *e;
convert_name (e1);
convert_name (e2);
if (e1->type == ex_error)
return e1;
if (e2->type == ex_error)
@ -2291,6 +2348,8 @@ cast_expr (type_t *type, expr_t *e)
expr_t *c;
type_t *e_type;
convert_name (e);
if (e->type == ex_error)
return e;

View file

@ -1022,7 +1022,7 @@ unary_expr
;
primary
: NAME { $$ = new_symbol_expr (check_undefined ($1)); }
: NAME { $$ = new_symbol_expr ($1); }
| BREAK %prec BREAK_PRIMARY { $$ = new_name_expr (save_string ("break")); }
| ARGS { $$ = new_name_expr (".args"); }
| SELF { $$ = new_self_expr (); }

View file

@ -114,6 +114,8 @@ case_label_expr (switch_block_t *switch_block, expr_t *value)
SYS_CHECKMEM (cl);
if (value)
convert_name (value);
if (value && !is_constant (value)) {
error (value, "non-constant case value");
free (cl);