Commit 98f63990d5

mlugg <mlugg@mlugg.co.uk>
2024-12-17 23:52:30
Zir: store declaration column number so Dwarf doesn't need to load the AST
Resolves: #21227
1 parent 737154f
Changed files (3)
lib
src
lib/std/zig/AstGen.zig
@@ -4151,6 +4151,8 @@ fn fnDecl(
     };
     defer fn_gz.unstack();
 
+    const decl_column = astgen.source_column;
+
     // Set this now, since parameter types, return type, etc may be generic.
     const prev_within_fn = astgen.within_fn;
     defer astgen.within_fn = prev_within_fn;
@@ -4523,6 +4525,7 @@ fn fnDecl(
         hash,
         .{ .named = fn_name_token },
         decl_gz.decl_line,
+        decl_column,
         is_pub,
         is_export,
         &decl_gz,
@@ -4568,6 +4571,8 @@ fn globalVarDecl(
     };
     defer block_scope.unstack();
 
+    const decl_column = astgen.source_column;
+
     const is_pub = var_decl.visib_token != null;
     const is_export = blk: {
         const maybe_export_token = var_decl.extern_export_token orelse break :blk false;
@@ -4693,6 +4698,7 @@ fn globalVarDecl(
         hash,
         .{ .named = name_token },
         block_scope.decl_line,
+        decl_column,
         is_pub,
         is_export,
         &block_scope,
@@ -4738,6 +4744,8 @@ fn comptimeDecl(
     };
     defer decl_block.unstack();
 
+    const decl_column = astgen.source_column;
+
     const block_result = try fullBodyExpr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node, .normal);
     if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) {
         _ = try decl_block.addBreak(.break_inline, decl_inst, .void_value);
@@ -4750,6 +4758,7 @@ fn comptimeDecl(
         hash,
         .@"comptime",
         decl_block.decl_line,
+        decl_column,
         false,
         false,
         &decl_block,
@@ -4797,6 +4806,8 @@ fn usingnamespaceDecl(
     };
     defer decl_block.unstack();
 
+    const decl_column = astgen.source_column;
+
     const namespace_inst = try typeExpr(&decl_block, &decl_block.base, type_expr);
     _ = try decl_block.addBreak(.break_inline, decl_inst, namespace_inst);
 
@@ -4807,6 +4818,7 @@ fn usingnamespaceDecl(
         hash,
         .@"usingnamespace",
         decl_block.decl_line,
+        decl_column,
         is_pub,
         false,
         &decl_block,
@@ -4849,6 +4861,8 @@ fn testDecl(
     };
     defer decl_block.unstack();
 
+    const decl_column = astgen.source_column;
+
     const main_tokens = tree.nodes.items(.main_token);
     const token_tags = tree.tokens.items(.tag);
     const test_token = main_tokens[node];
@@ -5013,6 +5027,7 @@ fn testDecl(
         hash,
         test_name,
         decl_block.decl_line,
+        decl_column,
         false,
         false,
         &decl_block,
@@ -14013,6 +14028,7 @@ fn addFailedDeclaration(
         @splat(0), // use a fixed hash to represent an AstGen failure; we don't care about source changes if AstGen still failed!
         name,
         gz.astgen.source_line,
+        gz.astgen.source_column,
         is_pub,
         false, // we don't care about exports since semantic analysis will fail
         &decl_gz,
@@ -14027,6 +14043,7 @@ fn setDeclaration(
     src_hash: std.zig.SrcHash,
     name: DeclarationName,
     src_line: u32,
+    src_column: u32,
     is_pub: bool,
     is_export: bool,
     value_gz: *GenZir,
@@ -14079,6 +14096,7 @@ fn setDeclaration(
             .@"usingnamespace" => .@"usingnamespace",
         },
         .src_line = src_line,
+        .src_column = src_column,
         .flags = .{
             .value_body_len = @intCast(value_len),
             .is_pub = is_pub,
lib/std/zig/Zir.zig
@@ -2636,6 +2636,7 @@ pub const Inst = struct {
         /// The name of this `Decl`. Also indicates whether it is a test, comptime block, etc.
         name: Name,
         src_line: u32,
+        src_column: u32,
         flags: Flags,
 
         pub const Flags = packed struct(u32) {
src/link/Dwarf.zig
@@ -2259,25 +2259,20 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
     switch (ip.indexToKey(nav_val.toIntern())) {
         else => {
             assert(file.zir_loaded);
-            const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
-            assert(decl_inst.tag == .declaration);
-            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));
+            const decl = file.zir.getDeclaration(inst_info.inst)[0];
 
             const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
-                const decl_extra = file.zir.extraData(Zir.Inst.Declaration, decl_inst.data.declaration.payload_index).data;
                 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
                 break :parent .{
                     parent_namespace_ptr.owner_type,
-                    switch (decl_extra.name) {
+                    switch (decl.name) {
                         .@"comptime",
                         .@"usingnamespace",
                         .unnamed_test,
                         => DW.ACCESS.private,
-                        _ => if (decl_extra.name.isNamedTest(file.zir))
+                        _ => if (decl.name.isNamedTest(file.zir))
                             DW.ACCESS.private
-                        else if (decl_extra.flags.is_pub)
+                        else if (decl.flags.is_pub)
                             DW.ACCESS.public
                         else
                             DW.ACCESS.private,
@@ -2289,8 +2284,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
             try wip_nav.abbrevCode(.decl_var);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.strp(nav.fqn.toSlice(ip));
@@ -2306,25 +2301,20 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
         },
         .variable => |variable| {
             assert(file.zir_loaded);
-            const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
-            assert(decl_inst.tag == .declaration);
-            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));
+            const decl = file.zir.getDeclaration(inst_info.inst)[0];
 
             const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
-                const decl_extra = file.zir.extraData(Zir.Inst.Declaration, decl_inst.data.declaration.payload_index).data;
                 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
                 break :parent .{
                     parent_namespace_ptr.owner_type,
-                    switch (decl_extra.name) {
+                    switch (decl.name) {
                         .@"comptime",
                         .@"usingnamespace",
                         .unnamed_test,
                         => DW.ACCESS.private,
-                        _ => if (decl_extra.name.isNamedTest(file.zir))
+                        _ => if (decl.name.isNamedTest(file.zir))
                             DW.ACCESS.private
-                        else if (decl_extra.flags.is_pub)
+                        else if (decl.flags.is_pub)
                             DW.ACCESS.public
                         else
                             DW.ACCESS.private,
@@ -2336,8 +2326,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
             try wip_nav.abbrevCode(.decl_var);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.strp(nav.fqn.toSlice(ip));
@@ -2351,25 +2341,20 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
         },
         .func => |func| {
             assert(file.zir_loaded);
-            const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
-            assert(decl_inst.tag == .declaration);
-            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));
+            const decl = file.zir.getDeclaration(inst_info.inst)[0];
 
             const parent_type, const accessibility: u8 = if (nav.analysis_owner.unwrap()) |cau| parent: {
-                const decl_extra = file.zir.extraData(Zir.Inst.Declaration, decl_inst.data.declaration.payload_index).data;
                 const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
                 break :parent .{
                     parent_namespace_ptr.owner_type,
-                    switch (decl_extra.name) {
+                    switch (decl.name) {
                         .@"comptime",
                         .@"usingnamespace",
                         .unnamed_test,
                         => DW.ACCESS.private,
-                        _ => if (decl_extra.name.isNamedTest(file.zir))
+                        _ => if (decl.name.isNamedTest(file.zir))
                             DW.ACCESS.private
-                        else if (decl_extra.flags.is_pub)
+                        else if (decl.flags.is_pub)
                             DW.ACCESS.public
                         else
                             DW.ACCESS.private,
@@ -2426,8 +2411,8 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
             try wip_nav.abbrevCode(.decl_func);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.strp(nav.fqn.toSlice(ip));
@@ -2476,7 +2461,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
                 try dlw.writeByte(DW.LNS.set_column);
                 try uleb128(dlw, func.lbrace_column + 1);
 
-                try wip_nav.advancePCAndLine(@intCast(loc.line + func.lbrace_line), 0);
+                try wip_nav.advancePCAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
             }
         },
     }
@@ -2600,14 +2585,12 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
     const inst_info = nav.srcInst(ip).resolveFull(ip).?;
     const file = zcu.fileByIndex(inst_info.file);
     assert(file.zir_loaded);
-    const decl_inst = file.zir.instructions.get(@intFromEnum(inst_info.inst));
-    assert(decl_inst.tag == .declaration);
-    const decl_extra = file.zir.extraData(Zir.Inst.Declaration, decl_inst.data.declaration.payload_index);
+    const decl = file.zir.getDeclaration(inst_info.inst)[0];
 
-    const is_test = switch (decl_extra.data.name) {
+    const is_test = switch (decl.name) {
         .unnamed_test => true,
         .@"comptime", .@"usingnamespace" => false,
-        _ => decl_extra.data.name.isNamedTest(file.zir),
+        _ => decl.name.isNamedTest(file.zir),
     };
     if (is_test) {
         // This isn't actually a comptime Nav! It's a test, so it'll definitely never be referenced at comptime.
@@ -2618,14 +2601,10 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
         const parent_namespace_ptr = ip.namespacePtr(ip.getCau(cau).namespace);
         break :parent .{
             parent_namespace_ptr.owner_type,
-            if (decl_extra.data.flags.is_pub) DW.ACCESS.public else DW.ACCESS.private,
+            if (decl.flags.is_pub) DW.ACCESS.public else DW.ACCESS.private,
         };
     } 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));
-
     var wip_nav: WipNav = .{
         .dwarf = dwarf,
         .pt = pt,
@@ -2688,8 +2667,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
                     try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
                     try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+                    try uleb128(diw, decl.src_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 {
@@ -2748,8 +2727,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
                     try wip_nav.abbrevCode(.decl_packed_struct);
                     try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+                    try uleb128(diw, decl.src_column + 1);
                     try diw.writeByte(accessibility);
                     try wip_nav.strp(nav.name.toSlice(ip));
                     try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
@@ -2790,8 +2769,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
             try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
@@ -2828,8 +2807,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
             try wip_nav.abbrevCode(.decl_union);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             const union_layout = Type.getUnionLayout(loaded_union, zcu);
@@ -2902,8 +2881,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
             try wip_nav.abbrevCode(.decl_namespace_struct);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try diw.writeByte(@intFromBool(false));
@@ -2958,8 +2937,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
                 .decl_empty_func_generic);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.refType(.fromInterned(func_type.return_type));
@@ -2990,8 +2969,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
             try wip_nav.abbrevCode(.decl_alias);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.refType(nav_val.toType());
@@ -3001,8 +2980,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
             try wip_nav.abbrevCode(.decl_var);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.strp(nav.fqn.toSlice(ip));
@@ -3028,8 +3007,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
                 .decl_const);
             try wip_nav.refType(.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.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
+            try uleb128(diw, decl.src_column + 1);
             try diw.writeByte(accessibility);
             try wip_nav.strp(nav.name.toSlice(ip));
             try wip_nav.strp(nav.fqn.toSlice(ip));