diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index 0c9c3cf79..ea6d77f8d 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -174,6 +174,17 @@ symbol_t *symtab_lookup (symtab_t *symtab, const char *name); */ symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol); +/** Append a symbol to the symbol table's symbols. + + The symbol is not checked for duplicate names, nor is it added to the + hash table. + + \param symtab The symol table to which the symbol will be added. + \param symbol The symbol to be added to the symbol table. + \return The symbol as in the table +*/ +symbol_t *symtab_appendsymbol (symtab_t *symtab, symbol_t *symbol); + /** Remove a symbol from the symbol table. \param symtab The symol table from which the symbol will be removed. diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index d88f05c6e..fbe452614 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -126,6 +126,22 @@ symtab_lookup (symtab_t *symtab, const char *name) return 0; } +symbol_t * +symtab_appendsymbol (symtab_t *symtab, symbol_t *symbol) +{ + if (symbol->table) + internal_error (0, "symbol '%s' is already in another symbol table", + symbol->name); + + symbol->next = *symtab->symtail; + *symtab->symtail = symbol; + symtab->symtail = &symbol->next; + + symbol->table = symtab; + + return symbol; +} + symbol_t * symtab_addsymbol (symtab_t *symtab, symbol_t *symbol) { @@ -137,13 +153,7 @@ symtab_addsymbol (symtab_t *symtab, symbol_t *symbol) return s; Hash_Add (symtab->tab, symbol); - symbol->next = *symtab->symtail; - *symtab->symtail = symbol; - symtab->symtail = &symbol->next; - - symbol->table = symtab; - - return symbol; + return symtab_appendsymbol (symtab, symbol); } symbol_t * diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index 40212a5be..abb1e10f4 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -47,22 +47,6 @@ #include "tools/qfcc/include/target.h" #include "tools/qfcc/include/type.h" -static bool -spirv_value_too_large (const type_t *val_type) -{ - return false; -} - -static void -spirv_build_scope (symbol_t *fsym) -{ -} - -target_t spirv_target = { - .value_too_large = spirv_value_too_large, - .build_scope = spirv_build_scope, -}; - typedef struct spirvctx_s { defspace_t *space; defspace_t *linkage; @@ -875,3 +859,56 @@ spirv_set_memory_model (module_t *module, SpvMemoryModel model) { module->memory_model = new_uint_expr (model); } + +static bool +spirv_value_too_large (const type_t *val_type) +{ + return false; +} + +static void +spirv_create_param (symtab_t *parameters, symbol_t *param, param_qual_t qual) +{ + if (!param->name) { + if (qual == pq_out) { + warning (0, "unnamed out parameter"); + } + param->name = save_string (""); + + symtab_appendsymbol (parameters, param); + } else { + symtab_addsymbol (parameters, param); + } + auto type = param->type; + if (qual != pq_const) { + param->lvalue = true; + } + param->type = type; +} + +static void +spirv_build_scope (symbol_t *fsym) +{ + function_t *func = fsym->metafunc->func; + + for (param_t *p = fsym->params; p; p = p->next) { + symbol_t *param; + if (is_void (p->type)) { + if (p->name) { + error (0, "invalid parameter type for %s", p->name); + } else if (p != fsym->params || p->next) { + error (0, "void must be the only parameter"); + continue; + } else { + continue; + } + } + param = new_symbol_type (p->name, p->type); + spirv_create_param (func->parameters, param, p->qual); + } +} + +target_t spirv_target = { + .value_too_large = spirv_value_too_large, + .build_scope = spirv_build_scope, +};