[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.
This commit is contained in:
Bill Currie 2024-11-03 18:03:31 +09:00
parent 88c67b3575
commit 04560f61a6
7 changed files with 66 additions and 29 deletions

View file

@ -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.

View file

@ -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;

View file

@ -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)
{

View file

@ -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 *

View file

@ -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,
};

View file

@ -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,
};

View file

@ -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,
};