[qfcc] Handle return in inline functions

The code is pretty lousy in that it assumes there's only one `return`
and it's the end of the function, and the generated code is even worse
(too many load/store ops in the spir-v), but it looks like it at least
works. It does pass validation.
This commit is contained in:
Bill Currie 2024-12-12 11:08:30 +09:00
parent 21eed88da5
commit 626680f22f
3 changed files with 33 additions and 0 deletions

View file

@ -155,6 +155,10 @@ typedef struct function_s {
int pseudo_addr;///< pseudo address space for flow analysis
struct pseudoop_s *pseudo_ops;///< pseudo operands used by this function
const expr_t *exprs;
const expr_t *(*return_imp) (function_t *func, const expr_t *val);
const expr_t *return_val;
const expr_t *return_label;
} function_t;
/** Represent an overloading of a function.

View file

@ -223,6 +223,25 @@ build_intrinsic_call (const expr_t *expr, const type_t *ftype,
return call;
}
static const expr_t *
inline_return_expr (function_t *func, const expr_t *val)
{
if (!func->return_val && val) {
return error (val, "returning a value for a void function");
}
if (func->return_val && !val) {
return error (val, "return from non-void function without a value");
}
auto ret = new_block_expr (nullptr);
if (val) {
append_expr (ret, assign_expr (func->return_val, val));
}
if (func->return_label) {
append_expr (ret, goto_expr (func->return_label));
}
return ret;
}
static expr_t *
build_inline_call (symbol_t *fsym, const type_t *ftype,
const expr_t **arguments, int arg_count)
@ -278,12 +297,19 @@ build_inline_call (symbol_t *fsym, const type_t *ftype,
append_expr (call, decl);
call->block.result = new_symbol_expr (ret);
}
func->return_val = call->block.result;
auto expr = metafunc->expr;
if (expr->type == ex_block) {
expr->block.scope->parent = locals;
}
append_expr (call, expr);
func->return_label = nullptr;//new_label_expr ();
//append_expr (call, func->return_label);
func->return_imp = inline_return_expr;
auto proc = new_process_expr (call);
proc->process.function = func;

View file

@ -511,6 +511,9 @@ proc_return (const expr_t *expr, rua_ctx_t *ctx)
if (ret_val) {
ret_val = expr_process (ret_val, ctx);
}
if (current_func->return_imp) {
return current_func->return_imp (current_func, ret_val);
}
if (expr->retrn.at_return) {
return at_return_expr (current_func, ret_val);
} else {