authorgravatar for techatrix@mailbox.orgTechatrix <techatrix@mailbox.org> 2023-09-25 04:54:07+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-09-25 18:10:44+03:00
log2adb932ad6ee4ff3d3c640cb8fb7bf7db0ff5d74
tree805211006b5f7e83115a641ca4fd358b0bcccadf
parente7bf143b364f004a76e86cad5fd3256fa87761e4

translate-c: convert clang errors messages into `std.zig.ErrorBundle`


5 files changed, 111 insertions(+), 111 deletions(-)

src/Compilation.zig+37-28
......@@ -33,7 +33,6 @@ const InternPool = @import("InternPool.zig");
3333const BuildId = std.Build.CompileStep.BuildId;
3434const Cache = std.Build.Cache;
3535const translate_c = @import("translate_c.zig");
36const clang = @import("clang.zig");
3736const c_codegen = @import("codegen/c.zig");
3837const libtsan = @import("libtsan.zig");
3938const Zir = @import("Zir.zig");
......@@ -2743,7 +2742,7 @@ pub fn totalErrorCount(self: *Compilation) u32 {
27432742 if (module.declFileScope(key).okToReportErrors()) {
27442743 total += 1;
27452744 if (module.cimport_errors.get(key)) |errors| {
2746 total += errors.len;
2745 total += errors.errorMessageCount();
27472746 }
27482747 }
27492748 }
......@@ -2867,20 +2866,26 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
28672866 // We'll try again once parsing succeeds.
28682867 if (module.declFileScope(decl_index).okToReportErrors()) {
28692868 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
2870 if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {
2871 try bundle.addRootErrorMessage(.{
2872 .msg = try bundle.addString(std.mem.span(c_error.msg)),
2873 .src_loc = if (c_error.path) |some| try bundle.addSourceLocation(.{
2874 .src_path = try bundle.addString(std.mem.span(some)),
2875 .span_start = c_error.offset,
2876 .span_main = c_error.offset,
2877 .span_end = c_error.offset + 1,
2878 .line = c_error.line,
2879 .column = c_error.column,
2880 .source_line = if (c_error.source_line) |line| try bundle.addString(std.mem.span(line)) else 0,
2881 }) else .none,
2882 });
2883 };
2869 if (module.cimport_errors.get(entry.key_ptr.*)) |errors| {
2870 for (errors.getMessages()) |err_msg_index| {
2871 const err_msg = errors.getErrorMessage(err_msg_index);
2872 try bundle.addRootErrorMessage(.{
2873 .msg = try bundle.addString(errors.nullTerminatedString(err_msg.msg)),
2874 .src_loc = if (err_msg.src_loc != .none) blk: {
2875 const src_loc = errors.getSourceLocation(err_msg.src_loc);
2876 break :blk try bundle.addSourceLocation(.{
2877 .src_path = try bundle.addString(errors.nullTerminatedString(src_loc.src_path)),
2878 .span_start = src_loc.span_start,
2879 .span_main = src_loc.span_main,
2880 .span_end = src_loc.span_end,
2881 .line = src_loc.line,
2882 .column = src_loc.column,
2883 .source_line = if (src_loc.source_line != 0) try bundle.addString(errors.nullTerminatedString(src_loc.source_line)) else 0,
2884 });
2885 } else .none,
2886 });
2887 }
2888 }
28842889 }
28852890 }
28862891 }
......@@ -3831,9 +3836,15 @@ test "cImport" {
38313836 _ = cImport;
38323837}
38333838
3834const CImportResult = struct {
3839pub const CImportResult = struct {
38353840 out_zig_path: []u8,
3836 errors: []clang.ErrorMsg,
3841 cache_hit: bool,
3842 errors: std.zig.ErrorBundle,
3843
3844 pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void {
3845 gpa.free(result.out_zig_path);
3846 result.errors.deinit(gpa);
3847 }
38373848};
38383849
38393850/// Caller owns returned memory.
......@@ -3906,25 +3917,22 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
39063917 new_argv[i] = try arena.dupeZ(u8, arg);
39073918 }
39083919
3909 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});
3910 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);
3911 var clang_errors: []clang.ErrorMsg = &[0]clang.ErrorMsg{};
3920 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
3921 var errors = std.zig.ErrorBundle.empty;
3922 errdefer errors.deinit(comp.gpa);
39123923 var tree = translate_c.translate(
39133924 comp.gpa,
39143925 new_argv.ptr,
39153926 new_argv.ptr + new_argv.len,
3916 &clang_errors,
3927 &errors,
39173928 c_headers_dir_path_z,
39183929 ) catch |err| switch (err) {
39193930 error.OutOfMemory => return error.OutOfMemory,
3920 error.ASTUnitFailure => {
3921 log.warn("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{});
3922 return error.ASTUnitFailure;
3923 },
39243931 error.SemanticAnalyzeFail => {
39253932 return CImportResult{
39263933 .out_zig_path = "",
3927 .errors = clang_errors,
3934 .cache_hit = actual_hit,
3935 .errors = errors,
39283936 };
39293937 },
39303938 };
......@@ -3976,7 +3984,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
39763984 }
39773985 return CImportResult{
39783986 .out_zig_path = out_zig_path,
3979 .errors = &[0]clang.ErrorMsg{},
3987 .cache_hit = actual_hit,
3988 .errors = std.zig.ErrorBundle.empty,
39803989 };
39813990}
39823991
src/Module.zig+7-5
......@@ -131,7 +131,7 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},
131131failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},
132132/// If a decl failed due to a cimport error, the corresponding Clang errors
133133/// are stored here.
134cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},
134cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, std.zig.ErrorBundle) = .{},
135135
136136/// Candidates for deletion. After a semantic analysis update completes, this list
137137/// contains Decls that need to be deleted if they end up having no references to them.
......@@ -2603,8 +2603,8 @@ pub fn deinit(mod: *Module) void {
26032603 }
26042604 mod.failed_exports.deinit(gpa);
26052605
2606 for (mod.cimport_errors.values()) |errs| {
2607 for (errs) |err| err.deinit(gpa);
2606 for (mod.cimport_errors.values()) |*errs| {
2607 errs.deinit(gpa);
26082608 }
26092609 mod.cimport_errors.deinit(gpa);
26102610
......@@ -4583,7 +4583,8 @@ pub fn clearDecl(
45834583 kv.value.destroy(gpa);
45844584 }
45854585 if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| {
4586 for (kv.value) |err| err.deinit(gpa);
4586 var errors = kv.value;
4587 errors.deinit(gpa);
45874588 }
45884589 if (mod.emit_h) |emit_h| {
45894590 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
......@@ -4965,7 +4966,8 @@ fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
49654966 kv.value.destroy(mod.gpa);
49664967 }
49674968 if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| {
4968 for (kv.value) |err| err.deinit(mod.gpa);
4969 var errors = kv.value;
4970 errors.deinit(mod.gpa);
49694971 }
49704972 if (mod.emit_h) |emit_h| {
49714973 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
src/Sema.zig+5-45
......@@ -5767,13 +5767,12 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57675767 _ = try sema.analyzeBodyBreak(&child_block, body);
57685768
57695769 const mod = sema.mod;
5770 const c_import_res = mod.comp.cImport(c_import_buf.items) catch |err|
5770 var c_import_res = mod.comp.cImport(c_import_buf.items) catch |err|
57715771 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
5772 defer c_import_res.deinit(mod.comp.gpa);
57725773
5773 if (c_import_res.errors.len != 0) {
5774 if (c_import_res.errors.errorMessageCount() != 0) {
57745775 const msg = msg: {
5775 defer @import("clang.zig").ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len);
5776
57775776 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
57785777 errdefer msg.destroy(sema.gpa);
57795778
......@@ -5782,47 +5781,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57825781
57835782 const gop = try mod.cimport_errors.getOrPut(sema.gpa, sema.owner_decl_index);
57845783 if (!gop.found_existing) {
5785 var errs = try std.ArrayListUnmanaged(Module.CImportError).initCapacity(sema.gpa, c_import_res.errors.len);
5786 errdefer {
5787 for (errs.items) |err| err.deinit(sema.gpa);
5788 errs.deinit(sema.gpa);
5789 }
5790
5791 for (c_import_res.errors) |c_error| {
5792 const path = if (c_error.filename_ptr) |some|
5793 try sema.gpa.dupeZ(u8, some[0..c_error.filename_len])
5794 else
5795 null;
5796 errdefer if (path) |some| sema.gpa.free(some);
5797
5798 const c_msg = try sema.gpa.dupeZ(u8, c_error.msg_ptr[0..c_error.msg_len]);
5799 errdefer sema.gpa.free(c_msg);
5800
5801 const line = line: {
5802 const source = c_error.source orelse break :line null;
5803 var start = c_error.offset;
5804 while (start > 0) : (start -= 1) {
5805 if (source[start - 1] == '\n') break;
5806 }
5807 var end = c_error.offset;
5808 while (true) : (end += 1) {
5809 if (source[end] == 0) break;
5810 if (source[end] == '\n') break;
5811 }
5812 break :line try sema.gpa.dupeZ(u8, source[start..end]);
5813 };
5814 errdefer if (line) |some| sema.gpa.free(some);
5815
5816 errs.appendAssumeCapacity(.{
5817 .path = path orelse null,
5818 .source_line = line orelse null,
5819 .line = c_error.line,
5820 .column = c_error.column,
5821 .offset = c_error.offset,
5822 .msg = c_msg,
5823 });
5824 }
5825 gop.value_ptr.* = errs.items;
5784 gop.value_ptr.* = c_import_res.errors;
5785 c_import_res.errors = std.zig.ErrorBundle.empty;
58265786 }
58275787 break :msg msg;
58285788 };
src/main.zig+21-27
......@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
2121const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2222const wasi_libc = @import("wasi_libc.zig");
2323const translate_c = @import("translate_c.zig");
24const clang = @import("clang.zig");
2524const BuildId = std.Build.CompileStep.BuildId;
2625const Cache = std.Build.Cache;
2726const target_util = @import("target.zig");
......@@ -3697,11 +3696,16 @@ fn serve(
36973696 var arena_instance = std.heap.ArenaAllocator.init(gpa);
36983697 defer arena_instance.deinit();
36993698 const arena = arena_instance.allocator();
3700 var output: TranslateCOutput = undefined;
3699 var output: Compilation.CImportResult = undefined;
37013700 try cmdTranslateC(comp, arena, &output);
3702 try server.serveEmitBinPath(output.path, .{
3703 .flags = .{ .cache_hit = output.cache_hit },
3704 });
3701 defer output.deinit(gpa);
3702 if (output.errors.errorMessageCount() != 0) {
3703 try server.serveErrorBundle(output.errors);
3704 } else {
3705 try server.serveEmitBinPath(output.out_zig_path, .{
3706 .flags = .{ .cache_hit = output.cache_hit },
3707 });
3708 }
37053709 continue;
37063710 }
37073711
......@@ -4168,12 +4172,7 @@ fn updateModule(comp: *Compilation) !void {
41684172 }
41694173}
41704174
4171const TranslateCOutput = struct {
4172 path: []const u8,
4173 cache_hit: bool,
4174};
4175
4176fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*TranslateCOutput) !void {
4175fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
41774176 if (!build_options.have_llvm)
41784177 fatal("cannot translate-c: compiler built without LLVM extensions", .{});
41794178
......@@ -4231,29 +4230,24 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate
42314230 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
42324231 }
42334232
4234 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});
4235 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);
4236 var clang_errors: []clang.ErrorMsg = &[0]clang.ErrorMsg{};
4233 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
4234 var errors = std.zig.ErrorBundle.empty;
42374235 var tree = translate_c.translate(
42384236 comp.gpa,
42394237 new_argv.ptr,
42404238 new_argv.ptr + new_argv.len,
4241 &clang_errors,
4239 &errors,
42424240 c_headers_dir_path_z,
42434241 ) catch |err| switch (err) {
42444242 error.OutOfMemory => return error.OutOfMemory,
4245 error.ASTUnitFailure => fatal("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{}),
42464243 error.SemanticAnalyzeFail => {
4247 // TODO convert these to zig errors
4248 for (clang_errors) |clang_err| {
4249 std.debug.print("{s}:{d}:{d}: {s}\n", .{
4250 if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",
4251 clang_err.line + 1,
4252 clang_err.column + 1,
4253 clang_err.msg_ptr[0..clang_err.msg_len],
4254 });
4244 if (fancy_output) |p| {
4245 p.errors = errors;
4246 return;
4247 } else {
4248 errors.renderToStdErr(renderOptions(comp.color));
4249 process.exit(1);
42554250 }
4256 process.exit(1);
42574251 },
42584252 };
42594253 defer tree.deinit(comp.gpa);
......@@ -4290,10 +4284,10 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate
42904284 };
42914285
42924286 if (fancy_output) |p| {
4293 const full_zig_path = try comp.local_cache_directory.join(arena, &[_][]const u8{
4287 p.out_zig_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{
42944288 "o", &digest, translated_zig_basename,
42954289 });
4296 p.path = full_zig_path;
4290 p.errors = std.zig.ErrorBundle.empty;
42974291 } else {
42984292 const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest, translated_zig_basename });
42994293 const zig_file = comp.local_cache_directory.handle.openFile(out_zig_path, .{}) catch |err| {
src/translate_c.zig+41-6
......@@ -372,19 +372,54 @@ pub fn translate(
372372 gpa: mem.Allocator,
373373 args_begin: [*]?[*]const u8,
374374 args_end: [*]?[*]const u8,
375 errors: *[]clang.ErrorMsg,
375 errors: *std.zig.ErrorBundle,
376376 resources_path: [*:0]const u8,
377377) !std.zig.Ast {
378 // TODO stage2 bug
379 var tmp = errors;
378 var clang_errors: []clang.ErrorMsg = &.{};
379
380380 const ast_unit = clang.LoadFromCommandLine(
381381 args_begin,
382382 args_end,
383 &tmp.ptr,
384 &tmp.len,
383 &clang_errors.ptr,
384 &clang_errors.len,
385385 resources_path,
386386 ) orelse {
387 if (errors.len == 0) return error.ASTUnitFailure;
387 defer clang.ErrorMsg.delete(clang_errors.ptr, clang_errors.len);
388
389 var bundle: std.zig.ErrorBundle.Wip = undefined;
390 try bundle.init(gpa);
391 defer bundle.deinit();
392
393 for (clang_errors) |c_error| {
394 const line = line: {
395 const source = c_error.source orelse break :line 0;
396 var start = c_error.offset;
397 while (start > 0) : (start -= 1) {
398 if (source[start - 1] == '\n') break;
399 }
400 var end = c_error.offset;
401 while (true) : (end += 1) {
402 if (source[end] == 0) break;
403 if (source[end] == '\n') break;
404 }
405 break :line try bundle.addString(source[start..end]);
406 };
407
408 try bundle.addRootErrorMessage(.{
409 .msg = try bundle.addString(c_error.msg_ptr[0..c_error.msg_len]),
410 .src_loc = if (c_error.filename_ptr) |filename_ptr| try bundle.addSourceLocation(.{
411 .src_path = try bundle.addString(filename_ptr[0..c_error.filename_len]),
412 .span_start = c_error.offset,
413 .span_main = c_error.offset,
414 .span_end = c_error.offset + 1,
415 .line = c_error.line,
416 .column = c_error.column,
417 .source_line = line,
418 }) else .none,
419 });
420 }
421 errors.* = try bundle.toOwnedBundle("");
422
388423 return error.SemanticAnalyzeFail;
389424 };
390425 defer ast_unit.delete();