[qfcc] Deal with generic types in prototypes

Mostly avoiding segfaults or mistreating type expressions as the default
type.
This commit is contained in:
Bill Currie 2024-05-31 13:51:38 +09:00
parent 8da8bd9917
commit a655e6cef3
2 changed files with 23 additions and 10 deletions

View file

@ -349,10 +349,12 @@ function_spec (specifier_t spec, param_t *params)
if (!spec.sym) {
spec.sym = new_symbol (0);
}
spec = default_type (spec, spec.sym);
if (!spec.type_expr) {
spec = default_type (spec, spec.sym);
}
spec.sym->params = params;
spec.sym->type = append_type (spec.sym->type, parse_params (0, params));
spec.is_function = 1; //FIXME do proper void(*)() -> ev_func
spec.is_function = true; //FIXME do proper void(*)() -> ev_func
return spec;
}
@ -671,11 +673,16 @@ qc_nocode_func
| identifier '=' expr
{
specifier_t spec = $<spec>0;
spec.sym = $1;
spec.sym->params = spec.params;
spec.sym->type = find_type (spec.type);
spec.is_function = 0;
declare_symbol (spec, $3, current_symtab);
symbol_t *sym = $1;
const expr_t *expr = $3;
sym->params = spec.sym->params;
sym = function_sym_type (spec, sym);
sym = function_symbol (sym, spec);
spec.sym = sym;
spec.type = sym->type;
spec.is_function = false;
sym->type = nullptr;
declare_symbol (spec, expr, current_symtab);
}
| identifier
{

View file

@ -264,7 +264,9 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab)
s = new_symbol (s->name);
}
spec = default_type (spec, s);
if (!spec.type_expr && !spec.is_function) {
spec = default_type (spec, s);
}
if (!spec.storage) {
spec.storage = current_storage;
}
@ -272,7 +274,9 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab)
space = pr.near_data;
}
s->type = append_type (spec.sym->type, spec.type);
if (spec.type) {
s->type = append_type (spec.sym->type, spec.type);
}
//FIXME is_function is bad (this whole implementation of handling
//function prototypes is bad)
if (spec.is_function && is_func (s->type)) {
@ -292,7 +296,9 @@ declare_symbol (specifier_t spec, const expr_t *init, symtab_t *symtab)
if (init) {
error (0, "function %s is initialized", s->name);
}
s->type = find_type (s->type);
if (!spec.type_expr) {
s->type = find_type (s->type);
}
s = function_symbol (s, spec);
} else {
s->type = find_type (s->type);