diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index e09980e0d..bc515c5bc 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -1035,15 +1035,6 @@ const type_t *resolve_type (const expr_t *te); const type_t **expand_type (const expr_t *te); const expr_t *evaluate_type (const expr_t *te); -/** 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. -*/ -const expr_t *convert_name (const expr_t *e) __attribute__((warn_unused_result)); - expr_t *append_expr (expr_t *block, const expr_t *e); expr_t *prepend_expr (expr_t *block, const expr_t *e); diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index 389479f56..fc76d1012 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -611,7 +611,6 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, } if (!init) return; - init = convert_name (init); if (init->type == ex_error) return; if ((is_structural (sym->type) || is_nonscalar (sym->type)) diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index 405bc2988..8611142ff 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -70,62 +70,10 @@ ALLOC_STATE (expr_t, exprs); ALLOC_STATE (ex_listitem_t, listitems); -const expr_t * -convert_name (const expr_t *e) -{ - symbol_t *sym; - - if (!e || e->type != ex_symbol || e->symbol->is_constexpr) - return e; - - sym = e->symbol; - - if (!strcmp (sym->name, "__PRETTY_FUNCTION__") - && current_func) { - return new_string_expr (current_func->name); - } - if (!strcmp (sym->name, "__FUNCTION__") - && current_func) { - return new_string_expr (current_func->def->name); - } - if (!strcmp (sym->name, "__LINE__") - && current_func) { - return new_int_expr (e->loc.line, false); - } - if (!strcmp (sym->name, "__INFINITY__") - && current_func) { - return new_float_expr (INFINITY, false); - } - if (!strcmp (sym->name, "__FILE__") - && current_func) { - return new_string_expr (GETSTR (e->loc.file)); - } - if (sym->sy_type == sy_var) { - return e; - } - if (!sym->table) { - e = error (e, "%s undefined", sym->name); - sym->type = type_default; - //FIXME need a def - return e; - } - if (sym->sy_type == sy_convert) { - return sym->convert.conv (sym, sym->convert.data); - } - if (sym->sy_type == sy_expr) { - return sym->expr; - } - if (sym->sy_type == sy_type) - internal_error (e, "unexpected typedef"); - // var, const and func shouldn't need extra handling - return e; -} - const type_t * get_type (const expr_t *e) { const type_t *type = nullptr; - e = convert_name (e); switch (e->type) { case ex_inout: if (!e->inout.out) { @@ -659,7 +607,6 @@ paren_expr (const expr_t *e) expr_t * new_horizontal_expr (int op, const expr_t *vec, type_t *type) { - vec = convert_name (vec); if (vec->type == ex_error) { return (expr_t *) vec; } @@ -683,7 +630,6 @@ new_horizontal_expr (int op, const expr_t *vec, type_t *type) const expr_t * new_swizzle_expr (const expr_t *src, const char *swizzle) { - src = convert_name (src); if (is_error (src)) { return (expr_t *) src; } @@ -1733,7 +1679,6 @@ field_expr (const expr_t *e1, const expr_t *e2) const type_t *t1, *t2; expr_t *e; - e1 = convert_name (e1); if (e1->type == ex_error) return e1; if (e1->type == ex_symbol && e1->symbol->sy_type == sy_namespace) { @@ -1763,7 +1708,6 @@ field_expr (const expr_t *e1, const expr_t *e2) e->expr.type = field->type; return e; } else { - e2 = convert_name (e2); t2 = get_type (e2); if (e2->type == ex_error) return e2; @@ -2422,9 +2366,6 @@ incop_expr (int op, const expr_t *e, int postop) const expr_t * array_expr (const expr_t *array, const expr_t *index) { - array = convert_name (array); - index = convert_name (index); - auto array_type = get_type (array); auto index_type = get_type (index); const type_t *ele_type; @@ -2557,7 +2498,6 @@ address_expr (const expr_t *e1, const type_t *t) { expr_t *e; - e1 = convert_name (e1); if (e1->type == ex_error) return e1; diff --git a/tools/qfcc/source/expr_assign.c b/tools/qfcc/source/expr_assign.c index 676f13fd4..6e9710195 100644 --- a/tools/qfcc/source/expr_assign.c +++ b/tools/qfcc/source/expr_assign.c @@ -233,7 +233,6 @@ assign_expr (const expr_t *dst, const expr_t *src) const expr_t *expr; const type_t *dst_type, *src_type; - dst = convert_name (dst); if (is_error (dst)) { return dst; } @@ -252,7 +251,6 @@ assign_expr (const expr_t *dst, const expr_t *src) } if (src && !is_memset (src)) { - src = convert_name (src); if (is_error (src)) { return src; } diff --git a/tools/qfcc/source/expr_binary.c b/tools/qfcc/source/expr_binary.c index 1dc6e8321..18afe2836 100644 --- a/tools/qfcc/source/expr_binary.c +++ b/tools/qfcc/source/expr_binary.c @@ -712,7 +712,6 @@ is_call (const expr_t *e) const expr_t * binary_expr (int op, const expr_t *e1, const expr_t *e2) { - e1 = convert_name (e1); // FIXME this is target-specific info and should not be in the // expression tree if (e1->type == ex_alias && is_call (e1->alias.expr)) { @@ -739,7 +738,6 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2) if (e1->type == ex_error) return e1; - e2 = convert_name (e2); if (e2->type == ex_error) return e2; diff --git a/tools/qfcc/source/expr_bool.c b/tools/qfcc/source/expr_bool.c index a0b227b15..002259270 100644 --- a/tools/qfcc/source/expr_bool.c +++ b/tools/qfcc/source/expr_bool.c @@ -70,7 +70,6 @@ test_expr (const expr_t *e) { const expr_t *new = 0; - e = convert_name (e); if (e->type == ex_error) return e; diff --git a/tools/qfcc/source/expr_call.c b/tools/qfcc/source/expr_call.c index 9d3d2d5e7..c449cfc20 100644 --- a/tools/qfcc/source/expr_call.c +++ b/tools/qfcc/source/expr_call.c @@ -340,18 +340,11 @@ build_function_call (const expr_t *fexpr, const type_t *ftype, const expr_t * function_expr (const expr_t *fexpr, const expr_t *args) { - if (args) { - for (auto p = args->list.head; p; p = p->next) { - p->expr = convert_name (p->expr); - } - } - if (fexpr->type == ex_symbol && fexpr->symbol->sy_type == sy_type) { return constructor_expr (fexpr, args); } fexpr = find_function (fexpr, args); - fexpr = convert_name (fexpr); if (is_error (fexpr)) { return fexpr; } @@ -387,7 +380,6 @@ return_expr (function_t *f, const expr_t *e) const type_t *t; const type_t *ret_type = unalias_type (f->type->func.ret_type); - e = convert_name (e); if (!e) { if (!is_void(ret_type)) { if (options.traditional) { diff --git a/tools/qfcc/source/expr_cast.c b/tools/qfcc/source/expr_cast.c index 8fe441726..02a51f85f 100644 --- a/tools/qfcc/source/expr_cast.c +++ b/tools/qfcc/source/expr_cast.c @@ -89,8 +89,6 @@ cast_expr (const type_t *dstType, const expr_t *e) { const type_t *srcType; - e = convert_name (e); - if (e->type == ex_error) return e; diff --git a/tools/qfcc/source/expr_process.c b/tools/qfcc/source/expr_process.c index aa2b284ea..e064d51f3 100644 --- a/tools/qfcc/source/expr_process.c +++ b/tools/qfcc/source/expr_process.c @@ -28,6 +28,7 @@ # include "config.h" #endif #include +#include #include "QF/fbsearch.h" #include "QF/heapsort.h" @@ -41,6 +42,7 @@ #include "tools/qfcc/include/qfcc.h" #include "tools/qfcc/include/rua-lang.h" #include "tools/qfcc/include/shared.h" +#include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/symtab.h" #include "tools/qfcc/include/target.h" #include "tools/qfcc/include/type.h" @@ -271,15 +273,68 @@ proc_block (const expr_t *expr) return block; } +static const expr_t * +ps_pretty_function (const expr_t *e) +{ + return new_string_expr (current_func->name); +} + +static const expr_t * +ps_function (const expr_t *e) +{ + return new_string_expr (current_func->def->name); +} + +static const expr_t * +ps_line (const expr_t *e) +{ + return new_int_expr (e->loc.line, false); +} + +static const expr_t * +ps_infinity (const expr_t *e) +{ + return new_float_expr (INFINITY, false); +} + +static const expr_t * +ps_file (const expr_t *e) +{ + return new_string_expr (GETSTR (e->loc.file)); +} + +static struct { + const char *name; + const expr_t *(*expr) (const expr_t *e); +} builtin_names[] = { + { .name = "__PRETTY_FUNCTION__", .expr = ps_pretty_function }, + { .name = "__FUNCTION__", .expr = ps_function }, + { .name = "__LINE__", .expr = ps_line }, + { .name = "__INFINITY__", .expr = ps_infinity }, + { .name = "__FILE__", .expr = ps_file }, + + {} +}; + static const expr_t * proc_symbol (const expr_t *expr) { - auto sym = symtab_lookup (current_symtab, expr->symbol->name); + auto sym = expr->symbol; + for (auto bi = builtin_names; bi->name; bi++) { + if (strcmp (bi->name, sym->name) == 0) { + scoped_src_loc (expr); + return bi->expr (expr); + } + } + sym = symtab_lookup (current_symtab, sym->name); if (sym) { - scoped_src_loc (expr); + if (sym->sy_type == sy_expr) { + return sym->expr; + } if (sym->sy_type == sy_convert) { return sym->convert.conv (sym, sym->convert.data); } + scoped_src_loc (expr); expr = new_symbol_expr (sym); } return expr; diff --git a/tools/qfcc/source/expr_unary.c b/tools/qfcc/source/expr_unary.c index 5588d781b..97b2c7c04 100644 --- a/tools/qfcc/source/expr_unary.c +++ b/tools/qfcc/source/expr_unary.c @@ -459,7 +459,6 @@ static unary_type_t *unary_expr_types[ev_type_count] = { const expr_t * unary_expr (int op, const expr_t *e) { - e = convert_name (e); if (e->type == ex_error) { return e; } diff --git a/tools/qfcc/source/struct.c b/tools/qfcc/source/struct.c index 63bc54d21..4edcce5ca 100644 --- a/tools/qfcc/source/struct.c +++ b/tools/qfcc/source/struct.c @@ -309,7 +309,6 @@ add_enum (symbol_t *enm, symbol_t *name, const expr_t *val) if (enum_tab->symbols) value = ((symbol_t *)(enum_tab->symtail))->value->uint_val + 1; if (val) { - val = convert_name (val); if (!is_constant (val)) error (val, "non-constant initializer"); else if (!is_int_val (val)) diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index 8d86e1a67..653d46460 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -114,8 +114,6 @@ case_label_expr (switch_block_t *switch_block, const expr_t *value) SYS_CHECKMEM (cl); - if (value) - value = convert_name (value); if (value && !is_constant (value)) { error (value, "non-constant case value"); free (cl);