authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-09-05 15:58:24-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-09-10 12:27:56-04:00
logf34b19825133ff13ea6e9faa576aa253f4d1252c
tree7ddaa6bbe9e5b3788a6976f78243f7a0e98e6535
parent778519bb0d883eed7b2a4e89ae7db68c15271ee3

Dwarf: implement and test decls


4 files changed, 405 insertions(+), 413 deletions(-)

ci/x86_64-linux-debug.sh+1-1
...@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \...@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464
65stage3-debug/bin/zig build test docs \65stage3-debug/bin/zig build test docs \
66 --maxrss 21000000000 \66 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Debug-befcd57a8/bin/lldb \67 -Dlldb=$HOME/deps/lldb-zig/Debug-4a44163df/bin/lldb \
68 -fqemu \68 -fqemu \
69 -fwasmtime \69 -fwasmtime \
70 -Dstatic-llvm \70 -Dstatic-llvm \
ci/x86_64-linux-release.sh+1-1
...@@ -64,7 +64,7 @@ stage3-release/bin/zig build \...@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464
65stage3-release/bin/zig build test docs \65stage3-release/bin/zig build test docs \
66 --maxrss 21000000000 \66 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Release-befcd57a8/bin/lldb \67 -Dlldb=$HOME/deps/lldb-zig/Release-4a44163df/bin/lldb \
68 -fqemu \68 -fqemu \
69 -fwasmtime \69 -fwasmtime \
70 -Dstatic-llvm \70 -Dstatic-llvm \
src/link/Dwarf.zig+340-407
...@@ -2509,6 +2509,19 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2509,6 +2509,19 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
2509 return;2509 return;
2510 }2510 }
25112511
2512 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
2513 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
2514 break :parent .{
2515 parent_namespace_ptr.owner_type,
2516 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
2517 DW.ACCESS.public
2518 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
2519 DW.ACCESS.private
2520 else
2521 unreachable,
2522 };
2523 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
2524
2512 const tree = try file.getTree(dwarf.gpa);2525 const tree = try file.getTree(dwarf.gpa);
2513 const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]);2526 const loc = tree.tokenLocation(0, tree.nodes.items(.main_token)[decl_inst.data.declaration.src_node]);
2514 assert(loc.line == zcu.navSrcLine(nav_index));2527 assert(loc.line == zcu.navSrcLine(nav_index));
...@@ -2534,459 +2547,380 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -2534,459 +2547,380 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25342547
2535 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);2548 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
2536 errdefer _ = dwarf.navs.pop();2549 errdefer _ = dwarf.navs.pop();
2537 switch (ip.indexToKey(nav_val.toIntern())) {
2538 .func => |func| {
2539 if (nav_gop.found_existing) {
2540 const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit);
2541 const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
2542 if (entry_ptr.len >= AbbrevCode.decl_bytes) {
2543 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
2544 if (try dwarf.getFile().?.preadAll(
2545 &abbrev_code_buf,
2546 dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
2547 ) != abbrev_code_buf.len) return error.InputOutput;
2548 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
2549 const abbrev_code: AbbrevCode = @enumFromInt(
2550 std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable,
2551 );
2552 switch (abbrev_code) {
2553 else => unreachable,
2554 .decl_func, .decl_empty_func => return,
2555 .decl_func_generic, .decl_empty_func_generic => {},
2556 }
2557 }
2558 entry_ptr.clear();
2559 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2560 wip_nav.entry = nav_gop.value_ptr.*;
2561
2562 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
2563 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
2564 break :parent .{
2565 parent_namespace_ptr.owner_type,
2566 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
2567 DW.ACCESS.public
2568 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
2569 DW.ACCESS.private
2570 else
2571 unreachable,
2572 };
2573 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
25742550
2575 const func_type = ip.indexToKey(func.ty).func_type;2551 const tag: enum { done, decl_alias } = switch (ip.indexToKey(nav_val.toIntern())) {
2576 const diw = wip_nav.debug_info.writer(dwarf.gpa);2552 .int_type,
2577 try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)2553 .ptr_type,
2578 .decl_func_generic2554 .array_type,
2579 else2555 .vector_type,
2580 .decl_empty_func_generic);2556 .opt_type,
2581 try wip_nav.refType(Type.fromInterned(parent_type));2557 .anyframe_type,
2582 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2558 .error_union_type,
2583 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2559 .simple_type,
2584 try uleb128(diw, loc.column + 1);2560 .anon_struct_type,
2585 try diw.writeByte(accessibility);2561 .func_type,
2586 try wip_nav.strp(nav.name.toSlice(ip));2562 .error_set_type,
2587 try wip_nav.refType(Type.fromInterned(func_type.return_type));2563 .inferred_error_set_type,
2588 if (func_type.param_types.len > 0 or func_type.is_var_args) {2564 => .decl_alias,
2589 for (0..func_type.param_types.len) |param_index| {2565 .struct_type => tag: {
2590 try wip_nav.abbrevCode(.func_type_param);
2591 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2592 }
2593 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
2594 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2595 }
2596 },
2597 .struct_type => done: {
2598 const loaded_struct = ip.loadStructType(nav_val.toIntern());2566 const loaded_struct = ip.loadStructType(nav_val.toIntern());
25992567 if (loaded_struct.zir_index == .none) break :tag .decl_alias;
2600 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {2568
2601 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);2569 const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
2602 break :parent .{2570 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2603 parent_namespace_ptr.owner_type,2571
2604 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))2572 const value_inst = value_inst: {
2605 DW.ACCESS.public2573 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2606 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))2574 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
2607 DW.ACCESS.private2575 if (break_inst.tag != .break_inline) break :value_inst null;
2608 else2576 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
2609 unreachable,2577 var value_inst = break_inst.data.@"break".operand.toIndex();
2578 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
2579 else => break,
2580 .as_node => value_inst = file.zir.extraData(
2581 Zir.Inst.As,
2582 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2583 ).data.operand.toIndex(),
2610 };2584 };
2611 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };2585 break :value_inst value_inst;
26122586 };
2613 decl_struct: {2587 if (type_inst_info.inst != value_inst) break :tag .decl_alias;
2614 if (loaded_struct.zir_index == .none) break :decl_struct;
2615
2616 const type_inst_info = loaded_struct.zir_index.unwrap().?.resolveFull(ip).?;
2617 if (type_inst_info.file != inst_info.file) break :decl_struct;
2618
2619 const value_inst = value_inst: {
2620 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2621 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
2622 if (break_inst.tag != .break_inline) break :value_inst null;
2623 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
2624 var value_inst = break_inst.data.@"break".operand.toIndex();
2625 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
2626 else => break,
2627 .as_node => value_inst = file.zir.extraData(
2628 Zir.Inst.As,
2629 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2630 ).data.operand.toIndex(),
2631 };
2632 break :value_inst value_inst;
2633 };
2634 if (type_inst_info.inst != value_inst) break :decl_struct;
26352588
2636 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2589 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2637 if (type_gop.found_existing) {2590 if (type_gop.found_existing) {
2638 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();2591 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
2639 nav_gop.value_ptr.* = type_gop.value_ptr.*;2592 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2640 } else {2593 } else {
2641 if (nav_gop.found_existing)2594 if (nav_gop.found_existing)
2642 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2595 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2643 else2596 else
2644 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2597 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2645 type_gop.value_ptr.* = nav_gop.value_ptr.*;2598 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2646 }2599 }
2647 wip_nav.entry = nav_gop.value_ptr.*;2600 wip_nav.entry = nav_gop.value_ptr.*;
26482601
2649 const diw = wip_nav.debug_info.writer(dwarf.gpa);2602 const diw = wip_nav.debug_info.writer(dwarf.gpa);
26502603
2651 switch (loaded_struct.layout) {2604 switch (loaded_struct.layout) {
2652 .auto, .@"extern" => {2605 .auto, .@"extern" => {
2653 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);2606 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
2654 try wip_nav.refType(Type.fromInterned(parent_type));2607 try wip_nav.refType(Type.fromInterned(parent_type));
2655 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2608 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2656 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2609 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2657 try uleb128(diw, loc.column + 1);2610 try uleb128(diw, loc.column + 1);
2658 try diw.writeByte(accessibility);2611 try diw.writeByte(accessibility);
2659 try wip_nav.strp(nav.name.toSlice(ip));2612 try wip_nav.strp(nav.name.toSlice(ip));
2660 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {2613 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
2661 try uleb128(diw, nav_val.toType().abiSize(zcu));2614 try uleb128(diw, nav_val.toType().abiSize(zcu));
2662 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);2615 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
2663 for (0..loaded_struct.field_types.len) |field_index| {
2664 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2665 try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
2666 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2667 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2668 defer dwarf.gpa.free(field_name);
2669 try wip_nav.strp(field_name);
2670 }
2671 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2672 try wip_nav.refType(field_type);
2673 if (!is_comptime) {
2674 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
2675 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
2676 field_type.abiAlignment(zcu).toByteUnits().?);
2677 }
2678 }
2679 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2680 }
2681 },
2682 .@"packed" => {
2683 try wip_nav.abbrevCode(.decl_packed_struct);
2684 try wip_nav.refType(Type.fromInterned(parent_type));
2685 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2686 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2687 try uleb128(diw, loc.column + 1);
2688 try diw.writeByte(accessibility);
2689 try wip_nav.strp(nav.name.toSlice(ip));
2690 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
2691 var field_bit_offset: u16 = 0;
2692 for (0..loaded_struct.field_types.len) |field_index| {2616 for (0..loaded_struct.field_types.len) |field_index| {
2693 try wip_nav.abbrevCode(.packed_struct_field);2617 const is_comptime = loaded_struct.fieldIsComptime(ip, field_index);
2694 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));2618 try wip_nav.abbrevCode(if (is_comptime) .struct_field_comptime else .struct_field);
2619 if (loaded_struct.fieldName(ip, field_index).unwrap()) |field_name| try wip_nav.strp(field_name.toSlice(ip)) else {
2620 const field_name = try std.fmt.allocPrint(dwarf.gpa, "{d}", .{field_index});
2621 defer dwarf.gpa.free(field_name);
2622 try wip_nav.strp(field_name);
2623 }
2695 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);2624 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2696 try wip_nav.refType(field_type);2625 try wip_nav.refType(field_type);
2697 try uleb128(diw, field_bit_offset);2626 if (!is_comptime) {
2698 field_bit_offset += @intCast(field_type.bitSize(zcu));2627 try uleb128(diw, loaded_struct.offsets.get(ip)[field_index]);
2628 try uleb128(diw, loaded_struct.fieldAlign(ip, field_index).toByteUnits() orelse
2629 field_type.abiAlignment(zcu).toByteUnits().?);
2630 }
2699 }2631 }
2700 try uleb128(diw, @intFromEnum(AbbrevCode.null));2632 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2701 },2633 }
2702 }2634 },
2703 break :done;2635 .@"packed" => {
2636 try wip_nav.abbrevCode(.decl_packed_struct);
2637 try wip_nav.refType(Type.fromInterned(parent_type));
2638 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2639 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2640 try uleb128(diw, loc.column + 1);
2641 try diw.writeByte(accessibility);
2642 try wip_nav.strp(nav.name.toSlice(ip));
2643 try wip_nav.refType(Type.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
2644 var field_bit_offset: u16 = 0;
2645 for (0..loaded_struct.field_types.len) |field_index| {
2646 try wip_nav.abbrevCode(.packed_struct_field);
2647 try wip_nav.strp(loaded_struct.fieldName(ip, field_index).unwrap().?.toSlice(ip));
2648 const field_type = Type.fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2649 try wip_nav.refType(field_type);
2650 try uleb128(diw, field_bit_offset);
2651 field_bit_offset += @intCast(field_type.bitSize(zcu));
2652 }
2653 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2654 },
2704 }2655 }
2656 break :tag .done;
2657 },
2658 .enum_type => tag: {
2659 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
2660 if (loaded_enum.zir_index == .none) break :tag .decl_alias;
2661
2662 const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
2663 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2664
2665 const value_inst = value_inst: {
2666 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2667 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
2668 if (break_inst.tag != .break_inline) break :value_inst null;
2669 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
2670 var value_inst = break_inst.data.@"break".operand.toIndex();
2671 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
2672 else => break,
2673 .as_node => value_inst = file.zir.extraData(
2674 Zir.Inst.As,
2675 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2676 ).data.operand.toIndex(),
2677 };
2678 break :value_inst value_inst;
2679 };
2680 if (type_inst_info.inst != value_inst) break :tag .decl_alias;
27052681
2706 if (nav_gop.found_existing)2682 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2707 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2683 if (type_gop.found_existing) {
2708 else2684 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
2709 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2685 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2686 } else {
2687 if (nav_gop.found_existing)
2688 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2689 else
2690 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2691 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2692 }
2710 wip_nav.entry = nav_gop.value_ptr.*;2693 wip_nav.entry = nav_gop.value_ptr.*;
2711 const diw = wip_nav.debug_info.writer(dwarf.gpa);2694 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2712 try wip_nav.abbrevCode(.decl_alias);2695 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
2713 try wip_nav.refType(Type.fromInterned(parent_type));2696 try wip_nav.refType(Type.fromInterned(parent_type));
2714 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2697 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2715 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2698 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2716 try uleb128(diw, loc.column + 1);2699 try uleb128(diw, loc.column + 1);
2717 try diw.writeByte(accessibility);2700 try diw.writeByte(accessibility);
2718 try wip_nav.strp(nav.name.toSlice(ip));2701 try wip_nav.strp(nav.name.toSlice(ip));
2719 try wip_nav.refType(nav_val.toType());2702 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
2703 for (0..loaded_enum.names.len) |field_index| {
2704 try wip_nav.enumConstValue(loaded_enum, .{
2705 .sdata = .signed_enum_field,
2706 .udata = .unsigned_enum_field,
2707 .block = .big_enum_field,
2708 }, field_index);
2709 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
2710 }
2711 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
2712 break :tag .done;
2720 },2713 },
2721 .enum_type => done: {2714 .union_type => tag: {
2722 const loaded_enum = ip.loadEnumType(nav_val.toIntern());2715 const loaded_union = ip.loadUnionType(nav_val.toIntern());
2723
2724 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
2725 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
2726 break :parent .{
2727 parent_namespace_ptr.owner_type,
2728 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))
2729 DW.ACCESS.public
2730 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))
2731 DW.ACCESS.private
2732 else
2733 unreachable,
2734 };
2735 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
27362716
2737 decl_enum: {2717 const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
2738 if (loaded_enum.zir_index == .none) break :decl_enum;2718 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
27392719
2740 const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;2720 const value_inst = value_inst: {
2741 if (type_inst_info.file != inst_info.file) break :decl_enum;2721 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
27422722 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
2743 const value_inst = value_inst: {2723 if (break_inst.tag != .break_inline) break :value_inst null;
2744 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2724 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
2745 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2725 var value_inst = break_inst.data.@"break".operand.toIndex();
2746 if (break_inst.tag != .break_inline) break :value_inst null;2726 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
2747 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);2727 else => break,
2748 var value_inst = break_inst.data.@"break".operand.toIndex();2728 .as_node => value_inst = file.zir.extraData(
2749 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {2729 Zir.Inst.As,
2750 else => break,2730 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2751 .as_node => value_inst = file.zir.extraData(2731 ).data.operand.toIndex(),
2752 Zir.Inst.As,
2753 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2754 ).data.operand.toIndex(),
2755 };
2756 break :value_inst value_inst;
2757 };2732 };
2758 if (type_inst_info.inst != value_inst) break :decl_enum;2733 break :value_inst value_inst;
2734 };
2735 if (type_inst_info.inst != value_inst) break :tag .decl_alias;
27592736
2760 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2737 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2761 if (type_gop.found_existing) {2738 if (type_gop.found_existing) {
2762 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();2739 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
2763 nav_gop.value_ptr.* = type_gop.value_ptr.*;2740 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2764 } else {2741 } else {
2765 if (nav_gop.found_existing)2742 if (nav_gop.found_existing)
2766 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2743 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2767 else2744 else
2768 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2745 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2769 type_gop.value_ptr.* = nav_gop.value_ptr.*;2746 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2770 }
2771 wip_nav.entry = nav_gop.value_ptr.*;
2772 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2773 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
2774 try wip_nav.refType(Type.fromInterned(parent_type));
2775 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2776 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2777 try uleb128(diw, loc.column + 1);
2778 try diw.writeByte(accessibility);
2779 try wip_nav.strp(nav.name.toSlice(ip));
2780 try wip_nav.refType(Type.fromInterned(loaded_enum.tag_ty));
2781 for (0..loaded_enum.names.len) |field_index| {
2782 try wip_nav.enumConstValue(loaded_enum, .{
2783 .sdata = .signed_enum_field,
2784 .udata = .unsigned_enum_field,
2785 .block = .big_enum_field,
2786 }, field_index);
2787 try wip_nav.strp(loaded_enum.names.get(ip)[field_index].toSlice(ip));
2788 }
2789 if (loaded_enum.names.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
2790 break :done;
2791 }2747 }
2792
2793 if (nav_gop.found_existing)
2794 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2795 else
2796 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2797 wip_nav.entry = nav_gop.value_ptr.*;2748 wip_nav.entry = nav_gop.value_ptr.*;
2798 const diw = wip_nav.debug_info.writer(dwarf.gpa);2749 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2799 try wip_nav.abbrevCode(.decl_alias);2750 try wip_nav.abbrevCode(.decl_union);
2800 try wip_nav.refType(Type.fromInterned(parent_type));2751 try wip_nav.refType(Type.fromInterned(parent_type));
2801 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2752 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2802 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2753 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2803 try uleb128(diw, loc.column + 1);2754 try uleb128(diw, loc.column + 1);
2804 try diw.writeByte(accessibility);2755 try diw.writeByte(accessibility);
2805 try wip_nav.strp(nav.name.toSlice(ip));2756 try wip_nav.strp(nav.name.toSlice(ip));
2806 try wip_nav.refType(nav_val.toType());2757 const union_layout = Type.getUnionLayout(loaded_union, zcu);
2807 },2758 try uleb128(diw, union_layout.abi_size);
2808 .union_type => done: {2759 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
2809 const loaded_union = ip.loadUnionType(nav_val.toIntern());2760 const loaded_tag = loaded_union.loadTagType(ip);
28102761 if (loaded_union.hasTag(ip)) {
2811 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {2762 try wip_nav.abbrevCode(.tagged_union);
2812 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);2763 try wip_nav.infoSectionOffset(
2813 break :parent .{2764 .debug_info,
2814 parent_namespace_ptr.owner_type,2765 wip_nav.unit,
2815 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))2766 wip_nav.entry,
2816 DW.ACCESS.public2767 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2817 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))2768 );
2818 DW.ACCESS.private2769 {
2819 else2770 try wip_nav.abbrevCode(.generated_field);
2820 unreachable,2771 try wip_nav.strp("tag");
2821 };2772 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
2822 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };2773 try uleb128(diw, union_layout.tagOffset());
28232774
2824 decl_union: {2775 for (0..loaded_union.field_types.len) |field_index| {
2825 const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;2776 try wip_nav.enumConstValue(loaded_tag, .{
2826 if (type_inst_info.file != inst_info.file) break :decl_union;2777 .sdata = .signed_tagged_union_field,
28272778 .udata = .unsigned_tagged_union_field,
2828 const value_inst = value_inst: {2779 .block = .big_tagged_union_field,
2829 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2780 }, field_index);
2830 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2781 {
2831 if (break_inst.tag != .break_inline) break :value_inst null;2782 try wip_nav.abbrevCode(.struct_field);
2832 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);2783 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2833 var value_inst = break_inst.data.@"break".operand.toIndex();2784 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2834 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {2785 try wip_nav.refType(field_type);
2835 else => break,2786 try uleb128(diw, union_layout.payloadOffset());
2836 .as_node => value_inst = file.zir.extraData(2787 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
2837 Zir.Inst.As,2788 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
2838 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2839 ).data.operand.toIndex(),
2840 };
2841 break :value_inst value_inst;
2842 };
2843 if (type_inst_info.inst != value_inst) break :decl_union;
2844
2845 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2846 if (type_gop.found_existing) {
2847 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
2848 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2849 } else {
2850 if (nav_gop.found_existing)
2851 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2852 else
2853 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2854 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2855 }
2856 wip_nav.entry = nav_gop.value_ptr.*;
2857 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2858 try wip_nav.abbrevCode(.decl_union);
2859 try wip_nav.refType(Type.fromInterned(parent_type));
2860 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2861 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2862 try uleb128(diw, loc.column + 1);
2863 try diw.writeByte(accessibility);
2864 try wip_nav.strp(nav.name.toSlice(ip));
2865 const union_layout = Type.getUnionLayout(loaded_union, zcu);
2866 try uleb128(diw, union_layout.abi_size);
2867 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
2868 const loaded_tag = loaded_union.loadTagType(ip);
2869 if (loaded_union.hasTag(ip)) {
2870 try wip_nav.abbrevCode(.tagged_union);
2871 try wip_nav.infoSectionOffset(
2872 .debug_info,
2873 wip_nav.unit,
2874 wip_nav.entry,
2875 @intCast(wip_nav.debug_info.items.len + dwarf.sectionOffsetBytes()),
2876 );
2877 {
2878 try wip_nav.abbrevCode(.generated_field);
2879 try wip_nav.strp("tag");
2880 try wip_nav.refType(Type.fromInterned(loaded_union.enum_tag_ty));
2881 try uleb128(diw, union_layout.tagOffset());
2882
2883 for (0..loaded_union.field_types.len) |field_index| {
2884 try wip_nav.enumConstValue(loaded_tag, .{
2885 .sdata = .signed_tagged_union_field,
2886 .udata = .unsigned_tagged_union_field,
2887 .block = .big_tagged_union_field,
2888 }, field_index);
2889 {
2890 try wip_nav.abbrevCode(.struct_field);
2891 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2892 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2893 try wip_nav.refType(field_type);
2894 try uleb128(diw, union_layout.payloadOffset());
2895 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
2896 if (field_type.isNoReturn(zcu)) 1 else field_type.abiAlignment(zcu).toByteUnits().?);
2897 }
2898 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2899 }2789 }
2790 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2900 }2791 }
2901 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2902 } else for (0..loaded_union.field_types.len) |field_index| {
2903 try wip_nav.abbrevCode(.untagged_union_field);
2904 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2905 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2906 try wip_nav.refType(field_type);
2907 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
2908 field_type.abiAlignment(zcu).toByteUnits().?);
2909 }2792 }
2910 try uleb128(diw, @intFromEnum(AbbrevCode.null));2793 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2911 break :done;2794 } else for (0..loaded_union.field_types.len) |field_index| {
2795 try wip_nav.abbrevCode(.untagged_union_field);
2796 try wip_nav.strp(loaded_tag.names.get(ip)[field_index].toSlice(ip));
2797 const field_type = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
2798 try wip_nav.refType(field_type);
2799 try uleb128(diw, loaded_union.fieldAlign(ip, field_index).toByteUnits() orelse
2800 field_type.abiAlignment(zcu).toByteUnits().?);
2912 }2801 }
2802 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2803 break :tag .done;
2804 },
2805 .opaque_type => tag: {
2806 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
29132807
2914 if (nav_gop.found_existing)2808 const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
2915 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2809 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2916 else2810
2917 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2811 const value_inst = value_inst: {
2812 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;
2813 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));
2814 if (break_inst.tag != .break_inline) break :value_inst null;
2815 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);
2816 var value_inst = break_inst.data.@"break".operand.toIndex();
2817 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {
2818 else => break,
2819 .as_node => value_inst = file.zir.extraData(
2820 Zir.Inst.As,
2821 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,
2822 ).data.operand.toIndex(),
2823 };
2824 break :value_inst value_inst;
2825 };
2826 if (type_inst_info.inst != value_inst) break :tag .decl_alias;
2827
2828 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
2829 if (type_gop.found_existing) {
2830 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();
2831 nav_gop.value_ptr.* = type_gop.value_ptr.*;
2832 } else {
2833 if (nav_gop.found_existing)
2834 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2835 else
2836 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2837 type_gop.value_ptr.* = nav_gop.value_ptr.*;
2838 }
2918 wip_nav.entry = nav_gop.value_ptr.*;2839 wip_nav.entry = nav_gop.value_ptr.*;
2919 const diw = wip_nav.debug_info.writer(dwarf.gpa);2840 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2920 try wip_nav.abbrevCode(.decl_alias);2841 try wip_nav.abbrevCode(.decl_namespace_struct);
2921 try wip_nav.refType(Type.fromInterned(parent_type));2842 try wip_nav.refType(Type.fromInterned(parent_type));
2922 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));2843 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2923 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);2844 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2924 try uleb128(diw, loc.column + 1);2845 try uleb128(diw, loc.column + 1);
2925 try diw.writeByte(accessibility);2846 try diw.writeByte(accessibility);
2926 try wip_nav.strp(nav.name.toSlice(ip));2847 try wip_nav.strp(nav.name.toSlice(ip));
2927 try wip_nav.refType(nav_val.toType());2848 try diw.writeByte(@intFromBool(false));
2849 break :tag .done;
2928 },2850 },
2929 .opaque_type => done: {2851 .undef,
2930 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());2852 .simple_value,
29312853 .variable,
2932 const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {2854 .@"extern",
2933 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);2855 .int,
2934 break :parent .{2856 .err,
2935 parent_namespace_ptr.owner_type,2857 .error_union,
2936 if (parent_namespace_ptr.pub_decls.containsContext(nav_index, .{ .zcu = zcu }))2858 .enum_literal,
2937 DW.ACCESS.public2859 .enum_tag,
2938 else if (parent_namespace_ptr.priv_decls.containsContext(nav_index, .{ .zcu = zcu }))2860 .empty_enum_value,
2939 DW.ACCESS.private2861 .float,
2940 else2862 .ptr,
2941 unreachable,2863 .slice,
2942 };2864 .opt,
2943 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };2865 .aggregate,
29442866 .un,
2945 decl_opaque: {2867 => {
2946 const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;2868 _ = dwarf.navs.pop();
2947 if (type_inst_info.file != inst_info.file) break :decl_opaque;2869 return;
29482870 },
2949 const value_inst = value_inst: {2871 .func => |func| tag: {
2950 const decl_value_body = decl_extra.data.getBodies(@intCast(decl_extra.end), file.zir).value_body;2872 if (nav_gop.found_existing) {
2951 const break_inst = file.zir.instructions.get(@intFromEnum(decl_value_body[decl_value_body.len - 1]));2873 const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit);
2952 if (break_inst.tag != .break_inline) break :value_inst null;2874 const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
2953 assert(file.zir.extraData(Zir.Inst.Break, break_inst.data.@"break".payload_index).data.block_inst == inst_info.inst);2875 if (entry_ptr.len >= AbbrevCode.decl_bytes) {
2954 var value_inst = break_inst.data.@"break".operand.toIndex();2876 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
2955 while (value_inst) |value_inst_index| switch (file.zir.instructions.items(.tag)[@intFromEnum(value_inst_index)]) {2877 if (try dwarf.getFile().?.preadAll(
2956 else => break,2878 &abbrev_code_buf,
2957 .as_node => value_inst = file.zir.extraData(2879 dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
2958 Zir.Inst.As,2880 ) != abbrev_code_buf.len) return error.InputOutput;
2959 file.zir.instructions.items(.data)[@intFromEnum(value_inst_index)].pl_node.payload_index,2881 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
2960 ).data.operand.toIndex(),2882 const abbrev_code: AbbrevCode = @enumFromInt(
2961 };2883 std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable,
2962 break :value_inst value_inst;2884 );
2963 };2885 switch (abbrev_code) {
2964 if (type_inst_info.inst != value_inst) break :decl_opaque;2886 else => unreachable,
2887 .decl_func, .decl_empty_func => return,
2888 .decl_func_generic, .decl_empty_func_generic => {},
2889 }
2890 }
2891 entry_ptr.clear();
2892 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2893 wip_nav.entry = nav_gop.value_ptr.*;
29652894
2966 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());2895 const func_type = ip.indexToKey(func.ty).func_type;
2967 if (type_gop.found_existing) {2896 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2968 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(type_gop.value_ptr.*).clear();2897 try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
2969 nav_gop.value_ptr.* = type_gop.value_ptr.*;2898 .decl_func_generic
2970 } else {2899 else
2971 if (nav_gop.found_existing)2900 .decl_empty_func_generic);
2972 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2901 try wip_nav.refType(Type.fromInterned(parent_type));
2973 else2902 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2974 nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);2903 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2975 type_gop.value_ptr.* = nav_gop.value_ptr.*;2904 try uleb128(diw, loc.column + 1);
2905 try diw.writeByte(accessibility);
2906 try wip_nav.strp(nav.name.toSlice(ip));
2907 try wip_nav.refType(Type.fromInterned(func_type.return_type));
2908 if (func_type.param_types.len > 0 or func_type.is_var_args) {
2909 for (0..func_type.param_types.len) |param_index| {
2910 try wip_nav.abbrevCode(.func_type_param);
2911 try wip_nav.refType(Type.fromInterned(func_type.param_types.get(ip)[param_index]));
2976 }2912 }
2977 wip_nav.entry = nav_gop.value_ptr.*;2913 if (func_type.is_var_args) try wip_nav.abbrevCode(.is_var_args);
2978 const diw = wip_nav.debug_info.writer(dwarf.gpa);2914 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2979 try wip_nav.abbrevCode(.decl_namespace_struct);
2980 try wip_nav.refType(Type.fromInterned(parent_type));
2981 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2982 try diw.writeInt(u32, @intCast(loc.line + 1), dwarf.endian);
2983 try uleb128(diw, loc.column + 1);
2984 try diw.writeByte(accessibility);
2985 try wip_nav.strp(nav.name.toSlice(ip));
2986 try diw.writeByte(@intFromBool(false));
2987 break :done;
2988 }2915 }
29892916 break :tag .done;
2917 },
2918 // memoization, not types
2919 .memoized_call => unreachable,
2920 };
2921 switch (tag) {
2922 .done => {},
2923 .decl_alias => {
2990 if (nav_gop.found_existing)2924 if (nav_gop.found_existing)
2991 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()2925 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear()
2992 else2926 else
...@@ -3002,10 +2936,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool...@@ -3002,10 +2936,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
3002 try wip_nav.strp(nav.name.toSlice(ip));2936 try wip_nav.strp(nav.name.toSlice(ip));
3003 try wip_nav.refType(nav_val.toType());2937 try wip_nav.refType(nav_val.toType());
3004 },2938 },
3005 else => {
3006 _ = dwarf.navs.pop();
3007 return;
3008 },
3009 }2939 }
3010 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);2940 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
3011 try wip_nav.flush();2941 try wip_nav.flush();
...@@ -3734,12 +3664,15 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A...@@ -3734,12 +3664,15 @@ fn refAbbrevCode(dwarf: *Dwarf, abbrev_code: AbbrevCode) UpdateError!@typeInfo(A
3734pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {3664pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
3735 const zcu = pt.zcu;3665 const zcu = pt.zcu;
3736 const ip = &zcu.intern_pool;3666 const ip = &zcu.intern_pool;
3737 if (dwarf.types.get(.anyerror_type)) |entry| {3667
3668 {
3669 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, .anyerror_type);
3670 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(.main);
3738 var wip_nav: WipNav = .{3671 var wip_nav: WipNav = .{
3739 .dwarf = dwarf,3672 .dwarf = dwarf,
3740 .pt = pt,3673 .pt = pt,
3741 .unit = .main,3674 .unit = .main,
3742 .entry = entry,3675 .entry = type_gop.value_ptr.*,
3743 .any_children = false,3676 .any_children = false,
3744 .func = .none,3677 .func = .none,
3745 .func_sym_index = undefined,3678 .func_sym_index = undefined,
test/src/Debugger.zig+63-4
...@@ -411,10 +411,27 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -411,10 +411,27 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
411 },411 },
412 \\breakpoint set --file enums.zig --source-pattern-regexp '_ = enums;'412 \\breakpoint set --file enums.zig --source-pattern-regexp '_ = enums;'
413 \\process launch413 \\process launch
414 \\expression --show-types -- Enums
414 \\frame variable --show-types enums415 \\frame variable --show-types enums
415 \\breakpoint delete --force 1416 \\breakpoint delete --force 1
416 ,417 ,
417 &.{418 &.{
419 \\(lldb) expression --show-types -- Enums
420 \\(type) Enums = struct {
421 \\ (type) Zero = enum {}
422 \\ (type) One = enum {
423 \\ (root.enums.Enums.One) first = .first
424 \\ }
425 \\ (type) Two = enum {
426 \\ (root.enums.Enums.Two) first = .first
427 \\ (root.enums.Enums.Two) second = .second
428 \\ }
429 \\ (type) Three = enum {
430 \\ (root.enums.Enums.Three) first = .first
431 \\ (root.enums.Enums.Three) second = .second
432 \\ (root.enums.Enums.Three) third = .third
433 \\ }
434 \\}
418 \\(lldb) frame variable --show-types enums435 \\(lldb) frame variable --show-types enums
419 \\(root.enums.Enums) enums = {436 \\(root.enums.Enums) enums = {
420 \\ (root.enums.Enums.Zero) zero = @enumFromInt(13)437 \\ (root.enums.Enums.Zero) zero = @enumFromInt(13)
...@@ -434,12 +451,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -434,12 +451,17 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
434 .path = "errors.zig",451 .path = "errors.zig",
435 .source =452 .source =
436 \\const Errors = struct {453 \\const Errors = struct {
437 \\ one: error{One} = error.One,454 \\ const Zero = error{};
438 \\ two: error{One,Two} = error.Two,455 \\ const One = Zero || error{One};
439 \\ three: error{One,Two,Three} = error.Three,456 \\ const Two = One || error{Two};
457 \\ const Three = Two || error{Three};
458 \\
459 \\ one: One = error.One,
460 \\ two: Two = error.Two,
461 \\ three: Three = error.Three,
440 \\ any: anyerror = error.Any,462 \\ any: anyerror = error.Any,
441 \\ any_void: anyerror!void = error.NotVoid,463 \\ any_void: anyerror!void = error.NotVoid,
442 \\ any_u32: error{One}!u32 = 42,464 \\ any_u32: One!u32 = 42,
443 \\};465 \\};
444 \\fn testErrors(errors: Errors) void {466 \\fn testErrors(errors: Errors) void {
445 \\ _ = errors;467 \\ _ = errors;
...@@ -453,10 +475,27 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -453,10 +475,27 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
453 },475 },
454 \\breakpoint set --file errors.zig --source-pattern-regexp '_ = errors;'476 \\breakpoint set --file errors.zig --source-pattern-regexp '_ = errors;'
455 \\process launch477 \\process launch
478 \\expression --show-types -- Errors
456 \\frame variable --show-types errors479 \\frame variable --show-types errors
457 \\breakpoint delete --force 1480 \\breakpoint delete --force 1
458 ,481 ,
459 &.{482 &.{
483 \\(lldb) expression --show-types -- Errors
484 \\(type) Errors = struct {
485 \\ (type) Zero = error {}
486 \\ (type) One = error {
487 \\ (error{One}) One = error.One
488 \\ }
489 \\ (type) Two = error {
490 \\ (error{One,Two}) One = error.One
491 \\ (error{One,Two}) Two = error.Two
492 \\ }
493 \\ (type) Three = error {
494 \\ (error{One,Two,Three}) One = error.One
495 \\ (error{One,Two,Three}) Two = error.Two
496 \\ (error{One,Two,Three}) Three = error.Three
497 \\ }
498 \\}
460 \\(lldb) frame variable --show-types errors499 \\(lldb) frame variable --show-types errors
461 \\(root.errors.Errors) errors = {500 \\(root.errors.Errors) errors = {
462 \\ (error{One}) one = error.One501 \\ (error{One}) one = error.One
...@@ -565,10 +604,30 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {...@@ -565,10 +604,30 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
565 },604 },
566 \\breakpoint set --file unions.zig --source-pattern-regexp '_ = unions;'605 \\breakpoint set --file unions.zig --source-pattern-regexp '_ = unions;'
567 \\process launch606 \\process launch
607 \\expression --show-types -- Unions
568 \\frame variable --show-types unions608 \\frame variable --show-types unions
569 \\breakpoint delete --force 1609 \\breakpoint delete --force 1
570 ,610 ,
571 &.{611 &.{
612 \\(lldb) expression --show-types -- Unions
613 \\(type) Unions = struct {
614 \\ (type) Untagged = union {}
615 \\ (type) SafetyTagged = union(enum) {
616 \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) void = .void
617 \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) en = .en
618 \\ (@typeInfo(unions.Unions.SafetyTagged).@"union".tag_type.?) eu = .eu
619 \\ }
620 \\ (type) Enum = enum {
621 \\ (root.unions.Unions.Enum) first = .first
622 \\ (root.unions.Unions.Enum) second = .second
623 \\ (root.unions.Unions.Enum) third = .third
624 \\ }
625 \\ (type) Tagged = union(enum) {
626 \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) void = .void
627 \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) en = .en
628 \\ (@typeInfo(unions.Unions.Tagged).@"union".tag_type.?) eu = .eu
629 \\ }
630 \\}
572 \\(lldb) frame variable --show-types unions631 \\(lldb) frame variable --show-types unions
573 \\(root.unions.Unions) unions = {632 \\(root.unions.Unions) unions = {
574 \\ (root.unions.Unions.Untagged) untagged = {633 \\ (root.unions.Unions.Untagged) untagged = {