]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
Merge branch 'cooking'
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index 01a08e5966072e3222a283c337483a718f453ed0..d845eb24a5db26dfd94e962bf198f2657efada26 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -21,7 +21,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -1101,9 +1100,10 @@ ast_function* ast_function_new(lex_ctx ctx, const char *name, ast_value *vtype)
     vtype->hasvalue = true;
     vtype->constval.vfunc = self;
 
-    self->varargs     = NULL;
-    self->argc        = NULL;
-    self->fixedparams = NULL;
+    self->varargs          = NULL;
+    self->argc             = NULL;
+    self->fixedparams      = NULL;
+    self->return_value     = NULL;
 
     return self;
 }
@@ -1133,6 +1133,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 +1627,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 +1684,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))
             {