From 635814379527e1c6985fe72691db9095c2553e15 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 4 Nov 2024 16:31:35 +0900 Subject: [PATCH] [qfcc] Clean up the local_expr global I never liked it and it made things a little difficult for spir-v. --- tools/qfcc/include/def.h | 6 ++-- tools/qfcc/include/expr.h | 2 -- tools/qfcc/include/glsl-lang.h | 3 +- tools/qfcc/include/rua-lang.h | 3 +- tools/qfcc/include/shared.h | 1 - tools/qfcc/include/symtab.h | 4 +-- tools/qfcc/include/target.h | 2 +- tools/qfcc/source/def.c | 42 ++++++++++++++-------------- tools/qfcc/source/expr_obj.c | 4 +-- tools/qfcc/source/expr_process.c | 8 +++--- tools/qfcc/source/glsl-block.c | 2 +- tools/qfcc/source/glsl-declaration.c | 8 +++--- tools/qfcc/source/glsl-parse.y | 8 ++---- tools/qfcc/source/qc-parse.y | 13 +++++---- tools/qfcc/source/qp-parse.y | 6 ++-- tools/qfcc/source/switch.c | 2 +- tools/qfcc/source/symtab.c | 5 ++-- tools/qfcc/source/target_spirv.c | 15 +++++++++- tools/qfcc/source/target_v6.c | 9 ++++-- 19 files changed, 80 insertions(+), 63 deletions(-) diff --git a/tools/qfcc/include/def.h b/tools/qfcc/include/def.h index 8cadf0756..8dd8223a0 100644 --- a/tools/qfcc/include/def.h +++ b/tools/qfcc/include/def.h @@ -268,9 +268,11 @@ void init_vector_components (struct symbol_s *vector_sym, int is_field, */ void initialize_def (struct symbol_s *sym, const struct expr_s *init, struct defspace_s *space, - storage_class_t storage, struct symtab_s *symtab); + storage_class_t storage, struct symtab_s *symtab, + expr_t *block); -void declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab); +void declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab, + expr_t *block); /** Convenience function for obtaining a def's actual offset. diff --git a/tools/qfcc/include/expr.h b/tools/qfcc/include/expr.h index e0a5aeed6..5657c2c58 100644 --- a/tools/qfcc/include/expr.h +++ b/tools/qfcc/include/expr.h @@ -426,8 +426,6 @@ void restore_src_loc (expr_t **e); __attribute__((cleanup(restore_src_loc))) \ expr_t *srclocScope = set_src_loc(e) -extern expr_t *local_expr; - /** Get the type descriptor of the expression result. \param e The expression from which to get the result type. diff --git a/tools/qfcc/include/glsl-lang.h b/tools/qfcc/include/glsl-lang.h index cc5710c10..5f8381609 100644 --- a/tools/qfcc/include/glsl-lang.h +++ b/tools/qfcc/include/glsl-lang.h @@ -99,7 +99,8 @@ symtab_t *glsl_optimize_attributes (attribute_t *attributes); void glsl_apply_attributes (symtab_t *attributes, specifier_t spec); void glsl_parse_declaration (specifier_t spec, symbol_t *sym, - const expr_t *init, symtab_t *symtab); + const expr_t *init, symtab_t *symtab, + expr_t *block); void glsl_declare_field (specifier_t spec, symtab_t *symtab); void glsl_layout (const ex_list_t *qualifiers, specifier_t spec); diff --git a/tools/qfcc/include/rua-lang.h b/tools/qfcc/include/rua-lang.h index 18ee0a2e8..dc2f5a7e0 100644 --- a/tools/qfcc/include/rua-lang.h +++ b/tools/qfcc/include/rua-lang.h @@ -204,7 +204,8 @@ typedef struct language_s { void (*version) (int version, const char *profile); bool (*on_include) (const char *name); void (*parse_declaration) (specifier_t spec, symbol_t *sym, - const expr_t *init, symtab_t *symtab); + const expr_t *init, symtab_t *symtab, + expr_t *block); void *sublanguage; } language_t; diff --git a/tools/qfcc/include/shared.h b/tools/qfcc/include/shared.h index 102f31b44..f43e0ec14 100644 --- a/tools/qfcc/include/shared.h +++ b/tools/qfcc/include/shared.h @@ -33,7 +33,6 @@ extern struct function_s *current_func; extern struct class_type_s *current_class; -extern struct expr_s *local_expr; extern enum vis_e current_visibility; extern enum storage_class_e current_storage; extern struct symtab_s *current_symtab; diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index ea6d77f8d..4ab955e5a 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -269,8 +269,8 @@ symbol_t *make_symbol (const char *name, const struct type_s *type, struct defspace_s *space, enum storage_class_e storage); struct specifier_s; -symbol_t *declare_symbol (struct specifier_s spec, const struct expr_s *init, - symtab_t *symtab); +symbol_t *declare_symbol (struct specifier_s spec, const expr_t *init, + symtab_t *symtab, expr_t *block); symbol_t *declare_field (struct specifier_s spec, symtab_t *symtab); ///@} diff --git a/tools/qfcc/include/target.h b/tools/qfcc/include/target.h index bb666db7f..7602ba210 100644 --- a/tools/qfcc/include/target.h +++ b/tools/qfcc/include/target.h @@ -40,7 +40,7 @@ typedef struct { void (*build_scope) (symbol_t *fsym); void (*build_code) (function_t *func, const expr_t *statements); void (*declare_sym) (specifier_t spec, const expr_t *init, - symtab_t *symtab); + symtab_t *symtab, expr_t *block); } target_t; extern target_t current_target; diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index 08bb4f9cf..a3814e3d8 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -301,7 +301,7 @@ def_to_ddef (def_t *def, ddef_t *ddef, int aux) } static int -zero_memory (expr_t *local_expr, def_t *def, type_t *zero_type, +zero_memory (expr_t *block, def_t *def, type_t *zero_type, int init_size, int init_offset) { int zero_size = type_size (zero_type); @@ -311,48 +311,47 @@ zero_memory (expr_t *local_expr, def_t *def, type_t *zero_type, for (; init_offset < init_size + 1 - zero_size; init_offset += zero_size) { dst = new_def_expr (def); dst = new_offset_alias_expr (zero_type, dst, init_offset); - append_expr (local_expr, assign_expr (dst, zero)); + append_expr (block, assign_expr (dst, zero)); } return init_offset; } static void -init_elements_nil (def_t *def) +init_elements_nil (def_t *def, expr_t *block) { - if (def->local && local_expr) { + if (def->local && block) { // memset to 0 int init_size = type_size (def->type); int init_offset = 0; if (options.code.progsversion != PROG_ID_VERSION) { - init_offset = zero_memory (local_expr, def, &type_zero, + init_offset = zero_memory (block, def, &type_zero, init_size, init_offset); } // probably won't happen any time soon, but who knows... if (options.code.progsversion != PROG_ID_VERSION && init_size - init_offset >= type_size (&type_quaternion)) { - init_offset = zero_memory (local_expr, def, &type_quaternion, + init_offset = zero_memory (block, def, &type_quaternion, init_size, init_offset); } if (init_size - init_offset >= type_size (&type_vector)) { - init_offset = zero_memory (local_expr, def, &type_vector, + init_offset = zero_memory (block, def, &type_vector, init_size, init_offset); } if (options.code.progsversion != PROG_ID_VERSION && init_size - init_offset >= type_size (&type_double)) { - init_offset = zero_memory (local_expr, def, &type_double, + init_offset = zero_memory (block, def, &type_double, init_size, init_offset); } if (init_size - init_offset >= type_size (type_default)) { - zero_memory (local_expr, def, type_default, - init_size, init_offset); + zero_memory (block, def, type_default, init_size, init_offset); } } // it's a global, so already initialized to 0 } static void -init_elements (struct def_s *def, const expr_t *eles) +init_elements (struct def_s *def, const expr_t *eles, expr_t *block) { const expr_t *c; pr_type_t *g; @@ -360,7 +359,7 @@ init_elements (struct def_s *def, const expr_t *eles) element_t *element; if (eles->type == ex_nil) { - init_elements_nil (def); + init_elements_nil (def, block); return; } @@ -368,9 +367,9 @@ init_elements (struct def_s *def, const expr_t *eles) element_chain.tail = &element_chain.head; build_element_chain (&element_chain, def->type, eles, 0); - if (def->local && local_expr) { + if (def->local && block) { expr_t *dst = new_def_expr (def); - assign_elements (local_expr, dst, &element_chain); + assign_elements (block, dst, &element_chain); } else { def_t dummy = *def; for (element = element_chain.head; element; element = element->next) { @@ -408,7 +407,7 @@ init_elements (struct def_s *def, const expr_t *eles) continue; } } else { - if (!def->local || !local_expr) { + if (!def->local || !block) { error (c, "non-constant initializer"); continue; } @@ -545,7 +544,7 @@ num_elements (const expr_t *e) void initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, - storage_class_t storage, symtab_t *symtab) + storage_class_t storage, symtab_t *symtab, expr_t *block) { symbol_t *check = symtab_lookup (symtab, sym->name); reloc_t *relocs = 0; @@ -616,7 +615,7 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, return; if ((is_structural (sym->type) || is_nonscalar (sym->type)) && (init->type == ex_compound || init->type == ex_nil)) { - init_elements (sym->def, init); + init_elements (sym->def, init, block); sym->def->initialized = 1; } else { if (init->type == ex_nil) { @@ -628,11 +627,11 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, get_type_string (sym->type), get_type_string (init_type)); return; } - if (storage == sc_local && local_expr) { + if (storage == sc_local && block) { sym->def->initialized = 1; init = assign_expr (new_symbol_expr (sym), init); // fold_constants takes care of int/float conversions - append_expr (local_expr, fold_constants (init)); + append_expr (block, fold_constants (init)); } else if (is_constexpr (init)) { init = assign_expr (new_symbol_expr (sym), init); add_ctor_expr (init); @@ -683,7 +682,8 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, } void -declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab) +declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab, + expr_t *block) { symbol_t *sym = spec.sym; defspace_t *space = symtab->space; @@ -692,7 +692,7 @@ declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab) space = pr.near_data; } - initialize_def (sym, init, space, spec.storage, symtab); + initialize_def (sym, init, space, spec.storage, symtab, block); if (sym->def) { sym->def->nosave |= spec.nosave; } diff --git a/tools/qfcc/source/expr_obj.c b/tools/qfcc/source/expr_obj.c index 4adfdd860..43e8dd172 100644 --- a/tools/qfcc/source/expr_obj.c +++ b/tools/qfcc/source/expr_obj.c @@ -155,8 +155,8 @@ super_expr (class_type_t *class_type) sym = symtab_lookup (current_symtab, ".super"); if (!sym || sym->table != current_symtab) { sym = new_symbol_type (".super", &type_super); - initialize_def (sym, 0, current_symtab->space, sc_local, - current_symtab); + initialize_def (sym, nullptr, current_symtab->space, sc_local, + current_symtab, nullptr); } super = new_symbol_expr (sym); diff --git a/tools/qfcc/source/expr_process.c b/tools/qfcc/source/expr_process.c index c304b48bd..a36813bb0 100644 --- a/tools/qfcc/source/expr_process.c +++ b/tools/qfcc/source/expr_process.c @@ -228,9 +228,10 @@ proc_return (const expr_t *expr) static const expr_t * proc_decl (const expr_t *expr) { + expr_t *block = nullptr; if (expr->decl.spec.storage == sc_local) { scoped_src_loc (expr); - local_expr = new_block_expr (nullptr); + block = new_block_expr (nullptr); } int count = list_count (&expr->decl.list); const expr_t *decls[count + 1]; @@ -258,10 +259,9 @@ proc_decl (const expr_t *expr) spec.type = find_type (spec.type); sym->type = nullptr; } - current_language.parse_declaration (spec, sym, init, current_symtab); + current_language.parse_declaration (spec, sym, init, current_symtab, + block); } - auto block = local_expr; - local_expr = nullptr; return block; } diff --git a/tools/qfcc/source/glsl-block.c b/tools/qfcc/source/glsl-block.c index 564649c7b..da733d7ef 100644 --- a/tools/qfcc/source/glsl-block.c +++ b/tools/qfcc/source/glsl-block.c @@ -176,7 +176,7 @@ glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name) auto space = current_symtab->space;// FIXME initialize_def (instance_name, nullptr, space, glsl_sc_from_iftype (block->interface), - current_symtab); + current_symtab, nullptr); } else { auto block_sym = symtab_lookup (interface, block->name->name); if (block_sym) { diff --git a/tools/qfcc/source/glsl-declaration.c b/tools/qfcc/source/glsl-declaration.c index 96bea9edc..28384101e 100644 --- a/tools/qfcc/source/glsl-declaration.c +++ b/tools/qfcc/source/glsl-declaration.c @@ -42,8 +42,8 @@ #include "tools/qfcc/include/type.h" void -glsl_parse_declaration (specifier_t spec, symbol_t *sym, - const expr_t *init, symtab_t *symtab) +glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init, + symtab_t *symtab, expr_t *block) { if (sym->type) { internal_error (0, "unexected typed symbol"); @@ -65,7 +65,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, internal_error (id_list, "not a symbol"); } spec.sym = id->expr->symbol; - spec.sym = declare_symbol (spec, init, symtab); + spec.sym = declare_symbol (spec, init, symtab, block); glsl_apply_attributes (attributes, spec); } } else { @@ -103,7 +103,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym, } symtab_addsymbol (symtab, sym); } else { - spec.sym = declare_symbol (spec, init, symtab); + spec.sym = declare_symbol (spec, init, symtab, block); } } glsl_apply_attributes (attributes, spec); diff --git a/tools/qfcc/source/glsl-parse.y b/tools/qfcc/source/glsl-parse.y index dea88022e..dd3e98df7 100644 --- a/tools/qfcc/source/glsl-parse.y +++ b/tools/qfcc/source/glsl-parse.y @@ -619,7 +619,7 @@ declaration | type_qualifier ';' { glsl_parse_declaration ($type_qualifier, nullptr, - nullptr, current_symtab); + nullptr, current_symtab, nullptr); $$ = nullptr; } | type_qualifier new_identifier ';' @@ -1150,10 +1150,8 @@ condition : expression | fully_specified_type new_identifier '=' initializer { - auto symtab = current_symtab; - auto space = symtab->space; - auto storage = current_storage; - initialize_def ($2, $initializer, space, storage, symtab); + auto decl = new_decl_expr ($fully_specified_type); + $$ = append_decl (decl, $new_identifier, $initializer); } ; diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index 51421c51c..bd2bda035 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -248,6 +248,7 @@ static const expr_t *break_label; static const expr_t *continue_label; static bool generic_scope, generic_block; static symtab_t *generic_symtab; +static expr_t *local_expr; static void end_generic_scope (void) @@ -828,12 +829,12 @@ qc_nocode_func specifier_t spec = qc_set_symbol ($0, $1); const expr_t *expr = $3; - declare_symbol (spec, expr, current_symtab); + declare_symbol (spec, expr, current_symtab, local_expr); } | identifier { specifier_t spec = qc_set_symbol ($0, $1); - declare_symbol (spec, nullptr, current_symtab); + declare_symbol (spec, nullptr, current_symtab, local_expr); } ; @@ -937,9 +938,9 @@ initdecls initdecl : declarator '=' var_initializer - { declare_symbol ($1, $3, current_symtab); } + { declare_symbol ($1, $3, current_symtab, local_expr); } | declarator - { declare_symbol ($1, 0, current_symtab); } + { declare_symbol ($1, 0, current_symtab, local_expr); } ; notype_initdecls @@ -949,9 +950,9 @@ notype_initdecls notype_initdecl : notype_declarator '=' var_initializer - { declare_symbol ($1, $3, current_symtab); } + { declare_symbol ($1, $3, current_symtab, local_expr); } | notype_declarator - { declare_symbol ($1, 0, current_symtab); } + { declare_symbol ($1, 0, current_symtab, local_expr); } ; /* various lists of type specifiers, storage class etc */ diff --git a/tools/qfcc/source/qp-parse.y b/tools/qfcc/source/qp-parse.y index eb16b1720..e2cdf7929 100644 --- a/tools/qfcc/source/qp-parse.y +++ b/tools/qfcc/source/qp-parse.y @@ -191,7 +191,7 @@ function_value (function_t *func) if (!ret || ret->table != func->locals) { ret = new_symbol_type (".ret", func->type->func.ret_type); initialize_def (ret, 0, func->locals->space, sc_local, - func->locals); + func->locals, nullptr); } } return ret; @@ -245,7 +245,7 @@ program_head symbol_t *sym = new_symbol ("ExitCode"); sym->type = &type_int; initialize_def (sym, 0, current_symtab->space, sc_global, - current_symtab); + current_symtab, nullptr); if (sym->def) { sym->def->nosave = 1; } @@ -281,7 +281,7 @@ declarations symbol_t *next = $3->next; $3->type = $5; initialize_def ($3, 0, current_symtab->space, current_storage, - current_symtab); + current_symtab, nullptr); $3 = next; } } diff --git a/tools/qfcc/source/switch.c b/tools/qfcc/source/switch.c index d1d18bdd9..dd26d7155 100644 --- a/tools/qfcc/source/switch.c +++ b/tools/qfcc/source/switch.c @@ -349,7 +349,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, const expr_t *sw_val, array_type (&type_int, high - low + 1)); initialize_def (table_sym, table_init, pr.near_data, sc_static, - current_symtab); + current_symtab, nullptr); table_expr = new_symbol_expr (table_sym); if (tree->left) { diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index bb7164ede..57f932860 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -269,7 +269,8 @@ shadows_param (symbol_t *sym, symtab_t *symtab) } symbol_t * -declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab) +declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab, + expr_t *block) { symbol_t *sym = spec.sym; @@ -310,7 +311,7 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab) if (!shadows_param (sym, symtab)) { sym->type = find_type (sym->type); spec.sym = sym; - current_target.declare_sym (spec, init, symtab); + current_target.declare_sym (spec, init, symtab, block); } } } diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index d4586a398..ca15bd2bd 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -1078,7 +1078,8 @@ spirv_build_code (function_t *func, const expr_t *statements) } static void -spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab) +spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab, + expr_t *block) { symbol_t *sym = spec.sym; symbol_t *check = symtab_lookup (symtab, sym->name); @@ -1090,6 +1091,18 @@ spirv_declare_sym (specifier_t spec, const expr_t *init, symtab_t *symtab) sym->type = reference_type (sym->type); } symtab_addsymbol (symtab, sym); + if (symtab->type == stab_local) { + if (init) { + if (is_constexpr (init)) { + } else if (block) { + auto r = pointer_deref (new_symbol_expr (sym)); + auto e = assign_expr (r, init); + append_expr (block, e); + } else { + error (init, "non-constant initializer"); + } + } + } } target_t spirv_target = { diff --git a/tools/qfcc/source/target_v6.c b/tools/qfcc/source/target_v6.c index 2d53612bf..cac0b0f40 100644 --- a/tools/qfcc/source/target_v6.c +++ b/tools/qfcc/source/target_v6.c @@ -59,7 +59,8 @@ v6p_build_scope (symbol_t *fsym) if (func->type->func.num_params < 0) { args = new_symbol_type (".args", &type_va_list); - initialize_def (args, 0, parameters->space, sc_param, locals); + initialize_def (args, nullptr, parameters->space, sc_param, locals, + nullptr); } for (p = fsym->params, i = 0; p; p = p->next) { @@ -72,7 +73,8 @@ v6p_build_scope (symbol_t *fsym) p->name = save_string (""); } param = new_symbol_type (p->name, p->type); - initialize_def (param, 0, parameters->space, sc_param, locals); + initialize_def (param, nullptr, parameters->space, sc_param, locals, + nullptr); if (p->qual == pq_out) { param->def->param = false; param->def->out_param = true; @@ -87,7 +89,8 @@ v6p_build_scope (symbol_t *fsym) if (args) { while (i < PR_MAX_PARAMS) { param = new_symbol_type (va (0, ".par%d", i), &type_param); - initialize_def (param, 0, parameters->space, sc_param, locals); + initialize_def (param, nullptr, parameters->space, sc_param, + locals, nullptr); i++; } }