From 19cf987198ff4de0b1460263a62ff6c41e1e3915 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 6 Apr 2021 23:19:46 -0700 Subject: C backend: implement Enum types and values They are lowered directly as the integer tag type, with no typedef. --- src/codegen/c.zig | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 876f86ed02..d5d18baa1c 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -172,7 +172,10 @@ pub const DeclGen = struct { val: Value, ) error{ OutOfMemory, AnalysisFail }!void { if (val.isUndef()) { - return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: properly handle undefined in all cases (with debug safety?)", .{}); + // This should lower to 0xaa bytes in safe modes, and for unsafe modes should + // lower to leaving variables uninitialized (that might need to be implemented + // outside of this function). + return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement renderValue undef", .{}); } switch (t.zigTypeTag()) { .Int => { @@ -288,6 +291,31 @@ pub const DeclGen = struct { try writer.writeAll(", .error = 0 }"); } }, + .Enum => { + switch (val.tag()) { + .enum_field_index => { + const field_index = val.castTag(.enum_field_index).?.data; + switch (t.tag()) { + .enum_simple => return writer.print("{d}", .{field_index}), + .enum_full, .enum_nonexhaustive => { + const enum_full = t.cast(Type.Payload.EnumFull).?.data; + if (enum_full.values.count() != 0) { + const tag_val = enum_full.values.entries.items[field_index].key; + return dg.renderValue(writer, enum_full.tag_ty, tag_val); + } else { + return writer.print("{d}", .{field_index}); + } + }, + else => unreachable, + } + }, + else => { + var int_tag_ty_buffer: Type.Payload.Bits = undefined; + const int_tag_ty = t.intTagType(&int_tag_ty_buffer); + return dg.renderValue(writer, int_tag_ty, val); + }, + } + }, else => |e| return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement value {s}", .{ @tagName(e), }), @@ -472,6 +500,13 @@ pub const DeclGen = struct { try w.writeAll(name); dg.typedefs.putAssumeCapacityNoClobber(t, .{ .name = name, .rendered = rendered }); }, + .Enum => { + // For enums, we simply use the integer tag type. + var int_tag_ty_buffer: Type.Payload.Bits = undefined; + const int_tag_ty = t.intTagType(&int_tag_ty_buffer); + + try dg.renderType(w, int_tag_ty); + }, .Null, .Undefined => unreachable, // must be const or comptime else => |e| return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type {s}", .{ @tagName(e), -- cgit v1.2.3