X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=81e1c121231e16bbb9bdde2c92cf72ec642fda1b;hb=121e0806979160e9236cd6cc6173fe76db3f2349;hp=50396538a32cba1d1a0e4f699bfd3c80d20a9afc;hpb=db6ca6c5f8abb2272c9f72bd820fd650bed0783a;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index 5039653..81e1c12 100644 --- a/ast.c +++ b/ast.c @@ -1104,6 +1104,7 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype) self->varargs = NULL; self->argc = NULL; self->fixedparams = NULL; + self->return_value = NULL; return self; } @@ -1133,6 +1134,8 @@ void ast_function_delete(ast_function *self) ast_delete(self->argc); if (self->fixedparams) ast_unref(self->fixedparams); + if (self->return_value) + ast_unref(self->return_value); mem_d(self); } @@ -1625,6 +1628,12 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) return true; } + /* have a local return value variable? */ + if (self->return_value) { + if (!ast_local_codegen(self->return_value, self->ir_func, false)) + return false; + } + if (!vec_size(self->blocks)) { compile_error(ast_ctx(self), "function `%s` has no body", self->name); return false; @@ -1676,8 +1685,13 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir) } else if (vec_size(self->curblock->entries) || self->curblock == irf->first) { - /* error("missing return"); */ - if (compile_warning(ast_ctx(self), WARN_MISSING_RETURN_VALUES, + if (self->return_value) { + cgen = self->return_value->expression.codegen; + if (!(*cgen)((ast_expression*)(self->return_value), self, false, &dummy)) + return false; + return ir_block_create_return(self->curblock, ast_ctx(self), dummy); + } + else if (compile_warning(ast_ctx(self), WARN_MISSING_RETURN_VALUES, "control reaches end of non-void function (`%s`) via %s", self->name, self->curblock->label)) {