aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen.zig1
-rw-r--r--src/link/Dwarf.zig69
2 files changed, 67 insertions, 3 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 20599f3eb6..cc7014a136 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -479,7 +479,6 @@ pub fn generateSymbol(
return Result{ .appended = {} };
},
.Enum => {
- // TODO populate .debug_info for the enum
var int_buffer: Value.Payload.U64 = undefined;
const int_val = typed_value.enumToInt(&int_buffer);
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index 8f0eb96132..7643fe55c4 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -81,8 +81,10 @@ pub const abbrev_base_type = 4;
pub const abbrev_ptr_type = 5;
pub const abbrev_struct_type = 6;
pub const abbrev_struct_member = 7;
-pub const abbrev_pad1 = 8;
-pub const abbrev_parameter = 9;
+pub const abbrev_enum_type = 8;
+pub const abbrev_enum_variant = 9;
+pub const abbrev_pad1 = 10;
+pub const abbrev_parameter = 11;
/// The reloc offset for the virtual address of a function in its Line Number Program.
/// Size is a virtual address integer.
@@ -879,6 +881,11 @@ fn addDbgInfoType(
}
},
.Struct => blk: {
+ if (ty.tag() == .tuple) {
+ log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
+ try dbg_info_buffer.append(abbrev_pad1);
+ break :blk;
+ }
// try dbg_info_buffer.ensureUnusedCapacity(23);
// DW.AT.structure_type
try dbg_info_buffer.append(abbrev_struct_type);
@@ -918,6 +925,46 @@ fn addDbgInfoType(
// DW.AT.structure_type delimit children
try dbg_info_buffer.append(0);
},
+ .Enum => {
+ // DW.AT.enumeration_type
+ try dbg_info_buffer.append(abbrev_enum_type);
+ // DW.AT.byte_size, DW.FORM.sdata
+ const abi_size = ty.abiSize(target);
+ try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
+ // DW.AT.name, DW.FORM.string
+ const enum_name = try ty.nameAllocArena(arena, target);
+ try dbg_info_buffer.ensureUnusedCapacity(enum_name.len + 1);
+ 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,
+ };
+ const target_endian = self.target.cpu.arch.endian();
+ for (fields.keys()) |field_name, field_i| {
+ // DW.AT.enumerator
+ try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64));
+ dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);
+ // DW.AT.name, DW.FORM.string
+ 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];
+ var int_buffer: Value.Payload.U64 = undefined;
+ break :value value.enumToInt(ty, &int_buffer).toUnsignedInt(target);
+ } else @intCast(u64, field_i);
+ mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), value, target_endian);
+ }
+
+ // DW.AT.enumeration_type delimit children
+ try dbg_info_buffer.append(0);
+ },
else => {
log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
try dbg_info_buffer.append(abbrev_pad1);
@@ -1006,6 +1053,24 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.sdata,
0,
0, // table sentinel
+ abbrev_enum_type,
+ DW.TAG.enumeration_type,
+ DW.CHILDREN.yes, // header
+ DW.AT.byte_size,
+ DW.FORM.sdata,
+ DW.AT.name,
+ DW.FORM.string,
+ 0,
+ 0, // table sentinel
+ abbrev_enum_variant,
+ DW.TAG.enumerator,
+ DW.CHILDREN.no, // header
+ DW.AT.name,
+ DW.FORM.string,
+ DW.AT.const_value,
+ DW.FORM.data8,
+ 0,
+ 0, // table sentinel
abbrev_pad1,
DW.TAG.unspecified_type,
DW.CHILDREN.no, // header