1lf: *link.File,
2format: DW.Format,
3endian: std.lang.Endian,
4address_size: AddressSize,
5const_pool: link.ConstPool,
6
7units: []Unit,
8/// Indices are `link.ConstPool.Index`.
9consts: std.ArrayList(Const),
10globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global),
11funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func),
12decls: std.array_hash_map.Auto(InternPool.TrackedInst.Index, Decl),
13pending_decl: struct { di: Decl.Index, instance_val: InternPool.Index },
14
15debug_abbrev: Abbrev,
16frame: Frame,
17debug_info: Info,
18debug_line: Line,
19debug_line_str: Str,
20debug_rnglists: Rnglists,
21debug_str: Str,
22debug_str_offsets: StrOffsets,
23
24pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
25
26pub const Unit = struct {
27 alive: bool,
28 dirs: std.array_hash_map.Auto(Unit.Index, void),
29 files: std.array_hash_map.Auto(Zcu.File.Index, void),
30 frame_ni: link.MappedFile.Node.Index.Optional,
31 cie_ni: link.MappedFile.Node.Index.Optional,
32 debug_info_ni: link.MappedFile.Node.Index.Optional,
33 debug_info_header_ni: link.MappedFile.Node.Index.Optional,
34 debug_info_footer_ni: link.MappedFile.Node.Index.Optional,
35 debug_line_ni: link.MappedFile.Node.Index.Optional,
36 debug_line_header_ni: link.MappedFile.Node.Index.Optional,
37 debug_line_header_changed: bool,
38 debug_rnglists_ni: link.MappedFile.Node.Index.Optional,
39 debug_rnglists_offsets_table_offset: usize,
40 debug_rnglists_end: usize,
41
42 pub const Index = enum(u32) {
43 _,
44
45 pub fn mod(ui: Unit.Index, dwarf: *Dwarf) *Module {
46 return dwarf.lf.comp.zcu.?.module_roots.keys()[@backingInt(ui)];
47 }
48
49 pub fn get(ui: Unit.Index, dwarf: *Dwarf) *Unit {
50 return &dwarf.units[@backingInt(ui)];
51 }
52 };
53
54 pub const DirIndex = enum(u32) {
55 root = 0,
56 _,
57
58 fn get(di: DirIndex, unit: *Unit) Unit.Index {
59 return unit.dirs.keys()[@backingInt(di)];
60 }
61 };
62
63 pub const FileIndex = enum(u32) {
64 root = 0,
65 _,
66
67 fn get(fi: FileIndex, unit: *Unit) Zcu.File.Index {
68 return unit.files.keys()[@backingInt(fi)];
69 }
70 };
71
72 fn deinit(unit: *Unit, gpa: std.mem.Allocator) void {
73 unit.dirs.deinit(gpa);
74 unit.files.deinit(gpa);
75 unit.* = undefined;
76 }
77
78 fn getFile(
79 unit: *Unit,
80 gpa: std.mem.Allocator,
81 ui: Unit.Index,
82 zfi: Zcu.File.Index,
83 ) std.mem.Allocator.Error!struct { DirIndex, FileIndex } {
84 try unit.dirs.ensureUnusedCapacity(gpa, 1);
85 try unit.files.ensureUnusedCapacity(gpa, 1);
86 const dir_gop = unit.dirs.getOrPutAssumeCapacity(ui);
87 const file_gop = unit.files.getOrPutAssumeCapacity(zfi);
88 if (!dir_gop.found_existing or !file_gop.found_existing) unit.debug_line_header_changed = true;
89 return .{ @fromBackingInt(@intCast(dir_gop.index)), @fromBackingInt(@intCast(file_gop.index)) };
90 }
91
92 pub fn cleanDebugLineHeaderChanged(unit: *Unit) bool {
93 defer unit.debug_line_header_changed = false;
94 return unit.debug_line_header_changed;
95 }
96};
97
98pub const Const = struct {
99 debug_info_ni: link.MappedFile.Node.Index.Optional,
100
101 pub fn get(cpi: link.ConstPool.Index, dwarf: *Dwarf) *Const {
102 return &dwarf.consts.items[@backingInt(cpi)];
103 }
104};
105
106pub const Global = struct {
107 debug_info_ni: link.MappedFile.Node.Index.Optional,
108
109 pub const Index = enum(u32) {
110 _,
111
112 pub fn nav(gi: Global.Index, dwarf: *Dwarf) InternPool.Nav.Index {
113 return dwarf.globals.keys()[@backingInt(gi)];
114 }
115
116 pub fn get(gi: Global.Index, dwarf: *Dwarf) *Global {
117 return &dwarf.globals.values()[@backingInt(gi)];
118 }
119 };
120};
121
122pub const Func = struct {
123 state: State,
124 fde_ni: link.MappedFile.Node.Index.Optional,
125 debug_info_ni: link.MappedFile.Node.Index.Optional,
126 debug_line_ni: link.MappedFile.Node.Index.Optional,
127
128 pub const State = enum { unresolved, resolved };
129
130 pub const Index = enum(u32) {
131 _,
132
133 pub fn nav(fi: Func.Index, dwarf: *Dwarf) InternPool.Nav.Index {
134 return dwarf.funcs.keys()[@backingInt(fi)];
135 }
136
137 pub fn get(fi: Func.Index, dwarf: *Dwarf) *Func {
138 return &dwarf.funcs.values()[@backingInt(fi)];
139 }
140 };
141};
142
143pub const Decl = struct {
144 debug_info_ni: link.MappedFile.Node.Index.Optional,
145
146 pub const Index = enum(u32) {
147 _,
148
149 pub fn srcInst(di: Decl.Index, dwarf: *Dwarf) InternPool.TrackedInst.Index {
150 return dwarf.decls.keys()[@backingInt(di)];
151 }
152
153 pub fn get(di: Decl.Index, dwarf: *Dwarf) *Decl {
154 return &dwarf.decls.values()[@backingInt(di)];
155 }
156 };
157};
158
159pub const Frame = struct {
160 header: Header,
161
162 pub const Header = struct {
163 code_alignment_factor: u32,
164 data_alignment_factor: i32,
165 return_address_register: u32,
166 initial_instructions: []const Cfa,
167 };
168
169 pub const Format = std.debug.Dwarf.Unwind.Section;
170};
171
172pub const Abbrev = struct {
173 ni: link.MappedFile.Node.Index.Optional,
174 end: usize,
175 set: std.enums.EnumSet(AbbrevCode),
176};
177
178pub const Info = struct {};
179
180pub const Line = struct {
181 header: Header,
182
183 pub const Header = struct {
184 minimum_instruction_length: u8,
185 maximum_operations_per_instruction: u8,
186 default_is_stmt: bool,
187 line_base: i8,
188 line_range: u8,
189 opcode_base: u8,
190 };
191};
192
193pub const Str = struct {
194 ni: link.MappedFile.Node.Index.Optional,
195 offset: usize,
196 map: std.HashMapUnmanaged(usize, void, Context, std.hash_map.default_max_load_percentage),
197
198 fn get(
199 s: *Str,
200 gpa: std.mem.Allocator,
201 mf: *link.MappedFile,
202 str: []const u8,
203 ) link.MappedFile.Error!usize {
204 const ni = s.ni.unwrap().?;
205 const slice = ni.sliceConst(mf);
206 const gop = try s.map.getOrPutContextAdapted(
207 gpa,
208 str,
209 Adapter{ .slice = slice },
210 .{ .slice = slice },
211 );
212 if (!gop.found_existing) {
213 gop.key_ptr.* = s.offset;
214 try ni.ensureMinimumSize(gpa, mf, s.offset + str.len + 1);
215 const slice_mut = ni.slice(mf);
216 @memcpy(slice_mut[s.offset..][0..str.len], str);
217 s.offset += str.len;
218 slice_mut[s.offset] = 0;
219 s.offset += 1;
220 }
221 return gop.key_ptr.*;
222 }
223
224 const Context = struct {
225 slice: []const u8,
226 pub fn hash(context: Context, offset: usize) u64 {
227 return std.hash.Wyhash.hash(0, std.mem.sliceTo(context.slice[offset..], 0));
228 }
229 pub fn eql(_: Context, lhs_offset: usize, rhs_offset: usize) bool {
230 return lhs_offset == rhs_offset;
231 }
232 };
233
234 const Adapter = struct {
235 slice: []const u8,
236 pub fn hash(_: Adapter, key: []const u8) u64 {
237 return std.hash.Wyhash.hash(0, key);
238 }
239 pub fn eql(adapter: Adapter, key: []const u8, rhs_offset: usize) bool {
240 return std.mem.startsWith(u8, adapter.slice[rhs_offset..], key) and
241 adapter.slice[rhs_offset + key.len] == 0;
242 }
243 };
244};
245
246pub const Rnglists = struct {
247 fn offsetsTableOffset(dwarf: *Dwarf) usize {
248 return dwarf.unitLengthSize() + 2 + 1 + 1 + 4;
249 }
250};
251
252pub const StrOffsets = struct {
253 ni: link.MappedFile.Node.Index.Optional,
254 offset: usize,
255};
256
257pub const SharedSection = enum { debug_abbrev, debug_line_str, debug_str, debug_str_offsets };
258
259pub const Loc = union(enum) {
260 empty,
261 addr_reloc: link.File.SymbolId,
262 deref: *const Loc,
263 constu: u64,
264 consts: i64,
265 plus: Bin,
266 reg: u32,
267 breg: u32,
268 push_object_address,
269 call: struct {
270 args: []const Loc = &.{},
271 node: link.MappedFile.Node.Index,
272 },
273 form_tls_address: *const Loc,
274 implicit_value: []const u8,
275 stack_value: *const Loc,
276 implicit_pointer: struct {
277 node: link.MappedFile.Node.Index,
278 offset: i65 = 0,
279 },
280 wasm_ext: union(enum) {
281 local: u32,
282 global: u32,
283 operand_stack: u32,
284 },
285
286 pub const Bin = struct { *const Loc, *const Loc };
287
288 fn getConst(loc: Loc, comptime Int: type) ?Int {
289 return switch (loc) {
290 .constu => |constu| std.math.cast(Int, constu),
291 .consts => |consts| std.math.cast(Int, consts),
292 else => null,
293 };
294 }
295
296 fn getBaseReg(loc: Loc) ?u32 {
297 return switch (loc) {
298 .breg => |breg| breg,
299 else => null,
300 };
301 }
302
303 fn writeReg(reg: u32, op0: u8, opx: u8, writer: *std.Io.Writer) std.Io.Writer.Error!void {
304 if (std.math.cast(u5, reg)) |small_reg| {
305 try writer.writeByte(op0 + small_reg);
306 } else {
307 try writer.writeByte(opx);
308 try writer.writeUleb128(reg);
309 }
310 }
311
312 fn write(loc: Loc, writer: union(enum) {
313 io: *std.Io.Writer,
314 mf: *link.MappedFile.Node.Writer,
315 }, dwarf: *Dwarf) link.EmitError!void {
316 const w = switch (writer) {
317 .io => |w| w,
318 .mf => |nw| &nw.interface,
319 };
320 switch (loc) {
321 .empty => {},
322 .addr_reloc => |si| {
323 try w.writeByte(DW.OP.addr);
324 switch (writer) {
325 .io => try dwarf.addrPlaceholder(w),
326 .mf => |nw| try dwarf.addrSym(nw, si, 0),
327 }
328 },
329 .deref => |addr| {
330 try addr.write(writer, dwarf);
331 try w.writeByte(DW.OP.deref);
332 },
333 .constu => |constu| if (std.math.cast(u5, constu)) |lit| {
334 try w.writeByte(@as(u8, DW.OP.lit0) + lit);
335 } else if (std.math.cast(u8, constu)) |const1u| {
336 try w.writeAll(&.{ DW.OP.const1u, const1u });
337 } else if (std.math.cast(u16, constu)) |const2u| {
338 try w.writeByte(DW.OP.const2u);
339 try w.writeInt(u16, const2u, dwarf.endian);
340 } else if (std.math.cast(u21, constu)) |const3u| {
341 try w.writeByte(DW.OP.constu);
342 try w.writeUleb128(const3u);
343 } else if (std.math.cast(u32, constu)) |const4u| {
344 try w.writeByte(DW.OP.const4u);
345 try w.writeInt(u32, const4u, dwarf.endian);
346 } else if (std.math.cast(u49, constu)) |const7u| {
347 try w.writeByte(DW.OP.constu);
348 try w.writeUleb128(const7u);
349 } else {
350 try w.writeByte(DW.OP.const8u);
351 try w.writeInt(u64, constu, dwarf.endian);
352 },
353 .consts => |consts| if (std.math.cast(i8, consts)) |const1s| {
354 try w.writeAll(&.{ DW.OP.const1s, @bitCast(const1s) });
355 } else if (std.math.cast(i16, consts)) |const2s| {
356 try w.writeByte(DW.OP.const2s);
357 try w.writeInt(i16, const2s, dwarf.endian);
358 } else if (std.math.cast(i21, consts)) |const3s| {
359 try w.writeByte(DW.OP.consts);
360 try w.writeSleb128(const3s);
361 } else if (std.math.cast(i32, consts)) |const4s| {
362 try w.writeByte(DW.OP.const4s);
363 try w.writeInt(i32, const4s, dwarf.endian);
364 } else if (std.math.cast(i49, consts)) |const7s| {
365 try w.writeByte(DW.OP.consts);
366 try w.writeSleb128(const7s);
367 } else {
368 try w.writeByte(DW.OP.const8s);
369 try w.writeInt(i64, consts, dwarf.endian);
370 },
371 .plus => |plus| done: {
372 if (plus[0].getConst(u0)) |_| {
373 try plus[1].write(writer, dwarf);
374 break :done;
375 }
376 if (plus[1].getConst(u0)) |_| {
377 try plus[0].write(writer, dwarf);
378 break :done;
379 }
380 if (plus[0].getBaseReg()) |breg| {
381 if (plus[1].getConst(i65)) |offset| {
382 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
383 try w.writeSleb128(offset);
384 break :done;
385 }
386 }
387 if (plus[1].getBaseReg()) |breg| {
388 if (plus[0].getConst(i65)) |offset| {
389 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
390 try w.writeSleb128(offset);
391 break :done;
392 }
393 }
394 if (plus[0].getConst(u64)) |uconst| {
395 try plus[1].write(writer, dwarf);
396 try w.writeByte(DW.OP.plus_uconst);
397 try w.writeUleb128(uconst);
398 break :done;
399 }
400 if (plus[1].getConst(u64)) |uconst| {
401 try plus[0].write(writer, dwarf);
402 try w.writeByte(DW.OP.plus_uconst);
403 try w.writeUleb128(uconst);
404 break :done;
405 }
406 try plus[0].write(writer, dwarf);
407 try plus[1].write(writer, dwarf);
408 try w.writeByte(DW.OP.plus);
409 },
410 .reg => |reg| try writeReg(reg, DW.OP.reg0, DW.OP.regx, w),
411 .breg => |breg| {
412 try writeReg(breg, DW.OP.breg0, DW.OP.bregx, w);
413 try w.writeSleb128(0);
414 },
415 .push_object_address => try w.writeByte(DW.OP.push_object_address),
416 .call => |call| {
417 for (call.args) |arg| try arg.write(writer, dwarf);
418 try w.writeByte(DW.OP.call_ref);
419 switch (writer) {
420 .io => try dwarf.secOffsetPlaceholder(w),
421 .mf => |nw| try dwarf.secOffset(nw, call.node, 0),
422 }
423 },
424 .form_tls_address => |addr| {
425 try addr.write(writer, dwarf);
426 try w.writeByte(DW.OP.form_tls_address);
427 },
428 .implicit_value => |value| {
429 try w.writeByte(DW.OP.implicit_value);
430 try w.writeUleb128(value.len);
431 try w.writeAll(value);
432 },
433 .stack_value => |value| {
434 try value.write(writer, dwarf);
435 try w.writeByte(DW.OP.stack_value);
436 },
437 .implicit_pointer => |implicit_pointer| {
438 try w.writeByte(DW.OP.implicit_pointer);
439 switch (writer) {
440 .io => try dwarf.secOffsetPlaceholder(w),
441 .mf => |nw| try dwarf.secOffset(nw, implicit_pointer.node, 0),
442 }
443 try w.writeSleb128(implicit_pointer.offset);
444 },
445 .wasm_ext => |wasm_ext| {
446 try w.writeByte(DW.OP.WASM_location);
447 switch (wasm_ext) {
448 .local => |local| {
449 try w.writeByte(DW.OP.WASM_local);
450 try w.writeUleb128(local);
451 },
452 .global => |global| if (std.math.cast(u21, global)) |global_u21| {
453 try w.writeByte(DW.OP.WASM_global);
454 try w.writeUleb128(global_u21);
455 } else {
456 try w.writeByte(DW.OP.WASM_global_u32);
457 try w.writeInt(u32, global, dwarf.endian);
458 },
459 .operand_stack => |operand_stack| {
460 try w.writeByte(DW.OP.WASM_operand_stack);
461 try w.writeUleb128(operand_stack);
462 },
463 }
464 },
465 }
466 }
467};
468
469pub const Cfa = union(enum) {
470 nop,
471 advance_loc: u32,
472 offset: RegOff,
473 rel_offset: RegOff,
474 restore: u32,
475 undefined: u32,
476 same_value: u32,
477 register: [2]u32,
478 remember_state,
479 restore_state,
480 def_cfa: RegOff,
481 def_cfa_register: u32,
482 def_cfa_offset: i64,
483 adjust_cfa_offset: i64,
484 def_cfa_expression: Loc,
485 expression: RegExpr,
486 val_offset: RegOff,
487 val_expression: RegExpr,
488 escape: []const u8,
489
490 const RegOff = struct { reg: u32, off: i64 };
491 const RegExpr = struct { reg: u32, expr: Loc };
492
493 fn write(cfa: Cfa, wip_nav: *WipNav) link.EmitError!void {
494 const df_nw = &wip_nav.fde_writer;
495 const df_w = &df_nw.interface;
496 switch (cfa) {
497 .nop => try df_w.writeByte(DW.CFA.nop),
498 .advance_loc => |loc| {
499 const delta =
500 @divExact(loc - wip_nav.cfi.loc, wip_nav.dwarf.frame.header.code_alignment_factor);
501 if (delta == 0) {} else if (std.math.cast(u6, delta)) |small_delta|
502 try df_w.writeByte(@as(u8, DW.CFA.advance_loc) + small_delta)
503 else if (std.math.cast(u8, delta)) |ubyte_delta|
504 try df_w.writeAll(&.{ DW.CFA.advance_loc1, ubyte_delta })
505 else if (std.math.cast(u16, delta)) |uhalf_delta| {
506 try df_w.writeByte(DW.CFA.advance_loc2);
507 try df_w.writeInt(u16, uhalf_delta, wip_nav.dwarf.endian);
508 } else if (std.math.cast(u32, delta)) |uword_delta| {
509 try df_w.writeByte(DW.CFA.advance_loc4);
510 try df_w.writeInt(u32, uword_delta, wip_nav.dwarf.endian);
511 }
512 wip_nav.cfi.loc = loc;
513 },
514 .offset, .rel_offset => |reg_off| {
515 const factored_off = @divExact(reg_off.off - switch (cfa) {
516 else => unreachable,
517 .offset => 0,
518 .rel_offset => wip_nav.cfi.cfa.off,
519 }, wip_nav.dwarf.frame.header.data_alignment_factor);
520 if (std.math.cast(u63, factored_off)) |unsigned_off| {
521 if (std.math.cast(u6, reg_off.reg)) |small_reg| {
522 try df_w.writeByte(@as(u8, DW.CFA.offset) + small_reg);
523 } else {
524 try df_w.writeByte(DW.CFA.offset_extended);
525 try df_w.writeUleb128(reg_off.reg);
526 }
527 try df_w.writeUleb128(unsigned_off);
528 } else {
529 try df_w.writeByte(DW.CFA.offset_extended_sf);
530 try df_w.writeUleb128(reg_off.reg);
531 try df_w.writeSleb128(factored_off);
532 }
533 },
534 .restore => |reg| if (std.math.cast(u6, reg)) |small_reg|
535 try df_w.writeByte(@as(u8, DW.CFA.restore) + small_reg)
536 else {
537 try df_w.writeByte(DW.CFA.restore_extended);
538 try df_w.writeUleb128(reg);
539 },
540 .undefined => |reg| {
541 try df_w.writeByte(DW.CFA.undefined);
542 try df_w.writeUleb128(reg);
543 },
544 .same_value => |reg| {
545 try df_w.writeByte(DW.CFA.same_value);
546 try df_w.writeUleb128(reg);
547 },
548 .register => |regs| if (regs[0] != regs[1]) {
549 try df_w.writeByte(DW.CFA.register);
550 for (regs) |reg| try df_w.writeUleb128(reg);
551 } else {
552 try df_w.writeByte(DW.CFA.same_value);
553 try df_w.writeUleb128(regs[0]);
554 },
555 .remember_state => try df_w.writeByte(DW.CFA.remember_state),
556 .restore_state => try df_w.writeByte(DW.CFA.restore_state),
557 .def_cfa, .def_cfa_register, .def_cfa_offset, .adjust_cfa_offset => {
558 const reg_off: RegOff = switch (cfa) {
559 else => unreachable,
560 .def_cfa => |reg_off| reg_off,
561 .def_cfa_register => |reg| .{ .reg = reg, .off = wip_nav.cfi.cfa.off },
562 .def_cfa_offset => |off| .{ .reg = wip_nav.cfi.cfa.reg, .off = off },
563 .adjust_cfa_offset => |off| .{
564 .reg = wip_nav.cfi.cfa.reg,
565 .off = wip_nav.cfi.cfa.off + off,
566 },
567 };
568 const changed_reg = reg_off.reg != wip_nav.cfi.cfa.reg;
569 const unsigned_off = std.math.cast(u63, reg_off.off);
570 if (reg_off.off == wip_nav.cfi.cfa.off) {
571 if (changed_reg) {
572 try df_w.writeByte(DW.CFA.def_cfa_register);
573 try df_w.writeUleb128(reg_off.reg);
574 }
575 } else if (switch (wip_nav.dwarf.frame.header.data_alignment_factor) {
576 0 => unreachable,
577 1 => unsigned_off != null,
578 else => |data_alignment_factor| @rem(reg_off.off, data_alignment_factor) != 0,
579 }) {
580 try df_w.writeByte(if (changed_reg) DW.CFA.def_cfa else DW.CFA.def_cfa_offset);
581 if (changed_reg) try df_w.writeUleb128(reg_off.reg);
582 try df_w.writeUleb128(unsigned_off.?);
583 } else {
584 try df_w.writeByte(if (changed_reg) DW.CFA.def_cfa_sf else DW.CFA.def_cfa_offset_sf);
585 if (changed_reg) try df_w.writeUleb128(reg_off.reg);
586 try df_w.writeSleb128(
587 @divExact(reg_off.off, wip_nav.dwarf.frame.header.data_alignment_factor),
588 );
589 }
590 wip_nav.cfi.cfa = reg_off;
591 },
592 .def_cfa_expression => |expr| {
593 try df_w.writeByte(DW.CFA.def_cfa_expression);
594 try wip_nav.dwarf.exprLoc(df_nw, expr);
595 },
596 .expression => |reg_expr| {
597 try df_w.writeByte(DW.CFA.expression);
598 try df_w.writeUleb128(reg_expr.reg);
599 try wip_nav.dwarf.exprLoc(df_nw, reg_expr.expr);
600 },
601 .val_offset => |reg_off| {
602 const factored_off =
603 @divExact(reg_off.off, wip_nav.dwarf.frame.header.data_alignment_factor);
604 if (std.math.cast(u63, factored_off)) |unsigned_off| {
605 try df_w.writeByte(DW.CFA.val_offset);
606 try df_w.writeUleb128(reg_off.reg);
607 try df_w.writeUleb128(unsigned_off);
608 } else {
609 try df_w.writeByte(DW.CFA.val_offset_sf);
610 try df_w.writeUleb128(reg_off.reg);
611 try df_w.writeSleb128(factored_off);
612 }
613 },
614 .val_expression => |reg_expr| {
615 try df_w.writeByte(DW.CFA.val_expression);
616 try df_w.writeUleb128(reg_expr.reg);
617 try wip_nav.dwarf.exprLoc(df_nw, reg_expr.expr);
618 },
619 .escape => |bytes| try df_w.writeAll(bytes),
620 }
621 }
622};
623
624pub const WipNav = struct {
625 dwarf: *Dwarf,
626 unit: Unit.Index,
627 func: InternPool.Index,
628 func_si: link.File.SymbolId,
629 cfi: struct {
630 loc: u32,
631 cfa: Cfa.RegOff,
632 },
633 frame_format: Frame.Format,
634 fde_writer: link.MappedFile.Node.Writer,
635 frame_func_length: struct { offset: usize, size: AddressSize },
636
637 pub const Debug = struct {
638 wip_nav: WipNav,
639 pt: Zcu.PerThread,
640 any_children: bool,
641 blocks: std.ArrayList(struct {
642 abbrev_code: u32,
643 low_pc_off: usize,
644 high_pc: u32,
645 }),
646 info_writer: link.MappedFile.Node.Writer,
647 info_func_length_offset: usize,
648 line_writer: link.MappedFile.Node.Writer,
649
650 pub fn deinit(debug: *Debug) void {
651 const gpa = debug.pt.zcu.gpa;
652 debug.line_writer.deinit();
653 debug.info_writer.deinit();
654 debug.blocks.deinit(gpa);
655 debug.wip_nav.deinit();
656 debug.* = undefined;
657 }
658
659 pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) link.Error!void {
660 return debug.wip_nav.genDebugFrame(loc, cfa);
661 }
662
663 pub fn startFuncDebugInfo(debug: *Debug) link.Error!void {
664 assert(debug.wip_nav.func != .none);
665 debug.startFuncDebugInfoInner() catch |err| switch (err) {
666 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
667 else => |e| return e,
668 };
669 }
670 fn startFuncDebugInfoInner(debug: *Debug) link.EmitError!void {
671 const dwarf = debug.wip_nav.dwarf;
672 const pt = debug.pt;
673 const zcu = pt.zcu;
674 const ip = &zcu.intern_pool;
675 const func = zcu.funcInfo(debug.wip_nav.func);
676 const nav = ip.getNav(func.owner_nav);
677 const func_type = ip.indexToKey(func.ty).func_type;
678 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
679 const zf = zcu.fileByIndex(inst_info.file);
680 const target = &zf.mod.?.resolved_target.result;
681 const decl = zf.zir.?.getDeclaration(inst_info.inst);
682 const di_nw = &debug.info_writer;
683 const di_w = &di_nw.interface;
684 try dwarf.abbrevCode(di_nw, .decl_func);
685 try dwarf.refType(pt, di_nw, .fromInterned(ip.namespacePtr(switch (func.generic_owner) {
686 .none => nav,
687 else => |generic_owner| ip.getNav(zcu.funcInfo(generic_owner).owner_nav),
688 }.analysis.?.namespace).owner_type));
689 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
690 try di_w.writeUleb128(decl.src_column + 1);
691 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
692 try dwarf.strp(&dwarf.debug_str, di_nw, nav.name.toSlice(ip));
693 try dwarf.strp(&dwarf.debug_str, di_nw, switch (decl.linkage) {
694 .normal => nav.fqn,
695 .@"extern", .@"export" => nav.name,
696 }.toSlice(ip));
697 try dwarf.refType(pt, di_nw, .fromInterned(func_type.return_type));
698 try dwarf.addrSym(di_nw, debug.wip_nav.func_si, 0);
699 debug.info_func_length_offset = di_w.end;
700 try di_w.writeInt(u32, undefined, dwarf.endian);
701 try di_w.writeUleb128(
702 target_info.minFunctionAlignment(target).max(nav.resolved.?.@"align").toByteUnits().?,
703 );
704 try di_w.writeByte(@intFromBool(decl.linkage != .normal));
705 try di_w.writeByte(@intFromBool(Type.fromInterned(func_type.return_type).isNoReturn(zcu)));
706 }
707
708 pub fn startDebugLine(debug: *Debug) link.Error!void {
709 assert(debug.wip_nav.func != .none);
710 debug.startDebugLineInner() catch |err| switch (err) {
711 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
712 else => |e| return e,
713 };
714 }
715 fn startDebugLineInner(debug: *Debug) link.EmitError!void {
716 const dwarf = debug.wip_nav.dwarf;
717 const zcu = debug.pt.zcu;
718 const ip = &zcu.intern_pool;
719 const func = zcu.funcInfo(debug.wip_nav.func);
720 const inst_info = ip.getNav(func.owner_nav).srcInst(ip).resolveFull(ip).?;
721 const zf = zcu.fileByIndex(inst_info.file);
722 const decl = zf.zir.?.getDeclaration(inst_info.inst);
723 const dl_nw = &debug.line_writer;
724 const dl_w = &dl_nw.interface;
725 try dl_w.writeByte(DW.LNS.extended_op);
726 if (zcu.comp.config.incremental) {
727 try dl_w.writeUleb128(1 + dwarf.secOffsetSize());
728 try dl_w.writeByte(DW.LNE.ZIG_set_decl);
729 try dwarf.secOffset(dl_nw, debug.info_writer.ni, 0);
730
731 try dl_w.writeByte(DW.LNS.set_column);
732 try dl_w.writeUleb128(func.lbrace_column + 1);
733
734 try debug.advanceLineAndPc(func.lbrace_line, 0, false);
735 } else {
736 try dl_w.writeUleb128(1 + @backingInt(dwarf.address_size));
737 try dl_w.writeByte(DW.LNE.set_address);
738 try dwarf.addrSym(dl_nw, debug.wip_nav.func_si, 0);
739
740 const unit = dwarf.getUnit(zf.mod.?);
741 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);
742 try dl_w.writeByte(DW.LNS.set_file);
743 try dl_w.writeUleb128(@backingInt(fi));
744
745 try dl_w.writeByte(DW.LNS.set_column);
746 try dl_w.writeUleb128(func.lbrace_column + 1);
747
748 try debug.advanceLineAndPc(decl.src_line + func.lbrace_line, 0, false);
749 }
750 }
751
752 pub fn finishFunc(debug: *Debug, func_length: u64) link.Error!void {
753 assert(debug.wip_nav.func != .none);
754 const di_nw = &debug.info_writer;
755 debug.finishDebugInfo(func_length) catch |err| switch (err) {
756 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(di_nw),
757 else => |e| return e,
758 };
759 debug.finishDebugLine() catch |err| switch (err) {
760 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(di_nw),
761 else => |e| return e,
762 };
763 }
764 fn finishDebugInfo(debug: *Debug, func_length: u64) link.EmitError!void {
765 const dwarf = debug.wip_nav.dwarf;
766 const di_w = &debug.info_writer.interface;
767 std.mem.writeInt(
768 u32,
769 di_w.buffered()[debug.info_func_length_offset..][0..4],
770 @intCast(func_length),
771 dwarf.endian,
772 );
773 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
774 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
775 }
776 fn finishDebugLine(debug: *Debug) link.EmitError!void {
777 const dl_w = &debug.line_writer.interface;
778 try genDebugLinePadding(dl_w, dl_w.unusedCapacityLen());
779 }
780
781 pub const LocalVarTag = enum { arg, local_var };
782 pub fn genLocalVarDebugInfo(
783 debug: *Debug,
784 tag: LocalVarTag,
785 opt_name: ?[]const u8,
786 ty: Type,
787 loc: Loc,
788 ) link.Error!void {
789 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {
790 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
791 else => |e| e,
792 };
793 }
794 fn genLocalVarDebugInfoInner(
795 debug: *Debug,
796 tag: LocalVarTag,
797 opt_name: ?[]const u8,
798 ty: Type,
799 loc: Loc,
800 ) link.EmitError!void {
801 assert(debug.wip_nav.func != .none);
802 const dwarf = debug.wip_nav.dwarf;
803 const di_nw = &debug.info_writer;
804 try dwarf.abbrevCode(di_nw, switch (tag) {
805 .arg => if (opt_name) |_| .arg else .unnamed_arg,
806 .local_var => if (opt_name) |_| .local_var else unreachable,
807 });
808 if (opt_name) |name| try dwarf.strp(&dwarf.debug_str, di_nw, name);
809 try dwarf.refType(debug.pt, di_nw, ty);
810 try dwarf.exprLoc(di_nw, loc);
811 debug.any_children = true;
812 }
813
814 pub const LocalConstTag = enum { comptime_arg, local_const };
815 pub fn genLocalConstDebugInfo(
816 debug: *Debug,
817 tag: LocalConstTag,
818 opt_name: ?[]const u8,
819 val: Value,
820 ) link.Error!void {
821 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {
822 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
823 else => |e| e,
824 };
825 }
826 fn genLocalConstDebugInfoInner(
827 debug: *Debug,
828 tag: LocalConstTag,
829 opt_name: ?[]const u8,
830 val: Value,
831 ) link.EmitError!void {
832 assert(debug.wip_nav.func != .none);
833 const dwarf = debug.wip_nav.dwarf;
834 const pt = debug.pt;
835 const zcu = debug.pt.zcu;
836 const ty = val.typeOf(zcu);
837 const ty_class = ty.classify(zcu);
838 const di_nw = &debug.info_writer;
839 try dwarf.abbrevCode(di_nw, switch (tag) {
840 .comptime_arg => if (opt_name) |_| switch (ty_class) {
841 .no_possible_value => unreachable,
842 .one_possible_value => .comptime_arg,
843 .runtime => .comptime_arg_fully_runtime,
844 .partially_comptime => .comptime_arg_partially_comptime,
845 .fully_comptime => .comptime_arg_fully_comptime,
846 } else switch (ty_class) {
847 .no_possible_value => unreachable,
848 .one_possible_value => .unnamed_comptime_arg,
849 .runtime => .unnamed_comptime_arg_fully_runtime,
850 .partially_comptime => .unnamed_comptime_arg_partially_comptime,
851 .fully_comptime => .unnamed_comptime_arg_fully_comptime,
852 },
853 .local_const => if (opt_name) |_| switch (ty_class) {
854 .no_possible_value => unreachable,
855 .one_possible_value => .local_const,
856 .runtime => .local_const_fully_runtime,
857 .partially_comptime => .local_const_partially_comptime,
858 .fully_comptime => .local_const_fully_comptime,
859 } else unreachable,
860 });
861 if (opt_name) |name| try dwarf.strp(&dwarf.debug_str, di_nw, name);
862 try dwarf.refType(pt, di_nw, ty);
863 if (ty_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, val);
864 if (ty_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, val);
865 debug.any_children = true;
866 }
867
868 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {
869 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {
870 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
871 else => |e| e,
872 };
873 }
874 fn genVarArgsDebugInfoInner(debug: *Debug) link.EmitError!void {
875 assert(debug.wip_nav.func != .none);
876 try debug.wip_nav.dwarf.abbrevCode(&debug.info_writer, .is_var_args);
877 debug.any_children = true;
878 }
879
880 pub fn advanceLineAndPc(
881 debug: *Debug,
882 delta_line: i33,
883 delta_pc: u64,
884 end: bool,
885 ) link.Error!void {
886 return debug.advanceLineAndPcInner(delta_line, delta_pc, end) catch |err| switch (err) {
887 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
888 };
889 }
890 fn advanceLineAndPcInner(
891 debug: *Debug,
892 delta_line: i33,
893 delta_pc: u64,
894 end: bool,
895 ) std.Io.Writer.Error!void {
896 const dl_w = &debug.line_writer.interface;
897
898 const header = debug.wip_nav.dwarf.debug_line.header;
899 assert(header.maximum_operations_per_instruction == 1);
900 const delta_op: u64 = 0;
901
902 const remaining_delta_line: i9 = @intCast(if (delta_line < header.line_base or
903 delta_line - header.line_base >= header.line_range)
904 remaining: {
905 assert(delta_line != 0);
906 try dl_w.writeByte(DW.LNS.advance_line);
907 try dl_w.writeSleb128(delta_line);
908 break :remaining 0;
909 } else delta_line);
910
911 const op_advance = @divExact(delta_pc, header.minimum_instruction_length) *
912 header.maximum_operations_per_instruction + delta_op;
913 const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range;
914 const remaining_op_advance: u8 = @intCast(if (end or
915 op_advance >= 2 * max_op_advance)
916 remaining: {
917 if (op_advance == max_op_advance) {
918 try dl_w.writeByte(DW.LNS.const_add_pc);
919 } else if (op_advance != 0) {
920 try dl_w.writeByte(DW.LNS.advance_pc);
921 try dl_w.writeUleb128(op_advance);
922 } else assert(end);
923 break :remaining 0;
924 } else if (op_advance >= max_op_advance) remaining: {
925 try dl_w.writeByte(DW.LNS.const_add_pc);
926 break :remaining op_advance - max_op_advance;
927 } else op_advance);
928
929 if (remaining_delta_line != 0 or remaining_op_advance != 0) {
930 assert(!end);
931 try dl_w.writeByte(@intCast((remaining_delta_line - header.line_base) +
932 (header.line_range * remaining_op_advance) + header.opcode_base));
933 } else if (end) {
934 try dl_w.writeByte(DW.LNS.extended_op);
935 try dl_w.writeUleb128(1);
936 try dl_w.writeByte(DW.LNE.end_sequence);
937 } else try dl_w.writeByte(DW.LNS.copy);
938 }
939
940 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {
941 return debug.setColumnInner(column) catch |err| switch (err) {
942 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
943 };
944 }
945 fn setColumnInner(debug: *Debug, column: u32) std.Io.Writer.Error!void {
946 const dl_w = &debug.line_writer.interface;
947 try dl_w.writeByte(DW.LNS.set_column);
948 try dl_w.writeUleb128(column + 1);
949 }
950
951 pub fn negateStmt(debug: *Debug) link.Error!void {
952 return debug.negateStmtInner() catch |err| switch (err) {
953 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
954 };
955 }
956 fn negateStmtInner(debug: *Debug) std.Io.Writer.Error!void {
957 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);
958 }
959
960 pub fn setPrologueEnd(debug: *Debug) link.Error!void {
961 return debug.setPrologueEndInner() catch |err| switch (err) {
962 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
963 };
964 }
965 fn setPrologueEndInner(debug: *Debug) std.Io.Writer.Error!void {
966 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);
967 }
968
969 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {
970 return debug.setEpilogueBeginInner() catch |err| switch (err) {
971 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
972 };
973 }
974 fn setEpilogueBeginInner(debug: *Debug) std.Io.Writer.Error!void {
975 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);
976 }
977
978 pub fn enterBlock(debug: *Debug, code_off: usize) link.Error!void {
979 return debug.enterBlockInner(code_off) catch |err| switch (err) {
980 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
981 else => |e| e,
982 };
983 }
984 fn enterBlockInner(debug: *Debug, code_off: usize) link.EmitError!void {
985 const dwarf = debug.wip_nav.dwarf;
986 const block = try debug.blocks.addOne(dwarf.lf.comp.gpa);
987
988 const di_nw = &debug.info_writer;
989 const di_w = &di_nw.interface;
990 block.abbrev_code = @intCast(di_w.end);
991 try dwarf.abbrevCode(di_nw, .block);
992 block.low_pc_off = code_off;
993 try dwarf.addrSym(di_nw, debug.wip_nav.func_si, code_off);
994 block.high_pc = @intCast(di_w.end);
995 try di_w.writeInt(u32, 0, dwarf.endian);
996 debug.any_children = false;
997 }
998
999 pub fn leaveBlock(debug: *Debug, code_off: usize) link.Error!void {
1000 return debug.leaveBlockInner(code_off) catch |err| switch (err) {
1001 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
1002 else => |e| e,
1003 };
1004 }
1005 fn leaveBlockInner(debug: *Debug, code_off: usize) link.EmitError!void {
1006 const dwarf = debug.wip_nav.dwarf;
1007 const block_size = comptime uleb128Size(@backingInt(AbbrevCode.block));
1008 const block = debug.blocks.pop().?;
1009
1010 const di_nw = &debug.info_writer;
1011 const di_w = &di_nw.interface;
1012 if (debug.any_children)
1013 try di_w.writeUleb128(@backingInt(AbbrevCode.null))
1014 else
1015 std.leb.writeUnsignedFixed(
1016 block_size,
1017 di_w.buffered()[block.abbrev_code..][0..block_size],
1018 @intCast(try dwarf.refAbbrevCode(di_nw.mf, .empty_block)),
1019 );
1020 std.mem.writeInt(
1021 u32,
1022 di_nw.interface.buffered()[block.high_pc..][0..4],
1023 @intCast(code_off - block.low_pc_off),
1024 dwarf.endian,
1025 );
1026 debug.any_children = true;
1027 }
1028
1029 pub fn enterInlineFunc(
1030 debug: *Debug,
1031 func: InternPool.Index,
1032 code_off: usize,
1033 line: u32,
1034 column: u32,
1035 ) link.Error!void {
1036 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {
1037 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
1038 else => |e| e,
1039 };
1040 }
1041 fn enterInlineFuncInner(
1042 debug: *Debug,
1043 func: InternPool.Index,
1044 code_off: usize,
1045 line: u32,
1046 column: u32,
1047 ) link.EmitError!void {
1048 const dwarf = debug.wip_nav.dwarf;
1049 const zcu = debug.pt.zcu;
1050 const block = try debug.blocks.addOne(zcu.gpa);
1051
1052 const di_nw = &debug.info_writer;
1053 const di_w = &di_nw.interface;
1054 block.abbrev_code = @intCast(di_w.end);
1055 try dwarf.abbrevCode(di_nw, .inlined_func);
1056 try debug.refFunc(func);
1057 try di_w.writeUleb128((if (zcu.comp.config.incremental)
1058 0
1059 else
1060 zcu.navSrcLine(zcu.funcInfo(debug.wip_nav.func).owner_nav) + 1) + line);
1061 try di_w.writeUleb128(column + 1);
1062 block.low_pc_off = code_off;
1063 try dwarf.addrSym(di_nw, debug.wip_nav.func_si, code_off);
1064 block.high_pc = @intCast(di_w.end);
1065 try di_w.writeInt(u32, 0, dwarf.endian);
1066 try debug.setInlineFunc(func);
1067 debug.any_children = false;
1068 }
1069
1070 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: usize) link.Error!void {
1071 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {
1072 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer),
1073 else => |e| e,
1074 };
1075 }
1076 fn leaveInlineFuncInner(
1077 debug: *Debug,
1078 func: InternPool.Index,
1079 code_off: usize,
1080 ) link.EmitError!void {
1081 const dwarf = debug.wip_nav.dwarf;
1082 const inlined_func_size = comptime uleb128Size(@backingInt(AbbrevCode.inlined_func));
1083 const block = debug.blocks.pop().?;
1084
1085 const di_nw = &debug.info_writer;
1086 const di_w = &di_nw.interface;
1087 if (debug.any_children)
1088 try di_w.writeUleb128(@backingInt(AbbrevCode.null))
1089 else
1090 std.leb.writeUnsignedFixed(
1091 inlined_func_size,
1092 di_w.buffered()[block.abbrev_code..][0..inlined_func_size],
1093 @intCast(try dwarf.refAbbrevCode(di_nw.mf, .empty_inlined_func)),
1094 );
1095 std.mem.writeInt(
1096 u32,
1097 di_w.buffered()[block.high_pc..][0..4],
1098 @intCast(code_off - block.low_pc_off),
1099 dwarf.endian,
1100 );
1101 try debug.setInlineFunc(func);
1102 debug.any_children = true;
1103 }
1104
1105 pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) link.Error!void {
1106 return debug.setInlineFuncInner(func) catch |err| switch (err) {
1107 error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.line_writer),
1108 else => |e| e,
1109 };
1110 }
1111 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void {
1112 const zcu = debug.pt.zcu;
1113 const ip = &zcu.intern_pool;
1114 const dwarf = debug.wip_nav.dwarf;
1115 if (debug.wip_nav.func == func) return;
1116
1117 const dl_nw = &debug.line_writer;
1118 const dl_w = &dl_nw.interface;
1119 const new_owner_nav = zcu.funcInfo(func).owner_nav;
1120 if (zcu.comp.config.incremental) {
1121 const new_func = try dwarf.getFunc(new_owner_nav);
1122 try dl_w.writeByte(DW.LNS.extended_op);
1123 try dl_w.writeUleb128(1 + dwarf.secOffsetSize());
1124 try dl_w.writeByte(DW.LNE.ZIG_set_decl);
1125 try dwarf.secOffset(dl_nw, new_func.get(dwarf).debug_info_ni.unwrap().?, 0);
1126 return;
1127 }
1128
1129 const old_owner_nav = zcu.funcInfo(debug.wip_nav.func).owner_nav;
1130 const old_inst_info = ip.getNav(old_owner_nav).srcInst(ip).resolveFull(ip).?;
1131 const old_zf = zcu.fileByIndex(old_inst_info.file);
1132 const new_inst_info = ip.getNav(new_owner_nav).srcInst(ip).resolveFull(ip).?;
1133 const new_zf = zcu.fileByIndex(new_inst_info.file);
1134 if (old_inst_info.file != new_inst_info.file) {
1135 const new_ui = dwarf.getUnit(new_zf.mod.?);
1136 _, const new_fi =
1137 try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_inst_info.file);
1138
1139 try dl_w.writeByte(DW.LNS.set_file);
1140 try dl_w.writeUleb128(@backingInt(new_fi));
1141 }
1142
1143 const old_src_line: i33 = old_zf.zir.?.getDeclaration(old_inst_info.inst).src_line;
1144 const new_src_line: i33 = new_zf.zir.?.getDeclaration(new_inst_info.inst).src_line;
1145 if (new_src_line != old_src_line) {
1146 try dl_w.writeByte(DW.LNS.advance_line);
1147 try dl_w.writeSleb128(new_src_line - old_src_line);
1148 }
1149
1150 debug.wip_nav.func = func;
1151 }
1152
1153 fn refFunc(debug: *Debug, func: InternPool.Index) link.EmitError!void {
1154 const dwarf = debug.wip_nav.dwarf;
1155 const fi = try dwarf.getFunc(debug.pt.zcu.funcInfo(func).owner_nav);
1156 try debug.wip_nav.dwarf.secOffset(
1157 &debug.info_writer,
1158 fi.get(dwarf).debug_info_ni.unwrap().?,
1159 0,
1160 );
1161 }
1162 };
1163
1164 pub fn deinit(wip_nav: *WipNav) void {
1165 wip_nav.fde_writer.deinit();
1166 wip_nav.* = undefined;
1167 }
1168
1169 pub fn genDebugFrameHeader(wip_nav: *WipNav) link.Error!void {
1170 wip_nav.genDebugFrameHeaderInner() catch |err| switch (err) {
1171 error.WriteFailed => return wip_nav.dwarf.reportWriteError(&wip_nav.fde_writer),
1172 else => |e| return e,
1173 };
1174 }
1175 fn genDebugFrameHeaderInner(wip_nav: *WipNav) link.EmitError!void {
1176 assert(wip_nav.func != .none);
1177 const dwarf = wip_nav.dwarf;
1178 const df_nw = &wip_nav.fde_writer;
1179 const df_w = &df_nw.interface;
1180 try dwarf.genUnitLength(df_w);
1181 switch (wip_nav.frame_format) {
1182 .eh_frame => {
1183 try df_w.writeInt(u32, undefined, dwarf.endian);
1184 {
1185 const offset = df_w.end;
1186 try df_w.writeInt(u32, 0, dwarf.endian);
1187 if (dwarf.lf.cast(.elf2)) |elf| try elf.addReloc(
1188 @bitCast(df_nw.ni),
1189 offset,
1190 wip_nav.func_si,
1191 0,
1192 .rel32(elf),
1193 ) else unreachable;
1194 }
1195 wip_nav.frame_func_length = .{ .offset = df_w.end, .size = .@"32" };
1196 try df_w.writeInt(u32, undefined, dwarf.endian);
1197 try df_w.writeUleb128(0);
1198 },
1199 .debug_frame => {
1200 try dwarf.secOffset(df_nw, wip_nav.unit.get(dwarf).cie_ni.unwrap().?, 0);
1201 try dwarf.addrSym(df_nw, wip_nav.func_si, 0);
1202 wip_nav.frame_func_length = .{ .offset = df_w.end, .size = dwarf.address_size };
1203 try dwarf.addrPlaceholder(df_w);
1204 },
1205 }
1206 }
1207
1208 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.Error!void {
1209 return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) {
1210 error.WriteFailed => return wip_nav.dwarf.reportWriteError(&wip_nav.fde_writer),
1211 else => |e| return e,
1212 };
1213 }
1214 fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.EmitError!void {
1215 assert(wip_nav.func != .none);
1216 const loc_cfa: Cfa = .{ .advance_loc = loc };
1217 try loc_cfa.write(wip_nav);
1218 try cfa.write(wip_nav);
1219 }
1220
1221 pub fn finishDebugFrameFde(wip_nav: *WipNav, func_length: u64) void {
1222 const dwarf = wip_nav.dwarf;
1223 const df_w = &wip_nav.fde_writer.interface;
1224 switch (wip_nav.frame_func_length.size) {
1225 _ => unreachable,
1226 .@"32" => std.mem.writeInt(
1227 u32,
1228 df_w.buffered()[wip_nav.frame_func_length.offset..][0..4],
1229 @intCast(func_length),
1230 dwarf.endian,
1231 ),
1232 .@"64" => std.mem.writeInt(
1233 u64,
1234 df_w.buffered()[wip_nav.frame_func_length.offset..][0..8],
1235 func_length,
1236 dwarf.endian,
1237 ),
1238 }
1239 @memset(df_w.unusedCapacitySlice(), DW.CFA.nop);
1240 }
1241};
1242
1243pub fn init(lf: *link.File, format: DW.Format) Dwarf {
1244 const target = &lf.comp.root_mod.resolved_target.result;
1245 return .{
1246 .lf = lf,
1247 .format = format,
1248 .address_size = switch (target.ptrBitWidth()) {
1249 0...32 => .@"32",
1250 33...64 => .@"64",
1251 else => unreachable,
1252 },
1253 .endian = target.cpu.arch.endian(),
1254 .const_pool = .empty,
1255
1256 .units = &.{},
1257 .consts = .empty,
1258 .globals = .empty,
1259 .funcs = .empty,
1260 .decls = .empty,
1261 .pending_decl = .{ .di = undefined, .instance_val = .none },
1262
1263 .debug_abbrev = .{
1264 .ni = .none,
1265 .end = 0,
1266 .set = .empty,
1267 },
1268 .frame = .{
1269 .header = if (target.cpu.arch == .x86_64 and target.ofmt == .elf) header: {
1270 dev.checkAny(&.{ .llvm_backend, .x86_64_backend });
1271 const Register = @import("../codegen/x86_64/bits.zig").Register;
1272 break :header comptime .{
1273 .code_alignment_factor = 1,
1274 .data_alignment_factor = -8,
1275 .return_address_register = Register.rip.dwarfNum(),
1276 .initial_instructions = &.{
1277 .{ .def_cfa = .{ .reg = Register.rsp.dwarfNum(), .off = 8 } },
1278 .{ .offset = .{ .reg = Register.rip.dwarfNum(), .off = -8 } },
1279 },
1280 };
1281 } else .{
1282 .code_alignment_factor = undefined,
1283 .data_alignment_factor = undefined,
1284 .return_address_register = undefined,
1285 .initial_instructions = &.{},
1286 },
1287 },
1288 .debug_info = .{},
1289 .debug_line = .{
1290 .header = switch (target.cpu.arch) {
1291 .x86_64, .aarch64 => .{
1292 .minimum_instruction_length = 1,
1293 .maximum_operations_per_instruction = 1,
1294 .default_is_stmt = true,
1295 .line_base = -5,
1296 .line_range = 14,
1297 .opcode_base = DW.LNS.set_isa + 1,
1298 },
1299 else => .{
1300 .minimum_instruction_length = 1,
1301 .maximum_operations_per_instruction = 1,
1302 .default_is_stmt = true,
1303 .line_base = 0,
1304 .line_range = 1,
1305 .opcode_base = DW.LNS.set_isa + 1,
1306 },
1307 },
1308 },
1309 .debug_line_str = .{
1310 .ni = .none,
1311 .offset = 0,
1312 .map = .empty,
1313 },
1314 .debug_rnglists = .{},
1315 .debug_str = .{
1316 .ni = .none,
1317 .offset = 0,
1318 .map = .empty,
1319 },
1320 .debug_str_offsets = .{
1321 .ni = .none,
1322 .offset = 0,
1323 },
1324 };
1325}
1326
1327pub fn deinit(dwarf: *Dwarf) void {
1328 const gpa = dwarf.lf.comp.gpa;
1329 dwarf.const_pool.deinit(gpa);
1330 for (dwarf.units) |*unit| unit.deinit(gpa);
1331 gpa.free(dwarf.units);
1332 dwarf.consts.deinit(gpa);
1333 dwarf.globals.deinit(gpa);
1334 dwarf.funcs.deinit(gpa);
1335 dwarf.decls.deinit(gpa);
1336 dwarf.debug_line_str.map.deinit(gpa);
1337 dwarf.debug_str.map.deinit(gpa);
1338 dwarf.* = undefined;
1339}
1340
1341pub fn initUnits(dwarf: *Dwarf, gpa: std.mem.Allocator, units_len: usize) std.mem.Allocator.Error!void {
1342 assert(dwarf.units.len == 0);
1343 dwarf.units = try gpa.alloc(Unit, units_len);
1344 @memset(dwarf.units, .{
1345 .alive = false,
1346 .dirs = .empty,
1347 .files = .empty,
1348 .frame_ni = .none,
1349 .cie_ni = .none,
1350 .debug_info_ni = .none,
1351 .debug_info_header_ni = .none,
1352 .debug_info_footer_ni = .none,
1353 .debug_line_ni = .none,
1354 .debug_line_header_ni = .none,
1355 .debug_line_header_changed = false,
1356 .debug_rnglists_ni = .none,
1357 .debug_rnglists_offsets_table_offset = undefined,
1358 .debug_rnglists_end = undefined,
1359 });
1360}
1361pub fn updateUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!bool {
1362 var units_changed = false;
1363 for (zcu.module_roots.values(), dwarf.units, 0..) |root, *unit, ui| {
1364 const root_zfi = root.unwrap() orelse continue; // non-zig
1365 const alive = zcu.alive_files.contains(root_zfi);
1366 if (unit.alive == alive) continue; // unchanged
1367 unit.alive = alive;
1368 units_changed = true;
1369 if (!alive) continue; // unreferenced
1370 assert(zcu.fileByIndex(root_zfi).mod != null);
1371 const root_di, const root_fi = try unit.getFile(
1372 zcu.gpa,
1373 @fromBackingInt(@intCast(ui)),
1374 root_zfi,
1375 );
1376 assert(root_di == .root and root_fi == .root);
1377 }
1378 return units_changed;
1379}
1380
1381pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index {
1382 return @fromBackingInt(@intCast(dwarf.lf.comp.zcu.?.module_roots.getIndex(mod).?));
1383}
1384
1385pub fn getConst(dwarf: *Dwarf, pt: Zcu.PerThread, val: Value) link.Error!link.ConstPool.Index {
1386 assert(val.typeOf(pt.zcu).comptimeOnly(pt.zcu));
1387 return dwarf.const_pool.get(pt, dwarf.constPoolUser(), val.toIntern());
1388}
1389
1390pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Index {
1391 const comp = dwarf.lf.comp;
1392 const gpa = comp.gpa;
1393 const global_gop = try dwarf.globals.getOrPut(gpa, nav);
1394 if (!global_gop.found_existing) global_gop.value_ptr.* = .{
1395 .debug_info_ni = .none,
1396 };
1397 const gi: Global.Index = @fromBackingInt(@intCast(global_gop.index));
1398 if (global_gop.value_ptr.debug_info_ni != .none) return gi;
1399 const mod = comp.zcu.?.navFileScope(nav).mod.?;
1400 assert(!mod.strip);
1401 const elf = dwarf.lf.cast(.elf2).?;
1402 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1403 try elf.dwarf_globals.append(gpa, .{
1404 .debug_info_first_target_reloc = .none,
1405 .debug_info_first_node_reloc = .none,
1406 .debug_info_first_symbol_reloc = .none,
1407 });
1408 const unit = dwarf.getUnit(mod).get(dwarf);
1409 global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1410 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1411 .enable_next_moved = true,
1412 }) catch |err| switch (err) {
1413 else => |e| return e,
1414 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1415 elf.mf.io_err.?,
1416 }),
1417 },
1418 .{ .global_debug_info = gi },
1419 ));
1420 return gi;
1421}
1422pub fn getGlobalIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Global.Index {
1423 return @fromBackingInt(@intCast(dwarf.globals.getIndex(nav) orelse return null));
1424}
1425
1426pub fn getFunc(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Func.Index {
1427 const comp = dwarf.lf.comp;
1428 const gpa = comp.gpa;
1429 const func_gop = try dwarf.funcs.getOrPut(gpa, nav);
1430 if (!func_gop.found_existing) func_gop.value_ptr.* = .{
1431 .state = .unresolved,
1432 .fde_ni = .none,
1433 .debug_info_ni = .none,
1434 .debug_line_ni = .none,
1435 };
1436 const fi: Func.Index = @fromBackingInt(@intCast(func_gop.index));
1437 if (func_gop.value_ptr.debug_info_ni != .none) return fi;
1438 const mod = comp.zcu.?.navFileScope(nav).mod.?;
1439 const elf = dwarf.lf.cast(.elf2).?;
1440 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1441 try elf.dwarf_funcs.append(gpa, .{
1442 .frame_fde_first_symbol_reloc = .none,
1443 .frame_fde_first_node_reloc = .none,
1444 .debug_info_first_target_reloc = .none,
1445 .debug_info_first_symbol_reloc = .none,
1446 .debug_info_first_node_reloc = .none,
1447 .debug_line_first_symbol_reloc = .none,
1448 .debug_line_first_node_reloc = .none,
1449 });
1450 if (mod.strip) return fi;
1451 const unit = dwarf.getUnit(mod).get(dwarf);
1452 func_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity(
1453 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1454 .enable_next_moved = true,
1455 }) catch |err| switch (err) {
1456 else => |e| return e,
1457 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1458 elf.mf.io_err.?,
1459 }),
1460 },
1461 .{ .func_debug_info = fi },
1462 ));
1463 return fi;
1464}
1465pub fn getFuncIfExists(dwarf: *Dwarf, nav: InternPool.Nav.Index) ?Func.Index {
1466 return @fromBackingInt(@intCast(dwarf.funcs.getIndex(nav) orelse return null));
1467}
1468
1469fn getDeclInst(dwarf: *Dwarf, val: InternPool.Index) ?InternPool.TrackedInst.Index {
1470 const ip = &dwarf.lf.comp.zcu.?.intern_pool;
1471 switch (ip.indexToKey(val)) {
1472 else => unreachable,
1473 .struct_type, .union_type, .enum_type, .opaque_type => |container, tag| switch (container) {
1474 .declared => |declared| switch (declared.captures.owned.len) {
1475 0 => return null,
1476 else => switch (tag) {
1477 else => unreachable,
1478 .struct_type => {
1479 const loaded_struct = ip.loadStructType(val);
1480 return ip.getNav(loaded_struct.name_nav.unwrap() orelse
1481 return loaded_struct.zir_index).srcInst(ip);
1482 },
1483 .union_type => {
1484 const loaded_union = ip.loadUnionType(val);
1485 return ip.getNav(loaded_union.name_nav.unwrap() orelse
1486 return loaded_union.zir_index).srcInst(ip);
1487 },
1488 .enum_type => {
1489 const loaded_enum = ip.loadEnumType(val);
1490 return ip.getNav(loaded_enum.name_nav.unwrap() orelse
1491 return loaded_enum.zir_index.unwrap().?).srcInst(ip);
1492 },
1493 .opaque_type => {
1494 const loaded_opaque = ip.loadOpaqueType(val);
1495 return ip.getNav(loaded_opaque.name_nav.unwrap() orelse
1496 return loaded_opaque.zir_index).srcInst(ip);
1497 },
1498 },
1499 },
1500 .reified => |reified| {
1501 assert(reified.zir_index.resolve(ip).? != .main_struct_inst);
1502 return reified.zir_index;
1503 },
1504 .generated_union_tag => unreachable,
1505 },
1506 .func => |func| return ip.getNav(switch (func.generic_owner) {
1507 .none => func.owner_nav,
1508 else => |generic_owner| ip.indexToKey(generic_owner).func.owner_nav,
1509 }).srcInst(ip),
1510 }
1511}
1512pub fn getDecl(
1513 dwarf: *Dwarf,
1514 pt: Zcu.PerThread,
1515 instance_val: InternPool.Index,
1516) link.Error!link.MappedFile.Node.Index {
1517 assert(dwarf.pending_decl.instance_val == .none);
1518 const comp = dwarf.lf.comp;
1519 const gpa = comp.gpa;
1520 const zcu = pt.zcu;
1521 const ip = &zcu.intern_pool;
1522 const inst = dwarf.getDeclInst(instance_val) orelse {
1523 const cpi = try dwarf.getConst(pt, .fromInterned(instance_val));
1524 return Const.get(cpi, dwarf).debug_info_ni.unwrap().?;
1525 };
1526 const decl_gop = try dwarf.decls.getOrPut(gpa, inst);
1527 if (!decl_gop.found_existing) decl_gop.value_ptr.* = .{
1528 .debug_info_ni = .none,
1529 };
1530 const di: Decl.Index = @fromBackingInt(@intCast(decl_gop.index));
1531 if (decl_gop.value_ptr.debug_info_ni.unwrap()) |debug_info_ni| return debug_info_ni;
1532 dwarf.pending_decl = .{ .di = di, .instance_val = instance_val };
1533 const elf = dwarf.lf.cast(.elf2).?;
1534 try elf.nodes.ensureUnusedCapacity(gpa, 1);
1535 try elf.dwarf_decls.putNoClobber(gpa, di, .{
1536 .debug_info_first_target_reloc = .none,
1537 .debug_info_first_node_reloc = .none,
1538 });
1539 const unit = dwarf.getUnit(zcu.fileByIndex(di.srcInst(dwarf).resolveFile(ip)).mod.?).get(dwarf);
1540 const debug_info_ni = elf.addNodeAssumeCapacity(
1541 unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{
1542 .enable_next_moved = true,
1543 }) catch |err| switch (err) {
1544 else => |e| return e,
1545 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
1546 elf.mf.io_err.?,
1547 }),
1548 },
1549 .{ .decl_debug_info = di },
1550 );
1551 decl_gop.value_ptr.debug_info_ni = .wrap(debug_info_ni);
1552 return debug_info_ni;
1553}
1554pub fn getDeclIfExists(dwarf: *Dwarf, inst: InternPool.TrackedInst.Index) ?Decl.Index {
1555 return @fromBackingInt(@intCast(dwarf.decls.getIndex(inst) orelse return null));
1556}
1557
1558pub fn unitLengthSize(dwarf: *Dwarf) usize {
1559 return switch (dwarf.format) {
1560 .@"32" => 4,
1561 .@"64" => 4 + 8,
1562 };
1563}
1564pub fn genUnitLength(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
1565 switch (dwarf.format) {
1566 .@"32" => try w.writeInt(u32, undefined, dwarf.endian),
1567 .@"64" => {
1568 try w.writeInt(u32, std.math.maxInt(u32), dwarf.endian);
1569 try w.writeInt(u64, undefined, dwarf.endian);
1570 },
1571 }
1572}
1573pub fn updateUnitLength(dwarf: *Dwarf, header: []u8, unit_length: u64) void {
1574 switch (dwarf.format) {
1575 .@"32" => std.mem.writeInt(u32, header[0..4], @intCast(unit_length - 4), dwarf.endian),
1576 .@"64" => std.mem.writeInt(u64, header[4..12], unit_length - 12, dwarf.endian),
1577 }
1578}
1579
1580pub fn genUnitPadding(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
1581 try dwarf.genUnitLength(w);
1582 try w.writeInt(u16, 0, dwarf.endian);
1583}
1584
1585pub const EhFrameHdr = extern struct {
1586 version: u8,
1587 eh_frame_ptr_enc: std.dwarf.EH.PE,
1588 fde_count_enc: std.dwarf.EH.PE,
1589 table_enc: std.dwarf.EH.PE,
1590 eh_frame_ptr: u32,
1591};
1592pub fn genEhFrameHdr(
1593 dwarf: *Dwarf,
1594 eh_frame_hdr_ai: link.File.AtomId,
1595 eh_frame_hdr: *EhFrameHdr,
1596 eh_frame_si: link.File.SymbolId,
1597) link.Error!void {
1598 eh_frame_hdr.* = .{
1599 .version = 1,
1600 .eh_frame_ptr_enc = .{ .type = .sdata4, .rel = .pcrel },
1601 .fde_count_enc = .omit,
1602 .table_enc = .omit,
1603 .eh_frame_ptr = undefined,
1604 };
1605 if (dwarf.lf.cast(.elf2)) |elf| try elf.addReloc(
1606 eh_frame_hdr_ai,
1607 @offsetOf(EhFrameHdr, "eh_frame_ptr"),
1608 eh_frame_si,
1609 0,
1610 .rel32(elf),
1611 ) else unreachable;
1612}
1613
1614pub fn genDebugFrameCie(
1615 dwarf: *Dwarf,
1616 df_w: *std.Io.Writer,
1617 /// `null` means to generate an architecture-agnostic padding cie
1618 arch: ?std.Target.Cpu.Arch,
1619 format: Frame.Format,
1620) std.Io.Writer.Error!void {
1621 try dwarf.genUnitLength(df_w);
1622 switch (format) {
1623 .eh_frame => try df_w.writeInt(u32, 0, dwarf.endian),
1624 .debug_frame => switch (dwarf.format) {
1625 .@"32" => try df_w.writeInt(u32, std.math.maxInt(u32), dwarf.endian),
1626 .@"64" => try df_w.writeInt(u64, std.math.maxInt(u64), dwarf.endian),
1627 },
1628 }
1629 try df_w.writeByte(if (arch) |_| switch (format) {
1630 .eh_frame => 1,
1631 .debug_frame => 4,
1632 } else 0);
1633 switch (arch orelse return) {
1634 else => unreachable,
1635 .x86_64 => {
1636 dev.checkAny(&.{ .llvm_backend, .x86_64_backend });
1637 const Register = @import("../codegen/x86_64/bits.zig").Register;
1638 switch (format) {
1639 .eh_frame => try df_w.writeAll("zR\x00"),
1640 .debug_frame => {
1641 try df_w.writeAll("\x00");
1642 try df_w.writeByte(@backingInt(dwarf.address_size));
1643 try df_w.writeByte(0);
1644 },
1645 }
1646 try df_w.writeUleb128(dwarf.frame.header.code_alignment_factor);
1647 try df_w.writeSleb128(dwarf.frame.header.data_alignment_factor);
1648 switch (format) {
1649 .eh_frame => try df_w.writeByte(@intCast(dwarf.frame.header.return_address_register)),
1650 .debug_frame => try df_w.writeUleb128(dwarf.frame.header.return_address_register),
1651 }
1652 switch (format) {
1653 .eh_frame => {
1654 try df_w.writeUleb128(1);
1655 try df_w.writeByte(@bitCast(@as(DW.EH.PE, .{ .type = .sdata4, .rel = .pcrel })));
1656 },
1657 .debug_frame => {},
1658 }
1659 try df_w.writeByte(DW.CFA.def_cfa_sf);
1660 try df_w.writeUleb128(Register.rsp.dwarfNum());
1661 try df_w.writeSleb128(-1);
1662 try df_w.writeByte(@as(u8, DW.CFA.offset) + Register.rip.dwarfNum());
1663 try df_w.writeUleb128(1);
1664 },
1665 }
1666 @memset(df_w.unusedCapacitySlice(), DW.CFA.nop);
1667}
1668
1669pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {
1670 const cie_pointer_offset = dwarf.unitLengthSize();
1671 std.mem.writeInt(
1672 u32,
1673 fde[cie_pointer_offset..][0..4],
1674 @intCast(fde_offset + cie_pointer_offset),
1675 dwarf.endian,
1676 );
1677}
1678
1679pub fn genDebugInfoHeader(
1680 dwarf: *Dwarf,
1681 zcu: *Zcu,
1682 mod: *Module,
1683 unit: *Unit,
1684 dih_nw: *link.MappedFile.Node.Writer,
1685) link.EmitError!void {
1686 const comp = zcu.comp;
1687 const dih_w = &dih_nw.interface;
1688 if (!unit.alive) return dwarf.genUnitPadding(dih_w);
1689 try dwarf.genUnitLength(dih_w);
1690 try dih_w.writeInt(u16, 5, dwarf.endian);
1691 try dih_w.writeByte(DW.UT.compile);
1692 try dih_w.writeByte(@backingInt(dwarf.address_size));
1693 try dwarf.secOffset(dih_nw, dwarf.debug_abbrev.ni.unwrap().?, 0);
1694 const compile_unit_offset = dih_w.end;
1695 try dwarf.abbrevCode(dih_nw, .compile_unit);
1696 try dih_w.writeByte(DW.LANG.Zig);
1697 try dwarf.strp(&dwarf.debug_str, dih_nw, "zig " ++ @import("build_options").version);
1698 const root_dir_path = try mod.root.toAbsolute(&comp.dirs, comp.gpa);
1699 defer comp.gpa.free(root_dir_path);
1700 try dwarf.strp(&dwarf.debug_line_str, dih_nw, root_dir_path);
1701 try dwarf.strp(&dwarf.debug_line_str, dih_nw, mod.root_src_path);
1702 try dwarf.secOffset(
1703 dih_nw,
1704 dwarf.getUnit(zcu.root_mod).get(dwarf).debug_info_header_ni.unwrap().?,
1705 compile_unit_offset,
1706 );
1707 try dwarf.secOffset(dih_nw, unit.debug_line_header_ni.unwrap().?, 0);
1708 try dwarf.secOffset(dih_nw, unit.debug_rnglists_ni.unwrap().?, Rnglists.offsetsTableOffset(dwarf));
1709 try dih_w.writeUleb128(0);
1710 const module_offset = dih_w.end;
1711 try dwarf.abbrevCode(dih_nw, .module);
1712 try dwarf.strp(&dwarf.debug_str, dih_nw, mod.fully_qualified_name);
1713 try dih_w.writeUleb128(0);
1714 try dwarf.genModuleDependency(
1715 dih_nw,
1716 "builtin",
1717 zcu.builtin_modules.get(mod.getBuiltinOptions(comp.config).hash()).?,
1718 module_offset,
1719 );
1720 try dwarf.genModuleDependency(dih_nw, "root", zcu.root_mod, module_offset);
1721 try dwarf.genModuleDependency(dih_nw, "std", zcu.std_mod, module_offset);
1722 for (mod.deps.keys(), mod.deps.values()) |name, dep|
1723 try dwarf.genModuleDependency(dih_nw, name, dep, module_offset);
1724 for ([2]AbbrevCode{ .pad_1, .pad_n }) |pad| _ = try dwarf.refAbbrevCode(dih_nw.mf, pad);
1725 try dwarf.genDebugInfoPadding(dih_w, dih_w.unusedCapacityLen());
1726}
1727
1728fn genModuleDependency(
1729 dwarf: *Dwarf,
1730 di_nw: *link.MappedFile.Node.Writer,
1731 name: []const u8,
1732 dep: *Module,
1733 module_offset: usize,
1734) link.EmitError!void {
1735 const dep_unit = dwarf.getUnit(dep).get(dwarf);
1736 if (!dep_unit.alive) return;
1737 try dwarf.abbrevCode(di_nw, .module_dependency);
1738 try dwarf.strp(&dwarf.debug_str, di_nw, name);
1739 try dwarf.secOffset(di_nw, dep_unit.debug_info_header_ni.unwrap().?, module_offset);
1740}
1741
1742pub fn genDebugInfoPadding(dwarf: *Dwarf, di_w: *std.Io.Writer, size: u64) std.Io.Writer.Error!void {
1743 switch (size) {
1744 0 => {},
1745 1 => try di_w.writeUleb128(dwarf.refAbbrevCodeIfExists(.pad_1).?),
1746 else => {
1747 const abbrev_code_offset = di_w.end;
1748 try di_w.writeUleb128(dwarf.refAbbrevCodeIfExists(.pad_n).?);
1749 const abbrev_code_size = di_w.end - abbrev_code_offset;
1750 var block_len_size: u5 = 1;
1751 while (true) switch (std.math.order(
1752 size - abbrev_code_size - block_len_size,
1753 @as(u64, 1) << 7 * block_len_size,
1754 )) {
1755 .lt => break try di_w.writeUleb128(size - abbrev_code_size - block_len_size),
1756 .eq => {
1757 // no length will ever work, so undercount and futz with
1758 // the leb encoding to make up the missing byte
1759 block_len_size += 1;
1760 std.leb.writeUnsignedExtended(
1761 try di_w.writableSlice(block_len_size),
1762 size - abbrev_code_size - block_len_size,
1763 );
1764 break;
1765 },
1766 .gt => block_len_size += 1,
1767 };
1768 },
1769 }
1770}
1771
1772pub fn genDebugLineHeader(
1773 dwarf: *Dwarf,
1774 unit: *Unit,
1775 dlh_nw: *link.MappedFile.Node.Writer,
1776 zcu: *Zcu,
1777) link.EmitError!void {
1778 const comp = zcu.comp;
1779 const dlh_w = &dlh_nw.interface;
1780 try dwarf.genUnitLength(dlh_w);
1781 try dlh_w.writeInt(u16, 5, dwarf.endian);
1782 try dlh_w.writeByte(@backingInt(dwarf.address_size));
1783 try dlh_w.writeByte(0);
1784 const header_length_offset = dlh_w.end;
1785 switch (dwarf.format) {
1786 .@"32" => try dlh_w.writeInt(u32, undefined, dwarf.endian),
1787 .@"64" => try dlh_w.writeInt(u64, undefined, dwarf.endian),
1788 }
1789 const header_start = dlh_w.end;
1790 const StandardOpcode = DeclValEnum(DW.LNS);
1791 try dlh_w.writeAll(&.{
1792 dwarf.debug_line.header.minimum_instruction_length,
1793 dwarf.debug_line.header.maximum_operations_per_instruction,
1794 @intFromBool(dwarf.debug_line.header.default_is_stmt),
1795 @bitCast(dwarf.debug_line.header.line_base),
1796 dwarf.debug_line.header.line_range,
1797 dwarf.debug_line.header.opcode_base,
1798 });
1799 try dlh_w.writeAll(std.enums.EnumArray(StandardOpcode, u8).init(.{
1800 .extended_op = undefined,
1801 .copy = 0,
1802 .advance_pc = 1,
1803 .advance_line = 1,
1804 .set_file = 1,
1805 .set_column = 1,
1806 .negate_stmt = 0,
1807 .set_basic_block = 0,
1808 .const_add_pc = 0,
1809 .fixed_advance_pc = 1,
1810 .set_prologue_end = 0,
1811 .set_epilogue_begin = 0,
1812 .set_isa = 1,
1813 }).values[1..dwarf.debug_line.header.opcode_base]);
1814 try dlh_w.writeByte(1);
1815 try dlh_w.writeUleb128(DW.LNCT.path);
1816 try dlh_w.writeUleb128(DW.FORM.line_strp);
1817 const dir_count = unit.dirs.count();
1818 const directory_index_form: DeclValEnum(DW.FORM) = if (dir_count <= 1 << 8)
1819 .data1
1820 else if (dir_count <= 1 << 16)
1821 .data2
1822 else
1823 .udata;
1824 try dlh_w.writeUleb128(dir_count);
1825 for (unit.dirs.keys()) |ui| {
1826 const root_dir_path = try ui.mod(dwarf).root.toAbsolute(&zcu.comp.dirs, comp.gpa);
1827 defer comp.gpa.free(root_dir_path);
1828 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, root_dir_path);
1829 }
1830 try dlh_w.writeByte(5);
1831 try dlh_w.writeUleb128(DW.LNCT.path);
1832 try dlh_w.writeUleb128(DW.FORM.line_strp);
1833 try dlh_w.writeUleb128(DW.LNCT.directory_index);
1834 try dlh_w.writeUleb128(@backingInt(directory_index_form));
1835 try dlh_w.writeUleb128(DW.LNCT.timestamp);
1836 try dlh_w.writeUleb128(DW.FORM.data8);
1837 try dlh_w.writeUleb128(DW.LNCT.size);
1838 try dlh_w.writeUleb128(DW.FORM.data8);
1839 try dlh_w.writeUleb128(DW.LNCT.LLVM_source);
1840 try dlh_w.writeUleb128(DW.FORM.line_strp);
1841 try dlh_w.writeUleb128(unit.files.count());
1842 for (unit.files.keys()) |zfi| {
1843 const zf = zcu.fileByIndex(zfi);
1844 try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zf.sub_file_path);
1845 const di =
1846 if (zcu.alive_files.contains(zfi)) unit.dirs.getIndex(dwarf.getUnit(zf.mod.?)).? else 0;
1847 switch (directory_index_form) {
1848 else => unreachable,
1849 .data1 => try dlh_w.writeByte(@intCast(di)),
1850 .data2 => try dlh_w.writeInt(u16, @intCast(di), dwarf.endian),
1851 .udata => try dlh_w.writeUleb128(di),
1852 }
1853 try dlh_w.writeInt(i64, @truncate(zf.stat.mtime.nanoseconds), dwarf.endian);
1854 try dlh_w.writeInt(u64, zf.stat.size, dwarf.endian);
1855 try dwarf.strp(
1856 &dwarf.debug_line_str,
1857 dlh_nw,
1858 if (zf.is_builtin) zf.source.? else "",
1859 );
1860 }
1861 switch (dwarf.format) {
1862 .@"32" => std.mem.writeInt(
1863 u32,
1864 dlh_w.buffer[header_length_offset..][0..4],
1865 @intCast(dlh_w.end - header_start),
1866 dwarf.endian,
1867 ),
1868 .@"64" => std.mem.writeInt(
1869 u64,
1870 dlh_w.buffer[header_length_offset..][0..8],
1871 dlh_w.end - header_start,
1872 dwarf.endian,
1873 ),
1874 }
1875 try genDebugLinePadding(dlh_w, dlh_w.unusedCapacityLen());
1876}
1877
1878pub fn genDebugLinePadding(dl_w: *std.Io.Writer, size: u64) std.Io.Writer.Error!void {
1879 switch (size) {
1880 0 => {},
1881 1 => try dl_w.writeByte(DW.LNS.const_add_pc),
1882 2 => try dl_w.writeAll(&.{ DW.LNS.negate_stmt, DW.LNS.negate_stmt }),
1883 else => {
1884 const extended_op_offset = dl_w.end;
1885 try dl_w.writeByte(DW.LNS.extended_op);
1886 const extended_op_size = dl_w.end - extended_op_offset;
1887 var op_len_size: u5 = 1;
1888 while (true) switch (std.math.order(
1889 size - extended_op_size - op_len_size,
1890 @as(u64, 1) << 7 * op_len_size,
1891 )) {
1892 .lt => break try dl_w.writeUleb128(size - extended_op_size - op_len_size),
1893 .eq => {
1894 // no length will ever work, so undercount and futz with
1895 // the leb encoding to make up the missing byte
1896 op_len_size += 1;
1897 std.leb.writeUnsignedExtended(
1898 try dl_w.writableSlice(op_len_size),
1899 size - extended_op_size - op_len_size,
1900 );
1901 break;
1902 },
1903 .gt => op_len_size += 1,
1904 };
1905 try dl_w.writeByte(DW.LNE.padding);
1906 },
1907 }
1908}
1909
1910pub fn genDebugRnglistsHeader(
1911 dwarf: *Dwarf,
1912 unit: *Unit,
1913 drh_nw: *link.MappedFile.Node.Writer,
1914) std.Io.Writer.Error!void {
1915 const drh_w = &drh_nw.interface;
1916 try dwarf.genUnitLength(drh_w);
1917 try drh_w.writeInt(u16, 5, dwarf.endian);
1918 try drh_w.writeByte(@backingInt(dwarf.address_size));
1919 try drh_w.writeByte(0);
1920 try drh_w.writeInt(u32, 1, dwarf.endian);
1921 assert(drh_w.end == Rnglists.offsetsTableOffset(dwarf));
1922 switch (dwarf.format) {
1923 .@"32" => try drh_w.writeInt(u32, 4, dwarf.endian),
1924 .@"64" => try drh_w.writeInt(u64, 8, dwarf.endian),
1925 }
1926 unit.debug_rnglists_end = drh_w.end;
1927 try drh_w.writeByte(DW.RLE.end_of_list);
1928}
1929
1930pub fn genDebugRnglists(
1931 dwarf: *Dwarf,
1932 unit: *Unit,
1933 dr_nw: *link.MappedFile.Node.Writer,
1934 func_si: link.File.SymbolId,
1935 func_length: u64,
1936) link.EmitError!void {
1937 const dr_w = &dr_nw.interface;
1938 dr_w.end = unit.debug_rnglists_end;
1939 try dr_w.writeByte(DW.RLE.start_length);
1940 try dwarf.addrSym(dr_nw, func_si, 0);
1941 try dr_w.writeUleb128(func_length);
1942 unit.debug_rnglists_end = dr_w.end;
1943 try dr_w.writeByte(DW.RLE.end_of_list);
1944}
1945
1946pub fn updateComptimeNav(
1947 dwarf: *Dwarf,
1948 pt: Zcu.PerThread,
1949 nav_index: InternPool.Nav.Index,
1950) link.Error!void {
1951 const zcu = pt.zcu;
1952 const ip = &zcu.intern_pool;
1953 const nav = ip.getNav(nav_index);
1954 log.debug("updateComptimeNav({f})", .{nav.fqn.fmt(ip)});
1955 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
1956 const nav_val: Value = .fromInterned(nav.resolved.?.value);
1957 const zf = zcu.fileByIndex(inst_info.file);
1958 const decl = zf.zir.?.getDeclaration(inst_info.inst);
1959 switch (decl.kind) {
1960 .unnamed_test, .@"test", .decltest => return,
1961 .@"comptime", .@"const", .@"var" => {},
1962 }
1963 done: switch (ip.indexToKey(nav_val.toIntern())) {
1964 .struct_type => {
1965 const loaded_struct = ip.loadStructType(nav_val.toIntern());
1966 if (nav_index.toOptional() == loaded_struct.name_nav) {
1967 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
1968 break :done;
1969 }
1970 return;
1971 },
1972 .enum_type => {
1973 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
1974 if (nav_index.toOptional() == loaded_enum.name_nav) {
1975 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
1976 break :done;
1977 }
1978 return;
1979 },
1980 .union_type => {
1981 const loaded_union = ip.loadUnionType(nav_val.toIntern());
1982 if (nav_index.toOptional() == loaded_union.name_nav) {
1983 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
1984 break :done;
1985 }
1986 return;
1987 },
1988 .opaque_type => {
1989 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
1990 if (nav_index.toOptional() == loaded_opaque.name_nav) {
1991 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
1992 break :done;
1993 }
1994 return;
1995 },
1996 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {
1997 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
1998 break :done;
1999 } else return,
2000
2001 else => return,
2002
2003 // memoization, not values
2004 .memoized_call => unreachable,
2005 }
2006 try dwarf.const_pool.flushPending(pt, dwarf.constPoolUser());
2007}
2008
2009pub fn addConst(
2010 dwarf: *Dwarf,
2011 cpi: link.ConstPool.Index,
2012 val: InternPool.Index,
2013 addConstNode: *const fn (
2014 lf: *link.File,
2015 ui: Unit.Index,
2016 cpi: link.ConstPool.Index,
2017 ) link.Error!link.MappedFile.Node.Index,
2018) link.Error!void {
2019 const zcu = dwarf.lf.comp.zcu.?;
2020 const ip = &zcu.intern_pool;
2021 assert(@backingInt(cpi) == dwarf.consts.items.len);
2022 dwarf.consts.appendAssumeCapacity(.{
2023 .debug_info_ni = debug_info_ni: switch (ip.indexToKey(val)) {
2024 else => try addConstNode(dwarf.lf, dwarf.getUnit(zcu.root_mod), cpi),
2025 .func => |func| {
2026 const fi = try dwarf.getFunc(func.owner_nav);
2027 break :debug_info_ni fi.get(dwarf).debug_info_ni.unwrap().?;
2028 },
2029 .@"extern" => |@"extern"| {
2030 const gi = try dwarf.getGlobal(@"extern".owner_nav);
2031 break :debug_info_ni gi.get(dwarf).debug_info_ni.unwrap().?;
2032 },
2033 .struct_type, .union_type, .enum_type, .opaque_type => |_, tag| {
2034 if (switch (tag) {
2035 else => unreachable,
2036 .struct_type => ip.loadStructType(val).name_nav,
2037 .union_type => ip.loadUnionType(val).name_nav,
2038 .enum_type => ip.loadEnumType(val).name_nav,
2039 .opaque_type => ip.loadOpaqueType(val).name_nav,
2040 }.unwrap()) |name_nav| {
2041 const name_gi = try dwarf.getGlobal(name_nav);
2042 break :debug_info_ni name_gi.get(dwarf).debug_info_ni.unwrap().?;
2043 }
2044 break :debug_info_ni try addConstNode(dwarf.lf, dwarf.getUnit(zcu.fileByIndex(
2045 Type.fromInterned(val).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip),
2046 ).mod.?), cpi);
2047 },
2048 }.toOptional(),
2049 });
2050}
2051
2052pub fn updateConst(
2053 dwarf: *Dwarf,
2054 pt: Zcu.PerThread,
2055 di_nw: *link.MappedFile.Node.Writer,
2056 val: InternPool.Index,
2057) link.Error!void {
2058 switch (val) {
2059 .generic_poison_type => log.debug("updateConst(anytype)", .{}),
2060 else => log.debug("updateConst({f})", .{Value.fromInterned(val).fmtValue(pt)}),
2061 }
2062 dwarf.updateConstInner(pt, di_nw, val) catch |err| switch (err) {
2063 else => |e| return e,
2064 error.WriteFailed => return dwarf.reportWriteError(di_nw),
2065 };
2066}
2067fn updateConstInner(
2068 dwarf: *Dwarf,
2069 pt: Zcu.PerThread,
2070 di_nw: *link.MappedFile.Node.Writer,
2071 val: InternPool.Index,
2072) link.EmitError!void {
2073 const zcu = pt.zcu;
2074 const ip = &zcu.intern_pool;
2075 const di_w = &di_nw.interface;
2076 switch (ip.indexToKey(val)) {
2077 .int_type => |int_type| {
2078 const ty: Type = .fromInterned(val);
2079 try dwarf.abbrevCode(di_nw, .numeric_type);
2080 var name_buf: [std.fmt.count("i{d}", .{std.math.maxInt(u16)})]u8 = undefined;
2081 try dwarf.strp(&dwarf.debug_str, di_nw, std.mem.print(&name_buf, "{f}", .{
2082 ty.fmt(pt),
2083 }) catch unreachable);
2084 try di_w.writeByte(switch (int_type.signedness) {
2085 .signed => DW.ATE.signed,
2086 .unsigned => DW.ATE.unsigned,
2087 });
2088 try di_w.writeUleb128(int_type.bits);
2089 try di_w.writeUleb128(ty.abiSize(zcu));
2090 try di_w.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
2091 },
2092 .ptr_type => |ptr_type| switch (ptr_type.flags.size) {
2093 .one, .many, .c => {
2094 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2095 defer zcu.gpa.free(name);
2096 try dwarf.abbrevCode(di_nw, switch (ptr_type.sentinel) {
2097 .none => switch (ptr_type.flags.alignment) {
2098 .none => .ptr_type,
2099 else => .ptr_aligned_type,
2100 },
2101 else => switch (ptr_type.flags.alignment) {
2102 .none => .ptr_sentinel_type,
2103 else => .ptr_aligned_sentinel_type,
2104 },
2105 });
2106 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2107 switch (ptr_type.sentinel) {
2108 .none => {},
2109 else => |sentinel| try dwarf.blockConst(pt, di_nw, .fromInterned(sentinel)),
2110 }
2111 if (ptr_type.flags.alignment.toByteUnits()) |a| try di_w.writeUleb128(a);
2112 try di_w.writeByte(@backingInt(ptr_type.flags.address_space));
2113 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try dwarf.secOffset(
2114 di_nw,
2115 di_nw.ni,
2116 di_w.end + dwarf.secOffsetSize(),
2117 );
2118 if (ptr_type.flags.is_const) {
2119 try dwarf.abbrevCode(di_nw, .is_const);
2120 if (ptr_type.flags.is_volatile) try dwarf.secOffset(
2121 di_nw,
2122 di_nw.ni,
2123 di_w.end + dwarf.secOffsetSize(),
2124 );
2125 }
2126 if (ptr_type.flags.is_volatile) try dwarf.abbrevCode(di_nw, .is_volatile);
2127 try dwarf.refType(pt, di_nw, .fromInterned(ptr_type.child));
2128 },
2129 .slice => {
2130 const ty: Type = .fromInterned(val);
2131 const name = try zcu.gpa.print("{f}", .{ty.fmt(pt)});
2132 defer zcu.gpa.free(name);
2133 try dwarf.abbrevCode(di_nw, .generated_struct_type);
2134 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2135 try di_w.writeUleb128(ty.abiSize(zcu));
2136 try di_w.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
2137 try dwarf.abbrevCode(di_nw, .generated_field);
2138 try dwarf.strp(&dwarf.debug_str, di_nw, "ptr");
2139 const ptr_field_ty = ty.slicePtrFieldType(zcu);
2140 try dwarf.refType(pt, di_nw, ptr_field_ty);
2141 try di_w.writeUleb128(0);
2142 try dwarf.abbrevCode(di_nw, .generated_field);
2143 try dwarf.strp(&dwarf.debug_str, di_nw, "len");
2144 const len_field_ty: Type = .usize;
2145 try dwarf.refType(pt, di_nw, len_field_ty);
2146 try di_w.writeUleb128(len_field_ty.abiAlignment(zcu).forward(ptr_field_ty.abiSize(zcu)));
2147 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2148 },
2149 },
2150 .array_type => |array_type| {
2151 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2152 defer zcu.gpa.free(name);
2153 try dwarf.abbrevCode(
2154 di_nw,
2155 if (array_type.sentinel == .none) .array_type else .array_sentinel_type,
2156 );
2157 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2158 if (array_type.sentinel != .none)
2159 try dwarf.blockConst(pt, di_nw, .fromInterned(array_type.sentinel));
2160 try dwarf.refType(pt, di_nw, .fromInterned(array_type.child));
2161 try dwarf.abbrevCode(di_nw, .array_len);
2162 try dwarf.refType(pt, di_nw, .usize);
2163 try di_w.writeUleb128(array_type.len);
2164 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2165 },
2166 .vector_type => |vector_type| {
2167 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2168 defer zcu.gpa.free(name);
2169 try dwarf.abbrevCode(di_nw, .vector_type);
2170 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2171 try dwarf.refType(pt, di_nw, .fromInterned(vector_type.child));
2172 try dwarf.abbrevCode(di_nw, .array_len);
2173 try dwarf.refType(pt, di_nw, .usize);
2174 try di_w.writeUleb128(vector_type.len);
2175 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2176 },
2177 .opt_type => |opt_child_type_index| {
2178 const opt_ty: Type = .fromInterned(val);
2179 const opt_child_ty: Type = .fromInterned(opt_child_type_index);
2180 const opt_repr = optRepr(opt_child_ty, zcu);
2181 const name = try zcu.gpa.print("{f}", .{opt_ty.fmt(pt)});
2182 defer zcu.gpa.free(name);
2183 try dwarf.abbrevCode(di_nw, .generated_union_type);
2184 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2185 try di_w.writeUleb128(opt_ty.abiSize(zcu));
2186 try di_w.writeUleb128(opt_ty.abiAlignment(zcu).toByteUnits().?);
2187 switch (opt_repr) {
2188 .opv_null => {
2189 try dwarf.abbrevCode(di_nw, .generated_field);
2190 try dwarf.strp(&dwarf.debug_str, di_nw, "null");
2191 try dwarf.refType(pt, di_nw, .null);
2192 try di_w.writeUleb128(0);
2193 },
2194 .unpacked, .error_set, .pointer => {
2195 try dwarf.abbrevCode(di_nw, .tagged_union);
2196 try dwarf.secOffset(di_nw, di_nw.ni, di_w.end + dwarf.secOffsetSize());
2197 {
2198 try dwarf.abbrevCode(di_nw, .generated_field);
2199 try dwarf.strp(&dwarf.debug_str, di_nw, "has_value");
2200 switch (opt_repr) {
2201 .opv_null => unreachable,
2202 .unpacked => {
2203 try dwarf.refType(pt, di_nw, .bool);
2204 try di_w.writeUleb128(if (opt_child_ty.hasRuntimeBits(zcu))
2205 opt_child_ty.abiSize(zcu)
2206 else
2207 0);
2208 },
2209 .error_set => {
2210 try dwarf.refType(pt, di_nw, try pt.intType(.unsigned, zcu.errorSetBits()));
2211 try di_w.writeUleb128(0);
2212 },
2213 .pointer => {
2214 try dwarf.refType(pt, di_nw, .usize);
2215 try di_w.writeUleb128(0);
2216 },
2217 }
2218
2219 try dwarf.abbrevCode(di_nw, .tagged_union_field);
2220 try di_w.writeUleb128(DW.FORM.data1);
2221 try di_w.writeByte(0);
2222 {
2223 try dwarf.abbrevCode(di_nw, .generated_field);
2224 try dwarf.strp(&dwarf.debug_str, di_nw, "null");
2225 try dwarf.refType(pt, di_nw, .null);
2226 try di_w.writeUleb128(0);
2227 }
2228 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2229
2230 try dwarf.abbrevCode(di_nw, .tagged_union_default_field);
2231 {
2232 try dwarf.abbrevCode(di_nw, .generated_field);
2233 try dwarf.strp(&dwarf.debug_str, di_nw, "?");
2234 try dwarf.refType(pt, di_nw, opt_child_ty);
2235 try di_w.writeUleb128(0);
2236 }
2237 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2238 }
2239 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2240 },
2241 }
2242 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2243 },
2244 .anyframe_type => unreachable,
2245 .error_union_type => |error_union_type| {
2246 const eu_ty: Type = .fromInterned(val);
2247 const eu_error_set_ty: Type = .fromInterned(error_union_type.error_set_type);
2248 const eu_payload_ty: Type = .fromInterned(error_union_type.payload_type);
2249 const eu_error_set_offset, const eu_payload_offset = switch (error_union_type.payload_type) {
2250 .generic_poison_type => .{ 0, 0 },
2251 else => .{
2252 codegen.errUnionErrorOffset(eu_payload_ty, zcu),
2253 codegen.errUnionPayloadOffset(eu_payload_ty, zcu),
2254 },
2255 };
2256 const name = try zcu.gpa.print("{f}", .{eu_ty.fmt(pt)});
2257 defer zcu.gpa.free(name);
2258
2259 try dwarf.abbrevCode(di_nw, .generated_union_type);
2260 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2261 if (error_union_type.error_set_type != .generic_poison_type and
2262 error_union_type.payload_type != .generic_poison_type)
2263 {
2264 try di_w.writeUleb128(eu_ty.abiSize(zcu));
2265 try di_w.writeUleb128(eu_ty.abiAlignment(zcu).toByteUnits().?);
2266 } else {
2267 try di_w.writeUleb128(0);
2268 try di_w.writeUleb128(1);
2269 }
2270 {
2271 try dwarf.abbrevCode(di_nw, .tagged_union);
2272 try dwarf.secOffset(di_nw, di_nw.ni, di_w.end + dwarf.secOffsetSize());
2273 {
2274 try dwarf.abbrevCode(di_nw, .generated_field);
2275 try dwarf.strp(&dwarf.debug_str, di_nw, "is_error");
2276 try dwarf.refType(pt, di_nw, try pt.intType(.unsigned, zcu.errorSetBits()));
2277 try di_w.writeUleb128(eu_error_set_offset);
2278
2279 try dwarf.abbrevCode(di_nw, .tagged_union_field);
2280 try di_w.writeUleb128(DW.FORM.udata);
2281 try di_w.writeUleb128(0);
2282 {
2283 try dwarf.abbrevCode(di_nw, .generated_field);
2284 try dwarf.strp(&dwarf.debug_str, di_nw, "value");
2285 try dwarf.refType(pt, di_nw, eu_payload_ty);
2286 try di_w.writeUleb128(eu_payload_offset);
2287 }
2288 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2289
2290 try dwarf.abbrevCode(di_nw, .tagged_union_default_field);
2291 {
2292 try dwarf.abbrevCode(di_nw, .generated_field);
2293 try dwarf.strp(&dwarf.debug_str, di_nw, "error");
2294 try dwarf.refType(pt, di_nw, eu_error_set_ty);
2295 try di_w.writeUleb128(eu_error_set_offset);
2296 }
2297 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2298 }
2299 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2300 }
2301 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2302 },
2303 .simple_type => |simple_type| switch (simple_type) {
2304 .f16,
2305 .f32,
2306 .f64,
2307 .f80,
2308 .f128,
2309 .usize,
2310 .isize,
2311 .c_char,
2312 .c_short,
2313 .c_ushort,
2314 .c_int,
2315 .c_uint,
2316 .c_long,
2317 .c_ulong,
2318 .c_longlong,
2319 .c_ulonglong,
2320 .c_longdouble,
2321 .bool,
2322 => {
2323 const ty: Type = .fromInterned(val);
2324 try dwarf.abbrevCode(di_nw, .numeric_type);
2325 try dwarf.strp(&dwarf.debug_str, di_nw, @tagName(simple_type));
2326 try di_w.writeByte(if (val == .bool_type)
2327 DW.ATE.boolean
2328 else if (ty.isRuntimeFloat())
2329 DW.ATE.float
2330 else if (ty.isSignedInt(zcu))
2331 DW.ATE.signed
2332 else if (ty.isUnsignedInt(zcu))
2333 DW.ATE.unsigned
2334 else
2335 unreachable);
2336 try di_w.writeUleb128(ty.bitSize(zcu));
2337 try di_w.writeUleb128(ty.abiSize(zcu));
2338 try di_w.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
2339 },
2340 .generic_poison => {
2341 try dwarf.abbrevCode(di_nw, .void_type);
2342 try dwarf.strp(&dwarf.debug_str, di_nw, "anytype");
2343 },
2344 .anyopaque,
2345 .void,
2346 .type,
2347 .comptime_int,
2348 .comptime_float,
2349 .noreturn,
2350 .null,
2351 .undefined,
2352 .enum_literal,
2353 => {
2354 const ty: Type = .fromInterned(val);
2355 try dwarf.abbrevCode(di_nw, .void_type);
2356 var name_buf: ["@TypeOf(undefined)".len]u8 = undefined;
2357 try dwarf.strp(&dwarf.debug_str, di_nw, std.mem.print(&name_buf, "{f}", .{
2358 ty.fmt(pt),
2359 }) catch unreachable);
2360 },
2361 .anyerror => {
2362 const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
2363 try dwarf.abbrevCode(di_nw, if (global_error_set_names.len > 0)
2364 .generated_enum_type
2365 else
2366 .generated_empty_enum_type);
2367 try dwarf.strp(&dwarf.debug_str, di_nw, "anyerror");
2368 try dwarf.refType(pt, di_nw, try pt.intType(.unsigned, zcu.errorSetBits()));
2369 for (global_error_set_names, 1..) |name, value| {
2370 try dwarf.abbrevCode(di_nw, .enum_field);
2371 try di_w.writeUleb128(DW.FORM.udata);
2372 try di_w.writeUleb128(value);
2373 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
2374 }
2375 if (global_error_set_names.len > 0) try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2376 },
2377 .adhoc_inferred_error_set => unreachable,
2378 },
2379 .tuple_type => |tuple_type| {
2380 const ty: Type = .fromInterned(val);
2381 const name = try zcu.gpa.print("{f}", .{ty.fmt(pt)});
2382 defer zcu.gpa.free(name);
2383 if (tuple_type.types.len == 0) {
2384 try dwarf.abbrevCode(di_nw, .generated_empty_struct_type);
2385 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2386 try di_w.writeByte(@intFromBool(false));
2387 } else {
2388 try dwarf.abbrevCode(di_nw, .generated_struct_type);
2389 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2390 try di_w.writeUleb128(ty.abiSize(zcu));
2391 try di_w.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
2392 var field_byte_offset: u64 = 0;
2393 for (0..tuple_type.types.len) |field_index| {
2394 const comptime_value = tuple_type.values.get(ip)[field_index];
2395 const field_ty: Type = .fromInterned(tuple_type.types.get(ip)[field_index]);
2396 const comptime_value_class = switch (comptime_value) {
2397 .none => .no_possible_value,
2398 else => field_ty.classify(zcu),
2399 };
2400 try dwarf.abbrevCode(di_nw, switch (comptime_value) {
2401 .none => .field,
2402 else => switch (comptime_value_class) {
2403 .no_possible_value, .one_possible_value => .field_comptime,
2404 .runtime => .field_comptime_fully_runtime,
2405 .partially_comptime => .field_comptime_partially_comptime,
2406 .fully_comptime => .field_comptime_fully_comptime,
2407 },
2408 });
2409 var field_name_buf: [std.fmt.count("{d}", .{std.math.maxInt(u32)})]u8 = undefined;
2410 try dwarf.strp(&dwarf.debug_str, di_nw, std.mem.print(&field_name_buf, "{d}", .{
2411 field_index,
2412 }) catch unreachable);
2413 try dwarf.refType(pt, di_nw, field_ty);
2414 if (comptime_value == .none) {
2415 const field_align = field_ty.abiAlignment(zcu);
2416 field_byte_offset = field_align.forward(field_byte_offset);
2417 try di_w.writeUleb128(field_byte_offset);
2418 try di_w.writeUleb128(field_ty.abiAlignment(zcu).toByteUnits().?);
2419 field_byte_offset += field_ty.abiSize(zcu);
2420 }
2421 if (comptime_value_class.hasRuntimeBits())
2422 try dwarf.blockConst(pt, di_nw, .fromInterned(comptime_value));
2423 if (comptime_value_class.comptimeOnly())
2424 try dwarf.refConst(pt, di_nw, .fromInterned(comptime_value));
2425 }
2426 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2427 }
2428 },
2429 .struct_type => {
2430 const loaded_struct = ip.loadStructType(val);
2431 const zfi = loaded_struct.zir_index.resolveFile(ip);
2432 const zf = zcu.fileByIndex(zfi);
2433 const src_inst = loaded_struct.zir_index.resolve(ip);
2434 if (src_inst == .main_struct_inst) {
2435 assert(loaded_struct.captures.len == 0);
2436 const ui = dwarf.getUnit(zf.mod.?);
2437 _, const fi = try ui.get(dwarf).getFile(zcu.gpa, ui, zfi);
2438 try dwarf.abbrevCode(di_nw, switch (loaded_struct.layout) {
2439 .auto => if (loaded_struct.field_types.len > 0) .file else .empty_file,
2440 .@"extern", .@"packed" => unreachable,
2441 });
2442 try di_w.writeUleb128(@backingInt(fi));
2443 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));
2444 } else if (loaded_struct.captures.len > 0 or loaded_struct.is_reified) {
2445 try dwarf.abbrevCode(di_nw, if (loaded_struct.captures.len > 0 or
2446 loaded_struct.field_types.len > 0) switch (loaded_struct.layout) {
2447 .auto, .@"extern" => .decl_instance_struct,
2448 .@"packed" => .decl_instance_packed_struct,
2449 } else switch (loaded_struct.layout) {
2450 .auto, .@"extern" => .decl_instance_empty_struct,
2451 .@"packed" => .decl_instance_empty_packed_struct,
2452 });
2453 try dwarf.secOffset(di_nw, try dwarf.getDecl(pt, val), 0);
2454 } else if (loaded_struct.name_nav.unwrap()) |name_ni| {
2455 const name_nav = ip.getNav(name_ni);
2456 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
2457 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2458 name_nav.analysis.?.namespace,
2459 ).owner_type);
2460 try dwarf.abbrevCode(di_nw, if (loaded_struct.field_types.len > 0)
2461 switch (loaded_struct.layout) {
2462 .auto, .@"extern" => .decl_struct,
2463 .@"packed" => .decl_packed_struct,
2464 }
2465 else switch (loaded_struct.layout) {
2466 .auto, .@"extern" => .decl_empty_struct,
2467 .@"packed" => .decl_empty_packed_struct,
2468 });
2469 try dwarf.secOffset(di_nw, parent_ni, 0);
2470 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2471 try di_w.writeUleb128(decl.src_column + 1);
2472 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2473 try dwarf.strp(&dwarf.debug_str, di_nw, name_nav.name.toSlice(ip));
2474 } else {
2475 const decl = zf.zir.?.getStructDecl(src_inst.?);
2476 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2477 ip.namespacePtr(loaded_struct.namespace).parent.unwrap().?,
2478 ).owner_type);
2479 try dwarf.abbrevCode(di_nw, if (loaded_struct.field_types.len > 0)
2480 switch (loaded_struct.layout) {
2481 .auto, .@"extern" => .type_decl_struct,
2482 .@"packed" => .type_decl_packed_struct,
2483 }
2484 else switch (loaded_struct.layout) {
2485 .auto, .@"extern" => .type_decl_empty_struct,
2486 .@"packed" => .type_decl_empty_packed_struct,
2487 });
2488 try dwarf.secOffset(di_nw, parent_ni, 0);
2489 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2490 try di_w.writeUleb128(decl.src_column + 1);
2491 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));
2492 }
2493 switch (loaded_struct.layout) {
2494 .auto, .@"extern" => {
2495 const ty: Type = .fromInterned(val);
2496 try di_w.writeUleb128(ty.abiSize(zcu));
2497 try di_w.writeUleb128(ty.abiAlignment(zcu).toByteUnits().?);
2498 try dwarf.genCaptures(pt, di_nw, loaded_struct.captures);
2499 for (0..loaded_struct.field_types.len) |field_index| {
2500 const is_comptime = loaded_struct.field_is_comptime_bits.get(ip, field_index);
2501 // TODO: we currently don't emit information about default values for
2502 // non-`comptime` fields, because these default values are resolved at a
2503 // separate time in the compiler frontend. To emit this information, the
2504 // frontend needs to tell us when the default values are available: like
2505 // how `Zcu.PerThread.ensureTypeLayoutUpToDate` enqueues a link task to
2506 // indicate completion of the type's layout, a task should be enqueued
2507 // by `Zcu.PerThread.ensureStructDefaultsUpToDate`, and upon receiving
2508 // it we should patch the correct default field values in.
2509 const field_default = if (is_comptime)
2510 loaded_struct.field_defaults.getOrNone(ip, field_index)
2511 else
2512 .none;
2513 assert(!(is_comptime and field_default == .none));
2514 const field_ty: Type =
2515 .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2516 const field_default_class = switch (field_default) {
2517 .none => .no_possible_value,
2518 else => field_ty.classify(zcu),
2519 };
2520 try dwarf.abbrevCode(di_nw, if (is_comptime) switch (field_default_class) {
2521 .no_possible_value, .one_possible_value => .field_comptime,
2522 .runtime => .field_comptime_fully_runtime,
2523 .partially_comptime => .field_comptime_partially_comptime,
2524 .fully_comptime => .field_comptime_fully_comptime,
2525 } else switch (field_default_class) {
2526 .no_possible_value, .one_possible_value => .field,
2527 .runtime => .field_default_fully_runtime,
2528 .partially_comptime => .field_default_partially_comptime,
2529 .fully_comptime => .field_default_fully_comptime,
2530 });
2531 try dwarf.strp(
2532 &dwarf.debug_str,
2533 di_nw,
2534 loaded_struct.field_names.get(ip)[field_index].toSlice(ip),
2535 );
2536 try dwarf.refType(pt, di_nw, field_ty);
2537 if (!is_comptime) {
2538 try di_w.writeUleb128(loaded_struct.field_offsets.get(ip)[field_index]);
2539 try di_w.writeUleb128(loaded_struct.field_aligns.getOrNone(
2540 ip,
2541 field_index,
2542 ).toByteUnits() orelse field_ty.abiAlignment(zcu).toByteUnits().?);
2543 }
2544 if (field_default_class.hasRuntimeBits())
2545 try dwarf.blockConst(pt, di_nw, .fromInterned(field_default));
2546 if (field_default_class.comptimeOnly())
2547 try dwarf.refConst(pt, di_nw, .fromInterned(field_default));
2548 }
2549 },
2550 .@"packed" => {
2551 try dwarf.refType(pt, di_nw, .fromInterned(loaded_struct.packed_backing_int_type));
2552 try dwarf.genCaptures(pt, di_nw, loaded_struct.captures);
2553 var field_bit_offset: u16 = 0;
2554 for (0..loaded_struct.field_types.len) |field_index| {
2555 try dwarf.abbrevCode(di_nw, .packed_field);
2556 try dwarf.strp(
2557 &dwarf.debug_str,
2558 di_nw,
2559 loaded_struct.field_names.get(ip)[field_index].toSlice(ip),
2560 );
2561 const field_ty: Type =
2562 .fromInterned(loaded_struct.field_types.get(ip)[field_index]);
2563 try dwarf.refType(pt, di_nw, field_ty);
2564 try di_w.writeUleb128(field_bit_offset);
2565 field_bit_offset += @intCast(field_ty.bitSize(zcu));
2566 }
2567 },
2568 }
2569 if (loaded_struct.captures.len > 0 or loaded_struct.field_types.len > 0)
2570 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2571 },
2572 .union_type => {
2573 const loaded_union = ip.loadUnionType(val);
2574 const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type);
2575 const zfi = loaded_union.zir_index.resolveFile(ip);
2576 const zf = zcu.fileByIndex(zfi);
2577 if (loaded_union.captures.len > 0 or loaded_union.is_reified) {
2578 try dwarf.abbrevCode(di_nw, if (loaded_union.captures.len > 0 or
2579 loaded_union.field_types.len > 0) switch (loaded_union.layout) {
2580 .auto, .@"extern" => .decl_instance_union,
2581 .@"packed" => .decl_instance_packed_union,
2582 } else switch (loaded_union.layout) {
2583 .auto, .@"extern" => .decl_instance_empty_union,
2584 .@"packed" => .decl_instance_empty_packed_union,
2585 });
2586 try dwarf.secOffset(di_nw, try dwarf.getDecl(pt, val), 0);
2587 } else if (loaded_union.name_nav.unwrap()) |name_ni| {
2588 const name_nav = ip.getNav(name_ni);
2589 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
2590 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2591 name_nav.analysis.?.namespace,
2592 ).owner_type);
2593 try dwarf.abbrevCode(di_nw, if (loaded_union.field_types.len > 0)
2594 switch (loaded_union.layout) {
2595 .auto, .@"extern" => .decl_union,
2596 .@"packed" => .decl_packed_union,
2597 }
2598 else switch (loaded_union.layout) {
2599 .auto, .@"extern" => .decl_empty_union,
2600 .@"packed" => .decl_empty_packed_union,
2601 });
2602 try dwarf.secOffset(di_nw, parent_ni, 0);
2603 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2604 try di_w.writeUleb128(decl.src_column + 1);
2605 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2606 try dwarf.strp(&dwarf.debug_str, di_nw, name_nav.name.toSlice(ip));
2607 } else {
2608 const decl = zf.zir.?.getUnionDecl(loaded_union.zir_index.resolve(ip).?);
2609 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2610 ip.namespacePtr(loaded_union.namespace).parent.unwrap().?,
2611 ).owner_type);
2612 try dwarf.abbrevCode(di_nw, if (loaded_union.field_types.len > 0)
2613 switch (loaded_union.layout) {
2614 .auto, .@"extern" => .type_decl_union,
2615 .@"packed" => .type_decl_packed_union,
2616 }
2617 else switch (loaded_union.layout) {
2618 .auto, .@"extern" => .type_decl_empty_union,
2619 .@"packed" => .type_decl_empty_packed_union,
2620 });
2621 try dwarf.secOffset(di_nw, parent_ni, 0);
2622 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2623 try di_w.writeUleb128(decl.src_column + 1);
2624 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_union.name.toSlice(ip));
2625 }
2626 switch (loaded_union.layout) {
2627 .auto, .@"extern" => {
2628 const union_layout = Type.getUnionLayout(loaded_union, zcu);
2629 try di_w.writeUleb128(union_layout.abi_size);
2630 try di_w.writeUleb128(union_layout.abi_align.toByteUnits().?);
2631 try dwarf.genCaptures(pt, di_nw, loaded_union.captures);
2632 if (loaded_union.has_runtime_tag) {
2633 try dwarf.abbrevCode(di_nw, .tagged_union);
2634 try dwarf.secOffset(di_nw, di_nw.ni, di_w.end + dwarf.secOffsetSize());
2635 {
2636 try dwarf.abbrevCode(di_nw, .generated_field);
2637 try dwarf.strp(&dwarf.debug_str, di_nw, "tag");
2638 try dwarf.refType(pt, di_nw, .fromInterned(loaded_union.enum_tag_type));
2639 try di_w.writeUleb128(union_layout.tagOffset());
2640
2641 for (0..loaded_union.field_types.len) |field_index| {
2642 try dwarf.abbrevCode(di_nw, .tagged_union_field);
2643 try dwarf.enumConstValue(di_w, loaded_tag, field_index);
2644 {
2645 try dwarf.abbrevCode(di_nw, .field);
2646 try dwarf.strp(
2647 &dwarf.debug_str,
2648 di_nw,
2649 loaded_tag.field_names.get(ip)[field_index].toSlice(ip),
2650 );
2651 const field_ty: Type =
2652 .fromInterned(loaded_union.field_types.get(ip)[field_index]);
2653 try dwarf.refType(pt, di_nw, field_ty);
2654 try di_w.writeUleb128(union_layout.payloadOffset());
2655 try di_w.writeUleb128(loaded_union.field_aligns.getOrNone(
2656 ip,
2657 field_index,
2658 ).toByteUnits() orelse if (field_ty.isNoReturn(zcu))
2659 1
2660 else
2661 field_ty.abiAlignment(zcu).toByteUnits().?);
2662 }
2663 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2664 }
2665 }
2666 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2667 } else for (0..loaded_union.field_types.len) |field_index| {
2668 try dwarf.abbrevCode(di_nw, .field);
2669 try dwarf.strp(
2670 &dwarf.debug_str,
2671 di_nw,
2672 loaded_tag.field_names.get(ip)[field_index].toSlice(ip),
2673 );
2674 const field_ty: Type =
2675 .fromInterned(loaded_union.field_types.get(ip)[field_index]);
2676 try dwarf.refType(pt, di_nw, field_ty);
2677 try di_w.writeUleb128(0);
2678 try di_w.writeUleb128(loaded_union.field_aligns.getOrNone(
2679 ip,
2680 field_index,
2681 ).toByteUnits() orelse if (field_ty.isNoReturn(zcu))
2682 1
2683 else
2684 field_ty.abiAlignment(zcu).toByteUnits().?);
2685 }
2686 },
2687 .@"packed" => {
2688 try dwarf.refType(pt, di_nw, .fromInterned(loaded_union.packed_backing_int_type));
2689 for (0..loaded_union.field_types.len) |field_index| {
2690 try dwarf.abbrevCode(di_nw, .packed_field);
2691 try dwarf.strp(
2692 &dwarf.debug_str,
2693 di_nw,
2694 loaded_tag.field_names.get(ip)[field_index].toSlice(ip),
2695 );
2696 try dwarf.refType(pt, di_nw, .fromInterned(
2697 loaded_union.field_types.get(ip)[field_index],
2698 ));
2699 try di_w.writeUleb128(0);
2700 }
2701 },
2702 }
2703 if (loaded_union.captures.len > 0 or loaded_union.field_types.len > 0)
2704 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2705 },
2706 .enum_type => {
2707 const loaded_enum = ip.loadEnumType(val);
2708 switch (loaded_enum.owner_union) {
2709 .none => {
2710 const zfi = loaded_enum.zir_index.unwrap().?.resolveFile(ip);
2711 const zf = zcu.fileByIndex(zfi);
2712 if (loaded_enum.captures.len > 0 or loaded_enum.is_reified) {
2713 try dwarf.abbrevCode(di_nw, if (loaded_enum.captures.len > 0 or
2714 loaded_enum.field_names.len > 0)
2715 .decl_instance_enum
2716 else
2717 .decl_instance_empty_enum);
2718 try dwarf.secOffset(di_nw, try dwarf.getDecl(pt, val), 0);
2719 } else if (loaded_enum.name_nav.unwrap()) |name_ni| {
2720 const name_nav = ip.getNav(name_ni);
2721 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
2722 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2723 name_nav.analysis.?.namespace,
2724 ).owner_type);
2725 try dwarf.abbrevCode(
2726 di_nw,
2727 if (loaded_enum.field_names.len > 0) .decl_enum else .decl_empty_enum,
2728 );
2729 try dwarf.secOffset(di_nw, parent_ni, 0);
2730 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2731 try di_w.writeUleb128(decl.src_column + 1);
2732 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2733 try dwarf.strp(&dwarf.debug_str, di_nw, name_nav.name.toSlice(ip));
2734 } else {
2735 const decl =
2736 zf.zir.?.getEnumDecl(loaded_enum.zir_index.unwrap().?.resolve(ip).?);
2737 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
2738 ip.namespacePtr(loaded_enum.namespace).parent.unwrap().?,
2739 ).owner_type);
2740 try dwarf.abbrevCode(di_nw, if (loaded_enum.field_names.len > 0)
2741 .type_decl_enum
2742 else
2743 .type_decl_empty_enum);
2744 try dwarf.secOffset(di_nw, parent_ni, 0);
2745 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2746 try di_w.writeUleb128(decl.src_column + 1);
2747 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_enum.name.toSlice(ip));
2748 }
2749 },
2750 else => {
2751 try dwarf.abbrevCode(di_nw, if (loaded_enum.field_names.len > 0)
2752 .generated_enum_type
2753 else
2754 .generated_empty_enum_type);
2755 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_enum.fqn.toSlice(ip));
2756 },
2757 }
2758 try dwarf.refType(pt, di_nw, .fromInterned(loaded_enum.int_tag_type));
2759 for (0..loaded_enum.field_names.len) |field_index| {
2760 try dwarf.abbrevCode(di_nw, .enum_field);
2761 try dwarf.enumConstValue(di_w, loaded_enum, field_index);
2762 try dwarf.strp(
2763 &dwarf.debug_str,
2764 di_nw,
2765 loaded_enum.field_names.get(ip)[field_index].toSlice(ip),
2766 );
2767 }
2768 if (loaded_enum.captures.len > 0 or loaded_enum.field_names.len > 0)
2769 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2770 },
2771 // no defined size, so lowered the same as incomplete struct types
2772 .opaque_type => return dwarf.updateConstIncompleteInner(pt, di_nw, val),
2773 .spirv_type => unreachable,
2774 .func_type => |func_type| {
2775 const is_nullary = func_type.param_types.len == 0 and !func_type.is_var_args;
2776 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2777 defer zcu.gpa.free(name);
2778 try dwarf.abbrevCode(di_nw, if (is_nullary) .nullary_func_type else .func_type);
2779 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2780 const cc: DW.CC = cc: {
2781 if (zcu.getTarget().cCallingConvention()) |cc| {
2782 if (@as(std.lang.CallingConvention.Tag, cc) == func_type.cc) {
2783 break :cc .normal;
2784 }
2785 }
2786 // For better or worse, we try to match what Clang emits.
2787 break :cc switch (func_type.cc) {
2788 .@"inline" => .nocall,
2789 .async, .auto, .naked => .normal,
2790 .x86_64_sysv => .LLVM_X86_64SysV,
2791 .x86_64_win => .LLVM_Win64,
2792 .x86_64_regcall_v3_sysv => .LLVM_X86RegCall,
2793 .x86_64_regcall_v4_win => .LLVM_X86RegCall,
2794 .x86_64_vectorcall => .LLVM_vectorcall,
2795 .x86_sysv, .x86_win, .x86_mingw => .normal,
2796 .x86_64_preserve_none => .LLVM_PreserveNone,
2797 .x86_stdcall => .BORLAND_stdcall,
2798 .x86_fastcall => .BORLAND_msfastcall,
2799 .x86_thiscall => .BORLAND_thiscall,
2800 .x86_thiscall_mingw => .BORLAND_thiscall,
2801 .x86_regcall_v3 => .LLVM_X86RegCall,
2802 .x86_regcall_v4_win => .LLVM_X86RegCall,
2803 .x86_vectorcall => .LLVM_vectorcall,
2804
2805 .aarch64_aapcs => .normal,
2806 .aarch64_aapcs_darwin => .normal,
2807 .aarch64_aapcs_win => .normal,
2808 .aarch64_vfabi => .LLVM_AAPCS,
2809 .aarch64_vfabi_sve => .LLVM_AAPCS,
2810 .aarch64_preserve_none => .LLVM_PreserveNone,
2811
2812 .arm_aapcs => .LLVM_AAPCS,
2813 .arm_aapcs_vfp => .LLVM_AAPCS_VFP,
2814
2815 .riscv64_lp64_v,
2816 .riscv32_ilp32_v,
2817 => .LLVM_RISCVVectorCall,
2818
2819 .m68k_rtd => .LLVM_M68kRTD,
2820
2821 .sh_renesas => .GNU_renesas_sh,
2822
2823 .amdgcn_kernel => .LLVM_OpenCLKernel,
2824 .nvptx_kernel,
2825 .spirv_kernel,
2826 => .nocall,
2827
2828 .x86_64_interrupt,
2829 .x86_interrupt,
2830 .arm_interrupt,
2831 .mips64_interrupt,
2832 .mips_interrupt,
2833 .riscv64_interrupt,
2834 .riscv32_interrupt,
2835 .sh_interrupt,
2836 .arc_interrupt,
2837 .avr_builtin,
2838 .avr_signal,
2839 .avr_interrupt,
2840 .csky_interrupt,
2841 .m68k_interrupt,
2842 .microblaze_interrupt,
2843 .msp430_interrupt,
2844 => .normal,
2845
2846 else => .nocall,
2847 };
2848 };
2849 try di_w.writeByte(@backingInt(cc));
2850 try dwarf.refType(pt, di_nw, .fromInterned(func_type.return_type));
2851 if (!is_nullary) {
2852 for (0..func_type.param_types.len) |param_index| {
2853 try dwarf.abbrevCode(di_nw, .unnamed_param);
2854 try dwarf.refType(pt, di_nw, .fromInterned(
2855 func_type.param_types.get(ip)[param_index],
2856 ));
2857 }
2858 if (func_type.is_var_args) try dwarf.abbrevCode(di_nw, .is_var_args);
2859 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2860 }
2861 },
2862 .error_set_type => |error_set_type| {
2863 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2864 defer zcu.gpa.free(name);
2865 try dwarf.abbrevCode(
2866 di_nw,
2867 if (error_set_type.names.len > 0) .generated_enum_type else .generated_empty_enum_type,
2868 );
2869 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2870 try dwarf.refType(pt, di_nw, try pt.intType(.unsigned, zcu.errorSetBits()));
2871 for (0..error_set_type.names.len) |field_index| {
2872 const field_name = error_set_type.names.get(ip)[field_index];
2873 try dwarf.abbrevCode(di_nw, .enum_field);
2874 try di_w.writeUleb128(DW.FORM.udata);
2875 try di_w.writeUleb128(ip.getErrorValueIfExists(field_name).?);
2876 try dwarf.strp(&dwarf.debug_str, di_nw, field_name.toSlice(ip));
2877 }
2878 if (error_set_type.names.len > 0) try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2879 },
2880 .inferred_error_set_type => |func| {
2881 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
2882 defer zcu.gpa.free(name);
2883 try dwarf.abbrevCode(di_nw, .inferred_error_set_type);
2884 try dwarf.strp(&dwarf.debug_str, di_nw, name);
2885 try dwarf.refType(pt, di_nw, switch (ies: {
2886 const fi = dwarf.getFuncIfExists(ip.indexToKey(func).func.owner_nav) orelse
2887 break :ies .none;
2888 break :ies switch (fi.get(dwarf).state) {
2889 .unresolved => .none,
2890 .resolved => ip.funcIesResolvedUnordered(func),
2891 };
2892 }) {
2893 .none => .anyerror,
2894 else => |ies| .fromInterned(ies),
2895 });
2896 },
2897
2898 else => return,
2899 .func => |func| {
2900 const fn_ty = ip.indexToKey(func.ty).func_type;
2901 const nav = ip.getNav(func.owner_nav);
2902 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
2903 const zf = zcu.fileByIndex(inst_info.file);
2904 const decl = zf.zir.?.getDeclaration(inst_info.inst);
2905 const parent_ty: Type = .fromInterned(ip.namespacePtr(nav.analysis.?.namespace).owner_type);
2906 try dwarf.abbrevCode(di_nw, .decl_func_generic);
2907 try dwarf.refType(pt, di_nw, parent_ty);
2908 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2909 try di_w.writeUleb128(decl.src_column + 1);
2910 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2911 try dwarf.strp(&dwarf.debug_str, di_nw, nav.name.toSlice(ip));
2912 try dwarf.refType(pt, di_nw, .fromInterned(fn_ty.return_type));
2913 var param_index: u32 = 0;
2914 for (zf.zir.?.getParamBody(func.zir_body_inst.resolve(ip).?)) |param_inst| {
2915 switch (zf.zir.?.getParamName(param_inst) orelse break) {
2916 .empty => try dwarf.abbrevCode(di_nw, .unnamed_param),
2917 else => |param_name| {
2918 try dwarf.abbrevCode(di_nw, .param);
2919 try dwarf.strp(&dwarf.debug_str, di_nw, zf.zir.?.nullTerminatedString(
2920 param_name,
2921 ));
2922 },
2923 }
2924 try dwarf.refType(pt, di_nw, .fromInterned(
2925 fn_ty.param_types.get(&zcu.intern_pool)[param_index],
2926 ));
2927 param_index += 1;
2928 }
2929 if (fn_ty.is_var_args) try dwarf.abbrevCode(di_nw, .is_var_args);
2930 try di_w.writeUleb128(@backingInt(AbbrevCode.null));
2931 },
2932
2933 .memoized_call => unreachable, // not a value
2934 }
2935 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
2936}
2937
2938fn optRepr(opt_child_type: Type, zcu: *const Zcu) enum { unpacked, opv_null, error_set, pointer } {
2939 if (opt_child_type.isNoReturn(zcu)) return .opv_null;
2940 return switch (opt_child_type.toIntern()) {
2941 .anyerror_type => .error_set,
2942 else => switch (zcu.intern_pool.indexToKey(opt_child_type.toIntern())) {
2943 else => .unpacked,
2944 .error_set_type, .inferred_error_set_type => .error_set,
2945 .ptr_type => |ptr_type| if (ptr_type.flags.is_allowzero) .unpacked else .pointer,
2946 },
2947 };
2948}
2949
2950pub fn updateConstIncomplete(
2951 dwarf: *Dwarf,
2952 pt: Zcu.PerThread,
2953 di_nw: *link.MappedFile.Node.Writer,
2954 val: InternPool.Index,
2955) link.Error!void {
2956 log.debug("updateConstIncomplete({f})", .{Value.fromInterned(val).fmtValue(pt)});
2957 dwarf.updateConstIncompleteInner(pt, di_nw, val) catch |err| switch (err) {
2958 else => |e| return e,
2959 error.WriteFailed => return dwarf.reportWriteError(di_nw),
2960 };
2961}
2962fn updateConstIncompleteInner(
2963 dwarf: *Dwarf,
2964 pt: Zcu.PerThread,
2965 di_nw: *link.MappedFile.Node.Writer,
2966 val: InternPool.Index,
2967) link.EmitError!void {
2968 const zcu = pt.zcu;
2969 const ip = &zcu.intern_pool;
2970 const di_w = &di_nw.interface;
2971 done: {
2972 const kind: enum { @"struct", @"union", @"enum" }, const zf, const src_line, const src_column, const is_reified, const captures, const name, const maybe_name_nav, const namespace = container: switch (ip.indexToKey(val)) {
2973 .struct_type => {
2974 const loaded_struct = ip.loadStructType(val);
2975 const src_inst = loaded_struct.zir_index.resolveFull(ip) orelse {
2976 try dwarf.lostTracking(di_nw);
2977 break :done;
2978 };
2979 const zf = zcu.fileByIndex(src_inst.file);
2980 switch (src_inst.inst) {
2981 .main_struct_inst => {
2982 const ui = dwarf.getUnit(zf.mod.?);
2983 _, const fi = try ui.get(dwarf).getFile(zcu.gpa, ui, src_inst.file);
2984 try dwarf.abbrevCode(di_nw, .empty_file);
2985 try di_w.writeUleb128(@backingInt(fi));
2986 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip));
2987 try di_w.writeByte(@intFromBool(true));
2988 break :done;
2989 },
2990 else => {
2991 const data =
2992 zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended;
2993 const src_line, const src_column = src_loc: switch (data.opcode) {
2994 else => unreachable,
2995 .struct_decl => {
2996 const decl = zf.zir.?.getStructDecl(src_inst.inst);
2997 break :src_loc .{ decl.src_line, decl.src_column };
2998 },
2999 .reify_struct => {
3000 const decl = zf.zir.?.extraData(
3001 std.zig.Zir.Inst.ReifyStruct,
3002 data.operand,
3003 ).data;
3004 break :src_loc .{ decl.src_line, decl.src_column };
3005 },
3006 };
3007 break :container .{
3008 .@"struct",
3009 zf,
3010 src_line,
3011 src_column,
3012 loaded_struct.is_reified,
3013 loaded_struct.captures,
3014 loaded_struct.name,
3015 loaded_struct.name_nav,
3016 loaded_struct.namespace,
3017 };
3018 },
3019 }
3020 },
3021 .union_type => {
3022 const loaded_union = ip.loadUnionType(val);
3023 const src_inst = loaded_union.zir_index.resolveFull(ip) orelse {
3024 try dwarf.lostTracking(di_nw);
3025 break :done;
3026 };
3027 const zf = zcu.fileByIndex(src_inst.file);
3028 const data = zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended;
3029 const src_line, const src_column = src_loc: switch (data.opcode) {
3030 else => unreachable,
3031 .union_decl => {
3032 const decl = zf.zir.?.getUnionDecl(src_inst.inst);
3033 break :src_loc .{ decl.src_line, decl.src_column };
3034 },
3035 .reify_union => {
3036 const decl = zf.zir.?.extraData(std.zig.Zir.Inst.ReifyUnion, data.operand).data;
3037 break :src_loc .{ decl.src_line, decl.src_column };
3038 },
3039 };
3040 break :container .{
3041 .@"union",
3042 zf,
3043 src_line,
3044 src_column,
3045 loaded_union.is_reified,
3046 loaded_union.captures,
3047 loaded_union.name,
3048 loaded_union.name_nav,
3049 loaded_union.namespace,
3050 };
3051 },
3052 .enum_type => {
3053 const loaded_enum = ip.loadEnumType(val);
3054 const zir_index = loaded_enum.zir_index.unwrap() orelse {
3055 try dwarf.abbrevCode(di_nw, .generated_empty_struct_type);
3056 try dwarf.strp(&dwarf.debug_str, di_nw, loaded_enum.name.toSlice(ip));
3057 try di_w.writeByte(@intFromBool(true));
3058 break :done;
3059 };
3060 const src_inst = zir_index.resolveFull(ip) orelse {
3061 try dwarf.lostTracking(di_nw);
3062 break :done;
3063 };
3064 const zf = zcu.fileByIndex(src_inst.file);
3065 const data = zf.zir.?.instructions.items(.data)[@backingInt(src_inst.inst)].extended;
3066 const src_line, const src_column = src_loc: switch (data.opcode) {
3067 else => unreachable,
3068 .enum_decl => {
3069 const decl = zf.zir.?.getEnumDecl(src_inst.inst);
3070 break :src_loc .{ decl.src_line, decl.src_column };
3071 },
3072 .reify_enum => {
3073 const decl = zf.zir.?.extraData(std.zig.Zir.Inst.ReifyEnum, data.operand).data;
3074 break :src_loc .{ decl.src_line, decl.src_column };
3075 },
3076 };
3077 break :container .{
3078 .@"enum",
3079 zf,
3080 src_line,
3081 src_column,
3082 loaded_enum.is_reified,
3083 loaded_enum.captures,
3084 loaded_enum.name,
3085 loaded_enum.name_nav,
3086 loaded_enum.namespace,
3087 };
3088 },
3089 // always complete, but forwarded from `updateConstInner`
3090 .opaque_type => {
3091 const loaded_opaque = ip.loadOpaqueType(val);
3092 const src_inst = loaded_opaque.zir_index.resolveFull(ip) orelse {
3093 try dwarf.lostTracking(di_nw);
3094 break :done;
3095 };
3096 const zf = zcu.fileByIndex(src_inst.file);
3097 const decl = zf.zir.?.getOpaqueDecl(src_inst.inst);
3098 break :container .{
3099 .@"struct",
3100 zf,
3101 decl.src_line,
3102 decl.src_column,
3103 false,
3104 loaded_opaque.captures,
3105 loaded_opaque.name,
3106 loaded_opaque.name_nav,
3107 loaded_opaque.namespace,
3108 };
3109 },
3110 else => |val_key| break :done switch (val_key.typeOf()) {
3111 .type_type => {
3112 const name = try zcu.gpa.print("{f}", .{Type.fromInterned(val).fmt(pt)});
3113 defer zcu.gpa.free(name);
3114 try dwarf.abbrevCode(di_nw, .generated_empty_struct_type);
3115 try dwarf.strp(&dwarf.debug_str, di_nw, name);
3116 try di_w.writeByte(@intFromBool(true));
3117 },
3118 else => |ty| {
3119 try dwarf.abbrevCode(di_nw, .undefined_comptime_value);
3120 try dwarf.refType(pt, di_nw, .fromInterned(ty));
3121 },
3122 },
3123 };
3124 if (captures.len > 0 or is_reified) {
3125 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3126 .@"struct" => .decl_instance_incomplete_struct,
3127 .@"union" => .decl_instance_incomplete_union,
3128 .@"enum" => .decl_instance_incomplete_enum,
3129 } else switch (kind) {
3130 .@"struct" => .decl_instance_empty_incomplete_struct,
3131 .@"union" => .decl_instance_empty_incomplete_union,
3132 .@"enum" => .decl_instance_empty_incomplete_enum,
3133 });
3134 try dwarf.secOffset(di_nw, try dwarf.getDecl(pt, val), 0);
3135 } else if (maybe_name_nav.unwrap()) |name_ni| {
3136 const name_nav = ip.getNav(name_ni);
3137 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
3138 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
3139 name_nav.analysis.?.namespace,
3140 ).owner_type);
3141 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3142 .@"struct" => .decl_incomplete_struct,
3143 .@"union" => .decl_incomplete_union,
3144 .@"enum" => .decl_incomplete_enum,
3145 } else switch (kind) {
3146 .@"struct" => .decl_empty_incomplete_struct,
3147 .@"union" => .decl_empty_incomplete_union,
3148 .@"enum" => .decl_empty_incomplete_enum,
3149 });
3150 try dwarf.secOffset(di_nw, parent_ni, 0);
3151 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
3152 try di_w.writeUleb128(decl.src_column + 1);
3153 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
3154 try dwarf.strp(&dwarf.debug_str, di_nw, name_nav.name.toSlice(ip));
3155 } else {
3156 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
3157 ip.namespacePtr(namespace).parent.unwrap().?,
3158 ).owner_type);
3159 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3160 .@"struct" => .type_decl_incomplete_struct,
3161 .@"union" => .type_decl_incomplete_union,
3162 .@"enum" => .type_decl_incomplete_enum,
3163 } else switch (kind) {
3164 .@"struct" => .type_decl_empty_incomplete_struct,
3165 .@"union" => .type_decl_empty_incomplete_union,
3166 .@"enum" => .type_decl_empty_incomplete_enum,
3167 });
3168 try dwarf.secOffset(di_nw, parent_ni, 0);
3169 try di_w.writeInt(u32, src_line + 1, dwarf.endian);
3170 try di_w.writeUleb128(src_column + 1);
3171 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
3172 }
3173 try dwarf.genCaptures(pt, di_nw, captures);
3174 if (captures.len > 0) try di_w.writeByte(@backingInt(AbbrevCode.null));
3175 }
3176 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
3177}
3178
3179fn genCaptures(
3180 dwarf: *Dwarf,
3181 pt: Zcu.PerThread,
3182 di_nw: *link.MappedFile.Node.Writer,
3183 captures: anytype,
3184) link.EmitError!void {
3185 const zcu = pt.zcu;
3186 const ip = &zcu.intern_pool;
3187 for (captures.get(ip)) |capture| switch (capture.unwrap()) {
3188 .@"comptime" => |capture_val| {
3189 const ty: Type = .fromInterned(ip.typeOf(capture_val));
3190 const ty_class = ty.classify(zcu);
3191 try dwarf.abbrevCode(di_nw, switch (ty_class) {
3192 .no_possible_value => unreachable,
3193 .one_possible_value => .comptime_capture,
3194 .runtime => .comptime_capture_runtime,
3195 .partially_comptime => .comptime_capture_partially_comptime,
3196 .fully_comptime => .comptime_capture_fully_comptime,
3197 });
3198 try dwarf.refType(pt, di_nw, ty);
3199 if (ty_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, .fromInterned(capture_val));
3200 if (ty_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, .fromInterned(capture_val));
3201 },
3202 .runtime => |capture_ty| {
3203 try dwarf.abbrevCode(di_nw, .runtime_capture);
3204 try dwarf.refType(pt, di_nw, .fromInterned(capture_ty));
3205 },
3206 .nav_val => |capture_nav| {
3207 const gi = try dwarf.getGlobal(capture_nav);
3208 try dwarf.abbrevCode(di_nw, .nav_capture);
3209 try dwarf.exprLoc(di_nw, .{ .implicit_pointer = .{
3210 .node = gi.get(dwarf).debug_info_ni.unwrap().?,
3211 } });
3212 },
3213 .nav_ref => |capture_nav| {
3214 const gi = try dwarf.getGlobal(capture_nav);
3215 try dwarf.abbrevCode(di_nw, .nav_capture);
3216 try dwarf.exprLoc(di_nw, .{ .stack_value = &.{ .implicit_pointer = .{
3217 .node = gi.get(dwarf).debug_info_ni.unwrap().?,
3218 } } });
3219 },
3220 };
3221}
3222
3223pub fn genDecl(
3224 dwarf: *Dwarf,
3225 pt: Zcu.PerThread,
3226 di_nw: *link.MappedFile.Node.Writer,
3227 instance_val: InternPool.Index,
3228) link.Error!void {
3229 log.debug("genDecl({f})", .{Value.fromInterned(instance_val).fmtValue(pt)});
3230 dwarf.genDeclInner(pt, di_nw, instance_val) catch |err| switch (err) {
3231 else => |e| return e,
3232 error.WriteFailed => return dwarf.reportWriteError(di_nw),
3233 };
3234}
3235fn genDeclInner(
3236 dwarf: *Dwarf,
3237 pt: Zcu.PerThread,
3238 di_nw: *link.MappedFile.Node.Writer,
3239 instance_val: InternPool.Index,
3240) link.EmitError!void {
3241 const zcu = pt.zcu;
3242 const ip = &zcu.intern_pool;
3243 const di_w = &di_nw.interface;
3244 done: {
3245 const kind: enum { @"struct", @"union", @"enum" }, const zf, const src_line, const src_column, const capture_names, const captures, const name, const maybe_name_nav, const namespace = container: switch (ip.indexToKey(instance_val)) {
3246 else => unreachable,
3247 .struct_type => {
3248 const loaded_struct = ip.loadStructType(instance_val);
3249 const src_inst = loaded_struct.zir_index.resolveFull(ip) orelse {
3250 try dwarf.lostTracking(di_nw);
3251 break :done;
3252 };
3253 const zf = zcu.fileByIndex(src_inst.file);
3254 const inst = zf.zir.?.instructions.get(@backingInt(src_inst.inst));
3255 const src_line, const src_column, const capture_names = decl: switch (inst.tag) {
3256 else => unreachable,
3257 .struct_init, .struct_init_ref => {
3258 const decl = zf.zir.?.extraData(
3259 std.zig.Zir.Inst.StructInit,
3260 inst.data.pl_node.payload_index,
3261 ).data;
3262 break :decl .{ decl.src_line, decl.src_column, &.{} };
3263 },
3264 .struct_init_anon => {
3265 const decl = zf.zir.?.extraData(
3266 std.zig.Zir.Inst.StructInitAnon,
3267 inst.data.pl_node.payload_index,
3268 ).data;
3269 break :decl .{ decl.src_line, decl.src_column, &.{} };
3270 },
3271 .extended => switch (inst.data.extended.opcode) {
3272 else => unreachable,
3273 .struct_decl => {
3274 const decl = zf.zir.?.getStructDecl(src_inst.inst);
3275 break :decl .{ decl.src_line, decl.src_column, decl.capture_names };
3276 },
3277 .reify_struct => {
3278 const decl = zf.zir.?.extraData(
3279 std.zig.Zir.Inst.ReifyStruct,
3280 inst.data.extended.operand,
3281 ).data;
3282 break :decl .{ decl.src_line, decl.src_column, &.{} };
3283 },
3284 },
3285 };
3286 break :container .{
3287 .@"struct",
3288 zf,
3289 src_line,
3290 src_column,
3291 capture_names,
3292 loaded_struct.captures,
3293 loaded_struct.name,
3294 loaded_struct.name_nav,
3295 loaded_struct.namespace,
3296 };
3297 },
3298 .union_type => {
3299 const loaded_union = ip.loadUnionType(instance_val);
3300 const src_inst = loaded_union.zir_index.resolveFull(ip) orelse {
3301 try dwarf.lostTracking(di_nw);
3302 break :done;
3303 };
3304 const zf = zcu.fileByIndex(src_inst.file);
3305 const inst = zf.zir.?.instructions.get(@backingInt(src_inst.inst));
3306 const src_line, const src_column, const capture_names = decl: switch (inst.tag) {
3307 else => unreachable,
3308 .extended => switch (inst.data.extended.opcode) {
3309 else => unreachable,
3310 .union_decl => {
3311 const decl = zf.zir.?.getUnionDecl(src_inst.inst);
3312 break :decl .{ decl.src_line, decl.src_column, decl.capture_names };
3313 },
3314 .reify_union => {
3315 const decl = zf.zir.?.extraData(
3316 std.zig.Zir.Inst.ReifyUnion,
3317 inst.data.extended.operand,
3318 ).data;
3319 break :decl .{ decl.src_line, decl.src_column, &.{} };
3320 },
3321 },
3322 };
3323 break :container .{
3324 .@"union",
3325 zf,
3326 src_line,
3327 src_column,
3328 capture_names,
3329 loaded_union.captures,
3330 loaded_union.name,
3331 loaded_union.name_nav,
3332 loaded_union.namespace,
3333 };
3334 },
3335 .enum_type => {
3336 const loaded_enum = ip.loadEnumType(instance_val);
3337 const src_inst = loaded_enum.zir_index.unwrap().?.resolveFull(ip) orelse {
3338 try dwarf.lostTracking(di_nw);
3339 break :done;
3340 };
3341 const zf = zcu.fileByIndex(src_inst.file);
3342 const inst = zf.zir.?.instructions.get(@backingInt(src_inst.inst));
3343 const src_line, const src_column, const capture_names = decl: switch (inst.tag) {
3344 else => unreachable,
3345 .extended => switch (inst.data.extended.opcode) {
3346 else => unreachable,
3347 .enum_decl => {
3348 const decl = zf.zir.?.getEnumDecl(src_inst.inst);
3349 break :decl .{ decl.src_line, decl.src_column, decl.capture_names };
3350 },
3351 .reify_enum => {
3352 const decl = zf.zir.?.extraData(
3353 std.zig.Zir.Inst.ReifyEnum,
3354 inst.data.extended.operand,
3355 ).data;
3356 break :decl .{ decl.src_line, decl.src_column, &.{} };
3357 },
3358 },
3359 };
3360 break :container .{
3361 .@"enum",
3362 zf,
3363 src_line,
3364 src_column,
3365 capture_names,
3366 loaded_enum.captures,
3367 loaded_enum.name,
3368 loaded_enum.name_nav,
3369 loaded_enum.namespace,
3370 };
3371 },
3372 .opaque_type => {
3373 const loaded_opaque = ip.loadOpaqueType(instance_val);
3374 const src_inst = loaded_opaque.zir_index.resolveFull(ip) orelse {
3375 try dwarf.lostTracking(di_nw);
3376 break :done;
3377 };
3378 const zf = zcu.fileByIndex(src_inst.file);
3379 const decl = zf.zir.?.getOpaqueDecl(src_inst.inst);
3380 break :container .{
3381 .@"struct",
3382 zf,
3383 decl.src_line,
3384 decl.src_column,
3385 decl.capture_names,
3386 loaded_opaque.captures,
3387 loaded_opaque.name,
3388 loaded_opaque.name_nav,
3389 loaded_opaque.namespace,
3390 };
3391 },
3392 };
3393 if (maybe_name_nav.unwrap()) |name_ni| {
3394 const name_nav = ip.getNav(name_ni);
3395 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
3396 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
3397 name_nav.analysis.?.namespace,
3398 ).owner_type);
3399 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3400 .@"struct" => .decl_specification_struct,
3401 .@"union" => .decl_specification_union,
3402 .@"enum" => .decl_specification_enum,
3403 } else switch (kind) {
3404 .@"struct" => .decl_specification_empty_struct,
3405 .@"union" => .decl_specification_empty_union,
3406 .@"enum" => .decl_specification_empty_enum,
3407 });
3408 try dwarf.secOffset(di_nw, parent_ni, 0);
3409 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
3410 try di_w.writeUleb128(decl.src_column + 1);
3411 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
3412 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
3413 } else {
3414 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(
3415 ip.namespacePtr(namespace).parent.unwrap().?,
3416 ).owner_type);
3417 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3418 .@"struct" => .type_decl_specification_struct,
3419 .@"union" => .type_decl_specification_union,
3420 .@"enum" => .type_decl_specification_enum,
3421 } else switch (kind) {
3422 .@"struct" => .type_decl_specification_empty_struct,
3423 .@"union" => .type_decl_specification_empty_union,
3424 .@"enum" => .type_decl_specification_empty_enum,
3425 });
3426 try dwarf.secOffset(di_nw, parent_ni, 0);
3427 try di_w.writeInt(u32, src_line + 1, dwarf.endian);
3428 try di_w.writeUleb128(src_column + 1);
3429 try dwarf.strp(&dwarf.debug_str, di_nw, name.toSlice(ip));
3430 }
3431 for (capture_names, captures.get(ip)) |capture_name, capture| {
3432 try dwarf.abbrevCode(di_nw, .capture_specification);
3433 switch (capture.unwrap()) {
3434 .@"comptime", .runtime, .nav_val => try dwarf.strp(
3435 &dwarf.debug_str,
3436 di_nw,
3437 zf.zir.?.nullTerminatedString(capture_name),
3438 ),
3439 .nav_ref => {
3440 const capture_name_slice = try zcu.gpa.print("&{s}", .{
3441 zf.zir.?.nullTerminatedString(capture_name),
3442 });
3443 defer zcu.gpa.free(capture_name_slice);
3444 try dwarf.strp(&dwarf.debug_str, di_nw, capture_name_slice);
3445 },
3446 }
3447 }
3448 if (captures.len > 0) try di_w.writeUleb128(@backingInt(AbbrevCode.null));
3449 }
3450 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
3451}
3452
3453pub fn updateLineNumber(
3454 dwarf: *Dwarf,
3455 mf: *link.MappedFile,
3456 inst: InternPool.TrackedInst.Index,
3457 line: u32,
3458) void {
3459 const di = dwarf.getDeclIfExists(inst) orelse return;
3460 const decl_ni = di.get(dwarf).debug_info_ni.unwrap().?;
3461 std.mem.writeInt(
3462 u32,
3463 decl_ni.slice(mf)[AbbrevCode.decl_size..][0..4],
3464 line + 1,
3465 dwarf.endian,
3466 );
3467}
3468
3469pub fn lostTracking(dwarf: *Dwarf, di_nw: *link.MappedFile.Node.Writer) link.EmitError!void {
3470 try dwarf.abbrevCode(di_nw, .decl_lost);
3471}
3472
3473fn refAbbrevCodeIfExists(
3474 dwarf: *Dwarf,
3475 abbrev_code: AbbrevCode,
3476) ?@typeInfo(AbbrevCode).@"enum".tag_type {
3477 assert(abbrev_code != .null);
3478 return if (dwarf.debug_abbrev.set.contains(abbrev_code)) @backingInt(abbrev_code) else null;
3479}
3480fn refAbbrevCode(
3481 dwarf: *Dwarf,
3482 mf: *link.MappedFile,
3483 abbrev_code: AbbrevCode,
3484) link.Error!@typeInfo(AbbrevCode).@"enum".tag_type {
3485 if (dwarf.refAbbrevCodeIfExists(abbrev_code)) |backing_int| {
3486 @branchHint(.likely);
3487 return backing_int;
3488 }
3489 var da_nw: link.MappedFile.Node.Writer = undefined;
3490 dwarf.debug_abbrev.ni.unwrap().?.writer(dwarf.lf.comp.gpa, mf, &da_nw);
3491 defer da_nw.deinit();
3492 dwarf.genDebugAbbrev(&da_nw, abbrev_code) catch |err| switch (err) {
3493 else => |e| return e,
3494 error.WriteFailed => return dwarf.reportWriteError(&da_nw),
3495 };
3496 dwarf.debug_abbrev.set.insert(abbrev_code);
3497 return dwarf.refAbbrevCodeIfExists(abbrev_code).?;
3498}
3499fn abbrevCode(
3500 dwarf: *Dwarf,
3501 nw: *link.MappedFile.Node.Writer,
3502 abbrev_code: AbbrevCode,
3503) link.EmitError!void {
3504 try nw.interface.writeUleb128(try dwarf.refAbbrevCode(nw.mf, abbrev_code));
3505}
3506
3507fn genDebugAbbrev(
3508 dwarf: *Dwarf,
3509 da_nw: *link.MappedFile.Node.Writer,
3510 abbrev_code: AbbrevCode,
3511) link.EmitError!void {
3512 const abbrev = AbbrevCode.abbrevs.get(abbrev_code);
3513 const da_w = &da_nw.interface;
3514 da_w.end = dwarf.debug_abbrev.end;
3515 try da_w.writeUleb128(@backingInt(abbrev_code));
3516 try da_w.writeUleb128(@backingInt(abbrev.tag));
3517 try da_w.writeByte(if (abbrev.children) DW.CHILDREN.yes else DW.CHILDREN.no);
3518 for (abbrev.attrs) |*attr| {
3519 try da_w.writeUleb128(@backingInt(switch (attr[0]) {
3520 else => |at| at,
3521 .ZIG_call_line_relative => |at| if (dwarf.lf.comp.config.incremental) at else .call_line,
3522 }));
3523 try da_w.writeUleb128(@backingInt(attr[1]));
3524 }
3525 for (0..2) |_| try da_w.writeUleb128(0);
3526 dwarf.debug_abbrev.end = da_w.end;
3527}
3528
3529pub fn secOffsetSize(dwarf: *Dwarf) usize {
3530 return switch (dwarf.format) {
3531 .@"32" => 4,
3532 .@"64" => 8,
3533 };
3534}
3535fn secOffsetPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
3536 @memset(try w.writableSlice(dwarf.secOffsetSize()), undefined);
3537}
3538fn secOffset(
3539 dwarf: *Dwarf,
3540 nw: *link.MappedFile.Node.Writer,
3541 target_ni: link.MappedFile.Node.Index,
3542 addend: usize,
3543) link.EmitError!void {
3544 const offset = nw.interface.end;
3545 try dwarf.secOffsetPlaceholder(&nw.interface);
3546 if (dwarf.lf.cast(.elf2)) |elf| try elf.addNodeReloc(
3547 nw.ni,
3548 offset,
3549 target_ni,
3550 @bitCast(@as(u64, addend)),
3551 switch (dwarf.format) {
3552 .@"32" => .abs32,
3553 .@"64" => .abs64,
3554 },
3555 ) else unreachable;
3556}
3557
3558fn addrPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
3559 @memset(try w.writableSlice(@backingInt(dwarf.address_size)), undefined);
3560}
3561fn addrSym(
3562 dwarf: *Dwarf,
3563 nw: *link.MappedFile.Node.Writer,
3564 target_si: link.File.SymbolId,
3565 addend: usize,
3566) link.EmitError!void {
3567 const offset = nw.interface.end;
3568 try dwarf.addrPlaceholder(&nw.interface);
3569 if (dwarf.lf.cast(.elf2)) |elf| try elf.addReloc(
3570 @bitCast(nw.ni),
3571 offset,
3572 target_si,
3573 @bitCast(@as(u64, addend)),
3574 .absAddr(elf),
3575 ) else unreachable;
3576}
3577
3578fn blockConst(
3579 dwarf: *Dwarf,
3580 pt: Zcu.PerThread,
3581 nw: *link.MappedFile.Node.Writer,
3582 val: Value,
3583) link.EmitError!void {
3584 const ty = val.typeOf(pt.zcu);
3585 const size = ty.abiSize(pt.zcu);
3586 try nw.interface.writeUleb128(size);
3587 const start = nw.interface.end;
3588 if (size > 0) try codegen.generateSymbol(
3589 dwarf.lf,
3590 pt,
3591 val,
3592 &nw.interface,
3593 .{ .atom_index = @bitCast(nw.ni) },
3594 );
3595 assert(start + size == nw.interface.end);
3596}
3597
3598fn refType(
3599 dwarf: *Dwarf,
3600 pt: Zcu.PerThread,
3601 nw: *link.MappedFile.Node.Writer,
3602 ty: Type,
3603) link.EmitError!void {
3604 return dwarf.refConst(pt, nw, ty.toValue());
3605}
3606fn refConst(
3607 dwarf: *Dwarf,
3608 pt: Zcu.PerThread,
3609 nw: *link.MappedFile.Node.Writer,
3610 val: Value,
3611) link.EmitError!void {
3612 try dwarf.secOffset(nw, Const.get(try dwarf.getConst(pt, val), dwarf).debug_info_ni.unwrap().?, 0);
3613}
3614
3615fn bigIntConstValue(
3616 dwarf: *Dwarf,
3617 di_w: *std.Io.Writer,
3618 ty: Type,
3619 big_int: std.math.big.int.Const,
3620) link.EmitError!void {
3621 const zcu = dwarf.lf.comp.zcu.?;
3622 const signedness = switch (ty.toIntern()) {
3623 .comptime_int_type => .signed,
3624 else => ty.intInfo(zcu).signedness,
3625 };
3626 const bits = @max(1, big_int.bitCountTwosCompForSignedness(signedness));
3627 if (bits <= 64) {
3628 try di_w.writeUleb128(@as(u13, switch (signedness) {
3629 .signed => DW.FORM.sdata,
3630 .unsigned => DW.FORM.udata,
3631 }));
3632 var bit: usize = 0;
3633 var carry: u1 = 1;
3634 for (try di_w.writableSlice(@divCeil(bits, 7))) |*byte| {
3635 const limb_bits = @typeInfo(std.math.big.Limb).int.bits;
3636 const limb_index = bit / limb_bits;
3637 const limb_shift: std.math.Log2Int(std.math.big.Limb) = @intCast(bit % limb_bits);
3638 const low_abs_part: u7 = @truncate(big_int.limbs[limb_index] >> limb_shift);
3639 const abs_part = if (limb_shift > limb_bits - 7 and
3640 limb_index + 1 < big_int.limbs.len)
3641 abs_part: {
3642 const high_abs_part: u7 = @truncate(big_int.limbs[limb_index + 1] << -%limb_shift);
3643 break :abs_part high_abs_part | low_abs_part;
3644 } else low_abs_part;
3645 const twos_comp_part = if (big_int.positive) abs_part else twos_comp_part: {
3646 const twos_comp_part, carry = @addWithOverflow(~abs_part, carry);
3647 break :twos_comp_part twos_comp_part;
3648 };
3649 bit += 7;
3650 byte.* = @as(u8, if (bit < bits) 0x80 else 0x00) | twos_comp_part;
3651 }
3652 } else {
3653 try di_w.writeUleb128(DW.FORM.block);
3654 const size = switch (ty.toIntern()) {
3655 .comptime_int_type => @divCeil(bits, 8),
3656 else => ty.abiSize(zcu),
3657 };
3658 try di_w.writeUleb128(size);
3659 big_int.writeTwosComplement(try di_w.writableSlice(@intCast(size)), dwarf.endian);
3660 }
3661}
3662
3663fn enumConstValue(
3664 dwarf: *Dwarf,
3665 di_w: *std.Io.Writer,
3666 loaded_enum: InternPool.LoadedEnumType,
3667 field_index: usize,
3668) link.EmitError!void {
3669 const zcu = dwarf.lf.comp.zcu.?;
3670 var big_int_space: Value.BigIntSpace = undefined;
3671 try dwarf.bigIntConstValue(
3672 di_w,
3673 .fromInterned(loaded_enum.int_tag_type),
3674 if (loaded_enum.field_values.len > 0)
3675 Value.fromInterned(loaded_enum.field_values.get(&zcu.intern_pool)[field_index])
3676 .toBigInt(&big_int_space, zcu)
3677 else
3678 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst(),
3679 );
3680}
3681
3682fn exprLoc(dwarf: *Dwarf, nw: *link.MappedFile.Node.Writer, loc: Loc) link.EmitError!void {
3683 var buf: [@max(8, std.atomic.cache_line)]u8 = undefined;
3684 var dw: std.Io.Writer.Discarding = .init(&buf);
3685 try loc.write(.{ .io = &dw.writer }, dwarf);
3686
3687 try nw.interface.writeUleb128(dw.fullCount());
3688 try loc.write(.{ .mf = nw }, dwarf);
3689}
3690
3691fn strp(dwarf: *Dwarf, s: *Str, nw: *link.MappedFile.Node.Writer, str: []const u8) link.EmitError!void {
3692 const comp = dwarf.lf.comp;
3693 try dwarf.secOffset(nw, s.ni.unwrap().?, s.get(comp.gpa, nw.mf, str) catch |err| switch (err) {
3694 error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{
3695 nw.mf.io_err.?,
3696 }),
3697 else => |e| return e,
3698 });
3699}
3700
3701fn reportWriteError(dwarf: *Dwarf, nw: *const link.MappedFile.Node.Writer) link.Error {
3702 switch (nw.err.?) {
3703 else => |e| return e,
3704 error.MappedFileIo => return dwarf.lf.comp.link_diags.fail(
3705 "failed to write output file: {t}",
3706 .{nw.mf.io_err.?},
3707 ),
3708 }
3709}
3710
3711fn constPoolUser(dwarf: *Dwarf) link.ConstPool.User {
3712 return if (dwarf.lf.cast(.elf2)) |elf| .{
3713 .elf2 = elf,
3714 } else unreachable;
3715}
3716
3717fn DeclValEnum(comptime T: type) type {
3718 const decl_names = @typeInfo(T).@"struct".decl_names;
3719 @setEvalBranchQuota(10 * decl_names.len);
3720 var field_names: [decl_names.len][]const u8 = undefined;
3721 var fields_len = 0;
3722 var min_value: ?comptime_int = null;
3723 var max_value: ?comptime_int = null;
3724 for (decl_names) |decl_name| {
3725 if (std.mem.startsWith(u8, decl_name, "HP_") or
3726 std.mem.endsWith(u8, decl_name, "_user")) continue;
3727 const value = @field(T, decl_name);
3728 field_names[fields_len] = decl_name;
3729 fields_len += 1;
3730 if (min_value == null or min_value.? > value) min_value = value;
3731 if (max_value == null or max_value.? < value) max_value = value;
3732 }
3733 if (fields_len == 0) return enum {};
3734 const TagInt = std.math.IntFittingRange(min_value orelse 0, max_value orelse 0);
3735 var field_vals: [fields_len]TagInt = undefined;
3736 for (field_names[0..fields_len], &field_vals) |name, *val| val.* = @field(T, name);
3737 return @Enum(TagInt, .exhaustive, field_names[0..fields_len], &field_vals);
3738}
3739
3740pub const AbbrevCode = enum {
3741 null,
3742 // padding codes must be one byte uleb128 values to function
3743 pad_1,
3744 pad_n,
3745 // decl, specification, and instance codes are assumed to all have the same uleb128 size
3746 decl_lost,
3747 decl_alias,
3748 decl_empty_incomplete_enum,
3749 decl_incomplete_enum,
3750 decl_empty_enum,
3751 decl_enum,
3752 type_decl_empty_incomplete_enum,
3753 type_decl_incomplete_enum,
3754 type_decl_empty_enum,
3755 type_decl_enum,
3756 decl_empty_incomplete_struct,
3757 decl_incomplete_struct,
3758 decl_empty_struct,
3759 decl_struct,
3760 type_decl_empty_incomplete_struct,
3761 type_decl_incomplete_struct,
3762 type_decl_empty_struct,
3763 type_decl_struct,
3764 decl_empty_packed_struct,
3765 decl_packed_struct,
3766 type_decl_empty_packed_struct,
3767 type_decl_packed_struct,
3768 decl_empty_incomplete_union,
3769 decl_incomplete_union,
3770 decl_empty_union,
3771 decl_union,
3772 type_decl_empty_incomplete_union,
3773 type_decl_incomplete_union,
3774 type_decl_empty_union,
3775 type_decl_union,
3776 decl_empty_packed_union,
3777 decl_packed_union,
3778 type_decl_empty_packed_union,
3779 type_decl_packed_union,
3780 decl_var,
3781 decl_const,
3782 decl_const_runtime_bits,
3783 decl_const_comptime_state,
3784 decl_const_runtime_bits_comptime_state,
3785 decl_nullary_func,
3786 decl_func,
3787 decl_nullary_func_generic,
3788 decl_func_generic,
3789 decl_extern_nullary_func,
3790 decl_extern_func,
3791 decl_specification_empty_struct,
3792 decl_specification_struct,
3793 type_decl_specification_empty_struct,
3794 type_decl_specification_struct,
3795 decl_specification_empty_enum,
3796 decl_specification_enum,
3797 type_decl_specification_empty_enum,
3798 type_decl_specification_enum,
3799 decl_specification_empty_union,
3800 decl_specification_union,
3801 type_decl_specification_empty_union,
3802 type_decl_specification_union,
3803 decl_specification_func,
3804 decl_instance_alias,
3805 decl_instance_empty_incomplete_enum,
3806 decl_instance_incomplete_enum,
3807 decl_instance_empty_enum,
3808 decl_instance_enum,
3809 decl_instance_empty_incomplete_struct,
3810 decl_instance_incomplete_struct,
3811 decl_instance_empty_struct,
3812 decl_instance_struct,
3813 decl_instance_empty_packed_struct,
3814 decl_instance_packed_struct,
3815 decl_instance_empty_incomplete_union,
3816 decl_instance_incomplete_union,
3817 decl_instance_empty_union,
3818 decl_instance_union,
3819 decl_instance_empty_packed_union,
3820 decl_instance_packed_union,
3821 decl_instance_var,
3822 decl_instance_const,
3823 decl_instance_const_runtime_bits,
3824 decl_instance_const_comptime_state,
3825 decl_instance_const_runtime_bits_comptime_state,
3826 decl_instance_nullary_func,
3827 decl_instance_func,
3828 decl_instance_nullary_func_generic,
3829 decl_instance_func_generic,
3830 decl_instance_extern_nullary_func,
3831 decl_instance_extern_func,
3832 // the rest are unrestricted other than empty variants must not be longer
3833 // than the non-empty variant, and so should appear first
3834 compile_unit,
3835 module,
3836 module_dependency,
3837 empty_file,
3838 file,
3839 access,
3840 enum_field,
3841 generated_field,
3842 field,
3843 field_default_fully_runtime,
3844 field_default_partially_comptime,
3845 field_default_fully_comptime,
3846 field_comptime,
3847 field_comptime_fully_runtime,
3848 field_comptime_partially_comptime,
3849 field_comptime_fully_comptime,
3850 packed_field,
3851 tagged_union,
3852 tagged_union_field,
3853 tagged_union_default_field,
3854 void_type,
3855 numeric_type,
3856 inferred_error_set_type,
3857 ptr_type,
3858 ptr_sentinel_type,
3859 ptr_aligned_type,
3860 ptr_aligned_sentinel_type,
3861 is_const,
3862 is_volatile,
3863 array_type,
3864 array_sentinel_type,
3865 vector_type,
3866 array_index,
3867 array_len,
3868 nullary_func_type,
3869 func_type,
3870 param,
3871 unnamed_param,
3872 is_var_args,
3873 generated_empty_enum_type,
3874 generated_enum_type,
3875 generated_empty_struct_type,
3876 generated_struct_type,
3877 generated_union_type,
3878 capture_specification,
3879 comptime_capture,
3880 comptime_capture_runtime,
3881 comptime_capture_partially_comptime,
3882 comptime_capture_fully_comptime,
3883 runtime_capture,
3884 nav_capture,
3885 builtin_extern_nullary_func,
3886 builtin_extern_func,
3887 builtin_extern_var,
3888 empty_block,
3889 block,
3890 empty_inlined_func,
3891 inlined_func,
3892 arg,
3893 unnamed_arg,
3894 comptime_arg,
3895 comptime_arg_fully_runtime,
3896 comptime_arg_partially_comptime,
3897 comptime_arg_fully_comptime,
3898 unnamed_comptime_arg,
3899 unnamed_comptime_arg_fully_runtime,
3900 unnamed_comptime_arg_partially_comptime,
3901 unnamed_comptime_arg_fully_comptime,
3902 extern_param,
3903 local_var,
3904 local_const,
3905 local_const_fully_runtime,
3906 local_const_partially_comptime,
3907 local_const_fully_comptime,
3908 undefined_comptime_value,
3909 comptime_value,
3910 location_comptime_value,
3911 aggregate_undefined_comptime_value,
3912 aggregate_comptime_value,
3913 aggregate_location_comptime_value,
3914 comptime_value_field_runtime_bits,
3915 comptime_value_field_comptime_state,
3916 comptime_value_elem_runtime_bits,
3917 comptime_value_elem_comptime_state,
3918
3919 const decl_size = uleb128Size(@backingInt(AbbrevCode.decl_instance_extern_func));
3920 comptime {
3921 assert(uleb128Size(@backingInt(AbbrevCode.pad_1)) == 1);
3922 assert(uleb128Size(@backingInt(AbbrevCode.pad_n)) == 1);
3923 assert(uleb128Size(@backingInt(AbbrevCode.decl_alias)) == decl_size);
3924 }
3925
3926 const Attr = struct {
3927 DeclValEnum(DW.AT),
3928 DeclValEnum(DW.FORM),
3929 };
3930 const decl_attrs = &[_]Attr{
3931 .{ .ZIG_parent, .ref_addr },
3932 .{ .decl_line, .data4 },
3933 .{ .decl_column, .udata },
3934 .{ .accessibility, .data1 },
3935 .{ .name, .strp },
3936 };
3937 const type_decl_attrs = &[_]Attr{
3938 .{ .ZIG_parent, .ref_addr },
3939 .{ .decl_line, .data4 },
3940 .{ .decl_column, .udata },
3941 .{ .name, .strp },
3942 };
3943 const decl_specification_attrs = decl_attrs ++ &[_]Attr{
3944 .{ .declaration, .flag_present },
3945 };
3946 const type_decl_specification_attrs = type_decl_attrs ++ &[_]Attr{
3947 .{ .declaration, .flag_present },
3948 };
3949 const decl_instance_attrs = &[_]Attr{
3950 .{ .specification, .ref_addr },
3951 };
3952
3953 const abbrevs = std.EnumArray(AbbrevCode, struct {
3954 tag: DeclValEnum(DW.TAG),
3955 children: bool = false,
3956 attrs: []const Attr = &.{},
3957 }).init(.{
3958 .null = undefined,
3959 .pad_1 = .{
3960 .tag = .ZIG_padding,
3961 },
3962 .pad_n = .{
3963 .tag = .ZIG_padding,
3964 .attrs = &.{
3965 .{ .ZIG_padding, .block },
3966 },
3967 },
3968 .decl_lost = .{
3969 .tag = .ZIG_lost_declaration,
3970 },
3971 .decl_alias = .{
3972 .tag = .imported_declaration,
3973 .attrs = decl_attrs ++ .{
3974 .{ .import, .ref_addr },
3975 },
3976 },
3977 .decl_empty_incomplete_enum = .{
3978 .tag = .enumeration_type,
3979 .attrs = decl_attrs,
3980 },
3981 .decl_incomplete_enum = .{
3982 .tag = .enumeration_type,
3983 .children = true,
3984 .attrs = decl_attrs,
3985 },
3986 .decl_empty_enum = .{
3987 .tag = .enumeration_type,
3988 .attrs = decl_attrs ++ .{
3989 .{ .type, .ref_addr },
3990 },
3991 },
3992 .decl_enum = .{
3993 .tag = .enumeration_type,
3994 .children = true,
3995 .attrs = decl_attrs ++ .{
3996 .{ .type, .ref_addr },
3997 },
3998 },
3999 .type_decl_empty_incomplete_enum = .{
4000 .tag = .enumeration_type,
4001 .attrs = type_decl_attrs,
4002 },
4003 .type_decl_incomplete_enum = .{
4004 .tag = .enumeration_type,
4005 .children = true,
4006 .attrs = type_decl_attrs,
4007 },
4008 .type_decl_empty_enum = .{
4009 .tag = .enumeration_type,
4010 .attrs = type_decl_attrs ++ .{
4011 .{ .type, .ref_addr },
4012 },
4013 },
4014 .type_decl_enum = .{
4015 .tag = .enumeration_type,
4016 .children = true,
4017 .attrs = type_decl_attrs ++ .{
4018 .{ .type, .ref_addr },
4019 },
4020 },
4021 .decl_empty_incomplete_struct = .{
4022 .tag = .structure_type,
4023 .attrs = decl_attrs,
4024 },
4025 .decl_incomplete_struct = .{
4026 .tag = .structure_type,
4027 .children = true,
4028 .attrs = decl_attrs,
4029 },
4030 .decl_empty_struct = .{
4031 .tag = .structure_type,
4032 .attrs = decl_attrs ++ .{
4033 .{ .byte_size, .udata },
4034 .{ .alignment, .udata },
4035 },
4036 },
4037 .decl_struct = .{
4038 .tag = .structure_type,
4039 .children = true,
4040 .attrs = decl_attrs ++ .{
4041 .{ .byte_size, .udata },
4042 .{ .alignment, .udata },
4043 },
4044 },
4045 .type_decl_empty_incomplete_struct = .{
4046 .tag = .structure_type,
4047 .attrs = type_decl_attrs,
4048 },
4049 .type_decl_incomplete_struct = .{
4050 .tag = .structure_type,
4051 .children = true,
4052 .attrs = type_decl_attrs,
4053 },
4054 .type_decl_empty_struct = .{
4055 .tag = .structure_type,
4056 .attrs = type_decl_attrs ++ .{
4057 .{ .byte_size, .udata },
4058 .{ .alignment, .udata },
4059 },
4060 },
4061 .type_decl_struct = .{
4062 .tag = .structure_type,
4063 .children = true,
4064 .attrs = type_decl_attrs ++ .{
4065 .{ .byte_size, .udata },
4066 .{ .alignment, .udata },
4067 },
4068 },
4069 .decl_empty_packed_struct = .{
4070 .tag = .structure_type,
4071 .attrs = decl_attrs ++ .{
4072 .{ .type, .ref_addr },
4073 },
4074 },
4075 .decl_packed_struct = .{
4076 .tag = .structure_type,
4077 .children = true,
4078 .attrs = decl_attrs ++ .{
4079 .{ .type, .ref_addr },
4080 },
4081 },
4082 .type_decl_empty_packed_struct = .{
4083 .tag = .structure_type,
4084 .attrs = type_decl_attrs ++ .{
4085 .{ .type, .ref_addr },
4086 },
4087 },
4088 .type_decl_packed_struct = .{
4089 .tag = .structure_type,
4090 .children = true,
4091 .attrs = type_decl_attrs ++ .{
4092 .{ .type, .ref_addr },
4093 },
4094 },
4095 .decl_empty_incomplete_union = .{
4096 .tag = .union_type,
4097 .attrs = decl_attrs,
4098 },
4099 .decl_incomplete_union = .{
4100 .tag = .union_type,
4101 .children = true,
4102 .attrs = decl_attrs,
4103 },
4104 .decl_empty_union = .{
4105 .tag = .union_type,
4106 .attrs = decl_attrs ++ .{
4107 .{ .byte_size, .udata },
4108 .{ .alignment, .udata },
4109 },
4110 },
4111 .decl_union = .{
4112 .tag = .union_type,
4113 .children = true,
4114 .attrs = decl_attrs ++ .{
4115 .{ .byte_size, .udata },
4116 .{ .alignment, .udata },
4117 },
4118 },
4119 .type_decl_empty_incomplete_union = .{
4120 .tag = .union_type,
4121 .attrs = type_decl_attrs,
4122 },
4123 .type_decl_incomplete_union = .{
4124 .tag = .union_type,
4125 .children = true,
4126 .attrs = type_decl_attrs,
4127 },
4128 .type_decl_empty_union = .{
4129 .tag = .union_type,
4130 .attrs = type_decl_attrs ++ .{
4131 .{ .byte_size, .udata },
4132 .{ .alignment, .udata },
4133 },
4134 },
4135 .type_decl_union = .{
4136 .tag = .union_type,
4137 .children = true,
4138 .attrs = type_decl_attrs ++ .{
4139 .{ .byte_size, .udata },
4140 .{ .alignment, .udata },
4141 },
4142 },
4143 .decl_empty_packed_union = .{
4144 .tag = .union_type,
4145 .attrs = decl_attrs ++ .{
4146 .{ .type, .ref_addr },
4147 },
4148 },
4149 .decl_packed_union = .{
4150 .tag = .union_type,
4151 .children = true,
4152 .attrs = decl_attrs ++ .{
4153 .{ .type, .ref_addr },
4154 },
4155 },
4156 .type_decl_empty_packed_union = .{
4157 .tag = .union_type,
4158 .attrs = type_decl_attrs ++ .{
4159 .{ .type, .ref_addr },
4160 },
4161 },
4162 .type_decl_packed_union = .{
4163 .tag = .union_type,
4164 .children = true,
4165 .attrs = type_decl_attrs ++ .{
4166 .{ .type, .ref_addr },
4167 },
4168 },
4169 .decl_var = .{
4170 .tag = .variable,
4171 .attrs = decl_attrs ++ .{
4172 .{ .linkage_name, .strp },
4173 .{ .type, .ref_addr },
4174 .{ .location, .exprloc },
4175 .{ .alignment, .udata },
4176 .{ .external, .flag },
4177 },
4178 },
4179 .decl_const = .{
4180 .tag = .constant,
4181 .attrs = decl_attrs ++ .{
4182 .{ .linkage_name, .strp },
4183 .{ .type, .ref_addr },
4184 .{ .alignment, .udata },
4185 .{ .external, .flag },
4186 },
4187 },
4188 .decl_const_runtime_bits = .{
4189 .tag = .constant,
4190 .attrs = decl_attrs ++ .{
4191 .{ .linkage_name, .strp },
4192 .{ .type, .ref_addr },
4193 .{ .alignment, .udata },
4194 .{ .external, .flag },
4195 .{ .const_value, .block },
4196 },
4197 },
4198 .decl_const_comptime_state = .{
4199 .tag = .constant,
4200 .attrs = decl_attrs ++ .{
4201 .{ .linkage_name, .strp },
4202 .{ .type, .ref_addr },
4203 .{ .alignment, .udata },
4204 .{ .external, .flag },
4205 .{ .ZIG_comptime_value, .ref_addr },
4206 },
4207 },
4208 .decl_const_runtime_bits_comptime_state = .{
4209 .tag = .constant,
4210 .attrs = decl_attrs ++ .{
4211 .{ .linkage_name, .strp },
4212 .{ .type, .ref_addr },
4213 .{ .alignment, .udata },
4214 .{ .external, .flag },
4215 .{ .const_value, .block },
4216 .{ .ZIG_comptime_value, .ref_addr },
4217 },
4218 },
4219 .decl_nullary_func = .{
4220 .tag = .subprogram,
4221 .attrs = decl_attrs ++ .{
4222 .{ .linkage_name, .strp },
4223 .{ .type, .ref_addr },
4224 .{ .low_pc, .addr },
4225 .{ .high_pc, .data4 },
4226 .{ .alignment, .udata },
4227 .{ .external, .flag },
4228 .{ .noreturn, .flag },
4229 },
4230 },
4231 .decl_func = .{
4232 .tag = .subprogram,
4233 .children = true,
4234 .attrs = decl_attrs ++ .{
4235 .{ .linkage_name, .strp },
4236 .{ .type, .ref_addr },
4237 .{ .low_pc, .addr },
4238 .{ .high_pc, .data4 },
4239 .{ .alignment, .udata },
4240 .{ .external, .flag },
4241 .{ .noreturn, .flag },
4242 },
4243 },
4244 .decl_nullary_func_generic = .{
4245 .tag = .subprogram,
4246 .attrs = decl_attrs ++ .{
4247 .{ .type, .ref_addr },
4248 .{ .noreturn, .flag },
4249 },
4250 },
4251 .decl_func_generic = .{
4252 .tag = .subprogram,
4253 .children = true,
4254 .attrs = decl_attrs ++ .{
4255 .{ .type, .ref_addr },
4256 },
4257 },
4258 .decl_extern_nullary_func = .{
4259 .tag = .subprogram,
4260 .attrs = decl_attrs ++ .{
4261 .{ .linkage_name, .strp },
4262 .{ .type, .ref_addr },
4263 .{ .low_pc, .addr },
4264 .{ .external, .flag_present },
4265 .{ .noreturn, .flag },
4266 },
4267 },
4268 .decl_extern_func = .{
4269 .tag = .subprogram,
4270 .children = true,
4271 .attrs = decl_attrs ++ .{
4272 .{ .linkage_name, .strp },
4273 .{ .type, .ref_addr },
4274 .{ .low_pc, .addr },
4275 .{ .external, .flag_present },
4276 .{ .noreturn, .flag },
4277 },
4278 },
4279 .decl_specification_empty_struct = .{
4280 .tag = .structure_type,
4281 .attrs = decl_specification_attrs,
4282 },
4283 .decl_specification_struct = .{
4284 .tag = .structure_type,
4285 .children = true,
4286 .attrs = decl_specification_attrs,
4287 },
4288 .type_decl_specification_empty_struct = .{
4289 .tag = .structure_type,
4290 .attrs = type_decl_specification_attrs,
4291 },
4292 .type_decl_specification_struct = .{
4293 .tag = .structure_type,
4294 .children = true,
4295 .attrs = type_decl_specification_attrs,
4296 },
4297 .decl_specification_empty_enum = .{
4298 .tag = .enumeration_type,
4299 .attrs = decl_specification_attrs,
4300 },
4301 .decl_specification_enum = .{
4302 .tag = .enumeration_type,
4303 .children = true,
4304 .attrs = decl_specification_attrs,
4305 },
4306 .type_decl_specification_empty_enum = .{
4307 .tag = .enumeration_type,
4308 .attrs = type_decl_specification_attrs,
4309 },
4310 .type_decl_specification_enum = .{
4311 .tag = .enumeration_type,
4312 .children = true,
4313 .attrs = type_decl_specification_attrs,
4314 },
4315 .decl_specification_empty_union = .{
4316 .tag = .union_type,
4317 .attrs = decl_specification_attrs,
4318 },
4319 .decl_specification_union = .{
4320 .tag = .union_type,
4321 .children = true,
4322 .attrs = decl_specification_attrs,
4323 },
4324 .type_decl_specification_empty_union = .{
4325 .tag = .union_type,
4326 .attrs = type_decl_specification_attrs,
4327 },
4328 .type_decl_specification_union = .{
4329 .tag = .union_type,
4330 .children = true,
4331 .attrs = type_decl_specification_attrs,
4332 },
4333 .decl_specification_func = .{
4334 .tag = .subprogram,
4335 .attrs = decl_specification_attrs,
4336 },
4337 .decl_instance_alias = .{
4338 .tag = .imported_declaration,
4339 .attrs = decl_instance_attrs ++ .{
4340 .{ .import, .ref_addr },
4341 },
4342 },
4343 .decl_instance_empty_incomplete_enum = .{
4344 .tag = .enumeration_type,
4345 .attrs = decl_instance_attrs,
4346 },
4347 .decl_instance_incomplete_enum = .{
4348 .tag = .enumeration_type,
4349 .children = true,
4350 .attrs = decl_instance_attrs,
4351 },
4352 .decl_instance_empty_enum = .{
4353 .tag = .enumeration_type,
4354 .attrs = decl_instance_attrs ++ .{
4355 .{ .type, .ref_addr },
4356 },
4357 },
4358 .decl_instance_enum = .{
4359 .tag = .enumeration_type,
4360 .children = true,
4361 .attrs = decl_instance_attrs ++ .{
4362 .{ .type, .ref_addr },
4363 },
4364 },
4365 .decl_instance_empty_incomplete_struct = .{
4366 .tag = .structure_type,
4367 .attrs = decl_instance_attrs,
4368 },
4369 .decl_instance_incomplete_struct = .{
4370 .tag = .structure_type,
4371 .children = true,
4372 .attrs = decl_instance_attrs,
4373 },
4374 .decl_instance_empty_struct = .{
4375 .tag = .structure_type,
4376 .attrs = decl_instance_attrs ++ .{
4377 .{ .byte_size, .udata },
4378 .{ .alignment, .udata },
4379 },
4380 },
4381 .decl_instance_struct = .{
4382 .tag = .structure_type,
4383 .children = true,
4384 .attrs = decl_instance_attrs ++ .{
4385 .{ .byte_size, .udata },
4386 .{ .alignment, .udata },
4387 },
4388 },
4389 .decl_instance_empty_packed_struct = .{
4390 .tag = .structure_type,
4391 .attrs = decl_instance_attrs ++ .{
4392 .{ .type, .ref_addr },
4393 },
4394 },
4395 .decl_instance_packed_struct = .{
4396 .tag = .structure_type,
4397 .children = true,
4398 .attrs = decl_instance_attrs ++ .{
4399 .{ .type, .ref_addr },
4400 },
4401 },
4402 .decl_instance_empty_incomplete_union = .{
4403 .tag = .union_type,
4404 .attrs = decl_instance_attrs,
4405 },
4406 .decl_instance_incomplete_union = .{
4407 .tag = .union_type,
4408 .children = true,
4409 .attrs = decl_instance_attrs,
4410 },
4411 .decl_instance_empty_union = .{
4412 .tag = .union_type,
4413 .attrs = decl_instance_attrs ++ .{
4414 .{ .byte_size, .udata },
4415 .{ .alignment, .udata },
4416 },
4417 },
4418 .decl_instance_union = .{
4419 .tag = .union_type,
4420 .children = true,
4421 .attrs = decl_instance_attrs ++ .{
4422 .{ .byte_size, .udata },
4423 .{ .alignment, .udata },
4424 },
4425 },
4426 .decl_instance_empty_packed_union = .{
4427 .tag = .union_type,
4428 .attrs = decl_instance_attrs ++ .{
4429 .{ .type, .ref_addr },
4430 },
4431 },
4432 .decl_instance_packed_union = .{
4433 .tag = .union_type,
4434 .children = true,
4435 .attrs = decl_instance_attrs ++ .{
4436 .{ .type, .ref_addr },
4437 },
4438 },
4439 .decl_instance_var = .{
4440 .tag = .variable,
4441 .attrs = decl_instance_attrs ++ .{
4442 .{ .linkage_name, .strp },
4443 .{ .type, .ref_addr },
4444 .{ .location, .exprloc },
4445 .{ .alignment, .udata },
4446 .{ .external, .flag },
4447 },
4448 },
4449 .decl_instance_const = .{
4450 .tag = .constant,
4451 .attrs = decl_instance_attrs ++ .{
4452 .{ .linkage_name, .strp },
4453 .{ .type, .ref_addr },
4454 .{ .alignment, .udata },
4455 .{ .external, .flag },
4456 },
4457 },
4458 .decl_instance_const_runtime_bits = .{
4459 .tag = .constant,
4460 .attrs = decl_instance_attrs ++ .{
4461 .{ .linkage_name, .strp },
4462 .{ .type, .ref_addr },
4463 .{ .alignment, .udata },
4464 .{ .external, .flag },
4465 .{ .const_value, .block },
4466 },
4467 },
4468 .decl_instance_const_comptime_state = .{
4469 .tag = .constant,
4470 .attrs = decl_instance_attrs ++ .{
4471 .{ .linkage_name, .strp },
4472 .{ .type, .ref_addr },
4473 .{ .alignment, .udata },
4474 .{ .external, .flag },
4475 .{ .ZIG_comptime_value, .ref_addr },
4476 },
4477 },
4478 .decl_instance_const_runtime_bits_comptime_state = .{
4479 .tag = .constant,
4480 .attrs = decl_instance_attrs ++ .{
4481 .{ .linkage_name, .strp },
4482 .{ .type, .ref_addr },
4483 .{ .alignment, .udata },
4484 .{ .external, .flag },
4485 .{ .const_value, .block },
4486 .{ .ZIG_comptime_value, .ref_addr },
4487 },
4488 },
4489 .decl_instance_nullary_func = .{
4490 .tag = .subprogram,
4491 .attrs = decl_instance_attrs ++ .{
4492 .{ .linkage_name, .strp },
4493 .{ .type, .ref_addr },
4494 .{ .low_pc, .addr },
4495 .{ .high_pc, .data4 },
4496 .{ .alignment, .udata },
4497 .{ .external, .flag },
4498 .{ .noreturn, .flag },
4499 },
4500 },
4501 .decl_instance_func = .{
4502 .tag = .subprogram,
4503 .children = true,
4504 .attrs = decl_instance_attrs ++ .{
4505 .{ .linkage_name, .strp },
4506 .{ .type, .ref_addr },
4507 .{ .low_pc, .addr },
4508 .{ .high_pc, .data4 },
4509 .{ .alignment, .udata },
4510 .{ .external, .flag },
4511 .{ .noreturn, .flag },
4512 },
4513 },
4514 .decl_instance_nullary_func_generic = .{
4515 .tag = .subprogram,
4516 .attrs = decl_instance_attrs ++ .{
4517 .{ .type, .ref_addr },
4518 },
4519 },
4520 .decl_instance_func_generic = .{
4521 .tag = .subprogram,
4522 .children = true,
4523 .attrs = decl_instance_attrs ++ .{
4524 .{ .type, .ref_addr },
4525 },
4526 },
4527 .decl_instance_extern_nullary_func = .{
4528 .tag = .subprogram,
4529 .attrs = decl_instance_attrs ++ .{
4530 .{ .linkage_name, .strp },
4531 .{ .type, .ref_addr },
4532 .{ .low_pc, .addr },
4533 .{ .external, .flag_present },
4534 .{ .noreturn, .flag },
4535 },
4536 },
4537 .decl_instance_extern_func = .{
4538 .tag = .subprogram,
4539 .children = true,
4540 .attrs = decl_instance_attrs ++ .{
4541 .{ .linkage_name, .strp },
4542 .{ .type, .ref_addr },
4543 .{ .low_pc, .addr },
4544 .{ .external, .flag_present },
4545 .{ .noreturn, .flag },
4546 },
4547 },
4548 .compile_unit = .{
4549 .tag = .compile_unit,
4550 .children = true,
4551 .attrs = &.{
4552 .{ .language, .data1 },
4553 .{ .producer, .strp },
4554 .{ .comp_dir, .line_strp },
4555 .{ .name, .line_strp },
4556 .{ .base_types, .ref_addr },
4557 .{ .stmt_list, .sec_offset },
4558 .{ .rnglists_base, .sec_offset },
4559 .{ .ranges, .rnglistx },
4560 .{ .use_UTF8, .flag_present },
4561 },
4562 },
4563 .module = .{
4564 .tag = .module,
4565 .children = true,
4566 .attrs = &.{
4567 .{ .name, .strp },
4568 .{ .ranges, .rnglistx },
4569 },
4570 },
4571 .module_dependency = .{
4572 .tag = .imported_module,
4573 .attrs = &.{
4574 .{ .name, .strp },
4575 .{ .import, .ref_addr },
4576 },
4577 },
4578 .empty_file = .{
4579 .tag = .structure_type,
4580 .attrs = &.{
4581 .{ .decl_file, .udata },
4582 .{ .name, .strp },
4583 .{ .declaration, .flag },
4584 },
4585 },
4586 .file = .{
4587 .tag = .structure_type,
4588 .children = true,
4589 .attrs = &.{
4590 .{ .decl_file, .udata },
4591 .{ .name, .strp },
4592 .{ .byte_size, .udata },
4593 .{ .alignment, .udata },
4594 },
4595 },
4596 .access = .{
4597 .tag = .member,
4598 .attrs = &.{
4599 .{ .name, .strp },
4600 },
4601 },
4602 .enum_field = .{
4603 .tag = .enumerator,
4604 .attrs = &.{
4605 .{ .const_value, .indirect },
4606 .{ .name, .strp },
4607 },
4608 },
4609 .generated_field = .{
4610 .tag = .member,
4611 .attrs = &.{
4612 .{ .name, .strp },
4613 .{ .type, .ref_addr },
4614 .{ .data_member_location, .udata },
4615 .{ .artificial, .flag_present },
4616 },
4617 },
4618 .field = .{
4619 .tag = .member,
4620 .attrs = &.{
4621 .{ .name, .strp },
4622 .{ .type, .ref_addr },
4623 .{ .data_member_location, .udata },
4624 .{ .alignment, .udata },
4625 },
4626 },
4627 .field_default_fully_runtime = .{
4628 .tag = .member,
4629 .attrs = &.{
4630 .{ .name, .strp },
4631 .{ .type, .ref_addr },
4632 .{ .data_member_location, .udata },
4633 .{ .alignment, .udata },
4634 .{ .default_value, .block },
4635 },
4636 },
4637 .field_default_partially_comptime = .{
4638 .tag = .member,
4639 .attrs = &.{
4640 .{ .name, .strp },
4641 .{ .type, .ref_addr },
4642 .{ .data_member_location, .udata },
4643 .{ .alignment, .udata },
4644 .{ .default_value, .block },
4645 .{ .ZIG_comptime_value, .ref_addr },
4646 },
4647 },
4648 .field_default_fully_comptime = .{
4649 .tag = .member,
4650 .attrs = &.{
4651 .{ .name, .strp },
4652 .{ .type, .ref_addr },
4653 .{ .data_member_location, .udata },
4654 .{ .alignment, .udata },
4655 .{ .ZIG_comptime_value, .ref_addr },
4656 },
4657 },
4658 .field_comptime = .{
4659 .tag = .member,
4660 .attrs = &.{
4661 .{ .const_expr, .flag_present },
4662 .{ .name, .strp },
4663 .{ .type, .ref_addr },
4664 },
4665 },
4666 .field_comptime_fully_runtime = .{
4667 .tag = .member,
4668 .attrs = &.{
4669 .{ .const_expr, .flag_present },
4670 .{ .name, .strp },
4671 .{ .type, .ref_addr },
4672 .{ .const_value, .block },
4673 },
4674 },
4675 .field_comptime_partially_comptime = .{
4676 .tag = .member,
4677 .attrs = &.{
4678 .{ .const_expr, .flag_present },
4679 .{ .name, .strp },
4680 .{ .type, .ref_addr },
4681 .{ .const_value, .block },
4682 .{ .ZIG_comptime_value, .ref_addr },
4683 },
4684 },
4685 .field_comptime_fully_comptime = .{
4686 .tag = .member,
4687 .attrs = &.{
4688 .{ .const_expr, .flag_present },
4689 .{ .name, .strp },
4690 .{ .type, .ref_addr },
4691 .{ .ZIG_comptime_value, .ref_addr },
4692 },
4693 },
4694 .packed_field = .{
4695 .tag = .member,
4696 .attrs = &.{
4697 .{ .name, .strp },
4698 .{ .type, .ref_addr },
4699 .{ .data_bit_offset, .udata },
4700 },
4701 },
4702 .tagged_union = .{
4703 .tag = .variant_part,
4704 .children = true,
4705 .attrs = &.{
4706 .{ .discr, .ref_addr },
4707 },
4708 },
4709 .tagged_union_field = .{
4710 .tag = .variant,
4711 .children = true,
4712 .attrs = &.{
4713 .{ .discr_value, .indirect },
4714 },
4715 },
4716 .tagged_union_default_field = .{
4717 .tag = .variant,
4718 .children = true,
4719 },
4720 .void_type = .{
4721 .tag = .unspecified_type,
4722 .attrs = &.{
4723 .{ .name, .strp },
4724 },
4725 },
4726 .numeric_type = .{
4727 .tag = .base_type,
4728 .attrs = &.{
4729 .{ .name, .strp },
4730 .{ .encoding, .data1 },
4731 .{ .bit_size, .udata },
4732 .{ .byte_size, .udata },
4733 .{ .alignment, .udata },
4734 },
4735 },
4736 .inferred_error_set_type = .{
4737 .tag = .typedef,
4738 .attrs = &.{
4739 .{ .name, .strp },
4740 .{ .type, .ref_addr },
4741 },
4742 },
4743 .ptr_type = .{
4744 .tag = .pointer_type,
4745 .attrs = &.{
4746 .{ .name, .strp },
4747 .{ .address_class, .data1 },
4748 .{ .type, .ref_addr },
4749 },
4750 },
4751 .ptr_sentinel_type = .{
4752 .tag = .pointer_type,
4753 .attrs = &.{
4754 .{ .name, .strp },
4755 .{ .ZIG_sentinel, .block },
4756 .{ .address_class, .data1 },
4757 .{ .type, .ref_addr },
4758 },
4759 },
4760 .ptr_aligned_type = .{
4761 .tag = .pointer_type,
4762 .attrs = &.{
4763 .{ .name, .strp },
4764 .{ .alignment, .udata },
4765 .{ .address_class, .data1 },
4766 .{ .type, .ref_addr },
4767 },
4768 },
4769 .ptr_aligned_sentinel_type = .{
4770 .tag = .pointer_type,
4771 .attrs = &.{
4772 .{ .name, .strp },
4773 .{ .ZIG_sentinel, .block },
4774 .{ .alignment, .udata },
4775 .{ .address_class, .data1 },
4776 .{ .type, .ref_addr },
4777 },
4778 },
4779 .is_const = .{
4780 .tag = .const_type,
4781 .attrs = &.{
4782 .{ .type, .ref_addr },
4783 },
4784 },
4785 .is_volatile = .{
4786 .tag = .volatile_type,
4787 .attrs = &.{
4788 .{ .type, .ref_addr },
4789 },
4790 },
4791 .array_type = .{
4792 .tag = .array_type,
4793 .children = true,
4794 .attrs = &.{
4795 .{ .name, .strp },
4796 .{ .type, .ref_addr },
4797 },
4798 },
4799 .array_sentinel_type = .{
4800 .tag = .array_type,
4801 .children = true,
4802 .attrs = &.{
4803 .{ .name, .strp },
4804 .{ .ZIG_sentinel, .block },
4805 .{ .type, .ref_addr },
4806 },
4807 },
4808 .vector_type = .{
4809 .tag = .array_type,
4810 .children = true,
4811 .attrs = &.{
4812 .{ .name, .strp },
4813 .{ .type, .ref_addr },
4814 .{ .GNU_vector, .flag_present },
4815 },
4816 },
4817 .array_index = .{
4818 .tag = .subrange_type,
4819 .attrs = &.{
4820 .{ .lower_bound, .udata },
4821 },
4822 },
4823 .array_len = .{
4824 .tag = .subrange_type,
4825 .attrs = &.{
4826 .{ .type, .ref_addr },
4827 .{ .count, .udata },
4828 },
4829 },
4830 .nullary_func_type = .{
4831 .tag = .subroutine_type,
4832 .attrs = &.{
4833 .{ .name, .strp },
4834 .{ .calling_convention, .data1 },
4835 .{ .type, .ref_addr },
4836 },
4837 },
4838 .func_type = .{
4839 .tag = .subroutine_type,
4840 .children = true,
4841 .attrs = &.{
4842 .{ .name, .strp },
4843 .{ .calling_convention, .data1 },
4844 .{ .type, .ref_addr },
4845 },
4846 },
4847 .param = .{
4848 .tag = .formal_parameter,
4849 .attrs = &.{
4850 .{ .name, .strp },
4851 .{ .type, .ref_addr },
4852 },
4853 },
4854 .unnamed_param = .{
4855 .tag = .formal_parameter,
4856 .attrs = &.{
4857 .{ .type, .ref_addr },
4858 },
4859 },
4860 .is_var_args = .{
4861 .tag = .unspecified_parameters,
4862 },
4863 .generated_empty_enum_type = .{
4864 .tag = .enumeration_type,
4865 .attrs = &.{
4866 .{ .name, .strp },
4867 .{ .type, .ref_addr },
4868 },
4869 },
4870 .generated_enum_type = .{
4871 .tag = .enumeration_type,
4872 .children = true,
4873 .attrs = &.{
4874 .{ .name, .strp },
4875 .{ .type, .ref_addr },
4876 },
4877 },
4878 .generated_empty_struct_type = .{
4879 .tag = .structure_type,
4880 .attrs = &.{
4881 .{ .name, .strp },
4882 .{ .declaration, .flag },
4883 },
4884 },
4885 .generated_struct_type = .{
4886 .tag = .structure_type,
4887 .children = true,
4888 .attrs = &.{
4889 .{ .name, .strp },
4890 .{ .byte_size, .udata },
4891 .{ .alignment, .udata },
4892 },
4893 },
4894 .generated_union_type = .{
4895 .tag = .union_type,
4896 .children = true,
4897 .attrs = &.{
4898 .{ .name, .strp },
4899 .{ .byte_size, .udata },
4900 .{ .alignment, .udata },
4901 },
4902 },
4903 .capture_specification = .{
4904 .tag = .template_value_parameter,
4905 .attrs = &.{
4906 .{ .name, .strp },
4907 },
4908 },
4909 .comptime_capture = .{
4910 .tag = .template_value_parameter,
4911 .attrs = &.{
4912 .{ .type, .ref_addr },
4913 },
4914 },
4915 .comptime_capture_runtime = .{
4916 .tag = .template_value_parameter,
4917 .attrs = &.{
4918 .{ .type, .ref_addr },
4919 .{ .const_value, .block },
4920 },
4921 },
4922 .comptime_capture_partially_comptime = .{
4923 .tag = .template_value_parameter,
4924 .attrs = &.{
4925 .{ .type, .ref_addr },
4926 .{ .const_value, .block },
4927 .{ .ZIG_comptime_value, .ref_addr },
4928 },
4929 },
4930 .comptime_capture_fully_comptime = .{
4931 .tag = .template_value_parameter,
4932 .attrs = &.{
4933 .{ .type, .ref_addr },
4934 .{ .ZIG_comptime_value, .ref_addr },
4935 },
4936 },
4937 .runtime_capture = .{
4938 .tag = .template_type_parameter,
4939 .attrs = &.{
4940 .{ .type, .ref_addr },
4941 },
4942 },
4943 .nav_capture = .{
4944 .tag = .template_value_parameter,
4945 .attrs = &.{
4946 .{ .location, .exprloc },
4947 },
4948 },
4949 .builtin_extern_nullary_func = .{
4950 .tag = .subprogram,
4951 .attrs = &.{
4952 .{ .ZIG_parent, .ref_addr },
4953 .{ .linkage_name, .strp },
4954 .{ .type, .ref_addr },
4955 .{ .low_pc, .addr },
4956 .{ .external, .flag_present },
4957 .{ .noreturn, .flag },
4958 },
4959 },
4960 .builtin_extern_func = .{
4961 .tag = .subprogram,
4962 .children = true,
4963 .attrs = &.{
4964 .{ .ZIG_parent, .ref_addr },
4965 .{ .linkage_name, .strp },
4966 .{ .type, .ref_addr },
4967 .{ .low_pc, .addr },
4968 .{ .external, .flag_present },
4969 .{ .noreturn, .flag },
4970 },
4971 },
4972 .builtin_extern_var = .{
4973 .tag = .variable,
4974 .attrs = &.{
4975 .{ .ZIG_parent, .ref_addr },
4976 .{ .linkage_name, .strp },
4977 .{ .type, .ref_addr },
4978 .{ .location, .exprloc },
4979 .{ .external, .flag_present },
4980 },
4981 },
4982 .empty_block = .{
4983 .tag = .lexical_block,
4984 .attrs = &.{
4985 .{ .low_pc, .addr },
4986 .{ .high_pc, .data4 },
4987 },
4988 },
4989 .block = .{
4990 .tag = .lexical_block,
4991 .children = true,
4992 .attrs = &.{
4993 .{ .low_pc, .addr },
4994 .{ .high_pc, .data4 },
4995 },
4996 },
4997 .empty_inlined_func = .{
4998 .tag = .inlined_subroutine,
4999 .attrs = &.{
5000 .{ .abstract_origin, .ref_addr },
5001 .{ .ZIG_call_line_relative, .udata },
5002 .{ .call_column, .udata },
5003 .{ .low_pc, .addr },
5004 .{ .high_pc, .data4 },
5005 },
5006 },
5007 .inlined_func = .{
5008 .tag = .inlined_subroutine,
5009 .children = true,
5010 .attrs = &.{
5011 .{ .abstract_origin, .ref_addr },
5012 .{ .ZIG_call_line_relative, .udata },
5013 .{ .call_column, .udata },
5014 .{ .low_pc, .addr },
5015 .{ .high_pc, .data4 },
5016 },
5017 },
5018 .arg = .{
5019 .tag = .formal_parameter,
5020 .attrs = &.{
5021 .{ .name, .strp },
5022 .{ .type, .ref_addr },
5023 .{ .location, .exprloc },
5024 },
5025 },
5026 .unnamed_arg = .{
5027 .tag = .formal_parameter,
5028 .attrs = &.{
5029 .{ .type, .ref_addr },
5030 .{ .location, .exprloc },
5031 },
5032 },
5033 .comptime_arg = .{
5034 .tag = .formal_parameter,
5035 .attrs = &.{
5036 .{ .const_expr, .flag_present },
5037 .{ .name, .strp },
5038 .{ .type, .ref_addr },
5039 },
5040 },
5041 .comptime_arg_fully_runtime = .{
5042 .tag = .formal_parameter,
5043 .attrs = &.{
5044 .{ .const_expr, .flag_present },
5045 .{ .name, .strp },
5046 .{ .type, .ref_addr },
5047 .{ .const_value, .block },
5048 },
5049 },
5050 .comptime_arg_partially_comptime = .{
5051 .tag = .formal_parameter,
5052 .attrs = &.{
5053 .{ .const_expr, .flag_present },
5054 .{ .name, .strp },
5055 .{ .type, .ref_addr },
5056 .{ .const_value, .block },
5057 .{ .ZIG_comptime_value, .ref_addr },
5058 },
5059 },
5060 .comptime_arg_fully_comptime = .{
5061 .tag = .formal_parameter,
5062 .attrs = &.{
5063 .{ .const_expr, .flag_present },
5064 .{ .name, .strp },
5065 .{ .type, .ref_addr },
5066 .{ .ZIG_comptime_value, .ref_addr },
5067 },
5068 },
5069 .unnamed_comptime_arg = .{
5070 .tag = .formal_parameter,
5071 .attrs = &.{
5072 .{ .const_expr, .flag_present },
5073 .{ .type, .ref_addr },
5074 },
5075 },
5076 .unnamed_comptime_arg_fully_runtime = .{
5077 .tag = .formal_parameter,
5078 .attrs = &.{
5079 .{ .const_expr, .flag_present },
5080 .{ .type, .ref_addr },
5081 .{ .const_value, .block },
5082 },
5083 },
5084 .unnamed_comptime_arg_partially_comptime = .{
5085 .tag = .formal_parameter,
5086 .attrs = &.{
5087 .{ .const_expr, .flag_present },
5088 .{ .type, .ref_addr },
5089 .{ .const_value, .block },
5090 .{ .ZIG_comptime_value, .ref_addr },
5091 },
5092 },
5093 .unnamed_comptime_arg_fully_comptime = .{
5094 .tag = .formal_parameter,
5095 .attrs = &.{
5096 .{ .const_expr, .flag_present },
5097 .{ .type, .ref_addr },
5098 .{ .ZIG_comptime_value, .ref_addr },
5099 },
5100 },
5101 .extern_param = .{
5102 .tag = .formal_parameter,
5103 .attrs = &.{
5104 .{ .type, .ref_addr },
5105 },
5106 },
5107 .local_var = .{
5108 .tag = .variable,
5109 .attrs = &.{
5110 .{ .name, .strp },
5111 .{ .type, .ref_addr },
5112 .{ .location, .exprloc },
5113 },
5114 },
5115 .local_const = .{
5116 .tag = .constant,
5117 .attrs = &.{
5118 .{ .name, .strp },
5119 .{ .type, .ref_addr },
5120 },
5121 },
5122 .local_const_fully_runtime = .{
5123 .tag = .constant,
5124 .attrs = &.{
5125 .{ .name, .strp },
5126 .{ .type, .ref_addr },
5127 .{ .const_value, .block },
5128 },
5129 },
5130 .local_const_partially_comptime = .{
5131 .tag = .constant,
5132 .attrs = &.{
5133 .{ .name, .strp },
5134 .{ .type, .ref_addr },
5135 .{ .const_value, .block },
5136 .{ .ZIG_comptime_value, .ref_addr },
5137 },
5138 },
5139 .local_const_fully_comptime = .{
5140 .tag = .constant,
5141 .attrs = &.{
5142 .{ .name, .strp },
5143 .{ .type, .ref_addr },
5144 .{ .ZIG_comptime_value, .ref_addr },
5145 },
5146 },
5147 .undefined_comptime_value = .{
5148 .tag = .ZIG_comptime_value,
5149 .attrs = &.{
5150 .{ .type, .ref_addr },
5151 },
5152 },
5153 .aggregate_undefined_comptime_value = .{
5154 .tag = .ZIG_comptime_value,
5155 .children = true,
5156 .attrs = &.{
5157 .{ .type, .ref_addr },
5158 },
5159 },
5160 .comptime_value = .{
5161 .tag = .ZIG_comptime_value,
5162 .attrs = &.{
5163 .{ .type, .ref_addr },
5164 .{ .const_value, .indirect },
5165 },
5166 },
5167 .aggregate_comptime_value = .{
5168 .tag = .ZIG_comptime_value,
5169 .children = true,
5170 .attrs = &.{
5171 .{ .type, .ref_addr },
5172 .{ .const_value, .indirect },
5173 },
5174 },
5175 .location_comptime_value = .{
5176 .tag = .ZIG_comptime_value,
5177 .attrs = &.{
5178 .{ .type, .ref_addr },
5179 .{ .location, .exprloc },
5180 },
5181 },
5182 .aggregate_location_comptime_value = .{
5183 .tag = .ZIG_comptime_value,
5184 .children = true,
5185 .attrs = &.{
5186 .{ .type, .ref_addr },
5187 .{ .location, .exprloc },
5188 },
5189 },
5190 .comptime_value_field_runtime_bits = .{
5191 .tag = .member,
5192 .attrs = &.{
5193 .{ .name, .strp },
5194 .{ .const_value, .block },
5195 },
5196 },
5197 .comptime_value_field_comptime_state = .{
5198 .tag = .member,
5199 .attrs = &.{
5200 .{ .name, .strp },
5201 .{ .ZIG_comptime_value, .ref_addr },
5202 },
5203 },
5204 .comptime_value_elem_runtime_bits = .{
5205 .tag = .member,
5206 .attrs = &.{
5207 .{ .const_value, .block },
5208 },
5209 },
5210 .comptime_value_elem_comptime_state = .{
5211 .tag = .member,
5212 .attrs = &.{
5213 .{ .ZIG_comptime_value, .ref_addr },
5214 },
5215 },
5216 });
5217};
5218
5219pub fn uleb128Size(value: anytype) u32 {
5220 var buf: [std.atomic.cache_line]u8 = undefined;
5221 var dw: std.Io.Writer.Discarding = .init(&buf);
5222 dw.writer.writeUleb128(value) catch unreachable;
5223 return @intCast(dw.fullCount());
5224}
5225
5226pub fn sleb128Size(value: anytype) u32 {
5227 var buf: [std.atomic.cache_line]u8 = undefined;
5228 var dw: std.Io.Writer.Discarding = .init(&buf);
5229 dw.writer.writeSleb128(value) catch unreachable;
5230 return @intCast(dw.fullCount());
5231}
5232
5233const assert = std.debug.assert;
5234const codegen = @import("../codegen.zig");
5235const Compilation = @import("../Compilation.zig");
5236const dev = @import("../dev.zig");
5237const DW = std.dwarf;
5238const Dwarf = @This();
5239const InternPool = @import("../InternPool.zig");
5240const link = @import("../link.zig");
5241const log = std.log.scoped(.dwarf);
5242const Module = @import("../Module.zig");
5243const std = @import("std");
5244const target_info = @import("../target.zig");
5245const Type = @import("../Type.zig");
5246const Value = @import("../Value.zig");
5247const Zcu = @import("../Zcu.zig");