diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index 17d2e9e09b..ed40dc3521 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -562,82 +562,3 @@ fn addMessage(d: *Diagnostics, msg: Message) Compilation.Error!void { }, } } - -const ErrorBundle = std.zig.ErrorBundle; - -pub fn toErrorBundle( - d: *const Diagnostics, - gpa: std.mem.Allocator, - fail_msg: ?[]const u8, -) !ErrorBundle { - @branchHint(.cold); - - var bundle: ErrorBundle.Wip = undefined; - try bundle.init(gpa); - errdefer bundle.deinit(); - - if (fail_msg) |msg| { - try bundle.addRootErrorMessage(.{ - .msg = try bundle.addString(msg), - }); - } - - var cur_err: ?ErrorBundle.ErrorMessage = null; - var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty; - defer cur_notes.deinit(gpa); - for (d.output.to_list.messages.items) |msg| { - switch (msg.kind) { - .off, .warning => { - if (cur_err) |err| { - try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); - // Clear the current error so that notes don't bleed into unassociated errors - cur_err = null; - } - continue; - }, - .note => if (cur_err == null) continue, - .@"fatal error", .@"error" => {}, - } - - const src_loc = src_loc: { - if (msg.location) |location| { - break :src_loc try bundle.addSourceLocation(.{ - .src_path = try bundle.addString(location.path), - .line = location.line_no - 1, // 1-based -> 0-based - .column = location.col - 1, // 1-based -> 0-based - .span_start = location.width, - .span_main = location.width, - .span_end = location.width, - .source_line = try bundle.addString(location.line), - }); - } - break :src_loc ErrorBundle.SourceLocationIndex.none; - }; - - switch (msg.kind) { - .@"fatal error", .@"error" => { - if (cur_err) |err| { - try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); - } - cur_err = .{ - .msg = try bundle.addString(msg.text), - .src_loc = src_loc, - }; - cur_notes.clearRetainingCapacity(); - }, - .note => { - cur_err.?.notes_len += 1; - try cur_notes.append(gpa, .{ - .msg = try bundle.addString(msg.text), - .src_loc = src_loc, - }); - }, - .off, .warning => unreachable, - } - } - if (cur_err) |err| { - try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); - } - - return try bundle.toOwnedBundle(""); -} diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index a0b4353a9f..ce8532ae9f 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -13,6 +13,7 @@ const cvtres = @import("cvtres.zig"); const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage; const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType; const aro = @import("aro"); +const compiler_util = @import("../util.zig"); pub fn main() !void { var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init; @@ -671,7 +672,11 @@ const ErrorHandler = union(enum) { ) !void { switch (self.*) { .server => |*server| { - var error_bundle = try comp.diagnostics.toErrorBundle(allocator, fail_msg); + var error_bundle = try compiler_util.aroDiagnosticsToErrorBundle( + comp.diagnostics, + allocator, + fail_msg, + ); defer error_bundle.deinit(allocator); try server.serveErrorBundle(error_bundle); diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index bdf776af56..3a3fd7577e 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -3,6 +3,7 @@ const assert = std.debug.assert; const mem = std.mem; const process = std.process; const aro = @import("aro"); +const compiler_util = @import("../util.zig"); const Translator = @import("Translator.zig"); const fast_exit = @import("builtin").mode != .Debug; @@ -88,7 +89,11 @@ pub fn main() u8 { } fn serveErrorBundle(arena: std.mem.Allocator, diagnostics: *const aro.Diagnostics) !void { - const error_bundle = try diagnostics.toErrorBundle(arena, "translation failure"); + const error_bundle = try compiler_util.aroDiagnosticsToErrorBundle( + diagnostics, + arena, + "translation failure", + ); var stdout_buffer: [1024]u8 = undefined; var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); var server: std.zig.Server = .{ diff --git a/lib/compiler/util.zig b/lib/compiler/util.zig new file mode 100644 index 0000000000..63a078cead --- /dev/null +++ b/lib/compiler/util.zig @@ -0,0 +1,81 @@ +//! Utilities shared between compiler sub-commands +const std = @import("std"); +const aro = @import("aro"); +const ErrorBundle = std.zig.ErrorBundle; + +pub fn aroDiagnosticsToErrorBundle( + d: *const aro.Diagnostics, + gpa: std.mem.Allocator, + fail_msg: ?[]const u8, +) !ErrorBundle { + @branchHint(.cold); + + var bundle: ErrorBundle.Wip = undefined; + try bundle.init(gpa); + errdefer bundle.deinit(); + + if (fail_msg) |msg| { + try bundle.addRootErrorMessage(.{ + .msg = try bundle.addString(msg), + }); + } + + var cur_err: ?ErrorBundle.ErrorMessage = null; + var cur_notes: std.ArrayList(ErrorBundle.ErrorMessage) = .empty; + defer cur_notes.deinit(gpa); + for (d.output.to_list.messages.items) |msg| { + switch (msg.kind) { + .off, .warning => { + if (cur_err) |err| { + try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); + // Clear the current error so that notes don't bleed into unassociated errors + cur_err = null; + } + continue; + }, + .note => if (cur_err == null) continue, + .@"fatal error", .@"error" => {}, + } + + const src_loc = src_loc: { + if (msg.location) |location| { + break :src_loc try bundle.addSourceLocation(.{ + .src_path = try bundle.addString(location.path), + .line = location.line_no - 1, // 1-based -> 0-based + .column = location.col - 1, // 1-based -> 0-based + .span_start = location.width, + .span_main = location.width, + .span_end = location.width, + .source_line = try bundle.addString(location.line), + }); + } + break :src_loc ErrorBundle.SourceLocationIndex.none; + }; + + switch (msg.kind) { + .@"fatal error", .@"error" => { + if (cur_err) |err| { + try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); + } + cur_err = .{ + .msg = try bundle.addString(msg.text), + .src_loc = src_loc, + }; + cur_notes.clearRetainingCapacity(); + }, + .note => { + cur_err.?.notes_len += 1; + try cur_notes.append(gpa, .{ + .msg = try bundle.addString(msg.text), + .src_loc = src_loc, + }); + }, + .off, .warning => unreachable, + } + } + if (cur_err) |err| { + try bundle.addRootErrorMessageWithNotes(err, cur_notes.items); + } + + return try bundle.toOwnedBundle(""); +}