aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-07 22:29:28 -0700
committerGitHub <noreply@github.com>2021-04-07 22:29:28 -0700
commitd4f61f9842da9025a4eb57e7a0fbb3298a4c01f6 (patch)
treecf9bdfa6cf51b7446df1da43bb37b76728ced769 /src/codegen
parent341dc03b638bc75bb8215dd2ad22231ebe106139 (diff)
parent759591577518fcaf03fb90efca67d896d0806458 (diff)
downloadzig-d4f61f9842da9025a4eb57e7a0fbb3298a4c01f6.tar.gz
zig-d4f61f9842da9025a4eb57e7a0fbb3298a4c01f6.zip
Merge pull request #8449 from ziglang/stage2-enums
stage2: implement simple enums
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig60
1 files changed, 55 insertions, 5 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 876f86ed02..874baccf42 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),
}),
@@ -368,6 +396,9 @@ pub const DeclGen = struct {
else => unreachable,
}
},
+
+ .Float => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Float", .{}),
+
.Pointer => {
if (t.isSlice()) {
return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement slices", .{});
@@ -472,10 +503,29 @@ pub const DeclGen = struct {
try w.writeAll(name);
dg.typedefs.putAssumeCapacityNoClobber(t, .{ .name = name, .rendered = rendered });
},
- .Null, .Undefined => unreachable, // must be const or comptime
- else => |e| return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type {s}", .{
- @tagName(e),
- }),
+ .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);
+ },
+ .Union => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Union", .{}),
+ .Fn => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Fn", .{}),
+ .Opaque => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Opaque", .{}),
+ .Frame => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Frame", .{}),
+ .AnyFrame => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type AnyFrame", .{}),
+ .Vector => return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type Vector", .{}),
+
+ .Null,
+ .Undefined,
+ .EnumLiteral,
+ .ComptimeFloat,
+ .ComptimeInt,
+ .Type,
+ => unreachable, // must be const or comptime
+
+ .BoundFn => unreachable, // this type will be deleted from the language
}
}