[qfcc] Resurrect is_function

In the end, it does simplify things a lot, though it helped get function
pointers working at least a bit (they're not quite the same as C yet,
but I think that's mostly that functions can be struct fields).
This commit is contained in:
Bill Currie 2025-01-03 17:52:19 +09:00
parent 99632ddb03
commit bec8b290d2
8 changed files with 44 additions and 28 deletions

View file

@ -81,6 +81,7 @@ typedef struct specifier_s {
bool is_overload:1;
bool is_generic:1;
bool is_generic_block:1;
bool is_function:1;
bool is_far:1;
};
unsigned spec_bits;

View file

@ -1659,9 +1659,9 @@ class_finish_module (rua_ctx_t *ctx)
exec_class_sym = symtab_lookup (pr.symtab, "__obj_exec_class");
if (!exec_class_sym) {
exec_class_sym = new_symbol_type ("__obj_exec_class",
&type_exec_class);
exec_class_sym = new_symbol ("__obj_exec_class");
exec_class_sym = function_symbol ((specifier_t) {
.type = &type_exec_class,
.sym = exec_class_sym
}, ctx);
make_function (exec_class_sym, 0, exec_class_sym->table->space,

View file

@ -2829,6 +2829,7 @@ const expr_t *
think_expr (symbol_t *think_sym, rua_ctx_t *ctx)
{
symbol_t *sym;
const type_t *type;
if (think_sym->table)
return new_symbol_expr (think_sym);
@ -2837,11 +2838,14 @@ think_expr (symbol_t *think_sym, rua_ctx_t *ctx)
if (sym && sym->sy_type == sy_def && sym->type
&& sym->type->type == ev_field
&& sym->type->fldptr.type->type == ev_func) {
think_sym->type = sym->type->fldptr.type;
type = sym->type->fldptr.type;
} else {
think_sym->type = &type_func;
type = &type_func;
}
think_sym = function_symbol ((specifier_t) { .sym = think_sym }, ctx);
think_sym = function_symbol ((specifier_t) {
.type = type,
.sym = think_sym,
}, ctx);
make_function (think_sym, 0, current_symtab->space, current_storage);
return new_symbol_expr (think_sym);
}

View file

@ -757,12 +757,11 @@ create_generic_sym (genfunc_t *g, const expr_t *fexpr, calltype_t *calltype,
static metafunc_t *
get_function (const char *name, specifier_t spec, rua_ctx_t *ctx)
{
if (!spec.sym->type || !spec.sym->type->encoding) {
spec = spec_process (spec, ctx);
spec.sym->type = spec.type;
set_func_attrs (spec.sym->type, spec.attributes);
spec.sym->type = find_type (spec.sym->type);
}
auto type = unalias_type (spec.sym->type);
int num_params = type->func.num_params;
if (num_params < 0) {
@ -1401,7 +1400,8 @@ emit_ctor (rua_ctx_t *ctx)
}
auto spec = (specifier_t) {
.sym = new_symbol_type (".ctor", &type_func),
.type = &type_func,
.sym = new_symbol (".ctor"),
.storage = sc_static,
.is_far = true,
};

View file

@ -183,8 +183,9 @@ method_symbol (class_type_t *class_type, method_t *method, rua_ctx_t *ctx)
*s = '_';
//printf ("%s %s %s %ld\n", method->name, method->types, str->str,
// str->size);
sym = new_symbol_type (str->str, method->type);
sym = function_symbol ((specifier_t) { .sym = sym }, ctx);
sym = new_symbol (str->str);
sym = function_symbol ((specifier_t) { .type = method->type, .sym = sym },
ctx);
sym->params = method->params;
dstring_delete (str);
return sym;
@ -369,8 +370,9 @@ send_message (int super, rua_ctx_t *ctx)
if (!sym) {
symtab_t *save = current_symtab;
current_symtab = pr.symtab;
sym = new_symbol_type (sm_name, sm_type);
sym = function_symbol ((specifier_t) { .sym = sym }, ctx);
sym = new_symbol (sm_name);
sym = function_symbol ((specifier_t) { .type = sm_type, .sym = sym },
ctx);
make_function (sym, 0, sym->table->space, sc_extern);
current_symtab = save;
}

View file

@ -422,6 +422,7 @@ function_spec (specifier_t spec, param_t *parameters)
if (spec.type_list) {
expr_append_expr (spec.type_list, type_expr);
} else {
spec.is_function = true;
spec.type_list = new_list_expr (type_expr);
}

View file

@ -154,10 +154,11 @@ build_dotmain (symbol_t *program, rua_ctx_t *ctx)
expr_t *code;
expr_t *exitcode;
dotmain->params = 0;
dotmain->type = parse_params (&type_int, 0);
dotmain->type = find_type (dotmain->type);
dotmain = function_symbol ((specifier_t) { .sym = dotmain }, ctx);
auto dmtype = find_type (parse_params (&type_int, 0));
dotmain = function_symbol ((specifier_t) {
.type = dmtype,
.sym = dotmain,
}, ctx);
exitcode = new_symbol_expr (symtab_lookup (current_symtab, "ExitCode"));
@ -214,9 +215,12 @@ function_decl (symbol_t *sym, param_t *params, const type_t *ret_type,
// use `@name` so `main` can be used (`.main` is reserved for the entry
// point)
auto fsym = new_symbol (va (0, "@%s", sym->name));
fsym->type = parse_params (ret_type, params);
fsym->type = find_type (fsym->type);
fsym = function_symbol ((specifier_t) {.sym = fsym, .params = params}, ctx);
auto ftype = find_type (parse_params (ret_type, params));
fsym = function_symbol ((specifier_t) {
.type = ftype,
.sym = fsym,
.params = params
}, ctx);
auto fsym_expr = new_symbol_expr (fsym);
if (!params) {
fsym_expr = new_call_expr (fsym_expr, nullptr, nullptr);
@ -314,9 +318,11 @@ program_head
sym->def->nosave = 1;
}
}
$$->type = parse_params (&type_void, 0);
$$->type = find_type ($$->type);
$$ = function_symbol ((specifier_t) { .sym = $$ }, ctx);
auto ftype = find_type (parse_params (&type_void, 0));
$$ = function_symbol ((specifier_t) {
.type = ftype,
.sym = $$,
}, ctx);
}
;

View file

@ -291,7 +291,9 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab,
sym->table = nullptr;
}
if (spec.is_typedef || !spec.is_function) {
spec = spec_process (spec, ctx);
}
if (!spec.storage) {
spec.storage = current_storage;
}
@ -307,7 +309,7 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab,
sym->type = find_type (alias_type (sym->type, sym->type, sym->name));
symtab_addsymbol (symtab, sym);
} else {
if (is_func (sym->type)) {
if (spec.is_function) {
if (init) {
error (0, "function %s is initialized", sym->name);
}