[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.
This commit is contained in:
Bill Currie 2024-10-01 16:51:49 +09:00
parent 3af078628e
commit f73e1bf353
5 changed files with 31 additions and 12 deletions

View file

@ -220,6 +220,9 @@ function_t *build_builtin_function (symbol_t *sym,
void emit_function (function_t *f, expr_t *e); void emit_function (function_t *f, expr_t *e);
void clear_functions (void); void clear_functions (void);
void add_ctor_expr (const expr_t *expr);
void emit_ctor (void);
///@} ///@}
#endif//__function_h #endif//__function_h

View file

@ -80,6 +80,8 @@ typedef struct pr_info_s {
struct symtab_s *symtab; struct symtab_s *symtab;
struct symtab_s *entity_fields; struct symtab_s *entity_fields;
struct expr_s *ctor_exprs;
srcline_t *srcline_stack; srcline_t *srcline_stack;
rua_loc_t loc; rua_loc_t loc;
int error_count; int error_count;

View file

@ -1612,8 +1612,6 @@ class_finish_module (void)
symbol_t *module_sym; symbol_t *module_sym;
pr_module_t *module; pr_module_t *module;
symbol_t *exec_class_sym; symbol_t *exec_class_sym;
symbol_t *init_sym;
expr_t *init_expr;
data.refs = emit_selectors (); data.refs = emit_selectors ();
if (class_hash) { if (class_hash) {
@ -1660,20 +1658,12 @@ class_finish_module (void)
sc_extern); sc_extern);
} }
init_sym = new_symbol_type (".ctor", &type_func);
init_sym = function_symbol ((specifier_t) { .sym = init_sym });
const expr_t *module_expr; const expr_t *module_expr;
module_expr = address_expr (new_symbol_expr (module_sym), 0); module_expr = address_expr (new_symbol_expr (module_sym), 0);
module_expr = new_list_expr (module_expr); module_expr = new_list_expr (module_expr);
init_expr = new_block_expr (0); add_ctor_expr (build_function_call (new_symbol_expr (exec_class_sym),
append_expr (init_expr, exec_class_sym->type, module_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);
} }
protocol_t * protocol_t *

View file

@ -1443,3 +1443,25 @@ clear_functions (void)
function_map = Hash_NewTable (1021, metafunc_get_name, 0, 0, 0); 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);
}

View file

@ -409,6 +409,7 @@ compile_to_obj (const char *file, const char *obj, language_t *lang)
err = lang->finish (file); err = lang->finish (file);
} }
if (!err) { if (!err) {
emit_ctor ();
debug_finish_module (obj); debug_finish_module (obj);
} }
err = pr.error_count; err = pr.error_count;
@ -838,6 +839,7 @@ progs_src_compile (void)
} }
class_finish_module (); class_finish_module ();
emit_ctor ();
debug_finish_module (options.output_file); debug_finish_module (options.output_file);
qfo = qfo_from_progs (&pr); qfo = qfo_from_progs (&pr);
if (options.compile) { if (options.compile) {