[qfcc] Report undefined symbols in proc_symbol

This required always recording the unmangled function symbol, but helps
with error checks in the long run.
This commit is contained in:
Bill Currie 2024-12-11 16:31:24 +09:00
parent fc519054f2
commit 5b13bcf11c
2 changed files with 40 additions and 3 deletions

View file

@ -312,6 +312,16 @@ ps_file (const expr_t *e)
return new_string_expr (GETSTR (e->loc.file));
}
static const expr_t *
ps_super (const expr_t *e)
{
if (current_class && strcmp (e->symbol->name, "super") == 0) {
// FIXME check for in message receiver expr?
return e;
}
return nullptr;
}
static struct {
const char *name;
const expr_t *(*expr) (const expr_t *e);
@ -321,6 +331,7 @@ static struct {
{ .name = "__LINE__", .expr = ps_line },
{ .name = "__INFINITY__", .expr = ps_infinity },
{ .name = "__FILE__", .expr = ps_file },
{ .name = "super", .expr = ps_super },
{}
};
@ -332,7 +343,11 @@ proc_symbol (const expr_t *expr, rua_ctx_t *ctx)
for (auto bi = builtin_names; bi->name; bi++) {
if (strcmp (bi->name, sym->name) == 0) {
scoped_src_loc (expr);
return bi->expr (expr);
auto e = bi->expr (expr);
if (e) {
return bi->expr (expr);
}
break;
}
}
sym = symtab_lookup (current_symtab, sym->name);
@ -344,9 +359,9 @@ proc_symbol (const expr_t *expr, rua_ctx_t *ctx)
return sym->convert.conv (sym, sym->convert.data);
}
scoped_src_loc (expr);
expr = new_symbol_expr (sym);
return new_symbol_expr (sym);
}
return expr;
return error (expr, "undefined symbol `%s`", expr->symbol->name);
}
static bool

View file

@ -852,6 +852,17 @@ function_symbol (specifier_t spec)
const char *name = sym->name;
metafunc_t *func = Hash_Find (function_map, name);
auto check = symtab_lookup (current_symtab, name);
if ((sym->table == current_symtab && sym->sy_type != sy_func)
|| (check && check->table == current_symtab
&& check->sy_type != sy_func)) {
auto err = new_symbol (nullptr);
err->sy_type = sy_expr;
err->expr = error (0, "`%s` redeclared as different kind of symbol",
name);
return err;
}
auto genfunc = parse_generic_function (name, spec);
if (genfunc) {
add_generic_function (genfunc);
@ -879,6 +890,17 @@ function_symbol (specifier_t spec)
s->type = unalias_type (sym->type);
symtab_addsymbol (current_symtab, s);
}
if (!sym->table && strcmp (s->name, sym->name) != 0) {
// record unmangled function symbol to avoid false undefined symbol
// errors
sym->sy_type = sy_func;
sym->metafunc = new_metafunc ();
*sym->metafunc = (metafunc_t) {
.name = save_string (name),
.meta_type = mf_overload,
};
symtab_addsymbol (current_symtab, sym);
}
//if it existed, override the declaration's parameters and metafunc
s->params = sym->params;
s->metafunc = func;