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");...@@ -33,7 +33,6 @@ const InternPool = @import("InternPool.zig");
33const BuildId = std.Build.CompileStep.BuildId;33const BuildId = std.Build.CompileStep.BuildId;
34const Cache = std.Build.Cache;34const Cache = std.Build.Cache;
35const translate_c = @import("translate_c.zig");35const translate_c = @import("translate_c.zig");
36const clang = @import("clang.zig");
37const c_codegen = @import("codegen/c.zig");36const c_codegen = @import("codegen/c.zig");
38const libtsan = @import("libtsan.zig");37const libtsan = @import("libtsan.zig");
39const Zir = @import("Zir.zig");38const Zir = @import("Zir.zig");
...@@ -2743,7 +2742,7 @@ pub fn totalErrorCount(self: *Compilation) u32 {...@@ -2743,7 +2742,7 @@ pub fn totalErrorCount(self: *Compilation) u32 {
2743 if (module.declFileScope(key).okToReportErrors()) {2742 if (module.declFileScope(key).okToReportErrors()) {
2744 total += 1;2743 total += 1;
2745 if (module.cimport_errors.get(key)) |errors| {2744 if (module.cimport_errors.get(key)) |errors| {
2746 total += errors.len;2745 total += errors.errorMessageCount();
2747 }2746 }
2748 }2747 }
2749 }2748 }
...@@ -2867,20 +2866,26 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {...@@ -2867,20 +2866,26 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
2867 // We'll try again once parsing succeeds.2866 // We'll try again once parsing succeeds.
2868 if (module.declFileScope(decl_index).okToReportErrors()) {2867 if (module.declFileScope(decl_index).okToReportErrors()) {
2869 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);2868 try addModuleErrorMsg(module, &bundle, entry.value_ptr.*.*);
2870 if (module.cimport_errors.get(entry.key_ptr.*)) |cimport_errors| for (cimport_errors) |c_error| {2869 if (module.cimport_errors.get(entry.key_ptr.*)) |errors| {
2871 try bundle.addRootErrorMessage(.{2870 for (errors.getMessages()) |err_msg_index| {
2872 .msg = try bundle.addString(std.mem.span(c_error.msg)),2871 const err_msg = errors.getErrorMessage(err_msg_index);
2873 .src_loc = if (c_error.path) |some| try bundle.addSourceLocation(.{2872 try bundle.addRootErrorMessage(.{
2874 .src_path = try bundle.addString(std.mem.span(some)),2873 .msg = try bundle.addString(errors.nullTerminatedString(err_msg.msg)),
2875 .span_start = c_error.offset,2874 .src_loc = if (err_msg.src_loc != .none) blk: {
2876 .span_main = c_error.offset,2875 const src_loc = errors.getSourceLocation(err_msg.src_loc);
2877 .span_end = c_error.offset + 1,2876 break :blk try bundle.addSourceLocation(.{
2878 .line = c_error.line,2877 .src_path = try bundle.addString(errors.nullTerminatedString(src_loc.src_path)),
2879 .column = c_error.column,2878 .span_start = src_loc.span_start,
2880 .source_line = if (c_error.source_line) |line| try bundle.addString(std.mem.span(line)) else 0,2879 .span_main = src_loc.span_main,
2881 }) else .none,2880 .span_end = src_loc.span_end,
2882 });2881 .line = src_loc.line,
2883 };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 }
2884 }2889 }
2885 }2890 }
2886 }2891 }
...@@ -3831,9 +3836,15 @@ test "cImport" {...@@ -3831,9 +3836,15 @@ test "cImport" {
3831 _ = cImport;3836 _ = cImport;
3832}3837}
38333838
3834const CImportResult = struct {3839pub const CImportResult = struct {
3835 out_zig_path: []u8,3840 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 }
3837};3848};
38383849
3839/// Caller owns returned memory.3850/// Caller owns returned memory.
...@@ -3906,25 +3917,22 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -3906,25 +3917,22 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3906 new_argv[i] = try arena.dupeZ(u8, arg);3917 new_argv[i] = try arena.dupeZ(u8, arg);
3907 }3918 }
39083919
3909 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});3920 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
3910 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);3921 var errors = std.zig.ErrorBundle.empty;
3911 var clang_errors: []clang.ErrorMsg = &[0]clang.ErrorMsg{};3922 errdefer errors.deinit(comp.gpa);
3912 var tree = translate_c.translate(3923 var tree = translate_c.translate(
3913 comp.gpa,3924 comp.gpa,
3914 new_argv.ptr,3925 new_argv.ptr,
3915 new_argv.ptr + new_argv.len,3926 new_argv.ptr + new_argv.len,
3916 &clang_errors,3927 &errors,
3917 c_headers_dir_path_z,3928 c_headers_dir_path_z,
3918 ) catch |err| switch (err) {3929 ) catch |err| switch (err) {
3919 error.OutOfMemory => return error.OutOfMemory,3930 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 },
3924 error.SemanticAnalyzeFail => {3931 error.SemanticAnalyzeFail => {
3925 return CImportResult{3932 return CImportResult{
3926 .out_zig_path = "",3933 .out_zig_path = "",
3927 .errors = clang_errors,3934 .cache_hit = actual_hit,
3935 .errors = errors,
3928 };3936 };
3929 },3937 },
3930 };3938 };
...@@ -3976,7 +3984,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {...@@ -3976,7 +3984,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3976 }3984 }
3977 return CImportResult{3985 return CImportResult{
3978 .out_zig_path = out_zig_path,3986 .out_zig_path = out_zig_path,
3979 .errors = &[0]clang.ErrorMsg{},3987 .cache_hit = actual_hit,
3988 .errors = std.zig.ErrorBundle.empty,
3980 };3989 };
3981}3990}
39823991
src/Module.zig+7-5
...@@ -131,7 +131,7 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},...@@ -131,7 +131,7 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},
131failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},131failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},
132/// If a decl failed due to a cimport error, the corresponding Clang errors132/// If a decl failed due to a cimport error, the corresponding Clang errors
133/// are stored here.133/// are stored here.
134cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},134cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, std.zig.ErrorBundle) = .{},
135135
136/// Candidates for deletion. After a semantic analysis update completes, this list136/// Candidates for deletion. After a semantic analysis update completes, this list
137/// contains Decls that need to be deleted if they end up having no references to them.137/// 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 {...@@ -2603,8 +2603,8 @@ pub fn deinit(mod: *Module) void {
2603 }2603 }
2604 mod.failed_exports.deinit(gpa);2604 mod.failed_exports.deinit(gpa);
26052605
2606 for (mod.cimport_errors.values()) |errs| {2606 for (mod.cimport_errors.values()) |*errs| {
2607 for (errs) |err| err.deinit(gpa);2607 errs.deinit(gpa);
2608 }2608 }
2609 mod.cimport_errors.deinit(gpa);2609 mod.cimport_errors.deinit(gpa);
26102610
...@@ -4583,7 +4583,8 @@ pub fn clearDecl(...@@ -4583,7 +4583,8 @@ pub fn clearDecl(
4583 kv.value.destroy(gpa);4583 kv.value.destroy(gpa);
4584 }4584 }
4585 if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| {4585 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);
4587 }4588 }
4588 if (mod.emit_h) |emit_h| {4589 if (mod.emit_h) |emit_h| {
4589 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {4590 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
...@@ -4965,7 +4966,8 @@ fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {...@@ -4965,7 +4966,8 @@ fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
4965 kv.value.destroy(mod.gpa);4966 kv.value.destroy(mod.gpa);
4966 }4967 }
4967 if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| {4968 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);
4969 }4971 }
4970 if (mod.emit_h) |emit_h| {4972 if (mod.emit_h) |emit_h| {
4971 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {4973 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...@@ -5767,13 +5767,12 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
5767 _ = try sema.analyzeBodyBreak(&child_block, body);5767 _ = try sema.analyzeBodyBreak(&child_block, body);
57685768
5769 const mod = sema.mod;5769 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|
5771 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});5771 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) {
5774 const msg = msg: {5775 const msg = msg: {
5775 defer @import("clang.zig").ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len);
5776
5777 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});5776 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
5778 errdefer msg.destroy(sema.gpa);5777 errdefer msg.destroy(sema.gpa);
57795778
...@@ -5782,47 +5781,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5782,47 +5781,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57825781
5783 const gop = try mod.cimport_errors.getOrPut(sema.gpa, sema.owner_decl_index);5782 const gop = try mod.cimport_errors.getOrPut(sema.gpa, sema.owner_decl_index);
5784 if (!gop.found_existing) {5783 if (!gop.found_existing) {
5785 var errs = try std.ArrayListUnmanaged(Module.CImportError).initCapacity(sema.gpa, c_import_res.errors.len);5784 gop.value_ptr.* = c_import_res.errors;
5786 errdefer {5785 c_import_res.errors = std.zig.ErrorBundle.empty;
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;
5826 }5786 }
5827 break :msg msg;5787 break :msg msg;
5828 };5788 };
src/main.zig+21-27
...@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");...@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;21const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
22const wasi_libc = @import("wasi_libc.zig");22const wasi_libc = @import("wasi_libc.zig");
23const translate_c = @import("translate_c.zig");23const translate_c = @import("translate_c.zig");
24const clang = @import("clang.zig");
25const BuildId = std.Build.CompileStep.BuildId;24const BuildId = std.Build.CompileStep.BuildId;
26const Cache = std.Build.Cache;25const Cache = std.Build.Cache;
27const target_util = @import("target.zig");26const target_util = @import("target.zig");
...@@ -3697,11 +3696,16 @@ fn serve(...@@ -3697,11 +3696,16 @@ fn serve(
3697 var arena_instance = std.heap.ArenaAllocator.init(gpa);3696 var arena_instance = std.heap.ArenaAllocator.init(gpa);
3698 defer arena_instance.deinit();3697 defer arena_instance.deinit();
3699 const arena = arena_instance.allocator();3698 const arena = arena_instance.allocator();
3700 var output: TranslateCOutput = undefined;3699 var output: Compilation.CImportResult = undefined;
3701 try cmdTranslateC(comp, arena, &output);3700 try cmdTranslateC(comp, arena, &output);
3702 try server.serveEmitBinPath(output.path, .{3701 defer output.deinit(gpa);
3703 .flags = .{ .cache_hit = output.cache_hit },3702 if (output.errors.errorMessageCount() != 0) {
3704 });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 }
3705 continue;3709 continue;
3706 }3710 }
37073711
...@@ -4168,12 +4172,7 @@ fn updateModule(comp: *Compilation) !void {...@@ -4168,12 +4172,7 @@ fn updateModule(comp: *Compilation) !void {
4168 }4172 }
4169}4173}
41704174
4171const TranslateCOutput = struct {4175fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
4172 path: []const u8,
4173 cache_hit: bool,
4174};
4175
4176fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*TranslateCOutput) !void {
4177 if (!build_options.have_llvm)4176 if (!build_options.have_llvm)
4178 fatal("cannot translate-c: compiler built without LLVM extensions", .{});4177 fatal("cannot translate-c: compiler built without LLVM extensions", .{});
41794178
...@@ -4231,29 +4230,24 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate...@@ -4231,29 +4230,24 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate
4231 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);4230 new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg);
4232 }4231 }
42334232
4234 const c_headers_dir_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"include"});4233 const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"});
4235 const c_headers_dir_path_z = try arena.dupeZ(u8, c_headers_dir_path);4234 var errors = std.zig.ErrorBundle.empty;
4236 var clang_errors: []clang.ErrorMsg = &[0]clang.ErrorMsg{};
4237 var tree = translate_c.translate(4235 var tree = translate_c.translate(
4238 comp.gpa,4236 comp.gpa,
4239 new_argv.ptr,4237 new_argv.ptr,
4240 new_argv.ptr + new_argv.len,4238 new_argv.ptr + new_argv.len,
4241 &clang_errors,4239 &errors,
4242 c_headers_dir_path_z,4240 c_headers_dir_path_z,
4243 ) catch |err| switch (err) {4241 ) catch |err| switch (err) {
4244 error.OutOfMemory => return error.OutOfMemory,4242 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", .{}),
4246 error.SemanticAnalyzeFail => {4243 error.SemanticAnalyzeFail => {
4247 // TODO convert these to zig errors4244 if (fancy_output) |p| {
4248 for (clang_errors) |clang_err| {4245 p.errors = errors;
4249 std.debug.print("{s}:{d}:{d}: {s}\n", .{4246 return;
4250 if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)",4247 } else {
4251 clang_err.line + 1,4248 errors.renderToStdErr(renderOptions(comp.color));
4252 clang_err.column + 1,4249 process.exit(1);
4253 clang_err.msg_ptr[0..clang_err.msg_len],
4254 });
4255 }4250 }
4256 process.exit(1);
4257 },4251 },
4258 };4252 };
4259 defer tree.deinit(comp.gpa);4253 defer tree.deinit(comp.gpa);
...@@ -4290,10 +4284,10 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate...@@ -4290,10 +4284,10 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Translate
4290 };4284 };
42914285
4292 if (fancy_output) |p| {4286 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{
4294 "o", &digest, translated_zig_basename,4288 "o", &digest, translated_zig_basename,
4295 });4289 });
4296 p.path = full_zig_path;4290 p.errors = std.zig.ErrorBundle.empty;
4297 } else {4291 } else {
4298 const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest, translated_zig_basename });4292 const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &digest, translated_zig_basename });
4299 const zig_file = comp.local_cache_directory.handle.openFile(out_zig_path, .{}) catch |err| {4293 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(...@@ -372,19 +372,54 @@ pub fn translate(
372 gpa: mem.Allocator,372 gpa: mem.Allocator,
373 args_begin: [*]?[*]const u8,373 args_begin: [*]?[*]const u8,
374 args_end: [*]?[*]const u8,374 args_end: [*]?[*]const u8,
375 errors: *[]clang.ErrorMsg,375 errors: *std.zig.ErrorBundle,
376 resources_path: [*:0]const u8,376 resources_path: [*:0]const u8,
377) !std.zig.Ast {377) !std.zig.Ast {
378 // TODO stage2 bug378 var clang_errors: []clang.ErrorMsg = &.{};
379 var tmp = errors;379
380 const ast_unit = clang.LoadFromCommandLine(380 const ast_unit = clang.LoadFromCommandLine(
381 args_begin,381 args_begin,
382 args_end,382 args_end,
383 &tmp.ptr,383 &clang_errors.ptr,
384 &tmp.len,384 &clang_errors.len,
385 resources_path,385 resources_path,
386 ) orelse {386 ) 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
388 return error.SemanticAnalyzeFail;423 return error.SemanticAnalyzeFail;
389 };424 };
390 defer ast_unit.delete();425 defer ast_unit.delete();