From f0d3b7abb8e96aede796c80ab73a0f82ecced722 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 13 Aug 2025 15:03:53 -0700 Subject: [PATCH] aro: fix dep file logic also add ability to omit main source file from dep file as it messes up caching strategy --- lib/compiler/aro/aro/Compilation.zig | 9 +++++++-- lib/compiler/aro/aro/Driver.zig | 17 +++++++++++------ lib/compiler/aro/aro/Parser.zig | 12 ++++++------ lib/compiler/aro/aro/Pragma.zig | 2 +- lib/compiler/aro/aro/Preprocessor.zig | 21 ++++++++------------- lib/compiler/aro/aro/pragmas/message.zig | 2 +- lib/compiler/aro/aro/text_literal.zig | 2 +- lib/compiler/translate-c/Translator.zig | 10 +++++----- lib/compiler/translate-c/main.zig | 6 +++++- 9 files changed, 45 insertions(+), 36 deletions(-) diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index d2affb3188..5517a5f426 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -934,7 +934,7 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, }; - if (allocating.getWritten().len > std.math.maxInt(u32)) return error.FileTooBig; + if (allocating.written().len > std.math.maxInt(u32)) return error.FileTooBig; const contents = try allocating.toOwnedSlice(); errdefer comp.gpa.free(contents); @@ -1589,6 +1589,7 @@ pub fn hasInclude( include_type: IncludeType, /// __has_include vs __has_include_next which: WhichInclude, + opt_dep_file: ?*DepFile, ) Compilation.Error!bool { if (try FindInclude.run(comp, filename, switch (which) { .next => .{ .only_search_after_dir = comp.getSource(includer_token_source).path }, @@ -1596,7 +1597,11 @@ pub fn hasInclude( .quotes => .{ .allow_same_dir = comp.getSource(includer_token_source).path }, .angle_brackets => .only_search, }, - })) |_| { + })) |found| { + if (opt_dep_file) |dep_file| { + const source = comp.getSource(found.source); + try dep_file.addDependency(comp.gpa, source.path); + } return true; } else { return false; diff --git a/lib/compiler/aro/aro/Driver.zig b/lib/compiler/aro/aro/Driver.zig index 2960d70328..f46b26b82b 100644 --- a/lib/compiler/aro/aro/Driver.zig +++ b/lib/compiler/aro/aro/Driver.zig @@ -831,7 +831,7 @@ pub fn err(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void { defer allocating.deinit(); Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory; - try d.diagnostics.add(.{ .kind = .@"error", .text = allocating.getWritten(), .location = null }); + try d.diagnostics.add(.{ .kind = .@"error", .text = allocating.written(), .location = null }); } pub fn warn(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void { @@ -840,7 +840,7 @@ pub fn warn(d: *Driver, fmt: []const u8, args: anytype) Compilation.Error!void { defer allocating.deinit(); Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory; - try d.diagnostics.add(.{ .kind = .warning, .text = allocating.getWritten(), .location = null }); + try d.diagnostics.add(.{ .kind = .warning, .text = allocating.written(), .location = null }); } pub fn unsupportedOptionForTarget(d: *Driver, target: std.Target, opt: []const u8) Compilation.Error!void { @@ -856,7 +856,7 @@ pub fn fatal(d: *Driver, comptime fmt: []const u8, args: anytype) error{ FatalEr defer allocating.deinit(); Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory; - try d.diagnostics.add(.{ .kind = .@"fatal error", .text = allocating.getWritten(), .location = null }); + try d.diagnostics.add(.{ .kind = .@"fatal error", .text = allocating.written(), .location = null }); unreachable; } @@ -986,7 +986,12 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8, comptime fast_ } /// Initializes a DepFile if requested by driver options. -pub fn initDepFile(d: *Driver, source: Source, buf: *[std.fs.max_name_bytes]u8) Compilation.Error!?DepFile { +pub fn initDepFile( + d: *Driver, + source: Source, + buf: *[std.fs.max_name_bytes]u8, + omit_source: bool, +) Compilation.Error!?DepFile { if (!d.dependencies.m and !d.dependencies.md) return null; var dep_file: DepFile = .{ .target = undefined, @@ -1004,7 +1009,7 @@ pub fn initDepFile(d: *Driver, source: Source, buf: *[std.fs.max_name_bytes]u8) return d.fatal("dependency file name too long for filesystem '{s}{s}'", args); } - try dep_file.addDependency(d.comp.gpa, source.path); + if (!omit_source) try dep_file.addDependency(d.comp.gpa, source.path); errdefer comptime unreachable; return dep_file; @@ -1101,7 +1106,7 @@ fn processSource( defer pp.deinit(); var name_buf: [std.fs.max_name_bytes]u8 = undefined; - var opt_dep_file = try d.initDepFile(source, &name_buf); + var opt_dep_file = try d.initDepFile(source, &name_buf, false); defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa); if (opt_dep_file) |*dep_file| pp.dep_file = dep_file; diff --git a/lib/compiler/aro/aro/Parser.zig b/lib/compiler/aro/aro/Parser.zig index 8cc088942b..76ac66678b 100644 --- a/lib/compiler/aro/aro/Parser.zig +++ b/lib/compiler/aro/aro/Parser.zig @@ -232,7 +232,7 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca try p.diagnostics.add(.{ .kind = diagnostic.kind, - .text = allocating.getWritten(), + .text = allocating.written(), .extension = diagnostic.extension, .opt = diagnostic.opt, .location = loc.expand(p.comp), @@ -244,7 +244,7 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca try p.diagnostics.add(.{ .kind = diagnostic.kind, - .text = allocating.getWritten(), + .text = allocating.written(), .extension = diagnostic.extension, .opt = diagnostic.opt, .location = loc.expand(p.comp), @@ -441,7 +441,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) } try p.diagnostics.addWithLocation(p.comp, .{ .kind = diagnostic.kind, - .text = allocating.getWritten(), + .text = allocating.written(), .opt = diagnostic.opt, .extension = diagnostic.extension, .location = loc.expand(p.comp), @@ -1487,13 +1487,13 @@ fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result if (maybe_message) |message| { assert(message.node.get(&p.tree) == .string_literal_expr); - if (allocating.getWritten().len > 0) { + if (allocating.written().len > 0) { try w.writeByte(' '); } const bytes = p.comp.interner.get(message.val.ref()).bytes; try Value.printString(bytes, message.qt, p.comp, w); } - return allocating.getWritten(); + return allocating.written(); } /// staticAssert @@ -9248,7 +9248,7 @@ fn primaryExpr(p: *Parser) Error!?Result { func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory; allocating.writer.writeByte(0) catch return error.OutOfMemory; - const predef = try p.makePredefinedIdentifier(allocating.getWritten()); + const predef = try p.makePredefinedIdentifier(allocating.written()); qt = predef.qt; p.func.pretty_ident = predef; } else { diff --git a/lib/compiler/aro/aro/Pragma.zig b/lib/compiler/aro/aro/Pragma.zig index 9b49596be8..0e10025fdd 100644 --- a/lib/compiler/aro/aro/Pragma.zig +++ b/lib/compiler/aro/aro/Pragma.zig @@ -203,7 +203,7 @@ pub fn err(pp: *Preprocessor, tok_i: TokenIndex, diagnostic: Diagnostic, args: a try pp.diagnostics.addWithLocation(pp.comp, .{ .kind = diagnostic.kind, .opt = diagnostic.opt, - .text = allocating.getWritten(), + .text = allocating.written(), .location = pp.tokens.items(.loc)[tok_i].expand(pp.comp), .extension = diagnostic.extension, }, pp.expansionSlice(tok_i), true); diff --git a/lib/compiler/aro/aro/Preprocessor.zig b/lib/compiler/aro/aro/Preprocessor.zig index 680e01ebf8..7618499da7 100644 --- a/lib/compiler/aro/aro/Preprocessor.zig +++ b/lib/compiler/aro/aro/Preprocessor.zig @@ -769,7 +769,7 @@ fn err(pp: *Preprocessor, loc: anytype, diagnostic: Diagnostic, args: anytype) C Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory; try pp.diagnostics.addWithLocation(pp.comp, .{ .kind = diagnostic.kind, - .text = allocating.getWritten(), + .text = allocating.written(), .opt = diagnostic.opt, .extension = diagnostic.extension, .location = switch (@TypeOf(loc)) { @@ -798,7 +798,7 @@ fn fatal(pp: *Preprocessor, raw: RawToken, comptime fmt: []const u8, args: anyty Diagnostics.formatArgs(&allocating.writer, fmt, args) catch return error.OutOfMemory; try pp.diagnostics.add(.{ .kind = .@"fatal error", - .text = allocating.getWritten(), + .text = allocating.written(), .location = (Source.Location{ .id = raw.source, .byte_offset = raw.start, @@ -1618,18 +1618,13 @@ fn handleBuiltinMacro(pp: *Preprocessor, builtin: RawToken.Id, param_toks: []con else => unreachable, }; const filename = include_str[1 .. include_str.len - 1]; - const res = res: { - if (builtin == .macro_param_has_include or pp.include_depth == 0) { - if (builtin == .macro_param_has_include_next) { - try pp.err(src_loc, .include_next_outside_header, .{}); - } - break :res try pp.comp.hasInclude(filename, src_loc.id, include_type, .first); + if (builtin == .macro_param_has_include or pp.include_depth == 0) { + if (builtin == .macro_param_has_include_next) { + try pp.err(src_loc, .include_next_outside_header, .{}); } - break :res try pp.comp.hasInclude(filename, src_loc.id, include_type, .next); - }; - - if (res) if (pp.dep_file) |dep_file| try dep_file.addDependencyDupe(pp.gpa, pp.comp.arena, filename); - return res; + return pp.comp.hasInclude(filename, src_loc.id, include_type, .first, pp.dep_file); + } + return pp.comp.hasInclude(filename, src_loc.id, include_type, .next, pp.dep_file); }, else => unreachable, } diff --git a/lib/compiler/aro/aro/pragmas/message.zig b/lib/compiler/aro/aro/pragmas/message.zig index b464d57423..d21077a084 100644 --- a/lib/compiler/aro/aro/pragmas/message.zig +++ b/lib/compiler/aro/aro/pragmas/message.zig @@ -51,7 +51,7 @@ fn preprocessorHandler(_: *Pragma, pp: *Preprocessor, start_idx: TokenIndex) Pra Diagnostics.formatArgs(&allocating.writer, diagnostic.fmt, .{str}) catch return error.OutOfMemory; try pp.diagnostics.add(.{ - .text = allocating.getWritten(), + .text = allocating.written(), .kind = diagnostic.kind, .opt = diagnostic.opt, .location = loc.expand(pp.comp), diff --git a/lib/compiler/aro/aro/text_literal.zig b/lib/compiler/aro/aro/text_literal.zig index 63556fe120..cb4ccdf12b 100644 --- a/lib/compiler/aro/aro/text_literal.zig +++ b/lib/compiler/aro/aro/text_literal.zig @@ -328,7 +328,7 @@ pub const Parser = struct { offset_location.byte_offset += p.offset; try p.comp.diagnostics.addWithLocation(p.comp, .{ .kind = diagnostic.kind, - .text = allocating.getWritten(), + .text = allocating.written(), .opt = diagnostic.opt, .extension = diagnostic.extension, .location = offset_location.expand(p.comp), diff --git a/lib/compiler/translate-c/Translator.zig b/lib/compiler/translate-c/Translator.zig index 0b7974c47b..cd42134a88 100644 --- a/lib/compiler/translate-c/Translator.zig +++ b/lib/compiler/translate-c/Translator.zig @@ -1005,7 +1005,7 @@ fn transStaticAssert(t: *Translator, scope: *Scope, static_assert: Node.StaticAs allocating.writer.end -= 1; // printString adds a terminating " so we need to remove it allocating.writer.writeAll("\\\"\"") catch return error.OutOfMemory; - break :str try ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.getWritten())); + break :str try ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.written())); } else try ZigTag.string_literal.create(t.arena, "\"static assertion failed\""); const assert_node = try ZigTag.static_assert.create(t.arena, .{ .lhs = condition, .rhs = diagnostic }); @@ -1020,7 +1020,7 @@ fn transGlobalAsm(t: *Translator, scope: *Scope, global_asm: Node.SimpleAsm) Err defer allocating.deinit(); aro.Value.printString(bytes, global_asm.asm_str.qt(t.tree), t.comp, &allocating.writer) catch return error.OutOfMemory; - const str_node = try ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.getWritten())); + const str_node = try ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.written())); const asm_node = try ZigTag.asm_simple.create(t.arena, str_node); const block = try ZigTag.block_single.create(t.arena, asm_node); @@ -1037,7 +1037,7 @@ fn getTypeStr(t: *Translator, qt: QualType) ![]const u8 { var allocating: std.Io.Writer.Allocating = .init(t.gpa); defer allocating.deinit(); qt.print(t.comp, &allocating.writer) catch return error.OutOfMemory; - return t.arena.dupe(u8, allocating.getWritten()); + return t.arena.dupe(u8, allocating.written()); } fn transType(t: *Translator, scope: *Scope, qt: QualType, source_loc: TokenIndex) TypeError!ZigNode { @@ -3345,7 +3345,7 @@ fn transFloatLiteral( defer allocating.deinit(); _ = val.print(float_literal.qt, t.comp, &allocating.writer) catch return error.OutOfMemory; - const float_lit_node = try ZigTag.float_literal.create(t.arena, try t.arena.dupe(u8, allocating.getWritten())); + const float_lit_node = try ZigTag.float_literal.create(t.arena, try t.arena.dupe(u8, allocating.written())); if (suppress_as == .no_as) { return t.maybeSuppressResult(used, float_lit_node); } @@ -3390,7 +3390,7 @@ fn transNarrowStringLiteral( aro.Value.printString(bytes, literal.qt, t.comp, &allocating.writer) catch return error.OutOfMemory; - return ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.getWritten())); + return ZigTag.string_literal.create(t.arena, try t.arena.dupe(u8, allocating.written())); } /// Translate a string literal that is initializing an array. In general narrow string diff --git a/lib/compiler/translate-c/main.zig b/lib/compiler/translate-c/main.zig index 15ec8b436c..6caa902c4b 100644 --- a/lib/compiler/translate-c/main.zig +++ b/lib/compiler/translate-c/main.zig @@ -145,7 +145,11 @@ fn translate(d: *aro.Driver, tc: *aro.Toolchain, args: [][:0]u8) !void { defer pp.deinit(); var name_buf: [std.fs.max_name_bytes]u8 = undefined; - var opt_dep_file = try d.initDepFile(source, &name_buf); + // Omit the source file from the dep file so that it can be tracked separately. + // In the Zig compiler we want to omit it from the cache hash since it will + // be written to a tmp file then renamed into place, meaning the path will be + // wrong as soon as the work is done. + var opt_dep_file = try d.initDepFile(source, &name_buf, true); defer if (opt_dep_file) |*dep_file| dep_file.deinit(pp.gpa); if (opt_dep_file) |*dep_file| pp.dep_file = dep_file;