self->node.context = ctx;
self->node.destroy = &_ast_node_destroy;
self->node.keep = false;
+ self->node.uses = 0;
self->node.nodetype = nodetype;
}
else
self->expression.vtype = left->expression.vtype;
+ ast_use(left);
+ ast_use(right);
+
return self;
}
else
self->expression.next = NULL;
+ ast_use(left);
+ ast_use(right);
+ ast_use(left);
+
return self;
}
self->op = op;
self->operand = expr;
+ ast_use(expr);
+
return self;
}
self->operand = expr;
+ ast_use(expr);
+
return self;
}
self->entity = entity;
self->field = field;
+ ast_use(entity);
+ ast_use(field);
+
return self;
}
self->owner = owner;
self->field = field;
+ ast_use(owner);
+
return self;
}
self->on_true = ontrue;
self->on_false = onfalse;
+ ast_use(cond);
+ if (ontrue) ast_use(ontrue);
+ if (onfalse) ast_use(onfalse);
+
return self;
}
self->on_false = onfalse;
self->phi_out = NULL;
+ ast_use(cond);
+ ast_use(ontrue);
+ ast_use(onfalse);
+
return self;
}
self->increment = increment;
self->body = body;
+ if (initexpr) ast_use(initexpr);
+ if (precond) ast_use(precond);
+ if (postcond) ast_use(postcond);
+ if (increment) ast_use(increment);
+ if (body) ast_use(body);
+
return self;
}
MEM_VECTOR_INIT(self, params);
self->func = funcexpr;
+ ast_use(funcexpr);
return self;
}
MEM_VEC_FUNCTIONS(ast_call, ast_expression*, params)
+bool ast_call_add_param(ast_call *self, ast_expression *expr)
+{
+ if (!ast_call_params_add(self, expr))
+ return false;
+ ast_use(expr);
+ return true;
+}
+
void ast_call_delete(ast_call *self)
{
size_t i;
self->dest = dest;
self->source = source;
+ ast_use(dest);
+ ast_use(source);
+
return self;
}
MEM_VEC_FUNCTIONS(ast_block, ast_value*, locals)
MEM_VEC_FUNCTIONS(ast_block, ast_expression*, exprs)
+bool ast_block_add_expr(ast_block *self, ast_expression *expr)
+{
+ if (!ast_block_exprs_add(self, expr))
+ return false;
+ ast_use(expr);
+ return true;
+}
+
void ast_block_delete(ast_block *self)
{
size_t i;
* prevents its dtor from destroying this node as well.
*/
bool keep;
+ /* usecount - so we can delete unused _x,_y and _z nodes... */
+ size_t uses;
} ast_node_common;
+#define ast_use(n) ((ast_node*)(n))->node.uses++
+#define ast_unuse(n) ((ast_node*)(n))->node.uses--
+
#define ast_delete(x) ( ( (ast_node*)(x) ) -> node.destroy )((ast_node*)(x))
#define ast_unref(x) do \
{ \
MEM_VECTOR_PROTO(ast_call, ast_expression*, params);
+bool ast_call_add_param(ast_call*, ast_expression*);
+
/* Blocks
*
*/
MEM_VECTOR_PROTO(ast_block, ast_value*, locals);
MEM_VECTOR_PROTO(ast_block, ast_expression*, exprs);
+bool ast_block_add_expr(ast_block*, ast_expression *expr);
+
bool ast_block_codegen(ast_block*, ast_function*, bool lvalue, ir_value**);
/* Function
case opid1(','):
if (blocks[0]) {
- if (!ast_block_exprs_add(blocks[0], exprs[1]))
+ if (!ast_block_add_expr(blocks[0], exprs[1]))
return false;
} else {
blocks[0] = ast_block_new(ctx);
- if (!ast_block_exprs_add(blocks[0], exprs[0]) ||
- !ast_block_exprs_add(blocks[0], exprs[1]))
+ if (!ast_block_add_expr(blocks[0], exprs[0]) ||
+ !ast_block_add_expr(blocks[0], exprs[1]))
{
return false;
}
if (!params) {
/* 1 param */
paramcount = 1;
- if (!ast_call_params_add(call, sy->out[sy->out_count].out)) {
+ if (!ast_call_add_param(call, sy->out[sy->out_count].out)) {
ast_delete(sy->out[sy->out_count].out);
parseerror(parser, "out of memory");
return false;
}
if (!expr)
continue;
- if (!ast_block_exprs_add(block, expr)) {
+ if (!ast_block_add_expr(block, expr)) {
ast_delete(expr);
ast_block_delete(block);
block = NULL;