self->keep_dest = false;
- self->expression.vtype = left->expression.vtype;
- if (left->expression.next) {
- self->expression.next = ast_type_copy(ctx, left);
- if (!self->expression.next) {
- ast_delete(self);
- return NULL;
- }
+ if (!ast_type_adopt(self, left)) {
+ ast_delete(self);
+ return NULL;
}
- else
- self->expression.next = NULL;
return self;
}
self->params = NULL;
self->func = funcexpr;
-/*
- self->expression.vtype = funcexpr->expression.next->expression.vtype;
- if (funcexpr->expression.next->expression.next)
- self->expression.next = ast_type_copy(ctx, funcexpr->expression.next->expression.next);
-*/
ast_type_adopt(self, funcexpr->expression.next);
return self;
self->dest = dest;
self->source = source;
- self->expression.vtype = dest->expression.vtype;
- if (dest->expression.next) {
- self->expression.next = ast_type_copy(ctx, dest);
- if (!self->expression.next) {
- ast_delete(self);
- return NULL;
- }
+ if (!ast_type_adopt(self, dest)) {
+ ast_delete(self);
+ return NULL;
}
- else
- self->expression.next = NULL;
return self;
}
return self;
}
-void ast_block_add_expr(ast_block *self, ast_expression *e)
+bool ast_block_add_expr(ast_block *self, ast_expression *e)
{
ast_propagate_effects(self, e);
vec_push(self->exprs, e);
+ if (self->expression.next) {
+ ast_delete(self->expression.next);
+ self->expression.next = NULL;
+ }
+ if (!ast_type_adopt(self, e)) {
+ compile_error(ast_ctx(self), "internal error: failed to adopt type");
+ return false;
+ }
+ return true;
}
void ast_block_collect(ast_block *self, ast_expression *expr)
{
if (self->expression.next)
ast_delete(self->expression.next);
- self->expression.vtype = from->expression.vtype;
- if (from->expression.next) {
- self->expression.next = ast_type_copy(self->expression.node.context, from->expression.next);
- if (!self->expression.next)
- return false;
- }
- else
- self->expression.next = NULL;
+ if (!ast_type_adopt(self, from))
+ return false;
return true;
}
v->cvq = self->cvq;
self->ir_v = v;
+ if (!ast_generate_accessors(self, func->owner))
+ return false;
+ return true;
+
+error: /* clean up */
+ ir_value_delete(v);
+ return false;
+}
+
+bool ast_generate_accessors(ast_value *self, ir_builder *ir)
+{
+ size_t i;
+ bool warn = OPTS_WARN(WARN_USED_UNINITIALIZED);
+ if (!self->setter || !self->getter)
+ return true;
+ for (i = 0; i < self->expression.count; ++i) {
+ if (!self->ir_values) {
+ compile_error(ast_ctx(self), "internal error: no array values generated for `%s`", self->name);
+ return false;
+ }
+ if (!self->ir_values[i]) {
+ compile_error(ast_ctx(self), "internal error: not all array values have been generated for `%s`", self->name);
+ return false;
+ }
+ if (self->ir_values[i]->life) {
+ compile_error(ast_ctx(self), "internal error: function containing `%s` already generated", self->name);
+ return false;
+ }
+ }
+
+ options_set(opts_warn, WARN_USED_UNINITIALIZED, false);
if (self->setter) {
- if (!ast_global_codegen(self->setter, func->owner, false) ||
- !ast_function_codegen(self->setter->constval.vfunc, func->owner) ||
+ if (!ast_global_codegen (self->setter, ir, false) ||
+ !ast_function_codegen(self->setter->constval.vfunc, ir) ||
!ir_function_finalize(self->setter->constval.vfunc->ir_func))
+ {
+ compile_error(ast_ctx(self), "internal error: failed to generate setter for `%s`", self->name);
+ options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
return false;
+ }
}
if (self->getter) {
- if (!ast_global_codegen(self->getter, func->owner, false) ||
- !ast_function_codegen(self->getter->constval.vfunc, func->owner) ||
+ if (!ast_global_codegen (self->getter, ir, false) ||
+ !ast_function_codegen(self->getter->constval.vfunc, ir) ||
!ir_function_finalize(self->getter->constval.vfunc->ir_func))
+ {
+ compile_error(ast_ctx(self), "internal error: failed to generate getter for `%s`", self->name);
+ options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
return false;
+ }
+ }
+ for (i = 0; i < self->expression.count; ++i) {
+ vec_free(self->ir_values[i]->life);
}
+ options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
return true;
-
-error: /* clean up */
- ir_value_delete(v);
- return false;
}
bool ast_function_codegen(ast_function *self, ir_builder *ir)
self->expression.outr = ir_phi_value(phi);
*out = self->expression.outr;
+ codegen_output_type(self, *out);
+
return true;
}