From f73e1bf3538806536763b1b00b24c33236738d87 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 1 Oct 2024 16:51:49 +0900 Subject: [PATCH] [qfcc] Move ctor creation out of class_finish_module Now, ctor expressions are collected and emitted after all other code, and the ctor function being created outside of class_finish_module means it's no longer limited to just class related initialization. --- tools/qfcc/include/function.h | 3 +++ tools/qfcc/include/qfcc.h | 2 ++ tools/qfcc/source/class.c | 14 ++------------ tools/qfcc/source/function.c | 22 ++++++++++++++++++++++ tools/qfcc/source/qfcc.c | 2 ++ 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/tools/qfcc/include/function.h b/tools/qfcc/include/function.h index 1d2324865..408178283 100644 --- a/tools/qfcc/include/function.h +++ b/tools/qfcc/include/function.h @@ -220,6 +220,9 @@ function_t *build_builtin_function (symbol_t *sym, void emit_function (function_t *f, expr_t *e); void clear_functions (void); +void add_ctor_expr (const expr_t *expr); +void emit_ctor (void); + ///@} #endif//__function_h diff --git a/tools/qfcc/include/qfcc.h b/tools/qfcc/include/qfcc.h index 0f5cf8a3d..33681fe70 100644 --- a/tools/qfcc/include/qfcc.h +++ b/tools/qfcc/include/qfcc.h @@ -80,6 +80,8 @@ typedef struct pr_info_s { struct symtab_s *symtab; struct symtab_s *entity_fields; + struct expr_s *ctor_exprs; + srcline_t *srcline_stack; rua_loc_t loc; int error_count; diff --git a/tools/qfcc/source/class.c b/tools/qfcc/source/class.c index a96105726..b2346ea53 100644 --- a/tools/qfcc/source/class.c +++ b/tools/qfcc/source/class.c @@ -1612,8 +1612,6 @@ class_finish_module (void) symbol_t *module_sym; pr_module_t *module; symbol_t *exec_class_sym; - symbol_t *init_sym; - expr_t *init_expr; data.refs = emit_selectors (); if (class_hash) { @@ -1660,20 +1658,12 @@ class_finish_module (void) sc_extern); } - init_sym = new_symbol_type (".ctor", &type_func); - init_sym = function_symbol ((specifier_t) { .sym = init_sym }); - const expr_t *module_expr; module_expr = address_expr (new_symbol_expr (module_sym), 0); module_expr = new_list_expr (module_expr); - init_expr = new_block_expr (0); - append_expr (init_expr, - build_function_call (new_symbol_expr (exec_class_sym), - exec_class_sym->type, module_expr)); - - current_func = begin_function (init_sym, 0, current_symtab, 1, sc_static); - build_code_function (init_sym, 0, init_expr); + add_ctor_expr (build_function_call (new_symbol_expr (exec_class_sym), + exec_class_sym->type, module_expr)); } protocol_t * diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 634712bd5..f91562943 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -1443,3 +1443,25 @@ clear_functions (void) function_map = Hash_NewTable (1021, metafunc_get_name, 0, 0, 0); } } + +void +add_ctor_expr (const expr_t *expr) +{ + if (!pr.ctor_exprs) { + pr.ctor_exprs = new_block_expr (nullptr); + } + append_expr (pr.ctor_exprs, expr); +} + +void +emit_ctor (void) +{ + if (!pr.ctor_exprs) { + return; + } + + auto ctor_sym = new_symbol_type (".ctor", &type_func); + ctor_sym = function_symbol ((specifier_t) { .sym = ctor_sym }); + current_func = begin_function (ctor_sym, 0, current_symtab, 1, sc_static); + build_code_function (ctor_sym, 0, pr.ctor_exprs); +} diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index 34a3b0af9..0376e38a6 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -409,6 +409,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang) err = lang->finish (file); } if (!err) { + emit_ctor (); debug_finish_module (obj); } err = pr.error_count; @@ -838,6 +839,7 @@ progs_src_compile (void) } class_finish_module (); + emit_ctor (); debug_finish_module (options.output_file); qfo = qfo_from_progs (&pr); if (options.compile) {