From: Wolfgang Bumiller Date: Sat, 12 Jan 2013 12:47:56 +0000 (+0100) Subject: create store to reserved:va_count; fix: don't build vararg accessor ast tree after... X-Git-Tag: before-library~293 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=d78997599afc5dc834b9e2129f9bab9a7a4e5000;p=xonotic%2Fgmqcc.git create store to reserved:va_count; fix: don't build vararg accessor ast tree after generating immediates as they create new ones --- diff --git a/parser.c b/parser.c index e69faac..3582dd7 100644 --- a/parser.c +++ b/parser.c @@ -1353,6 +1353,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy) { /* was a function call */ ast_expression *fun; + ast_value *funval = NULL; ast_call *call; size_t fid; @@ -1422,6 +1423,20 @@ static bool parser_close_call(parser_t *parser, shunt *sy) return false; } + if (ast_istype(fun, ast_value)) { + funval = (ast_value*)fun; + if ((fun->expression.flags & AST_FLAG_VARIADIC) && + !(funval->cvq == CV_CONST && funval->hasvalue && funval->constval.vfunc->builtin)) + { + size_t va_count; + if (paramcount < vec_size(fun->expression.params)) + va_count = 0; + else + va_count = paramcount - vec_size(fun->expression.params); + call->va_count = (ast_expression*)parser_const_float(parser, (double)va_count); + } + } + /* overwrite fid, the function, with a call */ sy->out[fid] = syexp(call->expression.node.context, (ast_expression*)call); @@ -5742,6 +5757,31 @@ bool parser_finish(const char *output) ir_builder_delete(ir); return false; } + /* Build function vararg accessor ast tree now before generating + * immediates, because the accessors may add new immediates + */ + for (i = 0; i < vec_size(parser->functions); ++i) { + ast_function *f = parser->functions[i]; + if (f->varargs) { + if (parser->max_param_count > vec_size(f->vtype->expression.params)) { + f->varargs->expression.count = parser->max_param_count - vec_size(f->vtype->expression.params); + 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); + 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); + return false; + } + } else { + ast_delete(f->varargs); + f->varargs = NULL; + } + } + } + /* Now we can generate immediates */ for (i = 0; i < vec_size(parser->imm_float); ++i) { if (!ast_global_codegen(parser->imm_float[i], ir, false)) { con_out("failed to generate global %s\n", parser->imm_float[i]->name); @@ -5799,24 +5839,6 @@ bool parser_finish(const char *output) } for (i = 0; i < vec_size(parser->functions); ++i) { ast_function *f = parser->functions[i]; - if (f->varargs) { - if (parser->max_param_count > vec_size(f->vtype->expression.params)) { - f->varargs->expression.count = parser->max_param_count - vec_size(f->vtype->expression.params); - 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); - 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); - return false; - } - } else { - ast_delete(f->varargs); - f->varargs = NULL; - } - } if (!ast_function_codegen(f, ir)) { con_out("failed to generate function %s\n", f->name); ir_builder_delete(ir);