diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-03-22 21:27:10 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-22 23:37:20 -0400 |
| commit | 47f1a43bb73607b7bdfcb50de2c4ac8d2bc796af (patch) | |
| tree | 3fc46290e6d1af3add9c0c4bdcd1c898ad07ffe2 /src/link | |
| parent | 8f9c3fd3dfb93a8621a55edef8ebfba87c9a6975 (diff) | |
| download | zig-47f1a43bb73607b7bdfcb50de2c4ac8d2bc796af.tar.gz zig-47f1a43bb73607b7bdfcb50de2c4ac8d2bc796af.zip | |
dwarf: lower enums
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Dwarf.zig | 69 |
1 files changed, 67 insertions, 2 deletions
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 |
