aboutsummaryrefslogtreecommitdiff
path: root/src/ir.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-28 20:16:18 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-28 20:16:18 +0000
commite86c990b75bb30f0116430453b42a59317e3fead (patch)
tree2645005099bd2cf744299d6a3538408ed5728d39 /src/ir.c
parent31aacd5bf435224c7d8f9b19359175d3e6d25660 (diff)
Overloaded `free`; 3 dotted ellipsisv0.0.6a
Diffstat (limited to 'src/ir.c')
-rw-r--r--src/ir.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/ir.c b/src/ir.c
index d2f423d4e..abbef8dbd 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -2909,6 +2909,37 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
return ir_emit_load(proc, slice);
} break;
+ case BuiltinProc_free: {
+ ir_emit_comment(proc, str_lit("free"));
+
+ gbAllocator allocator = proc->module->allocator;
+
+ AstNode *node = ce->args.e[0];
+ TypeAndValue tav = *type_and_value_of_expression(proc->module->info, node);
+ Type *type = base_type(tav.type);
+ irValue *val = ir_build_expr(proc, node);
+ irValue *ptr = NULL;
+ if (is_type_pointer(type)) {
+ ptr = val;
+ } else if (is_type_slice(type)) {
+ ptr = ir_slice_elem(proc, val);
+ } else if (is_type_string(type)) {
+ ptr = ir_string_elem(proc, val);
+ } else {
+ GB_PANIC("Invalid type to `free`");
+ }
+
+ if (ptr == NULL) {
+ return NULL;
+ }
+
+ ptr = ir_emit_conv(proc, ptr, t_rawptr);
+
+ irValue **args = gb_alloc_array(allocator, irValue *, 1);
+ args[0] = ptr;
+ return ir_emit_global_call(proc, "free_ptr", args, 1);
+ } break;
+
case BuiltinProc_assert: {
ir_emit_comment(proc, str_lit("assert"));
irValue *cond = ir_build_expr(proc, ce->args.e[0]);