| ... | ... | @@ -4568,17 +4568,18 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4568 | 4568 | // We can't know the digest until we do the C compiler invocation, |
| 4569 | 4569 | // so we need a temporary filename. |
| 4570 | 4570 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); |
| 4571 | | const out_diag_path = if (comp.clang_passthrough_mode) |
| 4572 | | undefined |
| 4573 | | else |
| 4574 | | try std.fmt.allocPrint(arena, "{s}.diag", .{out_obj_path}); |
| 4575 | 4571 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); |
| 4576 | 4572 | defer zig_cache_tmp_dir.close(); |
| 4577 | 4573 | |
| 4578 | | const out_dep_path: ?[]const u8 = if (comp.disable_c_depfile or !ext.clangSupportsDepFile()) |
| 4574 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) |
| 4575 | null |
| 4576 | else |
| 4577 | try std.fmt.allocPrint(arena, "{s}.diag", .{out_obj_path}); |
| 4578 | const out_dep_path = if (comp.disable_c_depfile or !ext.clangSupportsDepFile()) |
| 4579 | 4579 | null |
| 4580 | 4580 | else |
| 4581 | 4581 | try std.fmt.allocPrint(arena, "{s}.d", .{out_obj_path}); |
| 4582 | |
| 4582 | 4583 | try comp.addCCArgs(arena, &argv, ext, out_dep_path, c_object.src.owner); |
| 4583 | 4584 | try argv.appendSlice(c_object.src.extra_flags); |
| 4584 | 4585 | try argv.appendSlice(c_object.src.cache_exempt_flags); |
| ... | ... | @@ -4590,7 +4591,9 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4590 | 4591 | .pch => argv.appendSliceAssumeCapacity(&.{ "-Xclang", "-emit-pch", "-o", out_obj_path }), |
| 4591 | 4592 | .stdout => argv.appendAssumeCapacity("-E"), |
| 4592 | 4593 | } |
| 4593 | | if (comp.clang_passthrough_mode) { |
| 4594 | if (out_diag_path) |diag_file_path| { |
| 4595 | argv.appendSliceAssumeCapacity(&.{ "--serialize-diagnostics", diag_file_path }); |
| 4596 | } else if (comp.clang_passthrough_mode) { |
| 4594 | 4597 | if (comp.emit_asm != null) { |
| 4595 | 4598 | argv.appendAssumeCapacity("-S"); |
| 4596 | 4599 | } else if (comp.emit_llvm_ir != null) { |
| ... | ... | @@ -4598,8 +4601,6 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4598 | 4601 | } else if (comp.emit_llvm_bc != null) { |
| 4599 | 4602 | argv.appendAssumeCapacity("-emit-llvm"); |
| 4600 | 4603 | } |
| 4601 | | } else { |
| 4602 | | argv.appendSliceAssumeCapacity(&.{ "--serialize-diagnostics", out_diag_path }); |
| 4603 | 4604 | } |
| 4604 | 4605 | |
| 4605 | 4606 | if (comp.verbose_cc) { |
| ... | ... | @@ -4607,8 +4608,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4607 | 4608 | } |
| 4608 | 4609 | |
| 4609 | 4610 | // Just to save disk space, we delete the files that are never needed again. |
| 4610 | | defer if (!comp.clang_passthrough_mode) zig_cache_tmp_dir.deleteFile(std.fs.path.basename(out_diag_path)) catch |err| { |
| 4611 | | log.warn("failed to delete '{s}': {s}", .{ out_diag_path, @errorName(err) }); |
| 4611 | defer if (out_diag_path) |diag_file_path| zig_cache_tmp_dir.deleteFile(std.fs.path.basename(diag_file_path)) catch |err| { |
| 4612 | log.warn("failed to delete '{s}': {s}", .{ diag_file_path, @errorName(err) }); |
| 4612 | 4613 | }; |
| 4613 | 4614 | defer if (out_dep_path) |dep_file_path| zig_cache_tmp_dir.deleteFile(std.fs.path.basename(dep_file_path)) catch |err| { |
| 4614 | 4615 | log.warn("failed to delete '{s}': {s}", .{ dep_file_path, @errorName(err) }); |
| ... | ... | @@ -4647,14 +4648,15 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P |
| 4647 | 4648 | }; |
| 4648 | 4649 | |
| 4649 | 4650 | switch (term) { |
| 4650 | | .Exited => |code| { |
| 4651 | | if (code != 0) { |
| 4652 | | const bundle = CObject.Diag.Bundle.parse(comp.gpa, out_diag_path) catch |err| { |
| 4653 | | log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr }); |
| 4654 | | return comp.failCObj(c_object, "clang exited with code {d}", .{code}); |
| 4655 | | }; |
| 4656 | | return comp.failCObjWithOwnedDiagBundle(c_object, bundle); |
| 4657 | | } |
| 4651 | .Exited => |code| if (code != 0) if (out_diag_path) |diag_file_path| { |
| 4652 | const bundle = CObject.Diag.Bundle.parse(comp.gpa, diag_file_path) catch |err| { |
| 4653 | log.err("{}: failed to parse clang diagnostics: {s}", .{ err, stderr }); |
| 4654 | return comp.failCObj(c_object, "clang exited with code {d}", .{code}); |
| 4655 | }; |
| 4656 | return comp.failCObjWithOwnedDiagBundle(c_object, bundle); |
| 4657 | } else { |
| 4658 | log.err("clang failed with stderr: {s}", .{stderr}); |
| 4659 | return comp.failCObj(c_object, "clang exited with code {d}", .{code}); |
| 4658 | 4660 | }, |
| 4659 | 4661 | else => { |
| 4660 | 4662 | log.err("clang terminated with stderr: {s}", .{stderr}); |
| ... | ... | @@ -5110,7 +5112,7 @@ pub fn addCCArgs( |
| 5110 | 5112 | // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode |
| 5111 | 5113 | // we want Clang to infer it, and in normal mode we always want it off, which will be true since |
| 5112 | 5114 | // clang will detect stderr as a pipe rather than a terminal. |
| 5113 | | if (!comp.clang_passthrough_mode) { |
| 5115 | if (!comp.clang_passthrough_mode and ext.clangSupportsDiagnostics()) { |
| 5114 | 5116 | // Make stderr more easily parseable. |
| 5115 | 5117 | try argv.append("-fno-caret-diagnostics"); |
| 5116 | 5118 | } |
| ... | ... | @@ -5544,6 +5546,7 @@ fn failCObjWithOwnedDiagBundle( |
| 5544 | 5546 | diag_bundle: *CObject.Diag.Bundle, |
| 5545 | 5547 | ) SemaError { |
| 5546 | 5548 | @setCold(true); |
| 5549 | assert(diag_bundle.diags.len > 0); |
| 5547 | 5550 | { |
| 5548 | 5551 | comp.mutex.lock(); |
| 5549 | 5552 | defer comp.mutex.unlock(); |
| ... | ... | @@ -5619,6 +5622,25 @@ pub const FileExt = enum { |
| 5619 | 5622 | manifest, |
| 5620 | 5623 | unknown, |
| 5621 | 5624 | |
| 5625 | pub fn clangSupportsDiagnostics(ext: FileExt) bool { |
| 5626 | return switch (ext) { |
| 5627 | .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu, .ll, .bc => true, |
| 5628 | |
| 5629 | .assembly, |
| 5630 | .assembly_with_cpp, |
| 5631 | .shared_library, |
| 5632 | .object, |
| 5633 | .static_library, |
| 5634 | .zig, |
| 5635 | .def, |
| 5636 | .rc, |
| 5637 | .res, |
| 5638 | .manifest, |
| 5639 | .unknown, |
| 5640 | => false, |
| 5641 | }; |
| 5642 | } |
| 5643 | |
| 5622 | 5644 | pub fn clangSupportsDepFile(ext: FileExt) bool { |
| 5623 | 5645 | return switch (ext) { |
| 5624 | 5646 | .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true, |