aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-05-12 00:07:32 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-06-10 20:42:30 -0700
commit5881a2d63771b070107bdc2325aa1bc455b2d926 (patch)
tree0380faab30356377b721943de57c8b566e9f3744 /src/link
parent404cbc36c52a50975a69e78da716f2258e5b1696 (diff)
downloadzig-5881a2d63771b070107bdc2325aa1bc455b2d926.tar.gz
zig-5881a2d63771b070107bdc2325aa1bc455b2d926.zip
stage2: move enum types into the InternPool
Unlike unions and structs, enums are actually *encoded* into the InternPool directly, rather than using the SegmentedList trick. This results in them being quite compact, and greatly improved the ergonomics of using enum types throughout the compiler. It did however require introducing a new concept to the InternPool which is an "incomplete" item - something that is added to gain a permanent Index, but which is then mutated in place. This was necessary because enum tag values and tag types may reference the namespaces created by the enum itself, which required constructing the namespace, decl, and calling analyzeDecl on the decl, which required the decl value, which required the enum type, which required an InternPool index to be assigned and for it to be meaningful. The API for updating enums in place turned out to be quite slick and efficient - the methods directly populate pre-allocated arrays and return the information necessary to output the same compilation errors as before.
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Dwarf.zig21
1 files changed, 8 insertions, 13 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index d1e8d9601b..e20e127800 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -401,14 +401,9 @@ pub const DeclState = struct {
dbg_info_buffer.appendSliceAssumeCapacity(enum_name);
dbg_info_buffer.appendAssumeCapacity(0);
- const fields = ty.enumFields();
- const values: ?Module.EnumFull.ValueMap = switch (ty.tag()) {
- .enum_full, .enum_nonexhaustive => ty.cast(Type.Payload.EnumFull).?.data.values,
- .enum_simple => null,
- .enum_numbered => ty.castTag(.enum_numbered).?.data.values,
- else => unreachable,
- };
- for (fields.keys(), 0..) |field_name, field_i| {
+ const enum_type = mod.intern_pool.indexToKey(ty.ip_index).enum_type;
+ for (enum_type.names, 0..) |field_name_index, field_i| {
+ const field_name = mod.intern_pool.stringToSlice(field_name_index);
// DW.AT.enumerator
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64));
dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
@@ -416,14 +411,14 @@ pub const DeclState = struct {
dbg_info_buffer.appendSliceAssumeCapacity(field_name);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.const_value, DW.FORM.data8
- const value: u64 = if (values) |vals| value: {
- if (vals.count() == 0) break :value @intCast(u64, field_i); // auto-numbered
- const value = vals.keys()[field_i];
+ const value: u64 = value: {
+ if (enum_type.values.len == 0) break :value field_i; // auto-numbered
+ const value = enum_type.values[field_i];
// TODO do not assume a 64bit enum value - could be bigger.
// See https://github.com/ziglang/zig/issues/645
- const field_int_val = try value.enumToInt(ty, mod);
+ const field_int_val = try value.toValue().enumToInt(ty, mod);
break :value @bitCast(u64, field_int_val.toSignedInt(mod));
- } else @intCast(u64, field_i);
+ };
mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
}