diff options
| author | Veikka Tuominen <git@vexu.eu> | 2021-01-29 18:20:35 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2021-03-08 00:33:07 +0200 |
| commit | cfc19eace71c92ecd7e138db6d961271a1b6c126 (patch) | |
| tree | a95c89dbf3b86a83747203c406b4fbb34a1eaad2 /src/codegen | |
| parent | c22f010fdd2c5ead80cbdc902738a9d023322436 (diff) | |
| download | zig-cfc19eace71c92ecd7e138db6d961271a1b6c126.tar.gz zig-cfc19eace71c92ecd7e138db6d961271a1b6c126.zip | |
stage2 cbe: errors
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 642166092e..fe87a5994a 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -217,6 +217,11 @@ pub const DeclGen = struct { try writer.writeAll(" }"); } }, + .ErrorSet => { + const payload = val.castTag(.@"error").?; + // error values will be #defined at the top of the file + return writer.print("zig_error_{s}", .{payload.data.name}); + }, else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{ @tagName(e), }), @@ -327,6 +332,16 @@ pub const DeclGen = struct { try dg.renderType(w, child_type); try w.writeAll(" payload; bool is_null; }"); }, + .ErrorSet => { + comptime std.debug.assert(Type.initTag(.anyerror).abiSize(std.Target.current) == 2); + try w.writeAll("uint16_t"); + }, + .ErrorUnion => { + // TODO this needs to be typedeffed since different structs are different types. + try w.writeAll("struct { "); + try dg.renderType(w, t.errorUnionChild()); + try w.writeAll(" payload; uint16_t error; }"); + }, .Null, .Undefined => unreachable, // must be const or comptime else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{ @tagName(e), @@ -464,6 +479,8 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi .wrap_optional => try genWrapOptional(o, inst.castTag(.wrap_optional).?), .optional_payload => try genOptionalPayload(o, inst.castTag(.optional_payload).?), .optional_payload_ptr => try genOptionalPayload(o, inst.castTag(.optional_payload).?), + .is_err => try genIsErr(o, inst.castTag(.is_err).?), + .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?), else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}), }; switch (result_value) { @@ -900,6 +917,18 @@ fn genWrapOptional(o: *Object, inst: *Inst.UnOp) !CValue { return local; } +fn genIsErr(o: *Object, inst: *Inst.UnOp) !CValue { + const writer = o.writer(); + const maybe_deref = if (inst.base.tag == .is_err_ptr) "[0]" else ""; + const operand = try o.resolveInst(inst.operand); + + const local = try o.allocLocal(Type.initTag(.bool), .Const); + try writer.writeAll(" = ("); + try o.writeCValue(writer, operand); + try writer.print("){s}.error != 0;\n", .{maybe_deref}); + return local; +} + fn IndentWriter(comptime UnderlyingWriter: type) type { return struct { const Self = @This(); |
