X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ast.c;h=7d7443f882300c2eb5eecea99190f017fdaf5461;hb=6983142c4d782bcb49595eeca0fb8883ecd9479c;hp=b04acc6fce783e9f9761505415d61cc48e058f6e;hpb=ebc6954bf566a1e7f66eee8be5f4d9b06fb05212;p=xonotic%2Fgmqcc.git diff --git a/ast.c b/ast.c index b04acc6..7d7443f 100644 --- a/ast.c +++ b/ast.c @@ -651,7 +651,11 @@ ast_ternary* ast_ternary_new(lex_ctx ctx, ast_expression *cond, ast_expression * self->cond = cond; self->on_true = ontrue; self->on_false = onfalse; - self->phi_out = NULL; + + if (!ast_type_adopt(self, ontrue)) { + ast_ternary_delete(self); + return NULL; + } return self; } @@ -784,8 +788,12 @@ bool ast_call_check_types(ast_call *self) for (i = 0; i < count; ++i) { if (!ast_compare_type(self->params[i], (ast_expression*)(func->expression.params[i]))) { - asterror(ast_ctx(self), "invalid type for parameter %u in function call", - (unsigned int)(i+1)); + char texp[1024]; + char tgot[1024]; + ast_type_to_string(self->params[i], tgot, sizeof(tgot)); + ast_type_to_string((ast_expression*)func->expression.params[i], texp, sizeof(texp)); + asterror(ast_ctx(self), "invalid type for parameter %u in function call: expected %s, got %s", + (unsigned int)(i+1), texp, tgot); /* we don't immediately return */ retval = false; } @@ -1532,23 +1540,27 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va * but we translate this to (!(!a ? !a : !b)) */ - merge_id = vec_size(func->blocks); + merge_id = vec_size(func->ir_func->blocks); merge = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_merge")); cgen = self->left->expression.codegen; if (!(*cgen)((ast_expression*)(self->left), func, false, &left)) return false; - notop = type_not_instr[left->vtype]; - if (notop == AINSTR_END) { - asterror(ast_ctx(self), "don't know how to cast to bool..."); - return false; + if (!OPTS_FLAG(PERL_LOGIC)) { + notop = type_not_instr[left->vtype]; + if (notop == AINSTR_END) { + asterror(ast_ctx(self), "don't know how to cast to bool..."); + return false; + } + left = ir_block_create_unary(func->curblock, + ast_function_label(func, "sce_not"), + notop, + left); } - left = ir_block_create_unary(func->curblock, ast_function_label(func, "sce_not"), notop, left); - from_left = func->curblock; other = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_other")); - if (self->op == INSTR_OR) { + if ( !(self->op == INSTR_OR) != !OPTS_FLAG(PERL_LOGIC) ) { if (!ir_block_create_if(func->curblock, left, other, merge)) return false; } else { @@ -1562,12 +1574,17 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va cgen = self->right->expression.codegen; if (!(*cgen)((ast_expression*)(self->right), func, false, &right)) return false; - notop = type_not_instr[right->vtype]; - if (notop == AINSTR_END) { - asterror(ast_ctx(self), "don't know how to cast to bool..."); - return false; + if (!OPTS_FLAG(PERL_LOGIC)) { + notop = type_not_instr[right->vtype]; + if (notop == AINSTR_END) { + asterror(ast_ctx(self), "don't know how to cast to bool..."); + return false; + } + right = ir_block_create_unary(func->curblock, + ast_function_label(func, "sce_not"), + notop, + right); } - right = ir_block_create_unary(func->curblock, ast_function_label(func, "sce_not"), notop, right); from_right = func->curblock; if (!ir_block_create_jump(func->curblock, merge)) @@ -1581,12 +1598,19 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va ir_phi_add(phi, from_left, left); ir_phi_add(phi, from_right, right); *out = ir_phi_value(phi); - notop = type_not_instr[(*out)->vtype]; - if (notop == AINSTR_END) { - asterror(ast_ctx(self), "don't know how to cast to bool..."); - return false; + if (!OPTS_FLAG(PERL_LOGIC)) { + notop = type_not_instr[(*out)->vtype]; + if (notop == AINSTR_END) { + asterror(ast_ctx(self), "don't know how to cast to bool..."); + return false; + } + *out = ir_block_create_unary(func->curblock, + ast_function_label(func, "sce_final_not"), + notop, + *out); } - *out = ir_block_create_unary(func->curblock, ast_function_label(func, "sce_final_not"), notop, *out); + if (!*out) + return false; self->expression.outr = *out; return true; } @@ -1996,8 +2020,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ * may still happen, thus we remember a created ir_value and simply return one * if it already exists. */ - if (self->phi_out) { - *out = self->phi_out; + if (self->expression.outr) { + *out = self->expression.outr; return true; } @@ -2071,8 +2095,8 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_ ir_phi_add(phi, ontrue, trueval); ir_phi_add(phi, onfalse, falseval); - self->phi_out = ir_phi_value(phi); - *out = self->phi_out; + self->expression.outr = ir_phi_value(phi); + *out = self->expression.outr; return true; }