diff --git a/ci/x86_64-linux-debug.sh b/ci/x86_64-linux-debug.sh index 8e9929bc22..370100e68e 100755 --- a/ci/x86_64-linux-debug.sh +++ b/ci/x86_64-linux-debug.sh @@ -64,7 +64,7 @@ stage3-debug/bin/zig build \ stage3-debug/bin/zig build test docs \ --maxrss 21000000000 \ - -Dlldb=$HOME/deps/lldb-zig/Debug-befcd57a8/bin/lldb \ + -Dlldb=$HOME/deps/lldb-zig/Debug-4a44163df/bin/lldb \ -fqemu \ -fwasmtime \ -Dstatic-llvm \ diff --git a/ci/x86_64-linux-release.sh b/ci/x86_64-linux-release.sh index 346e942602..8ee7f79412 100755 --- a/ci/x86_64-linux-release.sh +++ b/ci/x86_64-linux-release.sh @@ -64,7 +64,7 @@ stage3-release/bin/zig build \ stage3-release/bin/zig build test docs \ --maxrss 21000000000 \ - -Dlldb=$HOME/deps/lldb-zig/Release-befcd57a8/bin/lldb \ + -Dlldb=$HOME/deps/lldb-zig/Release-4a44163df/bin/lldb \ -fqemu \ -fwasmtime \ -Dstatic-llvm \ diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index a812760172..54b85e4b3d 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -1767,9 +1767,11 @@ pub fn HashMapUnmanaged( } comptime { - if (!builtin.strip_debug_info) { - _ = &dbHelper; - } + if (!builtin.strip_debug_info) _ = switch (builtin.zig_backend) { + .stage2_llvm => &dbHelper, + .stage2_x86_64 => KV, + else => {}, + }; } }; } diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 0d9272d492..eedc540db2 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -573,7 +573,7 @@ pub fn MultiArrayList(comptime T: type) type { } comptime { - if (!builtin.strip_debug_info) { + if (builtin.zig_backend == .stage2_llvm and !builtin.strip_debug_info) { _ = &dbHelper; _ = &Slice.dbHelper; } diff --git a/src/InternPool.zig b/src/InternPool.zig index e09576c5aa..fbfd29369f 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -4723,7 +4723,7 @@ pub const Index = enum(u32) { } comptime { - if (!builtin.strip_debug_info) { + if (builtin.zig_backend == .stage2_llvm and !builtin.strip_debug_info) { _ = &dbHelper; } } diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 0d01b3d458..463fdde844 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -25,7 +25,6 @@ const Alignment = InternPool.Alignment; const CodeGenError = codegen.CodeGenError; const Result = codegen.Result; -const DebugInfoOutput = codegen.DebugInfoOutput; const bits = @import("bits.zig"); const abi = @import("abi.zig"); @@ -48,7 +47,7 @@ pt: Zcu.PerThread, air: Air, liveness: Liveness, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, func_index: InternPool.Index, owner_nav: InternPool.Nav.Index, @@ -327,7 +326,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const gpa = zcu.gpa; diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 6c56307183..860a264e72 100644 --- a/src/arch/aarch64/Emit.zig +++ b/src/arch/aarch64/Emit.zig @@ -13,11 +13,10 @@ const assert = std.debug.assert; const Instruction = bits.Instruction; const Register = bits.Register; const log = std.log.scoped(.aarch64_emit); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; mir: Mir, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, err_msg: ?*ErrorMsg = null, src_loc: Zcu.LazySrcLoc, diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 5d2ebf5209..a0b529b75e 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -25,7 +25,6 @@ const Alignment = InternPool.Alignment; const Result = codegen.Result; const CodeGenError = codegen.CodeGenError; -const DebugInfoOutput = codegen.DebugInfoOutput; const bits = @import("bits.zig"); const abi = @import("abi.zig"); @@ -49,7 +48,7 @@ pt: Zcu.PerThread, air: Air, liveness: Liveness, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, func_index: InternPool.Index, err_msg: ?*ErrorMsg, @@ -335,7 +334,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const gpa = zcu.gpa; diff --git a/src/arch/arm/Emit.zig b/src/arch/arm/Emit.zig index c1b5baad57..9ccef5a299 100644 --- a/src/arch/arm/Emit.zig +++ b/src/arch/arm/Emit.zig @@ -16,12 +16,11 @@ const assert = std.debug.assert; const Instruction = bits.Instruction; const Register = bits.Register; const log = std.log.scoped(.aarch32_emit); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; const CodeGen = @import("CodeGen.zig"); mir: Mir, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, err_msg: ?*ErrorMsg = null, src_loc: Zcu.LazySrcLoc, diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 1207eed88d..262dad6d24 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -32,7 +32,6 @@ const Alignment = InternPool.Alignment; const CodeGenError = codegen.CodeGenError; const Result = codegen.Result; -const DebugInfoOutput = codegen.DebugInfoOutput; const bits = @import("bits.zig"); const abi = @import("abi.zig"); @@ -61,7 +60,7 @@ gpa: Allocator, mod: *Package.Module, target: *const std.Target, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: InstTracking, @@ -760,7 +759,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const comp = zcu.comp; @@ -928,7 +927,7 @@ pub fn generateLazy( src_loc: Zcu.LazySrcLoc, lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const comp = bin_file.comp; const gpa = comp.gpa; diff --git a/src/arch/riscv64/Emit.zig b/src/arch/riscv64/Emit.zig index 258941f19d..8ee566c7ed 100644 --- a/src/arch/riscv64/Emit.zig +++ b/src/arch/riscv64/Emit.zig @@ -2,7 +2,7 @@ bin_file: *link.File, lower: Lower, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, code: *std.ArrayList(u8), prev_di_line: u32, @@ -216,7 +216,6 @@ const log = std.log.scoped(.emit); const mem = std.mem; const std = @import("std"); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; const Emit = @This(); const Lower = @import("Lower.zig"); const Mir = @import("Mir.zig"); diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 4f838b9c52..589e9978a2 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -22,7 +22,6 @@ const Liveness = @import("../../Liveness.zig"); const Type = @import("../../Type.zig"); const CodeGenError = codegen.CodeGenError; const Result = @import("../../codegen.zig").Result; -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; const Endian = std.builtin.Endian; const Alignment = InternPool.Alignment; @@ -57,7 +56,7 @@ bin_file: *link.File, target: *const std.Target, func_index: InternPool.Index, code: *std.ArrayList(u8), -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, err_msg: ?*ErrorMsg, args: []MCValue, ret_mcv: MCValue, @@ -268,7 +267,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const gpa = zcu.gpa; diff --git a/src/arch/sparc64/Emit.zig b/src/arch/sparc64/Emit.zig index 4e49bcf5b4..a87c9cd0ae 100644 --- a/src/arch/sparc64/Emit.zig +++ b/src/arch/sparc64/Emit.zig @@ -9,7 +9,6 @@ const Zcu = @import("../../Zcu.zig"); const ErrorMsg = Zcu.ErrorMsg; const Liveness = @import("../../Liveness.zig"); const log = std.log.scoped(.sparcv9_emit); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; const Emit = @This(); const Mir = @import("Mir.zig"); @@ -19,7 +18,7 @@ const Register = bits.Register; mir: Mir, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, err_msg: ?*ErrorMsg = null, src_loc: Zcu.LazySrcLoc, diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index d78b4ae80e..4c42cd4ad2 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -648,7 +648,7 @@ block_depth: u32 = 0, air: Air, liveness: Liveness, gpa: mem.Allocator, -debug_output: codegen.DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, func_index: InternPool.Index, /// Contains a list of current branches. /// When we return from a branch, the branch will be popped from this list, @@ -1211,7 +1211,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: codegen.DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) codegen.CodeGenError!codegen.Result { const zcu = pt.zcu; const gpa = zcu.gpa; diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index e02067f8ca..648af47153 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -26,7 +26,7 @@ owner_nav: InternPool.Nav.Index, // Debug information /// Holds the debug information for this emission -dbg_output: codegen.DebugInfoOutput, +dbg_output: link.File.DebugInfoOutput, /// Previous debug info line prev_di_line: u32, /// Previous debug info column diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 35f47ad882..2d0b35a636 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -17,7 +17,6 @@ const Air = @import("../../Air.zig"); const Allocator = mem.Allocator; const CodeGenError = codegen.CodeGenError; const Compilation = @import("../../Compilation.zig"); -const DebugInfoOutput = codegen.DebugInfoOutput; const ErrorMsg = Zcu.ErrorMsg; const Result = codegen.Result; const Emit = @import("Emit.zig"); @@ -53,7 +52,7 @@ pt: Zcu.PerThread, air: Air, liveness: Liveness, bin_file: *link.File, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, target: *const std.Target, owner: Owner, inline_func: InternPool.Index, @@ -819,7 +818,7 @@ pub fn generate( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const comp = zcu.comp; @@ -1000,7 +999,7 @@ pub fn generateLazy( src_loc: Zcu.LazySrcLoc, lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const comp = bin_file.comp; const gpa = comp.gpa; diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index da9fe303f1..372a520e52 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -3,7 +3,7 @@ air: Air, lower: Lower, atom_index: u32, -debug_output: DebugInfoOutput, +debug_output: link.File.DebugInfoOutput, code: *std.ArrayList(u8), prev_di_line: u32, @@ -546,7 +546,6 @@ const log = std.log.scoped(.emit); const std = @import("std"); const Air = @import("../../Air.zig"); -const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput; const Emit = @This(); const Lower = @import("Lower.zig"); const Mir = @import("Mir.zig"); diff --git a/src/codegen.zig b/src/codegen.zig index adc77c78ed..b41fa3c2ef 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -38,12 +38,6 @@ pub const CodeGenError = error{ CodegenFail, } || link.File.UpdateDebugInfoError; -pub const DebugInfoOutput = union(enum) { - dwarf: *link.File.Dwarf.WipNav, - plan9: *link.File.Plan9.DebugInfoOutput, - none, -}; - fn devFeatureForBackend(comptime backend: std.builtin.CompilerBackend) dev.Feature { comptime assert(mem.startsWith(u8, @tagName(backend), "stage2_")); return @field(dev.Feature, @tagName(backend)["stage2_".len..] ++ "_backend"); @@ -69,7 +63,7 @@ pub fn generateFunction( air: Air, liveness: Liveness, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const func = zcu.funcInfo(func_index); @@ -95,7 +89,7 @@ pub fn generateLazyFunction( src_loc: Zcu.LazySrcLoc, lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, + debug_output: link.File.DebugInfoOutput, ) CodeGenError!Result { const zcu = pt.zcu; const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool); @@ -127,10 +121,10 @@ pub fn generateLazySymbol( // TODO don't use an "out" parameter like this; put it in the result instead alignment: *Alignment, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, - reloc_info: RelocInfo, + debug_output: link.File.DebugInfoOutput, + reloc_parent: link.File.RelocInfo.Parent, ) CodeGenError!Result { - _ = reloc_info; + _ = reloc_parent; const tracy = trace(@src()); defer tracy.end(); @@ -192,8 +186,7 @@ pub fn generateSymbol( src_loc: Zcu.LazySrcLoc, val: Value, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, - reloc_info: RelocInfo, + reloc_parent: link.File.RelocInfo.Parent, ) CodeGenError!Result { const tracy = trace(@src()); defer tracy.end(); @@ -290,7 +283,7 @@ pub fn generateSymbol( switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), .payload => |payload| payload, - }), code, debug_output, reloc_info)) { + }), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } @@ -318,7 +311,7 @@ pub fn generateSymbol( }, .enum_tag => |enum_tag| { const int_tag_ty = ty.intTagType(zcu); - switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } @@ -334,16 +327,16 @@ pub fn generateSymbol( }, .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), }, - .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, debug_output, reloc_info, 0)) { + .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) { .ok => {}, .fail => |em| return .{ .fail = em }, }, .slice => |slice| { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } @@ -355,7 +348,7 @@ pub fn generateSymbol( if (ty.optionalReprIsPayload(zcu)) { if (payload_val) |value| { - switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -368,7 +361,7 @@ pub fn generateSymbol( const value = payload_val orelse Value.fromInterned(try pt.intern(.{ .undef = payload_type.toIntern(), })); - switch (try generateSymbol(bin_file, pt, src_loc, value, code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -390,7 +383,7 @@ pub fn generateSymbol( elem else array_type.sentinel, - }), code, debug_output, reloc_info)) { + }), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } @@ -449,7 +442,7 @@ pub fn generateSymbol( math.cast(usize, index) orelse return error.Overflow ], .repeated_elem => |elem| elem, - }), code, debug_output, reloc_info)) { + }), code, reloc_parent)) { .ok => {}, .fail => |em| return .{ .fail = em }, } @@ -482,7 +475,7 @@ pub fn generateSymbol( .repeated_elem => |elem| elem, }; - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -524,7 +517,7 @@ pub fn generateSymbol( return error.Overflow; var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); defer tmp_list.deinit(); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) { .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), .fail => |em| return Result{ .fail = em }, } @@ -559,7 +552,7 @@ pub fn generateSymbol( ) orelse return error.Overflow; if (padding > 0) try code.appendNTimes(0, padding); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -583,12 +576,12 @@ pub fn generateSymbol( const layout = ty.unionGetLayout(zcu); if (layout.payload_size == 0) { - return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info); + return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent); } // Check if we should store the tag first. if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -601,7 +594,7 @@ pub fn generateSymbol( if (!field_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -612,14 +605,14 @@ pub fn generateSymbol( } } } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } } if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, debug_output, reloc_info)) { + switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { .ok => {}, .fail => |em| return Result{ .fail = em }, } @@ -640,40 +633,29 @@ fn lowerPtr( src_loc: Zcu.LazySrcLoc, ptr_val: InternPool.Index, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, - reloc_info: RelocInfo, + reloc_parent: link.File.RelocInfo.Parent, prev_offset: u64, ) CodeGenError!Result { const zcu = pt.zcu; const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; const offset: u64 = prev_offset + ptr.byte_offset; return switch (ptr.base_addr) { - .nav => |nav| try lowerNavRef(bin_file, pt, src_loc, nav, code, debug_output, reloc_info, offset), - .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, debug_output, reloc_info, offset), - .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, debug_output, reloc_info), + .nav => |nav| try lowerNavRef(bin_file, pt, src_loc, nav, code, reloc_parent, offset), + .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, code, reloc_parent, offset), + .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), code, reloc_parent), .eu_payload => |eu_ptr| try lowerPtr( bin_file, pt, src_loc, eu_ptr, code, - debug_output, - reloc_info, + reloc_parent, offset + errUnionPayloadOffset( Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu).errorUnionPayload(zcu), zcu, ), ), - .opt_payload => |opt_ptr| try lowerPtr( - bin_file, - pt, - src_loc, - opt_ptr, - code, - debug_output, - reloc_info, - offset, - ), + .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, code, reloc_parent, offset), .field => |field| { const base_ptr = Value.fromInterned(field.base); const base_ty = base_ptr.typeOf(zcu).childType(zcu); @@ -692,27 +674,21 @@ fn lowerPtr( }, else => unreachable, }; - return lowerPtr(bin_file, pt, src_loc, field.base, code, debug_output, reloc_info, offset + field_off); + return lowerPtr(bin_file, pt, src_loc, field.base, code, reloc_parent, offset + field_off); }, .arr_elem, .comptime_field, .comptime_alloc => unreachable, }; } -const RelocInfo = struct { - parent_atom_index: u32, -}; - fn lowerUavRef( lf: *link.File, pt: Zcu.PerThread, src_loc: Zcu.LazySrcLoc, uav: InternPool.Key.Ptr.BaseAddr.Uav, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, - reloc_info: RelocInfo, + reloc_parent: link.File.RelocInfo.Parent, offset: u64, ) CodeGenError!Result { - _ = debug_output; const zcu = pt.zcu; const ip = &zcu.intern_pool; const target = lf.comp.root_mod.resolved_target.result; @@ -735,7 +711,7 @@ fn lowerUavRef( } const vaddr = try lf.getUavVAddr(uav_val, .{ - .parent_atom_index = reloc_info.parent_atom_index, + .parent = reloc_parent, .offset = code.items.len, .addend = @intCast(offset), }); @@ -756,12 +732,10 @@ fn lowerNavRef( src_loc: Zcu.LazySrcLoc, nav_index: InternPool.Nav.Index, code: *std.ArrayList(u8), - debug_output: DebugInfoOutput, - reloc_info: RelocInfo, + reloc_parent: link.File.RelocInfo.Parent, offset: u64, ) CodeGenError!Result { _ = src_loc; - _ = debug_output; const zcu = pt.zcu; const ip = &zcu.intern_pool; const target = zcu.navFileScope(nav_index).mod.resolved_target.result; @@ -775,7 +749,7 @@ fn lowerNavRef( } const vaddr = try lf.getNavVAddr(pt, nav_index, .{ - .parent_atom_index = reloc_info.parent_atom_index, + .parent = reloc_parent, .offset = code.items.len, .addend = @intCast(offset), }); diff --git a/src/link.zig b/src/link.zig index 508bc81352..2894302c11 100644 --- a/src/link.zig +++ b/src/link.zig @@ -330,6 +330,11 @@ pub const File = struct { } } + pub const DebugInfoOutput = union(enum) { + dwarf: *Dwarf.WipNav, + plan9: *Plan9.DebugInfoOutput, + none, + }; pub const UpdateDebugInfoError = Dwarf.UpdateError; pub const FlushDebugInfoError = Dwarf.FlushError; @@ -673,9 +678,14 @@ pub const File = struct { } pub const RelocInfo = struct { - parent_atom_index: u32, + parent: Parent, offset: u64, addend: u32, + + pub const Parent = union(enum) { + atom_index: u32, + debug_output: DebugInfoOutput, + }; }; /// Get allocated `Nav`'s address in virtual memory. diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 6bf47e2602..f67c7d54d7 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1163,8 +1163,8 @@ fn lowerConst( try self.setSymbolName(sym, name); sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_id + 1)); - const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .none, .{ - .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?, + const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ + .atom_index = self.getAtom(atom_index).getSymbolIndex().?, }); const code = switch (res) { .ok => code_buffer.items, @@ -1235,8 +1235,7 @@ pub fn updateNav( zcu.navSrcLoc(nav_index), nav_init, &code_buffer, - .none, - .{ .parent_atom_index = atom.getSymbolIndex().? }, + .{ .atom_index = atom.getSymbolIndex().? }, ); const code = switch (res) { .ok => code_buffer.items, @@ -1284,7 +1283,7 @@ fn updateLazySymbolAtom( &required_alignment, &code_buffer, .none, - .{ .parent_atom_index = local_sym_index }, + .{ .atom_index = local_sym_index }, ); const code = switch (res) { .ok => code_buffer.items, @@ -1823,7 +1822,10 @@ pub fn getNavVAddr( .@"extern" => |@"extern"| try self.getGlobalSymbol(nav.name.toSlice(ip), @"extern".lib_name.toSlice(ip)), else => self.getAtom(try self.getOrCreateAtomForNav(nav_index)).getSymbolIndex().?, }; - const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; + const atom_index = self.getAtomIndexForSymbol(.{ + .sym_index = reloc_info.parent.atom_index, + .file = null, + }).?; const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; try Atom.addRelocation(self, atom_index, .{ .type = .direct, @@ -1901,7 +1903,10 @@ pub fn getUavVAddr( const this_atom_index = self.uavs.get(uav).?.atom; const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; - const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; + const atom_index = self.getAtomIndexForSymbol(.{ + .sym_index = reloc_info.parent.atom_index, + .file = null, + }).?; const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; try Atom.addRelocation(self, atom_index, .{ .type = .direct, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index bff33ecf14..9ec0fa3012 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -19,8 +19,8 @@ debug_rnglists: DebugRngLists, debug_str: StringSection, pub const UpdateError = error{ + CodegenFail, ReinterpretDeclRef, - IllDefinedMemoryLayout, Unimplemented, OutOfMemory, EndOfStream, @@ -847,10 +847,11 @@ const Entry = struct { unit.len -| (unit.header_len + unit.trailer_len); if (entry_ptr.off + len > end) { if (entry_ptr.next.unwrap()) |next_entry| { - if (entry_ptr.prev.unwrap()) |prev_entry| - unit.getEntry(prev_entry).next = entry_ptr.next - else - unit.first = entry_ptr.next; + if (entry_ptr.prev.unwrap()) |prev_entry| { + const prev_entry_ptr = unit.getEntry(prev_entry); + prev_entry_ptr.next = entry_ptr.next; + try prev_entry_ptr.pad(unit, sec, dwarf); + } else unit.first = entry_ptr.next; const next_entry_ptr = unit.getEntry(next_entry); const entry = next_entry_ptr.prev; next_entry_ptr.prev = entry_ptr.prev; @@ -860,6 +861,7 @@ const Entry = struct { entry_ptr.next = .none; entry_ptr.off = last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len); unit.last = entry; + try last_entry_ptr.pad(unit, sec, dwarf); } try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(len) + unit.trailer_len)); } @@ -1582,6 +1584,18 @@ pub const WipNav = struct { wip_nav.func = func; } + fn externalReloc(wip_nav: *WipNav, sec: *Section, reloc: ExternalReloc) std.mem.Allocator.Error!void { + try sec.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(wip_nav.dwarf.gpa, reloc); + } + + pub fn infoExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void { + try wip_nav.externalReloc(&wip_nav.dwarf.debug_info.section, reloc); + } + + fn frameExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void { + try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc); + } + fn abbrevCode(wip_nav: *WipNav, abbrev_code: AbbrevCode) UpdateError!void { try uleb128(wip_nav.debug_info.writer(wip_nav.dwarf.gpa), try wip_nav.dwarf.refAbbrevCode(abbrev_code)); } @@ -1658,12 +1672,11 @@ pub const WipNav = struct { } fn infoAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void { - const dwarf = wip_nav.dwarf; - try dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{ + try wip_nav.infoExternalReloc(.{ .source_off = @intCast(wip_nav.debug_info.items.len), .target_sym = sym_index, }); - try wip_nav.debug_info.appendNTimes(dwarf.gpa, 0, @intFromEnum(dwarf.address_size)); + try wip_nav.debug_info.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size)); } fn frameExprloc(wip_nav: *WipNav, loc: Loc) UpdateError!void { @@ -1690,12 +1703,11 @@ pub const WipNav = struct { } fn frameAddrSym(wip_nav: *WipNav, sym_index: u32) UpdateError!void { - const dwarf = wip_nav.dwarf; - try dwarf.debug_frame.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(dwarf.gpa, .{ + try wip_nav.frameExternalReloc(.{ .source_off = @intCast(wip_nav.debug_frame.items.len), .target_sym = sym_index, }); - try wip_nav.debug_frame.appendNTimes(dwarf.gpa, 0, @intFromEnum(dwarf.address_size)); + try wip_nav.debug_frame.appendNTimes(wip_nav.dwarf.gpa, 0, @intFromEnum(wip_nav.dwarf.address_size)); } fn getTypeEntry(wip_nav: *WipNav, ty: Type) UpdateError!struct { Unit.Index, Entry.Index } { @@ -1747,6 +1759,27 @@ pub const WipNav = struct { reloc.target_off = @intCast(wip_nav.debug_info.items.len); } + fn blockValue(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc, val: Value) UpdateError!void { + const ty = val.typeOf(wip_nav.pt.zcu); + const diw = wip_nav.debug_info.writer(wip_nav.dwarf.gpa); + const bytes = if (ty.hasRuntimeBits(wip_nav.pt.zcu)) ty.abiSize(wip_nav.pt.zcu) else 0; + try uleb128(diw, bytes); + if (bytes == 0) return; + var dim = wip_nav.debug_info.toManaged(wip_nav.dwarf.gpa); + defer wip_nav.debug_info = dim.moveToUnmanaged(); + switch (try codegen.generateSymbol( + wip_nav.dwarf.bin_file, + wip_nav.pt, + src_loc, + val, + &dim, + .{ .debug_output = .{ .dwarf = wip_nav } }, + )) { + .ok => assert(dim.items.len == wip_nav.debug_info.items.len + bytes), + .fail => unreachable, + } + } + fn enumConstValue( wip_nav: *WipNav, loaded_enum: InternPool.LoadedEnumType, @@ -1812,8 +1845,8 @@ pub const WipNav = struct { } } - fn flush(wip_nav: *WipNav) UpdateError!void { - while (wip_nav.pending_types.popOrNull()) |ty| try wip_nav.dwarf.updateType(wip_nav.pt, ty, &wip_nav.pending_types); + fn flush(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void { + while (wip_nav.pending_types.popOrNull()) |ty| try wip_nav.dwarf.updateType(wip_nav.pt, src_loc, ty, &wip_nav.pending_types); } }; @@ -2169,15 +2202,15 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In try diw.writeByte(accessibility); try wip_nav.strp(nav.name.toSlice(ip)); try wip_nav.strp(nav.fqn.toSlice(ip)); - const ty = nav_val.typeOf(zcu); - const ty_reloc_index = try wip_nav.refForward(); + const nav_ty = nav_val.typeOf(zcu); + const nav_ty_reloc_index = try wip_nav.refForward(); try wip_nav.exprloc(.{ .addr = .{ .sym = sym_index } }); try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse - ty.abiAlignment(zcu).toByteUnits().?); + nav_ty.abiAlignment(zcu).toByteUnits().?); try diw.writeByte(@intFromBool(false)); - wip_nav.finishForward(ty_reloc_index); + wip_nav.finishForward(nav_ty_reloc_index); try wip_nav.abbrevCode(.is_const); - try wip_nav.refType(ty); + try wip_nav.refType(nav_ty); }, .variable => |variable| { assert(file.zir_loaded); @@ -2286,20 +2319,16 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In .source_off = @intCast(wip_nav.debug_frame.items.len), }); try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes()); - try entry.external_relocs.append(dwarf.gpa, .{ - .source_off = @intCast(wip_nav.debug_frame.items.len), - .target_sym = sym_index, - }); - try dfw.writeByteNTimes(0, @intFromEnum(dwarf.address_size)); + try wip_nav.frameAddrSym(sym_index); try dfw.writeByteNTimes(undefined, @intFromEnum(dwarf.address_size)); }, .eh_frame => { try dfw.writeInt(u32, undefined, dwarf.endian); - try entry.external_relocs.append(dwarf.gpa, .{ + try wip_nav.frameExternalReloc(.{ .source_off = @intCast(wip_nav.debug_frame.items.len), .target_sym = sym_index, }); - try dfw.writeByteNTimes(0, dwarf.sectionOffsetBytes()); + try dfw.writeInt(u32, 0, dwarf.endian); try dfw.writeInt(u32, undefined, dwarf.endian); try uleb128(dfw, 0); }, @@ -2479,12 +2508,13 @@ pub fn finishWipNav( } try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items); - try wip_nav.flush(); + try wip_nav.flush(zcu.navSrcLoc(nav_index)); } pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; + const nav_src_loc = zcu.navSrcLoc(nav_index); const nav_val = zcu.navValue(nav_index); const nav = ip.getNav(nav_index); @@ -2507,6 +2537,19 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool return; } + const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { + const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); + break :parent .{ + parent_namespace_ptr.owner_type, + if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) + DW.ACCESS.public + else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) + DW.ACCESS.private + else + unreachable, + }; + } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; + const tree = try file.getTree(dwarf.gpa); const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]); assert(loc.line == zcu.navSrcLine(nav_index)); @@ -2532,8 +2575,341 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); errdefer _ = dwarf.navs.pop(); - switch (ip.indexToKey(nav_val.toIntern())) { - .func => |func| { + + const tag: enum { done, decl_alias, decl_var, decl_const } = switch (ip.indexToKey(nav_val.toIntern())) { + .int_type, + .ptr_type, + .array_type, + .vector_type, + .opt_type, + .anyframe_type, + .error_union_type, + .simple_type, + .anon_struct_type, + .func_type, + .error_set_type, + .inferred_error_set_type, + => .decl_alias, + .struct_type => tag: { + const loaded_struct = ip.loadStructType(nav_val.toIntern()); + if (loaded_struct.zir_index == .none) break :tag .decl_alias; + + const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :tag .decl_alias; + + const value_inst = value_inst: { + const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; + const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); + if (break_inst.tag != .break_inline) break :value_inst null; + assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); + var value_inst = break_inst.data.@"break".operand.toIndex(); + while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { + else => break, + .as_node => value_inst = file.zir.extraData( + Zir.Inst.As, + file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, + ).data.operand.toIndex(), + }; + break :value_inst value_inst; + }; + if (type_inst_info.inst != value_inst) break :tag .decl_alias; + + const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); + if (type_gop.found_existing) { + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); + nav_gop.value_ptr.* = type_gop.value_ptr.*; + } else { + if (nav_gop.found_existing) + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() + else + nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); + type_gop.value_ptr.* = nav_gop.value_ptr.*; + } + wip_nav.entry = nav_gop.value_ptr.*; + + const diw = wip_nav.debug_info.writer(dwarf.gpa); + + switch (loaded_struct.layout) { + .auto, .@"extern" => { + try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct); + try wip_nav.refType(Type.fromInterned(parent_type)); + assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); + try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); + try uleb128(diw, loc.column + 1); + try diw.writeByte(accessibility); + try wip_nav.strp(nav.name.toSlice(ip)); + if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else { + try uleb128(diw, nav_val.toType().abiSize(zcu)); + try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?); + for (0..loaded_struct.field_types.len) |field_index| { + const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); + const field_init = if (loaded_struct.haveFieldInits(ip)) + loaded_struct.fieldInit(ip, field_index) + else + .none; + try wip_nav.abbrevCode(if (is_comptime) + .struct_field_comptime + else if (field_init != .none) + .struct_field_default + else + .struct_field); + if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else { + const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index}); + defer dwarf.gpa.free(field_name); + try wip_nav.strp(field_name); + } + if (is_comptime and field_init == .none) { + // workaround frontend bug + try wip_nav.refType(Type.void); + try wip_nav.blockValue(nav_src_loc, Value.void); + } else { + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); + } + if (field_init != .none) try wip_nav.blockValue(nav_src_loc, Value.fromInterned(field_init)); + } + } + try uleb128(diw, @intFromEnum(AbbrevCode.null)); + } + }, + .@"packed" => { + try wip_nav.abbrevCode(.decl_packed_struct); + try wip_nav.refType(Type.fromInterned(parent_type)); + assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); + try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); + try uleb128(diw, loc.column + 1); + try diw.writeByte(accessibility); + try wip_nav.strp(nav.name.toSlice(ip)); + try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip))); + var field_bit_offset: u16 = 0; + for (0..loaded_struct.field_types.len) |field_index| { + try wip_nav.abbrevCode(.packed_struct_field); + try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip)); + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + try uleb128(diw, field_bit_offset); + field_bit_offset += @intCast(field_type.bitSize(zcu)); + } + try uleb128(diw, @intFromEnum(AbbrevCode.null)); + }, + } + break :tag .done; + }, + .enum_type => tag: { + const loaded_enum = ip.loadEnumType(nav_val.toIntern()); + if (loaded_enum.zir_index == .none) break :tag .decl_alias; + + const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :tag .decl_alias; + + const value_inst = value_inst: { + const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; + const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); + if (break_inst.tag != .break_inline) break :value_inst null; + assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); + var value_inst = break_inst.data.@"break".operand.toIndex(); + while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { + else => break, + .as_node => value_inst = file.zir.extraData( + Zir.Inst.As, + file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, + ).data.operand.toIndex(), + }; + break :value_inst value_inst; + }; + if (type_inst_info.inst != value_inst) break :tag .decl_alias; + + const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); + if (type_gop.found_existing) { + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); + nav_gop.value_ptr.* = type_gop.value_ptr.*; + } else { + if (nav_gop.found_existing) + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() + else + nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); + type_gop.value_ptr.* = nav_gop.value_ptr.*; + } + wip_nav.entry = nav_gop.value_ptr.*; + const diw = wip_nav.debug_info.writer(dwarf.gpa); + try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum); + try wip_nav.refType(Type.fromInterned(parent_type)); + assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); + try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); + try uleb128(diw, loc.column + 1); + try diw.writeByte(accessibility); + try wip_nav.strp(nav.name.toSlice(ip)); + try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty)); + for (0..loaded_enum.names.len) |field_index| { + try wip_nav.enumConstValue(loaded_enum, .{ + .sdata = .signed_enum_field, + .udata = .unsigned_enum_field, + .block = .big_enum_field, + }, field_index); + try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip)); + } + if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null)); + break :tag .done; + }, + .union_type => tag: { + const loaded_union = ip.loadUnionType(nav_val.toIntern()); + + const type_inst_info = loaded_union.zir_index.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :tag .decl_alias; + + const value_inst = value_inst: { + const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; + const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); + if (break_inst.tag != .break_inline) break :value_inst null; + assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); + var value_inst = break_inst.data.@"break".operand.toIndex(); + while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { + else => break, + .as_node => value_inst = file.zir.extraData( + Zir.Inst.As, + file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, + ).data.operand.toIndex(), + }; + break :value_inst value_inst; + }; + if (type_inst_info.inst != value_inst) break :tag .decl_alias; + + const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); + if (type_gop.found_existing) { + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); + nav_gop.value_ptr.* = type_gop.value_ptr.*; + } else { + if (nav_gop.found_existing) + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() + else + nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); + type_gop.value_ptr.* = nav_gop.value_ptr.*; + } + wip_nav.entry = nav_gop.value_ptr.*; + const diw = wip_nav.debug_info.writer(dwarf.gpa); + try wip_nav.abbrevCode(.decl_union); + try wip_nav.refType(Type.fromInterned(parent_type)); + assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); + try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); + try uleb128(diw, loc.column + 1); + try diw.writeByte(accessibility); + try wip_nav.strp(nav.name.toSlice(ip)); + const union_layout = Type.getUnionLayout(loaded_union, zcu); + try uleb128(diw, union_layout.abi_size); + try uleb128(diw, union_layout.abi_align.toByteUnits().?); + const loaded_tag = loaded_union.loadTagType(ip); + if (loaded_union.hasTag(ip)) { + try wip_nav.abbrevCode(.tagged_union); + try wip_nav.infoSectionOffset( + .debug_info, + wip_nav.unit, + wip_nav.entry, + @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), + ); + { + try wip_nav.abbrevCode(.generated_field); + try wip_nav.strp("tag"); + try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty)); + try uleb128(diw, union_layout.tagOffset()); + + for (0..loaded_union.field_types.len) |field_index| { + try wip_nav.enumConstValue(loaded_tag, .{ + .sdata = .signed_tagged_union_field, + .udata = .unsigned_tagged_union_field, + .block = .big_tagged_union_field, + }, field_index); + { + try wip_nav.abbrevCode(.struct_field); + try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); + const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + try uleb128(diw, union_layout.payloadOffset()); + try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse + if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?); + } + try uleb128(diw, @intFromEnum(AbbrevCode.null)); + } + } + try uleb128(diw, @intFromEnum(AbbrevCode.null)); + } else for (0..loaded_union.field_types.len) |field_index| { + try wip_nav.abbrevCode(.untagged_union_field); + try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); + const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); + } + try uleb128(diw, @intFromEnum(AbbrevCode.null)); + break :tag .done; + }, + .opaque_type => tag: { + const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern()); + + const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?; + if (type_inst_info.file != inst_info.file) break :tag .decl_alias; + + const value_inst = value_inst: { + const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; + const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); + if (break_inst.tag != .break_inline) break :value_inst null; + assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); + var value_inst = break_inst.data.@"break".operand.toIndex(); + while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { + else => break, + .as_node => value_inst = file.zir.extraData( + Zir.Inst.As, + file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, + ).data.operand.toIndex(), + }; + break :value_inst value_inst; + }; + if (type_inst_info.inst != value_inst) break :tag .decl_alias; + + const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); + if (type_gop.found_existing) { + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); + nav_gop.value_ptr.* = type_gop.value_ptr.*; + } else { + if (nav_gop.found_existing) + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() + else + nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); + type_gop.value_ptr.* = nav_gop.value_ptr.*; + } + wip_nav.entry = nav_gop.value_ptr.*; + const diw = wip_nav.debug_info.writer(dwarf.gpa); + try wip_nav.abbrevCode(.decl_namespace_struct); + try wip_nav.refType(Type.fromInterned(parent_type)); + assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); + try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); + try uleb128(diw, loc.column + 1); + try diw.writeByte(accessibility); + try wip_nav.strp(nav.name.toSlice(ip)); + try diw.writeByte(@intFromBool(false)); + break :tag .done; + }, + .undef, + .simple_value, + .@"extern", + .int, + .err, + .error_union, + .enum_literal, + .enum_tag, + .empty_enum_value, + .float, + .ptr, + .slice, + .opt, + .aggregate, + .un, + => .decl_const, + .variable => .decl_var, + .func => |func| tag: { if (nav_gop.found_existing) { const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit); const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*); @@ -2557,19 +2933,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); wip_nav.entry = nav_gop.value_ptr.*; - const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { - const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); - break :parent .{ - parent_namespace_ptr.owner_type, - if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.public - else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.private - else - unreachable, - }; - } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; - const func_type = ip.indexToKey(func.ty).func_type; const diw = wip_nav.debug_info.writer(dwarf.gpa); try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args) @@ -2591,121 +2954,21 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args); try uleb128(diw, @intFromEnum(AbbrevCode.null)); } + break :tag .done; }, - .struct_type => done: { - const loaded_struct = ip.loadStructType(nav_val.toIntern()); - - const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { - const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); - break :parent .{ - parent_namespace_ptr.owner_type, - if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.public - else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.private - else - unreachable, - }; - } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; - - decl_struct: { - if (loaded_struct.zir_index == .none) break :decl_struct; - - const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?; - if (type_inst_info.file != inst_info.file) break :decl_struct; - - const value_inst = value_inst: { - const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; - const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); - if (break_inst.tag != .break_inline) break :value_inst null; - assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); - var value_inst = break_inst.data.@"break".operand.toIndex(); - while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { - else => break, - .as_node => value_inst = file.zir.extraData( - Zir.Inst.As, - file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, - ).data.operand.toIndex(), - }; - break :value_inst value_inst; - }; - if (type_inst_info.inst != value_inst) break :decl_struct; - - const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); - if (type_gop.found_existing) { - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); - nav_gop.value_ptr.* = type_gop.value_ptr.*; - } else { - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - type_gop.value_ptr.* = nav_gop.value_ptr.*; - } - wip_nav.entry = nav_gop.value_ptr.*; - - const diw = wip_nav.debug_info.writer(dwarf.gpa); - - switch (loaded_struct.layout) { - .auto, .@"extern" => { - try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else { - try uleb128(diw, nav_val.toType().abiSize(zcu)); - try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?); - for (0..loaded_struct.field_types.len) |field_index| { - const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field); - if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else { - const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index}); - defer dwarf.gpa.free(field_name); - try wip_nav.strp(field_name); - } - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); - } - } - try uleb128(diw, @intFromEnum(AbbrevCode.null)); - } - }, - .@"packed" => { - try wip_nav.abbrevCode(.decl_packed_struct); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip))); - var field_bit_offset: u16 = 0; - for (0..loaded_struct.field_types.len) |field_index| { - try wip_nav.abbrevCode(.packed_struct_field); - try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip)); - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - try uleb128(diw, field_bit_offset); - field_bit_offset += @intCast(field_type.bitSize(zcu)); - } - try uleb128(diw, @intFromEnum(AbbrevCode.null)); - }, - } - break :done; - } - - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - wip_nav.entry = nav_gop.value_ptr.*; + // memoization, not types + .memoized_call => unreachable, + }; + if (tag != .done) { + if (nav_gop.found_existing) + dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() + else + nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); + wip_nav.entry = nav_gop.value_ptr.*; + } + switch (tag) { + .done => {}, + .decl_alias => { const diw = wip_nav.debug_info.writer(dwarf.gpa); try wip_nav.abbrevCode(.decl_alias); try wip_nav.refType(Type.fromInterned(parent_type)); @@ -2716,302 +2979,52 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool try wip_nav.strp(nav.name.toSlice(ip)); try wip_nav.refType(nav_val.toType()); }, - .enum_type => done: { - const loaded_enum = ip.loadEnumType(nav_val.toIntern()); - - const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { - const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); - break :parent .{ - parent_namespace_ptr.owner_type, - if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.public - else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.private - else - unreachable, - }; - } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; - - decl_enum: { - if (loaded_enum.zir_index == .none) break :decl_enum; - - const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?; - if (type_inst_info.file != inst_info.file) break :decl_enum; - - const value_inst = value_inst: { - const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; - const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); - if (break_inst.tag != .break_inline) break :value_inst null; - assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); - var value_inst = break_inst.data.@"break".operand.toIndex(); - while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { - else => break, - .as_node => value_inst = file.zir.extraData( - Zir.Inst.As, - file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, - ).data.operand.toIndex(), - }; - break :value_inst value_inst; - }; - if (type_inst_info.inst != value_inst) break :decl_enum; - - const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); - if (type_gop.found_existing) { - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); - nav_gop.value_ptr.* = type_gop.value_ptr.*; - } else { - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - type_gop.value_ptr.* = nav_gop.value_ptr.*; - } - wip_nav.entry = nav_gop.value_ptr.*; - const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty)); - for (0..loaded_enum.names.len) |field_index| { - try wip_nav.enumConstValue(loaded_enum, .{ - .sdata = .signed_enum_field, - .udata = .unsigned_enum_field, - .block = .big_enum_field, - }, field_index); - try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip)); - } - if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null)); - break :done; - } - - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - wip_nav.entry = nav_gop.value_ptr.*; + .decl_var => { const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(.decl_alias); + try wip_nav.abbrevCode(.decl_var); try wip_nav.refType(Type.fromInterned(parent_type)); assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); try uleb128(diw, loc.column + 1); try diw.writeByte(accessibility); try wip_nav.strp(nav.name.toSlice(ip)); - try wip_nav.refType(nav_val.toType()); + try wip_nav.strp(nav.fqn.toSlice(ip)); + const nav_ty = nav_val.typeOf(zcu); + try wip_nav.refType(nav_ty); + try wip_nav.blockValue(nav_src_loc, nav_val); + try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse + nav_ty.abiAlignment(zcu).toByteUnits().?); + try diw.writeByte(@intFromBool(false)); }, - .union_type => done: { - const loaded_union = ip.loadUnionType(nav_val.toIntern()); - - const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { - const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); - break :parent .{ - parent_namespace_ptr.owner_type, - if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.public - else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.private - else - unreachable, - }; - } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; - - decl_union: { - const type_inst_info = loaded_union.zir_index.resolveFull(ip).?; - if (type_inst_info.file != inst_info.file) break :decl_union; - - const value_inst = value_inst: { - const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; - const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); - if (break_inst.tag != .break_inline) break :value_inst null; - assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); - var value_inst = break_inst.data.@"break".operand.toIndex(); - while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { - else => break, - .as_node => value_inst = file.zir.extraData( - Zir.Inst.As, - file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, - ).data.operand.toIndex(), - }; - break :value_inst value_inst; - }; - if (type_inst_info.inst != value_inst) break :decl_union; - - const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); - if (type_gop.found_existing) { - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); - nav_gop.value_ptr.* = type_gop.value_ptr.*; - } else { - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - type_gop.value_ptr.* = nav_gop.value_ptr.*; - } - wip_nav.entry = nav_gop.value_ptr.*; - const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(.decl_union); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - const union_layout = Type.getUnionLayout(loaded_union, zcu); - try uleb128(diw, union_layout.abi_size); - try uleb128(diw, union_layout.abi_align.toByteUnits().?); - const loaded_tag = loaded_union.loadTagType(ip); - if (loaded_union.hasTag(ip)) { - try wip_nav.abbrevCode(.tagged_union); - try wip_nav.infoSectionOffset( - .debug_info, - wip_nav.unit, - wip_nav.entry, - @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()), - ); - { - try wip_nav.abbrevCode(.generated_field); - try wip_nav.strp("tag"); - try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty)); - try uleb128(diw, union_layout.tagOffset()); - - for (0..loaded_union.field_types.len) |field_index| { - try wip_nav.enumConstValue(loaded_tag, .{ - .sdata = .signed_tagged_union_field, - .udata = .unsigned_tagged_union_field, - .block = .big_tagged_union_field, - }, field_index); - { - try wip_nav.abbrevCode(.struct_field); - try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); - const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - try uleb128(diw, union_layout.payloadOffset()); - try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse - if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?); - } - try uleb128(diw, @intFromEnum(AbbrevCode.null)); - } - } - try uleb128(diw, @intFromEnum(AbbrevCode.null)); - } else for (0..loaded_union.field_types.len) |field_index| { - try wip_nav.abbrevCode(.untagged_union_field); - try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip)); - const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); - } - try uleb128(diw, @intFromEnum(AbbrevCode.null)); - break :done; - } - - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - wip_nav.entry = nav_gop.value_ptr.*; + .decl_const => { const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(.decl_alias); + try wip_nav.abbrevCode(.decl_const); try wip_nav.refType(Type.fromInterned(parent_type)); assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); try uleb128(diw, loc.column + 1); try diw.writeByte(accessibility); try wip_nav.strp(nav.name.toSlice(ip)); - try wip_nav.refType(nav_val.toType()); - }, - .opaque_type => done: { - const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern()); - - const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: { - const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace); - break :parent .{ - parent_namespace_ptr.owner_type, - if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.public - else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu })) - DW.ACCESS.private - else - unreachable, - }; - } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private }; - - decl_opaque: { - const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?; - if (type_inst_info.file != inst_info.file) break :decl_opaque; - - const value_inst = value_inst: { - const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body; - const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1])); - if (break_inst.tag != .break_inline) break :value_inst null; - assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst); - var value_inst = break_inst.data.@"break".operand.toIndex(); - while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) { - else => break, - .as_node => value_inst = file.zir.extraData( - Zir.Inst.As, - file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index, - ).data.operand.toIndex(), - }; - break :value_inst value_inst; - }; - if (type_inst_info.inst != value_inst) break :decl_opaque; - - const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern()); - if (type_gop.found_existing) { - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear(); - nav_gop.value_ptr.* = type_gop.value_ptr.*; - } else { - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - type_gop.value_ptr.* = nav_gop.value_ptr.*; - } - wip_nav.entry = nav_gop.value_ptr.*; - const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(.decl_namespace_struct); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - try diw.writeByte(@intFromBool(false)); - break :done; - } - - if (nav_gop.found_existing) - dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear() - else - nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit); - wip_nav.entry = nav_gop.value_ptr.*; - const diw = wip_nav.debug_info.writer(dwarf.gpa); - try wip_nav.abbrevCode(.decl_alias); - try wip_nav.refType(Type.fromInterned(parent_type)); - assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf)); - try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian); - try uleb128(diw, loc.column + 1); - try diw.writeByte(accessibility); - try wip_nav.strp(nav.name.toSlice(ip)); - try wip_nav.refType(nav_val.toType()); - }, - else => { - _ = dwarf.navs.pop(); - return; + try wip_nav.strp(nav.fqn.toSlice(ip)); + const nav_ty = nav_val.typeOf(zcu); + const nav_ty_reloc_index = try wip_nav.refForward(); + try wip_nav.blockValue(nav_src_loc, nav_val); + try uleb128(diw, nav.status.resolved.alignment.toByteUnits() orelse + nav_ty.abiAlignment(zcu).toByteUnits().?); + try diw.writeByte(@intFromBool(false)); + wip_nav.finishForward(nav_ty_reloc_index); + try wip_nav.abbrevCode(.is_const); + try wip_nav.refType(nav_ty); }, } try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); - try wip_nav.flush(); + try wip_nav.flush(nav_src_loc); } fn updateType( dwarf: *Dwarf, pt: Zcu.PerThread, + src_loc: Zcu.LazySrcLoc, type_index: InternPool.Index, pending_types: *std.ArrayListUnmanaged(InternPool.Index), ) UpdateError!void { @@ -3068,15 +3081,10 @@ fn updateType( const ptr_child_type = Type.fromInterned(ptr_type.child); try wip_nav.abbrevCode(if (ptr_type.sentinel == .none) .ptr_type else .ptr_sentinel_type); try wip_nav.strp(name); - if (ptr_type.sentinel != .none) { - const bytes = ptr_child_type.abiSize(zcu); - try uleb128(diw, bytes); - const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes)); - Value.fromInterned(ptr_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) { - error.IllDefinedMemoryLayout => @memset(mem, 0), - else => |e| return e, - }; - } + if (ptr_type.sentinel != .none) try wip_nav.blockValue( + src_loc, + Value.fromInterned(ptr_type.sentinel), + ); try uleb128(diw, ptr_type.flags.alignment.toByteUnits() orelse ptr_child_type.abiAlignment(zcu).toByteUnits().?); try diw.writeByte(@intFromEnum(ptr_type.flags.address_space)); @@ -3122,15 +3130,10 @@ fn updateType( const array_child_type = Type.fromInterned(array_type.child); try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); try wip_nav.strp(name); - if (array_type.sentinel != .none) { - const bytes = array_child_type.abiSize(zcu); - try uleb128(diw, bytes); - const mem = try wip_nav.debug_info.addManyAsSlice(dwarf.gpa, @intCast(bytes)); - Value.fromInterned(array_type.sentinel).writeToMemory(pt, mem) catch |err| switch (err) { - error.IllDefinedMemoryLayout => @memset(mem, 0), - else => |e| return e, - }; - } + if (array_type.sentinel != .none) try wip_nav.blockValue( + src_loc, + Value.fromInterned(array_type.sentinel), + ); try wip_nav.refType(array_child_type); try wip_nav.abbrevCode(.array_index); try wip_nav.refType(Type.usize); @@ -3360,7 +3363,10 @@ fn updateType( } const field_type = Type.fromInterned(anon_struct_type.types.get(ip)[field_index]); try wip_nav.refType(field_type); - if (comptime_value == .none) { + if (comptime_value != .none) try wip_nav.blockValue( + src_loc, + Value.fromInterned(comptime_value), + ) else { const field_align = field_type.abiAlignment(zcu); field_byte_offset = field_align.forward(field_byte_offset); try uleb128(diw, field_byte_offset); @@ -3427,16 +3433,13 @@ fn updateType( } if (error_set_type.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null)); }, - .inferred_error_set_type => |func| switch (ip.funcIesResolvedUnordered(func)) { - .none => { - try wip_nav.abbrevCode(.void_type); - try wip_nav.strp(name); - }, - else => |ies| { - try wip_nav.abbrevCode(.inferred_error_set_type); - try wip_nav.strp(name); - try wip_nav.refType(Type.fromInterned(ies)); - }, + .inferred_error_set_type => |func| { + try wip_nav.abbrevCode(.inferred_error_set_type); + try wip_nav.strp(name); + try wip_nav.refType(Type.fromInterned(switch (ip.funcIesResolvedUnordered(func)) { + .none => .anyerror_type, + else => |ies| ies, + })); }, // values, not types @@ -3468,6 +3471,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP const zcu = pt.zcu; const ip = &zcu.intern_pool; const ty = Type.fromInterned(type_index); + const ty_src_loc = ty.srcLoc(zcu); log.debug("updateContainerType({}({d}))", .{ ty.fmt(pt), @intFromEnum(type_index) }); const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; @@ -3507,25 +3511,41 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?); for (0..loaded_struct.field_types.len) |field_index| { const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field); + const field_init = if (loaded_struct.haveFieldInits(ip)) + loaded_struct.fieldInit(ip, field_index) + else + .none; + try wip_nav.abbrevCode(if (is_comptime) + .struct_field_comptime + else if (field_init != .none) + .struct_field_default + else + .struct_field); if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else { const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index}); defer dwarf.gpa.free(field_name); try wip_nav.strp(field_name); } - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); + if (is_comptime and field_init == .none) { + // workaround frontend bug + try wip_nav.refType(Type.void); + try wip_nav.blockValue(ty_src_loc, Value.void); + } else { + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); + } + if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); } } try uleb128(diw, @intFromEnum(AbbrevCode.null)); } try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); - try wip_nav.flush(); + try wip_nav.flush(ty_src_loc); } else { const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst)); assert(decl_inst.tag == .extended); @@ -3575,18 +3595,34 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?); for (0..loaded_struct.field_types.len) |field_index| { const is_comptime = loaded_struct.fieldIsComptime(ip, field_index); - try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field); + const field_init = if (loaded_struct.haveFieldInits(ip)) + loaded_struct.fieldInit(ip, field_index) + else + .none; + try wip_nav.abbrevCode(if (is_comptime) + .struct_field_comptime + else if (field_init != .none) + .struct_field_default + else + .struct_field); if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else { const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index}); defer dwarf.gpa.free(field_name); try wip_nav.strp(field_name); } - const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); - try wip_nav.refType(field_type); - if (!is_comptime) { - try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); - try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse - field_type.abiAlignment(zcu).toByteUnits().?); + if (is_comptime and field_init == .none) { + // workaround frontend bug + try wip_nav.refType(Type.void); + try wip_nav.blockValue(ty_src_loc, Value.void); + } else { + const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]); + try wip_nav.refType(field_type); + if (!is_comptime) { + try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]); + try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse + field_type.abiAlignment(zcu).toByteUnits().?); + } + if (field_init != .none) try wip_nav.blockValue(ty_src_loc, Value.fromInterned(field_init)); } } try uleb128(diw, @intFromEnum(AbbrevCode.null)); @@ -3684,7 +3720,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP } try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items); try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.items); - try wip_nav.flush(); + try wip_nav.flush(ty_src_loc); } } @@ -3732,12 +3768,15 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; - if (dwarf.types.get(.anyerror_type)) |entry| { + + { + const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type); + if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main); var wip_nav: WipNav = .{ .dwarf = dwarf, .pt = pt, .unit = .main, - .entry = entry, + .entry = type_gop.value_ptr.*, .any_children = false, .func = .none, .func_sym_index = undefined, @@ -4150,6 +4189,7 @@ const AbbrevCode = enum { decl_packed_struct, decl_union, decl_var, + decl_const, decl_func, decl_empty_func, decl_func_generic, @@ -4164,6 +4204,7 @@ const AbbrevCode = enum { big_enum_field, generated_field, struct_field, + struct_field_default, struct_field_comptime, packed_struct_field, untagged_union_field, @@ -4285,6 +4326,16 @@ const AbbrevCode = enum { .{ .external, .flag }, }, }, + .decl_const = .{ + .tag = .constant, + .attrs = decl_abbrev_common_attrs ++ .{ + .{ .linkage_name, .strp }, + .{ .type, .ref_addr }, + .{ .const_value, .block }, + .{ .alignment, .udata }, + .{ .external, .flag }, + }, + }, .decl_func = .{ .tag = .subprogram, .children = true, @@ -4401,12 +4452,23 @@ const AbbrevCode = enum { .{ .alignment, .udata }, }, }, - .struct_field_comptime = .{ + .struct_field_default = .{ .tag = .member, .attrs = &.{ .{ .name, .strp }, .{ .type, .ref_addr }, + .{ .data_member_location, .udata }, + .{ .alignment, .udata }, + .{ .default_value, .block }, + }, + }, + .struct_field_comptime = .{ + .tag = .member, + .attrs = &.{ .{ .const_expr, .flag_present }, + .{ .name, .strp }, + .{ .type, .ref_addr }, + .{ .const_value, .block }, }, }, .packed_struct_field = .{ diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 0dc4bd9dae..98449d6a5b 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -957,13 +957,26 @@ pub fn getNavVAddr( }; const this_sym = self.symbol(this_sym_index); const vaddr = this_sym.address(.{}, elf_file); - const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; - const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); - try parent_atom.addReloc(elf_file.base.comp.gpa, .{ - .r_offset = reloc_info.offset, - .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type, - .r_addend = reloc_info.addend, - }, self); + switch (reloc_info.parent) { + .atom_index => |atom_index| { + const parent_atom = self.symbol(atom_index).atom(elf_file).?; + const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); + try parent_atom.addReloc(elf_file.base.comp.gpa, .{ + .r_offset = reloc_info.offset, + .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type, + .r_addend = reloc_info.addend, + }, self); + }, + .debug_output => |debug_output| switch (debug_output) { + .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ + .source_off = @intCast(reloc_info.offset), + .target_sym = this_sym_index, + .target_off = reloc_info.addend, + }), + .plan9 => unreachable, + .none => unreachable, + }, + } return @intCast(vaddr); } @@ -976,13 +989,26 @@ pub fn getUavVAddr( const sym_index = self.uavs.get(uav).?.symbol_index; const sym = self.symbol(sym_index); const vaddr = sym.address(.{}, elf_file); - const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; - const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); - try parent_atom.addReloc(elf_file.base.comp.gpa, .{ - .r_offset = reloc_info.offset, - .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, - .r_addend = reloc_info.addend, - }, self); + switch (reloc_info.parent) { + .atom_index => |atom_index| { + const parent_atom = self.symbol(atom_index).atom(elf_file).?; + const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); + try parent_atom.addReloc(elf_file.base.comp.gpa, .{ + .r_offset = reloc_info.offset, + .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, + .r_addend = reloc_info.addend, + }, self); + }, + .debug_output => |debug_output| switch (debug_output) { + .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ + .source_off = @intCast(reloc_info.offset), + .target_sym = sym_index, + .target_off = reloc_info.addend, + }), + .plan9 => unreachable, + .none => unreachable, + }, + } return @intCast(vaddr); } @@ -1600,15 +1626,13 @@ pub fn updateNav( var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, nav_index, sym_index) else null; defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit(); - // TODO implement .debug_info for global variables const res = try codegen.generateSymbol( &elf_file.base, pt, zcu.navSrcLoc(nav_index), Value.fromInterned(nav_init), &code_buffer, - if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, - .{ .parent_atom_index = sym_index }, + .{ .atom_index = sym_index }, ); const code = switch (res) { @@ -1691,7 +1715,7 @@ fn updateLazySymbol( &required_alignment, &code_buffer, .none, - .{ .parent_atom_index = symbol_index }, + .{ .atom_index = symbol_index }, ); const code = switch (res) { .ok => code_buffer.items, @@ -1780,8 +1804,7 @@ fn lowerConst( src_loc, val, &code_buffer, - .{ .none = {} }, - .{ .parent_atom_index = sym_index }, + .{ .atom_index = sym_index }, ); const code = switch (res) { .ok => code_buffer.items, diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 6a771a3b84..3ffa9c4745 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -633,20 +633,33 @@ pub fn getNavVAddr( }; const sym = self.symbols.items[sym_index]; const vaddr = sym.getAddress(.{}, macho_file); - const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?; - try parent_atom.addReloc(macho_file, .{ - .tag = .@"extern", - .offset = @intCast(reloc_info.offset), - .target = sym_index, - .addend = reloc_info.addend, - .type = .unsigned, - .meta = .{ - .pcrel = false, - .has_subtractor = false, - .length = 3, - .symbolnum = @intCast(sym.nlist_idx), + switch (reloc_info.parent) { + .atom_index => |atom_index| { + const parent_atom = self.symbols.items[atom_index].getAtom(macho_file).?; + try parent_atom.addReloc(macho_file, .{ + .tag = .@"extern", + .offset = @intCast(reloc_info.offset), + .target = sym_index, + .addend = reloc_info.addend, + .type = .unsigned, + .meta = .{ + .pcrel = false, + .has_subtractor = false, + .length = 3, + .symbolnum = @intCast(sym.nlist_idx), + }, + }); }, - }); + .debug_output => |debug_output| switch (debug_output) { + .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ + .source_off = @intCast(reloc_info.offset), + .target_sym = sym_index, + .target_off = reloc_info.addend, + }), + .plan9 => unreachable, + .none => unreachable, + }, + } return vaddr; } @@ -659,20 +672,33 @@ pub fn getUavVAddr( const sym_index = self.uavs.get(uav).?.symbol_index; const sym = self.symbols.items[sym_index]; const vaddr = sym.getAddress(.{}, macho_file); - const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?; - try parent_atom.addReloc(macho_file, .{ - .tag = .@"extern", - .offset = @intCast(reloc_info.offset), - .target = sym_index, - .addend = reloc_info.addend, - .type = .unsigned, - .meta = .{ - .pcrel = false, - .has_subtractor = false, - .length = 3, - .symbolnum = @intCast(sym.nlist_idx), + switch (reloc_info.parent) { + .atom_index => |atom_index| { + const parent_atom = self.symbols.items[atom_index].getAtom(macho_file).?; + try parent_atom.addReloc(macho_file, .{ + .tag = .@"extern", + .offset = @intCast(reloc_info.offset), + .target = sym_index, + .addend = reloc_info.addend, + .type = .unsigned, + .meta = .{ + .pcrel = false, + .has_subtractor = false, + .length = 3, + .symbolnum = @intCast(sym.nlist_idx), + }, + }); }, - }); + .debug_output => |debug_output| switch (debug_output) { + .dwarf => |wip_nav| try wip_nav.infoExternalReloc(.{ + .source_off = @intCast(reloc_info.offset), + .target_sym = sym_index, + .target_off = reloc_info.addend, + }), + .plan9 => unreachable, + .none => unreachable, + }, + } return vaddr; } @@ -903,8 +929,7 @@ pub fn updateNav( zcu.navSrcLoc(nav_index), Value.fromInterned(nav_init), &code_buffer, - if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, - .{ .parent_atom_index = sym_index }, + .{ .atom_index = sym_index }, ); const code = switch (res) { @@ -1212,11 +1237,14 @@ fn lowerConst( const name_str = try self.addString(gpa, name); const sym_index = try self.newSymbolWithAtom(gpa, name_str, macho_file); - const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ - .none = {}, - }, .{ - .parent_atom_index = sym_index, - }); + const res = try codegen.generateSymbol( + &macho_file.base, + pt, + src_loc, + val, + &code_buffer, + .{ .atom_index = sym_index }, + ); const code = switch (res) { .ok => code_buffer.items, .fail => |em| return .{ .fail = em }, @@ -1378,7 +1406,7 @@ fn updateLazySymbol( &required_alignment, &code_buffer, .none, - .{ .parent_atom_index = symbol_index }, + .{ .atom_index = symbol_index }, ); const code = switch (res) { .ok => code_buffer.items, diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 080b6853e7..7737c22d05 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -422,10 +422,7 @@ pub fn updateFunc(self: *Plan9, pt: Zcu.PerThread, func_index: InternPool.Index, ); const code = switch (res) { .ok => try code_buffer.toOwnedSlice(), - .fail => |em| { - try zcu.failed_codegen.put(gpa, func.owner_nav, em); - return; - }, + .fail => |em| return zcu.failed_codegen.put(gpa, func.owner_nav, em), }; self.getAtomPtr(atom_idx).code = .{ .code_ptr = null, @@ -463,15 +460,17 @@ pub fn updateNav(self: *Plan9, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); // TODO we need the symbol index for symbol in the table of locals for the containing atom - const res = try codegen.generateSymbol(&self.base, pt, zcu.navSrcLoc(nav_index), nav_init, &code_buffer, .none, .{ - .parent_atom_index = @intCast(atom_idx), - }); + const res = try codegen.generateSymbol( + &self.base, + pt, + zcu.navSrcLoc(nav_index), + nav_init, + &code_buffer, + .{ .atom_index = @intCast(atom_idx) }, + ); const code = switch (res) { .ok => code_buffer.items, - .fail => |em| { - try zcu.failed_codegen.put(gpa, nav_index, em); - return; - }, + .fail => |em| return zcu.failed_codegen.put(gpa, nav_index, em), }; try self.data_nav_table.ensureUnusedCapacity(gpa, 1); const duped_code = try gpa.dupe(u8, code); @@ -1116,7 +1115,7 @@ fn updateLazySymbolAtom(self: *Plan9, pt: Zcu.PerThread, sym: File.LazySymbol, a &required_alignment, &code_buffer, .none, - .{ .parent_atom_index = @as(Atom.Index, @intCast(atom_index)) }, + .{ .atom_index = @intCast(atom_index) }, ); const code = switch (res) { .ok => code_buffer.items, @@ -1373,21 +1372,21 @@ pub fn getNavVAddr( log.debug("getDeclVAddr for {}", .{nav.name.fmt(ip)}); if (ip.indexToKey(nav.status.resolved.val) == .@"extern") { if (nav.name.eqlSlice("etext", ip)) { - try self.addReloc(reloc_info.parent_atom_index, .{ + try self.addReloc(reloc_info.parent.atom_index, .{ .target = undefined, .offset = reloc_info.offset, .addend = reloc_info.addend, .type = .special_etext, }); } else if (nav.name.eqlSlice("edata", ip)) { - try self.addReloc(reloc_info.parent_atom_index, .{ + try self.addReloc(reloc_info.parent.atom_index, .{ .target = undefined, .offset = reloc_info.offset, .addend = reloc_info.addend, .type = .special_edata, }); } else if (nav.name.eqlSlice("end", ip)) { - try self.addReloc(reloc_info.parent_atom_index, .{ + try self.addReloc(reloc_info.parent.atom_index, .{ .target = undefined, .offset = reloc_info.offset, .addend = reloc_info.addend, @@ -1400,7 +1399,7 @@ pub fn getNavVAddr( // otherwise, we just add a relocation const atom_index = try self.seeNav(pt, nav_index); // the parent_atom_index in this case is just the decl_index of the parent - try self.addReloc(reloc_info.parent_atom_index, .{ + try self.addReloc(reloc_info.parent.atom_index, .{ .target = atom_index, .offset = reloc_info.offset, .addend = reloc_info.addend, @@ -1435,7 +1434,7 @@ pub fn lowerUav( gop.value_ptr.* = index; // we need to free name latex var code_buffer = std.ArrayList(u8).init(gpa); - const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index }); + const res = try codegen.generateSymbol(&self.base, pt, src_loc, val, &code_buffer, .{ .atom_index = index }); const code = switch (res) { .ok => code_buffer.items, .fail => |em| return .{ .fail = em }, @@ -1459,7 +1458,7 @@ pub fn lowerUav( pub fn getUavVAddr(self: *Plan9, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { const atom_index = self.uavs.get(uav).?; - try self.addReloc(reloc_info.parent_atom_index, .{ + try self.addReloc(reloc_info.parent.atom_index, .{ .target = atom_index, .offset = reloc_info.offset, .addend = reloc_info.addend, diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index c0d531582f..afb0216fd7 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -277,8 +277,7 @@ pub fn updateNav( zcu.navSrcLoc(nav_index), nav_init, &code_writer, - .none, - .{ .parent_atom_index = @intFromEnum(atom.sym_index) }, + .{ .atom_index = @intFromEnum(atom.sym_index) }, ); const code = switch (res) { @@ -520,10 +519,7 @@ fn lowerConst( src_loc, val, &value_bytes, - .none, - .{ - .parent_atom_index = @intFromEnum(atom.sym_index), - }, + .{ .atom_index = @intFromEnum(atom.sym_index) }, ); break :code switch (result) { .ok => value_bytes.items, @@ -762,8 +758,11 @@ pub fn getNavVAddr( else => {}, } - std.debug.assert(reloc_info.parent_atom_index != 0); - const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?; + std.debug.assert(reloc_info.parent.atom_index != 0); + const atom_index = wasm_file.symbol_atom.get(.{ + .file = zig_object.index, + .index = @enumFromInt(reloc_info.parent.atom_index), + }).?; const atom = wasm_file.getAtomPtr(atom_index); const is_wasm32 = target.cpu.arch == .wasm32; if (ip.isFunctionType(ip.getNav(nav_index).typeOf(ip))) { @@ -800,7 +799,10 @@ pub fn getUavVAddr( const atom_index = zig_object.uavs.get(uav).?; const target_symbol_index = @intFromEnum(wasm_file.getAtom(atom_index).sym_index); - const parent_atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?; + const parent_atom_index = wasm_file.symbol_atom.get(.{ + .file = zig_object.index, + .index = @enumFromInt(reloc_info.parent.atom_index), + }).?; const parent_atom = wasm_file.getAtomPtr(parent_atom_index); const is_wasm32 = target.cpu.arch == .wasm32; const zcu = wasm_file.base.comp.zcu.?; diff --git a/test/src/Debugger.zig b/test/src/Debugger.zig index afa4f6d803..6a930bf9dd 100644 --- a/test/src/Debugger.zig +++ b/test/src/Debugger.zig @@ -107,11 +107,11 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file basic.zig --source-pattern-regexp '_ = basic;' \\process launch - \\frame variable --show-types basic + \\frame variable --show-types -- basic \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types basic + \\(lldb) frame variable --show-types -- basic \\(root.basic.Basic) basic = { \\ (void) void = {} \\ (bool) bool_false = false @@ -243,11 +243,11 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file pointers.zig --source-pattern-regexp '_ = pointers;' \\process launch - \\frame variable --show-types pointers + \\frame variable --show-types -- pointers \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types pointers + \\(lldb) frame variable --show-types -- pointers \\(root.pointers.Pointers) pointers = { \\ (*u32) single = 0x0000000000001010 \\ (*const u32) single_const = 0x0000000000001014 @@ -330,13 +330,13 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file strings.zig --source-pattern-regexp '_ = strings;' \\process launch - \\frame variable --show-types strings.slice - \\frame variable --show-types --format character strings.slice - \\frame variable --show-types --format c-string strings + \\frame variable --show-types -- strings.slice + \\frame variable --show-types --format character -- strings.slice + \\frame variable --show-types --format c-string -- strings \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types strings.slice + \\(lldb) frame variable --show-types -- strings.slice \\([:0]const u8) strings.slice = len=9 { \\ (u8) [0] = 115 \\ (u8) [1] = 108 @@ -348,7 +348,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { \\ (u8) [7] = 92 \\ (u8) [8] = 0 \\} - \\(lldb) frame variable --show-types --format character strings.slice + \\(lldb) frame variable --show-types --format character -- strings.slice \\([:0]const u8) strings.slice = len=9 { \\ (u8) [0] = 's' \\ (u8) [1] = 'l' @@ -360,7 +360,7 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { \\ (u8) [7] = '\\' \\ (u8) [8] = '\x00' \\} - \\(lldb) frame variable --show-types --format c-string strings + \\(lldb) frame variable --show-types --format c-string -- strings \\(root.strings.Strings) strings = { \\ ([*c]const u8) c_ptr = "c_ptr\x07\x08\t" \\ ([*:0]const u8) many_ptr = "many_ptr\n\x0b\x0c" @@ -411,11 +411,28 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file enums.zig --source-pattern-regexp '_ = enums;' \\process launch - \\frame variable --show-types enums + \\expression --show-types -- Enums + \\frame variable --show-types -- enums \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types enums + \\(lldb) expression --show-types -- Enums + \\(type) Enums = struct { + \\ (type) Zero = enum {} + \\ (type) One = enum { + \\ (root.enums.Enums.One) first = .first + \\ } + \\ (type) Two = enum { + \\ (root.enums.Enums.Two) first = .first + \\ (root.enums.Enums.Two) second = .second + \\ } + \\ (type) Three = enum { + \\ (root.enums.Enums.Three) first = .first + \\ (root.enums.Enums.Three) second = .second + \\ (root.enums.Enums.Three) third = .third + \\ } + \\} + \\(lldb) frame variable --show-types -- enums \\(root.enums.Enums) enums = { \\ (root.enums.Enums.Zero) zero = @enumFromInt(13) \\ (root.enums.Enums.One) one = .first @@ -434,12 +451,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { .path = "errors.zig", .source = \\const Errors = struct { - \\ one: error{One} = error.One, - \\ two: error{One,Two} = error.Two, - \\ three: error{One,Two,Three} = error.Three, + \\ const Zero = error{}; + \\ const One = Zero || error{One}; + \\ const Two = One || error{Two}; + \\ const Three = Two || error{Three}; + \\ + \\ one: One = error.One, + \\ two: Two = error.Two, + \\ three: Three = error.Three, \\ any: anyerror = error.Any, \\ any_void: anyerror!void = error.NotVoid, - \\ any_u32: error{One}!u32 = 42, + \\ any_u32: One!u32 = 42, \\}; \\fn testErrors(errors: Errors) void { \\ _ = errors; @@ -453,11 +475,28 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file errors.zig --source-pattern-regexp '_ = errors;' \\process launch - \\frame variable --show-types errors + \\expression --show-types -- Errors + \\frame variable --show-types -- errors \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types errors + \\(lldb) expression --show-types -- Errors + \\(type) Errors = struct { + \\ (type) Zero = error {} + \\ (type) One = error { + \\ (error{One}) One = error.One + \\ } + \\ (type) Two = error { + \\ (error{One,Two}) One = error.One + \\ (error{One,Two}) Two = error.Two + \\ } + \\ (type) Three = error { + \\ (error{One,Two,Three}) One = error.One + \\ (error{One,Two,Three}) Two = error.Two + \\ (error{One,Two,Three}) Three = error.Three + \\ } + \\} + \\(lldb) frame variable --show-types -- errors \\(root.errors.Errors) errors = { \\ (error{One}) one = error.One \\ (error{One,Two}) two = error.Two @@ -496,23 +535,23 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file optionals.zig --source-pattern-regexp 'maybe_u32 = 123;' \\process launch - \\frame variable null_u32 maybe_u32 nonnull_u32 + \\frame variable -- null_u32 maybe_u32 nonnull_u32 \\breakpoint delete --force 1 \\ - \\breakpoint set --file optionals.zig --source-pattern-regexp '_ = .{ &null_u32, &nonnull_u32 };' + \\breakpoint set --file optionals.zig --source-pattern-regexp '_ = \.{ &null_u32, &nonnull_u32 };' \\process continue - \\frame variable --show-types null_u32 maybe_u32 nonnull_u32 + \\frame variable --show-types -- null_u32 maybe_u32 nonnull_u32 \\breakpoint delete --force 2 , &.{ - \\(lldb) frame variable null_u32 maybe_u32 nonnull_u32 + \\(lldb) frame variable -- null_u32 maybe_u32 nonnull_u32 \\(?u32) null_u32 = null \\(?u32) maybe_u32 = null \\(?u32) nonnull_u32 = (nonnull_u32.? = 456) \\(lldb) breakpoint delete --force 1 \\1 breakpoints deleted; 0 breakpoint locations disabled. , - \\(lldb) frame variable --show-types null_u32 maybe_u32 nonnull_u32 + \\(lldb) frame variable --show-types -- null_u32 maybe_u32 nonnull_u32 \\(?u32) null_u32 = null \\(?u32) maybe_u32 = { \\ (u32) maybe_u32.? = 123 @@ -565,11 +604,31 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file unions.zig --source-pattern-regexp '_ = unions;' \\process launch - \\frame variable --show-types unions + \\expression --show-types -- Unions + \\frame variable --show-types -- unions \\breakpoint delete --force 1 , &.{ - \\(lldb) frame variable --show-types unions + \\(lldb) expression --show-types -- Unions + \\(type) Unions = struct { + \\ (type) Untagged = union {} + \\ (type) SafetyTagged = union(enum) { + \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) void = .void + \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) en = .en + \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) eu = .eu + \\ } + \\ (type) Enum = enum { + \\ (root.unions.Unions.Enum) first = .first + \\ (root.unions.Unions.Enum) second = .second + \\ (root.unions.Unions.Enum) third = .third + \\ } + \\ (type) Tagged = union(enum) { + \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) void = .void + \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) en = .en + \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) eu = .eu + \\ } + \\} + \\(lldb) frame variable --show-types -- unions \\(root.unions.Unions) unions = { \\ (root.unions.Unions.Untagged) untagged = { \\ (u32) u32 = 3217031168 @@ -635,17 +694,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { }, \\breakpoint set --file storage.zig --source-pattern-regexp 'local_var = local_var;' \\process launch - \\target variable --show-types --format hex global_const global_var global_threadlocal1 global_threadlocal2 - \\frame variable --show-types --format hex param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var + \\target variable --show-types --format hex -- global_const global_var global_threadlocal1 global_threadlocal2 + \\frame variable --show-types --format hex -- param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var \\breakpoint delete --force 1 , &.{ - \\(lldb) target variable --show-types --format hex global_const global_var global_threadlocal1 global_threadlocal2 + \\(lldb) target variable --show-types --format hex -- global_const global_var global_threadlocal1 global_threadlocal2 \\(u64) global_const = 0x19e50dc8d6002077 \\(u64) global_var = 0xcc423cec08622e32 \\(u64) global_threadlocal1 = 0xb4d643528c042121 \\(u64) global_threadlocal2 = 0x43faea1cf5ad7a22 - \\(lldb) frame variable --show-types --format hex param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var + \\(lldb) frame variable --show-types --format hex -- param1 param2 param3 param4 param5 param6 param7 param8 local_comptime_val local_comptime_ptr.0 local_const local_var \\(u64) param1 = 0x6a607e08125c7e00 \\(u64) param2 = 0x98944cb2a45a8b51 \\(u64) param3 = 0xa320cf10601ee6fb @@ -1240,31 +1299,536 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void { \\ x = fabsf(x); \\ _ = &x; \\} + \\ , }, }, \\breakpoint set --file main.zig --source-pattern-regexp 'x = fabsf\(x\);' \\process launch - \\frame variable x + \\frame variable -- x \\breakpoint delete --force 1 \\ \\breakpoint set --file main.zig --source-pattern-regexp '_ = &x;' \\process continue - \\frame variable x + \\frame variable -- x \\breakpoint delete --force 2 , &.{ - \\(lldb) frame variable x + \\(lldb) frame variable -- x \\(f32) x = -1234.5 \\(lldb) breakpoint delete --force 1 \\1 breakpoints deleted; 0 breakpoint locations disabled. , - \\(lldb) frame variable x + \\(lldb) frame variable -- x \\(f32) x = 1234.5 \\(lldb) breakpoint delete --force 2 \\1 breakpoints deleted; 0 breakpoint locations disabled. }, ); + db.addLldbTest( + "hash_map", + target, + &.{ + .{ + .path = "main.zig", + .source = + \\const std = @import("std"); + \\const Context = struct { + \\ pub fn hash(_: Context, key: u32) Map.Hash { + \\ return key; + \\ } + \\ pub fn eql(_: Context, lhs: u32, rhs: u32) bool { + \\ return lhs == rhs; + \\ } + \\}; + \\const Map = std.HashMap(u32, u32, Context, 63); + \\fn testHashMap(map: Map) void { + \\ _ = map; + \\} + \\pub fn main() !void { + \\ var map = Map.init(std.heap.page_allocator); + \\ defer map.deinit(); + \\ try map.ensureTotalCapacity(10); + \\ map.putAssumeCapacity(0, 1); + \\ map.putAssumeCapacity(2, 3); + \\ map.putAssumeCapacity(4, 5); + \\ map.putAssumeCapacity(6, 7); + \\ map.putAssumeCapacity(8, 9); + \\ + \\ testHashMap(map); + \\} + \\ + , + }, + }, + \\breakpoint set --file main.zig --source-pattern-regexp '_ = map;' + \\process launch + \\frame variable --show-types -- map.unmanaged + \\breakpoint delete --force 1 + , + &.{ + \\(lldb) frame variable --show-types -- map.unmanaged + \\(std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63)) map.unmanaged = len=5 capacity=16 { + \\ (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [0] = { + \\ (u32) key = 0 + \\ (u32) value = 1 + \\ } + \\ (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [1] = { + \\ (u32) key = 2 + \\ (u32) value = 3 + \\ } + \\ (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [2] = { + \\ (u32) key = 4 + \\ (u32) value = 5 + \\ } + \\ (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [3] = { + \\ (u32) key = 6 + \\ (u32) value = 7 + \\ } + \\ (std.hash_map.HashMapUnmanaged(u32,u32,main.Context,63).KV) [4] = { + \\ (u32) key = 8 + \\ (u32) value = 9 + \\ } + \\} + \\(lldb) breakpoint delete --force 1 + \\1 breakpoints deleted; 0 breakpoint locations disabled. + }, + ); + db.addLldbTest( + "multi_array_list", + target, + &.{ + .{ + .path = "main.zig", + .source = + \\const std = @import("std"); + \\const Elem0 = struct { u32, u8, u16 }; + \\const Elem1 = struct { a: u32, b: u8, c: u16 }; + \\fn testMultiArrayList( + \\ list0: std.MultiArrayList(Elem0), + \\ slice0: std.MultiArrayList(Elem0).Slice, + \\ list1: std.MultiArrayList(Elem1), + \\ slice1: std.MultiArrayList(Elem1).Slice, + \\) void { + \\ _ = .{ list0, slice0, list1, slice1 }; + \\} + \\pub fn main() !void { + \\ var list0: std.MultiArrayList(Elem0) = .{}; + \\ defer list0.deinit(std.heap.page_allocator); + \\ try list0.setCapacity(std.heap.page_allocator, 8); + \\ list0.appendAssumeCapacity(.{ 1, 2, 3 }); + \\ list0.appendAssumeCapacity(.{ 4, 5, 6 }); + \\ list0.appendAssumeCapacity(.{ 7, 8, 9 }); + \\ const slice0 = list0.slice(); + \\ + \\ var list1: std.MultiArrayList(Elem1) = .{}; + \\ defer list1.deinit(std.heap.page_allocator); + \\ try list1.setCapacity(std.heap.page_allocator, 12); + \\ list1.appendAssumeCapacity(.{ .a = 1, .b = 2, .c = 3 }); + \\ list1.appendAssumeCapacity(.{ .a = 4, .b = 5, .c = 6 }); + \\ list1.appendAssumeCapacity(.{ .a = 7, .b = 8, .c = 9 }); + \\ const slice1 = list1.slice(); + \\ + \\ testMultiArrayList(list0, slice0, list1, slice1); + \\} + \\ + , + }, + }, + \\breakpoint set --file main.zig --source-pattern-regexp '_ = \.{ list0, slice0, list1, slice1 };' + \\process launch + \\frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.2 + \\frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.2 + \\frame variable --show-types -- list1 list1.len list1.capacity list1[0] list1[1] list1[2] list1.a list1.b list1.c + \\frame variable --show-types -- slice1 slice1.len slice1.capacity slice1[0] slice1[1] slice1[2] slice1.a slice1.b slice1.c + \\breakpoint delete --force 1 + , + &.{ + \\(lldb) frame variable --show-types -- list0 list0.len list0.capacity list0[0] list0[1] list0[2] list0.0 list0.1 list0.2 + \\(std.multi_array_list.MultiArrayList(main.Elem0)) list0 = len=3 capacity=8 { + \\ (root.main.Elem0) [0] = { + \\ (u32) 0 = 1 + \\ (u8) 1 = 2 + \\ (u16) 2 = 3 + \\ } + \\ (root.main.Elem0) [1] = { + \\ (u32) 0 = 4 + \\ (u8) 1 = 5 + \\ (u16) 2 = 6 + \\ } + \\ (root.main.Elem0) [2] = { + \\ (u32) 0 = 7 + \\ (u8) 1 = 8 + \\ (u16) 2 = 9 + \\ } + \\} + \\(usize) list0.len = 3 + \\(usize) list0.capacity = 8 + \\(root.main.Elem0) list0[0] = { + \\ (u32) 0 = 1 + \\ (u8) 1 = 2 + \\ (u16) 2 = 3 + \\} + \\(root.main.Elem0) list0[1] = { + \\ (u32) 0 = 4 + \\ (u8) 1 = 5 + \\ (u16) 2 = 6 + \\} + \\(root.main.Elem0) list0[2] = { + \\ (u32) 0 = 7 + \\ (u8) 1 = 8 + \\ (u16) 2 = 9 + \\} + \\([3]u32) list0.0 = { + \\ (u32) [0] = 1 + \\ (u32) [1] = 4 + \\ (u32) [2] = 7 + \\} + \\([3]u8) list0.1 = { + \\ (u8) [0] = 2 + \\ (u8) [1] = 5 + \\ (u8) [2] = 8 + \\} + \\([3]u16) list0.2 = { + \\ (u16) [0] = 3 + \\ (u16) [1] = 6 + \\ (u16) [2] = 9 + \\} + \\(lldb) frame variable --show-types -- slice0 slice0.len slice0.capacity slice0[0] slice0[1] slice0[2] slice0.0 slice0.1 slice0.2 + \\(std.multi_array_list.MultiArrayList(main.Elem0).Slice) slice0 = len=3 capacity=8 { + \\ (root.main.Elem0) [0] = { + \\ (u32) 0 = 1 + \\ (u8) 1 = 2 + \\ (u16) 2 = 3 + \\ } + \\ (root.main.Elem0) [1] = { + \\ (u32) 0 = 4 + \\ (u8) 1 = 5 + \\ (u16) 2 = 6 + \\ } + \\ (root.main.Elem0) [2] = { + \\ (u32) 0 = 7 + \\ (u8) 1 = 8 + \\ (u16) 2 = 9 + \\ } + \\} + \\(usize) slice0.len = 3 + \\(usize) slice0.capacity = 8 + \\(root.main.Elem0) slice0[0] = { + \\ (u32) 0 = 1 + \\ (u8) 1 = 2 + \\ (u16) 2 = 3 + \\} + \\(root.main.Elem0) slice0[1] = { + \\ (u32) 0 = 4 + \\ (u8) 1 = 5 + \\ (u16) 2 = 6 + \\} + \\(root.main.Elem0) slice0[2] = { + \\ (u32) 0 = 7 + \\ (u8) 1 = 8 + \\ (u16) 2 = 9 + \\} + \\([3]u32) slice0.0 = { + \\ (u32) [0] = 1 + \\ (u32) [1] = 4 + \\ (u32) [2] = 7 + \\} + \\([3]u8) slice0.1 = { + \\ (u8) [0] = 2 + \\ (u8) [1] = 5 + \\ (u8) [2] = 8 + \\} + \\([3]u16) slice0.2 = { + \\ (u16) [0] = 3 + \\ (u16) [1] = 6 + \\ (u16) [2] = 9 + \\} + \\(lldb) frame variable --show-types -- list1 list1.len list1.capacity list1[0] list1[1] list1[2] list1.a list1.b list1.c + \\(std.multi_array_list.MultiArrayList(main.Elem1)) list1 = len=3 capacity=12 { + \\ (root.main.Elem1) [0] = { + \\ (u32) a = 1 + \\ (u8) b = 2 + \\ (u16) c = 3 + \\ } + \\ (root.main.Elem1) [1] = { + \\ (u32) a = 4 + \\ (u8) b = 5 + \\ (u16) c = 6 + \\ } + \\ (root.main.Elem1) [2] = { + \\ (u32) a = 7 + \\ (u8) b = 8 + \\ (u16) c = 9 + \\ } + \\} + \\(usize) list1.len = 3 + \\(usize) list1.capacity = 12 + \\(root.main.Elem1) list1[0] = { + \\ (u32) a = 1 + \\ (u8) b = 2 + \\ (u16) c = 3 + \\} + \\(root.main.Elem1) list1[1] = { + \\ (u32) a = 4 + \\ (u8) b = 5 + \\ (u16) c = 6 + \\} + \\(root.main.Elem1) list1[2] = { + \\ (u32) a = 7 + \\ (u8) b = 8 + \\ (u16) c = 9 + \\} + \\([3]u32) list1.a = { + \\ (u32) [0] = 1 + \\ (u32) [1] = 4 + \\ (u32) [2] = 7 + \\} + \\([3]u8) list1.b = { + \\ (u8) [0] = 2 + \\ (u8) [1] = 5 + \\ (u8) [2] = 8 + \\} + \\([3]u16) list1.c = { + \\ (u16) [0] = 3 + \\ (u16) [1] = 6 + \\ (u16) [2] = 9 + \\} + \\(lldb) frame variable --show-types -- slice1 slice1.len slice1.capacity slice1[0] slice1[1] slice1[2] slice1.a slice1.b slice1.c + \\(std.multi_array_list.MultiArrayList(main.Elem1).Slice) slice1 = len=3 capacity=12 { + \\ (root.main.Elem1) [0] = { + \\ (u32) a = 1 + \\ (u8) b = 2 + \\ (u16) c = 3 + \\ } + \\ (root.main.Elem1) [1] = { + \\ (u32) a = 4 + \\ (u8) b = 5 + \\ (u16) c = 6 + \\ } + \\ (root.main.Elem1) [2] = { + \\ (u32) a = 7 + \\ (u8) b = 8 + \\ (u16) c = 9 + \\ } + \\} + \\(usize) slice1.len = 3 + \\(usize) slice1.capacity = 12 + \\(root.main.Elem1) slice1[0] = { + \\ (u32) a = 1 + \\ (u8) b = 2 + \\ (u16) c = 3 + \\} + \\(root.main.Elem1) slice1[1] = { + \\ (u32) a = 4 + \\ (u8) b = 5 + \\ (u16) c = 6 + \\} + \\(root.main.Elem1) slice1[2] = { + \\ (u32) a = 7 + \\ (u8) b = 8 + \\ (u16) c = 9 + \\} + \\([3]u32) slice1.a = { + \\ (u32) [0] = 1 + \\ (u32) [1] = 4 + \\ (u32) [2] = 7 + \\} + \\([3]u8) slice1.b = { + \\ (u8) [0] = 2 + \\ (u8) [1] = 5 + \\ (u8) [2] = 8 + \\} + \\([3]u16) slice1.c = { + \\ (u16) [0] = 3 + \\ (u16) [1] = 6 + \\ (u16) [2] = 9 + \\} + \\(lldb) breakpoint delete --force 1 + \\1 breakpoints deleted; 0 breakpoint locations disabled. + }, + ); + db.addLldbTest( + "segmented_list", + target, + &.{ + .{ + .path = "main.zig", + .source = + \\const std = @import("std"); + \\fn testSegmentedList() void {} + \\pub fn main() !void { + \\ var list0: std.SegmentedList(usize, 0) = .{}; + \\ defer list0.deinit(std.heap.page_allocator); + \\ + \\ var list1: std.SegmentedList(usize, 1) = .{}; + \\ defer list1.deinit(std.heap.page_allocator); + \\ + \\ var list2: std.SegmentedList(usize, 2) = .{}; + \\ defer list2.deinit(std.heap.page_allocator); + \\ + \\ var list4: std.SegmentedList(usize, 4) = .{}; + \\ defer list4.deinit(std.heap.page_allocator); + \\ + \\ for (0..32) |i| { + \\ try list0.append(std.heap.page_allocator, i); + \\ try list1.append(std.heap.page_allocator, i); + \\ try list2.append(std.heap.page_allocator, i); + \\ try list4.append(std.heap.page_allocator, i); + \\ } + \\ testSegmentedList(); + \\} + \\ + , + }, + }, + \\breakpoint set --file main.zig --source-pattern-regexp 'testSegmentedList\(\);' + \\process launch + \\frame variable -- list0 list1 list2 list4 + \\breakpoint delete --force 1 + , + &.{ + \\(lldb) frame variable -- list0 list1 list2 list4 + \\(std.segmented_list.SegmentedList(usize,0)) list0 = len=32 { + \\ [0] = 0 + \\ [1] = 1 + \\ [2] = 2 + \\ [3] = 3 + \\ [4] = 4 + \\ [5] = 5 + \\ [6] = 6 + \\ [7] = 7 + \\ [8] = 8 + \\ [9] = 9 + \\ [10] = 10 + \\ [11] = 11 + \\ [12] = 12 + \\ [13] = 13 + \\ [14] = 14 + \\ [15] = 15 + \\ [16] = 16 + \\ [17] = 17 + \\ [18] = 18 + \\ [19] = 19 + \\ [20] = 20 + \\ [21] = 21 + \\ [22] = 22 + \\ [23] = 23 + \\ [24] = 24 + \\ [25] = 25 + \\ [26] = 26 + \\ [27] = 27 + \\ [28] = 28 + \\ [29] = 29 + \\ [30] = 30 + \\ [31] = 31 + \\} + \\(std.segmented_list.SegmentedList(usize,1)) list1 = len=32 { + \\ [0] = 0 + \\ [1] = 1 + \\ [2] = 2 + \\ [3] = 3 + \\ [4] = 4 + \\ [5] = 5 + \\ [6] = 6 + \\ [7] = 7 + \\ [8] = 8 + \\ [9] = 9 + \\ [10] = 10 + \\ [11] = 11 + \\ [12] = 12 + \\ [13] = 13 + \\ [14] = 14 + \\ [15] = 15 + \\ [16] = 16 + \\ [17] = 17 + \\ [18] = 18 + \\ [19] = 19 + \\ [20] = 20 + \\ [21] = 21 + \\ [22] = 22 + \\ [23] = 23 + \\ [24] = 24 + \\ [25] = 25 + \\ [26] = 26 + \\ [27] = 27 + \\ [28] = 28 + \\ [29] = 29 + \\ [30] = 30 + \\ [31] = 31 + \\} + \\(std.segmented_list.SegmentedList(usize,2)) list2 = len=32 { + \\ [0] = 0 + \\ [1] = 1 + \\ [2] = 2 + \\ [3] = 3 + \\ [4] = 4 + \\ [5] = 5 + \\ [6] = 6 + \\ [7] = 7 + \\ [8] = 8 + \\ [9] = 9 + \\ [10] = 10 + \\ [11] = 11 + \\ [12] = 12 + \\ [13] = 13 + \\ [14] = 14 + \\ [15] = 15 + \\ [16] = 16 + \\ [17] = 17 + \\ [18] = 18 + \\ [19] = 19 + \\ [20] = 20 + \\ [21] = 21 + \\ [22] = 22 + \\ [23] = 23 + \\ [24] = 24 + \\ [25] = 25 + \\ [26] = 26 + \\ [27] = 27 + \\ [28] = 28 + \\ [29] = 29 + \\ [30] = 30 + \\ [31] = 31 + \\} + \\(std.segmented_list.SegmentedList(usize,4)) list4 = len=32 { + \\ [0] = 0 + \\ [1] = 1 + \\ [2] = 2 + \\ [3] = 3 + \\ [4] = 4 + \\ [5] = 5 + \\ [6] = 6 + \\ [7] = 7 + \\ [8] = 8 + \\ [9] = 9 + \\ [10] = 10 + \\ [11] = 11 + \\ [12] = 12 + \\ [13] = 13 + \\ [14] = 14 + \\ [15] = 15 + \\ [16] = 16 + \\ [17] = 17 + \\ [18] = 18 + \\ [19] = 19 + \\ [20] = 20 + \\ [21] = 21 + \\ [22] = 22 + \\ [23] = 23 + \\ [24] = 24 + \\ [25] = 25 + \\ [26] = 26 + \\ [27] = 27 + \\ [28] = 28 + \\ [29] = 29 + \\ [30] = 30 + \\ [31] = 31 + \\} + \\(lldb) breakpoint delete --force 1 + \\1 breakpoints deleted; 0 breakpoint locations disabled. + }, + ); } const File = struct { import: ?[]const u8 = null, path: []const u8, source: []const u8 };