[qfcc] Clean up the local_expr global

I never liked it and it made things a little difficult for spir-v.
This commit is contained in:
Bill Currie 2024-11-04 16:31:35 +09:00
parent 5bf9d3c57c
commit 6358143795
19 changed files with 80 additions and 63 deletions

View file

@ -268,9 +268,11 @@ void init_vector_components (struct symbol_s *vector_sym, int is_field,
*/ */
void initialize_def (struct symbol_s *sym, void initialize_def (struct symbol_s *sym,
const struct expr_s *init, struct defspace_s *space, 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. /** Convenience function for obtaining a def's actual offset.

View file

@ -426,8 +426,6 @@ void restore_src_loc (expr_t **e);
__attribute__((cleanup(restore_src_loc))) \ __attribute__((cleanup(restore_src_loc))) \
expr_t *srclocScope = set_src_loc(e) expr_t *srclocScope = set_src_loc(e)
extern expr_t *local_expr;
/** Get the type descriptor of the expression result. /** Get the type descriptor of the expression result.
\param e The expression from which to get the result type. \param e The expression from which to get the result type.

View file

@ -99,7 +99,8 @@ symtab_t *glsl_optimize_attributes (attribute_t *attributes);
void glsl_apply_attributes (symtab_t *attributes, specifier_t spec); void glsl_apply_attributes (symtab_t *attributes, specifier_t spec);
void glsl_parse_declaration (specifier_t spec, symbol_t *sym, 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_declare_field (specifier_t spec, symtab_t *symtab);
void glsl_layout (const ex_list_t *qualifiers, specifier_t spec); void glsl_layout (const ex_list_t *qualifiers, specifier_t spec);

View file

@ -204,7 +204,8 @@ typedef struct language_s {
void (*version) (int version, const char *profile); void (*version) (int version, const char *profile);
bool (*on_include) (const char *name); bool (*on_include) (const char *name);
void (*parse_declaration) (specifier_t spec, symbol_t *sym, 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; void *sublanguage;
} language_t; } language_t;

View file

@ -33,7 +33,6 @@
extern struct function_s *current_func; extern struct function_s *current_func;
extern struct class_type_s *current_class; extern struct class_type_s *current_class;
extern struct expr_s *local_expr;
extern enum vis_e current_visibility; extern enum vis_e current_visibility;
extern enum storage_class_e current_storage; extern enum storage_class_e current_storage;
extern struct symtab_s *current_symtab; extern struct symtab_s *current_symtab;

View file

@ -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 defspace_s *space, enum storage_class_e storage);
struct specifier_s; struct specifier_s;
symbol_t *declare_symbol (struct specifier_s spec, const struct expr_s *init, symbol_t *declare_symbol (struct specifier_s spec, const expr_t *init,
symtab_t *symtab); symtab_t *symtab, expr_t *block);
symbol_t *declare_field (struct specifier_s spec, symtab_t *symtab); symbol_t *declare_field (struct specifier_s spec, symtab_t *symtab);
///@} ///@}

View file

@ -40,7 +40,7 @@ typedef struct {
void (*build_scope) (symbol_t *fsym); void (*build_scope) (symbol_t *fsym);
void (*build_code) (function_t *func, const expr_t *statements); void (*build_code) (function_t *func, const expr_t *statements);
void (*declare_sym) (specifier_t spec, const expr_t *init, void (*declare_sym) (specifier_t spec, const expr_t *init,
symtab_t *symtab); symtab_t *symtab, expr_t *block);
} target_t; } target_t;
extern target_t current_target; extern target_t current_target;

View file

@ -301,7 +301,7 @@ def_to_ddef (def_t *def, ddef_t *ddef, int aux)
} }
static int 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 init_size, int init_offset)
{ {
int zero_size = type_size (zero_type); 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) { for (; init_offset < init_size + 1 - zero_size; init_offset += zero_size) {
dst = new_def_expr (def); dst = new_def_expr (def);
dst = new_offset_alias_expr (zero_type, dst, init_offset); 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; return init_offset;
} }
static void 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 // memset to 0
int init_size = type_size (def->type); int init_size = type_size (def->type);
int init_offset = 0; int init_offset = 0;
if (options.code.progsversion != PROG_ID_VERSION) { 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); init_size, init_offset);
} }
// probably won't happen any time soon, but who knows... // probably won't happen any time soon, but who knows...
if (options.code.progsversion != PROG_ID_VERSION if (options.code.progsversion != PROG_ID_VERSION
&& init_size - init_offset >= type_size (&type_quaternion)) { && 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); init_size, init_offset);
} }
if (init_size - init_offset >= type_size (&type_vector)) { 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); init_size, init_offset);
} }
if (options.code.progsversion != PROG_ID_VERSION if (options.code.progsversion != PROG_ID_VERSION
&& init_size - init_offset >= type_size (&type_double)) { && 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); init_size, init_offset);
} }
if (init_size - init_offset >= type_size (type_default)) { if (init_size - init_offset >= type_size (type_default)) {
zero_memory (local_expr, def, type_default, zero_memory (block, def, type_default, init_size, init_offset);
init_size, init_offset);
} }
} }
// it's a global, so already initialized to 0 // it's a global, so already initialized to 0
} }
static void 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; const expr_t *c;
pr_type_t *g; pr_type_t *g;
@ -360,7 +359,7 @@ init_elements (struct def_s *def, const expr_t *eles)
element_t *element; element_t *element;
if (eles->type == ex_nil) { if (eles->type == ex_nil) {
init_elements_nil (def); init_elements_nil (def, block);
return; return;
} }
@ -368,9 +367,9 @@ init_elements (struct def_s *def, const expr_t *eles)
element_chain.tail = &element_chain.head; element_chain.tail = &element_chain.head;
build_element_chain (&element_chain, def->type, eles, 0); 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); expr_t *dst = new_def_expr (def);
assign_elements (local_expr, dst, &element_chain); assign_elements (block, dst, &element_chain);
} else { } else {
def_t dummy = *def; def_t dummy = *def;
for (element = element_chain.head; element; element = element->next) { for (element = element_chain.head; element; element = element->next) {
@ -408,7 +407,7 @@ init_elements (struct def_s *def, const expr_t *eles)
continue; continue;
} }
} else { } else {
if (!def->local || !local_expr) { if (!def->local || !block) {
error (c, "non-constant initializer"); error (c, "non-constant initializer");
continue; continue;
} }
@ -545,7 +544,7 @@ num_elements (const expr_t *e)
void void
initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, 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); symbol_t *check = symtab_lookup (symtab, sym->name);
reloc_t *relocs = 0; reloc_t *relocs = 0;
@ -616,7 +615,7 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space,
return; return;
if ((is_structural (sym->type) || is_nonscalar (sym->type)) if ((is_structural (sym->type) || is_nonscalar (sym->type))
&& (init->type == ex_compound || init->type == ex_nil)) { && (init->type == ex_compound || init->type == ex_nil)) {
init_elements (sym->def, init); init_elements (sym->def, init, block);
sym->def->initialized = 1; sym->def->initialized = 1;
} else { } else {
if (init->type == ex_nil) { 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)); get_type_string (sym->type), get_type_string (init_type));
return; return;
} }
if (storage == sc_local && local_expr) { if (storage == sc_local && block) {
sym->def->initialized = 1; sym->def->initialized = 1;
init = assign_expr (new_symbol_expr (sym), init); init = assign_expr (new_symbol_expr (sym), init);
// fold_constants takes care of int/float conversions // 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)) { } else if (is_constexpr (init)) {
init = assign_expr (new_symbol_expr (sym), init); init = assign_expr (new_symbol_expr (sym), init);
add_ctor_expr (init); add_ctor_expr (init);
@ -683,7 +682,8 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space,
} }
void 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; symbol_t *sym = spec.sym;
defspace_t *space = symtab->space; 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; space = pr.near_data;
} }
initialize_def (sym, init, space, spec.storage, symtab); initialize_def (sym, init, space, spec.storage, symtab, block);
if (sym->def) { if (sym->def) {
sym->def->nosave |= spec.nosave; sym->def->nosave |= spec.nosave;
} }

View file

@ -155,8 +155,8 @@ super_expr (class_type_t *class_type)
sym = symtab_lookup (current_symtab, ".super"); sym = symtab_lookup (current_symtab, ".super");
if (!sym || sym->table != current_symtab) { if (!sym || sym->table != current_symtab) {
sym = new_symbol_type (".super", &type_super); sym = new_symbol_type (".super", &type_super);
initialize_def (sym, 0, current_symtab->space, sc_local, initialize_def (sym, nullptr, current_symtab->space, sc_local,
current_symtab); current_symtab, nullptr);
} }
super = new_symbol_expr (sym); super = new_symbol_expr (sym);

View file

@ -228,9 +228,10 @@ proc_return (const expr_t *expr)
static const expr_t * static const expr_t *
proc_decl (const expr_t *expr) proc_decl (const expr_t *expr)
{ {
expr_t *block = nullptr;
if (expr->decl.spec.storage == sc_local) { if (expr->decl.spec.storage == sc_local) {
scoped_src_loc (expr); scoped_src_loc (expr);
local_expr = new_block_expr (nullptr); block = new_block_expr (nullptr);
} }
int count = list_count (&expr->decl.list); int count = list_count (&expr->decl.list);
const expr_t *decls[count + 1]; const expr_t *decls[count + 1];
@ -258,10 +259,9 @@ proc_decl (const expr_t *expr)
spec.type = find_type (spec.type); spec.type = find_type (spec.type);
sym->type = nullptr; 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; return block;
} }

View file

@ -176,7 +176,7 @@ glsl_declare_block_instance (glsl_block_t *block, symbol_t *instance_name)
auto space = current_symtab->space;// FIXME auto space = current_symtab->space;// FIXME
initialize_def (instance_name, nullptr, space, initialize_def (instance_name, nullptr, space,
glsl_sc_from_iftype (block->interface), glsl_sc_from_iftype (block->interface),
current_symtab); current_symtab, nullptr);
} else { } else {
auto block_sym = symtab_lookup (interface, block->name->name); auto block_sym = symtab_lookup (interface, block->name->name);
if (block_sym) { if (block_sym) {

View file

@ -42,8 +42,8 @@
#include "tools/qfcc/include/type.h" #include "tools/qfcc/include/type.h"
void void
glsl_parse_declaration (specifier_t spec, symbol_t *sym, glsl_parse_declaration (specifier_t spec, symbol_t *sym, const expr_t *init,
const expr_t *init, symtab_t *symtab) symtab_t *symtab, expr_t *block)
{ {
if (sym->type) { if (sym->type) {
internal_error (0, "unexected typed symbol"); 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"); internal_error (id_list, "not a symbol");
} }
spec.sym = id->expr->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); glsl_apply_attributes (attributes, spec);
} }
} else { } else {
@ -103,7 +103,7 @@ glsl_parse_declaration (specifier_t spec, symbol_t *sym,
} }
symtab_addsymbol (symtab, sym); symtab_addsymbol (symtab, sym);
} else { } else {
spec.sym = declare_symbol (spec, init, symtab); spec.sym = declare_symbol (spec, init, symtab, block);
} }
} }
glsl_apply_attributes (attributes, spec); glsl_apply_attributes (attributes, spec);

View file

@ -619,7 +619,7 @@ declaration
| type_qualifier ';' | type_qualifier ';'
{ {
glsl_parse_declaration ($type_qualifier, nullptr, glsl_parse_declaration ($type_qualifier, nullptr,
nullptr, current_symtab); nullptr, current_symtab, nullptr);
$$ = nullptr; $$ = nullptr;
} }
| type_qualifier new_identifier ';' | type_qualifier new_identifier ';'
@ -1150,10 +1150,8 @@ condition
: expression : expression
| fully_specified_type new_identifier '=' initializer | fully_specified_type new_identifier '=' initializer
{ {
auto symtab = current_symtab; auto decl = new_decl_expr ($fully_specified_type);
auto space = symtab->space; $$ = append_decl (decl, $new_identifier, $initializer);
auto storage = current_storage;
initialize_def ($2, $initializer, space, storage, symtab);
} }
; ;

View file

@ -248,6 +248,7 @@ static const expr_t *break_label;
static const expr_t *continue_label; static const expr_t *continue_label;
static bool generic_scope, generic_block; static bool generic_scope, generic_block;
static symtab_t *generic_symtab; static symtab_t *generic_symtab;
static expr_t *local_expr;
static void static void
end_generic_scope (void) end_generic_scope (void)
@ -828,12 +829,12 @@ qc_nocode_func
specifier_t spec = qc_set_symbol ($<spec>0, $1); specifier_t spec = qc_set_symbol ($<spec>0, $1);
const expr_t *expr = $3; const expr_t *expr = $3;
declare_symbol (spec, expr, current_symtab); declare_symbol (spec, expr, current_symtab, local_expr);
} }
| identifier | identifier
{ {
specifier_t spec = qc_set_symbol ($<spec>0, $1); specifier_t spec = qc_set_symbol ($<spec>0, $1);
declare_symbol (spec, nullptr, current_symtab); declare_symbol (spec, nullptr, current_symtab, local_expr);
} }
; ;
@ -937,9 +938,9 @@ initdecls
initdecl initdecl
: declarator '=' var_initializer : declarator '=' var_initializer
{ declare_symbol ($1, $3, current_symtab); } { declare_symbol ($1, $3, current_symtab, local_expr); }
| declarator | declarator
{ declare_symbol ($1, 0, current_symtab); } { declare_symbol ($1, 0, current_symtab, local_expr); }
; ;
notype_initdecls notype_initdecls
@ -949,9 +950,9 @@ notype_initdecls
notype_initdecl notype_initdecl
: notype_declarator '=' var_initializer : notype_declarator '=' var_initializer
{ declare_symbol ($1, $3, current_symtab); } { declare_symbol ($1, $3, current_symtab, local_expr); }
| notype_declarator | notype_declarator
{ declare_symbol ($1, 0, current_symtab); } { declare_symbol ($1, 0, current_symtab, local_expr); }
; ;
/* various lists of type specifiers, storage class etc */ /* various lists of type specifiers, storage class etc */

View file

@ -191,7 +191,7 @@ function_value (function_t *func)
if (!ret || ret->table != func->locals) { if (!ret || ret->table != func->locals) {
ret = new_symbol_type (".ret", func->type->func.ret_type); ret = new_symbol_type (".ret", func->type->func.ret_type);
initialize_def (ret, 0, func->locals->space, sc_local, initialize_def (ret, 0, func->locals->space, sc_local,
func->locals); func->locals, nullptr);
} }
} }
return ret; return ret;
@ -245,7 +245,7 @@ program_head
symbol_t *sym = new_symbol ("ExitCode"); symbol_t *sym = new_symbol ("ExitCode");
sym->type = &type_int; sym->type = &type_int;
initialize_def (sym, 0, current_symtab->space, sc_global, initialize_def (sym, 0, current_symtab->space, sc_global,
current_symtab); current_symtab, nullptr);
if (sym->def) { if (sym->def) {
sym->def->nosave = 1; sym->def->nosave = 1;
} }
@ -281,7 +281,7 @@ declarations
symbol_t *next = $3->next; symbol_t *next = $3->next;
$3->type = $5; $3->type = $5;
initialize_def ($3, 0, current_symtab->space, current_storage, initialize_def ($3, 0, current_symtab->space, current_storage,
current_symtab); current_symtab, nullptr);
$3 = next; $3 = next;
} }
} }

View file

@ -349,7 +349,7 @@ build_switch (expr_t *sw, case_node_t *tree, int op, const expr_t *sw_val,
array_type (&type_int, array_type (&type_int,
high - low + 1)); high - low + 1));
initialize_def (table_sym, table_init, pr.near_data, sc_static, initialize_def (table_sym, table_init, pr.near_data, sc_static,
current_symtab); current_symtab, nullptr);
table_expr = new_symbol_expr (table_sym); table_expr = new_symbol_expr (table_sym);
if (tree->left) { if (tree->left) {

View file

@ -269,7 +269,8 @@ shadows_param (symbol_t *sym, symtab_t *symtab)
} }
symbol_t * 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; 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)) { if (!shadows_param (sym, symtab)) {
sym->type = find_type (sym->type); sym->type = find_type (sym->type);
spec.sym = sym; spec.sym = sym;
current_target.declare_sym (spec, init, symtab); current_target.declare_sym (spec, init, symtab, block);
} }
} }
} }

View file

@ -1078,7 +1078,8 @@ spirv_build_code (function_t *func, const expr_t *statements)
} }
static void 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 *sym = spec.sym;
symbol_t *check = symtab_lookup (symtab, sym->name); 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); sym->type = reference_type (sym->type);
} }
symtab_addsymbol (symtab, sym); 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 = { target_t spirv_target = {

View file

@ -59,7 +59,8 @@ v6p_build_scope (symbol_t *fsym)
if (func->type->func.num_params < 0) { if (func->type->func.num_params < 0) {
args = new_symbol_type (".args", &type_va_list); 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) { for (p = fsym->params, i = 0; p; p = p->next) {
@ -72,7 +73,8 @@ v6p_build_scope (symbol_t *fsym)
p->name = save_string (""); p->name = save_string ("");
} }
param = new_symbol_type (p->name, p->type); 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) { if (p->qual == pq_out) {
param->def->param = false; param->def->param = false;
param->def->out_param = true; param->def->out_param = true;
@ -87,7 +89,8 @@ v6p_build_scope (symbol_t *fsym)
if (args) { if (args) {
while (i < PR_MAX_PARAMS) { while (i < PR_MAX_PARAMS) {
param = new_symbol_type (va (0, ".par%d", i), &type_param); 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++; i++;
} }
} }