mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Return a metafunc for generic functions
One step closer to getting this idea to work.
This commit is contained in:
parent
67c380e98d
commit
d9e2108b91
1 changed files with 32 additions and 23 deletions
|
@ -89,14 +89,14 @@ gen_func_get_key (const void *_f, void *unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
ol_func_get_key (const void *_f, void *unused)
|
metafunc_get_full_name (const void *_f, void *unused)
|
||||||
{
|
{
|
||||||
metafunc_t *f = (metafunc_t *) _f;
|
metafunc_t *f = (metafunc_t *) _f;
|
||||||
return f->full_name;
|
return f->full_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
func_map_get_key (const void *_f, void *unused)
|
metafunc_get_name (const void *_f, void *unused)
|
||||||
{
|
{
|
||||||
metafunc_t *f = (metafunc_t *) _f;
|
metafunc_t *f = (metafunc_t *) _f;
|
||||||
return f->name;
|
return f->name;
|
||||||
|
@ -507,20 +507,31 @@ check_params (param_t *params)
|
||||||
static metafunc_t *
|
static metafunc_t *
|
||||||
get_function (const char *name, const type_t *type, specifier_t spec)
|
get_function (const char *name, const type_t *type, specifier_t spec)
|
||||||
{
|
{
|
||||||
auto genfunc = parse_generic_function (name, spec);
|
metafunc_t *func = Hash_Find (function_map, name);
|
||||||
|
|
||||||
|
auto genfunc = parse_generic_function (name, spec);
|
||||||
//FIXME want to be able to provide specific overloads for generic functions
|
//FIXME want to be able to provide specific overloads for generic functions
|
||||||
//but need to figure out details, so disallow for now.
|
//but need to figure out details, so disallow for now.
|
||||||
if (genfunc) {
|
if (genfunc) {
|
||||||
if (Hash_Find (function_map, name)) {
|
if (func && func->meta_type != mf_generic) {
|
||||||
error (0, "can't mix generic and overload");
|
error (0, "can't mix generic and simple or overload");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
add_generic_function (genfunc);
|
add_generic_function (genfunc);
|
||||||
return nullptr;// FIXME
|
|
||||||
|
ALLOC (1024, metafunc_t, metafuncs, func);
|
||||||
|
*func = (metafunc_t) {
|
||||||
|
.name = save_string (name),
|
||||||
|
.full_name = name,
|
||||||
|
.loc = pr.loc,
|
||||||
|
.meta_type = mf_generic,
|
||||||
|
};
|
||||||
|
Hash_Add (metafuncs, func);
|
||||||
|
Hash_Add (function_map, func);
|
||||||
|
return func;
|
||||||
}
|
}
|
||||||
if (Hash_Find (generic_functions, name)) {
|
if (func && func->meta_type == mf_generic) {
|
||||||
error (0, "can't mix generic and overload");
|
error (0, "can't mix generic and simple or overload");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,7 +540,6 @@ get_function (const char *name, const type_t *type, specifier_t spec)
|
||||||
|
|
||||||
full_name = save_string (va (0, "%s|%s", name, encode_params (type)));
|
full_name = save_string (va (0, "%s|%s", name, encode_params (type)));
|
||||||
|
|
||||||
metafunc_t *func;
|
|
||||||
// check if the exact function signature already exists, in which case
|
// check if the exact function signature already exists, in which case
|
||||||
// simply return it.
|
// simply return it.
|
||||||
func = Hash_Find (metafuncs, full_name);
|
func = Hash_Find (metafuncs, full_name);
|
||||||
|
@ -899,12 +909,14 @@ check_function (symbol_t *fsym)
|
||||||
param_t *params = fsym->params;
|
param_t *params = fsym->params;
|
||||||
param_t *p;
|
param_t *p;
|
||||||
int i;
|
int i;
|
||||||
|
auto ret_type = fsym->type->func.ret_type;
|
||||||
|
|
||||||
if (!type_size (fsym->type->func.ret_type)) {
|
if (!ret_type || !type_size (ret_type)) {
|
||||||
error (0, "return type is an incomplete type");
|
error (0, "return type is an incomplete type");
|
||||||
//fsym->type->func.type = &type_void;//FIXME better type?
|
return;
|
||||||
|
//fsym->type->t.func.type = &type_void;//FIXME better type?
|
||||||
}
|
}
|
||||||
if (value_too_large (fsym->type->func.ret_type)) {
|
if (value_too_large (ret_type)) {
|
||||||
error (0, "return value too large to be passed by value (%d)",
|
error (0, "return value too large to be passed by value (%d)",
|
||||||
type_size (&type_param));
|
type_size (&type_param));
|
||||||
//fsym->type->func.type = &type_void;//FIXME better type?
|
//fsym->type->func.type = &type_void;//FIXME better type?
|
||||||
|
@ -1089,8 +1101,6 @@ function_t *
|
||||||
begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
|
begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
|
||||||
int far, storage_class_t storage)
|
int far, storage_class_t storage)
|
||||||
{
|
{
|
||||||
defspace_t *space;
|
|
||||||
|
|
||||||
if (sym->sy_type != sy_func) {
|
if (sym->sy_type != sy_func) {
|
||||||
error (0, "%s is not a function", sym->name);
|
error (0, "%s is not a function", sym->name);
|
||||||
sym = new_symbol_type (sym->name, &type_func);
|
sym = new_symbol_type (sym->name, &type_func);
|
||||||
|
@ -1101,9 +1111,9 @@ begin_function (symbol_t *sym, const char *nicename, symtab_t *parent,
|
||||||
sym = new_symbol_type (sym->name, sym->type);
|
sym = new_symbol_type (sym->name, sym->type);
|
||||||
sym = function_symbol (sym, (specifier_t) { .is_overload = true });
|
sym = function_symbol (sym, (specifier_t) { .is_overload = true });
|
||||||
}
|
}
|
||||||
space = sym->table->space;
|
|
||||||
if (far)
|
defspace_t *space = far ? pr.far_data : sym->table->space;
|
||||||
space = pr.far_data;
|
|
||||||
make_function (sym, nicename, space, storage);
|
make_function (sym, nicename, space, storage);
|
||||||
if (!sym->func->def->external) {
|
if (!sym->func->def->external) {
|
||||||
sym->func->def->initialized = 1;
|
sym->func->def->initialized = 1;
|
||||||
|
@ -1263,7 +1273,6 @@ build_builtin_function (symbol_t *sym, const expr_t *bi_val, int far,
|
||||||
storage_class_t storage)
|
storage_class_t storage)
|
||||||
{
|
{
|
||||||
int bi;
|
int bi;
|
||||||
defspace_t *space;
|
|
||||||
|
|
||||||
if (sym->sy_type != sy_func) {
|
if (sym->sy_type != sy_func) {
|
||||||
error (bi_val, "%s is not a function", sym->name);
|
error (bi_val, "%s is not a function", sym->name);
|
||||||
|
@ -1277,10 +1286,10 @@ build_builtin_function (symbol_t *sym, const expr_t *bi_val, int far,
|
||||||
error (bi_val, "invalid constant for = #");
|
error (bi_val, "invalid constant for = #");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
space = sym->table->space;
|
|
||||||
if (far)
|
defspace_t *space = far ? pr.far_data : sym->table->space;
|
||||||
space = pr.far_data;
|
|
||||||
make_function (sym, 0, space, storage);
|
make_function (sym, 0, space, storage);
|
||||||
|
|
||||||
if (sym->func->def->external)
|
if (sym->func->def->external)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1333,7 +1342,7 @@ clear_functions (void)
|
||||||
Hash_FlushTable (function_map);
|
Hash_FlushTable (function_map);
|
||||||
} else {
|
} else {
|
||||||
generic_functions = Hash_NewTable (1021, gen_func_get_key, 0, 0, 0);
|
generic_functions = Hash_NewTable (1021, gen_func_get_key, 0, 0, 0);
|
||||||
metafuncs = Hash_NewTable (1021, ol_func_get_key, 0, 0, 0);
|
metafuncs = Hash_NewTable (1021, metafunc_get_full_name, 0, 0, 0);
|
||||||
function_map = Hash_NewTable (1021, func_map_get_key, 0, 0, 0);
|
function_map = Hash_NewTable (1021, metafunc_get_name, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue