mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 05:01:24 +00:00
[qfcc] Split up find_generic_function
I want to reuse its generic function search for defining implementations.
This commit is contained in:
parent
1893df34a3
commit
980dd913b5
1 changed files with 29 additions and 13 deletions
|
@ -717,7 +717,7 @@ select_type (gentype_t *gentype, const type_t *param_type)
|
|||
}
|
||||
|
||||
static bool
|
||||
check_type (const type_t *type, const type_t *param_type, unsigned *cost)
|
||||
check_type (const type_t *type, const type_t *param_type, unsigned *cost, bool promote)
|
||||
{
|
||||
if (!type) {
|
||||
return false;
|
||||
|
@ -737,16 +737,16 @@ check_type (const type_t *type, const type_t *param_type, unsigned *cost)
|
|||
if (type == param_type) {
|
||||
return true;
|
||||
}
|
||||
if (!type_promotes (type, param_type)) {
|
||||
if (!promote || !type_promotes (type, param_type)) {
|
||||
return false;
|
||||
}
|
||||
*cost += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const expr_t *
|
||||
find_generic_function (const expr_t *fexpr, genfunc_t **genfuncs,
|
||||
const type_t *call_type)
|
||||
static genfunc_t *
|
||||
find_generic_function (genfunc_t **genfuncs, const expr_t *fexpr,
|
||||
const type_t *call_type, bool promote)
|
||||
{
|
||||
int num_funcs = 0;
|
||||
for (auto gf = genfuncs; *gf; gf++, num_funcs++) continue;
|
||||
|
@ -768,9 +768,11 @@ find_generic_function (const expr_t *fexpr, genfunc_t **genfuncs,
|
|||
if (!types[ind]) {
|
||||
types[ind] = select_type (&g->types[ind], call_params[i]);
|
||||
}
|
||||
ok &= check_type (types[ind], call_params[i], costs + j);
|
||||
ok &= check_type (types[ind], call_params[i], costs + j,
|
||||
promote);
|
||||
} else {
|
||||
ok &= check_type (p->fixed_type, call_params[i], costs + j);
|
||||
ok &= check_type (p->fixed_type, call_params[i], costs + j,
|
||||
promote);
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
|
@ -783,7 +785,8 @@ find_generic_function (const expr_t *fexpr, genfunc_t **genfuncs,
|
|||
int best_ind = -1;
|
||||
for (int i = 0; i < num_funcs; i++) {
|
||||
if (best_ind >= 0 && costs[i] == best_cost) {
|
||||
return error (fexpr, "unable to disambiguate %s", fsym->name);
|
||||
error (fexpr, "unable to disambiguate %s", fsym->name);
|
||||
return nullptr;
|
||||
}
|
||||
if (costs[i] < best_cost) {
|
||||
best_ind = i;
|
||||
|
@ -791,11 +794,19 @@ find_generic_function (const expr_t *fexpr, genfunc_t **genfuncs,
|
|||
}
|
||||
}
|
||||
if (best_ind < 0) {
|
||||
return error (fexpr, "unable to find generic function matching %s",
|
||||
fsym->name);
|
||||
error (fexpr, "unable to find generic function matching %s",
|
||||
fsym->name);
|
||||
return nullptr;
|
||||
}
|
||||
return genfuncs[best_ind];
|
||||
}
|
||||
|
||||
auto g = genfuncs[best_ind];
|
||||
static symbol_t *
|
||||
create_generic_sym (genfunc_t *g, const expr_t *fexpr, const type_t *call_type)
|
||||
{
|
||||
auto fsym = fexpr->symbol;
|
||||
int num_params = call_type->func.num_params;
|
||||
auto call_params = call_type->func.param_types;
|
||||
const type_t *types[g->num_types] = {};
|
||||
const type_t *param_types[num_params];
|
||||
param_qual_t param_quals[num_params];
|
||||
|
@ -856,7 +867,7 @@ find_generic_function (const expr_t *fexpr, genfunc_t **genfuncs,
|
|||
*sym->metafunc = *fsym->metafunc;
|
||||
symtab_addsymbol (fsym->table, sym);
|
||||
}
|
||||
return new_symbol_expr (sym);
|
||||
return sym;
|
||||
}
|
||||
|
||||
const expr_t *
|
||||
|
@ -901,7 +912,12 @@ find_function (const expr_t *fexpr, const expr_t *params)
|
|||
const char *fname = fexpr->symbol->name;
|
||||
auto genfuncs = (genfunc_t **) Hash_FindList (generic_functions, fname);
|
||||
if (genfuncs) {
|
||||
return find_generic_function (fexpr, genfuncs, &call_type);
|
||||
auto gen = find_generic_function (genfuncs, fexpr, &call_type, true);
|
||||
if (!gen) {
|
||||
return new_error_expr ();
|
||||
}
|
||||
auto sym = create_generic_sym (gen, fexpr, &call_type);
|
||||
return new_symbol_expr (sym);
|
||||
}
|
||||
|
||||
auto funcs = (metafunc_t **) Hash_FindList (function_map, fname);
|
||||
|
|
Loading…
Reference in a new issue