mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-06 09:21:01 +00:00
[qfcc] Select correct generic function for references
When the parameter is a reference, implicit casting is not allowed, but when the parameter is by value and the argument is a reference, the argument is dereferenced and promotion is allowed. However, this covers only the selection of generic functions. It doesn't deal with otherwise overloaded functions, nor does it do the actual dereferencing or address taking.
This commit is contained in:
parent
421796b9ea
commit
d72113f5cb
2 changed files with 38 additions and 8 deletions
|
@ -685,7 +685,22 @@ static const type_t * __attribute__((pure))
|
|||
select_type (gentype_t *gentype, const type_t *param_type)
|
||||
{
|
||||
for (auto t = gentype->valid_types; t && *t; t++) {
|
||||
if (*t == param_type || type_promotes (*t, param_type)) {
|
||||
if (*t == param_type) {
|
||||
return *t;
|
||||
}
|
||||
if (is_reference (*t) && dereference_type (*t) == param_type) {
|
||||
// pass value by reference: no promotion
|
||||
return *t;
|
||||
}
|
||||
auto pt = param_type;
|
||||
if (is_reference (pt)) {
|
||||
// pass reference by value: promotion ok
|
||||
pt = dereference_type (pt);
|
||||
}
|
||||
if (*t == pt) {
|
||||
return *t;
|
||||
}
|
||||
if (type_promotes (*t, pt)) {
|
||||
return *t;
|
||||
}
|
||||
}
|
||||
|
@ -695,13 +710,28 @@ 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)
|
||||
{
|
||||
if (type != param_type) {
|
||||
if (type_promotes (type, param_type)) {
|
||||
*cost += 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (!type) {
|
||||
return false;
|
||||
}
|
||||
if (type == param_type) {
|
||||
return true;
|
||||
}
|
||||
if (is_reference (type)) {
|
||||
// pass by references is a free conversion, but no promotion
|
||||
return dereference_type (type) == param_type;
|
||||
}
|
||||
if (is_reference (param_type)) {
|
||||
// dereferencing a reference is free so long as there's no
|
||||
// promotion, otherwise there's the promotion cost
|
||||
param_type = dereference_type (param_type);
|
||||
}
|
||||
if (type == param_type) {
|
||||
return true;
|
||||
}
|
||||
if (!type_promotes (type, param_type)) {
|
||||
return false;
|
||||
}
|
||||
*cost += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1003,7 +1003,7 @@ print_type_str (dstring_t *str, const type_t *type)
|
|||
return;
|
||||
}
|
||||
}
|
||||
dasprintf (str, "(*");
|
||||
dasprintf (str, "(%c", type->fldptr.deref ? '&' : '*');
|
||||
print_type_str (str, type->fldptr.type);
|
||||
dasprintf (str, ")");
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue