authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-01 21:57:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-01 21:57:52-07:00
logeadcefc124b4ee61c99c8ed97434ed26e24c5f83
treee76e08b8c4411a8ef609efdef020e9731e43de4b
parent6248e2a5609cb9e30588f8bcd0000f5d5aa5fdee

stage2: dbg_stmt ZIR instructions have line/col

instead of node indexes. * AstGen: dbg_stmt instructions now have line and column indexes, relative to the parent declaration. This allows codegen to emit debug info without having the source bytes, tokens, or AST nodes loaded in memory. * ZIR: each decl has the absolute line number. This allows computing line numbers from offsets without consulting source code bytes. Memory management: creating a function definition does not prematurely set the Decl arena. Instead the function is allocated with the general purpose allocator. Codegen no longer looks at source code bytes for any reason. They can remain unloaded from disk.

8 files changed, 253 insertions(+), 130 deletions(-)

BRANCH_TODO-1
......@@ -1,4 +1,3 @@
1 * modify dbg_stmt ZIR instructions to have line/column rather than node indexes
21 * decouple AstGen from Module, Compilation
32 * AstGen threadlocal
43 * extern "foo" for vars and for functions
src/AstGen.zig+61-12
......@@ -94,6 +94,7 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir {
9494 .force_comptime = true,
9595 .parent = &file.base,
9696 .decl_node_index = 0,
97 .decl_line = 0,
9798 .astgen = &astgen,
9899 };
99100 defer gen_scope.instructions.deinit(gpa);
......@@ -2056,7 +2057,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
20562057 // ZIR instructions that are always either `noreturn` or `void`.
20572058 .breakpoint,
20582059 .fence,
2059 .dbg_stmt_node,
2060 .dbg_stmt,
20602061 .ensure_result_used,
20612062 .ensure_result_non_error,
20622063 .@"export",
......@@ -2395,9 +2396,25 @@ fn varDecl(
23952396}
23962397
23972398fn emitDbgNode(gz: *GenZir, node: ast.Node.Index) !void {
2398 if (!gz.force_comptime) {
2399 _ = try gz.addNode(.dbg_stmt_node, node);
2400 }
2399 // The instruction emitted here is for debugging runtime code.
2400 // If the current block will be evaluated only during semantic analysis
2401 // then no dbg_stmt ZIR instruction is needed.
2402 if (gz.force_comptime) return;
2403
2404 const astgen = gz.astgen;
2405 const tree = &astgen.file.tree;
2406 const node_tags = tree.nodes.items(.tag);
2407 const token_starts = tree.tokens.items(.start);
2408 const decl_start = token_starts[tree.firstToken(gz.decl_node_index)];
2409 const node_start = token_starts[tree.firstToken(node)];
2410 const source = tree.source[decl_start..node_start];
2411 const loc = std.zig.findLineColumn(source, source.len);
2412 _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{
2413 .dbg_stmt = .{
2414 .line = @intCast(u32, loc.line),
2415 .column = @intCast(u32, loc.column),
2416 },
2417 } });
24012418}
24022419
24032420fn assign(gz: *GenZir, scope: *Scope, infix_node: ast.Node.Index) InnerError!void {
......@@ -2689,6 +2706,7 @@ fn fnDecl(
26892706 var decl_gz: GenZir = .{
26902707 .force_comptime = true,
26912708 .decl_node_index = fn_proto.ast.proto_node,
2709 .decl_line = gz.calcLine(decl_node),
26922710 .parent = &gz.base,
26932711 .astgen = astgen,
26942712 };
......@@ -2791,7 +2809,7 @@ fn fnDecl(
27912809 return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{});
27922810 }
27932811 break :func try decl_gz.addFunc(.{
2794 .src_node = fn_proto.ast.proto_node,
2812 .src_node = decl_node,
27952813 .ret_ty = return_type_inst,
27962814 .param_types = param_types,
27972815 .body = &[0]Zir.Inst.Index{},
......@@ -2810,6 +2828,7 @@ fn fnDecl(
28102828 var fn_gz: GenZir = .{
28112829 .force_comptime = false,
28122830 .decl_node_index = fn_proto.ast.proto_node,
2831 .decl_line = decl_gz.decl_line,
28132832 .parent = &decl_gz.base,
28142833 .astgen = astgen,
28152834 };
......@@ -2866,7 +2885,7 @@ fn fnDecl(
28662885 astgen.fn_block = prev_fn_block;
28672886
28682887 break :func try decl_gz.addFunc(.{
2869 .src_node = fn_proto.ast.proto_node,
2888 .src_node = decl_node,
28702889 .ret_ty = return_type_inst,
28712890 .param_types = param_types,
28722891 .body = fn_gz.instructions.items,
......@@ -2889,12 +2908,16 @@ fn fnDecl(
28892908 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);
28902909 try decl_gz.setBlockBody(block_inst);
28912910
2892 try wip_decls.payload.ensureUnusedCapacity(gpa, 8);
2911 try wip_decls.payload.ensureUnusedCapacity(gpa, 9);
28932912 {
28942913 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
28952914 const casted = @bitCast([4]u32, contents_hash);
28962915 wip_decls.payload.appendSliceAssumeCapacity(&casted);
28972916 }
2917 {
2918 const line_delta = decl_gz.decl_line - gz.decl_line;
2919 wip_decls.payload.appendAssumeCapacity(line_delta);
2920 }
28982921 wip_decls.payload.appendAssumeCapacity(fn_name_str_index);
28992922 wip_decls.payload.appendAssumeCapacity(block_inst);
29002923 if (align_inst != .none) {
......@@ -2925,6 +2948,7 @@ fn globalVarDecl(
29252948 var block_scope: GenZir = .{
29262949 .parent = scope,
29272950 .decl_node_index = node,
2951 .decl_line = gz.calcLine(node),
29282952 .astgen = astgen,
29292953 .force_comptime = true,
29302954 };
......@@ -3024,12 +3048,16 @@ fn globalVarDecl(
30243048 const name_token = var_decl.ast.mut_token + 1;
30253049 const name_str_index = try astgen.identAsString(name_token);
30263050
3027 try wip_decls.payload.ensureUnusedCapacity(gpa, 8);
3051 try wip_decls.payload.ensureUnusedCapacity(gpa, 9);
30283052 {
30293053 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
30303054 const casted = @bitCast([4]u32, contents_hash);
30313055 wip_decls.payload.appendSliceAssumeCapacity(&casted);
30323056 }
3057 {
3058 const line_delta = block_scope.decl_line - gz.decl_line;
3059 wip_decls.payload.appendAssumeCapacity(line_delta);
3060 }
30333061 wip_decls.payload.appendAssumeCapacity(name_str_index);
30343062 wip_decls.payload.appendAssumeCapacity(block_inst);
30353063 if (align_inst != .none) {
......@@ -3060,6 +3088,7 @@ fn comptimeDecl(
30603088 var decl_block: GenZir = .{
30613089 .force_comptime = true,
30623090 .decl_node_index = node,
3091 .decl_line = gz.calcLine(node),
30633092 .parent = scope,
30643093 .astgen = astgen,
30653094 };
......@@ -3071,12 +3100,16 @@ fn comptimeDecl(
30713100 }
30723101 try decl_block.setBlockBody(block_inst);
30733102
3074 try wip_decls.payload.ensureUnusedCapacity(gpa, 6);
3103 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
30753104 {
30763105 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
30773106 const casted = @bitCast([4]u32, contents_hash);
30783107 wip_decls.payload.appendSliceAssumeCapacity(&casted);
30793108 }
3109 {
3110 const line_delta = decl_block.decl_line - gz.decl_line;
3111 wip_decls.payload.appendAssumeCapacity(line_delta);
3112 }
30803113 wip_decls.payload.appendAssumeCapacity(0);
30813114 wip_decls.payload.appendAssumeCapacity(block_inst);
30823115}
......@@ -3107,6 +3140,7 @@ fn usingnamespaceDecl(
31073140 var decl_block: GenZir = .{
31083141 .force_comptime = true,
31093142 .decl_node_index = node,
3143 .decl_line = gz.calcLine(node),
31103144 .parent = scope,
31113145 .astgen = astgen,
31123146 };
......@@ -3116,12 +3150,16 @@ fn usingnamespaceDecl(
31163150 _ = try decl_block.addBreak(.break_inline, block_inst, namespace_inst);
31173151 try decl_block.setBlockBody(block_inst);
31183152
3119 try wip_decls.payload.ensureUnusedCapacity(gpa, 6);
3153 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
31203154 {
31213155 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
31223156 const casted = @bitCast([4]u32, contents_hash);
31233157 wip_decls.payload.appendSliceAssumeCapacity(&casted);
31243158 }
3159 {
3160 const line_delta = decl_block.decl_line - gz.decl_line;
3161 wip_decls.payload.appendAssumeCapacity(line_delta);
3162 }
31253163 wip_decls.payload.appendAssumeCapacity(0);
31263164 wip_decls.payload.appendAssumeCapacity(block_inst);
31273165}
......@@ -3147,6 +3185,7 @@ fn testDecl(
31473185 var decl_block: GenZir = .{
31483186 .force_comptime = true,
31493187 .decl_node_index = node,
3188 .decl_line = gz.calcLine(node),
31503189 .parent = scope,
31513190 .astgen = astgen,
31523191 };
......@@ -3167,6 +3206,7 @@ fn testDecl(
31673206 var fn_block: GenZir = .{
31683207 .force_comptime = false,
31693208 .decl_node_index = node,
3209 .decl_line = decl_block.decl_line,
31703210 .parent = &decl_block.base,
31713211 .astgen = astgen,
31723212 };
......@@ -3200,12 +3240,16 @@ fn testDecl(
32003240 _ = try decl_block.addBreak(.break_inline, block_inst, func_inst);
32013241 try decl_block.setBlockBody(block_inst);
32023242
3203 try wip_decls.payload.ensureUnusedCapacity(gpa, 6);
3243 try wip_decls.payload.ensureUnusedCapacity(gpa, 7);
32043244 {
32053245 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
32063246 const casted = @bitCast([4]u32, contents_hash);
32073247 wip_decls.payload.appendSliceAssumeCapacity(&casted);
32083248 }
3249 {
3250 const line_delta = decl_block.decl_line - gz.decl_line;
3251 wip_decls.payload.appendAssumeCapacity(line_delta);
3252 }
32093253 wip_decls.payload.appendAssumeCapacity(test_name);
32103254 wip_decls.payload.appendAssumeCapacity(block_inst);
32113255}
......@@ -3237,6 +3281,7 @@ fn structDeclInner(
32373281 var block_scope: GenZir = .{
32383282 .parent = scope,
32393283 .decl_node_index = node,
3284 .decl_line = gz.calcLine(node),
32403285 .astgen = astgen,
32413286 .force_comptime = true,
32423287 .ref_start_index = gz.ref_start_index,
......@@ -3448,6 +3493,7 @@ fn unionDeclInner(
34483493 var block_scope: GenZir = .{
34493494 .parent = scope,
34503495 .decl_node_index = node,
3496 .decl_line = gz.calcLine(node),
34513497 .astgen = astgen,
34523498 .force_comptime = true,
34533499 .ref_start_index = gz.ref_start_index,
......@@ -3797,6 +3843,7 @@ fn containerDecl(
37973843 var block_scope: GenZir = .{
37983844 .parent = scope,
37993845 .decl_node_index = node,
3846 .decl_line = gz.calcLine(node),
38003847 .astgen = astgen,
38013848 .force_comptime = true,
38023849 .ref_start_index = gz.ref_start_index,
......@@ -4464,7 +4511,9 @@ fn boolBinOp(
44644511 node: ast.Node.Index,
44654512 zir_tag: Zir.Inst.Tag,
44664513) InnerError!Zir.Inst.Ref {
4467 const node_datas = gz.tree().nodes.items(.data);
4514 const astgen = gz.astgen;
4515 const tree = &astgen.file.tree;
4516 const node_datas = tree.nodes.items(.data);
44684517
44694518 const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs);
44704519 const bool_br = try gz.addBoolBr(zir_tag, lhs);
src/Module.zig+79-16
......@@ -182,9 +182,12 @@ pub const Decl = struct {
182182 /// The AST node index of this declaration.
183183 /// Must be recomputed when the corresponding source file is modified.
184184 src_node: ast.Node.Index,
185 /// Line number corresponding to `src_node`. Stored separately so that source files
186 /// do not need to be loaded into memory in order to compute debug line numbers.
187 src_line: u32,
185188 /// Index to ZIR `extra` array to the entry in the parent's decl structure
186189 /// (the part that says "for every decls_len"). The first item at this index is
187 /// the contents hash, followed by the name.
190 /// the contents hash, followed by line, name, etc.
188191 zir_decl_index: Zir.Inst.Index,
189192
190193 /// Represents the "shallow" analysis status. For example, for decls that are functions,
......@@ -282,6 +285,7 @@ pub const Decl = struct {
282285 if (decl.val.castTag(.function)) |payload| {
283286 const func = payload.data;
284287 func.deinit(gpa);
288 gpa.destroy(func);
285289 } else if (decl.val.getTypeNamespace()) |namespace| {
286290 if (namespace.getDecl() == decl) {
287291 namespace.clearDecls(module);
......@@ -323,7 +327,7 @@ pub const Decl = struct {
323327 }
324328
325329 pub fn getNameZir(decl: Decl, zir: Zir) ?[:0]const u8 {
326 const name_index = zir.extra[decl.zir_decl_index + 4];
330 const name_index = zir.extra[decl.zir_decl_index + 5];
327331 if (name_index <= 1) return null;
328332 return zir.nullTerminatedString(name_index);
329333 }
......@@ -341,7 +345,7 @@ pub const Decl = struct {
341345
342346 pub fn zirBlockIndex(decl: Decl) Zir.Inst.Index {
343347 const zir = decl.namespace.file_scope.zir;
344 return zir.extra[decl.zir_decl_index + 5];
348 return zir.extra[decl.zir_decl_index + 6];
345349 }
346350
347351 pub fn zirAlignRef(decl: Decl) Zir.Inst.Ref {
......@@ -357,6 +361,10 @@ pub const Decl = struct {
357361 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
358362 }
359363
364 pub fn relativeToLine(decl: Decl, offset: u32) u32 {
365 return decl.src_line + offset;
366 }
367
360368 pub fn relativeToNodeIndex(decl: Decl, offset: i32) ast.Node.Index {
361369 return @bitCast(ast.Node.Index, offset + @bitCast(i32, decl.src_node));
362370 }
......@@ -565,13 +573,21 @@ pub const EnumFull = struct {
565573/// the `Decl` only, with a `Value` tag of `extern_fn`.
566574pub const Fn = struct {
567575 owner_decl: *Decl,
576 /// undefined unless analysis state is `success`.
577 body: ir.Body,
568578 /// The ZIR instruction that is a function instruction. Use this to find
569579 /// the body. We store this rather than the body directly so that when ZIR
570580 /// is regenerated on update(), we can map this to the new corresponding
571581 /// ZIR instruction.
572582 zir_body_inst: Zir.Inst.Index,
573 /// undefined unless analysis state is `success`.
574 body: ir.Body,
583
584 /// Relative to owner Decl.
585 lbrace_line: u32,
586 /// Relative to owner Decl.
587 rbrace_line: u32,
588 lbrace_column: u16,
589 rbrace_column: u16,
590
575591 state: Analysis,
576592
577593 pub const Analysis = enum {
......@@ -1130,7 +1146,7 @@ pub const Scope = struct {
11301146 return &inst.base;
11311147 }
11321148
1133 pub fn addDbgStmt(block: *Scope.Block, src: LazySrcLoc, abs_byte_off: u32) !*ir.Inst {
1149 pub fn addDbgStmt(block: *Scope.Block, src: LazySrcLoc, line: u32, column: u32) !*ir.Inst {
11341150 const inst = try block.sema.arena.create(ir.Inst.DbgStmt);
11351151 inst.* = .{
11361152 .base = .{
......@@ -1138,7 +1154,8 @@ pub const Scope = struct {
11381154 .ty = Type.initTag(.void),
11391155 .src = src,
11401156 },
1141 .byte_offset = abs_byte_off,
1157 .line = line,
1158 .column = column,
11421159 };
11431160 try block.instructions.append(block.sema.gpa, &inst.base);
11441161 return &inst.base;
......@@ -1177,6 +1194,8 @@ pub const Scope = struct {
11771194 ref_start_index: u32 = Zir.Inst.Ref.typed_value_map.len,
11781195 /// The containing decl AST node.
11791196 decl_node_index: ast.Node.Index,
1197 /// The containing decl line index, absolute.
1198 decl_line: u32,
11801199 /// Parents can be: `GenZir`, `File`
11811200 parent: *Scope,
11821201 /// All `GenZir` scopes for the same ZIR share this.
......@@ -1218,6 +1237,7 @@ pub const Scope = struct {
12181237 .force_comptime = gz.force_comptime,
12191238 .ref_start_index = gz.ref_start_index,
12201239 .decl_node_index = gz.decl_node_index,
1240 .decl_line = gz.decl_line,
12211241 .parent = scope,
12221242 .astgen = gz.astgen,
12231243 .suspend_node = gz.suspend_node,
......@@ -1239,6 +1259,18 @@ pub const Scope = struct {
12391259 return false;
12401260 }
12411261
1262 pub fn calcLine(gz: GenZir, node: ast.Node.Index) u32 {
1263 const astgen = gz.astgen;
1264 const tree = &astgen.file.tree;
1265 const node_tags = tree.nodes.items(.tag);
1266 const token_starts = tree.tokens.items(.start);
1267 const decl_start = token_starts[tree.firstToken(gz.decl_node_index)];
1268 const node_start = token_starts[tree.firstToken(node)];
1269 const source = tree.source[decl_start..node_start];
1270 const loc = std.zig.findLineColumn(source, source.len);
1271 return @intCast(u32, gz.decl_line + loc.line);
1272 }
1273
12421274 pub fn tokSrcLoc(gz: GenZir, token_index: ast.TokenIndex) LazySrcLoc {
12431275 return .{ .token_offset = token_index - gz.srcToken() };
12441276 }
......@@ -1259,10 +1291,6 @@ pub const Scope = struct {
12591291 return gz.astgen.file.tree.firstToken(gz.decl_node_index);
12601292 }
12611293
1262 pub fn tree(gz: *const GenZir) *const ast.Tree {
1263 return &gz.astgen.file.tree;
1264 }
1265
12661294 pub fn indexToRef(gz: GenZir, inst: Zir.Inst.Index) Zir.Inst.Ref {
12671295 return @intToEnum(Zir.Inst.Ref, gz.ref_start_index + inst);
12681296 }
......@@ -1376,13 +1404,40 @@ pub const Scope = struct {
13761404 try gz.instructions.ensureUnusedCapacity(gpa, 1);
13771405 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
13781406
1407 var src_locs_buffer: [3]u32 = undefined;
1408 var src_locs: []u32 = src_locs_buffer[0..0];
1409 if (args.body.len != 0) {
1410 const tree = &astgen.file.tree;
1411 const node_tags = tree.nodes.items(.tag);
1412 const node_datas = tree.nodes.items(.data);
1413 const token_starts = tree.tokens.items(.start);
1414 const decl_start = token_starts[tree.firstToken(gz.decl_node_index)];
1415 const fn_decl = args.src_node;
1416 assert(node_tags[fn_decl] == .fn_decl or node_tags[fn_decl] == .test_decl);
1417 const block = node_datas[fn_decl].rhs;
1418 const lbrace_start = token_starts[tree.firstToken(block)];
1419 const rbrace_start = token_starts[tree.lastToken(block)];
1420 const lbrace_source = tree.source[decl_start..lbrace_start];
1421 const lbrace_loc = std.zig.findLineColumn(lbrace_source, lbrace_source.len);
1422 const rbrace_source = tree.source[lbrace_start..rbrace_start];
1423 const rbrace_loc = std.zig.findLineColumn(rbrace_source, rbrace_source.len);
1424 const lbrace_line = @intCast(u32, lbrace_loc.line);
1425 const rbrace_line = lbrace_line + @intCast(u32, rbrace_loc.line);
1426 const columns = @intCast(u32, lbrace_loc.column) |
1427 (@intCast(u32, rbrace_loc.column) << 16);
1428 src_locs_buffer[0] = lbrace_line;
1429 src_locs_buffer[1] = rbrace_line;
1430 src_locs_buffer[2] = columns;
1431 src_locs = &src_locs_buffer;
1432 }
1433
13791434 if (args.cc != .none or args.lib_name != 0 or
13801435 args.is_var_args or args.is_test or args.align_inst != .none)
13811436 {
13821437 try astgen.extra.ensureUnusedCapacity(
13831438 gpa,
13841439 @typeInfo(Zir.Inst.ExtendedFunc).Struct.fields.len +
1385 args.param_types.len + args.body.len +
1440 args.param_types.len + args.body.len + src_locs.len +
13861441 @boolToInt(args.lib_name != 0) +
13871442 @boolToInt(args.align_inst != .none) +
13881443 @boolToInt(args.cc != .none),
......@@ -1404,6 +1459,7 @@ pub const Scope = struct {
14041459 }
14051460 astgen.appendRefsAssumeCapacity(args.param_types);
14061461 astgen.extra.appendSliceAssumeCapacity(args.body);
1462 astgen.extra.appendSliceAssumeCapacity(src_locs);
14071463
14081464 const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
14091465 astgen.instructions.appendAssumeCapacity(.{
......@@ -1427,7 +1483,7 @@ pub const Scope = struct {
14271483 try gz.astgen.extra.ensureUnusedCapacity(
14281484 gpa,
14291485 @typeInfo(Zir.Inst.Func).Struct.fields.len +
1430 args.param_types.len + args.body.len,
1486 args.param_types.len + args.body.len + src_locs.len,
14311487 );
14321488
14331489 const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Func{
......@@ -1437,6 +1493,7 @@ pub const Scope = struct {
14371493 });
14381494 gz.astgen.appendRefsAssumeCapacity(args.param_types);
14391495 gz.astgen.extra.appendSliceAssumeCapacity(args.body);
1496 gz.astgen.extra.appendSliceAssumeCapacity(src_locs);
14401497
14411498 const tag: Zir.Inst.Tag = if (args.is_inferred_error) .func_inferred else .func;
14421499 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
......@@ -3297,6 +3354,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void {
32973354 file.namespace = &struct_obj.namespace;
32983355 const new_decl = try mod.allocateNewDecl(&struct_obj.namespace, 0);
32993356 struct_obj.owner_decl = new_decl;
3357 new_decl.src_line = 0;
33003358 new_decl.name = try file.fullyQualifiedNameZ(gpa);
33013359 new_decl.is_pub = true;
33023360 new_decl.is_exported = false;
......@@ -3694,7 +3752,7 @@ pub fn scanNamespace(
36943752 cur_bit_bag >>= 4;
36953753
36963754 const decl_sub_index = extra_index;
3697 extra_index += 6;
3755 extra_index += 7; // src_hash(4) + line(1) + name(1) + value(1)
36983756 extra_index += @truncate(u1, flags >> 2);
36993757 extra_index += @truncate(u1, flags >> 3);
37003758
......@@ -3752,8 +3810,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
37523810 const has_linksection = (flags & 0b1000) != 0;
37533811 // zig fmt: on
37543812
3755 const decl_name_index = zir.extra[decl_sub_index + 4];
3756 const decl_index = zir.extra[decl_sub_index + 5];
3813 const line = iter.parent_decl.relativeToLine(zir.extra[decl_sub_index + 4]);
3814 const decl_name_index = zir.extra[decl_sub_index + 5];
3815 const decl_index = zir.extra[decl_sub_index + 6];
37573816 const decl_block_inst_data = zir.instructions.items(.data)[decl_index].pl_node;
37583817 const decl_node = iter.parent_decl.relativeToNodeIndex(decl_block_inst_data.src_node);
37593818
......@@ -3783,6 +3842,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
37833842 const gop = try namespace.decls.getOrPut(gpa, decl_name);
37843843 if (!gop.found_existing) {
37853844 const new_decl = try mod.allocateNewDecl(namespace, decl_node);
3845 new_decl.src_line = line;
37863846 new_decl.name = decl_name;
37873847 gop.entry.value = new_decl;
37883848 // Exported decls, comptime decls, usingnamespace decls, and
......@@ -3807,6 +3867,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) InnerError!vo
38073867 // have been re-ordered.
38083868 const prev_src_node = decl.src_node;
38093869 decl.src_node = decl_node;
3870 decl.src_line = line;
38103871
38113872 decl.is_pub = is_pub;
38123873 decl.is_exported = is_exported;
......@@ -4056,6 +4117,7 @@ fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node
40564117 .name = "",
40574118 .namespace = namespace,
40584119 .src_node = src_node,
4120 .src_line = undefined,
40594121 .has_tv = false,
40604122 .ty = undefined,
40614123 .val = undefined,
......@@ -4292,6 +4354,7 @@ pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue)
42924354 const new_decl = try mod.allocateNewDecl(namespace, scope_decl.src_node);
42934355 namespace.decls.putAssumeCapacityNoClobber(name, new_decl);
42944356
4357 new_decl.src_line = scope_decl.src_line;
42954358 new_decl.name = name;
42964359 new_decl.ty = typed_value.ty;
42974360 new_decl.val = typed_value.val;
src/Sema.zig+29-21
......@@ -397,8 +397,8 @@ pub fn analyzeBody(
397397 try sema.zirFence(block, inst);
398398 continue;
399399 },
400 .dbg_stmt_node => {
401 try sema.zirDbgStmtNode(block, inst);
400 .dbg_stmt => {
401 try sema.zirDbgStmt(block, inst);
402402 continue;
403403 },
404404 .ensure_err_payload_void => {
......@@ -1920,7 +1920,7 @@ fn zirBreak(sema: *Sema, start_block: *Scope.Block, inst: Zir.Inst.Index) InnerE
19201920 }
19211921}
19221922
1923fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
1923fn zirDbgStmt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!void {
19241924 const tracy = trace(@src());
19251925 defer tracy.end();
19261926
......@@ -1930,14 +1930,8 @@ fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerE
19301930 // instructions.
19311931 if (block.is_comptime) return;
19321932
1933 const src_node = sema.code.instructions.items(.data)[inst].node;
1934 const src: LazySrcLoc = .{ .node_offset = src_node };
1935
1936 const src_loc = src.toSrcLoc(&block.base);
1937 const abs_byte_off = src_loc.byteOffset(sema.gpa) catch |err| {
1938 return sema.mod.fail(&block.base, src, "TODO modify dbg_stmt ZIR instructions to have line/column rather than node indexes. {s}", .{@errorName(err)});
1939 };
1940 _ = try block.addDbgStmt(src, abs_byte_off);
1933 const inst_data = sema.code.instructions.items(.data)[inst].dbg_stmt;
1934 _ = try block.addDbgStmt(.unneeded, inst_data.line, inst_data.column);
19411935}
19421936
19431937fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
......@@ -2793,7 +2787,14 @@ fn zirFunc(
27932787 const src = inst_data.src();
27942788 const extra = sema.code.extraData(Zir.Inst.Func, inst_data.payload_index);
27952789 const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len);
2796 const body_inst = if (extra.data.body_len != 0) inst else 0;
2790
2791 var body_inst: Zir.Inst.Index = 0;
2792 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
2793 if (extra.data.body_len != 0) {
2794 body_inst = inst;
2795 const extra_index = extra.end + extra.data.param_types_len + extra.data.body_len;
2796 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
2797 }
27972798
27982799 return sema.funcCommon(
27992800 block,
......@@ -2805,6 +2806,7 @@ fn zirFunc(
28052806 Value.initTag(.null_value),
28062807 false,
28072808 inferred_error_set,
2809 src_locs,
28082810 );
28092811}
28102812
......@@ -2819,6 +2821,7 @@ fn funcCommon(
28192821 align_val: Value,
28202822 var_args: bool,
28212823 inferred_error_set: bool,
2824 src_locs: Zir.Inst.Func.SrcLocs,
28222825) InnerError!*Inst {
28232826 const src: LazySrcLoc = .{ .node_offset = src_node_offset };
28242827 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
......@@ -2872,18 +2875,17 @@ fn funcCommon(
28722875 const is_inline = fn_ty.fnCallingConvention() == .Inline;
28732876 const anal_state: Module.Fn.Analysis = if (is_inline) .inline_only else .queued;
28742877
2875 // Use the Decl's arena for function memory.
2876 var fn_arena = std.heap.ArenaAllocator.init(sema.gpa);
2877 errdefer fn_arena.deinit();
2878
2879 const new_func = try fn_arena.allocator.create(Module.Fn);
2880 const fn_payload = try fn_arena.allocator.create(Value.Payload.Function);
2881
2878 const fn_payload = try sema.arena.create(Value.Payload.Function);
2879 const new_func = try sema.gpa.create(Module.Fn);
28822880 new_func.* = .{
28832881 .state = anal_state,
28842882 .zir_body_inst = body_inst,
28852883 .owner_decl = sema.owner_decl,
28862884 .body = undefined,
2885 .lbrace_line = src_locs.lbrace_line,
2886 .rbrace_line = src_locs.rbrace_line,
2887 .lbrace_column = @truncate(u16, src_locs.columns),
2888 .rbrace_column = @truncate(u16, src_locs.columns >> 16),
28872889 };
28882890 fn_payload.* = .{
28892891 .base = .{ .tag = .function },
......@@ -2893,7 +2895,6 @@ fn funcCommon(
28932895 .ty = fn_ty,
28942896 .val = Value.initPayload(&fn_payload.base),
28952897 });
2896 try sema.owner_decl.finalizeNewArena(&fn_arena);
28972898 return result;
28982899}
28992900
......@@ -5577,7 +5578,13 @@ fn zirFuncExtended(
55775578 const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len);
55785579 extra_index += param_types.len;
55795580
5580 const body_inst = if (extra.data.body_len != 0) inst else 0;
5581 var body_inst: Zir.Inst.Index = 0;
5582 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
5583 if (extra.data.body_len != 0) {
5584 body_inst = inst;
5585 extra_index += extra.data.body_len;
5586 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
5587 }
55815588
55825589 return sema.funcCommon(
55835590 block,
......@@ -5589,6 +5596,7 @@ fn zirFuncExtended(
55895596 align_val,
55905597 small.is_var_args,
55915598 small.is_inferred_error,
5599 src_locs,
55925600 );
55935601}
55945602
src/Zir.zig+56-7
......@@ -321,8 +321,9 @@ pub const Inst = struct {
321321 /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
322322 error_set_decl,
323323 /// Declares the beginning of a statement. Used for debug info.
324 /// Uses the `node` union field.
325 dbg_stmt_node,
324 /// Uses the `dbg_stmt` union field. The line and column are offset
325 /// from the parent declaration.
326 dbg_stmt,
326327 /// Uses a name to identify a Decl and takes a pointer to it.
327328 /// Uses the `str_tok` union field.
328329 decl_ref,
......@@ -1016,7 +1017,7 @@ pub const Inst = struct {
10161017 .enum_decl_nonexhaustive,
10171018 .opaque_decl,
10181019 .error_set_decl,
1019 .dbg_stmt_node,
1020 .dbg_stmt,
10201021 .decl_ref,
10211022 .decl_val,
10221023 .load,
......@@ -1276,7 +1277,7 @@ pub const Inst = struct {
12761277 .enum_decl_nonexhaustive = .pl_node,
12771278 .opaque_decl = .pl_node,
12781279 .error_set_decl = .pl_node,
1279 .dbg_stmt_node = .node,
1280 .dbg_stmt = .dbg_stmt,
12801281 .decl_ref = .str_tok,
12811282 .decl_val = .str_tok,
12821283 .load = .un_node,
......@@ -2118,6 +2119,10 @@ pub const Inst = struct {
21182119 switch_inst: Index,
21192120 prong_index: u32,
21202121 },
2122 dbg_stmt: struct {
2123 line: u32,
2124 column: u32,
2125 },
21212126
21222127 // Make sure we don't accidentally add a field to make this union
21232128 // bigger than expected. Note that in Debug builds, Zig is allowed
......@@ -2153,6 +2158,7 @@ pub const Inst = struct {
21532158 @"unreachable",
21542159 @"break",
21552160 switch_capture,
2161 dbg_stmt,
21562162 };
21572163 };
21582164
......@@ -2193,6 +2199,7 @@ pub const Inst = struct {
21932199 /// 2. align: Ref, // if has_align is set
21942200 /// 3. param_type: Ref // for each param_types_len
21952201 /// 4. body: Index // for each body_len
2202 /// 5. src_locs: Func.SrcLocs // if body_len != 0
21962203 pub const ExtendedFunc = struct {
21972204 src_node: i32,
21982205 return_type: Ref,
......@@ -2231,10 +2238,21 @@ pub const Inst = struct {
22312238 /// 0. param_type: Ref // for each param_types_len
22322239 /// - `none` indicates that the param type is `anytype`.
22332240 /// 1. body: Index // for each body_len
2241 /// 2. src_locs: SrcLocs // if body_len != 0
22342242 pub const Func = struct {
22352243 return_type: Ref,
22362244 param_types_len: u32,
22372245 body_len: u32,
2246
2247 pub const SrcLocs = struct {
2248 /// Absolute line number in the source file.
2249 lbrace_line: u32,
2250 /// Absolute line number in the source file.
2251 rbrace_line: u32,
2252 /// lbrace_column is least significant bits u16
2253 /// rbrace_column is most significant bits u16
2254 columns: u32,
2255 };
22382256 };
22392257
22402258 /// This data is stored inside extra, with trailing operands according to `operands_len`.
......@@ -2398,6 +2416,7 @@ pub const Inst = struct {
23982416 /// 0bX000: whether corresponding decl has a linksection expression
23992417 /// 1. decl: { // for every decls_len
24002418 /// src_hash: [4]u32, // hash of source bytes
2419 /// line: u32, // line number of decl, relative to parent
24012420 /// name: u32, // null terminated string index
24022421 /// - 0 means comptime or usingnamespace decl.
24032422 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
......@@ -2435,6 +2454,7 @@ pub const Inst = struct {
24352454 /// 0bX000: whether corresponding decl has a linksection expression
24362455 /// 1. decl: { // for every decls_len
24372456 /// src_hash: [4]u32, // hash of source bytes
2457 /// line: u32, // line number of decl, relative to parent
24382458 /// name: u32, // null terminated string index
24392459 /// - 0 means comptime or usingnamespace decl.
24402460 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
......@@ -2467,6 +2487,7 @@ pub const Inst = struct {
24672487 /// 0bX000: whether corresponding decl has a linksection expression
24682488 /// 1. decl: { // for every decls_len
24692489 /// src_hash: [4]u32, // hash of source bytes
2490 /// line: u32, // line number of decl, relative to parent
24702491 /// name: u32, // null terminated string index
24712492 /// - 0 means comptime or usingnamespace decl.
24722493 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
......@@ -2509,6 +2530,7 @@ pub const Inst = struct {
25092530 /// 0bX000: whether corresponding decl has a linksection expression
25102531 /// 1. decl: { // for every decls_len
25112532 /// src_hash: [4]u32, // hash of source bytes
2533 /// line: u32, // line number of decl, relative to parent
25122534 /// name: u32, // null terminated string index
25132535 /// - 0 means comptime or usingnamespace decl.
25142536 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
......@@ -2978,7 +3000,6 @@ const Writer = struct {
29783000
29793001 .breakpoint,
29803002 .fence,
2981 .dbg_stmt_node,
29823003 .repeat,
29833004 .repeat_inline,
29843005 .alloc_inferred,
......@@ -3007,6 +3028,8 @@ const Writer = struct {
30073028 .switch_capture_else_ref,
30083029 => try self.writeSwitchCapture(stream, inst),
30093030
3031 .dbg_stmt => try self.writeDbgStmt(stream, inst),
3032
30103033 .extended => try self.writeExtended(stream, inst),
30113034 }
30123035 }
......@@ -3606,6 +3629,8 @@ const Writer = struct {
36063629
36073630 const hash_u32s = self.code.extra[extra_index..][0..4];
36083631 extra_index += 4;
3632 const line = self.code.extra[extra_index];
3633 extra_index += 1;
36093634 const decl_name_index = self.code.extra[extra_index];
36103635 const decl_name = self.code.nullTerminatedString(decl_name_index);
36113636 extra_index += 1;
......@@ -3646,8 +3671,8 @@ const Writer = struct {
36463671 }
36473672 }
36483673 const tag = self.code.instructions.items(.tag)[decl_index];
3649 try stream.print(" hash({}): %{d} = {s}(", .{
3650 std.fmt.fmtSliceHexLower(&hash_bytes), decl_index, @tagName(tag),
3674 try stream.print(" line({d}) hash({}): %{d} = {s}(", .{
3675 line, std.fmt.fmtSliceHexLower(&hash_bytes), decl_index, @tagName(tag),
36513676 });
36523677
36533678 const decl_block_inst_data = self.code.instructions.items(.data)[decl_index].pl_node;
......@@ -3979,6 +4004,11 @@ const Writer = struct {
39794004 const extra = self.code.extraData(Inst.Func, inst_data.payload_index);
39804005 const param_types = self.code.refSlice(extra.end, extra.data.param_types_len);
39814006 const body = self.code.extra[extra.end + param_types.len ..][0..extra.data.body_len];
4007 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
4008 if (body.len != 0) {
4009 const extra_index = extra.end + param_types.len + body.len;
4010 src_locs = self.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
4011 }
39824012 return self.writeFuncCommon(
39834013 stream,
39844014 param_types,
......@@ -3989,6 +4019,7 @@ const Writer = struct {
39894019 .none,
39904020 body,
39914021 src,
4022 src_locs,
39924023 );
39934024 }
39944025
......@@ -4019,7 +4050,12 @@ const Writer = struct {
40194050 extra_index += param_types.len;
40204051
40214052 const body = self.code.extra[extra_index..][0..extra.data.body_len];
4053 extra_index += body.len;
40224054
4055 var src_locs: Zir.Inst.Func.SrcLocs = undefined;
4056 if (body.len != 0) {
4057 src_locs = self.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
4058 }
40234059 return self.writeFuncCommon(
40244060 stream,
40254061 param_types,
......@@ -4030,6 +4066,7 @@ const Writer = struct {
40304066 align_inst,
40314067 body,
40324068 src,
4069 src_locs,
40334070 );
40344071 }
40354072
......@@ -4111,6 +4148,7 @@ const Writer = struct {
41114148 align_inst: Inst.Ref,
41124149 body: []const Inst.Index,
41134150 src: LazySrcLoc,
4151 src_locs: Zir.Inst.Func.SrcLocs,
41144152 ) !void {
41154153 try stream.writeAll("[");
41164154 for (param_types) |param_type, i| {
......@@ -4134,6 +4172,12 @@ const Writer = struct {
41344172 try stream.writeByteNTimes(' ', self.indent);
41354173 try stream.writeAll("}) ");
41364174 }
4175 if (body.len != 0) {
4176 try stream.print("(lbrace={d}:{d},rbrace={d}:{d}) ", .{
4177 src_locs.lbrace_line, @truncate(u16, src_locs.columns),
4178 src_locs.rbrace_line, @truncate(u16, src_locs.columns >> 16),
4179 });
4180 }
41374181 try self.writeSrc(stream, src);
41384182 }
41394183
......@@ -4143,6 +4187,11 @@ const Writer = struct {
41434187 try stream.print(", {d})", .{inst_data.prong_index});
41444188 }
41454189
4190 fn writeDbgStmt(self: *Writer, stream: anytype, inst: Inst.Index) !void {
4191 const inst_data = self.code.instructions.items(.data)[inst].dbg_stmt;
4192 try stream.print("{d}, {d})", .{ inst_data.line, inst_data.column });
4193 }
4194
41464195 fn writeInstRef(self: *Writer, stream: anytype, ref: Inst.Ref) !void {
41474196 var i: usize = @enumToInt(ref);
41484197
src/codegen.zig+22-44
......@@ -264,14 +264,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
264264 src_loc: Module.SrcLoc,
265265 stack_align: u32,
266266
267 /// Byte offset within the source file.
268 prev_di_src: usize,
267 prev_di_line: u32,
268 prev_di_column: u32,
269 /// Byte offset within the source file of the ending curly.
270 end_di_line: u32,
271 end_di_column: u32,
269272 /// Relative to the beginning of `code`.
270273 prev_di_pc: usize,
271 /// Used to find newlines and count line deltas.
272 source: []const u8,
273 /// Byte offset within the source file of the ending curly.
274 rbrace_src: usize,
275274
276275 /// The value is an offset into the `Function` `code` from the beginning.
277276 /// To perform the reloc, write 32-bit signed little-endian integer
......@@ -411,25 +410,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
411410 }
412411 try branch_stack.append(.{});
413412
414 const src_data: struct { lbrace_src: usize, rbrace_src: usize, source: []const u8 } = blk: {
415 const namespace = module_fn.owner_decl.namespace;
416 const tree = namespace.file_scope.tree;
417 const node_tags = tree.nodes.items(.tag);
418 const node_datas = tree.nodes.items(.data);
419 const token_starts = tree.tokens.items(.start);
420
421 const fn_decl = module_fn.owner_decl.src_node;
422 assert(node_tags[fn_decl] == .fn_decl);
423 const block = node_datas[fn_decl].rhs;
424 const lbrace_src = token_starts[tree.firstToken(block)];
425 const rbrace_src = token_starts[tree.lastToken(block)];
426 break :blk .{
427 .lbrace_src = lbrace_src,
428 .rbrace_src = rbrace_src,
429 .source = tree.source,
430 };
431 };
432
433413 var function = Self{
434414 .gpa = bin_file.allocator,
435415 .target = &bin_file.options.target,
......@@ -446,9 +426,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
446426 .src_loc = src_loc,
447427 .stack_align = undefined,
448428 .prev_di_pc = 0,
449 .prev_di_src = src_data.lbrace_src,
450 .rbrace_src = src_data.rbrace_src,
451 .source = src_data.source,
429 .prev_di_line = module_fn.lbrace_line,
430 .prev_di_column = module_fn.lbrace_column,
431 .end_di_line = module_fn.rbrace_line,
432 .end_di_column = module_fn.rbrace_column,
452433 };
453434 defer function.stack.deinit(bin_file.allocator);
454435 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
......@@ -701,7 +682,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
701682 },
702683 }
703684 // Drop them off at the rbrace.
704 try self.dbgAdvancePCAndLine(self.rbrace_src);
685 try self.dbgAdvancePCAndLine(self.end_di_line, self.end_di_column);
705686 }
706687
707688 fn genBody(self: *Self, body: ir.Body) InnerError!void {
......@@ -727,7 +708,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
727708 switch (self.debug_output) {
728709 .dwarf => |dbg_out| {
729710 try dbg_out.dbg_line.append(DW.LNS_set_prologue_end);
730 try self.dbgAdvancePCAndLine(self.prev_di_src);
711 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
731712 },
732713 .none => {},
733714 }
......@@ -737,27 +718,21 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
737718 switch (self.debug_output) {
738719 .dwarf => |dbg_out| {
739720 try dbg_out.dbg_line.append(DW.LNS_set_epilogue_begin);
740 try self.dbgAdvancePCAndLine(self.prev_di_src);
721 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
741722 },
742723 .none => {},
743724 }
744725 }
745726
746 fn dbgAdvancePCAndLine(self: *Self, abs_byte_off: usize) InnerError!void {
747 self.prev_di_src = abs_byte_off;
748 self.prev_di_pc = self.code.items.len;
727 fn dbgAdvancePCAndLine(self: *Self, line: u32, column: u32) InnerError!void {
749728 switch (self.debug_output) {
750729 .dwarf => |dbg_out| {
751 // TODO Look into improving the performance here by adding a token-index-to-line
752 // lookup table, and changing ir.Inst from storing byte offset to token. Currently
753 // this involves scanning over the source code for newlines
754 // (but only from the previous byte offset to the new one).
755 const delta_line = std.zig.lineDelta(self.source, self.prev_di_src, abs_byte_off);
730 const delta_line = @intCast(i32, line) - @intCast(i32, self.prev_di_line);
756731 const delta_pc = self.code.items.len - self.prev_di_pc;
757 // TODO Look into using the DWARF special opcodes to compress this data. It lets you emit
758 // single-byte opcodes that add different numbers to both the PC and the line number
759 // at the same time.
760 try dbg_out.dbg_line.ensureCapacity(dbg_out.dbg_line.items.len + 11);
732 // TODO Look into using the DWARF special opcodes to compress this data.
733 // It lets you emit single-byte opcodes that add different numbers to
734 // both the PC and the line number at the same time.
735 try dbg_out.dbg_line.ensureUnusedCapacity(11);
761736 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_pc);
762737 leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable;
763738 if (delta_line != 0) {
......@@ -768,6 +743,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
768743 },
769744 .none => {},
770745 }
746 self.prev_di_line = line;
747 self.prev_di_column = column;
748 self.prev_di_pc = self.code.items.len;
771749 }
772750
773751 /// Asserts there is already capacity to insert into top branch inst_table.
......@@ -2317,7 +2295,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
23172295 // well to be more efficient, as well as support inlined function calls correctly.
23182296 // For now we convert LazySrcLoc to absolute byte offset, to match what the
23192297 // existing codegen code expects.
2320 try self.dbgAdvancePCAndLine(inst.byte_offset);
2298 try self.dbgAdvancePCAndLine(inst.line, inst.column);
23212299 assert(inst.base.isUnused());
23222300 return MCValue.dead;
23232301 }
src/ir.zig+2-1
......@@ -622,7 +622,8 @@ pub const Inst = struct {
622622 pub const base_tag = Tag.dbg_stmt;
623623
624624 base: Inst,
625 byte_offset: u32,
625 line: u32,
626 column: u32,
626627
627628 pub fn operandCount(self: *const DbgStmt) usize {
628629 return 0;
src/link/Elf.zig+4-28
......@@ -2221,21 +2221,8 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
22212221 // For functions we need to add a prologue to the debug line program.
22222222 try dbg_line_buffer.ensureCapacity(26);
22232223
2224 const line_off: u28 = blk: {
2225 const tree = decl.namespace.file_scope.tree;
2226 const node_tags = tree.nodes.items(.tag);
2227 const node_datas = tree.nodes.items(.data);
2228 const token_starts = tree.tokens.items(.start);
2229
2230 // TODO Look into improving the performance here by adding a token-index-to-line
2231 // lookup table. Currently this involves scanning over the source code for newlines.
2232 const fn_decl = decl.src_node;
2233 assert(node_tags[fn_decl] == .fn_decl);
2234 const block = node_datas[fn_decl].rhs;
2235 const lbrace = tree.firstToken(block);
2236 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
2237 break :blk @intCast(u28, line_delta);
2238 };
2224 const func = decl.val.castTag(.function).?.data;
2225 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);
22392226
22402227 const ptr_width_bytes = self.ptrWidthBytes();
22412228 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
......@@ -2750,19 +2737,8 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
27502737
27512738 if (self.llvm_object) |_| return;
27522739
2753 const tree = decl.namespace.file_scope.tree;
2754 const node_tags = tree.nodes.items(.tag);
2755 const node_datas = tree.nodes.items(.data);
2756 const token_starts = tree.tokens.items(.start);
2757
2758 // TODO Look into improving the performance here by adding a token-index-to-line
2759 // lookup table. Currently this involves scanning over the source code for newlines.
2760 const fn_decl = decl.src_node;
2761 assert(node_tags[fn_decl] == .fn_decl);
2762 const block = node_datas[fn_decl].rhs;
2763 const lbrace = tree.firstToken(block);
2764 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
2765 const casted_line_off = @intCast(u28, line_delta);
2740 const func = decl.val.castTag(.function).?.data;
2741 const casted_line_off = @intCast(u28, decl.src_line + func.lbrace_line);
27662742
27672743 const shdr = &self.sections.items[self.debug_line_section_index.?];
27682744 const file_pos = shdr.sh_offset + decl.fn_link.elf.off + self.getRelocDbgLineOff();