From 04560f61a6a2a54920b3c28db55766b7d9a0dec7 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 3 Nov 2024 18:03:31 +0900 Subject: [PATCH] [qfcc] Separate out backend variable declaration This time, rua/v6p/v6 share the code properly, since it's only spirv that needs something specific at this stage. --- tools/qfcc/include/def.h | 2 ++ tools/qfcc/include/target.h | 4 +++ tools/qfcc/source/def.c | 20 ++++++++--- tools/qfcc/source/symtab.c | 60 +++++++++++++++++++------------- tools/qfcc/source/target_rua.c | 1 + tools/qfcc/source/target_spirv.c | 6 ++++ tools/qfcc/source/target_v6.c | 2 ++ 7 files changed, 66 insertions(+), 29 deletions(-) diff --git a/tools/qfcc/include/def.h b/tools/qfcc/include/def.h index 28e023c88..8cadf0756 100644 --- a/tools/qfcc/include/def.h +++ b/tools/qfcc/include/def.h @@ -270,6 +270,8 @@ void initialize_def (struct symbol_s *sym, const struct expr_s *init, struct defspace_s *space, storage_class_t storage, struct symtab_s *symtab); +void declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab); + /** Convenience function for obtaining a def's actual offset. Takes care of an alias def's relative offset. diff --git a/tools/qfcc/include/target.h b/tools/qfcc/include/target.h index 3bd0a8c9a..bb666db7f 100644 --- a/tools/qfcc/include/target.h +++ b/tools/qfcc/include/target.h @@ -29,14 +29,18 @@ #define __target_h typedef struct symbol_s symbol_t; +typedef struct symtab_s symtab_t; typedef struct type_s type_t; typedef struct function_s function_t; typedef struct expr_s expr_t; +typedef struct specifier_s specifier_t; typedef struct { bool (*value_too_large) (const type_t *val_type); 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); } target_t; extern target_t current_target; diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c index e966d356c..08bb4f9cf 100644 --- a/tools/qfcc/source/def.c +++ b/tools/qfcc/source/def.c @@ -550,10 +550,6 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, symbol_t *check = symtab_lookup (symtab, sym->name); reloc_t *relocs = 0; - if (check && check->table == symtab->parent - && symtab->parent->type == stab_param) { - error (0, "%s shadows a parameter", sym->name); - } if (check && check->table == symtab) { if (check->sy_type != sy_def || !type_same (check->type, sym->type)) { error (0, "%s redefined", sym->name); @@ -686,6 +682,22 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space, sym->def->initializer = init; } +void +declare_def (specifier_t spec, const expr_t *init, symtab_t *symtab) +{ + symbol_t *sym = spec.sym; + defspace_t *space = symtab->space; + + if (spec.storage == sc_static) { + space = pr.near_data; + } + + initialize_def (sym, init, space, spec.storage, symtab); + if (sym->def) { + sym->def->nosave |= spec.nosave; + } +} + static int def_overlap (def_t *d, int offset, int size) { diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index fbe452614..bb7164ede 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -47,6 +47,7 @@ #include "tools/qfcc/include/shared.h" #include "tools/qfcc/include/strpool.h" #include "tools/qfcc/include/symtab.h" +#include "tools/qfcc/include/target.h" #include "tools/qfcc/include/type.h" ALLOC_STATE (symtab_t, symtabs); @@ -254,57 +255,66 @@ make_symbol (const char *name, const type_t *type, defspace_t *space, return sym; } +static bool +shadows_param (symbol_t *sym, symtab_t *symtab) +{ + symbol_t *check = symtab_lookup (symtab, sym->name); + + if (check && check->table == symtab->parent + && symtab->parent->type == stab_param) { + error (0, "%s shadows a parameter", sym->name); + return true; + } + return false; +} + symbol_t * declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab) { - symbol_t *s = spec.sym; - defspace_t *space = symtab->space; + symbol_t *sym = spec.sym; - if (s->table) { + if (sym->table) { // due to the way declarations work, we need a new symbol at all times. // redelcarations will be checked later - s = new_symbol (s->name); - *s = *spec.sym; - s->table = nullptr; + sym = new_symbol (sym->name); + *sym = *spec.sym; + sym->table = nullptr; } if (!spec.type_expr && !spec.is_function) { - spec = default_type (spec, s); + spec = default_type (spec, sym); } if (!spec.storage) { spec.storage = current_storage; } - if (spec.storage == sc_static) { - space = pr.near_data; - } - if (spec.type && (spec.is_typedef || !s->type || !is_func (s->type))) { - s->type = append_type (spec.sym->type, spec.type); + if (spec.type && (spec.is_typedef || !sym->type || !is_func (sym->type))) { + sym->type = append_type (spec.sym->type, spec.type); } if (spec.is_typedef) { if (init) { - error (0, "typedef %s is initialized", s->name); + error (0, "typedef %s is initialized", sym->name); } - s->sy_type = sy_type; - s->type = find_type (s->type); - s->type = find_type (alias_type (s->type, s->type, s->name)); - symtab_addsymbol (symtab, s); + sym->sy_type = sy_type; + sym->type = find_type (sym->type); + sym->type = find_type (alias_type (sym->type, sym->type, sym->name)); + symtab_addsymbol (symtab, sym); } else { - if (spec.is_function && is_func (s->type)) { + if (spec.is_function && is_func (sym->type)) { if (init) { - error (0, "function %s is initialized", s->name); + error (0, "function %s is initialized", sym->name); } - s = function_symbol (spec); + sym = function_symbol (spec); } else { - s->type = find_type (s->type); - initialize_def (s, init, space, spec.storage, symtab); - if (s->def) { - s->def->nosave |= spec.nosave; + if (!shadows_param (sym, symtab)) { + sym->type = find_type (sym->type); + spec.sym = sym; + current_target.declare_sym (spec, init, symtab); } } } - return s; + return sym; } symbol_t * diff --git a/tools/qfcc/source/target_rua.c b/tools/qfcc/source/target_rua.c index 295ac8747..740bd98c1 100644 --- a/tools/qfcc/source/target_rua.c +++ b/tools/qfcc/source/target_rua.c @@ -209,4 +209,5 @@ target_t ruamoko_target = { .value_too_large = ruamoko_value_too_large, .build_scope = ruamoko_build_scope, .build_code = ruamoko_build_code, + .declare_sym = declare_def, }; diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index 26ff2baac..ba4ad561c 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -918,8 +918,14 @@ 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) +{ +} + target_t spirv_target = { .value_too_large = spirv_value_too_large, .build_scope = spirv_build_scope, .build_code = spirv_build_code, + .declare_sym = spirv_declare_sym, }; diff --git a/tools/qfcc/source/target_v6.c b/tools/qfcc/source/target_v6.c index bf003c064..2d53612bf 100644 --- a/tools/qfcc/source/target_v6.c +++ b/tools/qfcc/source/target_v6.c @@ -132,10 +132,12 @@ target_t v6_target = { .value_too_large = v6_value_too_large, .build_scope = v6p_build_scope, .build_code = v6p_build_code, + .declare_sym = declare_def, }; target_t v6p_target = { .value_too_large = v6_value_too_large, .build_scope = v6p_build_scope, .build_code = v6p_build_code, + .declare_sym = declare_def, };