[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_overload:1;
bool is_generic:1; bool is_generic:1;
bool is_generic_block:1; bool is_generic_block:1;
bool is_function:1;
bool is_far:1; bool is_far:1;
}; };
unsigned spec_bits; 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"); exec_class_sym = symtab_lookup (pr.symtab, "__obj_exec_class");
if (!exec_class_sym) { if (!exec_class_sym) {
exec_class_sym = new_symbol_type ("__obj_exec_class", exec_class_sym = new_symbol ("__obj_exec_class");
&type_exec_class);
exec_class_sym = function_symbol ((specifier_t) { exec_class_sym = function_symbol ((specifier_t) {
.type = &type_exec_class,
.sym = exec_class_sym .sym = exec_class_sym
}, ctx); }, ctx);
make_function (exec_class_sym, 0, exec_class_sym->table->space, 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) think_expr (symbol_t *think_sym, rua_ctx_t *ctx)
{ {
symbol_t *sym; symbol_t *sym;
const type_t *type;
if (think_sym->table) if (think_sym->table)
return new_symbol_expr (think_sym); 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 if (sym && sym->sy_type == sy_def && sym->type
&& sym->type->type == ev_field && sym->type->type == ev_field
&& sym->type->fldptr.type->type == ev_func) { && sym->type->fldptr.type->type == ev_func) {
think_sym->type = sym->type->fldptr.type; type = sym->type->fldptr.type;
} else { } 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); make_function (think_sym, 0, current_symtab->space, current_storage);
return new_symbol_expr (think_sym); 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 * static metafunc_t *
get_function (const char *name, specifier_t spec, rua_ctx_t *ctx) 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 = spec_process (spec, ctx);
spec.sym->type = spec.type; spec.sym->type = spec.type;
set_func_attrs (spec.sym->type, spec.attributes); set_func_attrs (spec.sym->type, spec.attributes);
spec.sym->type = find_type (spec.sym->type); spec.sym->type = find_type (spec.sym->type);
}
auto type = unalias_type (spec.sym->type); auto type = unalias_type (spec.sym->type);
int num_params = type->func.num_params; int num_params = type->func.num_params;
if (num_params < 0) { if (num_params < 0) {
@ -1401,7 +1400,8 @@ emit_ctor (rua_ctx_t *ctx)
} }
auto spec = (specifier_t) { auto spec = (specifier_t) {
.sym = new_symbol_type (".ctor", &type_func), .type = &type_func,
.sym = new_symbol (".ctor"),
.storage = sc_static, .storage = sc_static,
.is_far = true, .is_far = true,
}; };

View file

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

View file

@ -422,6 +422,7 @@ function_spec (specifier_t spec, param_t *parameters)
if (spec.type_list) { if (spec.type_list) {
expr_append_expr (spec.type_list, type_expr); expr_append_expr (spec.type_list, type_expr);
} else { } else {
spec.is_function = true;
spec.type_list = new_list_expr (type_expr); 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 *code;
expr_t *exitcode; expr_t *exitcode;
dotmain->params = 0; auto dmtype = find_type (parse_params (&type_int, 0));
dotmain->type = parse_params (&type_int, 0); dotmain = function_symbol ((specifier_t) {
dotmain->type = find_type (dotmain->type); .type = dmtype,
dotmain = function_symbol ((specifier_t) { .sym = dotmain }, ctx); .sym = dotmain,
}, ctx);
exitcode = new_symbol_expr (symtab_lookup (current_symtab, "ExitCode")); 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 // use `@name` so `main` can be used (`.main` is reserved for the entry
// point) // point)
auto fsym = new_symbol (va (0, "@%s", sym->name)); auto fsym = new_symbol (va (0, "@%s", sym->name));
fsym->type = parse_params (ret_type, params); auto ftype = find_type (parse_params (ret_type, params));
fsym->type = find_type (fsym->type); fsym = function_symbol ((specifier_t) {
fsym = function_symbol ((specifier_t) {.sym = fsym, .params = params}, ctx); .type = ftype,
.sym = fsym,
.params = params
}, ctx);
auto fsym_expr = new_symbol_expr (fsym); auto fsym_expr = new_symbol_expr (fsym);
if (!params) { if (!params) {
fsym_expr = new_call_expr (fsym_expr, nullptr, nullptr); fsym_expr = new_call_expr (fsym_expr, nullptr, nullptr);
@ -314,9 +318,11 @@ program_head
sym->def->nosave = 1; sym->def->nosave = 1;
} }
} }
$$->type = parse_params (&type_void, 0); auto ftype = find_type (parse_params (&type_void, 0));
$$->type = find_type ($$->type); $$ = function_symbol ((specifier_t) {
$$ = function_symbol ((specifier_t) { .sym = $$ }, ctx); .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; sym->table = nullptr;
} }
if (spec.is_typedef || !spec.is_function) {
spec = spec_process (spec, ctx); spec = spec_process (spec, ctx);
}
if (!spec.storage) { if (!spec.storage) {
spec.storage = current_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)); sym->type = find_type (alias_type (sym->type, sym->type, sym->name));
symtab_addsymbol (symtab, sym); symtab_addsymbol (symtab, sym);
} else { } else {
if (is_func (sym->type)) { if (spec.is_function) {
if (init) { if (init) {
error (0, "function %s is initialized", sym->name); error (0, "function %s is initialized", sym->name);
} }