| author | |
| committer | |
| log | 31daea74d23be813737892a166cc16ade1272a1a |
| tree | b25f5d80c2a9c63fe6d0099af5f89d38ed492112 |
| parent | 5e4483fff8077ec8d87ba9125f946955a34b6fc0 |
Closes #7668
Closes #121418 files changed, 197 insertions(+), 40 deletions(-)
lib/build_runner.zig+12| ... | ... | @@ -185,6 +185,16 @@ pub fn main() !void { |
| 185 | 185 | builder.use_stage1 = true; |
| 186 | 186 | } else if (mem.eql(u8, arg, "-fno-stage1")) { |
| 187 | 187 | builder.use_stage1 = false; |
| 188 | } else if (mem.eql(u8, arg, "-freference-trace")) { | |
| 189 | builder.reference_trace = 256; | |
| 190 | } else if (mem.startsWith(u8, arg, "-freference-trace=")) { | |
| 191 | const num = arg["-freference-trace=".len..]; | |
| 192 | builder.reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { | |
| 193 | std.debug.print("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) }); | |
| 194 | process.exit(1); | |
| 195 | }; | |
| 196 | } else if (mem.eql(u8, arg, "-fno-reference-trace")) { | |
| 197 | builder.reference_trace = null; | |
| 188 | 198 | } else if (mem.eql(u8, arg, "--")) { |
| 189 | 199 | builder.args = argsRest(args, arg_idx); |
| 190 | 200 | break; |
| ... | ... | @@ -308,6 +318,8 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void |
| 308 | 318 | \\Advanced Options: |
| 309 | 319 | \\ -fstage1 Force using bootstrap compiler as the codegen backend |
| 310 | 320 | \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend |
| 321 | \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error | |
| 322 | \\ -fno-reference-trace Disable reference trace | |
| 311 | 323 | \\ --build-file [file] Override path to build.zig |
| 312 | 324 | \\ --cache-dir [path] Override path to local Zig cache directory |
| 313 | 325 | \\ --global-cache-dir [path] Override path to global Zig cache directory |
lib/std/build.zig+5| ... | ... | @@ -45,6 +45,7 @@ pub const Builder = struct { |
| 45 | 45 | /// The purpose of executing the command is for a human to read compile errors from the terminal |
| 46 | 46 | prominent_compile_errors: bool, |
| 47 | 47 | color: enum { auto, on, off } = .auto, |
| 48 | reference_trace: ?u32 = null, | |
| 48 | 49 | use_stage1: ?bool = null, |
| 49 | 50 | invalid_user_input: bool, |
| 50 | 51 | zig_exe: []const u8, |
| ... | ... | @@ -2475,6 +2476,10 @@ pub const LibExeObjStep = struct { |
| 2475 | 2476 | try zig_args.append(@tagName(builder.color)); |
| 2476 | 2477 | } |
| 2477 | 2478 | |
| 2479 | if (builder.reference_trace) |some| { | |
| 2480 | try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-freference-trace={d}", .{some})); | |
| 2481 | } | |
| 2482 | ||
| 2478 | 2483 | if (self.use_stage1) |stage1| { |
| 2479 | 2484 | if (stage1) { |
| 2480 | 2485 | try zig_args.append("-fstage1"); |
src/Compilation.zig+62| ... | ... | @@ -154,6 +154,10 @@ owned_link_dir: ?std.fs.Dir, |
| 154 | 154 | /// Don't use this for anything other than stage1 compatibility. |
| 155 | 155 | color: Color = .auto, |
| 156 | 156 | |
| 157 | /// How many lines of reference trace should be included per compile error. | |
| 158 | /// Null means only show snippet on first error. | |
| 159 | reference_trace: ?u32 = null, | |
| 160 | ||
| 157 | 161 | libcxx_abi_version: libcxx.AbiVersion = libcxx.AbiVersion.default, |
| 158 | 162 | |
| 159 | 163 | /// This mutex guards all `Compilation` mutable state. |
| ... | ... | @@ -348,6 +352,7 @@ pub const AllErrors = struct { |
| 348 | 352 | /// Does not include the trailing newline. |
| 349 | 353 | source_line: ?[]const u8, |
| 350 | 354 | notes: []Message = &.{}, |
| 355 | reference_trace: []Message = &.{}, | |
| 351 | 356 | |
| 352 | 357 | /// Splits the error message up into lines to properly indent them |
| 353 | 358 | /// to allow for long, good-looking error messages. |
| ... | ... | @@ -447,6 +452,34 @@ pub const AllErrors = struct { |
| 447 | 452 | for (src.notes) |note| { |
| 448 | 453 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent); |
| 449 | 454 | } |
| 455 | if (src.reference_trace.len != 0) { | |
| 456 | ttyconf.setColor(stderr, .Reset); | |
| 457 | ttyconf.setColor(stderr, .Dim); | |
| 458 | try stderr.print("referenced by:\n", .{}); | |
| 459 | for (src.reference_trace) |reference| { | |
| 460 | switch (reference) { | |
| 461 | .src => |ref_src| try stderr.print(" {s}: {s}:{d}:{d}\n", .{ | |
| 462 | ref_src.msg, | |
| 463 | ref_src.src_path, | |
| 464 | ref_src.line + 1, | |
| 465 | ref_src.column + 1, | |
| 466 | }), | |
| 467 | .plain => |plain| if (plain.count != 0) { | |
| 468 | try stderr.print( | |
| 469 | " {d} reference(s) hidden; use '-freference-trace={d}' to see all references\n", | |
| 470 | .{ plain.count, plain.count + src.reference_trace.len - 1 }, | |
| 471 | ); | |
| 472 | } else { | |
| 473 | try stderr.print( | |
| 474 | " remaining reference traces hidden; use '-freference-trace' to see all reference traces\n", | |
| 475 | .{}, | |
| 476 | ); | |
| 477 | }, | |
| 478 | } | |
| 479 | } | |
| 480 | try stderr.writeByte('\n'); | |
| 481 | ttyconf.setColor(stderr, .Reset); | |
| 482 | } | |
| 450 | 483 | }, |
| 451 | 484 | .plain => |plain| { |
| 452 | 485 | ttyconf.setColor(stderr, color); |
| ... | ... | @@ -572,6 +605,32 @@ pub const AllErrors = struct { |
| 572 | 605 | }); |
| 573 | 606 | return; |
| 574 | 607 | } |
| 608 | ||
| 609 | const reference_trace = try allocator.alloc(Message, module_err_msg.reference_trace.len); | |
| 610 | for (reference_trace) |*reference, i| { | |
| 611 | const module_reference = module_err_msg.reference_trace[i]; | |
| 612 | if (module_reference.hidden != 0) { | |
| 613 | reference.* = .{ .plain = .{ .msg = undefined, .count = module_reference.hidden } }; | |
| 614 | break; | |
| 615 | } else if (module_reference.decl == null) { | |
| 616 | reference.* = .{ .plain = .{ .msg = undefined, .count = 0 } }; | |
| 617 | break; | |
| 618 | } | |
| 619 | const source = try module_reference.src_loc.file_scope.getSource(module.gpa); | |
| 620 | const span = try module_reference.src_loc.span(module.gpa); | |
| 621 | const loc = std.zig.findLineColumn(source.bytes, span.main); | |
| 622 | const file_path = try module_reference.src_loc.file_scope.fullPath(allocator); | |
| 623 | reference.* = .{ | |
| 624 | .src = .{ | |
| 625 | .src_path = file_path, | |
| 626 | .msg = try allocator.dupe(u8, std.mem.sliceTo(module_reference.decl.?, 0)), | |
| 627 | .span = span, | |
| 628 | .line = @intCast(u32, loc.line), | |
| 629 | .column = @intCast(u32, loc.column), | |
| 630 | .source_line = null, | |
| 631 | }, | |
| 632 | }; | |
| 633 | } | |
| 575 | 634 | const file_path = try module_err_msg.src_loc.file_scope.fullPath(allocator); |
| 576 | 635 | try errors.append(.{ |
| 577 | 636 | .src = .{ |
| ... | ... | @@ -581,6 +640,7 @@ pub const AllErrors = struct { |
| 581 | 640 | .line = @intCast(u32, err_loc.line), |
| 582 | 641 | .column = @intCast(u32, err_loc.column), |
| 583 | 642 | .notes = notes_buf[0..note_i], |
| 643 | .reference_trace = reference_trace, | |
| 584 | 644 | .source_line = try allocator.dupe(u8, err_loc.source_line), |
| 585 | 645 | }, |
| 586 | 646 | }); |
| ... | ... | @@ -929,6 +989,7 @@ pub const InitOptions = struct { |
| 929 | 989 | clang_preprocessor_mode: ClangPreprocessorMode = .no, |
| 930 | 990 | /// This is for stage1 and should be deleted upon completion of self-hosting. |
| 931 | 991 | color: Color = .auto, |
| 992 | reference_trace: ?u32 = null, | |
| 932 | 993 | test_filter: ?[]const u8 = null, |
| 933 | 994 | test_name_prefix: ?[]const u8 = null, |
| 934 | 995 | subsystem: ?std.Target.SubSystem = null, |
| ... | ... | @@ -1838,6 +1899,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1838 | 1899 | .disable_c_depfile = options.disable_c_depfile, |
| 1839 | 1900 | .owned_link_dir = owned_link_dir, |
| 1840 | 1901 | .color = options.color, |
| 1902 | .reference_trace = options.reference_trace, | |
| 1841 | 1903 | .time_report = options.time_report, |
| 1842 | 1904 | .stack_report = options.stack_report, |
| 1843 | 1905 | .unwind_tables = unwind_tables, |
src/Module.zig+20| ... | ... | @@ -166,6 +166,11 @@ decls_free_list: std.ArrayListUnmanaged(Decl.Index) = .{}, |
| 166 | 166 | |
| 167 | 167 | global_assembly: std.AutoHashMapUnmanaged(Decl.Index, []u8) = .{}, |
| 168 | 168 | |
| 169 | reference_table: std.AutoHashMapUnmanaged(Decl.Index, struct { | |
| 170 | referencer: Decl.Index, | |
| 171 | src: LazySrcLoc, | |
| 172 | }) = .{}, | |
| 173 | ||
| 169 | 174 | pub const StringLiteralContext = struct { |
| 170 | 175 | bytes: *std.ArrayListUnmanaged(u8), |
| 171 | 176 | |
| ... | ... | @@ -2084,6 +2089,13 @@ pub const ErrorMsg = struct { |
| 2084 | 2089 | src_loc: SrcLoc, |
| 2085 | 2090 | msg: []const u8, |
| 2086 | 2091 | notes: []ErrorMsg = &.{}, |
| 2092 | reference_trace: []Trace = &.{}, | |
| 2093 | ||
| 2094 | pub const Trace = struct { | |
| 2095 | decl: ?[*:0]const u8, | |
| 2096 | src_loc: SrcLoc, | |
| 2097 | hidden: u32 = 0, | |
| 2098 | }; | |
| 2087 | 2099 | |
| 2088 | 2100 | pub fn create( |
| 2089 | 2101 | gpa: Allocator, |
| ... | ... | @@ -2122,8 +2134,15 @@ pub const ErrorMsg = struct { |
| 2122 | 2134 | } |
| 2123 | 2135 | gpa.free(err_msg.notes); |
| 2124 | 2136 | gpa.free(err_msg.msg); |
| 2137 | gpa.free(err_msg.reference_trace); | |
| 2125 | 2138 | err_msg.* = undefined; |
| 2126 | 2139 | } |
| 2140 | ||
| 2141 | pub fn clearTrace(err_msg: *ErrorMsg, gpa: Allocator) void { | |
| 2142 | if (err_msg.reference_trace.len == 0) return; | |
| 2143 | gpa.free(err_msg.reference_trace); | |
| 2144 | err_msg.reference_trace = &.{}; | |
| 2145 | } | |
| 2127 | 2146 | }; |
| 2128 | 2147 | |
| 2129 | 2148 | /// Canonical reference to a position within a source file. |
| ... | ... | @@ -3411,6 +3430,7 @@ pub fn deinit(mod: *Module) void { |
| 3411 | 3430 | mod.decls_free_list.deinit(gpa); |
| 3412 | 3431 | mod.allocated_decls.deinit(gpa); |
| 3413 | 3432 | mod.global_assembly.deinit(gpa); |
| 3433 | mod.reference_table.deinit(gpa); | |
| 3414 | 3434 | |
| 3415 | 3435 | mod.string_literal_table.deinit(gpa); |
| 3416 | 3436 | mod.string_literal_bytes.deinit(gpa); |
src/Sema.zig+62-25| ... | ... | @@ -111,6 +111,7 @@ const crash_report = @import("crash_report.zig"); |
| 111 | 111 | const build_options = @import("build_options"); |
| 112 | 112 | |
| 113 | 113 | pub const default_branch_quota = 1000; |
| 114 | pub const default_reference_trace_len = 2; | |
| 114 | 115 | |
| 115 | 116 | pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref); |
| 116 | 117 | |
| ... | ... | @@ -1958,13 +1959,53 @@ fn failWithOwnedErrorMsg(sema: *Sema, err_msg: *Module.ErrorMsg) CompileError { |
| 1958 | 1959 | } |
| 1959 | 1960 | |
| 1960 | 1961 | const mod = sema.mod; |
| 1961 | { | |
| 1962 | ref: { | |
| 1962 | 1963 | errdefer err_msg.destroy(mod.gpa); |
| 1963 | 1964 | if (err_msg.src_loc.lazy == .unneeded) { |
| 1964 | 1965 | return error.NeededSourceLocation; |
| 1965 | 1966 | } |
| 1966 | 1967 | try mod.failed_decls.ensureUnusedCapacity(mod.gpa, 1); |
| 1967 | 1968 | try mod.failed_files.ensureUnusedCapacity(mod.gpa, 1); |
| 1969 | ||
| 1970 | const max_references = blk: { | |
| 1971 | if (sema.mod.comp.reference_trace) |num| break :blk num; | |
| 1972 | // Do not add multiple traces without explicit request. | |
| 1973 | if (sema.mod.failed_decls.count() != 0) break :ref; | |
| 1974 | break :blk default_reference_trace_len; | |
| 1975 | }; | |
| 1976 | ||
| 1977 | var referenced_by = if (sema.func) |some| some.owner_decl else sema.owner_decl_index; | |
| 1978 | var reference_stack = std.ArrayList(Module.ErrorMsg.Trace).init(sema.gpa); | |
| 1979 | defer reference_stack.deinit(); | |
| 1980 | ||
| 1981 | // Avoid infinite loops. | |
| 1982 | var seen = std.AutoHashMap(Module.Decl.Index, void).init(sema.gpa); | |
| 1983 | defer seen.deinit(); | |
| 1984 | ||
| 1985 | var cur_reference_trace: u32 = 0; | |
| 1986 | while (sema.mod.reference_table.get(referenced_by)) |ref| : (cur_reference_trace += 1) { | |
| 1987 | const gop = try seen.getOrPut(ref.referencer); | |
| 1988 | if (gop.found_existing) break; | |
| 1989 | if (cur_reference_trace < max_references) { | |
| 1990 | const decl = sema.mod.declPtr(ref.referencer); | |
| 1991 | try reference_stack.append(.{ .decl = decl.name, .src_loc = ref.src.toSrcLoc(decl) }); | |
| 1992 | } | |
| 1993 | referenced_by = ref.referencer; | |
| 1994 | } | |
| 1995 | if (sema.mod.comp.reference_trace == null and cur_reference_trace > 0) { | |
| 1996 | try reference_stack.append(.{ | |
| 1997 | .decl = null, | |
| 1998 | .src_loc = undefined, | |
| 1999 | .hidden = 0, | |
| 2000 | }); | |
| 2001 | } else if (cur_reference_trace > max_references) { | |
| 2002 | try reference_stack.append(.{ | |
| 2003 | .decl = undefined, | |
| 2004 | .src_loc = undefined, | |
| 2005 | .hidden = cur_reference_trace - max_references, | |
| 2006 | }); | |
| 2007 | } | |
| 2008 | err_msg.reference_trace = reference_stack.toOwnedSlice(); | |
| 1968 | 2009 | } |
| 1969 | 2010 | if (sema.owner_func) |func| { |
| 1970 | 2011 | func.state = .sema_failure; |
| ... | ... | @@ -5366,14 +5407,8 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 5366 | 5407 | const src = inst_data.src(); |
| 5367 | 5408 | const decl_name = inst_data.get(sema.code); |
| 5368 | 5409 | const decl_index = try sema.lookupIdentifier(block, src, decl_name); |
| 5369 | return sema.analyzeDeclRef(decl_index) catch |err| switch (err) { | |
| 5370 | error.AnalysisFail => { | |
| 5371 | const msg = sema.err orelse return err; | |
| 5372 | try sema.errNote(block, src, msg, "referenced here", .{}); | |
| 5373 | return err; | |
| 5374 | }, | |
| 5375 | else => return err, | |
| 5376 | }; | |
| 5410 | try sema.addReferencedBy(block, src, decl_index); | |
| 5411 | return sema.analyzeDeclRef(decl_index); | |
| 5377 | 5412 | } |
| 5378 | 5413 | |
| 5379 | 5414 | fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | ... | @@ -6107,6 +6142,7 @@ fn analyzeCall( |
| 6107 | 6142 | error.AnalysisFail => { |
| 6108 | 6143 | const err_msg = sema.err orelse return err; |
| 6109 | 6144 | try sema.errNote(block, call_src, err_msg, "called from here", .{}); |
| 6145 | err_msg.clearTrace(sema.gpa); | |
| 6110 | 6146 | return err; |
| 6111 | 6147 | }, |
| 6112 | 6148 | else => |e| return e, |
| ... | ... | @@ -21741,14 +21777,8 @@ fn namespaceLookupRef( |
| 21741 | 21777 | decl_name: []const u8, |
| 21742 | 21778 | ) CompileError!?Air.Inst.Ref { |
| 21743 | 21779 | const decl = (try sema.namespaceLookup(block, src, namespace, decl_name)) orelse return null; |
| 21744 | return sema.analyzeDeclRef(decl) catch |err| switch (err) { | |
| 21745 | error.AnalysisFail => { | |
| 21746 | const msg = sema.err orelse return err; | |
| 21747 | try sema.errNote(block, src, msg, "referenced here", .{}); | |
| 21748 | return err; | |
| 21749 | }, | |
| 21750 | else => return err, | |
| 21751 | }; | |
| 21780 | try sema.addReferencedBy(block, src, decl); | |
| 21781 | return try sema.analyzeDeclRef(decl); | |
| 21752 | 21782 | } |
| 21753 | 21783 | |
| 21754 | 21784 | fn namespaceLookupVal( |
| ... | ... | @@ -26001,14 +26031,8 @@ fn analyzeDeclVal( |
| 26001 | 26031 | if (sema.decl_val_table.get(decl_index)) |result| { |
| 26002 | 26032 | return result; |
| 26003 | 26033 | } |
| 26004 | const decl_ref = sema.analyzeDeclRef(decl_index) catch |err| switch (err) { | |
| 26005 | error.AnalysisFail => { | |
| 26006 | const msg = sema.err orelse return err; | |
| 26007 | try sema.errNote(block, src, msg, "referenced here", .{}); | |
| 26008 | return err; | |
| 26009 | }, | |
| 26010 | else => return err, | |
| 26011 | }; | |
| 26034 | try sema.addReferencedBy(block, src, decl_index); | |
| 26035 | const decl_ref = try sema.analyzeDeclRef(decl_index); | |
| 26012 | 26036 | const result = try sema.analyzeLoad(block, src, decl_ref, src); |
| 26013 | 26037 | if (Air.refToIndex(result)) |index| { |
| 26014 | 26038 | if (sema.air_instructions.items(.tag)[index] == .constant and !block.is_typeof) { |
| ... | ... | @@ -26018,6 +26042,19 @@ fn analyzeDeclVal( |
| 26018 | 26042 | return result; |
| 26019 | 26043 | } |
| 26020 | 26044 | |
| 26045 | fn addReferencedBy( | |
| 26046 | sema: *Sema, | |
| 26047 | block: *Block, | |
| 26048 | src: LazySrcLoc, | |
| 26049 | decl_index: Decl.Index, | |
| 26050 | ) !void { | |
| 26051 | if (sema.mod.comp.reference_trace == @as(u32, 0)) return; | |
| 26052 | try sema.mod.reference_table.put(sema.gpa, decl_index, .{ | |
| 26053 | .referencer = block.src_decl, | |
| 26054 | .src = src, | |
| 26055 | }); | |
| 26056 | } | |
| 26057 | ||
| 26021 | 26058 | fn ensureDeclAnalyzed(sema: *Sema, decl_index: Decl.Index) CompileError!void { |
| 26022 | 26059 | const decl = sema.mod.declPtr(decl_index); |
| 26023 | 26060 | if (decl.analysis == .in_progress) { |
src/main.zig+35-14| ... | ... | @@ -396,6 +396,8 @@ const usage_build_generic = |
| 396 | 396 | \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend |
| 397 | 397 | \\ -fstage1 Force using bootstrap compiler as the codegen backend |
| 398 | 398 | \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend |
| 399 | \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error | |
| 400 | \\ -fno-reference-trace Disable reference trace | |
| 399 | 401 | \\ -fsingle-threaded Code assumes there is only one thread |
| 400 | 402 | \\ -fno-single-threaded Code may not assume there is only one thread |
| 401 | 403 | \\ -fbuiltin Enable implicit builtin knowledge of functions |
| ... | ... | @@ -742,6 +744,7 @@ fn buildOutputType( |
| 742 | 744 | var headerpad_size: ?u32 = null; |
| 743 | 745 | var headerpad_max_install_names: bool = false; |
| 744 | 746 | var dead_strip_dylibs: bool = false; |
| 747 | var reference_trace: ?u32 = null; | |
| 745 | 748 | |
| 746 | 749 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. |
| 747 | 750 | // This array is populated by zig cc frontend and then has to be converted to zig-style |
| ... | ... | @@ -928,14 +931,14 @@ fn buildOutputType( |
| 928 | 931 | fatal("expected parameter after {s}", .{arg}); |
| 929 | 932 | }; |
| 930 | 933 | stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { |
| 931 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 934 | fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 932 | 935 | }; |
| 933 | 936 | } else if (mem.eql(u8, arg, "--image-base")) { |
| 934 | 937 | const next_arg = args_iter.next() orelse { |
| 935 | 938 | fatal("expected parameter after {s}", .{arg}); |
| 936 | 939 | }; |
| 937 | 940 | image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| { |
| 938 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 941 | fatal("unable to parse image base override '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 939 | 942 | }; |
| 940 | 943 | } else if (mem.eql(u8, arg, "--name")) { |
| 941 | 944 | provided_name = args_iter.next() orelse { |
| ... | ... | @@ -984,7 +987,7 @@ fn buildOutputType( |
| 984 | 987 | fatal("expected parameter after {s}", .{arg}); |
| 985 | 988 | }; |
| 986 | 989 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 987 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 990 | fatal("unable to parse pagezero size'{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 988 | 991 | }; |
| 989 | 992 | } else if (mem.eql(u8, arg, "-search_paths_first")) { |
| 990 | 993 | search_strategy = .paths_first; |
| ... | ... | @@ -995,7 +998,7 @@ fn buildOutputType( |
| 995 | 998 | fatal("expected parameter after {s}", .{arg}); |
| 996 | 999 | }; |
| 997 | 1000 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 998 | fatal("unable to parser '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1001 | fatal("unable to parse headerpat size '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 999 | 1002 | }; |
| 1000 | 1003 | } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { |
| 1001 | 1004 | headerpad_max_install_names = true; |
| ... | ... | @@ -1214,6 +1217,15 @@ fn buildOutputType( |
| 1214 | 1217 | use_stage1 = true; |
| 1215 | 1218 | } else if (mem.eql(u8, arg, "-fno-stage1")) { |
| 1216 | 1219 | use_stage1 = false; |
| 1220 | } else if (mem.eql(u8, arg, "-freference-trace")) { | |
| 1221 | reference_trace = 256; | |
| 1222 | } else if (mem.startsWith(u8, arg, "-freference-trace=")) { | |
| 1223 | const num = arg["-freference-trace=".len..]; | |
| 1224 | reference_trace = std.fmt.parseUnsigned(u32, num, 10) catch |err| { | |
| 1225 | fatal("unable to parse reference_trace count '{s}': {s}", .{ num, @errorName(err) }); | |
| 1226 | }; | |
| 1227 | } else if (mem.eql(u8, arg, "-fno-reference-trace")) { | |
| 1228 | reference_trace = null; | |
| 1217 | 1229 | } else if (mem.eql(u8, arg, "-rdynamic")) { |
| 1218 | 1230 | rdynamic = true; |
| 1219 | 1231 | } else if (mem.eql(u8, arg, "-fsoname")) { |
| ... | ... | @@ -1785,11 +1797,11 @@ fn buildOutputType( |
| 1785 | 1797 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1786 | 1798 | } |
| 1787 | 1799 | linker_optimization = std.fmt.parseUnsigned(u8, linker_args.items[i], 10) catch |err| { |
| 1788 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1800 | fatal("unable to parse optimization level '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1789 | 1801 | }; |
| 1790 | 1802 | } else if (mem.startsWith(u8, arg, "-O")) { |
| 1791 | 1803 | linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| { |
| 1792 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1804 | fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1793 | 1805 | }; |
| 1794 | 1806 | } else if (mem.eql(u8, arg, "-pagezero_size")) { |
| 1795 | 1807 | i += 1; |
| ... | ... | @@ -1798,7 +1810,7 @@ fn buildOutputType( |
| 1798 | 1810 | } |
| 1799 | 1811 | const next_arg = linker_args.items[i]; |
| 1800 | 1812 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 1801 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1813 | fatal("unable to parse pagezero size '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 1802 | 1814 | }; |
| 1803 | 1815 | } else if (mem.eql(u8, arg, "-headerpad")) { |
| 1804 | 1816 | i += 1; |
| ... | ... | @@ -1807,7 +1819,7 @@ fn buildOutputType( |
| 1807 | 1819 | } |
| 1808 | 1820 | const next_arg = linker_args.items[i]; |
| 1809 | 1821 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 1810 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1822 | fatal("unable to parse headerpad size '{s}': {s}", .{ next_arg, @errorName(err) }); | |
| 1811 | 1823 | }; |
| 1812 | 1824 | } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { |
| 1813 | 1825 | headerpad_max_install_names = true; |
| ... | ... | @@ -1899,7 +1911,7 @@ fn buildOutputType( |
| 1899 | 1911 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1900 | 1912 | } |
| 1901 | 1913 | version.major = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { |
| 1902 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1914 | fatal("unable to parse major image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1903 | 1915 | }; |
| 1904 | 1916 | have_version = true; |
| 1905 | 1917 | } else if (mem.eql(u8, arg, "--minor-image-version")) { |
| ... | ... | @@ -1908,7 +1920,7 @@ fn buildOutputType( |
| 1908 | 1920 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1909 | 1921 | } |
| 1910 | 1922 | version.minor = std.fmt.parseUnsigned(u32, linker_args.items[i], 10) catch |err| { |
| 1911 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1923 | fatal("unable to parse minor image version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1912 | 1924 | }; |
| 1913 | 1925 | have_version = true; |
| 1914 | 1926 | } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) { |
| ... | ... | @@ -1923,7 +1935,7 @@ fn buildOutputType( |
| 1923 | 1935 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1924 | 1936 | } |
| 1925 | 1937 | stack_size_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { |
| 1926 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1938 | fatal("unable to parse stack size override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1927 | 1939 | }; |
| 1928 | 1940 | } else if (mem.eql(u8, arg, "--image-base")) { |
| 1929 | 1941 | i += 1; |
| ... | ... | @@ -1931,7 +1943,7 @@ fn buildOutputType( |
| 1931 | 1943 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1932 | 1944 | } |
| 1933 | 1945 | image_base_override = std.fmt.parseUnsigned(u64, linker_args.items[i], 0) catch |err| { |
| 1934 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1946 | fatal("unable to parse image base override '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1935 | 1947 | }; |
| 1936 | 1948 | } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) { |
| 1937 | 1949 | i += 1; |
| ... | ... | @@ -1984,7 +1996,7 @@ fn buildOutputType( |
| 1984 | 1996 | linker_args.items[i], |
| 1985 | 1997 | 10, |
| 1986 | 1998 | ) catch |err| { |
| 1987 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 1999 | fatal("unable to parse major subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 1988 | 2000 | }; |
| 1989 | 2001 | } else if (mem.eql(u8, arg, "--minor-subsystem-version")) { |
| 1990 | 2002 | i += 1; |
| ... | ... | @@ -1997,7 +2009,7 @@ fn buildOutputType( |
| 1997 | 2009 | linker_args.items[i], |
| 1998 | 2010 | 10, |
| 1999 | 2011 | ) catch |err| { |
| 2000 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); | |
| 2012 | fatal("unable to parse minor subsystem version '{s}': {s}", .{ linker_args.items[i], @errorName(err) }); | |
| 2001 | 2013 | }; |
| 2002 | 2014 | } else if (mem.eql(u8, arg, "-framework")) { |
| 2003 | 2015 | i += 1; |
| ... | ... | @@ -2981,6 +2993,7 @@ fn buildOutputType( |
| 2981 | 2993 | .headerpad_size = headerpad_size, |
| 2982 | 2994 | .headerpad_max_install_names = headerpad_max_install_names, |
| 2983 | 2995 | .dead_strip_dylibs = dead_strip_dylibs, |
| 2996 | .reference_trace = reference_trace, | |
| 2984 | 2997 | }) catch |err| switch (err) { |
| 2985 | 2998 | error.LibCUnavailable => { |
| 2986 | 2999 | const target = target_info.target; |
| ... | ... | @@ -3740,6 +3753,8 @@ pub const usage_build = |
| 3740 | 3753 | \\Options: |
| 3741 | 3754 | \\ -fstage1 Force using bootstrap compiler as the codegen backend |
| 3742 | 3755 | \\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend |
| 3756 | \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error | |
| 3757 | \\ -fno-reference-trace Disable reference trace | |
| 3743 | 3758 | \\ --build-file [file] Override path to build.zig |
| 3744 | 3759 | \\ --cache-dir [path] Override path to local Zig cache directory |
| 3745 | 3760 | \\ --global-cache-dir [path] Override path to global Zig cache directory |
| ... | ... | @@ -3812,6 +3827,12 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 3812 | 3827 | } else if (mem.eql(u8, arg, "-fno-stage1")) { |
| 3813 | 3828 | use_stage1 = false; |
| 3814 | 3829 | try child_argv.append(arg); |
| 3830 | } else if (mem.eql(u8, arg, "-freference-trace")) { | |
| 3831 | try child_argv.append(arg); | |
| 3832 | } else if (mem.startsWith(u8, arg, "-freference-trace=")) { | |
| 3833 | try child_argv.append(arg); | |
| 3834 | } else if (mem.eql(u8, arg, "-fno-reference-trace")) { | |
| 3835 | try child_argv.append(arg); | |
| 3815 | 3836 | } |
| 3816 | 3837 | } |
| 3817 | 3838 | try child_argv.append(arg); |
src/test.zig+1| ... | ... | @@ -1548,6 +1548,7 @@ pub const TestContext = struct { |
| 1548 | 1548 | .self_exe_path = std.testing.zig_exe_path, |
| 1549 | 1549 | // TODO instead of turning off color, pass in a std.Progress.Node |
| 1550 | 1550 | .color = .off, |
| 1551 | .reference_trace = 0, | |
| 1551 | 1552 | // TODO: force self-hosted linkers with stage2 backend to avoid LLD creeping in |
| 1552 | 1553 | // until the auto-select mechanism deems them worthy |
| 1553 | 1554 | .use_lld = switch (case.backend) { |
test/cases/compile_errors/top_level_decl_dependency_loop.zig-1| ... | ... | @@ -10,4 +10,3 @@ export fn entry() void { |
| 10 | 10 | // target=native |
| 11 | 11 | // |
| 12 | 12 | // :1:1: error: dependency loop detected |
| 13 | // :2:19: note: referenced here |