Skip to content

Commit 2adb932

Browse files
TechatrixVexu
authored andcommitted
translate-c: convert clang errors messages into std.zig.ErrorBundle
1 parent e7bf143 commit 2adb932

File tree

5 files changed

+111
-111
lines changed

5 files changed

+111
-111
lines changed

src/Compilation.zig

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ const InternPool = @import("InternPool.zig");
3333
const BuildId = std.Build.CompileStep.BuildId;
3434
const Cache = std.Build.Cache;
3535
const translate_c = @import("translate_c.zig");
36-
const clang = @import("clang.zig");
3736
const c_codegen = @import("codegen/c.zig");
3837
const libtsan = @import("libtsan.zig");
3938
const 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

3834-
const CImportResult = struct {
3839+
pub 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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .{},
131131
failed_exports: std.AutoArrayHashMapUnmanaged(*Export, *ErrorMsg) = .{},
132132
/// If a decl failed due to a cimport error, the corresponding Clang errors
133133
/// are stored here.
134-
cimport_errors: std.AutoArrayHashMapUnmanaged(Decl.Index, []CImportError) = .{},
134+
cimport_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

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
2121
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2222
const wasi_libc = @import("wasi_libc.zig");
2323
const translate_c = @import("translate_c.zig");
24-
const clang = @import("clang.zig");
2524
const BuildId = std.Build.CompileStep.BuildId;
2625
const Cache = std.Build.Cache;
2726
const 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

4171-
const TranslateCOutput = struct {
4172-
path: []const u8,
4173-
cache_hit: bool,
4174-
};
4175-
4176-
fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*TranslateCOutput) !void {
4175+
fn 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

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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();

0 commit comments

Comments
 (0)