self->ir_v = func->value;
if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
+ if (self->expression.flags & AST_FLAG_ERASEABLE)
+ self->ir_v->flags |= IR_FLAG_ERASEABLE;
/* The function is filled later on ast_function_codegen... */
return true;
}
v->unique_life = true;
v->locked = true;
array->ir_v = self->ir_v = v;
+
if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
+ if (self->expression.flags & AST_FLAG_ERASEABLE)
+ self->ir_v->flags |= IR_FLAG_ERASEABLE;
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
self->ir_v = v;
if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
+
+ if (self->expression.flags & AST_FLAG_ERASEABLE)
+ self->ir_v->flags |= IR_FLAG_ERASEABLE;
}
return true;
}
v->context = ast_ctx(self);
v->unique_life = true;
v->locked = true;
+
if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
v->flags |= IR_FLAG_INCLUDE_DEF;
+ if (self->expression.flags & AST_FLAG_ERASEABLE)
+ self->ir_v->flags |= IR_FLAG_ERASEABLE;
namelen = strlen(self->name);
name = (char*)mem_a(namelen + 16);
/* link us to the ir_value */
v->cvq = self->cvq;
self->ir_v = v;
+
if (self->expression.flags & AST_FLAG_INCLUDE_DEF)
self->ir_v->flags |= IR_FLAG_INCLUDE_DEF;
+ if (self->expression.flags & AST_FLAG_ERASEABLE)
+ self->ir_v->flags |= IR_FLAG_ERASEABLE;
/* initialize */
if (self->hasvalue) {
return true;
}
+static bool starts_a_label(ast_expression *ex)
+{
+ while (ex && ast_istype(ex, ast_block)) {
+ ast_block *b = (ast_block*)ex;
+ ex = b->exprs[0];
+ }
+ if (!ex)
+ return false;
+ return ast_istype(ex, ast_label);
+}
+
/* Note, you will not see ast_block_codegen generate ir_blocks.
* To the AST and the IR, blocks are 2 different things.
* In the AST it represents a block of code, usually enclosed in
for (i = 0; i < vec_size(self->exprs); ++i)
{
ast_expression_codegen *gen;
- if (func->curblock->final && !ast_istype(self->exprs[i], ast_label)) {
+ if (func->curblock->final && !starts_a_label(self->exprs[i])) {
if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement"))
return false;
continue;
/* update the block which will get the jump - because short-logic or ternaries may have changed this */
cond = func->curblock;
- /* try constant folding away the if */
- if ((fold = fold_cond(condval, func, self)) != -1)
+ /* try constant folding away the condition */
+ if ((fold = fold_cond_ifthen(condval, func, self)) != -1)
return fold;
if (self->on_true) {
ir_block *ontrue, *ontrue_out = NULL;
ir_block *onfalse, *onfalse_out = NULL;
ir_block *merge;
+ int fold = 0;
/* Ternary can never create an lvalue... */
if (lvalue)
return false;
cond_out = func->curblock;
+ /* try constant folding away the condition */
+ if ((fold = fold_cond_ternary(condval, func, self)) != -1)
+ return fold;
+
/* create on-true block */
ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_T"));
if (!ontrue)