[qfcc] Improve reference param and arg handling

In particular, type matching for overloads/generics and correct handling
for inline/intrinsic functions.
This commit is contained in:
Bill Currie 2025-01-21 22:41:42 +09:00
parent da6c5129eb
commit 198821f0d3
2 changed files with 12 additions and 5 deletions

View file

@ -170,7 +170,7 @@ check_arg_types (const expr_t **arguments, const type_t **arg_types,
err = param_mismatch (e, i + 1, fexpr->symbol->name,
t, param_type);
}
} else {
} else if (!is_reference (param_type)) {
if (!type_assignable (param_type, t)) {
err = param_mismatch (e, i + 1, fexpr->symbol->name,
param_type, t);
@ -236,7 +236,14 @@ build_call_scope (symbol_t *fsym, const expr_t **arguments)
}
auto psym = new_symbol (p->name);
psym->sy_type = sy_expr;
psym->expr = arguments[i];
auto arg_type = get_type (arguments[i]);
if (is_reference (p->type) && !is_reference (arg_type)) {
psym->expr = address_expr (arguments[i], nullptr);
} else if (!is_reference (p->type) && is_reference (arg_type)) {
psym->expr = pointer_deref (arguments[i]);
} else {
psym->expr = arguments[i];
}
symtab_addsymbol (params, psym);
}
}

View file

@ -604,19 +604,19 @@ check_type (const type_t *type, callparm_t param, unsigned *cost, bool promote)
if (!type) {
return false;
}
if (type == param.type) {
if (type_same (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;
return type_same (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) {
if (type_same (type, param.type)) {
return true;
}
int ret = obj_types_assignable (type, param.type);