From bec8b290d27b6fb3963634ca522a641c733f83d7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 3 Jan 2025 17:52:19 +0900 Subject: [PATCH] [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). --- tools/qfcc/include/specifier.h | 1 + tools/qfcc/source/class.c | 4 ++-- tools/qfcc/source/expr.c | 10 +++++++--- tools/qfcc/source/function.c | 14 +++++++------- tools/qfcc/source/method.c | 10 ++++++---- tools/qfcc/source/qc-parse.y | 1 + tools/qfcc/source/qp-parse.y | 26 ++++++++++++++++---------- tools/qfcc/source/symtab.c | 6 ++++-- 8 files changed, 44 insertions(+), 28 deletions(-) diff --git a/tools/qfcc/include/specifier.h b/tools/qfcc/include/specifier.h index 4082eed80..87a9b69b2 100644 --- a/tools/qfcc/include/specifier.h +++ b/tools/qfcc/include/specifier.h @@ -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; diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index 704efbdd8..b80bfad46 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -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, diff --git a/tools/qfcc/source/expr.c b/tools/qfcc/source/expr.c index cea7eab7e..cac6c51c1 100644 --- a/tools/qfcc/source/expr.c +++ b/tools/qfcc/source/expr.c @@ -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); } diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 91f2d77bc..cff82f1ba 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -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); - } + 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, }; diff --git a/tools/qfcc/source/method.c b/tools/qfcc/source/method.c index 5a1c5bb0c..d0fb116e7 100644 --- a/tools/qfcc/source/method.c +++ b/tools/qfcc/source/method.c @@ -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; } diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index c2853908c..dc8541836 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -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); } diff --git a/tools/qfcc/source/qp-parse.y b/tools/qfcc/source/qp-parse.y index f476cc5e3..572ffe813 100644 --- a/tools/qfcc/source/qp-parse.y +++ b/tools/qfcc/source/qp-parse.y @@ -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); } ; diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index ad8894b1f..3fbb45da0 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -291,7 +291,9 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab, sym->table = nullptr; } - spec = spec_process (spec, ctx); + 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); }