]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - parser.cpp
fix for loops
[xonotic/gmqcc.git] / parser.cpp
index 70c81f27201d98b33ae3e01ef710f8939a46b617..72f5479095c3b4a4ae3dacdf7a48fcdafbdc5b4e 100644 (file)
@@ -2480,18 +2480,20 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou
         initexpr = parse_expression_leave(parser, false, false, false);
         if (!initexpr)
             goto onerr;
-
         /* move on to condition */
         if (parser->tok != ';') {
             parseerror(parser, "expected semicolon after for-loop initializer");
             goto onerr;
         }
-
         if (!parser_next(parser)) {
             parseerror(parser, "expected for-loop condition");
             goto onerr;
         }
     }
+    else if (!parser_next(parser)) {
+        parseerror(parser, "expected for-loop condition");
+        goto onerr;
+    }
 
     /* parse the condition */
     if (parser->tok != ';') {
@@ -4088,7 +4090,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
         goto enderrfn;
     }
 
-    func->blocks.push_back(block);
+    func->blocks.emplace_back(block);
 
     parser->function = old;
     if (!parser_leaveblock(parser))
@@ -4348,7 +4350,7 @@ static bool parser_create_array_accessor(parser_t *parser, ast_value *array, con
         return false;
     }
 
-    func->blocks.push_back(body);
+    func->blocks.emplace_back(body);
     *out = fval;
 
     parser->accessors.push_back(fval);
@@ -4405,7 +4407,7 @@ static bool parser_create_array_setter_impl(parser_t *parser, ast_value *array)
         parseerror(parser, "failed to build accessor search tree");
         return false;
     }
-    if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0], root)) {
+    if (!ast_block_add_expr(array->setter->constval.vfunc->blocks[0].get(), root)) {
         ast_delete(root);
         return false;
     }
@@ -4457,7 +4459,7 @@ static bool parser_create_array_field_setter(parser_t *parser, ast_value *array,
     }
 
     array->setter = fval;
-    return ast_block_add_expr(func->blocks[0], root);
+    return ast_block_add_expr(func->blocks[0].get(), root);
 cleanup:
     if (entity) ast_delete(entity);
     if (index)  ast_delete(index);
@@ -4513,7 +4515,7 @@ static bool parser_create_array_getter_impl(parser_t *parser, ast_value *array)
         parseerror(parser, "failed to build accessor search tree");
         return false;
     }
-    if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0], root)) {
+    if (!ast_block_add_expr(array->getter->constval.vfunc->blocks[0].get(), root)) {
         ast_delete(root);
         return false;
     }
@@ -5685,6 +5687,8 @@ skipvar:
             ast_delete(basetype);
             for (auto &it : parser->gotos)
                 parseerror(parser, "undefined label: `%s`", it->name);
+            parser->gotos.clear();
+            parser->labels.clear();
             return true;
         } else {
             ast_expression *cexp;
@@ -6123,6 +6127,7 @@ static void parser_remove_ast(parser_t *parser)
 void parser_cleanup(parser_t *parser)
 {
     parser_remove_ast(parser);
+    parser->~parser_t();
     mem_d(parser);
 }
 
@@ -6144,7 +6149,7 @@ static bool parser_set_coverage_func(parser_t *parser, ir_builder *ir) {
     if (!func) {
         if (OPTS_OPTION_BOOL(OPTION_COVERAGE)) {
             con_out("coverage support requested but no coverage() builtin declared\n");
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
         return true;
@@ -6157,7 +6162,7 @@ static bool parser_set_coverage_func(parser_t *parser, ir_builder *ir) {
         char ty[1024];
         ast_type_to_string(expr, ty, sizeof(ty));
         con_out("invalid type for coverage(): %s\n", ty);
-        ir_builder_delete(ir);
+        delete ir;
         return false;
     }
 
@@ -6175,7 +6180,7 @@ bool parser_finish(parser_t *parser, const char *output)
         return false;
     }
 
-    ir = ir_builder_new("gmqcc_out");
+    ir = new ir_builder("gmqcc_out");
     if (!ir) {
         con_out("failed to allocate builder\n");
         return false;
@@ -6190,7 +6195,7 @@ bool parser_finish(parser_t *parser, const char *output)
         field->hasvalue = false;
         if (!ast_global_codegen((ast_value*)field, ir, true)) {
             con_out("failed to generate field %s\n", field->name);
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
         if (hasvalue) {
@@ -6217,7 +6222,7 @@ bool parser_finish(parser_t *parser, const char *output)
         }
         if (!ast_global_codegen(asvalue, ir, false)) {
             con_out("failed to generate global %s\n", asvalue->name);
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
@@ -6230,12 +6235,12 @@ bool parser_finish(parser_t *parser, const char *output)
                 f->varargs->count = parser->max_param_count - f->function_type->type_params.size();
                 if (!parser_create_array_setter_impl(parser, f->varargs)) {
                     con_out("failed to generate vararg setter for %s\n", f->name);
-                    ir_builder_delete(ir);
+                    delete ir;
                     return false;
                 }
                 if (!parser_create_array_getter_impl(parser, f->varargs)) {
                     con_out("failed to generate vararg getter for %s\n", f->name);
-                    ir_builder_delete(ir);
+                    delete ir;
                     return false;
                 }
             } else {
@@ -6267,7 +6272,7 @@ bool parser_finish(parser_t *parser, const char *output)
                                        asvalue->name);
         }
         if (!ast_generate_accessors(asvalue, ir)) {
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
@@ -6278,7 +6283,7 @@ bool parser_finish(parser_t *parser, const char *output)
         if (asvalue->vtype != TYPE_ARRAY)
             continue;
         if (!ast_generate_accessors(asvalue, ir)) {
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
@@ -6286,13 +6291,13 @@ bool parser_finish(parser_t *parser, const char *output)
         !ast_global_codegen(parser->reserved_version, ir, false))
     {
         con_out("failed to generate reserved::version");
-        ir_builder_delete(ir);
+        delete ir;
         return false;
     }
     for (auto &f : parser->functions) {
         if (!ast_function_codegen(f, ir)) {
             con_out("failed to generate function %s\n", f->name);
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
@@ -6304,7 +6309,7 @@ bool parser_finish(parser_t *parser, const char *output)
     for (auto &it : parser->functions) {
         if (!ir_function_finalize(it->ir_func)) {
             con_out("failed to finalize function %s\n", it->name);
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
@@ -6322,10 +6327,10 @@ bool parser_finish(parser_t *parser, const char *output)
 
         if (!ir_builder_generate(ir, output)) {
             con_out("*** failed to generate output file\n");
-            ir_builder_delete(ir);
+            delete ir;
             return false;
         }
     }
-    ir_builder_delete(ir);
+    delete ir;
     return retval;
 }