Function printUnbuffered [src]

Prototype

pub fn printUnbuffered( self: *Builder, backing_writer: anytype, ) (@TypeOf(backing_writer).Error || Allocator.Error)!void

Parameters

self: *Builder

Source

pub fn printUnbuffered( self: *Builder, backing_writer: anytype, ) (@TypeOf(backing_writer).Error || Allocator.Error)!void { const writer_with_errors = writerWithErrors(backing_writer, Allocator.Error); const writer = writer_with_errors.writer(); var need_newline = false; var metadata_formatter: Metadata.Formatter = .{ .builder = self, .need_comma = undefined }; defer metadata_formatter.map.deinit(self.gpa); if (self.source_filename != .none or self.data_layout != .none or self.target_triple != .none) { if (need_newline) try writer.writeByte('\n') else need_newline = true; if (self.source_filename != .none) try writer.print( \\; ModuleID = '{s}' \\source_filename = {"} \\ , .{ self.source_filename.slice(self).?, self.source_filename.fmt(self) }); if (self.data_layout != .none) try writer.print( \\target datalayout = {"} \\ , .{self.data_layout.fmt(self)}); if (self.target_triple != .none) try writer.print( \\target triple = {"} \\ , .{self.target_triple.fmt(self)}); } if (self.module_asm.items.len > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; var line_it = std.mem.tokenizeScalar(u8, self.module_asm.items, '\n'); while (line_it.next()) |line| { try writer.writeAll("module asm "); try printEscapedString(line, .always_quote, writer); try writer.writeByte('\n'); } } if (self.types.count() > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; for (self.types.keys(), self.types.values()) |id, ty| try writer.print( \\%{} = type {} \\ , .{ id.fmt(self), ty.fmt(self) }); } if (self.variables.items.len > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; for (self.variables.items) |variable| { if (variable.global.getReplacement(self) != .none) continue; const global = variable.global.ptrConst(self); metadata_formatter.need_comma = true; defer metadata_formatter.need_comma = undefined; try writer.print( \\{} ={}{}{}{}{ }{}{ }{} {s} {%}{ }{, }{} \\ , .{ variable.global.fmt(self), Linkage.fmtOptional(if (global.linkage == .external and variable.init != .no_init) null else global.linkage), global.preemption, global.visibility, global.dll_storage_class, variable.thread_local, global.unnamed_addr, global.addr_space, global.externally_initialized, @tagName(variable.mutability), global.type.fmt(self), variable.init.fmt(self), variable.alignment, try metadata_formatter.fmt("!dbg ", global.dbg), }); } } if (self.aliases.items.len > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; for (self.aliases.items) |alias| { if (alias.global.getReplacement(self) != .none) continue; const global = alias.global.ptrConst(self); metadata_formatter.need_comma = true; defer metadata_formatter.need_comma = undefined; try writer.print( \\{} ={}{}{}{}{ }{} alias {%}, {%}{} \\ , .{ alias.global.fmt(self), global.linkage, global.preemption, global.visibility, global.dll_storage_class, alias.thread_local, global.unnamed_addr, global.type.fmt(self), alias.aliasee.fmt(self), try metadata_formatter.fmt("!dbg ", global.dbg), }); } } var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .empty; defer attribute_groups.deinit(self.gpa); for (0.., self.functions.items) |function_i, function| { if (function.global.getReplacement(self) != .none) continue; if (need_newline) try writer.writeByte('\n') else need_newline = true; const function_index: Function.Index = @enumFromInt(function_i); const global = function.global.ptrConst(self); const params_len = global.type.functionParameters(self).len; const function_attributes = function.attributes.func(self); if (function_attributes != .none) try writer.print( \\; Function Attrs:{} \\ , .{function_attributes.fmt(self)}); try writer.print( \\{s}{}{}{}{}{}{"} {%} {}( , .{ if (function.instructions.len > 0) "define" else "declare", global.linkage, global.preemption, global.visibility, global.dll_storage_class, function.call_conv, function.attributes.ret(self).fmt(self), global.type.functionReturn(self).fmt(self), function.global.fmt(self), }); for (0..params_len) |arg| { if (arg > 0) try writer.writeAll(", "); try writer.print( \\{%}{"} , .{ global.type.functionParameters(self)[arg].fmt(self), function.attributes.param(arg, self).fmt(self), }); if (function.instructions.len > 0) try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)}) else try writer.print(" %{d}", .{arg}); } switch (global.type.functionKind(self)) { .normal => {}, .vararg => { if (params_len > 0) try writer.writeAll(", "); try writer.writeAll("..."); }, } try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space }); if (function_attributes != .none) try writer.print(" #{d}", .{ (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index, }); { metadata_formatter.need_comma = false; defer metadata_formatter.need_comma = undefined; try writer.print("{ }{}", .{ function.alignment, try metadata_formatter.fmt(" !dbg ", global.dbg), }); } if (function.instructions.len > 0) { var block_incoming_len: u32 = undefined; try writer.writeAll(" {\n"); var maybe_dbg_index: ?u32 = null; for (params_len..function.instructions.len) |instruction_i| { const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i); const instruction = function.instructions.get(@intFromEnum(instruction_index)); if (function.debug_locations.get(instruction_index)) |debug_location| switch (debug_location) { .no_location => maybe_dbg_index = null, .location => |location| { const gop = try metadata_formatter.map.getOrPut(self.gpa, .{ .debug_location = location, }); maybe_dbg_index = @intCast(gop.index); }, }; switch (instruction.tag) { .add, .@"add nsw", .@"add nuw", .@"add nuw nsw", .@"and", .ashr, .@"ashr exact", .fadd, .@"fadd fast", .@"fcmp false", .@"fcmp fast false", .@"fcmp fast oeq", .@"fcmp fast oge", .@"fcmp fast ogt", .@"fcmp fast ole", .@"fcmp fast olt", .@"fcmp fast one", .@"fcmp fast ord", .@"fcmp fast true", .@"fcmp fast ueq", .@"fcmp fast uge", .@"fcmp fast ugt", .@"fcmp fast ule", .@"fcmp fast ult", .@"fcmp fast une", .@"fcmp fast uno", .@"fcmp oeq", .@"fcmp oge", .@"fcmp ogt", .@"fcmp ole", .@"fcmp olt", .@"fcmp one", .@"fcmp ord", .@"fcmp true", .@"fcmp ueq", .@"fcmp uge", .@"fcmp ugt", .@"fcmp ule", .@"fcmp ult", .@"fcmp une", .@"fcmp uno", .fdiv, .@"fdiv fast", .fmul, .@"fmul fast", .frem, .@"frem fast", .fsub, .@"fsub fast", .@"icmp eq", .@"icmp ne", .@"icmp sge", .@"icmp sgt", .@"icmp sle", .@"icmp slt", .@"icmp uge", .@"icmp ugt", .@"icmp ule", .@"icmp ult", .lshr, .@"lshr exact", .mul, .@"mul nsw", .@"mul nuw", .@"mul nuw nsw", .@"or", .sdiv, .@"sdiv exact", .srem, .shl, .@"shl nsw", .@"shl nuw", .@"shl nuw nsw", .sub, .@"sub nsw", .@"sub nuw", .@"sub nuw nsw", .udiv, .@"udiv exact", .urem, .xor, => |tag| { const extra = function.extraData(Function.Instruction.Binary, instruction.data); try writer.print(" %{} = {s} {%}, {}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.lhs.fmt(function_index, self), extra.rhs.fmt(function_index, self), }); }, .addrspacecast, .bitcast, .fpext, .fptosi, .fptoui, .fptrunc, .inttoptr, .ptrtoint, .sext, .sitofp, .trunc, .uitofp, .zext, => |tag| { const extra = function.extraData(Function.Instruction.Cast, instruction.data); try writer.print(" %{} = {s} {%} to {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.val.fmt(function_index, self), extra.type.fmt(self), }); }, .alloca, .@"alloca inalloca", => |tag| { const extra = function.extraData(Function.Instruction.Alloca, instruction.data); try writer.print(" %{} = {s} {%}{,%}{, }{, }", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.type.fmt(self), Value.fmt(switch (extra.len) { .@"1" => .none, else => extra.len, }, function_index, self), extra.info.alignment, extra.info.addr_space, }); }, .arg => unreachable, .atomicrmw => |tag| { const extra = function.extraData(Function.Instruction.AtomicRmw, instruction.data); try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.info.access_kind, @tagName(extra.info.atomic_rmw_operation), extra.ptr.fmt(function_index, self), extra.val.fmt(function_index, self), extra.info.sync_scope, extra.info.success_ordering, extra.info.alignment, }); }, .block => { block_incoming_len = instruction.data; const name = instruction_index.name(&function); if (@intFromEnum(instruction_index) > params_len) try writer.writeByte('\n'); try writer.print("{}:\n", .{name.fmt(self)}); continue; }, .br => |tag| { const target: Function.Block.Index = @enumFromInt(instruction.data); try writer.print(" {s} {%}", .{ @tagName(tag), target.toInst(&function).fmt(function_index, self), }); }, .br_cond => { const extra = function.extraData(Function.Instruction.BrCond, instruction.data); try writer.print(" br {%}, {%}, {%}", .{ extra.cond.fmt(function_index, self), extra.then.toInst(&function).fmt(function_index, self), extra.@"else".toInst(&function).fmt(function_index, self), }); metadata_formatter.need_comma = true; defer metadata_formatter.need_comma = undefined; switch (extra.weights) { .none => {}, .unpredictable => try writer.writeAll("!unpredictable !{}"), _ => try writer.print("{}", .{ try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.weights)))), }), } }, .call, .@"call fast", .@"musttail call", .@"musttail call fast", .@"notail call", .@"notail call fast", .@"tail call", .@"tail call fast", => |tag| { var extra = function.extraDataTrail(Function.Instruction.Call, instruction.data); const args = extra.trail.next(extra.data.args_len, Value, &function); try writer.writeAll(" "); const ret_ty = extra.data.ty.functionReturn(self); switch (ret_ty) { .void => {}, else => try writer.print("%{} = ", .{ instruction_index.name(&function).fmt(self), }), .none => unreachable, } try writer.print("{s}{}{}{} {%} {}(", .{ @tagName(tag), extra.data.info.call_conv, extra.data.attributes.ret(self).fmt(self), extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self), switch (extra.data.ty.functionKind(self)) { .normal => ret_ty, .vararg => extra.data.ty, }.fmt(self), extra.data.callee.fmt(function_index, self), }); for (0.., args) |arg_index, arg| { if (arg_index > 0) try writer.writeAll(", "); metadata_formatter.need_comma = false; defer metadata_formatter.need_comma = undefined; try writer.print("{%}{}{}", .{ arg.typeOf(function_index, self).fmt(self), extra.data.attributes.param(arg_index, self).fmt(self), try metadata_formatter.fmtLocal(" ", arg, function_index), }); } try writer.writeByte(')'); if (extra.data.info.has_op_bundle_cold) { try writer.writeAll(" [ \"cold\"() ]"); } const call_function_attributes = extra.data.attributes.func(self); if (call_function_attributes != .none) try writer.print(" #{d}", .{ (try attribute_groups.getOrPutValue( self.gpa, call_function_attributes, {}, )).index, }); }, .cmpxchg, .@"cmpxchg weak", => |tag| { const extra = function.extraData(Function.Instruction.CmpXchg, instruction.data); try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.info.access_kind, extra.ptr.fmt(function_index, self), extra.cmp.fmt(function_index, self), extra.new.fmt(function_index, self), extra.info.sync_scope, extra.info.success_ordering, extra.info.failure_ordering, extra.info.alignment, }); }, .extractelement => |tag| { const extra = function.extraData(Function.Instruction.ExtractElement, instruction.data); try writer.print(" %{} = {s} {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.val.fmt(function_index, self), extra.index.fmt(function_index, self), }); }, .extractvalue => |tag| { var extra = function.extraDataTrail( Function.Instruction.ExtractValue, instruction.data, ); const indices = extra.trail.next(extra.data.indices_len, u32, &function); try writer.print(" %{} = {s} {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.data.val.fmt(function_index, self), }); for (indices) |index| try writer.print(", {d}", .{index}); }, .fence => |tag| { const info: MemoryAccessInfo = @bitCast(instruction.data); try writer.print(" {s}{ }{ }", .{ @tagName(tag), info.sync_scope, info.success_ordering, }); }, .fneg, .@"fneg fast", => |tag| { const val: Value = @enumFromInt(instruction.data); try writer.print(" %{} = {s} {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), val.fmt(function_index, self), }); }, .getelementptr, .@"getelementptr inbounds", => |tag| { var extra = function.extraDataTrail( Function.Instruction.GetElementPtr, instruction.data, ); const indices = extra.trail.next(extra.data.indices_len, Value, &function); try writer.print(" %{} = {s} {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.data.type.fmt(self), extra.data.base.fmt(function_index, self), }); for (indices) |index| try writer.print(", {%}", .{ index.fmt(function_index, self), }); }, .indirectbr => |tag| { var extra = function.extraDataTrail(Function.Instruction.IndirectBr, instruction.data); const targets = extra.trail.next(extra.data.targets_len, Function.Block.Index, &function); try writer.print(" {s} {%}, [", .{ @tagName(tag), extra.data.addr.fmt(function_index, self), }); for (0.., targets) |target_index, target| { if (target_index > 0) try writer.writeAll(", "); try writer.print("{%}", .{ target.toInst(&function).fmt(function_index, self), }); } try writer.writeByte(']'); }, .insertelement => |tag| { const extra = function.extraData(Function.Instruction.InsertElement, instruction.data); try writer.print(" %{} = {s} {%}, {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.val.fmt(function_index, self), extra.elem.fmt(function_index, self), extra.index.fmt(function_index, self), }); }, .insertvalue => |tag| { var extra = function.extraDataTrail(Function.Instruction.InsertValue, instruction.data); const indices = extra.trail.next(extra.data.indices_len, u32, &function); try writer.print(" %{} = {s} {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.data.val.fmt(function_index, self), extra.data.elem.fmt(function_index, self), }); for (indices) |index| try writer.print(", {d}", .{index}); }, .load, .@"load atomic", => |tag| { const extra = function.extraData(Function.Instruction.Load, instruction.data); try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.info.access_kind, extra.type.fmt(self), extra.ptr.fmt(function_index, self), extra.info.sync_scope, extra.info.success_ordering, extra.info.alignment, }); }, .phi, .@"phi fast", => |tag| { var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data); const vals = extra.trail.next(block_incoming_len, Value, &function); const blocks = extra.trail.next(block_incoming_len, Function.Block.Index, &function); try writer.print(" %{} = {s} {%} ", .{ instruction_index.name(&function).fmt(self), @tagName(tag), vals[0].typeOf(function_index, self).fmt(self), }); for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| { if (incoming_index > 0) try writer.writeAll(", "); try writer.print("[ {}, {} ]", .{ incoming_val.fmt(function_index, self), incoming_block.toInst(&function).fmt(function_index, self), }); } }, .ret => |tag| { const val: Value = @enumFromInt(instruction.data); try writer.print(" {s} {%}", .{ @tagName(tag), val.fmt(function_index, self), }); }, .@"ret void", .@"unreachable", => |tag| try writer.print(" {s}", .{@tagName(tag)}), .select, .@"select fast", => |tag| { const extra = function.extraData(Function.Instruction.Select, instruction.data); try writer.print(" %{} = {s} {%}, {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.cond.fmt(function_index, self), extra.lhs.fmt(function_index, self), extra.rhs.fmt(function_index, self), }); }, .shufflevector => |tag| { const extra = function.extraData(Function.Instruction.ShuffleVector, instruction.data); try writer.print(" %{} = {s} {%}, {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.lhs.fmt(function_index, self), extra.rhs.fmt(function_index, self), extra.mask.fmt(function_index, self), }); }, .store, .@"store atomic", => |tag| { const extra = function.extraData(Function.Instruction.Store, instruction.data); try writer.print(" {s}{ } {%}, {%}{ }{ }{, }", .{ @tagName(tag), extra.info.access_kind, extra.val.fmt(function_index, self), extra.ptr.fmt(function_index, self), extra.info.sync_scope, extra.info.success_ordering, extra.info.alignment, }); }, .@"switch" => |tag| { var extra = function.extraDataTrail(Function.Instruction.Switch, instruction.data); const vals = extra.trail.next(extra.data.cases_len, Constant, &function); const blocks = extra.trail.next(extra.data.cases_len, Function.Block.Index, &function); try writer.print(" {s} {%}, {%} [\n", .{ @tagName(tag), extra.data.val.fmt(function_index, self), extra.data.default.toInst(&function).fmt(function_index, self), }); for (vals, blocks) |case_val, case_block| try writer.print( " {%}, {%}\n", .{ case_val.fmt(self), case_block.toInst(&function).fmt(function_index, self), }, ); try writer.writeAll(" ]"); metadata_formatter.need_comma = true; defer metadata_formatter.need_comma = undefined; switch (extra.data.weights) { .none => {}, .unpredictable => try writer.writeAll("!unpredictable !{}"), _ => try writer.print("{}", .{ try metadata_formatter.fmt("!prof ", @as(Metadata, @enumFromInt(@intFromEnum(extra.data.weights)))), }), } }, .va_arg => |tag| { const extra = function.extraData(Function.Instruction.VaArg, instruction.data); try writer.print(" %{} = {s} {%}, {%}", .{ instruction_index.name(&function).fmt(self), @tagName(tag), extra.list.fmt(function_index, self), extra.type.fmt(self), }); }, } if (maybe_dbg_index) |dbg_index| { try writer.print(", !dbg !{}", .{dbg_index}); } try writer.writeByte('\n'); } try writer.writeByte('}'); } try writer.writeByte('\n'); } if (attribute_groups.count() > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; for (0.., attribute_groups.keys()) |attribute_group_index, attribute_group| try writer.print( \\attributes #{d} = {{{#"} }} \\ , .{ attribute_group_index, attribute_group.fmt(self) }); } if (self.metadata_named.count() > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; for (self.metadata_named.keys(), self.metadata_named.values()) |name, data| { const elements: []const Metadata = @ptrCast(self.metadata_extra.items[data.index..][0..data.len]); try writer.writeByte('!'); try printEscapedString(name.slice(self), .quote_unless_valid_identifier, writer); try writer.writeAll(" = !{"); metadata_formatter.need_comma = false; defer metadata_formatter.need_comma = undefined; for (elements) |element| try writer.print("{}", .{try metadata_formatter.fmt("", element)}); try writer.writeAll("}\n"); } } if (metadata_formatter.map.count() > 0) { if (need_newline) try writer.writeByte('\n') else need_newline = true; var metadata_index: usize = 0; while (metadata_index < metadata_formatter.map.count()) : (metadata_index += 1) { @setEvalBranchQuota(10_000); try writer.print("!{} = ", .{metadata_index}); metadata_formatter.need_comma = false; defer metadata_formatter.need_comma = undefined; const key = metadata_formatter.map.keys()[metadata_index]; const metadata_item = switch (key) { .debug_location => |location| { try metadata_formatter.specialized(.@"!", .DILocation, .{ .line = location.line, .column = location.column, .scope = location.scope, .inlinedAt = location.inlined_at, .isImplicitCode = false, }, writer); continue; }, .metadata => |metadata| self.metadata_items.get(@intFromEnum(metadata)), }; switch (metadata_item.tag) { .none, .expression, .constant => unreachable, .file => { const extra = self.metadataExtraData(Metadata.File, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIFile, .{ .filename = extra.filename, .directory = extra.directory, .checksumkind = null, .checksum = null, .source = null, }, writer); }, .compile_unit, .@"compile_unit optimized", => |kind| { const extra = self.metadataExtraData(Metadata.CompileUnit, metadata_item.data); try metadata_formatter.specialized(.@"distinct !", .DICompileUnit, .{ .language = .DW_LANG_C99, .file = extra.file, .producer = extra.producer, .isOptimized = switch (kind) { .compile_unit => false, .@"compile_unit optimized" => true, else => unreachable, }, .flags = null, .runtimeVersion = 0, .splitDebugFilename = null, .emissionKind = .FullDebug, .enums = extra.enums, .retainedTypes = null, .globals = extra.globals, .imports = null, .macros = null, .dwoId = null, .splitDebugInlining = false, .debugInfoForProfiling = null, .nameTableKind = null, .rangesBaseAddress = null, .sysroot = null, .sdk = null, }, writer); }, .subprogram, .@"subprogram local", .@"subprogram definition", .@"subprogram local definition", .@"subprogram optimized", .@"subprogram optimized local", .@"subprogram optimized definition", .@"subprogram optimized local definition", => |kind| { const extra = self.metadataExtraData(Metadata.Subprogram, metadata_item.data); try metadata_formatter.specialized(.@"distinct !", .DISubprogram, .{ .name = extra.name, .linkageName = extra.linkage_name, .scope = extra.file, .file = extra.file, .line = extra.line, .type = extra.ty, .scopeLine = extra.scope_line, .containingType = null, .virtualIndex = null, .thisAdjustment = null, .flags = extra.di_flags, .spFlags = @as(Metadata.Subprogram.DISPFlags, @bitCast(@as(u32, @as(u3, @intCast( @intFromEnum(kind) - @intFromEnum(Metadata.Tag.subprogram), ))) << 2)), .unit = extra.compile_unit, .templateParams = null, .declaration = null, .retainedNodes = null, .thrownTypes = null, .annotations = null, .targetFuncName = null, }, writer); }, .lexical_block => { const extra = self.metadataExtraData(Metadata.LexicalBlock, metadata_item.data); try metadata_formatter.specialized(.@"distinct !", .DILexicalBlock, .{ .scope = extra.scope, .file = extra.file, .line = extra.line, .column = extra.column, }, writer); }, .location => { const extra = self.metadataExtraData(Metadata.Location, metadata_item.data); try metadata_formatter.specialized(.@"!", .DILocation, .{ .line = extra.line, .column = extra.column, .scope = extra.scope, .inlinedAt = extra.inlined_at, .isImplicitCode = false, }, writer); }, .basic_bool_type, .basic_unsigned_type, .basic_signed_type, .basic_float_type, => |kind| { const extra = self.metadataExtraData(Metadata.BasicType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIBasicType, .{ .tag = null, .name = switch (extra.name) { .none => null, else => extra.name, }, .size = extra.bitSize(), .@"align" = null, .encoding = @as(enum { DW_ATE_boolean, DW_ATE_unsigned, DW_ATE_signed, DW_ATE_float, }, switch (kind) { .basic_bool_type => .DW_ATE_boolean, .basic_unsigned_type => .DW_ATE_unsigned, .basic_signed_type => .DW_ATE_signed, .basic_float_type => .DW_ATE_float, else => unreachable, }), .flags = null, }, writer); }, .composite_struct_type, .composite_union_type, .composite_enumeration_type, .composite_array_type, .composite_vector_type, => |kind| { const extra = self.metadataExtraData(Metadata.CompositeType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DICompositeType, .{ .tag = @as(enum { DW_TAG_structure_type, DW_TAG_union_type, DW_TAG_enumeration_type, DW_TAG_array_type, }, switch (kind) { .composite_struct_type => .DW_TAG_structure_type, .composite_union_type => .DW_TAG_union_type, .composite_enumeration_type => .DW_TAG_enumeration_type, .composite_array_type, .composite_vector_type => .DW_TAG_array_type, else => unreachable, }), .name = switch (extra.name) { .none => null, else => extra.name, }, .scope = extra.scope, .file = null, .line = null, .baseType = extra.underlying_type, .size = extra.bitSize(), .@"align" = extra.bitAlign(), .offset = null, .flags = null, .elements = extra.fields_tuple, .runtimeLang = null, .vtableHolder = null, .templateParams = null, .identifier = null, .discriminator = null, .dataLocation = null, .associated = null, .allocated = null, .rank = null, .annotations = null, }, writer); }, .derived_pointer_type, .derived_member_type, => |kind| { const extra = self.metadataExtraData(Metadata.DerivedType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIDerivedType, .{ .tag = @as(enum { DW_TAG_pointer_type, DW_TAG_member, }, switch (kind) { .derived_pointer_type => .DW_TAG_pointer_type, .derived_member_type => .DW_TAG_member, else => unreachable, }), .name = switch (extra.name) { .none => null, else => extra.name, }, .scope = extra.scope, .file = null, .line = null, .baseType = extra.underlying_type, .size = extra.bitSize(), .@"align" = extra.bitAlign(), .offset = switch (extra.bitOffset()) { 0 => null, else => |bit_offset| bit_offset, }, .flags = null, .extraData = null, .dwarfAddressSpace = null, .annotations = null, }, writer); }, .subroutine_type => { const extra = self.metadataExtraData(Metadata.SubroutineType, metadata_item.data); try metadata_formatter.specialized(.@"!", .DISubroutineType, .{ .flags = null, .cc = null, .types = extra.types_tuple, }, writer); }, .enumerator_unsigned, .enumerator_signed_positive, .enumerator_signed_negative, => |kind| { const extra = self.metadataExtraData(Metadata.Enumerator, metadata_item.data); const ExpectedContents = extern struct { const expected_limbs = @divExact(512, @bitSizeOf(std.math.big.Limb)); string: [ (std.math.big.int.Const{ .limbs = &([1]std.math.big.Limb{ std.math.maxInt(std.math.big.Limb), } ** expected_limbs), .positive = false, }).sizeInBaseUpperBound(10) ]u8, limbs: [ std.math.big.int.calcToStringLimbsBufferLen(expected_limbs, 10) ]std.math.big.Limb, }; var stack align(@alignOf(ExpectedContents)) = std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa); const allocator = stack.get(); const limbs = self.metadata_limbs.items[extra.limbs_index..][0..extra.limbs_len]; const bigint: std.math.big.int.Const = .{ .limbs = limbs, .positive = switch (kind) { .enumerator_unsigned, .enumerator_signed_positive, => true, .enumerator_signed_negative => false, else => unreachable, }, }; const str = try bigint.toStringAlloc(allocator, 10, undefined); defer allocator.free(str); try metadata_formatter.specialized(.@"!", .DIEnumerator, .{ .name = extra.name, .value = str, .isUnsigned = switch (kind) { .enumerator_unsigned => true, .enumerator_signed_positive, .enumerator_signed_negative, => false, else => unreachable, }, }, writer); }, .subrange => { const extra = self.metadataExtraData(Metadata.Subrange, metadata_item.data); try metadata_formatter.specialized(.@"!", .DISubrange, .{ .count = extra.count, .lowerBound = extra.lower_bound, .upperBound = null, .stride = null, }, writer); }, .tuple => { var extra = self.metadataExtraDataTrail(Metadata.Tuple, metadata_item.data); const elements = extra.trail.next(extra.data.elements_len, Metadata, self); try writer.writeAll("!{"); for (elements) |element| try writer.print("{[element]%}", .{ .element = try metadata_formatter.fmt("", element), }); try writer.writeAll("}\n"); }, .str_tuple => { var extra = self.metadataExtraDataTrail(Metadata.StrTuple, metadata_item.data); const elements = extra.trail.next(extra.data.elements_len, Metadata, self); try writer.print("!{{{[str]%}", .{ .str = try metadata_formatter.fmt("", extra.data.str), }); for (elements) |element| try writer.print("{[element]%}", .{ .element = try metadata_formatter.fmt("", element), }); try writer.writeAll("}\n"); }, .module_flag => { const extra = self.metadataExtraData(Metadata.ModuleFlag, metadata_item.data); try writer.print("!{{{[behavior]%}{[name]%}{[constant]%}}}\n", .{ .behavior = try metadata_formatter.fmt("", extra.behavior), .name = try metadata_formatter.fmt("", extra.name), .constant = try metadata_formatter.fmt("", extra.constant), }); }, .local_var => { const extra = self.metadataExtraData(Metadata.LocalVar, metadata_item.data); try metadata_formatter.specialized(.@"!", .DILocalVariable, .{ .name = extra.name, .arg = null, .scope = extra.scope, .file = extra.file, .line = extra.line, .type = extra.ty, .flags = null, .@"align" = null, .annotations = null, }, writer); }, .parameter => { const extra = self.metadataExtraData(Metadata.Parameter, metadata_item.data); try metadata_formatter.specialized(.@"!", .DILocalVariable, .{ .name = extra.name, .arg = extra.arg_no, .scope = extra.scope, .file = extra.file, .line = extra.line, .type = extra.ty, .flags = null, .@"align" = null, .annotations = null, }, writer); }, .global_var, .@"global_var local", => |kind| { const extra = self.metadataExtraData(Metadata.GlobalVar, metadata_item.data); try metadata_formatter.specialized(.@"distinct !", .DIGlobalVariable, .{ .name = extra.name, .linkageName = extra.linkage_name, .scope = extra.scope, .file = extra.file, .line = extra.line, .type = extra.ty, .isLocal = switch (kind) { .global_var => false, .@"global_var local" => true, else => unreachable, }, .isDefinition = true, .declaration = null, .templateParams = null, .@"align" = null, .annotations = null, }, writer); }, .global_var_expression => { const extra = self.metadataExtraData(Metadata.GlobalVarExpression, metadata_item.data); try metadata_formatter.specialized(.@"!", .DIGlobalVariableExpression, .{ .@"var" = extra.variable, .expr = extra.expression, }, writer); }, } } } }