| author | |
| committer | |
| log | 23c817548bbd3988a5fd224b590a4f6102dbe5db |
| tree | 5448478794cb493b456de356c2e29fb100e81cfb |
| parent | f2077f57ae03ef21f1bfee6e4e041c5f466fc3be |
| parent | 37a9a4e0f16c1df8de3a4add3a9566b24f024a95 |
| signature |
Incremental fixes, refactor `Zcu.File`53 files changed, 2796 insertions(+), 2394 deletions(-)
build.zig+11-6| ... | @@ -508,11 +508,9 @@ pub fn build(b: *std.Build) !void { | ... | @@ -508,11 +508,9 @@ pub fn build(b: *std.Build) !void { |
| 508 | test_step.dependOn(unit_tests_step); | 508 | test_step.dependOn(unit_tests_step); |
| 509 | 509 | ||
| 510 | const unit_tests = b.addTest(.{ | 510 | const unit_tests = b.addTest(.{ |
| 511 | .root_module = b.createModule(.{ | 511 | .root_module = addCompilerMod(b, .{ |
| 512 | .root_source_file = b.path("src/main.zig"), | ||
| 513 | .optimize = optimize, | 512 | .optimize = optimize, |
| 514 | .target = target, | 513 | .target = target, |
| 515 | .link_libc = link_libc, | ||
| 516 | .single_threaded = single_threaded, | 514 | .single_threaded = single_threaded, |
| 517 | }), | 515 | }), |
| 518 | .filters = test_filters, | 516 | .filters = test_filters, |
| ... | @@ -520,6 +518,9 @@ pub fn build(b: *std.Build) !void { | ... | @@ -520,6 +518,9 @@ pub fn build(b: *std.Build) !void { |
| 520 | .use_lld = use_llvm, | 518 | .use_lld = use_llvm, |
| 521 | .zig_lib_dir = b.path("lib"), | 519 | .zig_lib_dir = b.path("lib"), |
| 522 | }); | 520 | }); |
| 521 | if (link_libc) { | ||
| 522 | unit_tests.root_module.link_libc = true; | ||
| 523 | } | ||
| 523 | unit_tests.root_module.addOptions("build_options", exe_options); | 524 | unit_tests.root_module.addOptions("build_options", exe_options); |
| 524 | unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step); | 525 | unit_tests_step.dependOn(&b.addRunArtifact(unit_tests).step); |
| 525 | 526 | ||
| ... | @@ -650,7 +651,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { | ... | @@ -650,7 +651,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { |
| 650 | update_zig1_step.dependOn(&copy_zig_h.step); | 651 | update_zig1_step.dependOn(&copy_zig_h.step); |
| 651 | } | 652 | } |
| 652 | 653 | ||
| 653 | const AddCompilerStepOptions = struct { | 654 | const AddCompilerModOptions = struct { |
| 654 | optimize: std.builtin.OptimizeMode, | 655 | optimize: std.builtin.OptimizeMode, |
| 655 | target: std.Build.ResolvedTarget, | 656 | target: std.Build.ResolvedTarget, |
| 656 | strip: ?bool = null, | 657 | strip: ?bool = null, |
| ... | @@ -659,7 +660,7 @@ const AddCompilerStepOptions = struct { | ... | @@ -659,7 +660,7 @@ const AddCompilerStepOptions = struct { |
| 659 | single_threaded: ?bool = null, | 660 | single_threaded: ?bool = null, |
| 660 | }; | 661 | }; |
| 661 | 662 | ||
| 662 | fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile { | 663 | fn addCompilerMod(b: *std.Build, options: AddCompilerModOptions) *std.Build.Module { |
| 663 | const compiler_mod = b.createModule(.{ | 664 | const compiler_mod = b.createModule(.{ |
| 664 | .root_source_file = b.path("src/main.zig"), | 665 | .root_source_file = b.path("src/main.zig"), |
| 665 | .target = options.target, | 666 | .target = options.target, |
| ... | @@ -682,10 +683,14 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St | ... | @@ -682,10 +683,14 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St |
| 682 | compiler_mod.addImport("aro", aro_mod); | 683 | compiler_mod.addImport("aro", aro_mod); |
| 683 | compiler_mod.addImport("aro_translate_c", aro_translate_c_mod); | 684 | compiler_mod.addImport("aro_translate_c", aro_translate_c_mod); |
| 684 | 685 | ||
| 686 | return compiler_mod; | ||
| 687 | } | ||
| 688 | |||
| 689 | fn addCompilerStep(b: *std.Build, options: AddCompilerModOptions) *std.Build.Step.Compile { | ||
| 685 | const exe = b.addExecutable(.{ | 690 | const exe = b.addExecutable(.{ |
| 686 | .name = "zig", | 691 | .name = "zig", |
| 687 | .max_rss = 7_800_000_000, | 692 | .max_rss = 7_800_000_000, |
| 688 | .root_module = compiler_mod, | 693 | .root_module = addCompilerMod(b, options), |
| 689 | }); | 694 | }); |
| 690 | exe.stack_size = stack_size; | 695 | exe.stack_size = stack_size; |
| 691 | 696 |
lib/std/Build/Cache.zig+2-3| ... | @@ -1011,17 +1011,16 @@ pub const Manifest = struct { | ... | @@ -1011,17 +1011,16 @@ pub const Manifest = struct { |
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | /// Like `addFilePost` but when the file contents have already been loaded from disk. | 1013 | /// Like `addFilePost` but when the file contents have already been loaded from disk. |
| 1014 | /// On success, cache takes ownership of `resolved_path`. | ||
| 1015 | pub fn addFilePostContents( | 1014 | pub fn addFilePostContents( |
| 1016 | self: *Manifest, | 1015 | self: *Manifest, |
| 1017 | resolved_path: []u8, | 1016 | file_path: []const u8, |
| 1018 | bytes: []const u8, | 1017 | bytes: []const u8, |
| 1019 | stat: File.Stat, | 1018 | stat: File.Stat, |
| 1020 | ) !void { | 1019 | ) !void { |
| 1021 | assert(self.manifest_file != null); | 1020 | assert(self.manifest_file != null); |
| 1022 | const gpa = self.cache.gpa; | 1021 | const gpa = self.cache.gpa; |
| 1023 | 1022 | ||
| 1024 | const prefixed_path = try self.cache.findPrefixResolved(resolved_path); | 1023 | const prefixed_path = try self.cache.findPrefix(file_path); |
| 1025 | errdefer gpa.free(prefixed_path.sub_path); | 1024 | errdefer gpa.free(prefixed_path.sub_path); |
| 1026 | 1025 | ||
| 1027 | const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{}); | 1026 | const gop = try self.files.getOrPutAdapted(gpa, prefixed_path, FilesAdapter{}); |
src/Builtin.zig+64-27| ... | @@ -19,6 +19,26 @@ code_model: std.builtin.CodeModel, | ... | @@ -19,6 +19,26 @@ code_model: std.builtin.CodeModel, |
| 19 | omit_frame_pointer: bool, | 19 | omit_frame_pointer: bool, |
| 20 | wasi_exec_model: std.builtin.WasiExecModel, | 20 | wasi_exec_model: std.builtin.WasiExecModel, |
| 21 | 21 | ||
| 22 | /// Compute an abstract hash representing this `Builtin`. This is *not* a hash | ||
| 23 | /// of the resulting file contents. | ||
| 24 | pub fn hash(opts: @This()) [std.Build.Cache.bin_digest_len]u8 { | ||
| 25 | var h: Cache.Hasher = Cache.hasher_init; | ||
| 26 | inline for (@typeInfo(@This()).@"struct".fields) |f| { | ||
| 27 | if (comptime std.mem.eql(u8, f.name, "target")) { | ||
| 28 | // This needs special handling. | ||
| 29 | std.hash.autoHash(&h, opts.target.cpu); | ||
| 30 | std.hash.autoHash(&h, opts.target.os.tag); | ||
| 31 | std.hash.autoHash(&h, opts.target.os.versionRange()); | ||
| 32 | std.hash.autoHash(&h, opts.target.abi); | ||
| 33 | std.hash.autoHash(&h, opts.target.ofmt); | ||
| 34 | std.hash.autoHash(&h, opts.target.dynamic_linker); | ||
| 35 | } else { | ||
| 36 | std.hash.autoHash(&h, @field(opts, f.name)); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | return h.finalResult(); | ||
| 40 | } | ||
| 41 | |||
| 22 | pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 { | 42 | pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 { |
| 23 | var buffer = std.ArrayList(u8).init(allocator); | 43 | var buffer = std.ArrayList(u8).init(allocator); |
| 24 | try append(opts, &buffer); | 44 | try append(opts, &buffer); |
| ... | @@ -263,50 +283,66 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { | ... | @@ -263,50 +283,66 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void { |
| 263 | } | 283 | } |
| 264 | } | 284 | } |
| 265 | 285 | ||
| 266 | pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void { | 286 | /// This essentially takes the place of `Zcu.PerThread.updateFile`, but for 'builtin' modules. |
| 267 | if (mod.root.statFile(mod.root_src_path)) |stat| { | 287 | /// Instead of reading the file from disk, its contents are generated in-memory. |
| 288 | pub fn populateFile(opts: @This(), gpa: Allocator, file: *File) Allocator.Error!void { | ||
| 289 | assert(file.is_builtin); | ||
| 290 | assert(file.status == .never_loaded); | ||
| 291 | assert(file.source == null); | ||
| 292 | assert(file.tree == null); | ||
| 293 | assert(file.zir == null); | ||
| 294 | |||
| 295 | file.source = try opts.generate(gpa); | ||
| 296 | |||
| 297 | log.debug("parsing and generating 'builtin.zig'", .{}); | ||
| 298 | |||
| 299 | file.tree = try std.zig.Ast.parse(gpa, file.source.?, .zig); | ||
| 300 | assert(file.tree.?.errors.len == 0); // builtin.zig must parse | ||
| 301 | |||
| 302 | file.zir = try AstGen.generate(gpa, file.tree.?); | ||
| 303 | assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors | ||
| 304 | file.status = .success; | ||
| 305 | } | ||
| 306 | |||
| 307 | /// After `populateFile` succeeds, call this function to write the generated file out to disk | ||
| 308 | /// if necessary. This is useful for external tooling such as debuggers. | ||
| 309 | /// Assumes that `file.mod` is correctly set to the builtin module. | ||
| 310 | pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { | ||
| 311 | assert(file.is_builtin); | ||
| 312 | assert(file.status == .success); | ||
| 313 | assert(file.source != null); | ||
| 314 | |||
| 315 | const root_dir, const sub_path = file.path.openInfo(comp.dirs); | ||
| 316 | |||
| 317 | if (root_dir.statFile(sub_path)) |stat| { | ||
| 268 | if (stat.size != file.source.?.len) { | 318 | if (stat.size != file.source.?.len) { |
| 269 | std.log.warn( | 319 | std.log.warn( |
| 270 | "the cached file '{}{s}' had the wrong size. Expected {d}, found {d}. " ++ | 320 | "the cached file '{}' had the wrong size. Expected {d}, found {d}. " ++ |
| 271 | "Overwriting with correct file contents now", | 321 | "Overwriting with correct file contents now", |
| 272 | .{ mod.root, mod.root_src_path, file.source.?.len, stat.size }, | 322 | .{ file.path.fmt(comp), file.source.?.len, stat.size }, |
| 273 | ); | 323 | ); |
| 274 | |||
| 275 | try writeFile(file, mod); | ||
| 276 | } else { | 324 | } else { |
| 277 | file.stat = .{ | 325 | file.stat = .{ |
| 278 | .size = stat.size, | 326 | .size = stat.size, |
| 279 | .inode = stat.inode, | 327 | .inode = stat.inode, |
| 280 | .mtime = stat.mtime, | 328 | .mtime = stat.mtime, |
| 281 | }; | 329 | }; |
| 330 | return; | ||
| 282 | } | 331 | } |
| 283 | } else |err| switch (err) { | 332 | } else |err| switch (err) { |
| 284 | error.BadPathName => unreachable, // it's always "builtin.zig" | 333 | error.FileNotFound => {}, |
| 285 | error.NameTooLong => unreachable, // it's always "builtin.zig" | ||
| 286 | error.PipeBusy => unreachable, // it's not a pipe | ||
| 287 | error.NoDevice => unreachable, // it's not a pipe | ||
| 288 | error.WouldBlock => unreachable, // not asking for non-blocking I/O | ||
| 289 | 334 | ||
| 290 | error.FileNotFound => try writeFile(file, mod), | 335 | error.WouldBlock => unreachable, // not asking for non-blocking I/O |
| 336 | error.BadPathName => unreachable, // it's always "o/digest/builtin.zig" | ||
| 337 | error.NameTooLong => unreachable, // it's always "o/digest/builtin.zig" | ||
| 291 | 338 | ||
| 339 | // We don't expect the file to be a pipe, but can't mark `error.PipeBusy` as `unreachable`, | ||
| 340 | // because the user could always replace the file on disk. | ||
| 292 | else => |e| return e, | 341 | else => |e| return e, |
| 293 | } | 342 | } |
| 294 | 343 | ||
| 295 | log.debug("parsing and generating '{s}'", .{mod.root_src_path}); | 344 | // `make_path` matters because the dir hasn't actually been created yet. |
| 296 | 345 | var af = try root_dir.atomicFile(sub_path, .{ .make_path = true }); | |
| 297 | file.tree = try std.zig.Ast.parse(comp.gpa, file.source.?, .zig); | ||
| 298 | assert(file.tree.?.errors.len == 0); // builtin.zig must parse | ||
| 299 | |||
| 300 | file.zir = try AstGen.generate(comp.gpa, file.tree.?); | ||
| 301 | assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors | ||
| 302 | file.status = .success; | ||
| 303 | // Note that whilst we set `zir` here, we populated `path_digest` | ||
| 304 | // all the way back in `Package.Module.create`. | ||
| 305 | } | ||
| 306 | |||
| 307 | fn writeFile(file: *File, mod: *Module) !void { | ||
| 308 | var buf: [std.fs.max_path_bytes]u8 = undefined; | ||
| 309 | var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf); | ||
| 310 | defer af.deinit(); | 346 | defer af.deinit(); |
| 311 | try af.file.writeAll(file.source.?); | 347 | try af.file.writeAll(file.source.?); |
| 312 | af.finish() catch |err| switch (err) { | 348 | af.finish() catch |err| switch (err) { |
| ... | @@ -331,6 +367,7 @@ fn writeFile(file: *File, mod: *Module) !void { | ... | @@ -331,6 +367,7 @@ fn writeFile(file: *File, mod: *Module) !void { |
| 331 | const builtin = @import("builtin"); | 367 | const builtin = @import("builtin"); |
| 332 | const std = @import("std"); | 368 | const std = @import("std"); |
| 333 | const Allocator = std.mem.Allocator; | 369 | const Allocator = std.mem.Allocator; |
| 370 | const Cache = std.Build.Cache; | ||
| 334 | const build_options = @import("build_options"); | 371 | const build_options = @import("build_options"); |
| 335 | const Module = @import("Package/Module.zig"); | 372 | const Module = @import("Package/Module.zig"); |
| 336 | const assert = std.debug.assert; | 373 | const assert = std.debug.assert; |
src/Compilation.zig+830-577| ... | @@ -2,6 +2,7 @@ const Compilation = @This(); | ... | @@ -2,6 +2,7 @@ const Compilation = @This(); |
| 2 | 2 | ||
| 3 | const std = @import("std"); | 3 | const std = @import("std"); |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | const fs = std.fs; | ||
| 5 | const mem = std.mem; | 6 | const mem = std.mem; |
| 6 | const Allocator = std.mem.Allocator; | 7 | const Allocator = std.mem.Allocator; |
| 7 | const assert = std.debug.assert; | 8 | const assert = std.debug.assert; |
| ... | @@ -10,12 +11,13 @@ const Target = std.Target; | ... | @@ -10,12 +11,13 @@ const Target = std.Target; |
| 10 | const ThreadPool = std.Thread.Pool; | 11 | const ThreadPool = std.Thread.Pool; |
| 11 | const WaitGroup = std.Thread.WaitGroup; | 12 | const WaitGroup = std.Thread.WaitGroup; |
| 12 | const ErrorBundle = std.zig.ErrorBundle; | 13 | const ErrorBundle = std.zig.ErrorBundle; |
| 13 | const Path = Cache.Path; | 14 | const fatal = std.process.fatal; |
| 14 | 15 | ||
| 15 | const Value = @import("Value.zig"); | 16 | const Value = @import("Value.zig"); |
| 16 | const Type = @import("Type.zig"); | 17 | const Type = @import("Type.zig"); |
| 17 | const target_util = @import("target.zig"); | 18 | const target_util = @import("target.zig"); |
| 18 | const Package = @import("Package.zig"); | 19 | const Package = @import("Package.zig"); |
| 20 | const introspect = @import("introspect.zig"); | ||
| 19 | const link = @import("link.zig"); | 21 | const link = @import("link.zig"); |
| 20 | const tracy = @import("tracy.zig"); | 22 | const tracy = @import("tracy.zig"); |
| 21 | const trace = tracy.trace; | 23 | const trace = tracy.trace; |
| ... | @@ -28,7 +30,6 @@ const mingw = @import("libs/mingw.zig"); | ... | @@ -28,7 +30,6 @@ const mingw = @import("libs/mingw.zig"); |
| 28 | const libunwind = @import("libs/libunwind.zig"); | 30 | const libunwind = @import("libs/libunwind.zig"); |
| 29 | const libcxx = @import("libs/libcxx.zig"); | 31 | const libcxx = @import("libs/libcxx.zig"); |
| 30 | const wasi_libc = @import("libs/wasi_libc.zig"); | 32 | const wasi_libc = @import("libs/wasi_libc.zig"); |
| 31 | const fatal = @import("main.zig").fatal; | ||
| 32 | const clangMain = @import("main.zig").clangMain; | 33 | const clangMain = @import("main.zig").clangMain; |
| 33 | const Zcu = @import("Zcu.zig"); | 34 | const Zcu = @import("Zcu.zig"); |
| 34 | const Sema = @import("Sema.zig"); | 35 | const Sema = @import("Sema.zig"); |
| ... | @@ -43,7 +44,6 @@ const LlvmObject = @import("codegen/llvm.zig").Object; | ... | @@ -43,7 +44,6 @@ const LlvmObject = @import("codegen/llvm.zig").Object; |
| 43 | const dev = @import("dev.zig"); | 44 | const dev = @import("dev.zig"); |
| 44 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; | 45 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; |
| 45 | 46 | ||
| 46 | pub const Directory = Cache.Directory; | ||
| 47 | pub const Config = @import("Compilation/Config.zig"); | 47 | pub const Config = @import("Compilation/Config.zig"); |
| 48 | 48 | ||
| 49 | /// General-purpose allocator. Used for both temporary and long-term storage. | 49 | /// General-purpose allocator. Used for both temporary and long-term storage. |
| ... | @@ -75,9 +75,9 @@ bin_file: ?*link.File, | ... | @@ -75,9 +75,9 @@ bin_file: ?*link.File, |
| 75 | /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) | 75 | /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin) |
| 76 | sysroot: ?[]const u8, | 76 | sysroot: ?[]const u8, |
| 77 | /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used. | 77 | /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used. |
| 78 | implib_emit: ?Path, | 78 | implib_emit: ?Cache.Path, |
| 79 | /// This is non-null when `-femit-docs` is provided. | 79 | /// This is non-null when `-femit-docs` is provided. |
| 80 | docs_emit: ?Path, | 80 | docs_emit: ?Cache.Path, |
| 81 | root_name: [:0]const u8, | 81 | root_name: [:0]const u8, |
| 82 | compiler_rt_strat: RtStrat, | 82 | compiler_rt_strat: RtStrat, |
| 83 | ubsan_rt_strat: RtStrat, | 83 | ubsan_rt_strat: RtStrat, |
| ... | @@ -152,11 +152,6 @@ win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.Linea | ... | @@ -152,11 +152,6 @@ win32_resource_work_queue: if (dev.env.supports(.win32_resource)) std.fifo.Linea |
| 152 | pub fn deinit(_: @This()) void {} | 152 | pub fn deinit(_: @This()) void {} |
| 153 | }, | 153 | }, |
| 154 | 154 | ||
| 155 | /// These jobs are to tokenize, parse, and astgen files, which may be outdated | ||
| 156 | /// since the last compilation, as well as scan for `@import` and queue up | ||
| 157 | /// additional jobs corresponding to those new files. | ||
| 158 | astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic), | ||
| 159 | |||
| 160 | /// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator. | 155 | /// The ErrorMsg memory is owned by the `CObject`, using Compilation's general purpose allocator. |
| 161 | /// This data is accessed by multiple threads and is protected by `mutex`. | 156 | /// This data is accessed by multiple threads and is protected by `mutex`. |
| 162 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.Diag.Bundle) = .empty, | 157 | failed_c_objects: std.AutoArrayHashMapUnmanaged(*CObject, *CObject.Diag.Bundle) = .empty, |
| ... | @@ -207,9 +202,8 @@ cache_parent: *Cache, | ... | @@ -207,9 +202,8 @@ cache_parent: *Cache, |
| 207 | parent_whole_cache: ?ParentWholeCache, | 202 | parent_whole_cache: ?ParentWholeCache, |
| 208 | /// Path to own executable for invoking `zig clang`. | 203 | /// Path to own executable for invoking `zig clang`. |
| 209 | self_exe_path: ?[]const u8, | 204 | self_exe_path: ?[]const u8, |
| 210 | zig_lib_directory: Directory, | 205 | /// Owned by the caller of `Compilation.create`. |
| 211 | local_cache_directory: Directory, | 206 | dirs: Directories, |
| 212 | global_cache_directory: Directory, | ||
| 213 | libc_include_dir_list: []const []const u8, | 207 | libc_include_dir_list: []const []const u8, |
| 214 | libc_framework_dir_list: []const []const u8, | 208 | libc_framework_dir_list: []const []const u8, |
| 215 | rc_includes: RcIncludes, | 209 | rc_includes: RcIncludes, |
| ... | @@ -293,7 +287,6 @@ const QueuedJobs = struct { | ... | @@ -293,7 +287,6 @@ const QueuedJobs = struct { |
| 293 | ubsan_rt_lib: bool = false, | 287 | ubsan_rt_lib: bool = false, |
| 294 | ubsan_rt_obj: bool = false, | 288 | ubsan_rt_obj: bool = false, |
| 295 | fuzzer_lib: bool = false, | 289 | fuzzer_lib: bool = false, |
| 296 | update_builtin_zig: bool, | ||
| 297 | musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false), | 290 | musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false), |
| 298 | glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false), | 291 | glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false), |
| 299 | freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false), | 292 | freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false), |
| ... | @@ -312,12 +305,466 @@ const QueuedJobs = struct { | ... | @@ -312,12 +305,466 @@ const QueuedJobs = struct { |
| 312 | zigc_lib: bool = false, | 305 | zigc_lib: bool = false, |
| 313 | }; | 306 | }; |
| 314 | 307 | ||
| 308 | /// A filesystem path, represented relative to one of a few specific directories where possible. | ||
| 309 | /// Every path (considering symlinks as distinct paths) has a canonical representation in this form. | ||
| 310 | /// This abstraction allows us to: | ||
| 311 | /// * always open files relative to a consistent root on the filesystem | ||
| 312 | /// * detect when two paths correspond to the same file, e.g. for deduplicating `@import`s | ||
| 313 | pub const Path = struct { | ||
| 314 | root: Root, | ||
| 315 | /// This path is always in a normalized form, where: | ||
| 316 | /// * All components are separated by `fs.path.sep` | ||
| 317 | /// * There are no repeated separators (like "foo//bar") | ||
| 318 | /// * There are no "." or ".." components | ||
| 319 | /// * There is no trailing path separator | ||
| 320 | /// | ||
| 321 | /// There is a leading separator iff `root` is `.none` *and* `builtin.target.os.tag != .wasi`. | ||
| 322 | /// | ||
| 323 | /// If this `Path` exactly represents a `Root`, the sub path is "", not ".". | ||
| 324 | sub_path: []u8, | ||
| 325 | |||
| 326 | const Root = enum { | ||
| 327 | /// `sub_path` is relative to the Zig lib directory on `Compilation`. | ||
| 328 | zig_lib, | ||
| 329 | /// `sub_path` is relative to the global cache directory on `Compilation`. | ||
| 330 | global_cache, | ||
| 331 | /// `sub_path` is relative to the local cache directory on `Compilation`. | ||
| 332 | local_cache, | ||
| 333 | /// `sub_path` is not relative to any of the roots listed above. | ||
| 334 | /// It is resolved starting with `Directories.cwd`; so it is an absolute path on most | ||
| 335 | /// targets, but cwd-relative on WASI. We do not make it cwd-relative on other targets | ||
| 336 | /// so that `Path.digest` gives hashes which can be stored in the Zig cache (as they | ||
| 337 | /// don't depend on a specific compiler instance). | ||
| 338 | none, | ||
| 339 | }; | ||
| 340 | |||
| 341 | /// In general, we can only construct canonical `Path`s at runtime, because weird nesting might | ||
| 342 | /// mean that e.g. a sub path inside zig/lib/ is actually in the global cache. However, because | ||
| 343 | /// `Directories` guarantees that `zig_lib` is a distinct path from both cache directories, it's | ||
| 344 | /// okay for us to construct this path, and only this path, as a comptime constant. | ||
| 345 | pub const zig_lib_root: Path = .{ .root = .zig_lib, .sub_path = "" }; | ||
| 346 | |||
| 347 | pub fn deinit(p: Path, gpa: Allocator) void { | ||
| 348 | gpa.free(p.sub_path); | ||
| 349 | } | ||
| 350 | |||
| 351 | /// The returned digest is relocatable across any compiler process using the same lib and cache | ||
| 352 | /// directories; it does not depend on cwd. | ||
| 353 | pub fn digest(p: Path) Cache.BinDigest { | ||
| 354 | var h = Cache.hasher_init; | ||
| 355 | h.update(&.{@intFromEnum(p.root)}); | ||
| 356 | h.update(p.sub_path); | ||
| 357 | return h.finalResult(); | ||
| 358 | } | ||
| 359 | |||
| 360 | /// Given a `Path`, returns the directory handle and sub path to be used to open the path. | ||
| 361 | pub fn openInfo(p: Path, dirs: Directories) struct { fs.Dir, []const u8 } { | ||
| 362 | const dir = switch (p.root) { | ||
| 363 | .none => { | ||
| 364 | const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); | ||
| 365 | return .{ fs.cwd(), cwd_sub_path }; | ||
| 366 | }, | ||
| 367 | .zig_lib => dirs.zig_lib.handle, | ||
| 368 | .global_cache => dirs.global_cache.handle, | ||
| 369 | .local_cache => dirs.local_cache.handle, | ||
| 370 | }; | ||
| 371 | if (p.sub_path.len == 0) return .{ dir, "." }; | ||
| 372 | assert(!fs.path.isAbsolute(p.sub_path)); | ||
| 373 | return .{ dir, p.sub_path }; | ||
| 374 | } | ||
| 375 | |||
| 376 | pub const format = unreachable; // do not format direcetly | ||
| 377 | pub fn fmt(p: Path, comp: *Compilation) Formatter { | ||
| 378 | return .{ .p = p, .comp = comp }; | ||
| 379 | } | ||
| 380 | const Formatter = struct { | ||
| 381 | p: Path, | ||
| 382 | comp: *Compilation, | ||
| 383 | pub fn format(f: Formatter, comptime unused_fmt: []const u8, options: std.fmt.FormatOptions, w: anytype) !void { | ||
| 384 | comptime assert(unused_fmt.len == 0); | ||
| 385 | _ = options; | ||
| 386 | const root_path: []const u8 = switch (f.p.root) { | ||
| 387 | .zig_lib => f.comp.dirs.zig_lib.path orelse ".", | ||
| 388 | .global_cache => f.comp.dirs.global_cache.path orelse ".", | ||
| 389 | .local_cache => f.comp.dirs.local_cache.path orelse ".", | ||
| 390 | .none => { | ||
| 391 | const cwd_sub_path = absToCwdRelative(f.p.sub_path, f.comp.dirs.cwd); | ||
| 392 | try w.writeAll(cwd_sub_path); | ||
| 393 | return; | ||
| 394 | }, | ||
| 395 | }; | ||
| 396 | assert(root_path.len != 0); | ||
| 397 | try w.writeAll(root_path); | ||
| 398 | if (f.p.sub_path.len > 0) { | ||
| 399 | try w.writeByte(fs.path.sep); | ||
| 400 | try w.writeAll(f.p.sub_path); | ||
| 401 | } | ||
| 402 | } | ||
| 403 | }; | ||
| 404 | |||
| 405 | /// Given the `sub_path` of a `Path` with `Path.root == .none`, attempts to convert | ||
| 406 | /// the (absolute) path to a cwd-relative path. Otherwise, returns the absolute path | ||
| 407 | /// unmodified. The returned string is never empty: "" is converted to ".". | ||
| 408 | fn absToCwdRelative(sub_path: []const u8, cwd_path: []const u8) []const u8 { | ||
| 409 | if (builtin.target.os.tag == .wasi) { | ||
| 410 | if (sub_path.len == 0) return "."; | ||
| 411 | assert(!fs.path.isAbsolute(sub_path)); | ||
| 412 | return sub_path; | ||
| 413 | } | ||
| 414 | assert(fs.path.isAbsolute(sub_path)); | ||
| 415 | if (!std.mem.startsWith(u8, sub_path, cwd_path)) return sub_path; | ||
| 416 | if (sub_path.len == cwd_path.len) return "."; // the strings are equal | ||
| 417 | if (sub_path[cwd_path.len] != fs.path.sep) return sub_path; // last component before cwd differs | ||
| 418 | return sub_path[cwd_path.len + 1 ..]; // remove '/path/to/cwd/' prefix | ||
| 419 | } | ||
| 420 | |||
| 421 | /// From an unresolved path (which can be made of multiple not-yet-joined strings), construct a | ||
| 422 | /// canonical `Path`. | ||
| 423 | pub fn fromUnresolved(gpa: Allocator, dirs: Compilation.Directories, unresolved_parts: []const []const u8) Allocator.Error!Path { | ||
| 424 | const resolved = try introspect.resolvePath(gpa, dirs.cwd, unresolved_parts); | ||
| 425 | errdefer gpa.free(resolved); | ||
| 426 | |||
| 427 | // If, for instance, `dirs.local_cache.path` is within the lib dir, it must take priority, | ||
| 428 | // so that we prefer `.root = .local_cache` over `.root = .zig_lib`. The easiest way to do | ||
| 429 | // this is simply to prioritize the longest root path. | ||
| 430 | const PathAndRoot = struct { ?[]const u8, Root }; | ||
| 431 | var roots: [3]PathAndRoot = .{ | ||
| 432 | .{ dirs.zig_lib.path, .zig_lib }, | ||
| 433 | .{ dirs.global_cache.path, .global_cache }, | ||
| 434 | .{ dirs.local_cache.path, .local_cache }, | ||
| 435 | }; | ||
| 436 | // This must be a stable sort, because the global and local cache directories may be the same, in | ||
| 437 | // which case we need to make a consistent choice. | ||
| 438 | std.mem.sort(PathAndRoot, &roots, {}, struct { | ||
| 439 | fn lessThan(_: void, lhs: PathAndRoot, rhs: PathAndRoot) bool { | ||
| 440 | const lhs_path_len = if (lhs[0]) |p| p.len else 0; | ||
| 441 | const rhs_path_len = if (rhs[0]) |p| p.len else 0; | ||
| 442 | return lhs_path_len > rhs_path_len; // '>' instead of '<' to sort descending | ||
| 443 | } | ||
| 444 | }.lessThan); | ||
| 445 | |||
| 446 | for (roots) |path_and_root| { | ||
| 447 | const opt_root_path, const root = path_and_root; | ||
| 448 | const root_path = opt_root_path orelse { | ||
| 449 | // This root is the cwd. | ||
| 450 | if (!fs.path.isAbsolute(resolved)) { | ||
| 451 | return .{ | ||
| 452 | .root = root, | ||
| 453 | .sub_path = resolved, | ||
| 454 | }; | ||
| 455 | } | ||
| 456 | continue; | ||
| 457 | }; | ||
| 458 | if (!mem.startsWith(u8, resolved, root_path)) continue; | ||
| 459 | const sub: []const u8 = if (resolved.len != root_path.len) sub: { | ||
| 460 | // Check the trailing slash, so that we don't match e.g. `/foo/bar` with `/foo/barren` | ||
| 461 | if (resolved[root_path.len] != fs.path.sep) continue; | ||
| 462 | break :sub resolved[root_path.len + 1 ..]; | ||
| 463 | } else ""; | ||
| 464 | const duped = try gpa.dupe(u8, sub); | ||
| 465 | gpa.free(resolved); | ||
| 466 | return .{ .root = root, .sub_path = duped }; | ||
| 467 | } | ||
| 468 | |||
| 469 | // We're not relative to any root, so we will use an absolute path (on targets where they are available). | ||
| 470 | |||
| 471 | if (builtin.target.os.tag == .wasi or fs.path.isAbsolute(resolved)) { | ||
| 472 | // `resolved` is already absolute (or we're on WASI, where absolute paths don't really exist). | ||
| 473 | return .{ .root = .none, .sub_path = resolved }; | ||
| 474 | } | ||
| 475 | |||
| 476 | if (resolved.len == 0) { | ||
| 477 | // We just need the cwd path, no trailing separator. Note that `gpa.free(resolved)` would be a nop. | ||
| 478 | return .{ .root = .none, .sub_path = try gpa.dupe(u8, dirs.cwd) }; | ||
| 479 | } | ||
| 480 | |||
| 481 | // We need to make an absolute path. Because `resolved` came from `introspect.resolvePath`, we can just | ||
| 482 | // join the paths with a simple format string. | ||
| 483 | const abs_path = try std.fmt.allocPrint(gpa, "{s}{c}{s}", .{ dirs.cwd, fs.path.sep, resolved }); | ||
| 484 | gpa.free(resolved); | ||
| 485 | return .{ .root = .none, .sub_path = abs_path }; | ||
| 486 | } | ||
| 487 | |||
| 488 | /// Constructs a canonical `Path` representing `sub_path` relative to `root`. | ||
| 489 | /// | ||
| 490 | /// If `sub_path` is resolved, this is almost like directly constructing a `Path`, but this | ||
| 491 | /// function also canonicalizes the result, which matters because `sub_path` may move us into | ||
| 492 | /// a different root. | ||
| 493 | /// | ||
| 494 | /// For instance, if the Zig lib directory is inside the global cache, passing `root` as | ||
| 495 | /// `.global_cache` could still end up returning a `Path` with `Path.root == .zig_lib`. | ||
| 496 | pub fn fromRoot( | ||
| 497 | gpa: Allocator, | ||
| 498 | dirs: Compilation.Directories, | ||
| 499 | root: Path.Root, | ||
| 500 | sub_path: []const u8, | ||
| 501 | ) Allocator.Error!Path { | ||
| 502 | // Currently, this just wraps `fromUnresolved` for simplicity. A more efficient impl is | ||
| 503 | // probably possible if this function ever ends up impacting performance somehow. | ||
| 504 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 505 | switch (root) { | ||
| 506 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 507 | .global_cache => dirs.global_cache.path orelse "", | ||
| 508 | .local_cache => dirs.local_cache.path orelse "", | ||
| 509 | .none => "", | ||
| 510 | }, | ||
| 511 | sub_path, | ||
| 512 | }); | ||
| 513 | } | ||
| 514 | |||
| 515 | /// Given a `Path` and an (unresolved) sub path relative to it, construct a `Path` representing | ||
| 516 | /// the joined path `p/sub_path`. Note that, like with `fromRoot`, the `sub_path` might cause us | ||
| 517 | /// to move into a different `Path.Root`. | ||
| 518 | pub fn join( | ||
| 519 | p: Path, | ||
| 520 | gpa: Allocator, | ||
| 521 | dirs: Compilation.Directories, | ||
| 522 | sub_path: []const u8, | ||
| 523 | ) Allocator.Error!Path { | ||
| 524 | // Currently, this just wraps `fromUnresolved` for simplicity. A more efficient impl is | ||
| 525 | // probably possible if this function ever ends up impacting performance somehow. | ||
| 526 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 527 | switch (p.root) { | ||
| 528 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 529 | .global_cache => dirs.global_cache.path orelse "", | ||
| 530 | .local_cache => dirs.local_cache.path orelse "", | ||
| 531 | .none => "", | ||
| 532 | }, | ||
| 533 | p.sub_path, | ||
| 534 | sub_path, | ||
| 535 | }); | ||
| 536 | } | ||
| 537 | |||
| 538 | /// Like `join`, but `sub_path` is relative to the dirname of `p` instead of `p` itself. | ||
| 539 | pub fn upJoin( | ||
| 540 | p: Path, | ||
| 541 | gpa: Allocator, | ||
| 542 | dirs: Compilation.Directories, | ||
| 543 | sub_path: []const u8, | ||
| 544 | ) Allocator.Error!Path { | ||
| 545 | return .fromUnresolved(gpa, dirs, &.{ | ||
| 546 | switch (p.root) { | ||
| 547 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 548 | .global_cache => dirs.global_cache.path orelse "", | ||
| 549 | .local_cache => dirs.local_cache.path orelse "", | ||
| 550 | .none => "", | ||
| 551 | }, | ||
| 552 | p.sub_path, | ||
| 553 | "..", | ||
| 554 | sub_path, | ||
| 555 | }); | ||
| 556 | } | ||
| 557 | |||
| 558 | pub fn toCachePath(p: Path, dirs: Directories) Cache.Path { | ||
| 559 | const root_dir: Cache.Directory = switch (p.root) { | ||
| 560 | .zig_lib => dirs.zig_lib, | ||
| 561 | .global_cache => dirs.global_cache, | ||
| 562 | .local_cache => dirs.local_cache, | ||
| 563 | else => { | ||
| 564 | const cwd_sub_path = absToCwdRelative(p.sub_path, dirs.cwd); | ||
| 565 | return .{ | ||
| 566 | .root_dir = .cwd(), | ||
| 567 | .sub_path = cwd_sub_path, | ||
| 568 | }; | ||
| 569 | }, | ||
| 570 | }; | ||
| 571 | assert(!fs.path.isAbsolute(p.sub_path)); | ||
| 572 | return .{ | ||
| 573 | .root_dir = root_dir, | ||
| 574 | .sub_path = p.sub_path, | ||
| 575 | }; | ||
| 576 | } | ||
| 577 | |||
| 578 | /// This should not be used for most of the compiler pipeline, but is useful when emitting | ||
| 579 | /// paths from the compilation (e.g. in debug info), because they will not depend on the cwd. | ||
| 580 | /// The returned path is owned by the caller and allocated into `gpa`. | ||
| 581 | pub fn toAbsolute(p: Path, dirs: Directories, gpa: Allocator) Allocator.Error![]u8 { | ||
| 582 | const root_path: []const u8 = switch (p.root) { | ||
| 583 | .zig_lib => dirs.zig_lib.path orelse "", | ||
| 584 | .global_cache => dirs.global_cache.path orelse "", | ||
| 585 | .local_cache => dirs.local_cache.path orelse "", | ||
| 586 | .none => "", | ||
| 587 | }; | ||
| 588 | return fs.path.resolve(gpa, &.{ | ||
| 589 | dirs.cwd, | ||
| 590 | root_path, | ||
| 591 | p.sub_path, | ||
| 592 | }); | ||
| 593 | } | ||
| 594 | |||
| 595 | pub fn isNested(inner: Path, outer: Path) union(enum) { | ||
| 596 | /// Value is the sub path, which is a sub-slice of `inner.sub_path`. | ||
| 597 | yes: []const u8, | ||
| 598 | no, | ||
| 599 | different_roots, | ||
| 600 | } { | ||
| 601 | if (inner.root != outer.root) return .different_roots; | ||
| 602 | if (!mem.startsWith(u8, inner.sub_path, outer.sub_path)) return .no; | ||
| 603 | if (inner.sub_path.len == outer.sub_path.len) return .no; | ||
| 604 | if (outer.sub_path.len == 0) return .{ .yes = inner.sub_path }; | ||
| 605 | if (inner.sub_path[outer.sub_path.len] != fs.path.sep) return .no; | ||
| 606 | return .{ .yes = inner.sub_path[outer.sub_path.len + 1 ..] }; | ||
| 607 | } | ||
| 608 | |||
| 609 | /// Returns whether this `Path` is illegal to have as a user-imported `Zcu.File` (including | ||
| 610 | /// as the root of a module). Such paths exist in directories which the Zig compiler treats | ||
| 611 | /// specially, like 'global_cache/b/', which stores 'builtin.zig' files. | ||
| 612 | pub fn isIllegalZigImport(p: Path, gpa: Allocator, dirs: Directories) Allocator.Error!bool { | ||
| 613 | const zig_builtin_dir: Path = try .fromRoot(gpa, dirs, .global_cache, "b"); | ||
| 614 | defer zig_builtin_dir.deinit(gpa); | ||
| 615 | return switch (p.isNested(zig_builtin_dir)) { | ||
| 616 | .yes => true, | ||
| 617 | .no, .different_roots => false, | ||
| 618 | }; | ||
| 619 | } | ||
| 620 | }; | ||
| 621 | |||
| 622 | pub const Directories = struct { | ||
| 623 | /// The string returned by `introspect.getResolvedCwd`. This is typically an absolute path, | ||
| 624 | /// but on WASI is the empty string "" instead, because WASI does not have absolute paths. | ||
| 625 | cwd: []const u8, | ||
| 626 | /// The Zig 'lib' directory. | ||
| 627 | /// `zig_lib.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 628 | /// Guaranteed to be a different path from `global_cache` and `local_cache`. | ||
| 629 | zig_lib: Cache.Directory, | ||
| 630 | /// The global Zig cache directory. | ||
| 631 | /// `global_cache.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 632 | global_cache: Cache.Directory, | ||
| 633 | /// The local Zig cache directory. | ||
| 634 | /// `local_cache.path` is resolved (`introspect.resolvePath`) or `null` for cwd. | ||
| 635 | /// This may be the same as `global_cache`. | ||
| 636 | local_cache: Cache.Directory, | ||
| 637 | |||
| 638 | pub fn deinit(dirs: *Directories) void { | ||
| 639 | // The local and global caches could be the same. | ||
| 640 | const close_local = dirs.local_cache.handle.fd != dirs.global_cache.handle.fd; | ||
| 641 | |||
| 642 | dirs.global_cache.handle.close(); | ||
| 643 | if (close_local) dirs.local_cache.handle.close(); | ||
| 644 | dirs.zig_lib.handle.close(); | ||
| 645 | } | ||
| 646 | |||
| 647 | /// Returns a `Directories` where `local_cache` is replaced with `global_cache`, intended for | ||
| 648 | /// use by sub-compilations (e.g. compiler_rt). Do not `deinit` the returned `Directories`; it | ||
| 649 | /// shares handles with `dirs`. | ||
| 650 | pub fn withoutLocalCache(dirs: Directories) Directories { | ||
| 651 | return .{ | ||
| 652 | .cwd = dirs.cwd, | ||
| 653 | .zig_lib = dirs.zig_lib, | ||
| 654 | .global_cache = dirs.global_cache, | ||
| 655 | .local_cache = dirs.global_cache, | ||
| 656 | }; | ||
| 657 | } | ||
| 658 | |||
| 659 | /// Uses `std.process.fatal` on error conditions. | ||
| 660 | pub fn init( | ||
| 661 | arena: Allocator, | ||
| 662 | override_zig_lib: ?[]const u8, | ||
| 663 | override_global_cache: ?[]const u8, | ||
| 664 | local_cache_strat: union(enum) { | ||
| 665 | override: []const u8, | ||
| 666 | search, | ||
| 667 | global, | ||
| 668 | }, | ||
| 669 | wasi_preopens: switch (builtin.target.os.tag) { | ||
| 670 | .wasi => std.fs.wasi.Preopens, | ||
| 671 | else => void, | ||
| 672 | }, | ||
| 673 | self_exe_path: switch (builtin.target.os.tag) { | ||
| 674 | .wasi => void, | ||
| 675 | else => []const u8, | ||
| 676 | }, | ||
| 677 | ) Directories { | ||
| 678 | const wasi = builtin.target.os.tag == .wasi; | ||
| 679 | |||
| 680 | const cwd = introspect.getResolvedCwd(arena) catch |err| { | ||
| 681 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | ||
| 682 | }; | ||
| 683 | |||
| 684 | const zig_lib: Cache.Directory = d: { | ||
| 685 | if (override_zig_lib) |path| break :d openUnresolved(arena, cwd, path, .@"zig lib"); | ||
| 686 | if (wasi) break :d openWasiPreopen(wasi_preopens, "/lib"); | ||
| 687 | break :d introspect.findZigLibDirFromSelfExe(arena, cwd, self_exe_path) catch |err| { | ||
| 688 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | ||
| 689 | }; | ||
| 690 | }; | ||
| 691 | |||
| 692 | const global_cache: Cache.Directory = d: { | ||
| 693 | if (override_global_cache) |path| break :d openUnresolved(arena, cwd, path, .@"global cache"); | ||
| 694 | if (wasi) break :d openWasiPreopen(wasi_preopens, "/cache"); | ||
| 695 | const path = introspect.resolveGlobalCacheDir(arena) catch |err| { | ||
| 696 | fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); | ||
| 697 | }; | ||
| 698 | break :d openUnresolved(arena, cwd, path, .@"global cache"); | ||
| 699 | }; | ||
| 700 | |||
| 701 | const local_cache: Cache.Directory = switch (local_cache_strat) { | ||
| 702 | .override => |path| openUnresolved(arena, cwd, path, .@"local cache"), | ||
| 703 | .search => d: { | ||
| 704 | const maybe_path = introspect.resolveSuitableLocalCacheDir(arena, cwd) catch |err| { | ||
| 705 | fatal("unable to resolve zig cache directory: {s}", .{@errorName(err)}); | ||
| 706 | }; | ||
| 707 | const path = maybe_path orelse break :d global_cache; | ||
| 708 | break :d openUnresolved(arena, cwd, path, .@"local cache"); | ||
| 709 | }, | ||
| 710 | .global => global_cache, | ||
| 711 | }; | ||
| 712 | |||
| 713 | if (std.mem.eql(u8, zig_lib.path orelse "", global_cache.path orelse "")) { | ||
| 714 | fatal("zig lib directory '{}' cannot be equal to global cache directory '{}'", .{ zig_lib, global_cache }); | ||
| 715 | } | ||
| 716 | if (std.mem.eql(u8, zig_lib.path orelse "", local_cache.path orelse "")) { | ||
| 717 | fatal("zig lib directory '{}' cannot be equal to local cache directory '{}'", .{ zig_lib, local_cache }); | ||
| 718 | } | ||
| 719 | |||
| 720 | return .{ | ||
| 721 | .cwd = cwd, | ||
| 722 | .zig_lib = zig_lib, | ||
| 723 | .global_cache = global_cache, | ||
| 724 | .local_cache = local_cache, | ||
| 725 | }; | ||
| 726 | } | ||
| 727 | fn openWasiPreopen(preopens: std.fs.wasi.Preopens, name: []const u8) Cache.Directory { | ||
| 728 | return .{ | ||
| 729 | .path = if (std.mem.eql(u8, name, ".")) null else name, | ||
| 730 | .handle = .{ | ||
| 731 | .fd = preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), | ||
| 732 | }, | ||
| 733 | }; | ||
| 734 | } | ||
| 735 | fn openUnresolved(arena: Allocator, cwd: []const u8, unresolved_path: []const u8, thing: enum { @"zig lib", @"global cache", @"local cache" }) Cache.Directory { | ||
| 736 | const path = introspect.resolvePath(arena, cwd, &.{unresolved_path}) catch |err| { | ||
| 737 | fatal("unable to resolve {s} directory: {s}", .{ @tagName(thing), @errorName(err) }); | ||
| 738 | }; | ||
| 739 | const nonempty_path = if (path.len == 0) "." else path; | ||
| 740 | const handle_or_err = switch (thing) { | ||
| 741 | .@"zig lib" => std.fs.cwd().openDir(nonempty_path, .{}), | ||
| 742 | .@"global cache", .@"local cache" => std.fs.cwd().makeOpenPath(nonempty_path, .{}), | ||
| 743 | }; | ||
| 744 | return .{ | ||
| 745 | .path = if (path.len == 0) null else path, | ||
| 746 | .handle = handle_or_err catch |err| { | ||
| 747 | const extra_str: []const u8 = e: { | ||
| 748 | if (thing == .@"global cache") switch (err) { | ||
| 749 | error.AccessDenied, error.ReadOnlyFileSystem => break :e "\n" ++ | ||
| 750 | "If this location is not writable then consider specifying an alternative with " ++ | ||
| 751 | "the ZIG_GLOBAL_CACHE_DIR environment variable or the --global-cache-dir option.", | ||
| 752 | else => {}, | ||
| 753 | }; | ||
| 754 | break :e ""; | ||
| 755 | }; | ||
| 756 | fatal("unable to open {s} directory '{s}': {s}{s}", .{ @tagName(thing), nonempty_path, @errorName(err), extra_str }); | ||
| 757 | }, | ||
| 758 | }; | ||
| 759 | } | ||
| 760 | }; | ||
| 761 | |||
| 315 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; | 762 | pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size; |
| 316 | pub const SemaError = Zcu.SemaError; | 763 | pub const SemaError = Zcu.SemaError; |
| 317 | 764 | ||
| 318 | pub const CrtFile = struct { | 765 | pub const CrtFile = struct { |
| 319 | lock: Cache.Lock, | 766 | lock: Cache.Lock, |
| 320 | full_object_path: Path, | 767 | full_object_path: Cache.Path, |
| 321 | 768 | ||
| 322 | pub fn isObject(cf: CrtFile) bool { | 769 | pub fn isObject(cf: CrtFile) bool { |
| 323 | return switch (classifyFileExt(cf.full_object_path.sub_path)) { | 770 | return switch (classifyFileExt(cf.full_object_path.sub_path)) { |
| ... | @@ -430,7 +877,7 @@ pub const CObject = struct { | ... | @@ -430,7 +877,7 @@ pub const CObject = struct { |
| 430 | new, | 877 | new, |
| 431 | success: struct { | 878 | success: struct { |
| 432 | /// The outputted result. `sub_path` owned by gpa. | 879 | /// The outputted result. `sub_path` owned by gpa. |
| 433 | object_path: Path, | 880 | object_path: Cache.Path, |
| 434 | /// This is a file system lock on the cache hash manifest representing this | 881 | /// This is a file system lock on the cache hash manifest representing this |
| 435 | /// object. It prevents other invocations of the Zig compiler from interfering | 882 | /// object. It prevents other invocations of the Zig compiler from interfering |
| 436 | /// with this object until released. | 883 | /// with this object until released. |
| ... | @@ -854,7 +1301,7 @@ pub const MiscError = struct { | ... | @@ -854,7 +1301,7 @@ pub const MiscError = struct { |
| 854 | pub const EmitLoc = struct { | 1301 | pub const EmitLoc = struct { |
| 855 | /// If this is `null` it means the file will be output to the cache directory. | 1302 | /// If this is `null` it means the file will be output to the cache directory. |
| 856 | /// When provided, both the open file handle and the path name must outlive the `Compilation`. | 1303 | /// When provided, both the open file handle and the path name must outlive the `Compilation`. |
| 857 | directory: ?Compilation.Directory, | 1304 | directory: ?Cache.Directory, |
| 858 | /// This may not have sub-directories in it. | 1305 | /// This may not have sub-directories in it. |
| 859 | basename: []const u8, | 1306 | basename: []const u8, |
| 860 | }; | 1307 | }; |
| ... | @@ -977,7 +1424,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -977,7 +1424,7 @@ const CacheUse = union(CacheMode) { |
| 977 | implib_sub_path: ?[]u8, | 1424 | implib_sub_path: ?[]u8, |
| 978 | docs_sub_path: ?[]u8, | 1425 | docs_sub_path: ?[]u8, |
| 979 | lf_open_opts: link.File.OpenOptions, | 1426 | lf_open_opts: link.File.OpenOptions, |
| 980 | tmp_artifact_directory: ?Directory, | 1427 | tmp_artifact_directory: ?Cache.Directory, |
| 981 | /// Prevents other processes from clobbering files in the output directory. | 1428 | /// Prevents other processes from clobbering files in the output directory. |
| 982 | lock: ?Cache.Lock, | 1429 | lock: ?Cache.Lock, |
| 983 | 1430 | ||
| ... | @@ -997,7 +1444,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -997,7 +1444,7 @@ const CacheUse = union(CacheMode) { |
| 997 | 1444 | ||
| 998 | const Incremental = struct { | 1445 | const Incremental = struct { |
| 999 | /// Where build artifacts and incremental compilation metadata serialization go. | 1446 | /// Where build artifacts and incremental compilation metadata serialization go. |
| 1000 | artifact_directory: Compilation.Directory, | 1447 | artifact_directory: Cache.Directory, |
| 1001 | }; | 1448 | }; |
| 1002 | 1449 | ||
| 1003 | fn deinit(cu: CacheUse) void { | 1450 | fn deinit(cu: CacheUse) void { |
| ... | @@ -1013,9 +1460,7 @@ const CacheUse = union(CacheMode) { | ... | @@ -1013,9 +1460,7 @@ const CacheUse = union(CacheMode) { |
| 1013 | }; | 1460 | }; |
| 1014 | 1461 | ||
| 1015 | pub const CreateOptions = struct { | 1462 | pub const CreateOptions = struct { |
| 1016 | zig_lib_directory: Directory, | 1463 | dirs: Directories, |
| 1017 | local_cache_directory: Directory, | ||
| 1018 | global_cache_directory: Directory, | ||
| 1019 | thread_pool: *ThreadPool, | 1464 | thread_pool: *ThreadPool, |
| 1020 | self_exe_path: ?[]const u8 = null, | 1465 | self_exe_path: ?[]const u8 = null, |
| 1021 | 1466 | ||
| ... | @@ -1059,7 +1504,7 @@ pub const CreateOptions = struct { | ... | @@ -1059,7 +1504,7 @@ pub const CreateOptions = struct { |
| 1059 | /// This field is intended to be removed. | 1504 | /// This field is intended to be removed. |
| 1060 | /// The ELF implementation no longer uses this data, however the MachO and COFF | 1505 | /// The ELF implementation no longer uses this data, however the MachO and COFF |
| 1061 | /// implementations still do. | 1506 | /// implementations still do. |
| 1062 | lib_directories: []const Directory = &.{}, | 1507 | lib_directories: []const Cache.Directory = &.{}, |
| 1063 | rpath_list: []const []const u8 = &[0][]const u8{}, | 1508 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 1064 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .empty, | 1509 | symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .empty, |
| 1065 | c_source_files: []const CSourceFile = &.{}, | 1510 | c_source_files: []const CSourceFile = &.{}, |
| ... | @@ -1195,68 +1640,35 @@ pub const CreateOptions = struct { | ... | @@ -1195,68 +1640,35 @@ pub const CreateOptions = struct { |
| 1195 | }; | 1640 | }; |
| 1196 | 1641 | ||
| 1197 | fn addModuleTableToCacheHash( | 1642 | fn addModuleTableToCacheHash( |
| 1198 | gpa: Allocator, | 1643 | zcu: *Zcu, |
| 1199 | arena: Allocator, | 1644 | arena: Allocator, |
| 1200 | hash: *Cache.HashHelper, | 1645 | hash: *Cache.HashHelper, |
| 1201 | root_mod: *Package.Module, | ||
| 1202 | main_mod: *Package.Module, | ||
| 1203 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, | 1646 | hash_type: union(enum) { path_bytes, files: *Cache.Manifest }, |
| 1204 | ) (error{OutOfMemory} || std.process.GetCwdError)!void { | 1647 | ) error{ |
| 1205 | var seen_table: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; | 1648 | OutOfMemory, |
| 1206 | defer seen_table.deinit(gpa); | 1649 | Unexpected, |
| 1207 | 1650 | CurrentWorkingDirectoryUnlinked, | |
| 1208 | // root_mod and main_mod may be the same pointer. In fact they usually are. | 1651 | }!void { |
| 1209 | // However in the case of `zig test` or `zig build` they will be different, | 1652 | assert(zcu.module_roots.count() != 0); // module_roots is populated |
| 1210 | // and it's possible for one to not reference the other via the import table. | 1653 | |
| 1211 | try seen_table.put(gpa, root_mod, {}); | 1654 | for (zcu.module_roots.keys(), zcu.module_roots.values()) |mod, opt_mod_root_file| { |
| 1212 | try seen_table.put(gpa, main_mod, {}); | 1655 | if (mod == zcu.std_mod) continue; // redundant |
| 1213 | 1656 | if (opt_mod_root_file.unwrap()) |mod_root_file| { | |
| 1214 | const SortByName = struct { | 1657 | if (zcu.fileByIndex(mod_root_file).is_builtin) continue; // redundant |
| 1215 | has_builtin: bool, | ||
| 1216 | names: []const []const u8, | ||
| 1217 | |||
| 1218 | pub fn lessThan(ctx: @This(), lhs: usize, rhs: usize) bool { | ||
| 1219 | return if (ctx.has_builtin and (lhs == 0 or rhs == 0)) | ||
| 1220 | lhs < rhs | ||
| 1221 | else | ||
| 1222 | mem.lessThan(u8, ctx.names[lhs], ctx.names[rhs]); | ||
| 1223 | } | 1658 | } |
| 1224 | }; | ||
| 1225 | |||
| 1226 | var i: usize = 0; | ||
| 1227 | while (i < seen_table.count()) : (i += 1) { | ||
| 1228 | const mod = seen_table.keys()[i]; | ||
| 1229 | if (mod.isBuiltin()) { | ||
| 1230 | // Skip builtin.zig; it is useless as an input, and we don't want to | ||
| 1231 | // have to write it before checking for a cache hit. | ||
| 1232 | continue; | ||
| 1233 | } | ||
| 1234 | |||
| 1235 | cache_helpers.addModule(hash, mod); | 1659 | cache_helpers.addModule(hash, mod); |
| 1236 | |||
| 1237 | switch (hash_type) { | 1660 | switch (hash_type) { |
| 1238 | .path_bytes => { | 1661 | .path_bytes => { |
| 1239 | hash.addBytes(mod.root_src_path); | 1662 | hash.add(mod.root.root); |
| 1240 | hash.addOptionalBytes(mod.root.root_dir.path); | ||
| 1241 | hash.addBytes(mod.root.sub_path); | 1663 | hash.addBytes(mod.root.sub_path); |
| 1664 | hash.addBytes(mod.root_src_path); | ||
| 1242 | }, | 1665 | }, |
| 1243 | .files => |man| if (mod.root_src_path.len != 0) { | 1666 | .files => |man| if (mod.root_src_path.len != 0) { |
| 1244 | const pkg_zig_file = try mod.root.joinString(arena, mod.root_src_path); | 1667 | const root_src_path = try mod.root.toCachePath(zcu.comp.dirs).join(arena, mod.root_src_path); |
| 1245 | _ = try man.addFile(pkg_zig_file, null); | 1668 | _ = try man.addFilePath(root_src_path, null); |
| 1246 | }, | 1669 | }, |
| 1247 | } | 1670 | } |
| 1248 | |||
| 1249 | mod.deps.sortUnstable(SortByName{ | ||
| 1250 | .has_builtin = mod.deps.count() >= 1 and | ||
| 1251 | mod.deps.values()[0].isBuiltin(), | ||
| 1252 | .names = mod.deps.keys(), | ||
| 1253 | }); | ||
| 1254 | |||
| 1255 | hash.addListOfBytes(mod.deps.keys()); | 1671 | hash.addListOfBytes(mod.deps.keys()); |
| 1256 | |||
| 1257 | const deps = mod.deps.values(); | ||
| 1258 | try seen_table.ensureUnusedCapacity(gpa, deps.len); | ||
| 1259 | for (deps) |dep| seen_table.putAssumeCapacity(dep, {}); | ||
| 1260 | } | 1672 | } |
| 1261 | } | 1673 | } |
| 1262 | 1674 | ||
| ... | @@ -1310,7 +1722,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1310,7 +1722,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1310 | 1722 | ||
| 1311 | const libc_dirs = try std.zig.LibCDirs.detect( | 1723 | const libc_dirs = try std.zig.LibCDirs.detect( |
| 1312 | arena, | 1724 | arena, |
| 1313 | options.zig_lib_directory.path.?, | 1725 | options.dirs.zig_lib.path.?, |
| 1314 | options.root_mod.resolved_target.result, | 1726 | options.root_mod.resolved_target.result, |
| 1315 | options.root_mod.resolved_target.is_native_abi, | 1727 | options.root_mod.resolved_target.is_native_abi, |
| 1316 | link_libc, | 1728 | link_libc, |
| ... | @@ -1332,11 +1744,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1332,11 +1744,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1332 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` | 1744 | // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");` |
| 1333 | // injected into the object. | 1745 | // injected into the object. |
| 1334 | const compiler_rt_mod = try Package.Module.create(arena, .{ | 1746 | const compiler_rt_mod = try Package.Module.create(arena, .{ |
| 1335 | .global_cache_directory = options.global_cache_directory, | ||
| 1336 | .paths = .{ | 1747 | .paths = .{ |
| 1337 | .root = .{ | 1748 | .root = .zig_lib_root, |
| 1338 | .root_dir = options.zig_lib_directory, | ||
| 1339 | }, | ||
| 1340 | .root_src_path = "compiler_rt.zig", | 1749 | .root_src_path = "compiler_rt.zig", |
| 1341 | }, | 1750 | }, |
| 1342 | .fully_qualified_name = "compiler_rt", | 1751 | .fully_qualified_name = "compiler_rt", |
| ... | @@ -1348,8 +1757,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1348,8 +1757,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1348 | }, | 1757 | }, |
| 1349 | .global = options.config, | 1758 | .global = options.config, |
| 1350 | .parent = options.root_mod, | 1759 | .parent = options.root_mod, |
| 1351 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1352 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1353 | }); | 1760 | }); |
| 1354 | try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod); | 1761 | try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod); |
| 1355 | } | 1762 | } |
| ... | @@ -1369,11 +1776,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1369,11 +1776,8 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1369 | 1776 | ||
| 1370 | if (ubsan_rt_strat == .zcu) { | 1777 | if (ubsan_rt_strat == .zcu) { |
| 1371 | const ubsan_rt_mod = try Package.Module.create(arena, .{ | 1778 | const ubsan_rt_mod = try Package.Module.create(arena, .{ |
| 1372 | .global_cache_directory = options.global_cache_directory, | ||
| 1373 | .paths = .{ | 1779 | .paths = .{ |
| 1374 | .root = .{ | 1780 | .root = .zig_lib_root, |
| 1375 | .root_dir = options.zig_lib_directory, | ||
| 1376 | }, | ||
| 1377 | .root_src_path = "ubsan_rt.zig", | 1781 | .root_src_path = "ubsan_rt.zig", |
| 1378 | }, | 1782 | }, |
| 1379 | .fully_qualified_name = "ubsan_rt", | 1783 | .fully_qualified_name = "ubsan_rt", |
| ... | @@ -1381,8 +1785,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1381,8 +1785,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1381 | .inherited = .{}, | 1785 | .inherited = .{}, |
| 1382 | .global = options.config, | 1786 | .global = options.config, |
| 1383 | .parent = options.root_mod, | 1787 | .parent = options.root_mod, |
| 1384 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1385 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1386 | }); | 1788 | }); |
| 1387 | try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod); | 1789 | try options.root_mod.deps.putNoClobber(arena, "ubsan_rt", ubsan_rt_mod); |
| 1388 | } | 1790 | } |
| ... | @@ -1415,13 +1817,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1415,13 +1817,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1415 | const cache = try arena.create(Cache); | 1817 | const cache = try arena.create(Cache); |
| 1416 | cache.* = .{ | 1818 | cache.* = .{ |
| 1417 | .gpa = gpa, | 1819 | .gpa = gpa, |
| 1418 | .manifest_dir = try options.local_cache_directory.handle.makeOpenPath("h", .{}), | 1820 | .manifest_dir = try options.dirs.local_cache.handle.makeOpenPath("h", .{}), |
| 1419 | }; | 1821 | }; |
| 1420 | // These correspond to std.zig.Server.Message.PathPrefix. | 1822 | // These correspond to std.zig.Server.Message.PathPrefix. |
| 1421 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); | 1823 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); |
| 1422 | cache.addPrefix(options.zig_lib_directory); | 1824 | cache.addPrefix(options.dirs.zig_lib); |
| 1423 | cache.addPrefix(options.local_cache_directory); | 1825 | cache.addPrefix(options.dirs.local_cache); |
| 1424 | cache.addPrefix(options.global_cache_directory); | 1826 | cache.addPrefix(options.dirs.global_cache); |
| 1425 | errdefer cache.manifest_dir.close(); | 1827 | errdefer cache.manifest_dir.close(); |
| 1426 | 1828 | ||
| 1427 | // This is shared hasher state common to zig source and all C source files. | 1829 | // This is shared hasher state common to zig source and all C source files. |
| ... | @@ -1458,26 +1860,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1458,26 +1860,22 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1458 | // to redundantly happen for each AstGen operation. | 1860 | // to redundantly happen for each AstGen operation. |
| 1459 | const zir_sub_dir = "z"; | 1861 | const zir_sub_dir = "z"; |
| 1460 | 1862 | ||
| 1461 | var local_zir_dir = try options.local_cache_directory.handle.makeOpenPath(zir_sub_dir, .{}); | 1863 | var local_zir_dir = try options.dirs.local_cache.handle.makeOpenPath(zir_sub_dir, .{}); |
| 1462 | errdefer local_zir_dir.close(); | 1864 | errdefer local_zir_dir.close(); |
| 1463 | const local_zir_cache: Directory = .{ | 1865 | const local_zir_cache: Cache.Directory = .{ |
| 1464 | .handle = local_zir_dir, | 1866 | .handle = local_zir_dir, |
| 1465 | .path = try options.local_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}), | 1867 | .path = try options.dirs.local_cache.join(arena, &.{zir_sub_dir}), |
| 1466 | }; | 1868 | }; |
| 1467 | var global_zir_dir = try options.global_cache_directory.handle.makeOpenPath(zir_sub_dir, .{}); | 1869 | var global_zir_dir = try options.dirs.global_cache.handle.makeOpenPath(zir_sub_dir, .{}); |
| 1468 | errdefer global_zir_dir.close(); | 1870 | errdefer global_zir_dir.close(); |
| 1469 | const global_zir_cache: Directory = .{ | 1871 | const global_zir_cache: Cache.Directory = .{ |
| 1470 | .handle = global_zir_dir, | 1872 | .handle = global_zir_dir, |
| 1471 | .path = try options.global_cache_directory.join(arena, &[_][]const u8{zir_sub_dir}), | 1873 | .path = try options.dirs.global_cache.join(arena, &.{zir_sub_dir}), |
| 1472 | }; | 1874 | }; |
| 1473 | 1875 | ||
| 1474 | const std_mod = options.std_mod orelse try Package.Module.create(arena, .{ | 1876 | const std_mod = options.std_mod orelse try Package.Module.create(arena, .{ |
| 1475 | .global_cache_directory = options.global_cache_directory, | ||
| 1476 | .paths = .{ | 1877 | .paths = .{ |
| 1477 | .root = .{ | 1878 | .root = try .fromRoot(arena, options.dirs, .zig_lib, "std"), |
| 1478 | .root_dir = options.zig_lib_directory, | ||
| 1479 | .sub_path = "std", | ||
| 1480 | }, | ||
| 1481 | .root_src_path = "std.zig", | 1879 | .root_src_path = "std.zig", |
| 1482 | }, | 1880 | }, |
| 1483 | .fully_qualified_name = "std", | 1881 | .fully_qualified_name = "std", |
| ... | @@ -1485,8 +1883,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1485,8 +1883,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1485 | .inherited = .{}, | 1883 | .inherited = .{}, |
| 1486 | .global = options.config, | 1884 | .global = options.config, |
| 1487 | .parent = options.root_mod, | 1885 | .parent = options.root_mod, |
| 1488 | .builtin_mod = options.root_mod.getBuiltinDependency(), | ||
| 1489 | .builtin_modules = null, // `builtin_mod` is set | ||
| 1490 | }); | 1886 | }); |
| 1491 | 1887 | ||
| 1492 | const zcu = try arena.create(Zcu); | 1888 | const zcu = try arena.create(Zcu); |
| ... | @@ -1522,16 +1918,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1522,16 +1918,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1522 | .docs_emit = null, // handled below | 1918 | .docs_emit = null, // handled below |
| 1523 | .root_mod = options.root_mod, | 1919 | .root_mod = options.root_mod, |
| 1524 | .config = options.config, | 1920 | .config = options.config, |
| 1525 | .zig_lib_directory = options.zig_lib_directory, | 1921 | .dirs = options.dirs, |
| 1526 | .local_cache_directory = options.local_cache_directory, | ||
| 1527 | .global_cache_directory = options.global_cache_directory, | ||
| 1528 | .emit_asm = options.emit_asm, | 1922 | .emit_asm = options.emit_asm, |
| 1529 | .emit_llvm_ir = options.emit_llvm_ir, | 1923 | .emit_llvm_ir = options.emit_llvm_ir, |
| 1530 | .emit_llvm_bc = options.emit_llvm_bc, | 1924 | .emit_llvm_bc = options.emit_llvm_bc, |
| 1531 | .work_queues = @splat(.init(gpa)), | 1925 | .work_queues = @splat(.init(gpa)), |
| 1532 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), | 1926 | .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), |
| 1533 | .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa) else .{}, | 1927 | .win32_resource_work_queue = if (dev.env.supports(.win32_resource)) std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa) else .{}, |
| 1534 | .astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa), | ||
| 1535 | .c_source_files = options.c_source_files, | 1928 | .c_source_files = options.c_source_files, |
| 1536 | .rc_source_files = options.rc_source_files, | 1929 | .rc_source_files = options.rc_source_files, |
| 1537 | .cache_parent = cache, | 1930 | .cache_parent = cache, |
| ... | @@ -1572,9 +1965,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1572,9 +1965,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1572 | .framework_dirs = options.framework_dirs, | 1965 | .framework_dirs = options.framework_dirs, |
| 1573 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, | 1966 | .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit, |
| 1574 | .skip_linker_dependencies = options.skip_linker_dependencies, | 1967 | .skip_linker_dependencies = options.skip_linker_dependencies, |
| 1575 | .queued_jobs = .{ | 1968 | .queued_jobs = .{}, |
| 1576 | .update_builtin_zig = have_zcu, | ||
| 1577 | }, | ||
| 1578 | .function_sections = options.function_sections, | 1969 | .function_sections = options.function_sections, |
| 1579 | .data_sections = options.data_sections, | 1970 | .data_sections = options.data_sections, |
| 1580 | .native_system_include_paths = options.native_system_include_paths, | 1971 | .native_system_include_paths = options.native_system_include_paths, |
| ... | @@ -1596,6 +1987,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1596,6 +1987,13 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1596 | comp.config.any_sanitize_c = any_sanitize_c; | 1987 | comp.config.any_sanitize_c = any_sanitize_c; |
| 1597 | comp.config.any_fuzz = any_fuzz; | 1988 | comp.config.any_fuzz = any_fuzz; |
| 1598 | 1989 | ||
| 1990 | if (opt_zcu) |zcu| { | ||
| 1991 | // Populate `zcu.module_roots`. | ||
| 1992 | const pt: Zcu.PerThread = .activate(zcu, .main); | ||
| 1993 | defer pt.deactivate(); | ||
| 1994 | try pt.populateModuleRootTable(); | ||
| 1995 | } | ||
| 1996 | |||
| 1599 | const lf_open_opts: link.File.OpenOptions = .{ | 1997 | const lf_open_opts: link.File.OpenOptions = .{ |
| 1600 | .linker_script = options.linker_script, | 1998 | .linker_script = options.linker_script, |
| 1601 | .z_nodelete = options.linker_z_nodelete, | 1999 | .z_nodelete = options.linker_z_nodelete, |
| ... | @@ -1686,7 +2084,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1686,7 +2084,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1686 | // do want to namespace different source file names because they are | 2084 | // do want to namespace different source file names because they are |
| 1687 | // likely different compilations and therefore this would be likely to | 2085 | // likely different compilations and therefore this would be likely to |
| 1688 | // cause cache hits. | 2086 | // cause cache hits. |
| 1689 | try addModuleTableToCacheHash(gpa, arena, &hash, options.root_mod, main_mod, .path_bytes); | 2087 | if (comp.zcu) |zcu| { |
| 2088 | try addModuleTableToCacheHash(zcu, arena, &hash, .path_bytes); | ||
| 2089 | } else { | ||
| 2090 | cache_helpers.addModule(&hash, options.root_mod); | ||
| 2091 | } | ||
| 1690 | 2092 | ||
| 1691 | // In the case of incremental cache mode, this `artifact_directory` | 2093 | // In the case of incremental cache mode, this `artifact_directory` |
| 1692 | // is computed based on a hash of non-linker inputs, and it is where all | 2094 | // is computed based on a hash of non-linker inputs, and it is where all |
| ... | @@ -1695,11 +2097,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1695,11 +2097,11 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1695 | const digest = hash.final(); | 2097 | const digest = hash.final(); |
| 1696 | 2098 | ||
| 1697 | const artifact_sub_dir = "o" ++ std.fs.path.sep_str ++ digest; | 2099 | const artifact_sub_dir = "o" ++ std.fs.path.sep_str ++ digest; |
| 1698 | var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{}); | 2100 | var artifact_dir = try options.dirs.local_cache.handle.makeOpenPath(artifact_sub_dir, .{}); |
| 1699 | errdefer artifact_dir.close(); | 2101 | errdefer artifact_dir.close(); |
| 1700 | const artifact_directory: Directory = .{ | 2102 | const artifact_directory: Cache.Directory = .{ |
| 1701 | .handle = artifact_dir, | 2103 | .handle = artifact_dir, |
| 1702 | .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}), | 2104 | .path = try options.dirs.local_cache.join(arena, &.{artifact_sub_dir}), |
| 1703 | }; | 2105 | }; |
| 1704 | 2106 | ||
| 1705 | const incremental = try arena.create(CacheUse.Incremental); | 2107 | const incremental = try arena.create(CacheUse.Incremental); |
| ... | @@ -1709,7 +2111,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil | ... | @@ -1709,7 +2111,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil |
| 1709 | comp.cache_use = .{ .incremental = incremental }; | 2111 | comp.cache_use = .{ .incremental = incremental }; |
| 1710 | 2112 | ||
| 1711 | if (options.emit_bin) |emit_bin| { | 2113 | if (options.emit_bin) |emit_bin| { |
| 1712 | const emit: Path = .{ | 2114 | const emit: Cache.Path = .{ |
| 1713 | .root_dir = emit_bin.directory orelse artifact_directory, | 2115 | .root_dir = emit_bin.directory orelse artifact_directory, |
| 1714 | .sub_path = emit_bin.basename, | 2116 | .sub_path = emit_bin.basename, |
| 1715 | }; | 2117 | }; |
| ... | @@ -1998,10 +2400,10 @@ pub fn destroy(comp: *Compilation) void { | ... | @@ -1998,10 +2400,10 @@ pub fn destroy(comp: *Compilation) void { |
| 1998 | if (comp.bin_file) |lf| lf.destroy(); | 2400 | if (comp.bin_file) |lf| lf.destroy(); |
| 1999 | if (comp.zcu) |zcu| zcu.deinit(); | 2401 | if (comp.zcu) |zcu| zcu.deinit(); |
| 2000 | comp.cache_use.deinit(); | 2402 | comp.cache_use.deinit(); |
| 2403 | |||
| 2001 | for (comp.work_queues) |work_queue| work_queue.deinit(); | 2404 | for (comp.work_queues) |work_queue| work_queue.deinit(); |
| 2002 | comp.c_object_work_queue.deinit(); | 2405 | comp.c_object_work_queue.deinit(); |
| 2003 | comp.win32_resource_work_queue.deinit(); | 2406 | comp.win32_resource_work_queue.deinit(); |
| 2004 | comp.astgen_work_queue.deinit(); | ||
| 2005 | 2407 | ||
| 2006 | comp.windows_libs.deinit(gpa); | 2408 | comp.windows_libs.deinit(gpa); |
| 2007 | 2409 | ||
| ... | @@ -2207,15 +2609,15 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2207,15 +2609,15 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2207 | log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name}); | 2609 | log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name}); |
| 2208 | 2610 | ||
| 2209 | // Compile the artifacts to a temporary directory. | 2611 | // Compile the artifacts to a temporary directory. |
| 2210 | const tmp_artifact_directory: Directory = d: { | 2612 | const tmp_artifact_directory: Cache.Directory = d: { |
| 2211 | const s = std.fs.path.sep_str; | 2613 | const s = std.fs.path.sep_str; |
| 2212 | tmp_dir_rand_int = std.crypto.random.int(u64); | 2614 | tmp_dir_rand_int = std.crypto.random.int(u64); |
| 2213 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); | 2615 | const tmp_dir_sub_path = "tmp" ++ s ++ std.fmt.hex(tmp_dir_rand_int); |
| 2214 | 2616 | ||
| 2215 | const path = try comp.local_cache_directory.join(gpa, &.{tmp_dir_sub_path}); | 2617 | const path = try comp.dirs.local_cache.join(gpa, &.{tmp_dir_sub_path}); |
| 2216 | errdefer gpa.free(path); | 2618 | errdefer gpa.free(path); |
| 2217 | 2619 | ||
| 2218 | const handle = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 2620 | const handle = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 2219 | errdefer handle.close(); | 2621 | errdefer handle.close(); |
| 2220 | 2622 | ||
| 2221 | break :d .{ | 2623 | break :d .{ |
| ... | @@ -2243,7 +2645,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2243,7 +2645,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2243 | } | 2645 | } |
| 2244 | 2646 | ||
| 2245 | if (whole.bin_sub_path) |sub_path| { | 2647 | if (whole.bin_sub_path) |sub_path| { |
| 2246 | const emit: Path = .{ | 2648 | const emit: Cache.Path = .{ |
| 2247 | .root_dir = tmp_artifact_directory, | 2649 | .root_dir = tmp_artifact_directory, |
| 2248 | .sub_path = std.fs.path.basename(sub_path), | 2650 | .sub_path = std.fs.path.basename(sub_path), |
| 2249 | }; | 2651 | }; |
| ... | @@ -2265,26 +2667,22 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2265,26 +2667,22 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2265 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. | 2667 | // For compiling C objects, we rely on the cache hash system to avoid duplicating work. |
| 2266 | // Add a Job for each C object. | 2668 | // Add a Job for each C object. |
| 2267 | try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count()); | 2669 | try comp.c_object_work_queue.ensureUnusedCapacity(comp.c_object_table.count()); |
| 2268 | for (comp.c_object_table.keys()) |key| { | 2670 | for (comp.c_object_table.keys()) |c_object| { |
| 2269 | comp.c_object_work_queue.writeItemAssumeCapacity(key); | 2671 | comp.c_object_work_queue.writeItemAssumeCapacity(c_object); |
| 2270 | } | 2672 | try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{c_object.src.src_path})); |
| 2271 | if (comp.file_system_inputs) |fsi| { | ||
| 2272 | for (comp.c_object_table.keys()) |c_object| { | ||
| 2273 | try comp.appendFileSystemInput(fsi, Cache.Path.cwd(), c_object.src.src_path); | ||
| 2274 | } | ||
| 2275 | } | 2673 | } |
| 2276 | 2674 | ||
| 2277 | // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work. | 2675 | // For compiling Win32 resources, we rely on the cache hash system to avoid duplicating work. |
| 2278 | // Add a Job for each Win32 resource file. | 2676 | // Add a Job for each Win32 resource file. |
| 2279 | try comp.win32_resource_work_queue.ensureUnusedCapacity(comp.win32_resource_table.count()); | 2677 | try comp.win32_resource_work_queue.ensureUnusedCapacity(comp.win32_resource_table.count()); |
| 2280 | for (comp.win32_resource_table.keys()) |key| { | 2678 | for (comp.win32_resource_table.keys()) |win32_resource| { |
| 2281 | comp.win32_resource_work_queue.writeItemAssumeCapacity(key); | 2679 | comp.win32_resource_work_queue.writeItemAssumeCapacity(win32_resource); |
| 2282 | } | 2680 | switch (win32_resource.src) { |
| 2283 | if (comp.file_system_inputs) |fsi| { | 2681 | .rc => |f| { |
| 2284 | for (comp.win32_resource_table.keys()) |win32_resource| switch (win32_resource.src) { | 2682 | try comp.appendFileSystemInput(try .fromUnresolved(arena, comp.dirs, &.{f.src_path})); |
| 2285 | .rc => |f| try comp.appendFileSystemInput(fsi, Cache.Path.cwd(), f.src_path), | 2683 | }, |
| 2286 | .manifest => continue, | 2684 | .manifest => {}, |
| 2287 | }; | 2685 | } |
| 2288 | } | 2686 | } |
| 2289 | 2687 | ||
| 2290 | if (comp.zcu) |zcu| { | 2688 | if (comp.zcu) |zcu| { |
| ... | @@ -2293,69 +2691,26 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2293,69 +2691,26 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2293 | 2691 | ||
| 2294 | zcu.skip_analysis_this_update = false; | 2692 | zcu.skip_analysis_this_update = false; |
| 2295 | 2693 | ||
| 2296 | // Make sure std.zig is inside the import_table. We unconditionally need | 2694 | // TODO: doing this in `resolveReferences` later could avoid adding inputs for dead embedfiles. Investigate! |
| 2297 | // it for start.zig. | 2695 | for (zcu.embed_table.keys()) |embed_file| { |
| 2298 | const std_mod = zcu.std_mod; | 2696 | try comp.appendFileSystemInput(embed_file.path); |
| 2299 | _ = try pt.importPkg(std_mod); | ||
| 2300 | |||
| 2301 | // Normally we rely on importing std to in turn import the root source file | ||
| 2302 | // in the start code, but when using the stage1 backend that won't happen, | ||
| 2303 | // so in order to run AstGen on the root source file we put it into the | ||
| 2304 | // import_table here. | ||
| 2305 | // Likewise, in the case of `zig test`, the test runner is the root source file, | ||
| 2306 | // and so there is nothing to import the main file. | ||
| 2307 | if (comp.config.is_test) { | ||
| 2308 | _ = try pt.importPkg(zcu.main_mod); | ||
| 2309 | } | ||
| 2310 | |||
| 2311 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { | ||
| 2312 | _ = try pt.importPkg(ubsan_rt_mod); | ||
| 2313 | } | ||
| 2314 | |||
| 2315 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | ||
| 2316 | _ = try pt.importPkg(compiler_rt_mod); | ||
| 2317 | } | ||
| 2318 | |||
| 2319 | // Put a work item in for every known source file to detect if | ||
| 2320 | // it changed, and, if so, re-compute ZIR and then queue the job | ||
| 2321 | // to update it. | ||
| 2322 | try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count()); | ||
| 2323 | for (zcu.import_table.values()) |file_index| { | ||
| 2324 | if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue; | ||
| 2325 | comp.astgen_work_queue.writeItemAssumeCapacity(file_index); | ||
| 2326 | } | ||
| 2327 | if (comp.file_system_inputs) |fsi| { | ||
| 2328 | for (zcu.import_table.values()) |file_index| { | ||
| 2329 | const file = zcu.fileByIndex(file_index); | ||
| 2330 | try comp.appendFileSystemInput(fsi, file.mod.root, file.sub_file_path); | ||
| 2331 | } | ||
| 2332 | } | ||
| 2333 | |||
| 2334 | if (comp.file_system_inputs) |fsi| { | ||
| 2335 | const ip = &zcu.intern_pool; | ||
| 2336 | for (zcu.embed_table.values()) |embed_file| { | ||
| 2337 | const sub_file_path = embed_file.sub_file_path.toSlice(ip); | ||
| 2338 | try comp.appendFileSystemInput(fsi, embed_file.owner.root, sub_file_path); | ||
| 2339 | } | ||
| 2340 | } | 2697 | } |
| 2341 | 2698 | ||
| 2342 | zcu.analysis_roots.clear(); | 2699 | zcu.analysis_roots.clear(); |
| 2343 | 2700 | ||
| 2344 | try comp.queueJob(.{ .analyze_mod = std_mod }); | 2701 | zcu.analysis_roots.appendAssumeCapacity(zcu.std_mod); |
| 2345 | zcu.analysis_roots.appendAssumeCapacity(std_mod); | ||
| 2346 | 2702 | ||
| 2347 | if (comp.config.is_test and zcu.main_mod != std_mod) { | 2703 | // Normally we rely on importing std to in turn import the root source file in the start code. |
| 2348 | try comp.queueJob(.{ .analyze_mod = zcu.main_mod }); | 2704 | // However, the main module is distinct from the root module in tests, so that won't happen there. |
| 2705 | if (comp.config.is_test and zcu.main_mod != zcu.std_mod) { | ||
| 2349 | zcu.analysis_roots.appendAssumeCapacity(zcu.main_mod); | 2706 | zcu.analysis_roots.appendAssumeCapacity(zcu.main_mod); |
| 2350 | } | 2707 | } |
| 2351 | 2708 | ||
| 2352 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { | 2709 | if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { |
| 2353 | try comp.queueJob(.{ .analyze_mod = compiler_rt_mod }); | ||
| 2354 | zcu.analysis_roots.appendAssumeCapacity(compiler_rt_mod); | 2710 | zcu.analysis_roots.appendAssumeCapacity(compiler_rt_mod); |
| 2355 | } | 2711 | } |
| 2356 | 2712 | ||
| 2357 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { | 2713 | if (zcu.root_mod.deps.get("ubsan_rt")) |ubsan_rt_mod| { |
| 2358 | try comp.queueJob(.{ .analyze_mod = ubsan_rt_mod }); | ||
| 2359 | zcu.analysis_roots.appendAssumeCapacity(ubsan_rt_mod); | 2714 | zcu.analysis_roots.appendAssumeCapacity(ubsan_rt_mod); |
| 2360 | } | 2715 | } |
| 2361 | } | 2716 | } |
| ... | @@ -2451,13 +2806,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2451,13 +2806,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2451 | break :w .no; | 2806 | break :w .no; |
| 2452 | }; | 2807 | }; |
| 2453 | 2808 | ||
| 2454 | renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path) catch |err| { | 2809 | renameTmpIntoCache(comp.dirs.local_cache, tmp_dir_sub_path, o_sub_path) catch |err| { |
| 2455 | return comp.setMiscFailure( | 2810 | return comp.setMiscFailure( |
| 2456 | .rename_results, | 2811 | .rename_results, |
| 2457 | "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}", | 2812 | "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}", |
| 2458 | .{ | 2813 | .{ |
| 2459 | comp.local_cache_directory, tmp_dir_sub_path, | 2814 | comp.dirs.local_cache, tmp_dir_sub_path, |
| 2460 | comp.local_cache_directory, o_sub_path, | 2815 | comp.dirs.local_cache, o_sub_path, |
| 2461 | @errorName(err), | 2816 | @errorName(err), |
| 2462 | }, | 2817 | }, |
| 2463 | ); | 2818 | ); |
| ... | @@ -2470,7 +2825,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2470,7 +2825,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2470 | // references object file paths. | 2825 | // references object file paths. |
| 2471 | if (comp.bin_file) |lf| { | 2826 | if (comp.bin_file) |lf| { |
| 2472 | lf.emit = .{ | 2827 | lf.emit = .{ |
| 2473 | .root_dir = comp.local_cache_directory, | 2828 | .root_dir = comp.dirs.local_cache, |
| 2474 | .sub_path = whole.bin_sub_path.?, | 2829 | .sub_path = whole.bin_sub_path.?, |
| 2475 | }; | 2830 | }; |
| 2476 | 2831 | ||
| ... | @@ -2486,7 +2841,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2486,7 +2841,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2486 | } | 2841 | } |
| 2487 | 2842 | ||
| 2488 | try flush(comp, arena, .{ | 2843 | try flush(comp, arena, .{ |
| 2489 | .root_dir = comp.local_cache_directory, | 2844 | .root_dir = comp.dirs.local_cache, |
| 2490 | .sub_path = o_sub_path, | 2845 | .sub_path = o_sub_path, |
| 2491 | }, .main, main_progress_node); | 2846 | }, .main, main_progress_node); |
| 2492 | 2847 | ||
| ... | @@ -2515,34 +2870,36 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { | ... | @@ -2515,34 +2870,36 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2515 | } | 2870 | } |
| 2516 | } | 2871 | } |
| 2517 | 2872 | ||
| 2518 | pub fn appendFileSystemInput( | 2873 | pub fn appendFileSystemInput(comp: *Compilation, path: Compilation.Path) Allocator.Error!void { |
| 2519 | comp: *Compilation, | ||
| 2520 | file_system_inputs: *std.ArrayListUnmanaged(u8), | ||
| 2521 | root: Cache.Path, | ||
| 2522 | sub_file_path: []const u8, | ||
| 2523 | ) Allocator.Error!void { | ||
| 2524 | const gpa = comp.gpa; | 2874 | const gpa = comp.gpa; |
| 2875 | const fsi = comp.file_system_inputs orelse return; | ||
| 2525 | const prefixes = comp.cache_parent.prefixes(); | 2876 | const prefixes = comp.cache_parent.prefixes(); |
| 2526 | try file_system_inputs.ensureUnusedCapacity(gpa, root.sub_path.len + sub_file_path.len + 3); | 2877 | |
| 2527 | if (file_system_inputs.items.len > 0) file_system_inputs.appendAssumeCapacity(0); | 2878 | const want_prefix_dir: Cache.Directory = switch (path.root) { |
| 2528 | for (prefixes, 1..) |prefix_directory, i| { | 2879 | .zig_lib => comp.dirs.zig_lib, |
| 2529 | if (prefix_directory.eql(root.root_dir)) { | 2880 | .global_cache => comp.dirs.global_cache, |
| 2530 | file_system_inputs.appendAssumeCapacity(@intCast(i)); | 2881 | .local_cache => comp.dirs.local_cache, |
| 2531 | if (root.sub_path.len > 0) { | 2882 | .none => .cwd(), |
| 2532 | file_system_inputs.appendSliceAssumeCapacity(root.sub_path); | 2883 | }; |
| 2533 | file_system_inputs.appendAssumeCapacity(std.fs.path.sep); | 2884 | const prefix: u8 = for (prefixes, 1..) |prefix_dir, i| { |
| 2534 | } | 2885 | if (prefix_dir.eql(want_prefix_dir)) { |
| 2535 | file_system_inputs.appendSliceAssumeCapacity(sub_file_path); | 2886 | break @intCast(i); |
| 2536 | return; | ||
| 2537 | } | 2887 | } |
| 2538 | } | 2888 | } else std.debug.panic( |
| 2539 | std.debug.panic("missing prefix directory: {}, {s}", .{ root, sub_file_path }); | 2889 | "missing prefix directory '{s}' ('{}') for '{s}'", |
| 2890 | .{ @tagName(path.root), want_prefix_dir, path.sub_path }, | ||
| 2891 | ); | ||
| 2892 | |||
| 2893 | try fsi.ensureUnusedCapacity(gpa, path.sub_path.len + 3); | ||
| 2894 | if (fsi.items.len > 0) fsi.appendAssumeCapacity(0); | ||
| 2895 | fsi.appendAssumeCapacity(prefix); | ||
| 2896 | fsi.appendSliceAssumeCapacity(path.sub_path); | ||
| 2540 | } | 2897 | } |
| 2541 | 2898 | ||
| 2542 | fn flush( | 2899 | fn flush( |
| 2543 | comp: *Compilation, | 2900 | comp: *Compilation, |
| 2544 | arena: Allocator, | 2901 | arena: Allocator, |
| 2545 | default_artifact_directory: Path, | 2902 | default_artifact_directory: Cache.Path, |
| 2546 | tid: Zcu.PerThread.Id, | 2903 | tid: Zcu.PerThread.Id, |
| 2547 | prog_node: std.Progress.Node, | 2904 | prog_node: std.Progress.Node, |
| 2548 | ) !void { | 2905 | ) !void { |
| ... | @@ -2574,7 +2931,7 @@ fn flush( | ... | @@ -2574,7 +2931,7 @@ fn flush( |
| 2574 | /// implementation at the bottom of this function. | 2931 | /// implementation at the bottom of this function. |
| 2575 | /// This function is only called when CacheMode is `whole`. | 2932 | /// This function is only called when CacheMode is `whole`. |
| 2576 | fn renameTmpIntoCache( | 2933 | fn renameTmpIntoCache( |
| 2577 | cache_directory: Compilation.Directory, | 2934 | cache_directory: Cache.Directory, |
| 2578 | tmp_dir_sub_path: []const u8, | 2935 | tmp_dir_sub_path: []const u8, |
| 2579 | o_sub_path: []const u8, | 2936 | o_sub_path: []const u8, |
| 2580 | ) !void { | 2937 | ) !void { |
| ... | @@ -2627,7 +2984,7 @@ fn wholeCacheModeSetBinFilePath( | ... | @@ -2627,7 +2984,7 @@ fn wholeCacheModeSetBinFilePath( |
| 2627 | @memcpy(sub_path[digest_start..][0..digest.len], digest); | 2984 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2628 | 2985 | ||
| 2629 | comp.implib_emit = .{ | 2986 | comp.implib_emit = .{ |
| 2630 | .root_dir = comp.local_cache_directory, | 2987 | .root_dir = comp.dirs.local_cache, |
| 2631 | .sub_path = sub_path, | 2988 | .sub_path = sub_path, |
| 2632 | }; | 2989 | }; |
| 2633 | } | 2990 | } |
| ... | @@ -2636,7 +2993,7 @@ fn wholeCacheModeSetBinFilePath( | ... | @@ -2636,7 +2993,7 @@ fn wholeCacheModeSetBinFilePath( |
| 2636 | @memcpy(sub_path[digest_start..][0..digest.len], digest); | 2993 | @memcpy(sub_path[digest_start..][0..digest.len], digest); |
| 2637 | 2994 | ||
| 2638 | comp.docs_emit = .{ | 2995 | comp.docs_emit = .{ |
| 2639 | .root_dir = comp.local_cache_directory, | 2996 | .root_dir = comp.dirs.local_cache, |
| 2640 | .sub_path = sub_path, | 2997 | .sub_path = sub_path, |
| 2641 | }; | 2998 | }; |
| 2642 | } | 2999 | } |
| ... | @@ -2661,19 +3018,17 @@ fn addNonIncrementalStuffToCacheManifest( | ... | @@ -2661,19 +3018,17 @@ fn addNonIncrementalStuffToCacheManifest( |
| 2661 | arena: Allocator, | 3018 | arena: Allocator, |
| 2662 | man: *Cache.Manifest, | 3019 | man: *Cache.Manifest, |
| 2663 | ) !void { | 3020 | ) !void { |
| 2664 | const gpa = comp.gpa; | ||
| 2665 | |||
| 2666 | comptime assert(link_hash_implementation_version == 14); | 3021 | comptime assert(link_hash_implementation_version == 14); |
| 2667 | 3022 | ||
| 2668 | if (comp.zcu) |mod| { | 3023 | if (comp.zcu) |zcu| { |
| 2669 | try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.root_mod, mod.main_mod, .{ .files = man }); | 3024 | try addModuleTableToCacheHash(zcu, arena, &man.hash, .{ .files = man }); |
| 2670 | 3025 | ||
| 2671 | // Synchronize with other matching comments: ZigOnlyHashStuff | 3026 | // Synchronize with other matching comments: ZigOnlyHashStuff |
| 2672 | man.hash.addListOfBytes(comp.test_filters); | 3027 | man.hash.addListOfBytes(comp.test_filters); |
| 2673 | man.hash.addOptionalBytes(comp.test_name_prefix); | 3028 | man.hash.addOptionalBytes(comp.test_name_prefix); |
| 2674 | man.hash.add(comp.skip_linker_dependencies); | 3029 | man.hash.add(comp.skip_linker_dependencies); |
| 2675 | //man.hash.add(mod.emit_h != null); | 3030 | //man.hash.add(zcu.emit_h != null); |
| 2676 | man.hash.add(mod.error_limit); | 3031 | man.hash.add(zcu.error_limit); |
| 2677 | } else { | 3032 | } else { |
| 2678 | cache_helpers.addModule(&man.hash, comp.root_mod); | 3033 | cache_helpers.addModule(&man.hash, comp.root_mod); |
| 2679 | } | 3034 | } |
| ... | @@ -2839,7 +3194,7 @@ fn emitOthers(comp: *Compilation) void { | ... | @@ -2839,7 +3194,7 @@ fn emitOthers(comp: *Compilation) void { |
| 2839 | pub fn emitLlvmObject( | 3194 | pub fn emitLlvmObject( |
| 2840 | comp: *Compilation, | 3195 | comp: *Compilation, |
| 2841 | arena: Allocator, | 3196 | arena: Allocator, |
| 2842 | default_artifact_directory: Path, | 3197 | default_artifact_directory: Cache.Path, |
| 2843 | bin_emit_loc: ?EmitLoc, | 3198 | bin_emit_loc: ?EmitLoc, |
| 2844 | llvm_object: LlvmObject.Ptr, | 3199 | llvm_object: LlvmObject.Ptr, |
| 2845 | prog_node: std.Progress.Node, | 3200 | prog_node: std.Progress.Node, |
| ... | @@ -2866,7 +3221,7 @@ pub fn emitLlvmObject( | ... | @@ -2866,7 +3221,7 @@ pub fn emitLlvmObject( |
| 2866 | 3221 | ||
| 2867 | fn resolveEmitLoc( | 3222 | fn resolveEmitLoc( |
| 2868 | arena: Allocator, | 3223 | arena: Allocator, |
| 2869 | default_artifact_directory: Path, | 3224 | default_artifact_directory: Cache.Path, |
| 2870 | opt_loc: ?EmitLoc, | 3225 | opt_loc: ?EmitLoc, |
| 2871 | ) Allocator.Error!?[*:0]const u8 { | 3226 | ) Allocator.Error!?[*:0]const u8 { |
| 2872 | const loc = opt_loc orelse return null; | 3227 | const loc = opt_loc orelse return null; |
| ... | @@ -2877,132 +3232,6 @@ fn resolveEmitLoc( | ... | @@ -2877,132 +3232,6 @@ fn resolveEmitLoc( |
| 2877 | return slice.ptr; | 3232 | return slice.ptr; |
| 2878 | } | 3233 | } |
| 2879 | 3234 | ||
| 2880 | fn reportMultiModuleErrors(pt: Zcu.PerThread) !void { | ||
| 2881 | const zcu = pt.zcu; | ||
| 2882 | const gpa = zcu.gpa; | ||
| 2883 | const ip = &zcu.intern_pool; | ||
| 2884 | // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to | ||
| 2885 | // print all of, so we'll cap the number of these to emit. | ||
| 2886 | var num_errors: u32 = 0; | ||
| 2887 | const max_errors = 5; | ||
| 2888 | // Attach the "some omitted" note to the final error message | ||
| 2889 | var last_err: ?*Zcu.ErrorMsg = null; | ||
| 2890 | |||
| 2891 | for (zcu.import_table.values()) |file_index| { | ||
| 2892 | const file = zcu.fileByIndex(file_index); | ||
| 2893 | if (!file.multi_pkg) continue; | ||
| 2894 | |||
| 2895 | num_errors += 1; | ||
| 2896 | if (num_errors > max_errors) continue; | ||
| 2897 | |||
| 2898 | const err = err_blk: { | ||
| 2899 | // Like with errors, let's cap the number of notes to prevent a huge error spew. | ||
| 2900 | const max_notes = 5; | ||
| 2901 | const omitted = file.references.items.len -| max_notes; | ||
| 2902 | const num_notes = file.references.items.len - omitted; | ||
| 2903 | |||
| 2904 | const notes = try gpa.alloc(Zcu.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes); | ||
| 2905 | errdefer gpa.free(notes); | ||
| 2906 | |||
| 2907 | for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| { | ||
| 2908 | errdefer for (notes[0..i]) |*n| n.deinit(gpa); | ||
| 2909 | note.* = switch (ref) { | ||
| 2910 | .import => |import| try Zcu.ErrorMsg.init( | ||
| 2911 | gpa, | ||
| 2912 | .{ | ||
| 2913 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2914 | .file = import.file, | ||
| 2915 | .inst = .main_struct_inst, | ||
| 2916 | }), | ||
| 2917 | .offset = .{ .token_abs = import.token }, | ||
| 2918 | }, | ||
| 2919 | "imported from module {s}", | ||
| 2920 | .{zcu.fileByIndex(import.file).mod.fully_qualified_name}, | ||
| 2921 | ), | ||
| 2922 | .root => |pkg| try Zcu.ErrorMsg.init( | ||
| 2923 | gpa, | ||
| 2924 | .{ | ||
| 2925 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2926 | .file = file_index, | ||
| 2927 | .inst = .main_struct_inst, | ||
| 2928 | }), | ||
| 2929 | .offset = .entire_file, | ||
| 2930 | }, | ||
| 2931 | "root of module {s}", | ||
| 2932 | .{pkg.fully_qualified_name}, | ||
| 2933 | ), | ||
| 2934 | }; | ||
| 2935 | } | ||
| 2936 | errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa); | ||
| 2937 | |||
| 2938 | if (omitted > 0) { | ||
| 2939 | notes[num_notes] = try Zcu.ErrorMsg.init( | ||
| 2940 | gpa, | ||
| 2941 | .{ | ||
| 2942 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2943 | .file = file_index, | ||
| 2944 | .inst = .main_struct_inst, | ||
| 2945 | }), | ||
| 2946 | .offset = .entire_file, | ||
| 2947 | }, | ||
| 2948 | "{} more references omitted", | ||
| 2949 | .{omitted}, | ||
| 2950 | ); | ||
| 2951 | } | ||
| 2952 | errdefer if (omitted > 0) notes[num_notes].deinit(gpa); | ||
| 2953 | |||
| 2954 | const err = try Zcu.ErrorMsg.create( | ||
| 2955 | gpa, | ||
| 2956 | .{ | ||
| 2957 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 2958 | .file = file_index, | ||
| 2959 | .inst = .main_struct_inst, | ||
| 2960 | }), | ||
| 2961 | .offset = .entire_file, | ||
| 2962 | }, | ||
| 2963 | "file exists in multiple modules", | ||
| 2964 | .{}, | ||
| 2965 | ); | ||
| 2966 | err.notes = notes; | ||
| 2967 | break :err_blk err; | ||
| 2968 | }; | ||
| 2969 | errdefer err.destroy(gpa); | ||
| 2970 | try zcu.failed_files.putNoClobber(gpa, file, err); | ||
| 2971 | last_err = err; | ||
| 2972 | } | ||
| 2973 | |||
| 2974 | // If we omitted any errors, add a note saying that | ||
| 2975 | if (num_errors > max_errors) { | ||
| 2976 | const err = last_err.?; | ||
| 2977 | |||
| 2978 | // There isn't really any meaningful place to put this note, so just attach it to the | ||
| 2979 | // last failed file | ||
| 2980 | var note = try Zcu.ErrorMsg.init( | ||
| 2981 | gpa, | ||
| 2982 | err.src_loc, | ||
| 2983 | "{} more errors omitted", | ||
| 2984 | .{num_errors - max_errors}, | ||
| 2985 | ); | ||
| 2986 | errdefer note.deinit(gpa); | ||
| 2987 | |||
| 2988 | const i = err.notes.len; | ||
| 2989 | err.notes = try gpa.realloc(err.notes, i + 1); | ||
| 2990 | err.notes[i] = note; | ||
| 2991 | } | ||
| 2992 | |||
| 2993 | // Now that we've reported the errors, we need to deal with | ||
| 2994 | // dependencies. Any file referenced by a multi_pkg file should also be | ||
| 2995 | // marked multi_pkg and have its status set to astgen_failure, as it's | ||
| 2996 | // ambiguous which package they should be analyzed as a part of. We need | ||
| 2997 | // to add this flag after reporting the errors however, as otherwise | ||
| 2998 | // we'd get an error for every single downstream file, which wouldn't be | ||
| 2999 | // very useful. | ||
| 3000 | for (zcu.import_table.values()) |file_index| { | ||
| 3001 | const file = zcu.fileByIndex(file_index); | ||
| 3002 | if (file.multi_pkg) file.recursiveMarkMultiPkg(pt); | ||
| 3003 | } | ||
| 3004 | } | ||
| 3005 | |||
| 3006 | /// Having the file open for writing is problematic as far as executing the | 3235 | /// Having the file open for writing is problematic as far as executing the |
| 3007 | /// binary is concerned. This will remove the write flag, or close the file, | 3236 | /// binary is concerned. This will remove the write flag, or close the file, |
| 3008 | /// or whatever is needed so that it can be executed. | 3237 | /// or whatever is needed so that it can be executed. |
| ... | @@ -3326,16 +3555,77 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { | ... | @@ -3326,16 +3555,77 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3326 | } | 3555 | } |
| 3327 | 3556 | ||
| 3328 | if (comp.zcu) |zcu| zcu_errors: { | 3557 | if (comp.zcu) |zcu| zcu_errors: { |
| 3329 | for (zcu.failed_files.keys(), zcu.failed_files.values()) |file, error_msg| { | 3558 | if (zcu.multi_module_err != null) { |
| 3559 | try zcu.addFileInMultipleModulesError(&bundle); | ||
| 3560 | break :zcu_errors; | ||
| 3561 | } | ||
| 3562 | for (zcu.failed_imports.items) |failed| { | ||
| 3563 | assert(zcu.alive_files.contains(failed.file_index)); // otherwise it wouldn't have been added | ||
| 3564 | const file = zcu.fileByIndex(failed.file_index); | ||
| 3565 | const source = try file.getSource(zcu); | ||
| 3566 | const tree = try file.getTree(zcu); | ||
| 3567 | const start = tree.tokenStart(failed.import_token); | ||
| 3568 | const end = start + tree.tokenSlice(failed.import_token).len; | ||
| 3569 | const loc = std.zig.findLineColumn(source.bytes, start); | ||
| 3570 | try bundle.addRootErrorMessage(.{ | ||
| 3571 | .msg = switch (failed.kind) { | ||
| 3572 | .file_outside_module_root => try bundle.addString("import of file outside module path"), | ||
| 3573 | .illegal_zig_import => try bundle.addString("this compiler implementation does not allow importing files from this directory"), | ||
| 3574 | }, | ||
| 3575 | .src_loc = try bundle.addSourceLocation(.{ | ||
| 3576 | .src_path = try bundle.printString("{}", .{file.path.fmt(comp)}), | ||
| 3577 | .span_start = start, | ||
| 3578 | .span_main = start, | ||
| 3579 | .span_end = @intCast(end), | ||
| 3580 | .line = @intCast(loc.line), | ||
| 3581 | .column = @intCast(loc.column), | ||
| 3582 | .source_line = try bundle.addString(loc.source_line), | ||
| 3583 | }), | ||
| 3584 | .notes_len = 0, | ||
| 3585 | }); | ||
| 3586 | } | ||
| 3587 | |||
| 3588 | // Before iterating `failed_files`, we need to sort it into a consistent order so that error | ||
| 3589 | // messages appear consistently despite different ordering from the AstGen worker pool. File | ||
| 3590 | // paths are a great key for this sort! We are using sorting the `ArrayHashMap` itself to | ||
| 3591 | // make sure it reindexes; that's important because these entries need to be retained for | ||
| 3592 | // future updates. | ||
| 3593 | const FileSortCtx = struct { | ||
| 3594 | zcu: *Zcu, | ||
| 3595 | failed_files_keys: []const Zcu.File.Index, | ||
| 3596 | pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool { | ||
| 3597 | const lhs_path = ctx.zcu.fileByIndex(ctx.failed_files_keys[lhs_index]).path; | ||
| 3598 | const rhs_path = ctx.zcu.fileByIndex(ctx.failed_files_keys[rhs_index]).path; | ||
| 3599 | if (lhs_path.root != rhs_path.root) return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root); | ||
| 3600 | return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt); | ||
| 3601 | } | ||
| 3602 | }; | ||
| 3603 | zcu.failed_files.sort(@as(FileSortCtx, .{ | ||
| 3604 | .zcu = zcu, | ||
| 3605 | .failed_files_keys = zcu.failed_files.keys(), | ||
| 3606 | })); | ||
| 3607 | |||
| 3608 | for (zcu.failed_files.keys(), zcu.failed_files.values()) |file_index, error_msg| { | ||
| 3609 | if (!zcu.alive_files.contains(file_index)) continue; | ||
| 3610 | const file = zcu.fileByIndex(file_index); | ||
| 3611 | const is_retryable = switch (file.status) { | ||
| 3612 | .retryable_failure => true, | ||
| 3613 | .success, .astgen_failure => false, | ||
| 3614 | .never_loaded => unreachable, | ||
| 3615 | }; | ||
| 3330 | if (error_msg) |msg| { | 3616 | if (error_msg) |msg| { |
| 3331 | try addModuleErrorMsg(zcu, &bundle, msg.*, false); | 3617 | assert(is_retryable); |
| 3618 | try addWholeFileError(zcu, &bundle, file_index, msg); | ||
| 3332 | } else { | 3619 | } else { |
| 3333 | // Must be ZIR or Zoir errors. Note that this may include AST errors. | 3620 | assert(!is_retryable); |
| 3334 | _ = try file.getTree(gpa); // Tree must be loaded. | 3621 | // AstGen/ZoirGen succeeded with errors. Note that this may include AST errors. |
| 3622 | _ = try file.getTree(zcu); // Tree must be loaded. | ||
| 3623 | const path = try std.fmt.allocPrint(gpa, "{}", .{file.path.fmt(comp)}); | ||
| 3624 | defer gpa.free(path); | ||
| 3335 | if (file.zir != null) { | 3625 | if (file.zir != null) { |
| 3336 | try addZirErrorMessages(&bundle, file); | 3626 | try bundle.addZirErrorMessages(file.zir.?, file.tree.?, file.source.?, path); |
| 3337 | } else if (file.zoir != null) { | 3627 | } else if (file.zoir != null) { |
| 3338 | try addZoirErrorMessages(&bundle, file); | 3628 | try bundle.addZoirErrorMessages(file.zoir.?, file.tree.?, file.source.?, path); |
| 3339 | } else { | 3629 | } else { |
| 3340 | // Either Zir or Zoir must have been loaded. | 3630 | // Either Zir or Zoir must have been loaded. |
| 3341 | unreachable; | 3631 | unreachable; |
| ... | @@ -3646,20 +3936,16 @@ pub fn addModuleErrorMsg( | ... | @@ -3646,20 +3936,16 @@ pub fn addModuleErrorMsg( |
| 3646 | const gpa = eb.gpa; | 3936 | const gpa = eb.gpa; |
| 3647 | const ip = &zcu.intern_pool; | 3937 | const ip = &zcu.intern_pool; |
| 3648 | const err_src_loc = module_err_msg.src_loc.upgrade(zcu); | 3938 | const err_src_loc = module_err_msg.src_loc.upgrade(zcu); |
| 3649 | const err_source = err_src_loc.file_scope.getSource(gpa) catch |err| { | 3939 | const err_source = err_src_loc.file_scope.getSource(zcu) catch |err| { |
| 3650 | const file_path = try err_src_loc.file_scope.fullPath(gpa); | ||
| 3651 | defer gpa.free(file_path); | ||
| 3652 | try eb.addRootErrorMessage(.{ | 3940 | try eb.addRootErrorMessage(.{ |
| 3653 | .msg = try eb.printString("unable to load '{s}': {s}", .{ | 3941 | .msg = try eb.printString("unable to load '{}': {s}", .{ |
| 3654 | file_path, @errorName(err), | 3942 | err_src_loc.file_scope.path.fmt(zcu.comp), @errorName(err), |
| 3655 | }), | 3943 | }), |
| 3656 | }); | 3944 | }); |
| 3657 | return; | 3945 | return; |
| 3658 | }; | 3946 | }; |
| 3659 | const err_span = try err_src_loc.span(gpa); | 3947 | const err_span = try err_src_loc.span(zcu); |
| 3660 | const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main); | 3948 | const err_loc = std.zig.findLineColumn(err_source.bytes, err_span.main); |
| 3661 | const file_path = try err_src_loc.file_scope.fullPath(gpa); | ||
| 3662 | defer gpa.free(file_path); | ||
| 3663 | 3949 | ||
| 3664 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty; | 3950 | var ref_traces: std.ArrayListUnmanaged(ErrorBundle.ReferenceTrace) = .empty; |
| 3665 | defer ref_traces.deinit(gpa); | 3951 | defer ref_traces.deinit(gpa); |
| ... | @@ -3715,16 +4001,13 @@ pub fn addModuleErrorMsg( | ... | @@ -3715,16 +4001,13 @@ pub fn addModuleErrorMsg( |
| 3715 | } | 4001 | } |
| 3716 | 4002 | ||
| 3717 | const src_loc = try eb.addSourceLocation(.{ | 4003 | const src_loc = try eb.addSourceLocation(.{ |
| 3718 | .src_path = try eb.addString(file_path), | 4004 | .src_path = try eb.printString("{}", .{err_src_loc.file_scope.path.fmt(zcu.comp)}), |
| 3719 | .span_start = err_span.start, | 4005 | .span_start = err_span.start, |
| 3720 | .span_main = err_span.main, | 4006 | .span_main = err_span.main, |
| 3721 | .span_end = err_span.end, | 4007 | .span_end = err_span.end, |
| 3722 | .line = @intCast(err_loc.line), | 4008 | .line = @intCast(err_loc.line), |
| 3723 | .column = @intCast(err_loc.column), | 4009 | .column = @intCast(err_loc.column), |
| 3724 | .source_line = if (err_src_loc.lazy == .entire_file) | 4010 | .source_line = try eb.addString(err_loc.source_line), |
| 3725 | 0 | ||
| 3726 | else | ||
| 3727 | try eb.addString(err_loc.source_line), | ||
| 3728 | .reference_trace_len = @intCast(ref_traces.items.len), | 4011 | .reference_trace_len = @intCast(ref_traces.items.len), |
| 3729 | }); | 4012 | }); |
| 3730 | 4013 | ||
| ... | @@ -3740,11 +4023,9 @@ pub fn addModuleErrorMsg( | ... | @@ -3740,11 +4023,9 @@ pub fn addModuleErrorMsg( |
| 3740 | var last_note_loc: ?std.zig.Loc = null; | 4023 | var last_note_loc: ?std.zig.Loc = null; |
| 3741 | for (module_err_msg.notes) |module_note| { | 4024 | for (module_err_msg.notes) |module_note| { |
| 3742 | const note_src_loc = module_note.src_loc.upgrade(zcu); | 4025 | const note_src_loc = module_note.src_loc.upgrade(zcu); |
| 3743 | const source = try note_src_loc.file_scope.getSource(gpa); | 4026 | const source = try note_src_loc.file_scope.getSource(zcu); |
| 3744 | const span = try note_src_loc.span(gpa); | 4027 | const span = try note_src_loc.span(zcu); |
| 3745 | const loc = std.zig.findLineColumn(source.bytes, span.main); | 4028 | const loc = std.zig.findLineColumn(source.bytes, span.main); |
| 3746 | const note_file_path = try note_src_loc.file_scope.fullPath(gpa); | ||
| 3747 | defer gpa.free(note_file_path); | ||
| 3748 | 4029 | ||
| 3749 | const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?)); | 4030 | const omit_source_line = loc.eql(err_loc) or (last_note_loc != null and loc.eql(last_note_loc.?)); |
| 3750 | last_note_loc = loc; | 4031 | last_note_loc = loc; |
| ... | @@ -3752,7 +4033,7 @@ pub fn addModuleErrorMsg( | ... | @@ -3752,7 +4033,7 @@ pub fn addModuleErrorMsg( |
| 3752 | const gop = try notes.getOrPutContext(gpa, .{ | 4033 | const gop = try notes.getOrPutContext(gpa, .{ |
| 3753 | .msg = try eb.addString(module_note.msg), | 4034 | .msg = try eb.addString(module_note.msg), |
| 3754 | .src_loc = try eb.addSourceLocation(.{ | 4035 | .src_loc = try eb.addSourceLocation(.{ |
| 3755 | .src_path = try eb.addString(note_file_path), | 4036 | .src_path = try eb.printString("{}", .{note_src_loc.file_scope.path.fmt(zcu.comp)}), |
| 3756 | .span_start = span.start, | 4037 | .span_start = span.start, |
| 3757 | .span_main = span.main, | 4038 | .span_main = span.main, |
| 3758 | .span_end = span.end, | 4039 | .span_end = span.end, |
| ... | @@ -3791,15 +4072,13 @@ fn addReferenceTraceFrame( | ... | @@ -3791,15 +4072,13 @@ fn addReferenceTraceFrame( |
| 3791 | ) !void { | 4072 | ) !void { |
| 3792 | const gpa = zcu.gpa; | 4073 | const gpa = zcu.gpa; |
| 3793 | const src = lazy_src.upgrade(zcu); | 4074 | const src = lazy_src.upgrade(zcu); |
| 3794 | const source = try src.file_scope.getSource(gpa); | 4075 | const source = try src.file_scope.getSource(zcu); |
| 3795 | const span = try src.span(gpa); | 4076 | const span = try src.span(zcu); |
| 3796 | const loc = std.zig.findLineColumn(source.bytes, span.main); | 4077 | const loc = std.zig.findLineColumn(source.bytes, span.main); |
| 3797 | const rt_file_path = try src.file_scope.fullPath(gpa); | ||
| 3798 | defer gpa.free(rt_file_path); | ||
| 3799 | try ref_traces.append(gpa, .{ | 4078 | try ref_traces.append(gpa, .{ |
| 3800 | .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }), | 4079 | .decl_name = try eb.printString("{s}{s}", .{ name, if (inlined) " [inlined]" else "" }), |
| 3801 | .src_loc = try eb.addSourceLocation(.{ | 4080 | .src_loc = try eb.addSourceLocation(.{ |
| 3802 | .src_path = try eb.addString(rt_file_path), | 4081 | .src_path = try eb.printString("{}", .{src.file_scope.path.fmt(zcu.comp)}), |
| 3803 | .span_start = span.start, | 4082 | .span_start = span.start, |
| 3804 | .span_main = span.main, | 4083 | .span_main = span.main, |
| 3805 | .span_end = span.end, | 4084 | .span_end = span.end, |
| ... | @@ -3810,18 +4089,30 @@ fn addReferenceTraceFrame( | ... | @@ -3810,18 +4089,30 @@ fn addReferenceTraceFrame( |
| 3810 | }); | 4089 | }); |
| 3811 | } | 4090 | } |
| 3812 | 4091 | ||
| 3813 | pub fn addZirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void { | 4092 | pub fn addWholeFileError( |
| 3814 | const gpa = eb.gpa; | 4093 | zcu: *Zcu, |
| 3815 | const src_path = try file.fullPath(gpa); | 4094 | eb: *ErrorBundle.Wip, |
| 3816 | defer gpa.free(src_path); | 4095 | file_index: Zcu.File.Index, |
| 3817 | return eb.addZirErrorMessages(file.zir.?, file.tree.?, file.source.?, src_path); | 4096 | msg: []const u8, |
| 3818 | } | 4097 | ) !void { |
| 4098 | // note: "file imported here" on the import reference token | ||
| 4099 | const imported_note: ?ErrorBundle.MessageIndex = switch (zcu.alive_files.get(file_index).?) { | ||
| 4100 | .analysis_root => null, | ||
| 4101 | .import => |import| try eb.addErrorMessage(.{ | ||
| 4102 | .msg = try eb.addString("file imported here"), | ||
| 4103 | .src_loc = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb), | ||
| 4104 | }), | ||
| 4105 | }; | ||
| 3819 | 4106 | ||
| 3820 | pub fn addZoirErrorMessages(eb: *ErrorBundle.Wip, file: *Zcu.File) !void { | 4107 | try eb.addRootErrorMessage(.{ |
| 3821 | const gpa = eb.gpa; | 4108 | .msg = try eb.addString(msg), |
| 3822 | const src_path = try file.fullPath(gpa); | 4109 | .src_loc = try zcu.fileByIndex(file_index).errorBundleWholeFileSrc(zcu, eb), |
| 3823 | defer gpa.free(src_path); | 4110 | .notes_len = if (imported_note != null) 1 else 0, |
| 3824 | return eb.addZoirErrorMessages(file.zoir.?, file.tree.?, file.source.?, src_path); | 4111 | }); |
| 4112 | if (imported_note) |n| { | ||
| 4113 | const note_idx = try eb.reserveNotes(1); | ||
| 4114 | eb.extra.items[note_idx] = @intFromEnum(n); | ||
| 4115 | } | ||
| 3825 | } | 4116 | } |
| 3826 | 4117 | ||
| 3827 | pub fn performAllTheWork( | 4118 | pub fn performAllTheWork( |
| ... | @@ -3966,51 +4257,48 @@ fn performAllTheWorkInner( | ... | @@ -3966,51 +4257,48 @@ fn performAllTheWorkInner( |
| 3966 | var astgen_wait_group: WaitGroup = .{}; | 4257 | var astgen_wait_group: WaitGroup = .{}; |
| 3967 | defer astgen_wait_group.wait(); | 4258 | defer astgen_wait_group.wait(); |
| 3968 | 4259 | ||
| 3969 | // builtin.zig is handled specially for two reasons: | 4260 | if (comp.zcu) |zcu| { |
| 3970 | // 1. to avoid race condition of zig processes truncating each other's builtin.zig files | 4261 | const gpa = zcu.gpa; |
| 3971 | // 2. optimization; in the hot path it only incurs a stat() syscall, which happens | 4262 | |
| 3972 | // in the `astgen_wait_group`. | 4263 | // We cannot reference `zcu.import_table` after we spawn any `workerUpdateFile` jobs, |
| 3973 | if (comp.queued_jobs.update_builtin_zig) b: { | 4264 | // because on single-threaded targets the worker will be run eagerly, meaning the |
| 3974 | comp.queued_jobs.update_builtin_zig = false; | 4265 | // `import_table` could be mutated, and not even holding `comp.mutex` will save us. So, |
| 3975 | if (comp.zcu == null) break :b; | 4266 | // build up a list of the files to update *before* we spawn any jobs. |
| 3976 | // TODO put all the modules in a flat array to make them easy to iterate. | 4267 | var astgen_work_items: std.MultiArrayList(struct { |
| 3977 | var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .empty; | 4268 | file_index: Zcu.File.Index, |
| 3978 | defer seen.deinit(comp.gpa); | 4269 | file: *Zcu.File, |
| 3979 | try seen.put(comp.gpa, comp.root_mod, {}); | 4270 | }) = .empty; |
| 3980 | var i: usize = 0; | 4271 | defer astgen_work_items.deinit(gpa); |
| 3981 | while (i < seen.count()) : (i += 1) { | 4272 | // Not every item in `import_table` will need updating, because some are builtin.zig |
| 3982 | const mod = seen.keys()[i]; | 4273 | // files. However, most will, so let's just reserve sufficient capacity upfront. |
| 3983 | for (mod.deps.values()) |dep| | 4274 | try astgen_work_items.ensureTotalCapacity(gpa, zcu.import_table.count()); |
| 3984 | try seen.put(comp.gpa, dep, {}); | 4275 | for (zcu.import_table.keys()) |file_index| { |
| 3985 | 4276 | const file = zcu.fileByIndex(file_index); | |
| 3986 | const file = mod.builtin_file orelse continue; | 4277 | if (file.is_builtin) { |
| 3987 | 4278 | // This is a `builtin.zig`, so updating is redundant. However, we want to make | |
| 3988 | comp.thread_pool.spawnWg(&astgen_wait_group, workerUpdateBuiltinZigFile, .{ | 4279 | // sure the file contents are still correct on disk, since it can improve the |
| 3989 | comp, mod, file, | 4280 | // debugging experience better. That job only needs `file`, so we can kick it |
| 4281 | // off right now. | ||
| 4282 | comp.thread_pool.spawnWg(&astgen_wait_group, workerUpdateBuiltinFile, .{ comp, file }); | ||
| 4283 | continue; | ||
| 4284 | } | ||
| 4285 | astgen_work_items.appendAssumeCapacity(.{ | ||
| 4286 | .file_index = file_index, | ||
| 4287 | .file = file, | ||
| 3990 | }); | 4288 | }); |
| 3991 | } | 4289 | } |
| 3992 | } | ||
| 3993 | 4290 | ||
| 3994 | if (comp.zcu) |zcu| { | 4291 | // Now that we're not going to touch `zcu.import_table` again, we can spawn `workerUpdateFile` jobs. |
| 3995 | { | 4292 | for (astgen_work_items.items(.file_index), astgen_work_items.items(.file)) |file_index, file| { |
| 3996 | // Worker threads may append to zcu.files and zcu.import_table | 4293 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateFile, .{ |
| 3997 | // so we must hold the lock while spawning those tasks, since | 4294 | comp, file, file_index, zir_prog_node, &astgen_wait_group, |
| 3998 | // we access those tables in this loop. | 4295 | }); |
| 3999 | comp.mutex.lock(); | ||
| 4000 | defer comp.mutex.unlock(); | ||
| 4001 | |||
| 4002 | while (comp.astgen_work_queue.readItem()) |file_index| { | ||
| 4003 | // Pre-load these things from our single-threaded context since they | ||
| 4004 | // will be needed by the worker threads. | ||
| 4005 | const path_digest = zcu.filePathDigest(file_index); | ||
| 4006 | const file = zcu.fileByIndex(file_index); | ||
| 4007 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateFile, .{ | ||
| 4008 | comp, file, file_index, path_digest, zir_prog_node, &astgen_wait_group, .root, | ||
| 4009 | }); | ||
| 4010 | } | ||
| 4011 | } | 4296 | } |
| 4012 | 4297 | ||
| 4013 | for (0.., zcu.embed_table.values()) |ef_index_usize, ef| { | 4298 | // On the other hand, it's fine to directly iterate `zcu.embed_table.keys()` here |
| 4299 | // because `workerUpdateEmbedFile` can't invalidate it. The different here is that one | ||
| 4300 | // `@embedFile` can't trigger analysis of a new `@embedFile`! | ||
| 4301 | for (0.., zcu.embed_table.keys()) |ef_index_usize, ef| { | ||
| 4014 | const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize); | 4302 | const ef_index: Zcu.EmbedFile.Index = @enumFromInt(ef_index_usize); |
| 4015 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateEmbedFile, .{ | 4303 | comp.thread_pool.spawnWgId(&astgen_wait_group, workerUpdateEmbedFile, .{ |
| 4016 | comp, ef_index, ef, | 4304 | comp, ef_index, ef, |
| ... | @@ -4035,25 +4323,39 @@ fn performAllTheWorkInner( | ... | @@ -4035,25 +4323,39 @@ fn performAllTheWorkInner( |
| 4035 | const pt: Zcu.PerThread = .activate(zcu, .main); | 4323 | const pt: Zcu.PerThread = .activate(zcu, .main); |
| 4036 | defer pt.deactivate(); | 4324 | defer pt.deactivate(); |
| 4037 | 4325 | ||
| 4038 | // If the cache mode is `whole`, then add every source file to the cache manifest. | 4326 | const gpa = zcu.gpa; |
| 4327 | |||
| 4328 | // On an incremental update, a source file might become "dead", in that all imports of | ||
| 4329 | // the file were removed. This could even change what module the file belongs to! As such, | ||
| 4330 | // we do a traversal over the files, to figure out which ones are alive and the modules | ||
| 4331 | // they belong to. | ||
| 4332 | const any_fatal_files = try pt.computeAliveFiles(); | ||
| 4333 | |||
| 4334 | // If the cache mode is `whole`, add every alive source file to the manifest. | ||
| 4039 | switch (comp.cache_use) { | 4335 | switch (comp.cache_use) { |
| 4040 | .whole => |whole| if (whole.cache_manifest) |man| { | 4336 | .whole => |whole| if (whole.cache_manifest) |man| { |
| 4041 | const gpa = zcu.gpa; | 4337 | for (zcu.alive_files.keys()) |file_index| { |
| 4042 | for (zcu.import_table.values()) |file_index| { | ||
| 4043 | const file = zcu.fileByIndex(file_index); | 4338 | const file = zcu.fileByIndex(file_index); |
| 4044 | const source = file.getSource(gpa) catch |err| { | 4339 | |
| 4045 | try pt.reportRetryableFileError(file_index, "unable to load source: {s}", .{@errorName(err)}); | 4340 | switch (file.status) { |
| 4046 | continue; | 4341 | .never_loaded => unreachable, // AstGen tried to load it |
| 4342 | .retryable_failure => continue, // the file cannot be read; this is a guaranteed error | ||
| 4343 | .astgen_failure, .success => {}, // the file was read successfully | ||
| 4344 | } | ||
| 4345 | |||
| 4346 | const path = try file.path.toAbsolute(comp.dirs, gpa); | ||
| 4347 | defer gpa.free(path); | ||
| 4348 | |||
| 4349 | const result = res: { | ||
| 4350 | whole.cache_manifest_mutex.lock(); | ||
| 4351 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4352 | if (file.source) |source| { | ||
| 4353 | break :res man.addFilePostContents(path, source, file.stat); | ||
| 4354 | } else { | ||
| 4355 | break :res man.addFilePost(path); | ||
| 4356 | } | ||
| 4047 | }; | 4357 | }; |
| 4048 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 4358 | result catch |err| switch (err) { |
| 4049 | file.mod.root.root_dir.path orelse ".", | ||
| 4050 | file.mod.root.sub_path, | ||
| 4051 | file.sub_file_path, | ||
| 4052 | }); | ||
| 4053 | errdefer gpa.free(resolved_path); | ||
| 4054 | whole.cache_manifest_mutex.lock(); | ||
| 4055 | defer whole.cache_manifest_mutex.unlock(); | ||
| 4056 | man.addFilePostContents(resolved_path, source.bytes, source.stat) catch |err| switch (err) { | ||
| 4057 | error.OutOfMemory => |e| return e, | 4359 | error.OutOfMemory => |e| return e, |
| 4058 | else => { | 4360 | else => { |
| 4059 | try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)}); | 4361 | try pt.reportRetryableFileError(file_index, "unable to update cache: {s}", .{@errorName(err)}); |
| ... | @@ -4065,23 +4367,14 @@ fn performAllTheWorkInner( | ... | @@ -4065,23 +4367,14 @@ fn performAllTheWorkInner( |
| 4065 | .incremental => {}, | 4367 | .incremental => {}, |
| 4066 | } | 4368 | } |
| 4067 | 4369 | ||
| 4068 | try reportMultiModuleErrors(pt); | 4370 | if (any_fatal_files or |
| 4069 | 4371 | zcu.multi_module_err != null or | |
| 4070 | const any_fatal_files = for (zcu.import_table.values()) |file_index| { | 4372 | zcu.failed_imports.items.len > 0 or |
| 4071 | const file = zcu.fileByIndex(file_index); | 4373 | comp.alloc_failure_occurred) |
| 4072 | switch (file.status) { | 4374 | { |
| 4073 | .never_loaded => unreachable, // everything is loaded by the workers | ||
| 4074 | .retryable_failure, .astgen_failure => break true, | ||
| 4075 | .success => {}, | ||
| 4076 | } | ||
| 4077 | } else false; | ||
| 4078 | |||
| 4079 | if (any_fatal_files or comp.alloc_failure_occurred) { | ||
| 4080 | // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents | 4375 | // We give up right now! No updating of ZIR refs, no nothing. The idea is that this prevents |
| 4081 | // us from invalidating lots of incremental dependencies due to files with e.g. parse errors. | 4376 | // us from invalidating lots of incremental dependencies due to files with e.g. parse errors. |
| 4082 | // However, this means our analysis data is invalid, so we want to omit all analysis errors. | 4377 | // However, this means our analysis data is invalid, so we want to omit all analysis errors. |
| 4083 | |||
| 4084 | assert(zcu.failed_files.count() > 0); // we will get an error | ||
| 4085 | zcu.skip_analysis_this_update = true; | 4378 | zcu.skip_analysis_this_update = true; |
| 4086 | return; | 4379 | return; |
| 4087 | } | 4380 | } |
| ... | @@ -4093,6 +4386,11 @@ fn performAllTheWorkInner( | ... | @@ -4093,6 +4386,11 @@ fn performAllTheWorkInner( |
| 4093 | } | 4386 | } |
| 4094 | try zcu.flushRetryableFailures(); | 4387 | try zcu.flushRetryableFailures(); |
| 4095 | 4388 | ||
| 4389 | // It's analysis time! Queue up our initial analysis. | ||
| 4390 | for (zcu.analysis_roots.slice()) |mod| { | ||
| 4391 | try comp.queueJob(.{ .analyze_mod = mod }); | ||
| 4392 | } | ||
| 4393 | |||
| 4096 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | 4394 | zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); |
| 4097 | zcu.codegen_prog_node = if (comp.bin_file != null) main_progress_node.start("Code Generation", 0) else .none; | 4395 | zcu.codegen_prog_node = if (comp.bin_file != null) main_progress_node.start("Code Generation", 0) else .none; |
| 4098 | } | 4396 | } |
| ... | @@ -4236,7 +4534,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { | ... | @@ -4236,7 +4534,7 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job) JobError!void { |
| 4236 | 4534 | ||
| 4237 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | 4535 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 4238 | defer pt.deactivate(); | 4536 | defer pt.deactivate(); |
| 4239 | pt.semaPkg(mod) catch |err| switch (err) { | 4537 | pt.semaMod(mod) catch |err| switch (err) { |
| 4240 | error.OutOfMemory => return error.OutOfMemory, | 4538 | error.OutOfMemory => return error.OutOfMemory, |
| 4241 | error.AnalysisFail => return, | 4539 | error.AnalysisFail => return, |
| 4242 | }; | 4540 | }; |
| ... | @@ -4301,7 +4599,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -4301,7 +4599,7 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4301 | 4599 | ||
| 4302 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { | 4600 | for (&[_][]const u8{ "docs/main.js", "docs/index.html" }) |sub_path| { |
| 4303 | const basename = std.fs.path.basename(sub_path); | 4601 | const basename = std.fs.path.basename(sub_path); |
| 4304 | comp.zig_lib_directory.handle.copyFile(sub_path, out_dir, basename, .{}) catch |err| { | 4602 | comp.dirs.zig_lib.handle.copyFile(sub_path, out_dir, basename, .{}) catch |err| { |
| 4305 | comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {s}", .{ | 4603 | comp.lockAndSetMiscFailure(.docs_copy, "unable to copy {s}: {s}", .{ |
| 4306 | sub_path, | 4604 | sub_path, |
| 4307 | @errorName(err), | 4605 | @errorName(err), |
| ... | @@ -4338,10 +4636,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { | ... | @@ -4338,10 +4636,12 @@ fn docsCopyFallible(comp: *Compilation) anyerror!void { |
| 4338 | 4636 | ||
| 4339 | fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, tar_file: std.fs.File) !void { | 4637 | fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, tar_file: std.fs.File) !void { |
| 4340 | const root = module.root; | 4638 | const root = module.root; |
| 4341 | const sub_path = if (root.sub_path.len == 0) "." else root.sub_path; | 4639 | var mod_dir = d: { |
| 4342 | var mod_dir = root.root_dir.handle.openDir(sub_path, .{ .iterate = true }) catch |err| { | 4640 | const root_dir, const sub_path = root.openInfo(comp.dirs); |
| 4641 | break :d root_dir.openDir(sub_path, .{ .iterate = true }); | ||
| 4642 | } catch |err| { | ||
| 4343 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{}': {s}", .{ | 4643 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open directory '{}': {s}", .{ |
| 4344 | root, @errorName(err), | 4644 | root.fmt(comp), @errorName(err), |
| 4345 | }); | 4645 | }); |
| 4346 | }; | 4646 | }; |
| 4347 | defer mod_dir.close(); | 4647 | defer mod_dir.close(); |
| ... | @@ -4363,13 +4663,13 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, | ... | @@ -4363,13 +4663,13 @@ fn docsCopyModule(comp: *Compilation, module: *Package.Module, name: []const u8, |
| 4363 | } | 4663 | } |
| 4364 | var file = mod_dir.openFile(entry.path, .{}) catch |err| { | 4664 | var file = mod_dir.openFile(entry.path, .{}) catch |err| { |
| 4365 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open '{}{s}': {s}", .{ | 4665 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to open '{}{s}': {s}", .{ |
| 4366 | root, entry.path, @errorName(err), | 4666 | root.fmt(comp), entry.path, @errorName(err), |
| 4367 | }); | 4667 | }); |
| 4368 | }; | 4668 | }; |
| 4369 | defer file.close(); | 4669 | defer file.close(); |
| 4370 | archiver.writeFile(entry.path, file) catch |err| { | 4670 | archiver.writeFile(entry.path, file) catch |err| { |
| 4371 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive '{}{s}': {s}", .{ | 4671 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to archive '{}{s}': {s}", .{ |
| 4372 | root, entry.path, @errorName(err), | 4672 | root.fmt(comp), entry.path, @errorName(err), |
| 4373 | }); | 4673 | }); |
| 4374 | }; | 4674 | }; |
| 4375 | } | 4675 | } |
| ... | @@ -4430,13 +4730,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4430,13 +4730,11 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4430 | const src_basename = "main.zig"; | 4730 | const src_basename = "main.zig"; |
| 4431 | const root_name = std.fs.path.stem(src_basename); | 4731 | const root_name = std.fs.path.stem(src_basename); |
| 4432 | 4732 | ||
| 4733 | const dirs = comp.dirs.withoutLocalCache(); | ||
| 4734 | |||
| 4433 | const root_mod = try Package.Module.create(arena, .{ | 4735 | const root_mod = try Package.Module.create(arena, .{ |
| 4434 | .global_cache_directory = comp.global_cache_directory, | ||
| 4435 | .paths = .{ | 4736 | .paths = .{ |
| 4436 | .root = .{ | 4737 | .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"), |
| 4437 | .root_dir = comp.zig_lib_directory, | ||
| 4438 | .sub_path = "docs/wasm", | ||
| 4439 | }, | ||
| 4440 | .root_src_path = src_basename, | 4738 | .root_src_path = src_basename, |
| 4441 | }, | 4739 | }, |
| 4442 | .fully_qualified_name = root_name, | 4740 | .fully_qualified_name = root_name, |
| ... | @@ -4447,16 +4745,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4447,16 +4745,10 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4447 | .global = config, | 4745 | .global = config, |
| 4448 | .cc_argv = &.{}, | 4746 | .cc_argv = &.{}, |
| 4449 | .parent = null, | 4747 | .parent = null, |
| 4450 | .builtin_mod = null, | ||
| 4451 | .builtin_modules = null, | ||
| 4452 | }); | 4748 | }); |
| 4453 | const walk_mod = try Package.Module.create(arena, .{ | 4749 | const walk_mod = try Package.Module.create(arena, .{ |
| 4454 | .global_cache_directory = comp.global_cache_directory, | ||
| 4455 | .paths = .{ | 4750 | .paths = .{ |
| 4456 | .root = .{ | 4751 | .root = try .fromRoot(arena, dirs, .zig_lib, "docs/wasm"), |
| 4457 | .root_dir = comp.zig_lib_directory, | ||
| 4458 | .sub_path = "docs/wasm", | ||
| 4459 | }, | ||
| 4460 | .root_src_path = "Walk.zig", | 4752 | .root_src_path = "Walk.zig", |
| 4461 | }, | 4753 | }, |
| 4462 | .fully_qualified_name = "Walk", | 4754 | .fully_qualified_name = "Walk", |
| ... | @@ -4467,8 +4759,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4467,8 +4759,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4467 | .global = config, | 4759 | .global = config, |
| 4468 | .cc_argv = &.{}, | 4760 | .cc_argv = &.{}, |
| 4469 | .parent = root_mod, | 4761 | .parent = root_mod, |
| 4470 | .builtin_mod = root_mod.getBuiltinDependency(), | ||
| 4471 | .builtin_modules = null, // `builtin_mod` is set | ||
| 4472 | }); | 4762 | }); |
| 4473 | try root_mod.deps.put(arena, "Walk", walk_mod); | 4763 | try root_mod.deps.put(arena, "Walk", walk_mod); |
| 4474 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | 4764 | const bin_basename = try std.zig.binNameAlloc(arena, .{ |
| ... | @@ -4478,9 +4768,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4478,9 +4768,7 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4478 | }); | 4768 | }); |
| 4479 | 4769 | ||
| 4480 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 4770 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 4481 | .global_cache_directory = comp.global_cache_directory, | 4771 | .dirs = dirs, |
| 4482 | .local_cache_directory = comp.global_cache_directory, | ||
| 4483 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 4484 | .self_exe_path = comp.self_exe_path, | 4772 | .self_exe_path = comp.self_exe_path, |
| 4485 | .config = config, | 4773 | .config = config, |
| 4486 | .root_mod = root_mod, | 4774 | .root_mod = root_mod, |
| ... | @@ -4517,14 +4805,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -4517,14 +4805,14 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 4517 | }; | 4805 | }; |
| 4518 | defer out_dir.close(); | 4806 | defer out_dir.close(); |
| 4519 | 4807 | ||
| 4520 | sub_compilation.local_cache_directory.handle.copyFile( | 4808 | sub_compilation.dirs.local_cache.handle.copyFile( |
| 4521 | sub_compilation.cache_use.whole.bin_sub_path.?, | 4809 | sub_compilation.cache_use.whole.bin_sub_path.?, |
| 4522 | out_dir, | 4810 | out_dir, |
| 4523 | "main.wasm", | 4811 | "main.wasm", |
| 4524 | .{}, | 4812 | .{}, |
| 4525 | ) catch |err| { | 4813 | ) catch |err| { |
| 4526 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}{s}' to '{}{s}': {s}", .{ | 4814 | return comp.lockAndSetMiscFailure(.docs_copy, "unable to copy '{}{s}' to '{}{s}': {s}", .{ |
| 4527 | sub_compilation.local_cache_directory, | 4815 | sub_compilation.dirs.local_cache, |
| 4528 | sub_compilation.cache_use.whole.bin_sub_path.?, | 4816 | sub_compilation.cache_use.whole.bin_sub_path.?, |
| 4529 | emit.root_dir, | 4817 | emit.root_dir, |
| 4530 | emit.sub_path, | 4818 | emit.sub_path, |
| ... | @@ -4538,28 +4826,23 @@ fn workerUpdateFile( | ... | @@ -4538,28 +4826,23 @@ fn workerUpdateFile( |
| 4538 | comp: *Compilation, | 4826 | comp: *Compilation, |
| 4539 | file: *Zcu.File, | 4827 | file: *Zcu.File, |
| 4540 | file_index: Zcu.File.Index, | 4828 | file_index: Zcu.File.Index, |
| 4541 | path_digest: Cache.BinDigest, | ||
| 4542 | prog_node: std.Progress.Node, | 4829 | prog_node: std.Progress.Node, |
| 4543 | wg: *WaitGroup, | 4830 | wg: *WaitGroup, |
| 4544 | src: Zcu.AstGenSrc, | ||
| 4545 | ) void { | 4831 | ) void { |
| 4546 | const child_prog_node = prog_node.start(file.sub_file_path, 0); | 4832 | const child_prog_node = prog_node.start(std.fs.path.basename(file.path.sub_path), 0); |
| 4547 | defer child_prog_node.end(); | 4833 | defer child_prog_node.end(); |
| 4548 | 4834 | ||
| 4549 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); | 4835 | const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid)); |
| 4550 | defer pt.deactivate(); | 4836 | defer pt.deactivate(); |
| 4551 | pt.updateFile(file, path_digest) catch |err| switch (err) { | 4837 | pt.updateFile(file_index, file) catch |err| { |
| 4552 | error.AnalysisFail => return, | 4838 | pt.reportRetryableFileError(file_index, "unable to load '{s}': {s}", .{ std.fs.path.basename(file.path.sub_path), @errorName(err) }) catch |oom| switch (oom) { |
| 4553 | else => { | 4839 | error.OutOfMemory => { |
| 4554 | pt.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) { | 4840 | comp.mutex.lock(); |
| 4555 | error.OutOfMemory => { | 4841 | defer comp.mutex.unlock(); |
| 4556 | comp.mutex.lock(); | 4842 | comp.setAllocFailure(); |
| 4557 | defer comp.mutex.unlock(); | 4843 | }, |
| 4558 | comp.setAllocFailure(); | 4844 | }; |
| 4559 | }, | 4845 | return; |
| 4560 | }; | ||
| 4561 | return; | ||
| 4562 | }, | ||
| 4563 | }; | 4846 | }; |
| 4564 | 4847 | ||
| 4565 | switch (file.getMode()) { | 4848 | switch (file.getMode()) { |
| ... | @@ -4567,9 +4850,9 @@ fn workerUpdateFile( | ... | @@ -4567,9 +4850,9 @@ fn workerUpdateFile( |
| 4567 | .zon => return, // ZON can't import anything so we're done | 4850 | .zon => return, // ZON can't import anything so we're done |
| 4568 | } | 4851 | } |
| 4569 | 4852 | ||
| 4570 | // Pre-emptively look for `@import` paths and queue them up. | 4853 | // Discover all imports in the file. Imports of modules we ignore for now since we don't |
| 4571 | // If we experience an error preemptively fetching the | 4854 | // know which module we're in, but imports of file paths might need us to queue up other |
| 4572 | // file, just ignore it and let it happen again later during Sema. | 4855 | // AstGen jobs. |
| 4573 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 4856 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; |
| 4574 | if (imports_index != 0) { | 4857 | if (imports_index != 0) { |
| 4575 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 4858 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); |
| ... | @@ -4581,54 +4864,34 @@ fn workerUpdateFile( | ... | @@ -4581,54 +4864,34 @@ fn workerUpdateFile( |
| 4581 | extra_index = item.end; | 4864 | extra_index = item.end; |
| 4582 | 4865 | ||
| 4583 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | 4866 | const import_path = file.zir.?.nullTerminatedString(item.data.name); |
| 4584 | // `@import("builtin")` is handled specially. | ||
| 4585 | if (mem.eql(u8, import_path, "builtin")) continue; | ||
| 4586 | |||
| 4587 | const import_result, const imported_path_digest = blk: { | ||
| 4588 | comp.mutex.lock(); | ||
| 4589 | defer comp.mutex.unlock(); | ||
| 4590 | 4867 | ||
| 4591 | const res = pt.importFile(file, import_path) catch continue; | 4868 | if (pt.discoverImport(file.path, import_path)) |res| switch (res) { |
| 4592 | if (!res.is_pkg) { | 4869 | .module, .existing_file => {}, |
| 4593 | res.file.addReference(pt.zcu, .{ .import = .{ | 4870 | .new_file => |new| { |
| 4594 | .file = file_index, | 4871 | comp.thread_pool.spawnWgId(wg, workerUpdateFile, .{ |
| 4595 | .token = item.data.token, | 4872 | comp, new.file, new.index, prog_node, wg, |
| 4596 | } }) catch continue; | 4873 | }); |
| 4597 | } | 4874 | }, |
| 4598 | if (res.is_new) if (comp.file_system_inputs) |fsi| { | 4875 | } else |err| switch (err) { |
| 4599 | comp.appendFileSystemInput(fsi, res.file.mod.root, res.file.sub_file_path) catch continue; | 4876 | error.OutOfMemory => { |
| 4600 | }; | 4877 | comp.mutex.lock(); |
| 4601 | const imported_path_digest = pt.zcu.filePathDigest(res.file_index); | 4878 | defer comp.mutex.unlock(); |
| 4602 | break :blk .{ res, imported_path_digest }; | 4879 | comp.setAllocFailure(); |
| 4603 | }; | 4880 | }, |
| 4604 | if (import_result.is_new) { | ||
| 4605 | log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{ | ||
| 4606 | file.sub_file_path, import_path, import_result.file.sub_file_path, | ||
| 4607 | }); | ||
| 4608 | const sub_src: Zcu.AstGenSrc = .{ .import = .{ | ||
| 4609 | .importing_file = file_index, | ||
| 4610 | .import_tok = item.data.token, | ||
| 4611 | } }; | ||
| 4612 | comp.thread_pool.spawnWgId(wg, workerUpdateFile, .{ | ||
| 4613 | comp, import_result.file, import_result.file_index, imported_path_digest, prog_node, wg, sub_src, | ||
| 4614 | }); | ||
| 4615 | } | 4881 | } |
| 4616 | } | 4882 | } |
| 4617 | } | 4883 | } |
| 4618 | } | 4884 | } |
| 4619 | 4885 | ||
| 4620 | fn workerUpdateBuiltinZigFile( | 4886 | fn workerUpdateBuiltinFile(comp: *Compilation, file: *Zcu.File) void { |
| 4621 | comp: *Compilation, | 4887 | Builtin.updateFileOnDisk(file, comp) catch |err| { |
| 4622 | mod: *Package.Module, | ||
| 4623 | file: *Zcu.File, | ||
| 4624 | ) void { | ||
| 4625 | Builtin.populateFile(comp, mod, file) catch |err| { | ||
| 4626 | comp.mutex.lock(); | 4888 | comp.mutex.lock(); |
| 4627 | defer comp.mutex.unlock(); | 4889 | defer comp.mutex.unlock(); |
| 4628 | 4890 | comp.setMiscFailure( | |
| 4629 | comp.setMiscFailure(.write_builtin_zig, "unable to write '{}{s}': {s}", .{ | 4891 | .write_builtin_zig, |
| 4630 | mod.root, mod.root_src_path, @errorName(err), | 4892 | "unable to write '{}': {s}", |
| 4631 | }); | 4893 | .{ file.path.fmt(comp), @errorName(err) }, |
| 4894 | ); | ||
| 4632 | }; | 4895 | }; |
| 4633 | } | 4896 | } |
| 4634 | 4897 | ||
| ... | @@ -4738,10 +5001,10 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4738,10 +5001,10 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4738 | 5001 | ||
| 4739 | const tmp_digest = man.hash.peek(); | 5002 | const tmp_digest = man.hash.peek(); |
| 4740 | const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest }); | 5003 | const tmp_dir_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &tmp_digest }); |
| 4741 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 5004 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 4742 | defer zig_cache_tmp_dir.close(); | 5005 | defer zig_cache_tmp_dir.close(); |
| 4743 | const cimport_basename = "cimport.h"; | 5006 | const cimport_basename = "cimport.h"; |
| 4744 | const out_h_path = try comp.local_cache_directory.join(arena, &[_][]const u8{ | 5007 | const out_h_path = try comp.dirs.local_cache.join(arena, &[_][]const u8{ |
| 4745 | tmp_dir_sub_path, cimport_basename, | 5008 | tmp_dir_sub_path, cimport_basename, |
| 4746 | }); | 5009 | }); |
| 4747 | const out_dep_path = try std.fmt.allocPrint(arena, "{s}.d", .{out_h_path}); | 5010 | const out_dep_path = try std.fmt.allocPrint(arena, "{s}.d", .{out_h_path}); |
| ... | @@ -4779,7 +5042,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4779,7 +5042,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4779 | new_argv[i] = try arena.dupeZ(u8, arg); | 5042 | new_argv[i] = try arena.dupeZ(u8, arg); |
| 4780 | } | 5043 | } |
| 4781 | 5044 | ||
| 4782 | const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); | 5045 | const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); |
| 4783 | var errors = std.zig.ErrorBundle.empty; | 5046 | var errors = std.zig.ErrorBundle.empty; |
| 4784 | errdefer errors.deinit(comp.gpa); | 5047 | errdefer errors.deinit(comp.gpa); |
| 4785 | break :tree translate_c.translate( | 5048 | break :tree translate_c.translate( |
| ... | @@ -4820,7 +5083,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module | ... | @@ -4820,7 +5083,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module |
| 4820 | const bin_digest = man.finalBin(); | 5083 | const bin_digest = man.finalBin(); |
| 4821 | const hex_digest = Cache.binToHex(bin_digest); | 5084 | const hex_digest = Cache.binToHex(bin_digest); |
| 4822 | const o_sub_path = "o" ++ std.fs.path.sep_str ++ hex_digest; | 5085 | const o_sub_path = "o" ++ std.fs.path.sep_str ++ hex_digest; |
| 4823 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5086 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 4824 | defer o_dir.close(); | 5087 | defer o_dir.close(); |
| 4825 | 5088 | ||
| 4826 | var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{}); | 5089 | var out_zig_file = try o_dir.createFile(cimport_zig_basename, .{}); |
| ... | @@ -5226,7 +5489,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5226,7 +5489,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5226 | // We can't know the digest until we do the C compiler invocation, | 5489 | // We can't know the digest until we do the C compiler invocation, |
| 5227 | // so we need a temporary filename. | 5490 | // so we need a temporary filename. |
| 5228 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); | 5491 | const out_obj_path = try comp.tmpFilePath(arena, o_basename); |
| 5229 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 5492 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 5230 | defer zig_cache_tmp_dir.close(); | 5493 | defer zig_cache_tmp_dir.close(); |
| 5231 | 5494 | ||
| 5232 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) | 5495 | const out_diag_path = if (comp.clang_passthrough_mode or !ext.clangSupportsDiagnostics()) |
| ... | @@ -5362,7 +5625,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5362,7 +5625,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5362 | // Rename into place. | 5625 | // Rename into place. |
| 5363 | const digest = man.final(); | 5626 | const digest = man.final(); |
| 5364 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 5627 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 5365 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5628 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5366 | defer o_dir.close(); | 5629 | defer o_dir.close(); |
| 5367 | const tmp_basename = std.fs.path.basename(out_obj_path); | 5630 | const tmp_basename = std.fs.path.basename(out_obj_path); |
| 5368 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); | 5631 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, o_basename); |
| ... | @@ -5386,7 +5649,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr | ... | @@ -5386,7 +5649,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr |
| 5386 | c_object.status = .{ | 5649 | c_object.status = .{ |
| 5387 | .success = .{ | 5650 | .success = .{ |
| 5388 | .object_path = .{ | 5651 | .object_path = .{ |
| 5389 | .root_dir = comp.local_cache_directory, | 5652 | .root_dir = comp.dirs.local_cache, |
| 5390 | .sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, o_basename }), | 5653 | .sub_path = try std.fs.path.join(gpa, &.{ "o", &digest, o_basename }), |
| 5391 | }, | 5654 | }, |
| 5392 | .lock = man.toOwnedLock(), | 5655 | .lock = man.toOwnedLock(), |
| ... | @@ -5449,13 +5712,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5449,13 +5712,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5449 | const digest = man.final(); | 5712 | const digest = man.final(); |
| 5450 | 5713 | ||
| 5451 | const o_sub_path = try std.fs.path.join(arena, &.{ "o", &digest }); | 5714 | const o_sub_path = try std.fs.path.join(arena, &.{ "o", &digest }); |
| 5452 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5715 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5453 | defer o_dir.close(); | 5716 | defer o_dir.close(); |
| 5454 | 5717 | ||
| 5455 | const in_rc_path = try comp.local_cache_directory.join(comp.gpa, &.{ | 5718 | const in_rc_path = try comp.dirs.local_cache.join(comp.gpa, &.{ |
| 5456 | o_sub_path, rc_basename, | 5719 | o_sub_path, rc_basename, |
| 5457 | }); | 5720 | }); |
| 5458 | const out_res_path = try comp.local_cache_directory.join(comp.gpa, &.{ | 5721 | const out_res_path = try comp.dirs.local_cache.join(comp.gpa, &.{ |
| 5459 | o_sub_path, res_basename, | 5722 | o_sub_path, res_basename, |
| 5460 | }); | 5723 | }); |
| 5461 | 5724 | ||
| ... | @@ -5517,7 +5780,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5517,7 +5780,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5517 | 5780 | ||
| 5518 | win32_resource.status = .{ | 5781 | win32_resource.status = .{ |
| 5519 | .success = .{ | 5782 | .success = .{ |
| 5520 | .res_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{ | 5783 | .res_path = try comp.dirs.local_cache.join(comp.gpa, &[_][]const u8{ |
| 5521 | "o", &digest, res_basename, | 5784 | "o", &digest, res_basename, |
| 5522 | }), | 5785 | }), |
| 5523 | .lock = man.toOwnedLock(), | 5786 | .lock = man.toOwnedLock(), |
| ... | @@ -5535,7 +5798,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5535,7 +5798,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5535 | const rc_basename_noext = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; | 5798 | const rc_basename_noext = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; |
| 5536 | 5799 | ||
| 5537 | const digest = if (try man.hit()) man.final() else blk: { | 5800 | const digest = if (try man.hit()) man.final() else blk: { |
| 5538 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 5801 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 5539 | defer zig_cache_tmp_dir.close(); | 5802 | defer zig_cache_tmp_dir.close(); |
| 5540 | 5803 | ||
| 5541 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); | 5804 | const res_filename = try std.fmt.allocPrint(arena, "{s}.res", .{rc_basename_noext}); |
| ... | @@ -5605,7 +5868,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5605,7 +5868,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5605 | // Rename into place. | 5868 | // Rename into place. |
| 5606 | const digest = man.final(); | 5869 | const digest = man.final(); |
| 5607 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 5870 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 5608 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 5871 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 5609 | defer o_dir.close(); | 5872 | defer o_dir.close(); |
| 5610 | const tmp_basename = std.fs.path.basename(out_res_path); | 5873 | const tmp_basename = std.fs.path.basename(out_res_path); |
| 5611 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); | 5874 | try std.fs.rename(zig_cache_tmp_dir, tmp_basename, o_dir, res_filename); |
| ... | @@ -5626,7 +5889,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 | ... | @@ -5626,7 +5889,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32 |
| 5626 | 5889 | ||
| 5627 | win32_resource.status = .{ | 5890 | win32_resource.status = .{ |
| 5628 | .success = .{ | 5891 | .success = .{ |
| 5629 | .res_path = try comp.local_cache_directory.join(comp.gpa, &[_][]const u8{ | 5892 | .res_path = try comp.dirs.local_cache.join(comp.gpa, &[_][]const u8{ |
| 5630 | "o", &digest, res_basename, | 5893 | "o", &digest, res_basename, |
| 5631 | }), | 5894 | }), |
| 5632 | .lock = man.toOwnedLock(), | 5895 | .lock = man.toOwnedLock(), |
| ... | @@ -5721,7 +5984,7 @@ fn spawnZigRc( | ... | @@ -5721,7 +5984,7 @@ fn spawnZigRc( |
| 5721 | pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { | 5984 | pub fn tmpFilePath(comp: Compilation, ally: Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { |
| 5722 | const s = std.fs.path.sep_str; | 5985 | const s = std.fs.path.sep_str; |
| 5723 | const rand_int = std.crypto.random.int(u64); | 5986 | const rand_int = std.crypto.random.int(u64); |
| 5724 | if (comp.local_cache_directory.path) |p| { | 5987 | if (comp.dirs.local_cache.path) |p| { |
| 5725 | return std.fmt.allocPrint(ally, "{s}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix }); | 5988 | return std.fmt.allocPrint(ally, "{s}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix }); |
| 5726 | } else { | 5989 | } else { |
| 5727 | return std.fmt.allocPrint(ally, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix }); | 5990 | return std.fmt.allocPrint(ally, "tmp" ++ s ++ "{x}-{s}", .{ rand_int, suffix }); |
| ... | @@ -5962,12 +6225,12 @@ pub fn addCCArgs( | ... | @@ -5962,12 +6225,12 @@ pub fn addCCArgs( |
| 5962 | if (comp.config.link_libcpp) { | 6225 | if (comp.config.link_libcpp) { |
| 5963 | try argv.append("-isystem"); | 6226 | try argv.append("-isystem"); |
| 5964 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6227 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5965 | comp.zig_lib_directory.path.?, "libcxx", "include", | 6228 | comp.dirs.zig_lib.path.?, "libcxx", "include", |
| 5966 | })); | 6229 | })); |
| 5967 | 6230 | ||
| 5968 | try argv.append("-isystem"); | 6231 | try argv.append("-isystem"); |
| 5969 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6232 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5970 | comp.zig_lib_directory.path.?, "libcxxabi", "include", | 6233 | comp.dirs.zig_lib.path.?, "libcxxabi", "include", |
| 5971 | })); | 6234 | })); |
| 5972 | 6235 | ||
| 5973 | try libcxx.addCxxArgs(comp, arena, argv); | 6236 | try libcxx.addCxxArgs(comp, arena, argv); |
| ... | @@ -5977,7 +6240,7 @@ pub fn addCCArgs( | ... | @@ -5977,7 +6240,7 @@ pub fn addCCArgs( |
| 5977 | // However as noted by @dimenus, appending libc headers before compiler headers breaks | 6240 | // However as noted by @dimenus, appending libc headers before compiler headers breaks |
| 5978 | // intrinsics and other compiler specific items. | 6241 | // intrinsics and other compiler specific items. |
| 5979 | try argv.append("-isystem"); | 6242 | try argv.append("-isystem"); |
| 5980 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" })); | 6243 | try argv.append(try std.fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "include" })); |
| 5981 | 6244 | ||
| 5982 | try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); | 6245 | try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); |
| 5983 | for (comp.libc_include_dir_list) |include_dir| { | 6246 | for (comp.libc_include_dir_list) |include_dir| { |
| ... | @@ -5996,7 +6259,7 @@ pub fn addCCArgs( | ... | @@ -5996,7 +6259,7 @@ pub fn addCCArgs( |
| 5996 | if (comp.config.link_libunwind) { | 6259 | if (comp.config.link_libunwind) { |
| 5997 | try argv.append("-isystem"); | 6260 | try argv.append("-isystem"); |
| 5998 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ | 6261 | try argv.append(try std.fs.path.join(arena, &[_][]const u8{ |
| 5999 | comp.zig_lib_directory.path.?, "libunwind", "include", | 6262 | comp.dirs.zig_lib.path.?, "libunwind", "include", |
| 6000 | })); | 6263 | })); |
| 6001 | } | 6264 | } |
| 6002 | 6265 | ||
| ... | @@ -6584,12 +6847,12 @@ test "classifyFileExt" { | ... | @@ -6584,12 +6847,12 @@ test "classifyFileExt" { |
| 6584 | try std.testing.expectEqual(FileExt.zig, classifyFileExt("foo.zig")); | 6847 | try std.testing.expectEqual(FileExt.zig, classifyFileExt("foo.zig")); |
| 6585 | } | 6848 | } |
| 6586 | 6849 | ||
| 6587 | fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) !Path { | 6850 | fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const u8) !Cache.Path { |
| 6588 | return (try crtFilePath(&comp.crt_files, basename)) orelse { | 6851 | return (try crtFilePath(&comp.crt_files, basename)) orelse { |
| 6589 | const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable; | 6852 | const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable; |
| 6590 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir; | 6853 | const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCrtDir; |
| 6591 | const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename }); | 6854 | const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename }); |
| 6592 | return Path.initCwd(full_path); | 6855 | return Cache.Path.initCwd(full_path); |
| 6593 | }; | 6856 | }; |
| 6594 | } | 6857 | } |
| 6595 | 6858 | ||
| ... | @@ -6598,7 +6861,7 @@ pub fn crtFileAsString(comp: *Compilation, arena: Allocator, basename: []const u | ... | @@ -6598,7 +6861,7 @@ pub fn crtFileAsString(comp: *Compilation, arena: Allocator, basename: []const u |
| 6598 | return path.toString(arena); | 6861 | return path.toString(arena); |
| 6599 | } | 6862 | } |
| 6600 | 6863 | ||
| 6601 | fn crtFilePath(crt_files: *std.StringHashMapUnmanaged(CrtFile), basename: []const u8) Allocator.Error!?Path { | 6864 | fn crtFilePath(crt_files: *std.StringHashMapUnmanaged(CrtFile), basename: []const u8) Allocator.Error!?Cache.Path { |
| 6602 | const crt_file = crt_files.get(basename) orelse return null; | 6865 | const crt_file = crt_files.get(basename) orelse return null; |
| 6603 | return crt_file.full_object_path; | 6866 | return crt_file.full_object_path; |
| 6604 | } | 6867 | } |
| ... | @@ -6736,9 +6999,8 @@ fn buildOutputFromZig( | ... | @@ -6736,9 +6999,8 @@ fn buildOutputFromZig( |
| 6736 | }); | 6999 | }); |
| 6737 | 7000 | ||
| 6738 | const root_mod = try Package.Module.create(arena, .{ | 7001 | const root_mod = try Package.Module.create(arena, .{ |
| 6739 | .global_cache_directory = comp.global_cache_directory, | ||
| 6740 | .paths = .{ | 7002 | .paths = .{ |
| 6741 | .root = .{ .root_dir = comp.zig_lib_directory }, | 7003 | .root = .zig_lib_root, |
| 6742 | .root_src_path = src_basename, | 7004 | .root_src_path = src_basename, |
| 6743 | }, | 7005 | }, |
| 6744 | .fully_qualified_name = "root", | 7006 | .fully_qualified_name = "root", |
| ... | @@ -6760,8 +7022,6 @@ fn buildOutputFromZig( | ... | @@ -6760,8 +7022,6 @@ fn buildOutputFromZig( |
| 6760 | .global = config, | 7022 | .global = config, |
| 6761 | .cc_argv = &.{}, | 7023 | .cc_argv = &.{}, |
| 6762 | .parent = null, | 7024 | .parent = null, |
| 6763 | .builtin_mod = null, | ||
| 6764 | .builtin_modules = null, // there is only one module in this compilation | ||
| 6765 | }); | 7025 | }); |
| 6766 | const target = comp.getTarget(); | 7026 | const target = comp.getTarget(); |
| 6767 | const bin_basename = try std.zig.binNameAlloc(arena, .{ | 7027 | const bin_basename = try std.zig.binNameAlloc(arena, .{ |
| ... | @@ -6785,9 +7045,7 @@ fn buildOutputFromZig( | ... | @@ -6785,9 +7045,7 @@ fn buildOutputFromZig( |
| 6785 | }; | 7045 | }; |
| 6786 | 7046 | ||
| 6787 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 7047 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 6788 | .global_cache_directory = comp.global_cache_directory, | 7048 | .dirs = comp.dirs.withoutLocalCache(), |
| 6789 | .local_cache_directory = comp.global_cache_directory, | ||
| 6790 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 6791 | .cache_mode = .whole, | 7049 | .cache_mode = .whole, |
| 6792 | .parent_whole_cache = parent_whole_cache, | 7050 | .parent_whole_cache = parent_whole_cache, |
| 6793 | .self_exe_path = comp.self_exe_path, | 7051 | .self_exe_path = comp.self_exe_path, |
| ... | @@ -6878,9 +7136,8 @@ pub fn build_crt_file( | ... | @@ -6878,9 +7136,8 @@ pub fn build_crt_file( |
| 6878 | }, | 7136 | }, |
| 6879 | }); | 7137 | }); |
| 6880 | const root_mod = try Package.Module.create(arena, .{ | 7138 | const root_mod = try Package.Module.create(arena, .{ |
| 6881 | .global_cache_directory = comp.global_cache_directory, | ||
| 6882 | .paths = .{ | 7139 | .paths = .{ |
| 6883 | .root = .{ .root_dir = comp.zig_lib_directory }, | 7140 | .root = .zig_lib_root, |
| 6884 | .root_src_path = "", | 7141 | .root_src_path = "", |
| 6885 | }, | 7142 | }, |
| 6886 | .fully_qualified_name = "root", | 7143 | .fully_qualified_name = "root", |
| ... | @@ -6908,8 +7165,6 @@ pub fn build_crt_file( | ... | @@ -6908,8 +7165,6 @@ pub fn build_crt_file( |
| 6908 | .global = config, | 7165 | .global = config, |
| 6909 | .cc_argv = &.{}, | 7166 | .cc_argv = &.{}, |
| 6910 | .parent = null, | 7167 | .parent = null, |
| 6911 | .builtin_mod = null, | ||
| 6912 | .builtin_modules = null, // there is only one module in this compilation | ||
| 6913 | }); | 7168 | }); |
| 6914 | 7169 | ||
| 6915 | for (c_source_files) |*item| { | 7170 | for (c_source_files) |*item| { |
| ... | @@ -6917,9 +7172,7 @@ pub fn build_crt_file( | ... | @@ -6917,9 +7172,7 @@ pub fn build_crt_file( |
| 6917 | } | 7172 | } |
| 6918 | 7173 | ||
| 6919 | const sub_compilation = try Compilation.create(gpa, arena, .{ | 7174 | const sub_compilation = try Compilation.create(gpa, arena, .{ |
| 6920 | .local_cache_directory = comp.global_cache_directory, | 7175 | .dirs = comp.dirs.withoutLocalCache(), |
| 6921 | .global_cache_directory = comp.global_cache_directory, | ||
| 6922 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 6923 | .self_exe_path = comp.self_exe_path, | 7176 | .self_exe_path = comp.self_exe_path, |
| 6924 | .cache_mode = .whole, | 7177 | .cache_mode = .whole, |
| 6925 | .config = config, | 7178 | .config = config, |
| ... | @@ -6962,7 +7215,7 @@ pub fn build_crt_file( | ... | @@ -6962,7 +7215,7 @@ pub fn build_crt_file( |
| 6962 | } | 7215 | } |
| 6963 | } | 7216 | } |
| 6964 | 7217 | ||
| 6965 | pub fn queueLinkTaskMode(comp: *Compilation, path: Path, output_mode: std.builtin.OutputMode) void { | 7218 | pub fn queueLinkTaskMode(comp: *Compilation, path: Cache.Path, output_mode: std.builtin.OutputMode) void { |
| 6966 | comp.queueLinkTasks(switch (output_mode) { | 7219 | comp.queueLinkTasks(switch (output_mode) { |
| 6967 | .Exe => unreachable, | 7220 | .Exe => unreachable, |
| 6968 | .Obj => &.{.{ .load_object = path }}, | 7221 | .Obj => &.{.{ .load_object = path }}, |
| ... | @@ -6983,7 +7236,7 @@ pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.Task) void { | ... | @@ -6983,7 +7236,7 @@ pub fn queueLinkTasks(comp: *Compilation, tasks: []const link.Task) void { |
| 6983 | pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile { | 7236 | pub fn toCrtFile(comp: *Compilation) Allocator.Error!CrtFile { |
| 6984 | return .{ | 7237 | return .{ |
| 6985 | .full_object_path = .{ | 7238 | .full_object_path = .{ |
| 6986 | .root_dir = comp.local_cache_directory, | 7239 | .root_dir = comp.dirs.local_cache, |
| 6987 | .sub_path = try comp.gpa.dupe(u8, comp.cache_use.whole.bin_sub_path.?), | 7240 | .sub_path = try comp.gpa.dupe(u8, comp.cache_use.whole.bin_sub_path.?), |
| 6988 | }, | 7241 | }, |
| 6989 | .lock = comp.cache_use.whole.moveLock(), | 7242 | .lock = comp.cache_use.whole.moveLock(), |
src/InternPool.zig+13| ... | @@ -1723,6 +1723,19 @@ pub const FileIndex = enum(u32) { | ... | @@ -1723,6 +1723,19 @@ pub const FileIndex = enum(u32) { |
| 1723 | .index = @intFromEnum(file_index) & ip.getIndexMask(u32), | 1723 | .index = @intFromEnum(file_index) & ip.getIndexMask(u32), |
| 1724 | }; | 1724 | }; |
| 1725 | } | 1725 | } |
| 1726 | pub fn toOptional(i: FileIndex) Optional { | ||
| 1727 | return @enumFromInt(@intFromEnum(i)); | ||
| 1728 | } | ||
| 1729 | pub const Optional = enum(u32) { | ||
| 1730 | none = std.math.maxInt(u32), | ||
| 1731 | _, | ||
| 1732 | pub fn unwrap(opt: Optional) ?FileIndex { | ||
| 1733 | return switch (opt) { | ||
| 1734 | .none => null, | ||
| 1735 | _ => @enumFromInt(@intFromEnum(opt)), | ||
| 1736 | }; | ||
| 1737 | } | ||
| 1738 | }; | ||
| 1726 | }; | 1739 | }; |
| 1727 | 1740 | ||
| 1728 | const File = struct { | 1741 | const File = struct { |
src/Package/Module.zig+74-148| ... | @@ -1,15 +1,17 @@ | ... | @@ -1,15 +1,17 @@ |
| 1 | //! Corresponds to something that Zig source code can `@import`. | 1 | //! Corresponds to something that Zig source code can `@import`. |
| 2 | 2 | ||
| 3 | /// Only files inside this directory can be imported. | 3 | /// The root directory of the module. Only files inside this directory can be imported. |
| 4 | root: Cache.Path, | 4 | root: Compilation.Path, |
| 5 | /// Relative to `root`. May contain path separators. | 5 | /// Path to the root source file of this module. Relative to `root`. May contain path separators. |
| 6 | root_src_path: []const u8, | 6 | root_src_path: []const u8, |
| 7 | /// Name used in compile errors. Looks like "root.foo.bar". | 7 | /// Name used in compile errors. Looks like "root.foo.bar". |
| 8 | fully_qualified_name: []const u8, | 8 | fully_qualified_name: []const u8, |
| 9 | /// The dependency table of this module. Shared dependencies such as 'std', | 9 | /// The dependency table of this module. The shared dependencies 'std' and |
| 10 | /// 'builtin', and 'root' are not specified in every dependency table, but | 10 | /// 'root' are not specified in every module dependency table, but are stored |
| 11 | /// instead only in the table of `main_mod`. `Module.importFile` is | 11 | /// separately in `Zcu`. 'builtin' is also not stored here, although it is |
| 12 | /// responsible for detecting these names and using the correct package. | 12 | /// not necessarily the same between all modules. Handling of `@import` in |
| 13 | /// the rest of the compiler must detect these special names and use the | ||
| 14 | /// correct module instead of consulting `deps`. | ||
| 13 | deps: Deps = .{}, | 15 | deps: Deps = .{}, |
| 14 | 16 | ||
| 15 | resolved_target: ResolvedTarget, | 17 | resolved_target: ResolvedTarget, |
| ... | @@ -33,25 +35,14 @@ cc_argv: []const []const u8, | ... | @@ -33,25 +35,14 @@ cc_argv: []const []const u8, |
| 33 | structured_cfg: bool, | 35 | structured_cfg: bool, |
| 34 | no_builtin: bool, | 36 | no_builtin: bool, |
| 35 | 37 | ||
| 36 | /// If the module is an `@import("builtin")` module, this is the `File` that | ||
| 37 | /// is preallocated for it. Otherwise this field is null. | ||
| 38 | builtin_file: ?*File, | ||
| 39 | |||
| 40 | pub const Deps = std.StringArrayHashMapUnmanaged(*Module); | 38 | pub const Deps = std.StringArrayHashMapUnmanaged(*Module); |
| 41 | 39 | ||
| 42 | pub fn isBuiltin(m: Module) bool { | ||
| 43 | return m.builtin_file != null; | ||
| 44 | } | ||
| 45 | |||
| 46 | pub const Tree = struct { | 40 | pub const Tree = struct { |
| 47 | /// Each `Package` exposes a `Module` with build.zig as its root source file. | 41 | /// Each `Package` exposes a `Module` with build.zig as its root source file. |
| 48 | build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module), | 42 | build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module), |
| 49 | }; | 43 | }; |
| 50 | 44 | ||
| 51 | pub const CreateOptions = struct { | 45 | pub const CreateOptions = struct { |
| 52 | /// Where to store builtin.zig. The global cache directory is used because | ||
| 53 | /// it is a pure function based on CLI flags. | ||
| 54 | global_cache_directory: Cache.Directory, | ||
| 55 | paths: Paths, | 46 | paths: Paths, |
| 56 | fully_qualified_name: []const u8, | 47 | fully_qualified_name: []const u8, |
| 57 | 48 | ||
| ... | @@ -61,15 +52,8 @@ pub const CreateOptions = struct { | ... | @@ -61,15 +52,8 @@ pub const CreateOptions = struct { |
| 61 | /// If this is null then `resolved_target` must be non-null. | 52 | /// If this is null then `resolved_target` must be non-null. |
| 62 | parent: ?*Package.Module, | 53 | parent: ?*Package.Module, |
| 63 | 54 | ||
| 64 | builtin_mod: ?*Package.Module, | ||
| 65 | |||
| 66 | /// Allocated into the given `arena`. Should be shared across all module creations in a Compilation. | ||
| 67 | /// Ignored if `builtin_mod` is passed or if `!have_zcu`. | ||
| 68 | /// Otherwise, may be `null` only if this Compilation consists of a single module. | ||
| 69 | builtin_modules: ?*std.StringHashMapUnmanaged(*Module), | ||
| 70 | |||
| 71 | pub const Paths = struct { | 55 | pub const Paths = struct { |
| 72 | root: Cache.Path, | 56 | root: Compilation.Path, |
| 73 | /// Relative to `root`. May contain path separators. | 57 | /// Relative to `root`. May contain path separators. |
| 74 | root_src_path: []const u8, | 58 | root_src_path: []const u8, |
| 75 | }; | 59 | }; |
| ... | @@ -401,126 +385,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { | ... | @@ -401,126 +385,13 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { |
| 401 | .cc_argv = options.cc_argv, | 385 | .cc_argv = options.cc_argv, |
| 402 | .structured_cfg = structured_cfg, | 386 | .structured_cfg = structured_cfg, |
| 403 | .no_builtin = no_builtin, | 387 | .no_builtin = no_builtin, |
| 404 | .builtin_file = null, | ||
| 405 | }; | 388 | }; |
| 406 | |||
| 407 | const opt_builtin_mod = options.builtin_mod orelse b: { | ||
| 408 | if (!options.global.have_zcu) break :b null; | ||
| 409 | |||
| 410 | const generated_builtin_source = try Builtin.generate(.{ | ||
| 411 | .target = target, | ||
| 412 | .zig_backend = zig_backend, | ||
| 413 | .output_mode = options.global.output_mode, | ||
| 414 | .link_mode = options.global.link_mode, | ||
| 415 | .unwind_tables = unwind_tables, | ||
| 416 | .is_test = options.global.is_test, | ||
| 417 | .single_threaded = single_threaded, | ||
| 418 | .link_libc = options.global.link_libc, | ||
| 419 | .link_libcpp = options.global.link_libcpp, | ||
| 420 | .optimize_mode = optimize_mode, | ||
| 421 | .error_tracing = error_tracing, | ||
| 422 | .valgrind = valgrind, | ||
| 423 | .sanitize_thread = sanitize_thread, | ||
| 424 | .fuzz = fuzz, | ||
| 425 | .pic = pic, | ||
| 426 | .pie = options.global.pie, | ||
| 427 | .strip = strip, | ||
| 428 | .code_model = code_model, | ||
| 429 | .omit_frame_pointer = omit_frame_pointer, | ||
| 430 | .wasi_exec_model = options.global.wasi_exec_model, | ||
| 431 | }, arena); | ||
| 432 | |||
| 433 | const new = if (options.builtin_modules) |builtins| new: { | ||
| 434 | const gop = try builtins.getOrPut(arena, generated_builtin_source); | ||
| 435 | if (gop.found_existing) break :b gop.value_ptr.*; | ||
| 436 | errdefer builtins.removeByPtr(gop.key_ptr); | ||
| 437 | const new = try arena.create(Module); | ||
| 438 | gop.value_ptr.* = new; | ||
| 439 | break :new new; | ||
| 440 | } else try arena.create(Module); | ||
| 441 | errdefer if (options.builtin_modules) |builtins| assert(builtins.remove(generated_builtin_source)); | ||
| 442 | |||
| 443 | const new_file = try arena.create(File); | ||
| 444 | |||
| 445 | const hex_digest = digest: { | ||
| 446 | var hasher: Cache.Hasher = Cache.hasher_init; | ||
| 447 | hasher.update(generated_builtin_source); | ||
| 448 | |||
| 449 | var bin_digest: Cache.BinDigest = undefined; | ||
| 450 | hasher.final(&bin_digest); | ||
| 451 | |||
| 452 | var hex_digest: Cache.HexDigest = undefined; | ||
| 453 | _ = std.fmt.bufPrint( | ||
| 454 | &hex_digest, | ||
| 455 | "{s}", | ||
| 456 | .{std.fmt.fmtSliceHexLower(&bin_digest)}, | ||
| 457 | ) catch unreachable; | ||
| 458 | |||
| 459 | break :digest hex_digest; | ||
| 460 | }; | ||
| 461 | |||
| 462 | const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ hex_digest); | ||
| 463 | |||
| 464 | new.* = .{ | ||
| 465 | .root = .{ | ||
| 466 | .root_dir = options.global_cache_directory, | ||
| 467 | .sub_path = builtin_sub_path, | ||
| 468 | }, | ||
| 469 | .root_src_path = "builtin.zig", | ||
| 470 | .fully_qualified_name = if (options.parent == null) | ||
| 471 | "builtin" | ||
| 472 | else | ||
| 473 | try std.fmt.allocPrint(arena, "{s}.builtin", .{options.fully_qualified_name}), | ||
| 474 | .resolved_target = .{ | ||
| 475 | .result = target, | ||
| 476 | .is_native_os = resolved_target.is_native_os, | ||
| 477 | .is_native_abi = resolved_target.is_native_abi, | ||
| 478 | .llvm_cpu_features = llvm_cpu_features, | ||
| 479 | }, | ||
| 480 | .optimize_mode = optimize_mode, | ||
| 481 | .single_threaded = single_threaded, | ||
| 482 | .error_tracing = error_tracing, | ||
| 483 | .valgrind = valgrind, | ||
| 484 | .pic = pic, | ||
| 485 | .strip = strip, | ||
| 486 | .omit_frame_pointer = omit_frame_pointer, | ||
| 487 | .stack_check = stack_check, | ||
| 488 | .stack_protector = stack_protector, | ||
| 489 | .code_model = code_model, | ||
| 490 | .red_zone = red_zone, | ||
| 491 | .sanitize_c = sanitize_c, | ||
| 492 | .sanitize_thread = sanitize_thread, | ||
| 493 | .fuzz = fuzz, | ||
| 494 | .unwind_tables = unwind_tables, | ||
| 495 | .cc_argv = &.{}, | ||
| 496 | .structured_cfg = structured_cfg, | ||
| 497 | .no_builtin = no_builtin, | ||
| 498 | .builtin_file = new_file, | ||
| 499 | }; | ||
| 500 | new_file.* = .{ | ||
| 501 | .sub_file_path = "builtin.zig", | ||
| 502 | .stat = undefined, | ||
| 503 | .source = generated_builtin_source, | ||
| 504 | .tree = null, | ||
| 505 | .zir = null, | ||
| 506 | .zoir = null, | ||
| 507 | .status = .never_loaded, | ||
| 508 | .mod = new, | ||
| 509 | }; | ||
| 510 | break :b new; | ||
| 511 | }; | ||
| 512 | |||
| 513 | if (opt_builtin_mod) |builtin_mod| { | ||
| 514 | try mod.deps.ensureUnusedCapacity(arena, 1); | ||
| 515 | mod.deps.putAssumeCapacityNoClobber("builtin", builtin_mod); | ||
| 516 | } | ||
| 517 | |||
| 518 | return mod; | 389 | return mod; |
| 519 | } | 390 | } |
| 520 | 391 | ||
| 521 | /// All fields correspond to `CreateOptions`. | 392 | /// All fields correspond to `CreateOptions`. |
| 522 | pub const LimitedOptions = struct { | 393 | pub const LimitedOptions = struct { |
| 523 | root: Cache.Path, | 394 | root: Compilation.Path, |
| 524 | root_src_path: []const u8, | 395 | root_src_path: []const u8, |
| 525 | fully_qualified_name: []const u8, | 396 | fully_qualified_name: []const u8, |
| 526 | }; | 397 | }; |
| ... | @@ -553,18 +424,73 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P | ... | @@ -553,18 +424,73 @@ pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*P |
| 553 | .cc_argv = undefined, | 424 | .cc_argv = undefined, |
| 554 | .structured_cfg = undefined, | 425 | .structured_cfg = undefined, |
| 555 | .no_builtin = undefined, | 426 | .no_builtin = undefined, |
| 556 | .builtin_file = null, | ||
| 557 | }; | 427 | }; |
| 558 | return mod; | 428 | return mod; |
| 559 | } | 429 | } |
| 560 | 430 | ||
| 561 | /// Asserts that the module has a builtin module, which is not true for non-zig | 431 | /// Does not ensure that the module's root directory exists on-disk; see `Builtin.updateFileOnDisk` for that task. |
| 562 | /// modules such as ones only used for `@embedFile`, or the root module when | 432 | pub fn createBuiltin(arena: Allocator, opts: Builtin, dirs: Compilation.Directories) Allocator.Error!*Module { |
| 563 | /// there is no Zig Compilation Unit. | 433 | const sub_path = "b" ++ Cache.binToHex(opts.hash()); |
| 564 | pub fn getBuiltinDependency(m: Module) *Module { | 434 | const new = try arena.create(Module); |
| 565 | const result = m.deps.values()[0]; | 435 | new.* = .{ |
| 566 | assert(result.isBuiltin()); | 436 | .root = try .fromRoot(arena, dirs, .global_cache, sub_path), |
| 567 | return result; | 437 | .root_src_path = "builtin.zig", |
| 438 | .fully_qualified_name = "builtin", | ||
| 439 | .resolved_target = .{ | ||
| 440 | .result = opts.target, | ||
| 441 | // These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code. | ||
| 442 | .is_native_os = false, | ||
| 443 | .is_native_abi = false, | ||
| 444 | .llvm_cpu_features = null, | ||
| 445 | }, | ||
| 446 | .optimize_mode = opts.optimize_mode, | ||
| 447 | .single_threaded = opts.single_threaded, | ||
| 448 | .error_tracing = opts.error_tracing, | ||
| 449 | .valgrind = opts.valgrind, | ||
| 450 | .pic = opts.pic, | ||
| 451 | .strip = opts.strip, | ||
| 452 | .omit_frame_pointer = opts.omit_frame_pointer, | ||
| 453 | .code_model = opts.code_model, | ||
| 454 | .sanitize_thread = opts.sanitize_thread, | ||
| 455 | .fuzz = opts.fuzz, | ||
| 456 | .unwind_tables = opts.unwind_tables, | ||
| 457 | .cc_argv = &.{}, | ||
| 458 | // These values are not in `opts`, but do not matter because `builtin.zig` contains no runtime code. | ||
| 459 | .stack_check = false, | ||
| 460 | .stack_protector = 0, | ||
| 461 | .red_zone = false, | ||
| 462 | .sanitize_c = .off, | ||
| 463 | .structured_cfg = false, | ||
| 464 | .no_builtin = false, | ||
| 465 | }; | ||
| 466 | return new; | ||
| 467 | } | ||
| 468 | |||
| 469 | /// Returns the `Builtin` which forms the contents of `@import("builtin")` for this module. | ||
| 470 | pub fn getBuiltinOptions(m: Module, global: Compilation.Config) Builtin { | ||
| 471 | assert(global.have_zcu); | ||
| 472 | return .{ | ||
| 473 | .target = m.resolved_target.result, | ||
| 474 | .zig_backend = target_util.zigBackend(m.resolved_target.result, global.use_llvm), | ||
| 475 | .output_mode = global.output_mode, | ||
| 476 | .link_mode = global.link_mode, | ||
| 477 | .unwind_tables = m.unwind_tables, | ||
| 478 | .is_test = global.is_test, | ||
| 479 | .single_threaded = m.single_threaded, | ||
| 480 | .link_libc = global.link_libc, | ||
| 481 | .link_libcpp = global.link_libcpp, | ||
| 482 | .optimize_mode = m.optimize_mode, | ||
| 483 | .error_tracing = m.error_tracing, | ||
| 484 | .valgrind = m.valgrind, | ||
| 485 | .sanitize_thread = m.sanitize_thread, | ||
| 486 | .fuzz = m.fuzz, | ||
| 487 | .pic = m.pic, | ||
| 488 | .pie = global.pie, | ||
| 489 | .strip = m.strip, | ||
| 490 | .code_model = m.code_model, | ||
| 491 | .omit_frame_pointer = m.omit_frame_pointer, | ||
| 492 | .wasi_exec_model = global.wasi_exec_model, | ||
| 493 | }; | ||
| 568 | } | 494 | } |
| 569 | 495 | ||
| 570 | const Module = @This(); | 496 | const Module = @This(); |
src/Sema.zig+81-70| ... | @@ -829,7 +829,7 @@ pub const Block = struct { | ... | @@ -829,7 +829,7 @@ pub const Block = struct { |
| 829 | 829 | ||
| 830 | pub fn ownerModule(block: Block) *Package.Module { | 830 | pub fn ownerModule(block: Block) *Package.Module { |
| 831 | const zcu = block.sema.pt.zcu; | 831 | const zcu = block.sema.pt.zcu; |
| 832 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod; | 832 | return zcu.namespacePtr(block.namespace).fileScope(zcu).mod.?; |
| 833 | } | 833 | } |
| 834 | 834 | ||
| 835 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { | 835 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { |
| ... | @@ -1127,10 +1127,10 @@ fn analyzeBodyInner( | ... | @@ -1127,10 +1127,10 @@ fn analyzeBodyInner( |
| 1127 | 1127 | ||
| 1128 | // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. | 1128 | // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. |
| 1129 | if (build_options.enable_logging) { | 1129 | if (build_options.enable_logging) { |
| 1130 | std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: { | 1130 | std.log.scoped(.sema_zir).debug("sema ZIR {} %{d}", .{ path: { |
| 1131 | const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool); | 1131 | const file_index = block.src_base_inst.resolveFile(&zcu.intern_pool); |
| 1132 | const file = zcu.fileByIndex(file_index); | 1132 | const file = zcu.fileByIndex(file_index); |
| 1133 | break :sub_file_path file.sub_file_path; | 1133 | break :path file.path.fmt(zcu.comp); |
| 1134 | }, inst }); | 1134 | }, inst }); |
| 1135 | } | 1135 | } |
| 1136 | 1136 | ||
| ... | @@ -6162,50 +6162,67 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6162,50 +6162,67 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr |
| 6162 | } | 6162 | } |
| 6163 | const parent_mod = parent_block.ownerModule(); | 6163 | const parent_mod = parent_block.ownerModule(); |
| 6164 | const digest = Cache.binToHex(c_import_res.digest); | 6164 | const digest = Cache.binToHex(c_import_res.digest); |
| 6165 | const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest); | ||
| 6166 | const c_import_mod = Package.Module.create(comp.arena, .{ | ||
| 6167 | .global_cache_directory = comp.global_cache_directory, | ||
| 6168 | .paths = .{ | ||
| 6169 | .root = .{ | ||
| 6170 | .root_dir = comp.local_cache_directory, | ||
| 6171 | .sub_path = c_import_zig_path, | ||
| 6172 | }, | ||
| 6173 | .root_src_path = "cimport.zig", | ||
| 6174 | }, | ||
| 6175 | .fully_qualified_name = c_import_zig_path, | ||
| 6176 | .cc_argv = parent_mod.cc_argv, | ||
| 6177 | .inherited = .{}, | ||
| 6178 | .global = comp.config, | ||
| 6179 | .parent = parent_mod, | ||
| 6180 | .builtin_mod = parent_mod.getBuiltinDependency(), | ||
| 6181 | .builtin_modules = null, // `builtin_mod` is set | ||
| 6182 | }) catch |err| switch (err) { | ||
| 6183 | // None of these are possible because we are creating a package with | ||
| 6184 | // the exact same configuration as the parent package, which already | ||
| 6185 | // passed these checks. | ||
| 6186 | error.ValgrindUnsupportedOnTarget => unreachable, | ||
| 6187 | error.TargetRequiresSingleThreaded => unreachable, | ||
| 6188 | error.BackendRequiresSingleThreaded => unreachable, | ||
| 6189 | error.TargetRequiresPic => unreachable, | ||
| 6190 | error.PieRequiresPic => unreachable, | ||
| 6191 | error.DynamicLinkingRequiresPic => unreachable, | ||
| 6192 | error.TargetHasNoRedZone => unreachable, | ||
| 6193 | error.StackCheckUnsupportedByTarget => unreachable, | ||
| 6194 | error.StackProtectorUnsupportedByTarget => unreachable, | ||
| 6195 | error.StackProtectorUnavailableWithoutLibC => unreachable, | ||
| 6196 | 6165 | ||
| 6197 | else => |e| return e, | 6166 | const new_file_index = file: { |
| 6198 | }; | 6167 | const c_import_zig_path = try comp.arena.dupe(u8, "o" ++ std.fs.path.sep_str ++ digest); |
| 6168 | const c_import_mod = Package.Module.create(comp.arena, .{ | ||
| 6169 | .paths = .{ | ||
| 6170 | .root = try .fromRoot(comp.arena, comp.dirs, .local_cache, c_import_zig_path), | ||
| 6171 | .root_src_path = "cimport.zig", | ||
| 6172 | }, | ||
| 6173 | .fully_qualified_name = c_import_zig_path, | ||
| 6174 | .cc_argv = parent_mod.cc_argv, | ||
| 6175 | .inherited = .{}, | ||
| 6176 | .global = comp.config, | ||
| 6177 | .parent = parent_mod, | ||
| 6178 | }) catch |err| switch (err) { | ||
| 6179 | // None of these are possible because we are creating a package with | ||
| 6180 | // the exact same configuration as the parent package, which already | ||
| 6181 | // passed these checks. | ||
| 6182 | error.ValgrindUnsupportedOnTarget => unreachable, | ||
| 6183 | error.TargetRequiresSingleThreaded => unreachable, | ||
| 6184 | error.BackendRequiresSingleThreaded => unreachable, | ||
| 6185 | error.TargetRequiresPic => unreachable, | ||
| 6186 | error.PieRequiresPic => unreachable, | ||
| 6187 | error.DynamicLinkingRequiresPic => unreachable, | ||
| 6188 | error.TargetHasNoRedZone => unreachable, | ||
| 6189 | error.StackCheckUnsupportedByTarget => unreachable, | ||
| 6190 | error.StackProtectorUnsupportedByTarget => unreachable, | ||
| 6191 | error.StackProtectorUnavailableWithoutLibC => unreachable, | ||
| 6199 | 6192 | ||
| 6200 | const result = pt.importPkg(c_import_mod) catch |err| | 6193 | else => |e| return e, |
| 6201 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6194 | }; |
| 6202 | 6195 | const c_import_file_path: Compilation.Path = try c_import_mod.root.join(gpa, comp.dirs, "cimport.zig"); | |
| 6203 | const path_digest = zcu.filePathDigest(result.file_index); | 6196 | errdefer c_import_file_path.deinit(gpa); |
| 6204 | pt.updateFile(result.file, path_digest) catch |err| | 6197 | const c_import_file = try gpa.create(Zcu.File); |
| 6198 | errdefer gpa.destroy(c_import_file); | ||
| 6199 | const c_import_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ | ||
| 6200 | .bin_digest = c_import_file_path.digest(), | ||
| 6201 | .file = c_import_file, | ||
| 6202 | .root_type = .none, | ||
| 6203 | }); | ||
| 6204 | c_import_file.* = .{ | ||
| 6205 | .status = .never_loaded, | ||
| 6206 | .stat = undefined, | ||
| 6207 | .is_builtin = false, | ||
| 6208 | .path = c_import_file_path, | ||
| 6209 | .source = null, | ||
| 6210 | .tree = null, | ||
| 6211 | .zir = null, | ||
| 6212 | .zoir = null, | ||
| 6213 | .mod = c_import_mod, | ||
| 6214 | .sub_file_path = "cimport.zig", | ||
| 6215 | .module_changed = false, | ||
| 6216 | .prev_zir = null, | ||
| 6217 | .zoir_invalidated = false, | ||
| 6218 | }; | ||
| 6219 | break :file c_import_file_index; | ||
| 6220 | }; | ||
| 6221 | pt.updateFile(new_file_index, zcu.fileByIndex(new_file_index)) catch |err| | ||
| 6205 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); | 6222 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6206 | 6223 | ||
| 6207 | try pt.ensureFileAnalyzed(result.file_index); | 6224 | try pt.ensureFileAnalyzed(new_file_index); |
| 6208 | const ty = zcu.fileRootType(result.file_index); | 6225 | const ty = zcu.fileRootType(new_file_index); |
| 6209 | try sema.declareDependency(.{ .interned = ty }); | 6226 | try sema.declareDependency(.{ .interned = ty }); |
| 6210 | try sema.addTypeReferenceEntry(src, ty); | 6227 | try sema.addTypeReferenceEntry(src, ty); |
| 6211 | return Air.internedToRef(ty); | 6228 | return Air.internedToRef(ty); |
| ... | @@ -14097,25 +14114,19 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14097,25 +14114,19 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14097 | const operand_src = block.tokenOffset(inst_data.src_tok); | 14114 | const operand_src = block.tokenOffset(inst_data.src_tok); |
| 14098 | const operand = sema.code.nullTerminatedString(extra.path); | 14115 | const operand = sema.code.nullTerminatedString(extra.path); |
| 14099 | 14116 | ||
| 14100 | const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) { | 14117 | const result = pt.doImport(block.getFileScope(zcu), operand) catch |err| switch (err) { |
| 14101 | error.ImportOutsideModulePath => { | 14118 | error.ModuleNotFound => return sema.fail(block, operand_src, "no module named '{s}' available within module '{s}'", .{ |
| 14102 | return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand}); | 14119 | operand, block.getFileScope(zcu).mod.?.fully_qualified_name, |
| 14103 | }, | 14120 | }), |
| 14104 | error.ModuleNotFound => { | 14121 | error.IllegalZigImport => unreachable, // caught before semantic analysis |
| 14105 | return sema.fail(block, operand_src, "no module named '{s}' available within module {s}", .{ | 14122 | error.OutOfMemory => |e| return e, |
| 14106 | operand, block.getFileScope(zcu).mod.fully_qualified_name, | ||
| 14107 | }); | ||
| 14108 | }, | ||
| 14109 | else => { | ||
| 14110 | // TODO: these errors are file system errors; make sure an update() will | ||
| 14111 | // retry this and not cache the file system error, which may be transient. | ||
| 14112 | return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); | ||
| 14113 | }, | ||
| 14114 | }; | 14123 | }; |
| 14115 | switch (result.file.getMode()) { | 14124 | const file_index = result.file; |
| 14125 | const file = zcu.fileByIndex(file_index); | ||
| 14126 | switch (file.getMode()) { | ||
| 14116 | .zig => { | 14127 | .zig => { |
| 14117 | try pt.ensureFileAnalyzed(result.file_index); | 14128 | try pt.ensureFileAnalyzed(file_index); |
| 14118 | const ty = zcu.fileRootType(result.file_index); | 14129 | const ty = zcu.fileRootType(file_index); |
| 14119 | try sema.declareDependency(.{ .interned = ty }); | 14130 | try sema.declareDependency(.{ .interned = ty }); |
| 14120 | try sema.addTypeReferenceEntry(operand_src, ty); | 14131 | try sema.addTypeReferenceEntry(operand_src, ty); |
| 14121 | return Air.internedToRef(ty); | 14132 | return Air.internedToRef(ty); |
| ... | @@ -14129,11 +14140,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -14129,11 +14140,11 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 14129 | break :b res_ty.toIntern(); | 14140 | break :b res_ty.toIntern(); |
| 14130 | }; | 14141 | }; |
| 14131 | 14142 | ||
| 14132 | try sema.declareDependency(.{ .zon_file = result.file_index }); | 14143 | try sema.declareDependency(.{ .zon_file = file_index }); |
| 14133 | const interned = try LowerZon.run( | 14144 | const interned = try LowerZon.run( |
| 14134 | sema, | 14145 | sema, |
| 14135 | result.file, | 14146 | file, |
| 14136 | result.file_index, | 14147 | file_index, |
| 14137 | res_ty, | 14148 | res_ty, |
| 14138 | operand_src, | 14149 | operand_src, |
| 14139 | block, | 14150 | block, |
| ... | @@ -17308,10 +17319,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17308,10 +17319,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17308 | const name = name: { | 17319 | const name = name: { |
| 17309 | // TODO: we should probably store this name in the ZIR to avoid this complexity. | 17320 | // TODO: we should probably store this name in the ZIR to avoid this complexity. |
| 17310 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | 17321 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; |
| 17311 | const tree = file.getTree(sema.gpa) catch |err| { | 17322 | const tree = file.getTree(zcu) catch |err| { |
| 17312 | // In this case we emit a warning + a less precise source location. | 17323 | // In this case we emit a warning + a less precise source location. |
| 17313 | log.warn("unable to load {s}: {s}", .{ | 17324 | log.warn("unable to load {}: {s}", .{ |
| 17314 | file.sub_file_path, @errorName(err), | 17325 | file.path.fmt(zcu.comp), @errorName(err), |
| 17315 | }); | 17326 | }); |
| 17316 | break :name null; | 17327 | break :name null; |
| 17317 | }; | 17328 | }; |
| ... | @@ -17336,10 +17347,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -17336,10 +17347,10 @@ fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 17336 | const msg = msg: { | 17347 | const msg = msg: { |
| 17337 | const name = name: { | 17348 | const name = name: { |
| 17338 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; | 17349 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu).?; |
| 17339 | const tree = file.getTree(sema.gpa) catch |err| { | 17350 | const tree = file.getTree(zcu) catch |err| { |
| 17340 | // In this case we emit a warning + a less precise source location. | 17351 | // In this case we emit a warning + a less precise source location. |
| 17341 | log.warn("unable to load {s}: {s}", .{ | 17352 | log.warn("unable to load {}: {s}", .{ |
| 17342 | file.sub_file_path, @errorName(err), | 17353 | file.path.fmt(zcu.comp), @errorName(err), |
| 17343 | }); | 17354 | }); |
| 17344 | break :name null; | 17355 | break :name null; |
| 17345 | }; | 17356 | }; |
| ... | @@ -17433,7 +17444,7 @@ fn zirBuiltinSrc( | ... | @@ -17433,7 +17444,7 @@ fn zirBuiltinSrc( |
| 17433 | }; | 17444 | }; |
| 17434 | 17445 | ||
| 17435 | const module_name_val = v: { | 17446 | const module_name_val = v: { |
| 17436 | const module_name = file_scope.mod.fully_qualified_name; | 17447 | const module_name = file_scope.mod.?.fully_qualified_name; |
| 17437 | const array_ty = try pt.intern(.{ .array_type = .{ | 17448 | const array_ty = try pt.intern(.{ .array_type = .{ |
| 17438 | .len = module_name.len, | 17449 | .len = module_name.len, |
| 17439 | .sentinel = .zero_u8, | 17450 | .sentinel = .zero_u8, |
src/Zcu.zig+441-262| ... | @@ -72,9 +72,9 @@ sema_prog_node: std.Progress.Node = std.Progress.Node.none, | ... | @@ -72,9 +72,9 @@ sema_prog_node: std.Progress.Node = std.Progress.Node.none, |
| 72 | codegen_prog_node: std.Progress.Node = std.Progress.Node.none, | 72 | codegen_prog_node: std.Progress.Node = std.Progress.Node.none, |
| 73 | 73 | ||
| 74 | /// Used by AstGen worker to load and store ZIR cache. | 74 | /// Used by AstGen worker to load and store ZIR cache. |
| 75 | global_zir_cache: Compilation.Directory, | 75 | global_zir_cache: Cache.Directory, |
| 76 | /// Used by AstGen worker to load and store ZIR cache. | 76 | /// Used by AstGen worker to load and store ZIR cache. |
| 77 | local_zir_cache: Compilation.Directory, | 77 | local_zir_cache: Cache.Directory, |
| 78 | 78 | ||
| 79 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; | 79 | /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; |
| 80 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. | 80 | /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. |
| ... | @@ -93,27 +93,72 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | ... | @@ -93,27 +93,72 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 93 | len: u32, | 93 | len: u32, |
| 94 | }) = .{}, | 94 | }) = .{}, |
| 95 | 95 | ||
| 96 | /// Key is the digest returned by `Builtin.hash`; value is the corresponding module. | ||
| 97 | builtin_modules: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, *Package.Module) = .empty, | ||
| 98 | |||
| 99 | /// Populated as soon as the `Compilation` is created. Guaranteed to contain all modules, even builtin ones. | ||
| 100 | /// Modules whose root file is not a Zig or ZON file have the value `.none`. | ||
| 101 | module_roots: std.AutoArrayHashMapUnmanaged(*Package.Module, File.Index.Optional) = .empty, | ||
| 102 | |||
| 96 | /// The set of all the Zig source files in the Zig Compilation Unit. Tracked in | 103 | /// The set of all the Zig source files in the Zig Compilation Unit. Tracked in |
| 97 | /// order to iterate over it and check which source files have been modified on | 104 | /// order to iterate over it and check which source files have been modified on |
| 98 | /// the file system when an update is requested, as well as to cache `@import` | 105 | /// the file system when an update is requested, as well as to cache `@import` |
| 99 | /// results. | 106 | /// results. |
| 100 | /// | 107 | /// |
| 101 | /// Keys are fully resolved file paths. This table owns the keys and values. | 108 | /// Always accessed through `ImportTableAdapter`, where keys are fully resolved |
| 109 | /// file paths in order to ensure files are properly deduplicated. This table owns | ||
| 110 | /// the keys and values. | ||
| 102 | /// | 111 | /// |
| 103 | /// Protected by Compilation's mutex. | 112 | /// Protected by Compilation's mutex. |
| 104 | /// | 113 | /// |
| 105 | /// Not serialized. This state is reconstructed during the first call to | 114 | /// Not serialized. This state is reconstructed during the first call to |
| 106 | /// `Compilation.update` of the process for a given `Compilation`. | 115 | /// `Compilation.update` of the process for a given `Compilation`. |
| 107 | /// | 116 | import_table: std.ArrayHashMapUnmanaged( |
| 108 | /// Indexes correspond 1:1 to `files`. | 117 | File.Index, |
| 109 | import_table: std.StringArrayHashMapUnmanaged(File.Index) = .empty, | 118 | void, |
| 119 | struct { | ||
| 120 | pub const hash = @compileError("all accesses should be through ImportTableAdapter"); | ||
| 121 | pub const eql = @compileError("all accesses should be through ImportTableAdapter"); | ||
| 122 | }, | ||
| 123 | true, // This is necessary! Without it, the map tries to use its Context to rehash. #21918 | ||
| 124 | ) = .empty, | ||
| 125 | |||
| 126 | /// The set of all files in `import_table` which are "alive" this update, meaning | ||
| 127 | /// they are reachable by traversing imports starting from an analysis root. This | ||
| 128 | /// is usually all files in `import_table`, but some could be omitted if an incremental | ||
| 129 | /// update removes an import, or if a module specified on the CLI is never imported. | ||
| 130 | /// Reconstructed on every update, after AstGen and before Sema. | ||
| 131 | /// Value is why the file is alive. | ||
| 132 | alive_files: std.AutoArrayHashMapUnmanaged(File.Index, File.Reference) = .empty, | ||
| 133 | |||
| 134 | /// If this is populated, a "file exists in multiple modules" error should be emitted. | ||
| 135 | /// This causes file errors to not be shown, because we don't really know which files | ||
| 136 | /// should be alive (because the user has messed up their imports somewhere!). | ||
| 137 | /// Cleared and recomputed every update, after AstGen and before Sema. | ||
| 138 | multi_module_err: ?struct { | ||
| 139 | file: File.Index, | ||
| 140 | modules: [2]*Package.Module, | ||
| 141 | refs: [2]File.Reference, | ||
| 142 | } = null, | ||
| 110 | 143 | ||
| 111 | /// The set of all the files which have been loaded with `@embedFile` in the Module. | 144 | /// The set of all the files which have been loaded with `@embedFile` in the Module. |
| 112 | /// We keep track of this in order to iterate over it and check which files have been | 145 | /// We keep track of this in order to iterate over it and check which files have been |
| 113 | /// modified on the file system when an update is requested, as well as to cache | 146 | /// modified on the file system when an update is requested, as well as to cache |
| 114 | /// `@embedFile` results. | 147 | /// `@embedFile` results. |
| 115 | /// Keys are fully resolved file paths. This table owns the keys and values. | 148 | /// |
| 116 | embed_table: std.StringArrayHashMapUnmanaged(*EmbedFile) = .empty, | 149 | /// Like `import_table`, this is accessed through `EmbedTableAdapter`, so that it is keyed |
| 150 | /// on the `Compilation.Path` of the `EmbedFile`. | ||
| 151 | /// | ||
| 152 | /// This table owns all of the `*EmbedFile` memory, which is allocated into gpa. | ||
| 153 | embed_table: std.ArrayHashMapUnmanaged( | ||
| 154 | *EmbedFile, | ||
| 155 | void, | ||
| 156 | struct { | ||
| 157 | pub const hash = @compileError("all accesses should be through EmbedTableAdapter"); | ||
| 158 | pub const eql = @compileError("all accesses should be through EmbedTableAdapter"); | ||
| 159 | }, | ||
| 160 | true, // This is necessary! Without it, the map tries to use its Context to rehash. #21918 | ||
| 161 | ) = .empty, | ||
| 117 | 162 | ||
| 118 | /// Stores all Type and Value objects. | 163 | /// Stores all Type and Value objects. |
| 119 | /// The idea is that this will be periodically garbage-collected, but such logic | 164 | /// The idea is that this will be periodically garbage-collected, but such logic |
| ... | @@ -147,9 +192,41 @@ compile_logs: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { | ... | @@ -147,9 +192,41 @@ compile_logs: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 147 | }) = .empty, | 192 | }) = .empty, |
| 148 | compile_log_lines: std.ArrayListUnmanaged(CompileLogLine) = .empty, | 193 | compile_log_lines: std.ArrayListUnmanaged(CompileLogLine) = .empty, |
| 149 | free_compile_log_lines: std.ArrayListUnmanaged(CompileLogLine.Index) = .empty, | 194 | free_compile_log_lines: std.ArrayListUnmanaged(CompileLogLine.Index) = .empty, |
| 150 | /// Using a map here for consistency with the other fields here. | 195 | /// This tracks files which triggered errors when generating AST/ZIR/ZOIR. |
| 151 | /// The ErrorMsg memory is owned by the `File`, using Module's general purpose allocator. | 196 | /// If not `null`, the value is a retryable error (the file status is guaranteed |
| 152 | failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .empty, | 197 | /// to be `.retryable_failure`). Otherwise, the file status is `.astgen_failure` |
| 198 | /// or `.success`, and there are ZIR/ZOIR errors which should be printed. | ||
| 199 | /// We just store a `[]u8` instead of a full `*ErrorMsg`, because the source | ||
| 200 | /// location is always the entire file. The `[]u8` memory is owned by the map | ||
| 201 | /// and allocated into `gpa`. | ||
| 202 | failed_files: std.AutoArrayHashMapUnmanaged(File.Index, ?[]u8) = .empty, | ||
| 203 | /// AstGen is not aware of modules, and so cannot determine whether an import | ||
| 204 | /// string makes sense. That is the job of a traversal after AstGen. | ||
| 205 | /// | ||
| 206 | /// There are several ways in which an import can fail: | ||
| 207 | /// | ||
| 208 | /// * It is an import of a file which does not exist. This case is not handled | ||
| 209 | /// by this field, but with a `failed_files` entry on the *imported* file. | ||
| 210 | /// * It is an import of a module which does not exist in the current module's | ||
| 211 | /// dependency table. This happens at `Sema` time, so is not tracked by this | ||
| 212 | /// field. | ||
| 213 | /// * It is an import which reaches outside of the current module's root | ||
| 214 | /// directory. This is tracked by this field. | ||
| 215 | /// * It is an import which reaches into an "illegal import directory". Right now, | ||
| 216 | /// the only such directory is 'global_cache/b/', but in general, these are | ||
| 217 | /// directories the compiler treats specially. This is tracked by this field. | ||
| 218 | /// | ||
| 219 | /// This is a flat array containing all of the relevant errors. It is cleared and | ||
| 220 | /// recomputed on every update. The errors here are fatal, i.e. they block any | ||
| 221 | /// semantic analysis this update. | ||
| 222 | /// | ||
| 223 | /// Allocated into gpa. | ||
| 224 | failed_imports: std.ArrayListUnmanaged(struct { | ||
| 225 | file_index: File.Index, | ||
| 226 | import_string: Zir.NullTerminatedString, | ||
| 227 | import_token: Ast.TokenIndex, | ||
| 228 | kind: enum { file_outside_module_root, illegal_zig_import }, | ||
| 229 | }) = .empty, | ||
| 153 | failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty, | 230 | failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty, |
| 154 | /// If analysis failed due to a cimport error, the corresponding Clang errors | 231 | /// If analysis failed due to a cimport error, the corresponding Clang errors |
| 155 | /// are stored here. | 232 | /// are stored here. |
| ... | @@ -235,6 +312,32 @@ generation: u32 = 0, | ... | @@ -235,6 +312,32 @@ generation: u32 = 0, |
| 235 | 312 | ||
| 236 | pub const PerThread = @import("Zcu/PerThread.zig"); | 313 | pub const PerThread = @import("Zcu/PerThread.zig"); |
| 237 | 314 | ||
| 315 | pub const ImportTableAdapter = struct { | ||
| 316 | zcu: *const Zcu, | ||
| 317 | pub fn hash(ctx: ImportTableAdapter, path: Compilation.Path) u32 { | ||
| 318 | _ = ctx; | ||
| 319 | return @truncate(std.hash.Wyhash.hash(@intFromEnum(path.root), path.sub_path)); | ||
| 320 | } | ||
| 321 | pub fn eql(ctx: ImportTableAdapter, a_path: Compilation.Path, b_file: File.Index, b_index: usize) bool { | ||
| 322 | _ = b_index; | ||
| 323 | const b_path = ctx.zcu.fileByIndex(b_file).path; | ||
| 324 | return a_path.root == b_path.root and mem.eql(u8, a_path.sub_path, b_path.sub_path); | ||
| 325 | } | ||
| 326 | }; | ||
| 327 | |||
| 328 | pub const EmbedTableAdapter = struct { | ||
| 329 | pub fn hash(ctx: EmbedTableAdapter, path: Compilation.Path) u32 { | ||
| 330 | _ = ctx; | ||
| 331 | return @truncate(std.hash.Wyhash.hash(@intFromEnum(path.root), path.sub_path)); | ||
| 332 | } | ||
| 333 | pub fn eql(ctx: EmbedTableAdapter, a_path: Compilation.Path, b_file: *EmbedFile, b_index: usize) bool { | ||
| 334 | _ = ctx; | ||
| 335 | _ = b_index; | ||
| 336 | const b_path = b_file.path; | ||
| 337 | return a_path.root == b_path.root and mem.eql(u8, a_path.sub_path, b_path.sub_path); | ||
| 338 | } | ||
| 339 | }; | ||
| 340 | |||
| 238 | /// Names of declarations in `std.builtin` whose values are memoized in a `BuiltinDecl.Memoized`. | 341 | /// Names of declarations in `std.builtin` whose values are memoized in a `BuiltinDecl.Memoized`. |
| 239 | /// The name must exactly match the declaration name, as comptime logic is used to compute the namespace accesses. | 342 | /// The name must exactly match the declaration name, as comptime logic is used to compute the namespace accesses. |
| 240 | /// Parent namespaces must be before their children in this enum. For instance, `.Type` must be before `.@"Type.Fn"`. | 343 | /// Parent namespaces must be before their children in this enum. For instance, `.Type` must be before `.@"Type.Fn"`. |
| ... | @@ -732,41 +835,61 @@ pub const Namespace = struct { | ... | @@ -732,41 +835,61 @@ pub const Namespace = struct { |
| 732 | }; | 835 | }; |
| 733 | 836 | ||
| 734 | pub const File = struct { | 837 | pub const File = struct { |
| 735 | /// Relative to the owning package's root source directory. | ||
| 736 | /// Memory is stored in gpa, owned by File. | ||
| 737 | sub_file_path: []const u8, | ||
| 738 | |||
| 739 | status: enum { | 838 | status: enum { |
| 740 | /// We have not yet attempted to load this file. | 839 | /// We have not yet attempted to load this file. |
| 741 | /// `stat` is not populated and may be `undefined`. | 840 | /// `stat` is not populated and may be `undefined`. |
| 742 | never_loaded, | 841 | never_loaded, |
| 743 | /// A filesystem access failed. It should be retried on the next update. | 842 | /// A filesystem access failed. It should be retried on the next update. |
| 744 | /// There is a `failed_files` entry containing a non-`null` message. | 843 | /// There is guaranteed to be a `failed_files` entry with at least one message. |
| 844 | /// ZIR/ZOIR errors should not be emitted as `zir`/`zoir` is not up-to-date. | ||
| 745 | /// `stat` is not populated and may be `undefined`. | 845 | /// `stat` is not populated and may be `undefined`. |
| 746 | retryable_failure, | 846 | retryable_failure, |
| 747 | /// Parsing/AstGen/ZonGen of this file has failed. | 847 | /// This file has failed parsing, AstGen, or ZonGen. |
| 748 | /// There is an error in `zir` or `zoir`. | 848 | /// There is guaranteed to be a `failed_files` entry, which may or may not have messages. |
| 749 | /// There is a `failed_files` entry (with a `null` message). | 849 | /// ZIR/ZOIR errors *should* be emitted as `zir`/`zoir` is up-to-date. |
| 750 | /// `stat` is populated. | 850 | /// `stat` is populated. |
| 751 | astgen_failure, | 851 | astgen_failure, |
| 752 | /// Parsing and AstGen/ZonGen of this file has succeeded. | 852 | /// Parsing and AstGen/ZonGen of this file has succeeded. |
| 853 | /// There may still be a `failed_files` entry, e.g. for non-fatal AstGen errors. | ||
| 753 | /// `stat` is populated. | 854 | /// `stat` is populated. |
| 754 | success, | 855 | success, |
| 755 | }, | 856 | }, |
| 756 | /// Whether this is populated depends on `status`. | 857 | /// Whether this is populated depends on `status`. |
| 757 | stat: Cache.File.Stat, | 858 | stat: Cache.File.Stat, |
| 758 | 859 | ||
| 860 | /// Whether this file is the generated file of a "builtin" module. This matters because those | ||
| 861 | /// files are generated and stored in-nemory rather than being read off-disk. The rest of the | ||
| 862 | /// pipeline generally shouldn't care about this. | ||
| 863 | is_builtin: bool, | ||
| 864 | |||
| 865 | /// The path of this file. It is important that this path has a "canonical form" because files | ||
| 866 | /// are deduplicated based on path; `Compilation.Path` guarantees this. Owned by this `File`, | ||
| 867 | /// allocated into `gpa`. | ||
| 868 | path: Compilation.Path, | ||
| 869 | |||
| 759 | source: ?[:0]const u8, | 870 | source: ?[:0]const u8, |
| 760 | tree: ?Ast, | 871 | tree: ?Ast, |
| 761 | zir: ?Zir, | 872 | zir: ?Zir, |
| 762 | zoir: ?Zoir, | 873 | zoir: ?Zoir, |
| 763 | 874 | ||
| 764 | /// Module that this file is a part of, managed externally. | 875 | /// Module that this file is a part of, managed externally. |
| 765 | mod: *Package.Module, | 876 | /// This is initially `null`. After AstGen, a pass is run to determine which module each |
| 766 | /// Whether this file is a part of multiple packages. This is an error condition which will be reported after AstGen. | 877 | /// file belongs to, at which point this field is set. It is never set to `null` again; |
| 767 | multi_pkg: bool = false, | 878 | /// this is so that if the file starts belonging to a different module instead, we can |
| 768 | /// List of references to this file, used for multi-package errors. | 879 | /// tell, and invalidate dependencies as needed (see `module_changed`). |
| 769 | references: std.ArrayListUnmanaged(File.Reference) = .empty, | 880 | /// During semantic analysis, this is always non-`null` for alive files (i.e. those which |
| 881 | /// have imports targeting them). | ||
| 882 | mod: ?*Package.Module, | ||
| 883 | /// Relative to the root directory of `mod`. If `mod == null`, this field is `undefined`. | ||
| 884 | /// This memory is managed externally and must not be directly freed. | ||
| 885 | /// Its lifetime is at least equal to that of this `File`. | ||
| 886 | sub_file_path: []const u8, | ||
| 887 | |||
| 888 | /// If this file's module identity changes on an incremental update, this flag is set to signal | ||
| 889 | /// to `Zcu.updateZirRefs` that all references to this file must be invalidated. This matters | ||
| 890 | /// because changing your module changes things like your optimization mode and codegen flags, | ||
| 891 | /// so everything needs to be re-done. `updateZirRefs` is responsible for resetting this flag. | ||
| 892 | module_changed: bool, | ||
| 770 | 893 | ||
| 771 | /// The ZIR for this file from the last update with no file failures. As such, this ZIR is never | 894 | /// The ZIR for this file from the last update with no file failures. As such, this ZIR is never |
| 772 | /// failed (although it may have compile errors). | 895 | /// failed (although it may have compile errors). |
| ... | @@ -777,7 +900,7 @@ pub const File = struct { | ... | @@ -777,7 +900,7 @@ pub const File = struct { |
| 777 | /// | 900 | /// |
| 778 | /// In other words, if `TrackedInst`s are tied to ZIR other than what's in the `zir` field, this | 901 | /// In other words, if `TrackedInst`s are tied to ZIR other than what's in the `zir` field, this |
| 779 | /// field is populated with that old ZIR. | 902 | /// field is populated with that old ZIR. |
| 780 | prev_zir: ?*Zir = null, | 903 | prev_zir: ?*Zir, |
| 781 | 904 | ||
| 782 | /// This field serves a similar purpose to `prev_zir`, but for ZOIR. However, since we do not | 905 | /// This field serves a similar purpose to `prev_zir`, but for ZOIR. However, since we do not |
| 783 | /// need to map old ZOIR to new ZOIR -- instead only invalidating dependencies if the ZOIR | 906 | /// need to map old ZOIR to new ZOIR -- instead only invalidating dependencies if the ZOIR |
| ... | @@ -785,27 +908,42 @@ pub const File = struct { | ... | @@ -785,27 +908,42 @@ pub const File = struct { |
| 785 | /// | 908 | /// |
| 786 | /// When `zoir` is updated, this field is set to `true`. In `updateZirRefs`, if this is `true`, | 909 | /// When `zoir` is updated, this field is set to `true`. In `updateZirRefs`, if this is `true`, |
| 787 | /// we invalidate the corresponding `zon_file` dependency, and reset it to `false`. | 910 | /// we invalidate the corresponding `zon_file` dependency, and reset it to `false`. |
| 788 | zoir_invalidated: bool = false, | 911 | zoir_invalidated: bool, |
| 912 | |||
| 913 | pub const Path = struct { | ||
| 914 | root: enum { | ||
| 915 | cwd, | ||
| 916 | fs_root, | ||
| 917 | local_cache, | ||
| 918 | global_cache, | ||
| 919 | lib_dir, | ||
| 920 | }, | ||
| 921 | }; | ||
| 789 | 922 | ||
| 790 | /// A single reference to a file. | 923 | /// A single reference to a file. |
| 791 | pub const Reference = union(enum) { | 924 | pub const Reference = union(enum) { |
| 792 | /// The file is imported directly (i.e. not as a package) with @import. | 925 | analysis_root: *Package.Module, |
| 793 | import: struct { | 926 | import: struct { |
| 794 | file: File.Index, | 927 | importer: Zcu.File.Index, |
| 795 | token: Ast.TokenIndex, | 928 | tok: Ast.TokenIndex, |
| 929 | /// If the file is imported as the root of a module, this is that module. | ||
| 930 | /// `null` means the file was imported directly by path. | ||
| 931 | module: ?*Package.Module, | ||
| 796 | }, | 932 | }, |
| 797 | /// The file is the root of a module. | ||
| 798 | root: *Package.Module, | ||
| 799 | }; | 933 | }; |
| 800 | 934 | ||
| 801 | pub fn getMode(self: File) Ast.Mode { | 935 | pub fn getMode(self: File) Ast.Mode { |
| 802 | if (std.mem.endsWith(u8, self.sub_file_path, ".zon")) { | 936 | // We never create a `File` whose path doesn't give a mode. |
| 937 | return modeFromPath(self.path.sub_path).?; | ||
| 938 | } | ||
| 939 | |||
| 940 | pub fn modeFromPath(path: []const u8) ?Ast.Mode { | ||
| 941 | if (std.mem.endsWith(u8, path, ".zon")) { | ||
| 803 | return .zon; | 942 | return .zon; |
| 804 | } else if (std.mem.endsWith(u8, self.sub_file_path, ".zig")) { | 943 | } else if (std.mem.endsWith(u8, path, ".zig")) { |
| 805 | return .zig; | 944 | return .zig; |
| 806 | } else { | 945 | } else { |
| 807 | // `Module.importFile` rejects all other extensions | 946 | return null; |
| 808 | unreachable; | ||
| 809 | } | 947 | } |
| 810 | } | 948 | } |
| 811 | 949 | ||
| ... | @@ -842,15 +980,18 @@ pub const File = struct { | ... | @@ -842,15 +980,18 @@ pub const File = struct { |
| 842 | stat: Cache.File.Stat, | 980 | stat: Cache.File.Stat, |
| 843 | }; | 981 | }; |
| 844 | 982 | ||
| 845 | pub fn getSource(file: *File, gpa: Allocator) !Source { | 983 | pub fn getSource(file: *File, zcu: *const Zcu) !Source { |
| 984 | const gpa = zcu.gpa; | ||
| 985 | |||
| 846 | if (file.source) |source| return .{ | 986 | if (file.source) |source| return .{ |
| 847 | .bytes = source, | 987 | .bytes = source, |
| 848 | .stat = file.stat, | 988 | .stat = file.stat, |
| 849 | }; | 989 | }; |
| 850 | 990 | ||
| 851 | // Keep track of inode, file size, mtime, hash so we can detect which files | 991 | var f = f: { |
| 852 | // have been modified when an incremental update is requested. | 992 | const dir, const sub_path = file.path.openInfo(zcu.comp.dirs); |
| 853 | var f = try file.mod.root.openFile(file.sub_file_path, .{}); | 993 | break :f try dir.openFile(sub_path, .{}); |
| 994 | }; | ||
| 854 | defer f.close(); | 995 | defer f.close(); |
| 855 | 996 | ||
| 856 | const stat = try f.stat(); | 997 | const stat = try f.stat(); |
| ... | @@ -882,28 +1023,14 @@ pub const File = struct { | ... | @@ -882,28 +1023,14 @@ pub const File = struct { |
| 882 | }; | 1023 | }; |
| 883 | } | 1024 | } |
| 884 | 1025 | ||
| 885 | pub fn getTree(file: *File, gpa: Allocator) !*const Ast { | 1026 | pub fn getTree(file: *File, zcu: *const Zcu) !*const Ast { |
| 886 | if (file.tree) |*tree| return tree; | 1027 | if (file.tree) |*tree| return tree; |
| 887 | 1028 | ||
| 888 | const source = try file.getSource(gpa); | 1029 | const source = try file.getSource(zcu); |
| 889 | file.tree = try .parse(gpa, source.bytes, file.getMode()); | 1030 | file.tree = try .parse(zcu.gpa, source.bytes, file.getMode()); |
| 890 | return &file.tree.?; | 1031 | return &file.tree.?; |
| 891 | } | 1032 | } |
| 892 | 1033 | ||
| 893 | pub fn getZoir(file: *File, zcu: *Zcu) !*const Zoir { | ||
| 894 | if (file.zoir) |*zoir| return zoir; | ||
| 895 | |||
| 896 | const tree = file.tree.?; | ||
| 897 | assert(tree.mode == .zon); | ||
| 898 | |||
| 899 | file.zoir = try ZonGen.generate(zcu.gpa, tree, .{}); | ||
| 900 | if (file.zoir.?.hasCompileErrors()) { | ||
| 901 | try zcu.failed_files.putNoClobber(zcu.gpa, file, null); | ||
| 902 | return error.AnalysisFail; | ||
| 903 | } | ||
| 904 | return &file.zoir.?; | ||
| 905 | } | ||
| 906 | |||
| 907 | pub fn fullyQualifiedNameLen(file: File) usize { | 1034 | pub fn fullyQualifiedNameLen(file: File) usize { |
| 908 | const ext = std.fs.path.extension(file.sub_file_path); | 1035 | const ext = std.fs.path.extension(file.sub_file_path); |
| 909 | return file.sub_file_path.len - ext.len; | 1036 | return file.sub_file_path.len - ext.len; |
| ... | @@ -937,85 +1064,49 @@ pub const File = struct { | ... | @@ -937,85 +1064,49 @@ pub const File = struct { |
| 937 | return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls); | 1064 | return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls); |
| 938 | } | 1065 | } |
| 939 | 1066 | ||
| 940 | pub fn fullPath(file: File, ally: Allocator) ![]u8 { | 1067 | pub const Index = InternPool.FileIndex; |
| 941 | return file.mod.root.joinString(ally, file.sub_file_path); | ||
| 942 | } | ||
| 943 | |||
| 944 | pub fn dumpSrc(file: *File, src: LazySrcLoc) void { | ||
| 945 | const loc = std.zig.findLineColumn(file.source.bytes, src); | ||
| 946 | std.debug.print("{s}:{d}:{d}\n", .{ file.sub_file_path, loc.line + 1, loc.column + 1 }); | ||
| 947 | } | ||
| 948 | |||
| 949 | /// Add a reference to this file during AstGen. | ||
| 950 | pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void { | ||
| 951 | // Don't add the same module root twice. Note that since we always add module roots at the | ||
| 952 | // front of the references array (see below), this loop is actually O(1) on valid code. | ||
| 953 | if (ref == .root) { | ||
| 954 | for (file.references.items) |other| { | ||
| 955 | switch (other) { | ||
| 956 | .root => |r| if (ref.root == r) return, | ||
| 957 | else => break, // reached the end of the "is-root" references | ||
| 958 | } | ||
| 959 | } | ||
| 960 | } | ||
| 961 | |||
| 962 | switch (ref) { | ||
| 963 | // We put root references at the front of the list both to make the above loop fast and | ||
| 964 | // to make multi-module errors more helpful (since "root-of" notes are generally more | ||
| 965 | // informative than "imported-from" notes). This path is hit very rarely, so the speed | ||
| 966 | // of the insert operation doesn't matter too much. | ||
| 967 | .root => try file.references.insert(zcu.gpa, 0, ref), | ||
| 968 | |||
| 969 | // Other references we'll just put at the end. | ||
| 970 | else => try file.references.append(zcu.gpa, ref), | ||
| 971 | } | ||
| 972 | 1068 | ||
| 973 | const mod = switch (ref) { | 1069 | pub fn errorBundleWholeFileSrc( |
| 974 | .import => |import| zcu.fileByIndex(import.file).mod, | 1070 | file: *File, |
| 975 | .root => |mod| mod, | 1071 | zcu: *const Zcu, |
| 976 | }; | 1072 | eb: *std.zig.ErrorBundle.Wip, |
| 977 | if (mod != file.mod) file.multi_pkg = true; | 1073 | ) !std.zig.ErrorBundle.SourceLocationIndex { |
| 1074 | return eb.addSourceLocation(.{ | ||
| 1075 | .src_path = try eb.printString("{}", .{file.path.fmt(zcu.comp)}), | ||
| 1076 | .span_start = 0, | ||
| 1077 | .span_main = 0, | ||
| 1078 | .span_end = 0, | ||
| 1079 | .line = 0, | ||
| 1080 | .column = 0, | ||
| 1081 | .source_line = 0, | ||
| 1082 | }); | ||
| 978 | } | 1083 | } |
| 979 | 1084 | pub fn errorBundleTokenSrc( | |
| 980 | /// Mark this file and every file referenced by it as multi_pkg and report an | 1085 | file: *File, |
| 981 | /// astgen_failure error for them. AstGen must have completed in its entirety. | 1086 | tok: Ast.TokenIndex, |
| 982 | pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void { | 1087 | zcu: *const Zcu, |
| 983 | file.multi_pkg = true; | 1088 | eb: *std.zig.ErrorBundle.Wip, |
| 984 | file.status = .astgen_failure; | 1089 | ) !std.zig.ErrorBundle.SourceLocationIndex { |
| 985 | 1090 | const source = try file.getSource(zcu); | |
| 986 | // We can only mark children as failed if the ZIR is loaded, which may not | 1091 | const tree = try file.getTree(zcu); |
| 987 | // be the case if there were other astgen failures in this file | 1092 | const start = tree.tokenStart(tok); |
| 988 | if (file.zir == null) return; | 1093 | const end = start + tree.tokenSlice(tok).len; |
| 989 | 1094 | const loc = std.zig.findLineColumn(source.bytes, start); | |
| 990 | const imports_index = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 1095 | return eb.addSourceLocation(.{ |
| 991 | if (imports_index == 0) return; | 1096 | .src_path = try eb.printString("{}", .{file.path.fmt(zcu.comp)}), |
| 992 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 1097 | .span_start = start, |
| 993 | 1098 | .span_main = start, | |
| 994 | var extra_index = extra.end; | 1099 | .span_end = @intCast(end), |
| 995 | for (0..extra.data.imports_len) |_| { | 1100 | .line = @intCast(loc.line), |
| 996 | const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index); | 1101 | .column = @intCast(loc.column), |
| 997 | extra_index = item.end; | 1102 | .source_line = try eb.addString(loc.source_line), |
| 998 | 1103 | }); | |
| 999 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | ||
| 1000 | if (mem.eql(u8, import_path, "builtin")) continue; | ||
| 1001 | |||
| 1002 | const res = pt.importFile(file, import_path) catch continue; | ||
| 1003 | if (!res.is_pkg and !res.file.multi_pkg) { | ||
| 1004 | res.file.recursiveMarkMultiPkg(pt); | ||
| 1005 | } | ||
| 1006 | } | ||
| 1007 | } | 1104 | } |
| 1008 | |||
| 1009 | pub const Index = InternPool.FileIndex; | ||
| 1010 | }; | 1105 | }; |
| 1011 | 1106 | ||
| 1012 | /// Represents the contents of a file loaded with `@embedFile`. | 1107 | /// Represents the contents of a file loaded with `@embedFile`. |
| 1013 | pub const EmbedFile = struct { | 1108 | pub const EmbedFile = struct { |
| 1014 | /// Module that this file is a part of, managed externally. | 1109 | path: Compilation.Path, |
| 1015 | owner: *Package.Module, | ||
| 1016 | /// Relative to the owning module's root directory. | ||
| 1017 | sub_file_path: InternPool.NullTerminatedString, | ||
| 1018 | |||
| 1019 | /// `.none` means the file was not loaded, so `stat` is undefined. | 1110 | /// `.none` means the file was not loaded, so `stat` is undefined. |
| 1020 | val: InternPool.Index, | 1111 | val: InternPool.Index, |
| 1021 | /// If this is `null` and `val` is `.none`, the file has never been loaded. | 1112 | /// If this is `null` and `val` is `.none`, the file has never been loaded. |
| ... | @@ -1025,7 +1116,7 @@ pub const EmbedFile = struct { | ... | @@ -1025,7 +1116,7 @@ pub const EmbedFile = struct { |
| 1025 | pub const Index = enum(u32) { | 1116 | pub const Index = enum(u32) { |
| 1026 | _, | 1117 | _, |
| 1027 | pub fn get(idx: Index, zcu: *const Zcu) *EmbedFile { | 1118 | pub fn get(idx: Index, zcu: *const Zcu) *EmbedFile { |
| 1028 | return zcu.embed_table.values()[@intFromEnum(idx)]; | 1119 | return zcu.embed_table.keys()[@intFromEnum(idx)]; |
| 1029 | } | 1120 | } |
| 1030 | }; | 1121 | }; |
| 1031 | }; | 1122 | }; |
| ... | @@ -1103,32 +1194,31 @@ pub const SrcLoc = struct { | ... | @@ -1103,32 +1194,31 @@ pub const SrcLoc = struct { |
| 1103 | 1194 | ||
| 1104 | pub const Span = Ast.Span; | 1195 | pub const Span = Ast.Span; |
| 1105 | 1196 | ||
| 1106 | pub fn span(src_loc: SrcLoc, gpa: Allocator) !Span { | 1197 | pub fn span(src_loc: SrcLoc, zcu: *const Zcu) !Span { |
| 1107 | switch (src_loc.lazy) { | 1198 | switch (src_loc.lazy) { |
| 1108 | .unneeded => unreachable, | 1199 | .unneeded => unreachable, |
| 1109 | .entire_file => return Span{ .start = 0, .end = 1, .main = 0 }, | ||
| 1110 | 1200 | ||
| 1111 | .byte_abs => |byte_index| return Span{ .start = byte_index, .end = byte_index + 1, .main = byte_index }, | 1201 | .byte_abs => |byte_index| return Span{ .start = byte_index, .end = byte_index + 1, .main = byte_index }, |
| 1112 | 1202 | ||
| 1113 | .token_abs => |tok_index| { | 1203 | .token_abs => |tok_index| { |
| 1114 | const tree = try src_loc.file_scope.getTree(gpa); | 1204 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1115 | const start = tree.tokenStart(tok_index); | 1205 | const start = tree.tokenStart(tok_index); |
| 1116 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1206 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1117 | return Span{ .start = start, .end = end, .main = start }; | 1207 | return Span{ .start = start, .end = end, .main = start }; |
| 1118 | }, | 1208 | }, |
| 1119 | .node_abs => |node| { | 1209 | .node_abs => |node| { |
| 1120 | const tree = try src_loc.file_scope.getTree(gpa); | 1210 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1121 | return tree.nodeToSpan(node); | 1211 | return tree.nodeToSpan(node); |
| 1122 | }, | 1212 | }, |
| 1123 | .byte_offset => |byte_off| { | 1213 | .byte_offset => |byte_off| { |
| 1124 | const tree = try src_loc.file_scope.getTree(gpa); | 1214 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1125 | const tok_index = src_loc.baseSrcToken(); | 1215 | const tok_index = src_loc.baseSrcToken(); |
| 1126 | const start = tree.tokenStart(tok_index) + byte_off; | 1216 | const start = tree.tokenStart(tok_index) + byte_off; |
| 1127 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1217 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| 1128 | return Span{ .start = start, .end = end, .main = start }; | 1218 | return Span{ .start = start, .end = end, .main = start }; |
| 1129 | }, | 1219 | }, |
| 1130 | .token_offset => |tok_off| { | 1220 | .token_offset => |tok_off| { |
| 1131 | const tree = try src_loc.file_scope.getTree(gpa); | 1221 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1132 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); | 1222 | const tok_index = tok_off.toAbsolute(src_loc.baseSrcToken()); |
| 1133 | const start = tree.tokenStart(tok_index); | 1223 | const start = tree.tokenStart(tok_index); |
| 1134 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); | 1224 | const end = start + @as(u32, @intCast(tree.tokenSlice(tok_index).len)); |
| ... | @@ -1136,23 +1226,23 @@ pub const SrcLoc = struct { | ... | @@ -1136,23 +1226,23 @@ pub const SrcLoc = struct { |
| 1136 | }, | 1226 | }, |
| 1137 | .node_offset => |traced_off| { | 1227 | .node_offset => |traced_off| { |
| 1138 | const node_off = traced_off.x; | 1228 | const node_off = traced_off.x; |
| 1139 | const tree = try src_loc.file_scope.getTree(gpa); | 1229 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1140 | const node = node_off.toAbsolute(src_loc.base_node); | 1230 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1141 | return tree.nodeToSpan(node); | 1231 | return tree.nodeToSpan(node); |
| 1142 | }, | 1232 | }, |
| 1143 | .node_offset_main_token => |node_off| { | 1233 | .node_offset_main_token => |node_off| { |
| 1144 | const tree = try src_loc.file_scope.getTree(gpa); | 1234 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1145 | const node = node_off.toAbsolute(src_loc.base_node); | 1235 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1146 | const main_token = tree.nodeMainToken(node); | 1236 | const main_token = tree.nodeMainToken(node); |
| 1147 | return tree.tokensToSpan(main_token, main_token, main_token); | 1237 | return tree.tokensToSpan(main_token, main_token, main_token); |
| 1148 | }, | 1238 | }, |
| 1149 | .node_offset_bin_op => |node_off| { | 1239 | .node_offset_bin_op => |node_off| { |
| 1150 | const tree = try src_loc.file_scope.getTree(gpa); | 1240 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1151 | const node = node_off.toAbsolute(src_loc.base_node); | 1241 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1152 | return tree.nodeToSpan(node); | 1242 | return tree.nodeToSpan(node); |
| 1153 | }, | 1243 | }, |
| 1154 | .node_offset_initializer => |node_off| { | 1244 | .node_offset_initializer => |node_off| { |
| 1155 | const tree = try src_loc.file_scope.getTree(gpa); | 1245 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1156 | const node = node_off.toAbsolute(src_loc.base_node); | 1246 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1157 | return tree.tokensToSpan( | 1247 | return tree.tokensToSpan( |
| 1158 | tree.firstToken(node) - 3, | 1248 | tree.firstToken(node) - 3, |
| ... | @@ -1161,7 +1251,7 @@ pub const SrcLoc = struct { | ... | @@ -1161,7 +1251,7 @@ pub const SrcLoc = struct { |
| 1161 | ); | 1251 | ); |
| 1162 | }, | 1252 | }, |
| 1163 | .node_offset_var_decl_ty => |node_off| { | 1253 | .node_offset_var_decl_ty => |node_off| { |
| 1164 | const tree = try src_loc.file_scope.getTree(gpa); | 1254 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1165 | const node = node_off.toAbsolute(src_loc.base_node); | 1255 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1166 | const full = switch (tree.nodeTag(node)) { | 1256 | const full = switch (tree.nodeTag(node)) { |
| 1167 | .global_var_decl, | 1257 | .global_var_decl, |
| ... | @@ -1183,7 +1273,7 @@ pub const SrcLoc = struct { | ... | @@ -1183,7 +1273,7 @@ pub const SrcLoc = struct { |
| 1183 | return Span{ .start = start, .end = end, .main = start }; | 1273 | return Span{ .start = start, .end = end, .main = start }; |
| 1184 | }, | 1274 | }, |
| 1185 | .node_offset_var_decl_align => |node_off| { | 1275 | .node_offset_var_decl_align => |node_off| { |
| 1186 | const tree = try src_loc.file_scope.getTree(gpa); | 1276 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1187 | const node = node_off.toAbsolute(src_loc.base_node); | 1277 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1188 | var buf: [1]Ast.Node.Index = undefined; | 1278 | var buf: [1]Ast.Node.Index = undefined; |
| 1189 | const align_node = if (tree.fullVarDecl(node)) |v| | 1279 | const align_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1195,7 +1285,7 @@ pub const SrcLoc = struct { | ... | @@ -1195,7 +1285,7 @@ pub const SrcLoc = struct { |
| 1195 | return tree.nodeToSpan(align_node); | 1285 | return tree.nodeToSpan(align_node); |
| 1196 | }, | 1286 | }, |
| 1197 | .node_offset_var_decl_section => |node_off| { | 1287 | .node_offset_var_decl_section => |node_off| { |
| 1198 | const tree = try src_loc.file_scope.getTree(gpa); | 1288 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1199 | const node = node_off.toAbsolute(src_loc.base_node); | 1289 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1200 | var buf: [1]Ast.Node.Index = undefined; | 1290 | var buf: [1]Ast.Node.Index = undefined; |
| 1201 | const section_node = if (tree.fullVarDecl(node)) |v| | 1291 | const section_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1207,7 +1297,7 @@ pub const SrcLoc = struct { | ... | @@ -1207,7 +1297,7 @@ pub const SrcLoc = struct { |
| 1207 | return tree.nodeToSpan(section_node); | 1297 | return tree.nodeToSpan(section_node); |
| 1208 | }, | 1298 | }, |
| 1209 | .node_offset_var_decl_addrspace => |node_off| { | 1299 | .node_offset_var_decl_addrspace => |node_off| { |
| 1210 | const tree = try src_loc.file_scope.getTree(gpa); | 1300 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1211 | const node = node_off.toAbsolute(src_loc.base_node); | 1301 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1212 | var buf: [1]Ast.Node.Index = undefined; | 1302 | var buf: [1]Ast.Node.Index = undefined; |
| 1213 | const addrspace_node = if (tree.fullVarDecl(node)) |v| | 1303 | const addrspace_node = if (tree.fullVarDecl(node)) |v| |
| ... | @@ -1219,7 +1309,7 @@ pub const SrcLoc = struct { | ... | @@ -1219,7 +1309,7 @@ pub const SrcLoc = struct { |
| 1219 | return tree.nodeToSpan(addrspace_node); | 1309 | return tree.nodeToSpan(addrspace_node); |
| 1220 | }, | 1310 | }, |
| 1221 | .node_offset_var_decl_init => |node_off| { | 1311 | .node_offset_var_decl_init => |node_off| { |
| 1222 | const tree = try src_loc.file_scope.getTree(gpa); | 1312 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1223 | const node = node_off.toAbsolute(src_loc.base_node); | 1313 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1224 | const init_node = switch (tree.nodeTag(node)) { | 1314 | const init_node = switch (tree.nodeTag(node)) { |
| 1225 | .global_var_decl, | 1315 | .global_var_decl, |
| ... | @@ -1233,14 +1323,14 @@ pub const SrcLoc = struct { | ... | @@ -1233,14 +1323,14 @@ pub const SrcLoc = struct { |
| 1233 | return tree.nodeToSpan(init_node); | 1323 | return tree.nodeToSpan(init_node); |
| 1234 | }, | 1324 | }, |
| 1235 | .node_offset_builtin_call_arg => |builtin_arg| { | 1325 | .node_offset_builtin_call_arg => |builtin_arg| { |
| 1236 | const tree = try src_loc.file_scope.getTree(gpa); | 1326 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1237 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); | 1327 | const node = builtin_arg.builtin_call_node.toAbsolute(src_loc.base_node); |
| 1238 | var buf: [2]Ast.Node.Index = undefined; | 1328 | var buf: [2]Ast.Node.Index = undefined; |
| 1239 | const params = tree.builtinCallParams(&buf, node).?; | 1329 | const params = tree.builtinCallParams(&buf, node).?; |
| 1240 | return tree.nodeToSpan(params[builtin_arg.arg_index]); | 1330 | return tree.nodeToSpan(params[builtin_arg.arg_index]); |
| 1241 | }, | 1331 | }, |
| 1242 | .node_offset_ptrcast_operand => |node_off| { | 1332 | .node_offset_ptrcast_operand => |node_off| { |
| 1243 | const tree = try src_loc.file_scope.getTree(gpa); | 1333 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1244 | 1334 | ||
| 1245 | var node = node_off.toAbsolute(src_loc.base_node); | 1335 | var node = node_off.toAbsolute(src_loc.base_node); |
| 1246 | while (true) { | 1336 | while (true) { |
| ... | @@ -1273,7 +1363,7 @@ pub const SrcLoc = struct { | ... | @@ -1273,7 +1363,7 @@ pub const SrcLoc = struct { |
| 1273 | return tree.nodeToSpan(node); | 1363 | return tree.nodeToSpan(node); |
| 1274 | }, | 1364 | }, |
| 1275 | .node_offset_array_access_index => |node_off| { | 1365 | .node_offset_array_access_index => |node_off| { |
| 1276 | const tree = try src_loc.file_scope.getTree(gpa); | 1366 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1277 | const node = node_off.toAbsolute(src_loc.base_node); | 1367 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1278 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); | 1368 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1279 | }, | 1369 | }, |
| ... | @@ -1282,7 +1372,7 @@ pub const SrcLoc = struct { | ... | @@ -1282,7 +1372,7 @@ pub const SrcLoc = struct { |
| 1282 | .node_offset_slice_end, | 1372 | .node_offset_slice_end, |
| 1283 | .node_offset_slice_sentinel, | 1373 | .node_offset_slice_sentinel, |
| 1284 | => |node_off| { | 1374 | => |node_off| { |
| 1285 | const tree = try src_loc.file_scope.getTree(gpa); | 1375 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1286 | const node = node_off.toAbsolute(src_loc.base_node); | 1376 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1287 | const full = tree.fullSlice(node).?; | 1377 | const full = tree.fullSlice(node).?; |
| 1288 | const part_node = switch (src_loc.lazy) { | 1378 | const part_node = switch (src_loc.lazy) { |
| ... | @@ -1295,14 +1385,14 @@ pub const SrcLoc = struct { | ... | @@ -1295,14 +1385,14 @@ pub const SrcLoc = struct { |
| 1295 | return tree.nodeToSpan(part_node); | 1385 | return tree.nodeToSpan(part_node); |
| 1296 | }, | 1386 | }, |
| 1297 | .node_offset_call_func => |node_off| { | 1387 | .node_offset_call_func => |node_off| { |
| 1298 | const tree = try src_loc.file_scope.getTree(gpa); | 1388 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1299 | const node = node_off.toAbsolute(src_loc.base_node); | 1389 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1300 | var buf: [1]Ast.Node.Index = undefined; | 1390 | var buf: [1]Ast.Node.Index = undefined; |
| 1301 | const full = tree.fullCall(&buf, node).?; | 1391 | const full = tree.fullCall(&buf, node).?; |
| 1302 | return tree.nodeToSpan(full.ast.fn_expr); | 1392 | return tree.nodeToSpan(full.ast.fn_expr); |
| 1303 | }, | 1393 | }, |
| 1304 | .node_offset_field_name => |node_off| { | 1394 | .node_offset_field_name => |node_off| { |
| 1305 | const tree = try src_loc.file_scope.getTree(gpa); | 1395 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1306 | const node = node_off.toAbsolute(src_loc.base_node); | 1396 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1307 | var buf: [1]Ast.Node.Index = undefined; | 1397 | var buf: [1]Ast.Node.Index = undefined; |
| 1308 | const tok_index = switch (tree.nodeTag(node)) { | 1398 | const tok_index = switch (tree.nodeTag(node)) { |
| ... | @@ -1326,7 +1416,7 @@ pub const SrcLoc = struct { | ... | @@ -1326,7 +1416,7 @@ pub const SrcLoc = struct { |
| 1326 | return Span{ .start = start, .end = end, .main = start }; | 1416 | return Span{ .start = start, .end = end, .main = start }; |
| 1327 | }, | 1417 | }, |
| 1328 | .node_offset_field_name_init => |node_off| { | 1418 | .node_offset_field_name_init => |node_off| { |
| 1329 | const tree = try src_loc.file_scope.getTree(gpa); | 1419 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1330 | const node = node_off.toAbsolute(src_loc.base_node); | 1420 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1331 | const tok_index = tree.firstToken(node) - 2; | 1421 | const tok_index = tree.firstToken(node) - 2; |
| 1332 | const start = tree.tokenStart(tok_index); | 1422 | const start = tree.tokenStart(tok_index); |
| ... | @@ -1334,18 +1424,18 @@ pub const SrcLoc = struct { | ... | @@ -1334,18 +1424,18 @@ pub const SrcLoc = struct { |
| 1334 | return Span{ .start = start, .end = end, .main = start }; | 1424 | return Span{ .start = start, .end = end, .main = start }; |
| 1335 | }, | 1425 | }, |
| 1336 | .node_offset_deref_ptr => |node_off| { | 1426 | .node_offset_deref_ptr => |node_off| { |
| 1337 | const tree = try src_loc.file_scope.getTree(gpa); | 1427 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1338 | const node = node_off.toAbsolute(src_loc.base_node); | 1428 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1339 | return tree.nodeToSpan(node); | 1429 | return tree.nodeToSpan(node); |
| 1340 | }, | 1430 | }, |
| 1341 | .node_offset_asm_source => |node_off| { | 1431 | .node_offset_asm_source => |node_off| { |
| 1342 | const tree = try src_loc.file_scope.getTree(gpa); | 1432 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1343 | const node = node_off.toAbsolute(src_loc.base_node); | 1433 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1344 | const full = tree.fullAsm(node).?; | 1434 | const full = tree.fullAsm(node).?; |
| 1345 | return tree.nodeToSpan(full.ast.template); | 1435 | return tree.nodeToSpan(full.ast.template); |
| 1346 | }, | 1436 | }, |
| 1347 | .node_offset_asm_ret_ty => |node_off| { | 1437 | .node_offset_asm_ret_ty => |node_off| { |
| 1348 | const tree = try src_loc.file_scope.getTree(gpa); | 1438 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1349 | const node = node_off.toAbsolute(src_loc.base_node); | 1439 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1350 | const full = tree.fullAsm(node).?; | 1440 | const full = tree.fullAsm(node).?; |
| 1351 | const asm_output = full.outputs[0]; | 1441 | const asm_output = full.outputs[0]; |
| ... | @@ -1353,7 +1443,7 @@ pub const SrcLoc = struct { | ... | @@ -1353,7 +1443,7 @@ pub const SrcLoc = struct { |
| 1353 | }, | 1443 | }, |
| 1354 | 1444 | ||
| 1355 | .node_offset_if_cond => |node_off| { | 1445 | .node_offset_if_cond => |node_off| { |
| 1356 | const tree = try src_loc.file_scope.getTree(gpa); | 1446 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1357 | const node = node_off.toAbsolute(src_loc.base_node); | 1447 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1358 | const src_node = switch (tree.nodeTag(node)) { | 1448 | const src_node = switch (tree.nodeTag(node)) { |
| 1359 | .if_simple, | 1449 | .if_simple, |
| ... | @@ -1381,14 +1471,14 @@ pub const SrcLoc = struct { | ... | @@ -1381,14 +1471,14 @@ pub const SrcLoc = struct { |
| 1381 | return tree.nodeToSpan(src_node); | 1471 | return tree.nodeToSpan(src_node); |
| 1382 | }, | 1472 | }, |
| 1383 | .for_input => |for_input| { | 1473 | .for_input => |for_input| { |
| 1384 | const tree = try src_loc.file_scope.getTree(gpa); | 1474 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1385 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); | 1475 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); |
| 1386 | const for_full = tree.fullFor(node).?; | 1476 | const for_full = tree.fullFor(node).?; |
| 1387 | const src_node = for_full.ast.inputs[for_input.input_index]; | 1477 | const src_node = for_full.ast.inputs[for_input.input_index]; |
| 1388 | return tree.nodeToSpan(src_node); | 1478 | return tree.nodeToSpan(src_node); |
| 1389 | }, | 1479 | }, |
| 1390 | .for_capture_from_input => |node_off| { | 1480 | .for_capture_from_input => |node_off| { |
| 1391 | const tree = try src_loc.file_scope.getTree(gpa); | 1481 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1392 | const input_node = node_off.toAbsolute(src_loc.base_node); | 1482 | const input_node = node_off.toAbsolute(src_loc.base_node); |
| 1393 | // We have to actually linear scan the whole AST to find the for loop | 1483 | // We have to actually linear scan the whole AST to find the for loop |
| 1394 | // that contains this input. | 1484 | // that contains this input. |
| ... | @@ -1429,7 +1519,7 @@ pub const SrcLoc = struct { | ... | @@ -1429,7 +1519,7 @@ pub const SrcLoc = struct { |
| 1429 | } else unreachable; | 1519 | } else unreachable; |
| 1430 | }, | 1520 | }, |
| 1431 | .call_arg => |call_arg| { | 1521 | .call_arg => |call_arg| { |
| 1432 | const tree = try src_loc.file_scope.getTree(gpa); | 1522 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1433 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); | 1523 | const node = call_arg.call_node_offset.toAbsolute(src_loc.base_node); |
| 1434 | var buf: [2]Ast.Node.Index = undefined; | 1524 | var buf: [2]Ast.Node.Index = undefined; |
| 1435 | const call_full = tree.fullCall(buf[0..1], node) orelse { | 1525 | const call_full = tree.fullCall(buf[0..1], node) orelse { |
| ... | @@ -1466,7 +1556,7 @@ pub const SrcLoc = struct { | ... | @@ -1466,7 +1556,7 @@ pub const SrcLoc = struct { |
| 1466 | return tree.nodeToSpan(call_full.ast.params[call_arg.arg_index]); | 1556 | return tree.nodeToSpan(call_full.ast.params[call_arg.arg_index]); |
| 1467 | }, | 1557 | }, |
| 1468 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { | 1558 | .fn_proto_param, .fn_proto_param_type => |fn_proto_param| { |
| 1469 | const tree = try src_loc.file_scope.getTree(gpa); | 1559 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1470 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); | 1560 | const node = fn_proto_param.fn_proto_node_offset.toAbsolute(src_loc.base_node); |
| 1471 | var buf: [1]Ast.Node.Index = undefined; | 1561 | var buf: [1]Ast.Node.Index = undefined; |
| 1472 | const full = tree.fullFnProto(&buf, node).?; | 1562 | const full = tree.fullFnProto(&buf, node).?; |
| ... | @@ -1494,17 +1584,17 @@ pub const SrcLoc = struct { | ... | @@ -1494,17 +1584,17 @@ pub const SrcLoc = struct { |
| 1494 | unreachable; | 1584 | unreachable; |
| 1495 | }, | 1585 | }, |
| 1496 | .node_offset_bin_lhs => |node_off| { | 1586 | .node_offset_bin_lhs => |node_off| { |
| 1497 | const tree = try src_loc.file_scope.getTree(gpa); | 1587 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1498 | const node = node_off.toAbsolute(src_loc.base_node); | 1588 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1499 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); | 1589 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[0]); |
| 1500 | }, | 1590 | }, |
| 1501 | .node_offset_bin_rhs => |node_off| { | 1591 | .node_offset_bin_rhs => |node_off| { |
| 1502 | const tree = try src_loc.file_scope.getTree(gpa); | 1592 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1503 | const node = node_off.toAbsolute(src_loc.base_node); | 1593 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1504 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); | 1594 | return tree.nodeToSpan(tree.nodeData(node).node_and_node[1]); |
| 1505 | }, | 1595 | }, |
| 1506 | .array_cat_lhs, .array_cat_rhs => |cat| { | 1596 | .array_cat_lhs, .array_cat_rhs => |cat| { |
| 1507 | const tree = try src_loc.file_scope.getTree(gpa); | 1597 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1508 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); | 1598 | const node = cat.array_cat_offset.toAbsolute(src_loc.base_node); |
| 1509 | const arr_node = if (src_loc.lazy == .array_cat_lhs) | 1599 | const arr_node = if (src_loc.lazy == .array_cat_lhs) |
| 1510 | tree.nodeData(node).node_and_node[0] | 1600 | tree.nodeData(node).node_and_node[0] |
| ... | @@ -1530,20 +1620,20 @@ pub const SrcLoc = struct { | ... | @@ -1530,20 +1620,20 @@ pub const SrcLoc = struct { |
| 1530 | }, | 1620 | }, |
| 1531 | 1621 | ||
| 1532 | .node_offset_try_operand => |node_off| { | 1622 | .node_offset_try_operand => |node_off| { |
| 1533 | const tree = try src_loc.file_scope.getTree(gpa); | 1623 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1534 | const node = node_off.toAbsolute(src_loc.base_node); | 1624 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1535 | return tree.nodeToSpan(tree.nodeData(node).node); | 1625 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1536 | }, | 1626 | }, |
| 1537 | 1627 | ||
| 1538 | .node_offset_switch_operand => |node_off| { | 1628 | .node_offset_switch_operand => |node_off| { |
| 1539 | const tree = try src_loc.file_scope.getTree(gpa); | 1629 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1540 | const node = node_off.toAbsolute(src_loc.base_node); | 1630 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1541 | const condition, _ = tree.nodeData(node).node_and_extra; | 1631 | const condition, _ = tree.nodeData(node).node_and_extra; |
| 1542 | return tree.nodeToSpan(condition); | 1632 | return tree.nodeToSpan(condition); |
| 1543 | }, | 1633 | }, |
| 1544 | 1634 | ||
| 1545 | .node_offset_switch_special_prong => |node_off| { | 1635 | .node_offset_switch_special_prong => |node_off| { |
| 1546 | const tree = try src_loc.file_scope.getTree(gpa); | 1636 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1547 | const switch_node = node_off.toAbsolute(src_loc.base_node); | 1637 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1548 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 1638 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1549 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 1639 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -1560,7 +1650,7 @@ pub const SrcLoc = struct { | ... | @@ -1560,7 +1650,7 @@ pub const SrcLoc = struct { |
| 1560 | }, | 1650 | }, |
| 1561 | 1651 | ||
| 1562 | .node_offset_switch_range => |node_off| { | 1652 | .node_offset_switch_range => |node_off| { |
| 1563 | const tree = try src_loc.file_scope.getTree(gpa); | 1653 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1564 | const switch_node = node_off.toAbsolute(src_loc.base_node); | 1654 | const switch_node = node_off.toAbsolute(src_loc.base_node); |
| 1565 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 1655 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1566 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 1656 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -1580,28 +1670,28 @@ pub const SrcLoc = struct { | ... | @@ -1580,28 +1670,28 @@ pub const SrcLoc = struct { |
| 1580 | } else unreachable; | 1670 | } else unreachable; |
| 1581 | }, | 1671 | }, |
| 1582 | .node_offset_fn_type_align => |node_off| { | 1672 | .node_offset_fn_type_align => |node_off| { |
| 1583 | const tree = try src_loc.file_scope.getTree(gpa); | 1673 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1584 | const node = node_off.toAbsolute(src_loc.base_node); | 1674 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1585 | var buf: [1]Ast.Node.Index = undefined; | 1675 | var buf: [1]Ast.Node.Index = undefined; |
| 1586 | const full = tree.fullFnProto(&buf, node).?; | 1676 | const full = tree.fullFnProto(&buf, node).?; |
| 1587 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); | 1677 | return tree.nodeToSpan(full.ast.align_expr.unwrap().?); |
| 1588 | }, | 1678 | }, |
| 1589 | .node_offset_fn_type_addrspace => |node_off| { | 1679 | .node_offset_fn_type_addrspace => |node_off| { |
| 1590 | const tree = try src_loc.file_scope.getTree(gpa); | 1680 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1591 | const node = node_off.toAbsolute(src_loc.base_node); | 1681 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1592 | var buf: [1]Ast.Node.Index = undefined; | 1682 | var buf: [1]Ast.Node.Index = undefined; |
| 1593 | const full = tree.fullFnProto(&buf, node).?; | 1683 | const full = tree.fullFnProto(&buf, node).?; |
| 1594 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); | 1684 | return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?); |
| 1595 | }, | 1685 | }, |
| 1596 | .node_offset_fn_type_section => |node_off| { | 1686 | .node_offset_fn_type_section => |node_off| { |
| 1597 | const tree = try src_loc.file_scope.getTree(gpa); | 1687 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1598 | const node = node_off.toAbsolute(src_loc.base_node); | 1688 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1599 | var buf: [1]Ast.Node.Index = undefined; | 1689 | var buf: [1]Ast.Node.Index = undefined; |
| 1600 | const full = tree.fullFnProto(&buf, node).?; | 1690 | const full = tree.fullFnProto(&buf, node).?; |
| 1601 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); | 1691 | return tree.nodeToSpan(full.ast.section_expr.unwrap().?); |
| 1602 | }, | 1692 | }, |
| 1603 | .node_offset_fn_type_cc => |node_off| { | 1693 | .node_offset_fn_type_cc => |node_off| { |
| 1604 | const tree = try src_loc.file_scope.getTree(gpa); | 1694 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1605 | const node = node_off.toAbsolute(src_loc.base_node); | 1695 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1606 | var buf: [1]Ast.Node.Index = undefined; | 1696 | var buf: [1]Ast.Node.Index = undefined; |
| 1607 | const full = tree.fullFnProto(&buf, node).?; | 1697 | const full = tree.fullFnProto(&buf, node).?; |
| ... | @@ -1609,14 +1699,14 @@ pub const SrcLoc = struct { | ... | @@ -1609,14 +1699,14 @@ pub const SrcLoc = struct { |
| 1609 | }, | 1699 | }, |
| 1610 | 1700 | ||
| 1611 | .node_offset_fn_type_ret_ty => |node_off| { | 1701 | .node_offset_fn_type_ret_ty => |node_off| { |
| 1612 | const tree = try src_loc.file_scope.getTree(gpa); | 1702 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1613 | const node = node_off.toAbsolute(src_loc.base_node); | 1703 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1614 | var buf: [1]Ast.Node.Index = undefined; | 1704 | var buf: [1]Ast.Node.Index = undefined; |
| 1615 | const full = tree.fullFnProto(&buf, node).?; | 1705 | const full = tree.fullFnProto(&buf, node).?; |
| 1616 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); | 1706 | return tree.nodeToSpan(full.ast.return_type.unwrap().?); |
| 1617 | }, | 1707 | }, |
| 1618 | .node_offset_param => |node_off| { | 1708 | .node_offset_param => |node_off| { |
| 1619 | const tree = try src_loc.file_scope.getTree(gpa); | 1709 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1620 | const node = node_off.toAbsolute(src_loc.base_node); | 1710 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1621 | 1711 | ||
| 1622 | var first_tok = tree.firstToken(node); | 1712 | var first_tok = tree.firstToken(node); |
| ... | @@ -1631,7 +1721,7 @@ pub const SrcLoc = struct { | ... | @@ -1631,7 +1721,7 @@ pub const SrcLoc = struct { |
| 1631 | ); | 1721 | ); |
| 1632 | }, | 1722 | }, |
| 1633 | .token_offset_param => |token_off| { | 1723 | .token_offset_param => |token_off| { |
| 1634 | const tree = try src_loc.file_scope.getTree(gpa); | 1724 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1635 | const main_token = tree.nodeMainToken(src_loc.base_node); | 1725 | const main_token = tree.nodeMainToken(src_loc.base_node); |
| 1636 | const tok_index = token_off.toAbsolute(main_token); | 1726 | const tok_index = token_off.toAbsolute(main_token); |
| 1637 | 1727 | ||
| ... | @@ -1648,14 +1738,14 @@ pub const SrcLoc = struct { | ... | @@ -1648,14 +1738,14 @@ pub const SrcLoc = struct { |
| 1648 | }, | 1738 | }, |
| 1649 | 1739 | ||
| 1650 | .node_offset_anyframe_type => |node_off| { | 1740 | .node_offset_anyframe_type => |node_off| { |
| 1651 | const tree = try src_loc.file_scope.getTree(gpa); | 1741 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1652 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1742 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1653 | _, const child_type = tree.nodeData(parent_node).token_and_node; | 1743 | _, const child_type = tree.nodeData(parent_node).token_and_node; |
| 1654 | return tree.nodeToSpan(child_type); | 1744 | return tree.nodeToSpan(child_type); |
| 1655 | }, | 1745 | }, |
| 1656 | 1746 | ||
| 1657 | .node_offset_lib_name => |node_off| { | 1747 | .node_offset_lib_name => |node_off| { |
| 1658 | const tree = try src_loc.file_scope.getTree(gpa); | 1748 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1659 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1749 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1660 | var buf: [1]Ast.Node.Index = undefined; | 1750 | var buf: [1]Ast.Node.Index = undefined; |
| 1661 | const full = tree.fullFnProto(&buf, parent_node).?; | 1751 | const full = tree.fullFnProto(&buf, parent_node).?; |
| ... | @@ -1666,75 +1756,75 @@ pub const SrcLoc = struct { | ... | @@ -1666,75 +1756,75 @@ pub const SrcLoc = struct { |
| 1666 | }, | 1756 | }, |
| 1667 | 1757 | ||
| 1668 | .node_offset_array_type_len => |node_off| { | 1758 | .node_offset_array_type_len => |node_off| { |
| 1669 | const tree = try src_loc.file_scope.getTree(gpa); | 1759 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1670 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1760 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1671 | 1761 | ||
| 1672 | const full = tree.fullArrayType(parent_node).?; | 1762 | const full = tree.fullArrayType(parent_node).?; |
| 1673 | return tree.nodeToSpan(full.ast.elem_count); | 1763 | return tree.nodeToSpan(full.ast.elem_count); |
| 1674 | }, | 1764 | }, |
| 1675 | .node_offset_array_type_sentinel => |node_off| { | 1765 | .node_offset_array_type_sentinel => |node_off| { |
| 1676 | const tree = try src_loc.file_scope.getTree(gpa); | 1766 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1677 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1767 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1678 | 1768 | ||
| 1679 | const full = tree.fullArrayType(parent_node).?; | 1769 | const full = tree.fullArrayType(parent_node).?; |
| 1680 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); | 1770 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1681 | }, | 1771 | }, |
| 1682 | .node_offset_array_type_elem => |node_off| { | 1772 | .node_offset_array_type_elem => |node_off| { |
| 1683 | const tree = try src_loc.file_scope.getTree(gpa); | 1773 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1684 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1774 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1685 | 1775 | ||
| 1686 | const full = tree.fullArrayType(parent_node).?; | 1776 | const full = tree.fullArrayType(parent_node).?; |
| 1687 | return tree.nodeToSpan(full.ast.elem_type); | 1777 | return tree.nodeToSpan(full.ast.elem_type); |
| 1688 | }, | 1778 | }, |
| 1689 | .node_offset_un_op => |node_off| { | 1779 | .node_offset_un_op => |node_off| { |
| 1690 | const tree = try src_loc.file_scope.getTree(gpa); | 1780 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1691 | const node = node_off.toAbsolute(src_loc.base_node); | 1781 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1692 | return tree.nodeToSpan(tree.nodeData(node).node); | 1782 | return tree.nodeToSpan(tree.nodeData(node).node); |
| 1693 | }, | 1783 | }, |
| 1694 | .node_offset_ptr_elem => |node_off| { | 1784 | .node_offset_ptr_elem => |node_off| { |
| 1695 | const tree = try src_loc.file_scope.getTree(gpa); | 1785 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1696 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1786 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1697 | 1787 | ||
| 1698 | const full = tree.fullPtrType(parent_node).?; | 1788 | const full = tree.fullPtrType(parent_node).?; |
| 1699 | return tree.nodeToSpan(full.ast.child_type); | 1789 | return tree.nodeToSpan(full.ast.child_type); |
| 1700 | }, | 1790 | }, |
| 1701 | .node_offset_ptr_sentinel => |node_off| { | 1791 | .node_offset_ptr_sentinel => |node_off| { |
| 1702 | const tree = try src_loc.file_scope.getTree(gpa); | 1792 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1703 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1793 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1704 | 1794 | ||
| 1705 | const full = tree.fullPtrType(parent_node).?; | 1795 | const full = tree.fullPtrType(parent_node).?; |
| 1706 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); | 1796 | return tree.nodeToSpan(full.ast.sentinel.unwrap().?); |
| 1707 | }, | 1797 | }, |
| 1708 | .node_offset_ptr_align => |node_off| { | 1798 | .node_offset_ptr_align => |node_off| { |
| 1709 | const tree = try src_loc.file_scope.getTree(gpa); | 1799 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1710 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1800 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1711 | 1801 | ||
| 1712 | const full = tree.fullPtrType(parent_node).?; | 1802 | const full = tree.fullPtrType(parent_node).?; |
| 1713 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); | 1803 | return tree.nodeToSpan(full.ast.align_node.unwrap().?); |
| 1714 | }, | 1804 | }, |
| 1715 | .node_offset_ptr_addrspace => |node_off| { | 1805 | .node_offset_ptr_addrspace => |node_off| { |
| 1716 | const tree = try src_loc.file_scope.getTree(gpa); | 1806 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1717 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1807 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1718 | 1808 | ||
| 1719 | const full = tree.fullPtrType(parent_node).?; | 1809 | const full = tree.fullPtrType(parent_node).?; |
| 1720 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); | 1810 | return tree.nodeToSpan(full.ast.addrspace_node.unwrap().?); |
| 1721 | }, | 1811 | }, |
| 1722 | .node_offset_ptr_bitoffset => |node_off| { | 1812 | .node_offset_ptr_bitoffset => |node_off| { |
| 1723 | const tree = try src_loc.file_scope.getTree(gpa); | 1813 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1724 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1814 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1725 | 1815 | ||
| 1726 | const full = tree.fullPtrType(parent_node).?; | 1816 | const full = tree.fullPtrType(parent_node).?; |
| 1727 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); | 1817 | return tree.nodeToSpan(full.ast.bit_range_start.unwrap().?); |
| 1728 | }, | 1818 | }, |
| 1729 | .node_offset_ptr_hostsize => |node_off| { | 1819 | .node_offset_ptr_hostsize => |node_off| { |
| 1730 | const tree = try src_loc.file_scope.getTree(gpa); | 1820 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1731 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1821 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1732 | 1822 | ||
| 1733 | const full = tree.fullPtrType(parent_node).?; | 1823 | const full = tree.fullPtrType(parent_node).?; |
| 1734 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); | 1824 | return tree.nodeToSpan(full.ast.bit_range_end.unwrap().?); |
| 1735 | }, | 1825 | }, |
| 1736 | .node_offset_container_tag => |node_off| { | 1826 | .node_offset_container_tag => |node_off| { |
| 1737 | const tree = try src_loc.file_scope.getTree(gpa); | 1827 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1738 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1828 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1739 | 1829 | ||
| 1740 | switch (tree.nodeTag(parent_node)) { | 1830 | switch (tree.nodeTag(parent_node)) { |
| ... | @@ -1757,7 +1847,7 @@ pub const SrcLoc = struct { | ... | @@ -1757,7 +1847,7 @@ pub const SrcLoc = struct { |
| 1757 | } | 1847 | } |
| 1758 | }, | 1848 | }, |
| 1759 | .node_offset_field_default => |node_off| { | 1849 | .node_offset_field_default => |node_off| { |
| 1760 | const tree = try src_loc.file_scope.getTree(gpa); | 1850 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1761 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1851 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1762 | 1852 | ||
| 1763 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { | 1853 | const full: Ast.full.ContainerField = switch (tree.nodeTag(parent_node)) { |
| ... | @@ -1768,7 +1858,7 @@ pub const SrcLoc = struct { | ... | @@ -1768,7 +1858,7 @@ pub const SrcLoc = struct { |
| 1768 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); | 1858 | return tree.nodeToSpan(full.ast.value_expr.unwrap().?); |
| 1769 | }, | 1859 | }, |
| 1770 | .node_offset_init_ty => |node_off| { | 1860 | .node_offset_init_ty => |node_off| { |
| 1771 | const tree = try src_loc.file_scope.getTree(gpa); | 1861 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1772 | const parent_node = node_off.toAbsolute(src_loc.base_node); | 1862 | const parent_node = node_off.toAbsolute(src_loc.base_node); |
| 1773 | 1863 | ||
| 1774 | var buf: [2]Ast.Node.Index = undefined; | 1864 | var buf: [2]Ast.Node.Index = undefined; |
| ... | @@ -1779,7 +1869,7 @@ pub const SrcLoc = struct { | ... | @@ -1779,7 +1869,7 @@ pub const SrcLoc = struct { |
| 1779 | return tree.nodeToSpan(type_expr); | 1869 | return tree.nodeToSpan(type_expr); |
| 1780 | }, | 1870 | }, |
| 1781 | .node_offset_store_ptr => |node_off| { | 1871 | .node_offset_store_ptr => |node_off| { |
| 1782 | const tree = try src_loc.file_scope.getTree(gpa); | 1872 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1783 | const node = node_off.toAbsolute(src_loc.base_node); | 1873 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1784 | 1874 | ||
| 1785 | switch (tree.nodeTag(node)) { | 1875 | switch (tree.nodeTag(node)) { |
| ... | @@ -1806,7 +1896,7 @@ pub const SrcLoc = struct { | ... | @@ -1806,7 +1896,7 @@ pub const SrcLoc = struct { |
| 1806 | } | 1896 | } |
| 1807 | }, | 1897 | }, |
| 1808 | .node_offset_store_operand => |node_off| { | 1898 | .node_offset_store_operand => |node_off| { |
| 1809 | const tree = try src_loc.file_scope.getTree(gpa); | 1899 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1810 | const node = node_off.toAbsolute(src_loc.base_node); | 1900 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1811 | 1901 | ||
| 1812 | switch (tree.nodeTag(node)) { | 1902 | switch (tree.nodeTag(node)) { |
| ... | @@ -1833,7 +1923,7 @@ pub const SrcLoc = struct { | ... | @@ -1833,7 +1923,7 @@ pub const SrcLoc = struct { |
| 1833 | } | 1923 | } |
| 1834 | }, | 1924 | }, |
| 1835 | .node_offset_return_operand => |node_off| { | 1925 | .node_offset_return_operand => |node_off| { |
| 1836 | const tree = try src_loc.file_scope.getTree(gpa); | 1926 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1837 | const node = node_off.toAbsolute(src_loc.base_node); | 1927 | const node = node_off.toAbsolute(src_loc.base_node); |
| 1838 | if (tree.nodeTag(node) == .@"return") { | 1928 | if (tree.nodeTag(node) == .@"return") { |
| 1839 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { | 1929 | if (tree.nodeData(node).opt_node.unwrap()) |lhs| { |
| ... | @@ -1847,7 +1937,7 @@ pub const SrcLoc = struct { | ... | @@ -1847,7 +1937,7 @@ pub const SrcLoc = struct { |
| 1847 | .container_field_type, | 1937 | .container_field_type, |
| 1848 | .container_field_align, | 1938 | .container_field_align, |
| 1849 | => |field_idx| { | 1939 | => |field_idx| { |
| 1850 | const tree = try src_loc.file_scope.getTree(gpa); | 1940 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1851 | const node = src_loc.base_node; | 1941 | const node = src_loc.base_node; |
| 1852 | var buf: [2]Ast.Node.Index = undefined; | 1942 | var buf: [2]Ast.Node.Index = undefined; |
| 1853 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1943 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| ... | @@ -1875,7 +1965,7 @@ pub const SrcLoc = struct { | ... | @@ -1875,7 +1965,7 @@ pub const SrcLoc = struct { |
| 1875 | } else unreachable; | 1965 | } else unreachable; |
| 1876 | }, | 1966 | }, |
| 1877 | .tuple_field_type, .tuple_field_init => |field_info| { | 1967 | .tuple_field_type, .tuple_field_init => |field_info| { |
| 1878 | const tree = try src_loc.file_scope.getTree(gpa); | 1968 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1879 | const node = src_loc.base_node; | 1969 | const node = src_loc.base_node; |
| 1880 | var buf: [2]Ast.Node.Index = undefined; | 1970 | var buf: [2]Ast.Node.Index = undefined; |
| 1881 | const container_decl = tree.fullContainerDecl(&buf, node) orelse | 1971 | const container_decl = tree.fullContainerDecl(&buf, node) orelse |
| ... | @@ -1889,7 +1979,7 @@ pub const SrcLoc = struct { | ... | @@ -1889,7 +1979,7 @@ pub const SrcLoc = struct { |
| 1889 | }); | 1979 | }); |
| 1890 | }, | 1980 | }, |
| 1891 | .init_elem => |init_elem| { | 1981 | .init_elem => |init_elem| { |
| 1892 | const tree = try src_loc.file_scope.getTree(gpa); | 1982 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1893 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); | 1983 | const init_node = init_elem.init_node_offset.toAbsolute(src_loc.base_node); |
| 1894 | var buf: [2]Ast.Node.Index = undefined; | 1984 | var buf: [2]Ast.Node.Index = undefined; |
| 1895 | if (tree.fullArrayInit(&buf, init_node)) |full| { | 1985 | if (tree.fullArrayInit(&buf, init_node)) |full| { |
| ... | @@ -1928,7 +2018,7 @@ pub const SrcLoc = struct { | ... | @@ -1928,7 +2018,7 @@ pub const SrcLoc = struct { |
| 1928 | .init_field_dll_import => "dll_import", | 2018 | .init_field_dll_import => "dll_import", |
| 1929 | else => unreachable, | 2019 | else => unreachable, |
| 1930 | }; | 2020 | }; |
| 1931 | const tree = try src_loc.file_scope.getTree(gpa); | 2021 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1932 | const node = builtin_call_node.toAbsolute(src_loc.base_node); | 2022 | const node = builtin_call_node.toAbsolute(src_loc.base_node); |
| 1933 | var builtin_buf: [2]Ast.Node.Index = undefined; | 2023 | var builtin_buf: [2]Ast.Node.Index = undefined; |
| 1934 | const args = tree.builtinCallParams(&builtin_buf, node).?; | 2024 | const args = tree.builtinCallParams(&builtin_buf, node).?; |
| ... | @@ -1967,7 +2057,7 @@ pub const SrcLoc = struct { | ... | @@ -1967,7 +2057,7 @@ pub const SrcLoc = struct { |
| 1967 | else => unreachable, | 2057 | else => unreachable, |
| 1968 | }; | 2058 | }; |
| 1969 | 2059 | ||
| 1970 | const tree = try src_loc.file_scope.getTree(gpa); | 2060 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1971 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); | 2061 | const switch_node = switch_node_offset.toAbsolute(src_loc.base_node); |
| 1972 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; | 2062 | _, const extra_index = tree.nodeData(switch_node).node_and_extra; |
| 1973 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); | 2063 | const case_nodes = tree.extraDataSlice(tree.extraData(extra_index, Ast.Node.SubRange), Ast.Node.Index); |
| ... | @@ -2062,7 +2152,7 @@ pub const SrcLoc = struct { | ... | @@ -2062,7 +2152,7 @@ pub const SrcLoc = struct { |
| 2062 | } | 2152 | } |
| 2063 | }, | 2153 | }, |
| 2064 | .func_decl_param_comptime => |param_idx| { | 2154 | .func_decl_param_comptime => |param_idx| { |
| 2065 | const tree = try src_loc.file_scope.getTree(gpa); | 2155 | const tree = try src_loc.file_scope.getTree(zcu); |
| 2066 | var buf: [1]Ast.Node.Index = undefined; | 2156 | var buf: [1]Ast.Node.Index = undefined; |
| 2067 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; | 2157 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; |
| 2068 | var param_it = full.iterate(tree); | 2158 | var param_it = full.iterate(tree); |
| ... | @@ -2071,7 +2161,7 @@ pub const SrcLoc = struct { | ... | @@ -2071,7 +2161,7 @@ pub const SrcLoc = struct { |
| 2071 | return tree.tokenToSpan(param.comptime_noalias.?); | 2161 | return tree.tokenToSpan(param.comptime_noalias.?); |
| 2072 | }, | 2162 | }, |
| 2073 | .func_decl_param_ty => |param_idx| { | 2163 | .func_decl_param_ty => |param_idx| { |
| 2074 | const tree = try src_loc.file_scope.getTree(gpa); | 2164 | const tree = try src_loc.file_scope.getTree(zcu); |
| 2075 | var buf: [1]Ast.Node.Index = undefined; | 2165 | var buf: [1]Ast.Node.Index = undefined; |
| 2076 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; | 2166 | const full = tree.fullFnProto(&buf, src_loc.base_node).?; |
| 2077 | var param_it = full.iterate(tree); | 2167 | var param_it = full.iterate(tree); |
| ... | @@ -2100,9 +2190,6 @@ pub const LazySrcLoc = struct { | ... | @@ -2100,9 +2190,6 @@ pub const LazySrcLoc = struct { |
| 2100 | /// value is being set to this tag. | 2190 | /// value is being set to this tag. |
| 2101 | /// `base_node_inst` is unused. | 2191 | /// `base_node_inst` is unused. |
| 2102 | unneeded, | 2192 | unneeded, |
| 2103 | /// Means the source location points to an entire file; not any particular | ||
| 2104 | /// location within the file. `file_scope` union field will be active. | ||
| 2105 | entire_file, | ||
| 2106 | /// The source location points to a byte offset within a source file, | 2193 | /// The source location points to a byte offset within a source file, |
| 2107 | /// offset from 0. The source file is determined contextually. | 2194 | /// offset from 0. The source file is determined contextually. |
| 2108 | byte_abs: u32, | 2195 | byte_abs: u32, |
| ... | @@ -2521,10 +2608,7 @@ pub const LazySrcLoc = struct { | ... | @@ -2521,10 +2608,7 @@ pub const LazySrcLoc = struct { |
| 2521 | 2608 | ||
| 2522 | /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates. | 2609 | /// Like `upgrade`, but returns `null` if the source location has been lost across incremental updates. |
| 2523 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { | 2610 | pub fn upgradeOrLost(lazy: LazySrcLoc, zcu: *Zcu) ?SrcLoc { |
| 2524 | const file, const base_node: Ast.Node.Index = if (lazy.offset == .entire_file) .{ | 2611 | const file, const base_node: Ast.Node.Index = resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; |
| 2525 | zcu.fileByIndex(lazy.base_node_inst.resolveFile(&zcu.intern_pool)), | ||
| 2526 | .root, | ||
| 2527 | } else resolveBaseNode(lazy.base_node_inst, zcu) orelse return null; | ||
| 2528 | return .{ | 2612 | return .{ |
| 2529 | .file_scope = file, | 2613 | .file_scope = file, |
| 2530 | .base_node = base_node, | 2614 | .base_node = base_node, |
| ... | @@ -2544,15 +2628,16 @@ pub const LazySrcLoc = struct { | ... | @@ -2544,15 +2628,16 @@ pub const LazySrcLoc = struct { |
| 2544 | return true; | 2628 | return true; |
| 2545 | }; | 2629 | }; |
| 2546 | if (lhs_src.file_scope != rhs_src.file_scope) { | 2630 | if (lhs_src.file_scope != rhs_src.file_scope) { |
| 2547 | return std.mem.order( | 2631 | const lhs_path = lhs_src.file_scope.path; |
| 2548 | u8, | 2632 | const rhs_path = rhs_src.file_scope.path; |
| 2549 | lhs_src.file_scope.sub_file_path, | 2633 | if (lhs_path.root != rhs_path.root) { |
| 2550 | rhs_src.file_scope.sub_file_path, | 2634 | return @intFromEnum(lhs_path.root) < @intFromEnum(rhs_path.root); |
| 2551 | ).compare(.lt); | 2635 | } |
| 2636 | return std.mem.order(u8, lhs_path.sub_path, rhs_path.sub_path).compare(.lt); | ||
| 2552 | } | 2637 | } |
| 2553 | 2638 | ||
| 2554 | const lhs_span = try lhs_src.span(zcu.gpa); | 2639 | const lhs_span = try lhs_src.span(zcu); |
| 2555 | const rhs_span = try rhs_src.span(zcu.gpa); | 2640 | const rhs_span = try rhs_src.span(zcu); |
| 2556 | return lhs_span.main < rhs_span.main; | 2641 | return lhs_span.main < rhs_span.main; |
| 2557 | } | 2642 | } |
| 2558 | }; | 2643 | }; |
| ... | @@ -2583,16 +2668,16 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2583,16 +2668,16 @@ pub fn deinit(zcu: *Zcu) void { |
| 2583 | 2668 | ||
| 2584 | if (zcu.llvm_object) |llvm_object| llvm_object.deinit(); | 2669 | if (zcu.llvm_object) |llvm_object| llvm_object.deinit(); |
| 2585 | 2670 | ||
| 2586 | for (zcu.import_table.keys()) |key| { | 2671 | zcu.builtin_modules.deinit(gpa); |
| 2587 | gpa.free(key); | 2672 | zcu.module_roots.deinit(gpa); |
| 2588 | } | 2673 | for (zcu.import_table.keys()) |file_index| { |
| 2589 | for (zcu.import_table.values()) |file_index| { | ||
| 2590 | pt.destroyFile(file_index); | 2674 | pt.destroyFile(file_index); |
| 2591 | } | 2675 | } |
| 2592 | zcu.import_table.deinit(gpa); | 2676 | zcu.import_table.deinit(gpa); |
| 2677 | zcu.alive_files.deinit(gpa); | ||
| 2593 | 2678 | ||
| 2594 | for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| { | 2679 | for (zcu.embed_table.keys()) |embed_file| { |
| 2595 | gpa.free(path); | 2680 | embed_file.path.deinit(gpa); |
| 2596 | gpa.destroy(embed_file); | 2681 | gpa.destroy(embed_file); |
| 2597 | } | 2682 | } |
| 2598 | zcu.embed_table.deinit(gpa); | 2683 | zcu.embed_table.deinit(gpa); |
| ... | @@ -2610,9 +2695,10 @@ pub fn deinit(zcu: *Zcu) void { | ... | @@ -2610,9 +2695,10 @@ pub fn deinit(zcu: *Zcu) void { |
| 2610 | zcu.failed_types.deinit(gpa); | 2695 | zcu.failed_types.deinit(gpa); |
| 2611 | 2696 | ||
| 2612 | for (zcu.failed_files.values()) |value| { | 2697 | for (zcu.failed_files.values()) |value| { |
| 2613 | if (value) |msg| msg.destroy(gpa); | 2698 | if (value) |msg| gpa.free(msg); |
| 2614 | } | 2699 | } |
| 2615 | zcu.failed_files.deinit(gpa); | 2700 | zcu.failed_files.deinit(gpa); |
| 2701 | zcu.failed_imports.deinit(gpa); | ||
| 2616 | 2702 | ||
| 2617 | for (zcu.failed_exports.values()) |value| { | 2703 | for (zcu.failed_exports.values()) |value| { |
| 2618 | value.destroy(gpa); | 2704 | value.destroy(gpa); |
| ... | @@ -3407,27 +3493,21 @@ pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void | ... | @@ -3407,27 +3493,21 @@ pub fn ensureNavValAnalysisQueued(zcu: *Zcu, nav_id: InternPool.Nav.Index) !void |
| 3407 | zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {}); | 3493 | zcu.nav_val_analysis_queued.putAssumeCapacityNoClobber(nav_id, {}); |
| 3408 | } | 3494 | } |
| 3409 | 3495 | ||
| 3410 | pub const ImportFileResult = struct { | 3496 | pub const ImportResult = struct { |
| 3411 | file: *File, | 3497 | /// Whether `file` has been newly created; in other words, whether this is the first import of |
| 3412 | file_index: File.Index, | 3498 | /// this file. This should only be `true` when importing files during AstGen. After that, all |
| 3499 | /// files should have already been discovered. | ||
| 3413 | is_new: bool, | 3500 | is_new: bool, |
| 3414 | is_pkg: bool, | ||
| 3415 | }; | ||
| 3416 | 3501 | ||
| 3417 | pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { | 3502 | /// `file.mod` is not populated by this function, so if `is_new`, then it is `undefined`. |
| 3418 | const want_local_cache = mod == zcu.main_mod; | 3503 | file: *Zcu.File, |
| 3419 | var path_hash: Cache.HashHelper = .{}; | 3504 | file_index: File.Index, |
| 3420 | path_hash.addBytes(build_options.version); | 3505 | |
| 3421 | path_hash.add(builtin.zig_backend); | 3506 | /// If this import was a simple file path, this is `null`; the imported file should exist within |
| 3422 | if (!want_local_cache) { | 3507 | /// the importer's module. Otherwise, it's the module which the import resolved to. This module |
| 3423 | path_hash.addOptionalBytes(mod.root.root_dir.path); | 3508 | /// could match the module of `cur_file`, since a module can depend on itself. |
| 3424 | path_hash.addBytes(mod.root.sub_path); | 3509 | module: ?*Package.Module, |
| 3425 | } | 3510 | }; |
| 3426 | path_hash.addBytes(sub_file_path); | ||
| 3427 | var bin: Cache.BinDigest = undefined; | ||
| 3428 | path_hash.hasher.final(&bin); | ||
| 3429 | return bin; | ||
| 3430 | } | ||
| 3431 | 3511 | ||
| 3432 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of | 3512 | /// Delete all the Export objects that are caused by this `AnalUnit`. Re-analysis of |
| 3433 | /// this `AnalUnit` will cause them to be re-created (or not). | 3513 | /// this `AnalUnit` will cause them to be re-created (or not). |
| ... | @@ -3941,15 +4021,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv | ... | @@ -3941,15 +4021,7 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv |
| 3941 | 4021 | ||
| 3942 | try type_queue.ensureTotalCapacity(gpa, zcu.analysis_roots.len); | 4022 | try type_queue.ensureTotalCapacity(gpa, zcu.analysis_roots.len); |
| 3943 | for (zcu.analysis_roots.slice()) |mod| { | 4023 | for (zcu.analysis_roots.slice()) |mod| { |
| 3944 | // Logic ripped from `Zcu.PerThread.importPkg`. | 4024 | const file = zcu.module_roots.get(mod).?.unwrap() orelse continue; |
| 3945 | // TODO: this is silly, `Module` should just store a reference to its root `File`. | ||
| 3946 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 3947 | mod.root.root_dir.path orelse ".", | ||
| 3948 | mod.root.sub_path, | ||
| 3949 | mod.root_src_path, | ||
| 3950 | }); | ||
| 3951 | defer gpa.free(resolved_path); | ||
| 3952 | const file = zcu.import_table.get(resolved_path).?; | ||
| 3953 | const root_ty = zcu.fileRootType(file); | 4025 | const root_ty = zcu.fileRootType(file); |
| 3954 | if (root_ty == .none) continue; | 4026 | if (root_ty == .none) continue; |
| 3955 | type_queue.putAssumeCapacityNoClobber(root_ty, null); | 4027 | type_queue.putAssumeCapacityNoClobber(root_ty, null); |
| ... | @@ -4229,8 +4301,8 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co | ... | @@ -4229,8 +4301,8 @@ fn formatAnalUnit(data: struct { unit: AnalUnit, zcu: *Zcu }, comptime fmt: []co |
| 4229 | .@"comptime" => |cu_id| { | 4301 | .@"comptime" => |cu_id| { |
| 4230 | const cu = ip.getComptimeUnit(cu_id); | 4302 | const cu = ip.getComptimeUnit(cu_id); |
| 4231 | if (cu.zir_index.resolveFull(ip)) |resolved| { | 4303 | if (cu.zir_index.resolveFull(ip)) |resolved| { |
| 4232 | const file_path = zcu.fileByIndex(resolved.file).sub_file_path; | 4304 | const file_path = zcu.fileByIndex(resolved.file).path; |
| 4233 | return writer.print("comptime(inst=('{s}', %{}) [{}])", .{ file_path, @intFromEnum(resolved.inst), @intFromEnum(cu_id) }); | 4305 | return writer.print("comptime(inst=('{}', %{}) [{}])", .{ file_path.fmt(zcu.comp), @intFromEnum(resolved.inst), @intFromEnum(cu_id) }); |
| 4234 | } else { | 4306 | } else { |
| 4235 | return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); | 4307 | return writer.print("comptime(inst=<lost> [{}])", .{@intFromEnum(cu_id)}); |
| 4236 | } | 4308 | } |
| ... | @@ -4254,8 +4326,8 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com | ... | @@ -4254,8 +4326,8 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com |
| 4254 | const info = ti.resolveFull(ip) orelse { | 4326 | const info = ti.resolveFull(ip) orelse { |
| 4255 | return writer.writeAll("inst(<lost>)"); | 4327 | return writer.writeAll("inst(<lost>)"); |
| 4256 | }; | 4328 | }; |
| 4257 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4329 | const file_path = zcu.fileByIndex(info.file).path; |
| 4258 | return writer.print("inst('{s}', %{d})", .{ file_path, @intFromEnum(info.inst) }); | 4330 | return writer.print("inst('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) }); |
| 4259 | }, | 4331 | }, |
| 4260 | .nav_val => |nav| { | 4332 | .nav_val => |nav| { |
| 4261 | const fqn = ip.getNav(nav).fqn; | 4333 | const fqn = ip.getNav(nav).fqn; |
| ... | @@ -4271,30 +4343,26 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com | ... | @@ -4271,30 +4343,26 @@ fn formatDependee(data: struct { dependee: InternPool.Dependee, zcu: *Zcu }, com |
| 4271 | else => unreachable, | 4343 | else => unreachable, |
| 4272 | }, | 4344 | }, |
| 4273 | .zon_file => |file| { | 4345 | .zon_file => |file| { |
| 4274 | const file_path = zcu.fileByIndex(file).sub_file_path; | 4346 | const file_path = zcu.fileByIndex(file).path; |
| 4275 | return writer.print("zon_file('{s}')", .{file_path}); | 4347 | return writer.print("zon_file('{}')", .{file_path.fmt(zcu.comp)}); |
| 4276 | }, | 4348 | }, |
| 4277 | .embed_file => |ef_idx| { | 4349 | .embed_file => |ef_idx| { |
| 4278 | const ef = ef_idx.get(zcu); | 4350 | const ef = ef_idx.get(zcu); |
| 4279 | return writer.print("embed_file('{s}')", .{std.fs.path.fmtJoin(&.{ | 4351 | return writer.print("embed_file('{}')", .{ef.path.fmt(zcu.comp)}); |
| 4280 | ef.owner.root.root_dir.path orelse "", | ||
| 4281 | ef.owner.root.sub_path, | ||
| 4282 | ef.sub_file_path.toSlice(ip), | ||
| 4283 | })}); | ||
| 4284 | }, | 4352 | }, |
| 4285 | .namespace => |ti| { | 4353 | .namespace => |ti| { |
| 4286 | const info = ti.resolveFull(ip) orelse { | 4354 | const info = ti.resolveFull(ip) orelse { |
| 4287 | return writer.writeAll("namespace(<lost>)"); | 4355 | return writer.writeAll("namespace(<lost>)"); |
| 4288 | }; | 4356 | }; |
| 4289 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4357 | const file_path = zcu.fileByIndex(info.file).path; |
| 4290 | return writer.print("namespace('{s}', %{d})", .{ file_path, @intFromEnum(info.inst) }); | 4358 | return writer.print("namespace('{}', %{d})", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst) }); |
| 4291 | }, | 4359 | }, |
| 4292 | .namespace_name => |k| { | 4360 | .namespace_name => |k| { |
| 4293 | const info = k.namespace.resolveFull(ip) orelse { | 4361 | const info = k.namespace.resolveFull(ip) orelse { |
| 4294 | return writer.print("namespace(<lost>, '{}')", .{k.name.fmt(ip)}); | 4362 | return writer.print("namespace(<lost>, '{}')", .{k.name.fmt(ip)}); |
| 4295 | }; | 4363 | }; |
| 4296 | const file_path = zcu.fileByIndex(info.file).sub_file_path; | 4364 | const file_path = zcu.fileByIndex(info.file).path; |
| 4297 | return writer.print("namespace('{s}', %{d}, '{}')", .{ file_path, @intFromEnum(info.inst), k.name.fmt(ip) }); | 4365 | return writer.print("namespace('{}', %{d}, '{}')", .{ file_path.fmt(zcu.comp), @intFromEnum(info.inst), k.name.fmt(ip) }); |
| 4298 | }, | 4366 | }, |
| 4299 | .memoized_state => return writer.writeAll("memoized_state"), | 4367 | .memoized_state => return writer.writeAll("memoized_state"), |
| 4300 | } | 4368 | } |
| ... | @@ -4511,3 +4579,114 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) | ... | @@ -4511,3 +4579,114 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) |
| 4511 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); | 4579 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4512 | return error.CodegenFail; | 4580 | return error.CodegenFail; |
| 4513 | } | 4581 | } |
| 4582 | |||
| 4583 | /// Asserts that `zcu.multi_module_err != null`. | ||
| 4584 | pub fn addFileInMultipleModulesError( | ||
| 4585 | zcu: *Zcu, | ||
| 4586 | eb: *std.zig.ErrorBundle.Wip, | ||
| 4587 | ) !void { | ||
| 4588 | const gpa = zcu.gpa; | ||
| 4589 | |||
| 4590 | const info = zcu.multi_module_err.?; | ||
| 4591 | const file = info.file; | ||
| 4592 | |||
| 4593 | // error: file exists in modules 'root.foo' and 'root.bar' | ||
| 4594 | // note: files must belong to only one module | ||
| 4595 | // note: file is imported here | ||
| 4596 | // note: which is imported here | ||
| 4597 | // note: which is the root of module 'root.foo' imported here | ||
| 4598 | // note: file is the root of module 'root.bar' imported here | ||
| 4599 | |||
| 4600 | const file_src = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb); | ||
| 4601 | const root_msg = try eb.printString("file exists in modules '{s}' and '{s}'", .{ | ||
| 4602 | info.modules[0].fully_qualified_name, | ||
| 4603 | info.modules[1].fully_qualified_name, | ||
| 4604 | }); | ||
| 4605 | |||
| 4606 | var notes: std.ArrayListUnmanaged(std.zig.ErrorBundle.MessageIndex) = .empty; | ||
| 4607 | defer notes.deinit(gpa); | ||
| 4608 | |||
| 4609 | try notes.append(gpa, try eb.addErrorMessage(.{ | ||
| 4610 | .msg = try eb.addString("files must belong to only one module"), | ||
| 4611 | .src_loc = file_src, | ||
| 4612 | })); | ||
| 4613 | |||
| 4614 | try zcu.explainWhyFileIsInModule(eb, &notes, file, info.modules[0], info.refs[0]); | ||
| 4615 | try zcu.explainWhyFileIsInModule(eb, &notes, file, info.modules[1], info.refs[1]); | ||
| 4616 | |||
| 4617 | try eb.addRootErrorMessage(.{ | ||
| 4618 | .msg = root_msg, | ||
| 4619 | .src_loc = file_src, | ||
| 4620 | .notes_len = @intCast(notes.items.len), | ||
| 4621 | }); | ||
| 4622 | const notes_start = try eb.reserveNotes(@intCast(notes.items.len)); | ||
| 4623 | const notes_slice: []std.zig.ErrorBundle.MessageIndex = @ptrCast(eb.extra.items[notes_start..]); | ||
| 4624 | @memcpy(notes_slice, notes.items); | ||
| 4625 | } | ||
| 4626 | |||
| 4627 | fn explainWhyFileIsInModule( | ||
| 4628 | zcu: *Zcu, | ||
| 4629 | eb: *std.zig.ErrorBundle.Wip, | ||
| 4630 | notes_out: *std.ArrayListUnmanaged(std.zig.ErrorBundle.MessageIndex), | ||
| 4631 | file: File.Index, | ||
| 4632 | in_module: *Package.Module, | ||
| 4633 | ref: File.Reference, | ||
| 4634 | ) !void { | ||
| 4635 | const gpa = zcu.gpa; | ||
| 4636 | |||
| 4637 | // error: file is the root of module 'foo' | ||
| 4638 | // | ||
| 4639 | // error: file is imported here by the root of module 'foo' | ||
| 4640 | // | ||
| 4641 | // error: file is imported here | ||
| 4642 | // note: which is imported here | ||
| 4643 | // note: which is imported here by the root of module 'foo' | ||
| 4644 | |||
| 4645 | var import = switch (ref) { | ||
| 4646 | .analysis_root => |mod| { | ||
| 4647 | assert(mod == in_module); | ||
| 4648 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4649 | .msg = try eb.printString("file is the root of module '{s}'", .{mod.fully_qualified_name}), | ||
| 4650 | .src_loc = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb), | ||
| 4651 | })); | ||
| 4652 | return; | ||
| 4653 | }, | ||
| 4654 | .import => |import| if (import.module) |mod| { | ||
| 4655 | assert(mod == in_module); | ||
| 4656 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4657 | .msg = try eb.printString("file is the root of module '{s}'", .{mod.fully_qualified_name}), | ||
| 4658 | .src_loc = try zcu.fileByIndex(file).errorBundleWholeFileSrc(zcu, eb), | ||
| 4659 | })); | ||
| 4660 | return; | ||
| 4661 | } else import, | ||
| 4662 | }; | ||
| 4663 | |||
| 4664 | var is_first = true; | ||
| 4665 | while (true) { | ||
| 4666 | const thing: []const u8 = if (is_first) "file" else "which"; | ||
| 4667 | is_first = false; | ||
| 4668 | |||
| 4669 | const import_src = try zcu.fileByIndex(import.importer).errorBundleTokenSrc(import.tok, zcu, eb); | ||
| 4670 | |||
| 4671 | const importer_ref = zcu.alive_files.get(import.importer).?; | ||
| 4672 | const importer_root: ?*Package.Module = switch (importer_ref) { | ||
| 4673 | .analysis_root => |mod| mod, | ||
| 4674 | .import => |i| i.module, | ||
| 4675 | }; | ||
| 4676 | |||
| 4677 | if (importer_root) |m| { | ||
| 4678 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4679 | .msg = try eb.printString("{s} is imported here by the root of module '{s}'", .{ thing, m.fully_qualified_name }), | ||
| 4680 | .src_loc = import_src, | ||
| 4681 | })); | ||
| 4682 | return; | ||
| 4683 | } | ||
| 4684 | |||
| 4685 | try notes_out.append(gpa, try eb.addErrorMessage(.{ | ||
| 4686 | .msg = try eb.printString("{s} is imported here", .{thing}), | ||
| 4687 | .src_loc = import_src, | ||
| 4688 | })); | ||
| 4689 | |||
| 4690 | import = importer_ref.import; | ||
| 4691 | } | ||
| 4692 | } |
src/Zcu/PerThread.zig+529-334| ... | @@ -8,23 +8,26 @@ const Ast = std.zig.Ast; | ... | @@ -8,23 +8,26 @@ const Ast = std.zig.Ast; |
| 8 | const AstGen = std.zig.AstGen; | 8 | const AstGen = std.zig.AstGen; |
| 9 | const BigIntConst = std.math.big.int.Const; | 9 | const BigIntConst = std.math.big.int.Const; |
| 10 | const BigIntMutable = std.math.big.int.Mutable; | 10 | const BigIntMutable = std.math.big.int.Mutable; |
| 11 | const Builtin = @import("../Builtin.zig"); | ||
| 11 | const build_options = @import("build_options"); | 12 | const build_options = @import("build_options"); |
| 12 | const builtin = @import("builtin"); | 13 | const builtin = @import("builtin"); |
| 13 | const Cache = std.Build.Cache; | 14 | const Cache = std.Build.Cache; |
| 14 | const dev = @import("../dev.zig"); | 15 | const dev = @import("../dev.zig"); |
| 15 | const InternPool = @import("../InternPool.zig"); | 16 | const InternPool = @import("../InternPool.zig"); |
| 16 | const AnalUnit = InternPool.AnalUnit; | 17 | const AnalUnit = InternPool.AnalUnit; |
| 17 | const isUpDir = @import("../introspect.zig").isUpDir; | 18 | const introspect = @import("../introspect.zig"); |
| 18 | const Liveness = @import("../Liveness.zig"); | 19 | const Liveness = @import("../Liveness.zig"); |
| 19 | const log = std.log.scoped(.zcu); | 20 | const log = std.log.scoped(.zcu); |
| 20 | const Module = @import("../Package.zig").Module; | 21 | const Module = @import("../Package.zig").Module; |
| 21 | const Sema = @import("../Sema.zig"); | 22 | const Sema = @import("../Sema.zig"); |
| 22 | const std = @import("std"); | 23 | const std = @import("std"); |
| 24 | const mem = std.mem; | ||
| 23 | const target_util = @import("../target.zig"); | 25 | const target_util = @import("../target.zig"); |
| 24 | const trace = @import("../tracy.zig").trace; | 26 | const trace = @import("../tracy.zig").trace; |
| 25 | const Type = @import("../Type.zig"); | 27 | const Type = @import("../Type.zig"); |
| 26 | const Value = @import("../Value.zig"); | 28 | const Value = @import("../Value.zig"); |
| 27 | const Zcu = @import("../Zcu.zig"); | 29 | const Zcu = @import("../Zcu.zig"); |
| 30 | const Compilation = @import("../Compilation.zig"); | ||
| 28 | const Zir = std.zig.Zir; | 31 | const Zir = std.zig.Zir; |
| 29 | const Zoir = std.zig.Zoir; | 32 | const Zoir = std.zig.Zoir; |
| 30 | const ZonGen = std.zig.ZonGen; | 33 | const ZonGen = std.zig.ZonGen; |
| ... | @@ -50,16 +53,9 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ... | @@ -50,16 +53,9 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 50 | const zcu = pt.zcu; | 53 | const zcu = pt.zcu; |
| 51 | const gpa = zcu.gpa; | 54 | const gpa = zcu.gpa; |
| 52 | const file = zcu.fileByIndex(file_index); | 55 | const file = zcu.fileByIndex(file_index); |
| 53 | const is_builtin = file.mod.isBuiltin(); | 56 | log.debug("deinit File {}", .{file.path.fmt(zcu.comp)}); |
| 54 | log.debug("deinit File {s}", .{file.sub_file_path}); | 57 | file.path.deinit(gpa); |
| 55 | if (is_builtin) { | 58 | file.unload(gpa); |
| 56 | file.unloadTree(gpa); | ||
| 57 | file.unloadZir(gpa); | ||
| 58 | } else { | ||
| 59 | gpa.free(file.sub_file_path); | ||
| 60 | file.unload(gpa); | ||
| 61 | } | ||
| 62 | file.references.deinit(gpa); | ||
| 63 | if (file.prev_zir) |prev_zir| { | 59 | if (file.prev_zir) |prev_zir| { |
| 64 | prev_zir.deinit(gpa); | 60 | prev_zir.deinit(gpa); |
| 65 | gpa.destroy(prev_zir); | 61 | gpa.destroy(prev_zir); |
| ... | @@ -70,20 +66,19 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | ... | @@ -70,20 +66,19 @@ fn deinitFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 70 | pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { | 66 | pub fn destroyFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) void { |
| 71 | const gpa = pt.zcu.gpa; | 67 | const gpa = pt.zcu.gpa; |
| 72 | const file = pt.zcu.fileByIndex(file_index); | 68 | const file = pt.zcu.fileByIndex(file_index); |
| 73 | const is_builtin = file.mod.isBuiltin(); | ||
| 74 | pt.deinitFile(file_index); | 69 | pt.deinitFile(file_index); |
| 75 | if (!is_builtin) gpa.destroy(file); | 70 | gpa.destroy(file); |
| 76 | } | 71 | } |
| 77 | 72 | ||
| 78 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs | 73 | /// Ensures that `file` has up-to-date ZIR. If not, loads the ZIR cache or runs |
| 79 | /// AstGen as needed. Also updates `file.status`. | 74 | /// AstGen as needed. Also updates `file.status`. Does not assume that `file.mod` |
| 75 | /// is populated. Does not return `error.AnalysisFail` on AstGen failures. | ||
| 80 | pub fn updateFile( | 76 | pub fn updateFile( |
| 81 | pt: Zcu.PerThread, | 77 | pt: Zcu.PerThread, |
| 78 | file_index: Zcu.File.Index, | ||
| 82 | file: *Zcu.File, | 79 | file: *Zcu.File, |
| 83 | path_digest: Cache.BinDigest, | ||
| 84 | ) !void { | 80 | ) !void { |
| 85 | dev.check(.ast_gen); | 81 | dev.check(.ast_gen); |
| 86 | assert(!file.mod.isBuiltin()); | ||
| 87 | 82 | ||
| 88 | const tracy = trace(@src()); | 83 | const tracy = trace(@src()); |
| 89 | defer tracy.end(); | 84 | defer tracy.end(); |
| ... | @@ -93,13 +88,20 @@ pub fn updateFile( | ... | @@ -93,13 +88,20 @@ pub fn updateFile( |
| 93 | const gpa = zcu.gpa; | 88 | const gpa = zcu.gpa; |
| 94 | 89 | ||
| 95 | // In any case we need to examine the stat of the file to determine the course of action. | 90 | // In any case we need to examine the stat of the file to determine the course of action. |
| 96 | var source_file = try file.mod.root.openFile(file.sub_file_path, .{}); | 91 | var source_file = f: { |
| 92 | const dir, const sub_path = file.path.openInfo(comp.dirs); | ||
| 93 | break :f try dir.openFile(sub_path, .{}); | ||
| 94 | }; | ||
| 97 | defer source_file.close(); | 95 | defer source_file.close(); |
| 98 | 96 | ||
| 99 | const stat = try source_file.stat(); | 97 | const stat = try source_file.stat(); |
| 100 | 98 | ||
| 101 | const want_local_cache = file.mod == zcu.main_mod; | 99 | const want_local_cache = switch (file.path.root) { |
| 102 | const hex_digest = Cache.binToHex(path_digest); | 100 | .none, .local_cache => true, |
| 101 | .global_cache, .zig_lib => false, | ||
| 102 | }; | ||
| 103 | |||
| 104 | const hex_digest = Cache.binToHex(file.path.digest()); | ||
| 103 | const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache; | 105 | const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache; |
| 104 | const zir_dir = cache_directory.handle; | 106 | const zir_dir = cache_directory.handle; |
| 105 | 107 | ||
| ... | @@ -107,8 +109,8 @@ pub fn updateFile( | ... | @@ -107,8 +109,8 @@ pub fn updateFile( |
| 107 | var lock: std.fs.File.Lock = switch (file.status) { | 109 | var lock: std.fs.File.Lock = switch (file.status) { |
| 108 | .never_loaded, .retryable_failure => lock: { | 110 | .never_loaded, .retryable_failure => lock: { |
| 109 | // First, load the cached ZIR code, if any. | 111 | // First, load the cached ZIR code, if any. |
| 110 | log.debug("AstGen checking cache: {s} (local={}, digest={s})", .{ | 112 | log.debug("AstGen checking cache: {} (local={}, digest={s})", .{ |
| 111 | file.sub_file_path, want_local_cache, &hex_digest, | 113 | file.path.fmt(comp), want_local_cache, &hex_digest, |
| 112 | }); | 114 | }); |
| 113 | 115 | ||
| 114 | break :lock .shared; | 116 | break :lock .shared; |
| ... | @@ -120,18 +122,18 @@ pub fn updateFile( | ... | @@ -120,18 +122,18 @@ pub fn updateFile( |
| 120 | stat.inode == file.stat.inode; | 122 | stat.inode == file.stat.inode; |
| 121 | 123 | ||
| 122 | if (unchanged_metadata) { | 124 | if (unchanged_metadata) { |
| 123 | log.debug("unmodified metadata of file: {s}", .{file.sub_file_path}); | 125 | log.debug("unmodified metadata of file: {}", .{file.path.fmt(comp)}); |
| 124 | return; | 126 | return; |
| 125 | } | 127 | } |
| 126 | 128 | ||
| 127 | log.debug("metadata changed: {s}", .{file.sub_file_path}); | 129 | log.debug("metadata changed: {}", .{file.path.fmt(comp)}); |
| 128 | 130 | ||
| 129 | break :lock .exclusive; | 131 | break :lock .exclusive; |
| 130 | }, | 132 | }, |
| 131 | }; | 133 | }; |
| 132 | 134 | ||
| 133 | // The old compile error, if any, is no longer relevant. | 135 | // The old compile error, if any, is no longer relevant. |
| 134 | pt.lockAndClearFileCompileError(file); | 136 | pt.lockAndClearFileCompileError(file_index, file); |
| 135 | 137 | ||
| 136 | // If `zir` is not null, and `prev_zir` is null, then `TrackedInst`s are associated with `zir`. | 138 | // If `zir` is not null, and `prev_zir` is null, then `TrackedInst`s are associated with `zir`. |
| 137 | // We need to keep it around! | 139 | // We need to keep it around! |
| ... | @@ -211,12 +213,12 @@ pub fn updateFile( | ... | @@ -211,12 +213,12 @@ pub fn updateFile( |
| 211 | }; | 213 | }; |
| 212 | switch (result) { | 214 | switch (result) { |
| 213 | .success => { | 215 | .success => { |
| 214 | log.debug("AstGen cached success: {s}", .{file.sub_file_path}); | 216 | log.debug("AstGen cached success: {}", .{file.path.fmt(comp)}); |
| 215 | break false; | 217 | break false; |
| 216 | }, | 218 | }, |
| 217 | .invalid => {}, | 219 | .invalid => {}, |
| 218 | .truncated => log.warn("unexpected EOF reading cached ZIR for {s}", .{file.sub_file_path}), | 220 | .truncated => log.warn("unexpected EOF reading cached ZIR for {}", .{file.path.fmt(comp)}), |
| 219 | .stale => log.debug("AstGen cache stale: {s}", .{file.sub_file_path}), | 221 | .stale => log.debug("AstGen cache stale: {}", .{file.path.fmt(comp)}), |
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | // If we already have the exclusive lock then it is our job to update. | 224 | // If we already have the exclusive lock then it is our job to update. |
| ... | @@ -255,22 +257,22 @@ pub fn updateFile( | ... | @@ -255,22 +257,22 @@ pub fn updateFile( |
| 255 | file.zir = try AstGen.generate(gpa, file.tree.?); | 257 | file.zir = try AstGen.generate(gpa, file.tree.?); |
| 256 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { | 258 | Zcu.saveZirCache(gpa, cache_file, stat, file.zir.?) catch |err| switch (err) { |
| 257 | error.OutOfMemory => |e| return e, | 259 | error.OutOfMemory => |e| return e, |
| 258 | else => log.warn("unable to write cached ZIR code for {}{s} to {}{s}: {s}", .{ | 260 | else => log.warn("unable to write cached ZIR code for {} to {}{s}: {s}", .{ |
| 259 | file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), | 261 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 260 | }), | 262 | }), |
| 261 | }; | 263 | }; |
| 262 | }, | 264 | }, |
| 263 | .zon => { | 265 | .zon => { |
| 264 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); | 266 | file.zoir = try ZonGen.generate(gpa, file.tree.?, .{}); |
| 265 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { | 267 | Zcu.saveZoirCache(cache_file, stat, file.zoir.?) catch |err| { |
| 266 | log.warn("unable to write cached ZOIR code for {}{s} to {}{s}: {s}", .{ | 268 | log.warn("unable to write cached ZOIR code for {} to {}{s}: {s}", .{ |
| 267 | file.mod.root, file.sub_file_path, cache_directory, &hex_digest, @errorName(err), | 269 | file.path.fmt(comp), cache_directory, &hex_digest, @errorName(err), |
| 268 | }); | 270 | }); |
| 269 | }; | 271 | }; |
| 270 | }, | 272 | }, |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | log.debug("AstGen fresh success: {s}", .{file.sub_file_path}); | 275 | log.debug("AstGen fresh success: {}", .{file.path.fmt(comp)}); |
| 274 | } | 276 | } |
| 275 | 277 | ||
| 276 | file.stat = .{ | 278 | file.stat = .{ |
| ... | @@ -287,7 +289,7 @@ pub fn updateFile( | ... | @@ -287,7 +289,7 @@ pub fn updateFile( |
| 287 | if (file.zir.?.hasCompileErrors()) { | 289 | if (file.zir.?.hasCompileErrors()) { |
| 288 | comp.mutex.lock(); | 290 | comp.mutex.lock(); |
| 289 | defer comp.mutex.unlock(); | 291 | defer comp.mutex.unlock(); |
| 290 | try zcu.failed_files.putNoClobber(gpa, file, null); | 292 | try zcu.failed_files.putNoClobber(gpa, file_index, null); |
| 291 | } | 293 | } |
| 292 | if (file.zir.?.loweringFailed()) { | 294 | if (file.zir.?.loweringFailed()) { |
| 293 | file.status = .astgen_failure; | 295 | file.status = .astgen_failure; |
| ... | @@ -300,7 +302,7 @@ pub fn updateFile( | ... | @@ -300,7 +302,7 @@ pub fn updateFile( |
| 300 | file.status = .astgen_failure; | 302 | file.status = .astgen_failure; |
| 301 | comp.mutex.lock(); | 303 | comp.mutex.lock(); |
| 302 | defer comp.mutex.unlock(); | 304 | defer comp.mutex.unlock(); |
| 303 | try zcu.failed_files.putNoClobber(gpa, file, null); | 305 | try zcu.failed_files.putNoClobber(gpa, file_index, null); |
| 304 | } else { | 306 | } else { |
| 305 | file.status = .success; | 307 | file.status = .success; |
| 306 | } | 308 | } |
| ... | @@ -310,8 +312,7 @@ pub fn updateFile( | ... | @@ -310,8 +312,7 @@ pub fn updateFile( |
| 310 | switch (file.status) { | 312 | switch (file.status) { |
| 311 | .never_loaded => unreachable, | 313 | .never_loaded => unreachable, |
| 312 | .retryable_failure => unreachable, | 314 | .retryable_failure => unreachable, |
| 313 | .astgen_failure => return error.AnalysisFail, | 315 | .astgen_failure, .success => {}, |
| 314 | .success => return, | ||
| 315 | } | 316 | } |
| 316 | } | 317 | } |
| 317 | 318 | ||
| ... | @@ -388,9 +389,18 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -388,9 +389,18 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 388 | var updated_files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, UpdatedFile) = .empty; | 389 | var updated_files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, UpdatedFile) = .empty; |
| 389 | defer cleanupUpdatedFiles(gpa, &updated_files); | 390 | defer cleanupUpdatedFiles(gpa, &updated_files); |
| 390 | 391 | ||
| 391 | for (zcu.import_table.values()) |file_index| { | 392 | for (zcu.import_table.keys()) |file_index| { |
| 393 | if (!zcu.alive_files.contains(file_index)) continue; | ||
| 392 | const file = zcu.fileByIndex(file_index); | 394 | const file = zcu.fileByIndex(file_index); |
| 393 | assert(file.status == .success); | 395 | assert(file.status == .success); |
| 396 | if (file.module_changed) { | ||
| 397 | try updated_files.putNoClobber(gpa, file_index, .{ | ||
| 398 | .file = file, | ||
| 399 | // We intentionally don't map any instructions here; that's the point, the whole file is outdated! | ||
| 400 | .inst_map = .{}, | ||
| 401 | }); | ||
| 402 | continue; | ||
| 403 | } | ||
| 394 | switch (file.getMode()) { | 404 | switch (file.getMode()) { |
| 395 | .zig => {}, // logic below | 405 | .zig => {}, // logic below |
| 396 | .zon => { | 406 | .zon => { |
| ... | @@ -540,10 +550,12 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { | ... | @@ -540,10 +550,12 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void { |
| 540 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { | 550 | for (updated_files.keys(), updated_files.values()) |file_index, updated_file| { |
| 541 | const file = updated_file.file; | 551 | const file = updated_file.file; |
| 542 | 552 | ||
| 543 | const prev_zir = file.prev_zir.?; | 553 | if (file.prev_zir) |prev_zir| { |
| 544 | file.prev_zir = null; | 554 | prev_zir.deinit(gpa); |
| 545 | prev_zir.deinit(gpa); | 555 | gpa.destroy(prev_zir); |
| 546 | gpa.destroy(prev_zir); | 556 | file.prev_zir = null; |
| 557 | } | ||
| 558 | file.module_changed = false; | ||
| 547 | 559 | ||
| 548 | // For every file which has changed, re-scan the namespace of the file's root struct type. | 560 | // For every file which has changed, re-scan the namespace of the file's root struct type. |
| 549 | // These types are special-cased because they don't have an enclosing declaration which will | 561 | // These types are special-cased because they don't have an enclosing declaration which will |
| ... | @@ -661,9 +673,9 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) | ... | @@ -661,9 +673,9 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) |
| 661 | // * The type `std`, and its namespace | 673 | // * The type `std`, and its namespace |
| 662 | // * The type `std.builtin`, and its namespace | 674 | // * The type `std.builtin`, and its namespace |
| 663 | // * A semi-reasonable source location | 675 | // * A semi-reasonable source location |
| 664 | const std_file_imported = pt.importPkg(zcu.std_mod) catch return error.AnalysisFail; | 676 | const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?; |
| 665 | try pt.ensureFileAnalyzed(std_file_imported.file_index); | 677 | try pt.ensureFileAnalyzed(std_file_index); |
| 666 | const std_type: Type = .fromInterned(zcu.fileRootType(std_file_imported.file_index)); | 678 | const std_type: Type = .fromInterned(zcu.fileRootType(std_file_index)); |
| 667 | const std_namespace = std_type.getNamespaceIndex(zcu); | 679 | const std_namespace = std_type.getNamespaceIndex(zcu); |
| 668 | try pt.ensureNamespaceUpToDate(std_namespace); | 680 | try pt.ensureNamespaceUpToDate(std_namespace); |
| 669 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); | 681 | const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls); |
| ... | @@ -675,7 +687,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) | ... | @@ -675,7 +687,7 @@ fn analyzeMemoizedState(pt: Zcu.PerThread, stage: InternPool.MemoizedStateStage) |
| 675 | try pt.ensureNamespaceUpToDate(builtin_namespace); | 687 | try pt.ensureNamespaceUpToDate(builtin_namespace); |
| 676 | const src: Zcu.LazySrcLoc = .{ | 688 | const src: Zcu.LazySrcLoc = .{ |
| 677 | .base_node_inst = builtin_type.typeDeclInst(zcu).?, | 689 | .base_node_inst = builtin_type.typeDeclInst(zcu).?, |
| 678 | .offset = .entire_file, | 690 | .offset = .{ .byte_abs = 0 }, |
| 679 | }; | 691 | }; |
| 680 | 692 | ||
| 681 | var analysis_arena: std.heap.ArenaAllocator = .init(gpa); | 693 | var analysis_arena: std.heap.ArenaAllocator = .init(gpa); |
| ... | @@ -1250,7 +1262,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr | ... | @@ -1250,7 +1262,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr |
| 1250 | 1262 | ||
| 1251 | if (!try nav_ty.hasRuntimeBitsSema(pt)) { | 1263 | if (!try nav_ty.hasRuntimeBitsSema(pt)) { |
| 1252 | if (zcu.comp.config.use_llvm) break :queue_codegen; | 1264 | if (zcu.comp.config.use_llvm) break :queue_codegen; |
| 1253 | if (file.mod.strip) break :queue_codegen; | 1265 | if (file.mod.?.strip) break :queue_codegen; |
| 1254 | } | 1266 | } |
| 1255 | 1267 | ||
| 1256 | // This job depends on any resolve_type_fully jobs queued up before it. | 1268 | // This job depends on any resolve_type_fully jobs queued up before it. |
| ... | @@ -1730,13 +1742,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai | ... | @@ -1730,13 +1742,12 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai |
| 1730 | } | 1742 | } |
| 1731 | } | 1743 | } |
| 1732 | 1744 | ||
| 1733 | /// https://github.com/ziglang/zig/issues/14307 | 1745 | pub fn semaMod(pt: Zcu.PerThread, mod: *Module) !void { |
| 1734 | pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void { | ||
| 1735 | dev.check(.sema); | 1746 | dev.check(.sema); |
| 1736 | const import_file_result = try pt.importPkg(pkg); | 1747 | const file_index = pt.zcu.module_roots.get(mod).?.unwrap().?; |
| 1737 | const root_type = pt.zcu.fileRootType(import_file_result.file_index); | 1748 | const root_type = pt.zcu.fileRootType(file_index); |
| 1738 | if (root_type == .none) { | 1749 | if (root_type == .none) { |
| 1739 | return pt.semaFile(import_file_result.file_index); | 1750 | return pt.semaFile(file_index); |
| 1740 | } | 1751 | } |
| 1741 | } | 1752 | } |
| 1742 | 1753 | ||
| ... | @@ -1808,7 +1819,7 @@ fn createFileRootStruct( | ... | @@ -1808,7 +1819,7 @@ fn createFileRootStruct( |
| 1808 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); | 1819 | try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index }); |
| 1809 | codegen_type: { | 1820 | codegen_type: { |
| 1810 | if (zcu.comp.config.use_llvm) break :codegen_type; | 1821 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 1811 | if (file.mod.strip) break :codegen_type; | 1822 | if (file.mod.?.strip) break :codegen_type; |
| 1812 | // This job depends on any resolve_type_fully jobs queued up before it. | 1823 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 1813 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 1824 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 1814 | } | 1825 | } |
| ... | @@ -1829,7 +1840,7 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. | ... | @@ -1829,7 +1840,7 @@ fn updateFileNamespace(pt: Zcu.PerThread, file_index: Zcu.File.Index) Allocator. |
| 1829 | if (file_root_type == .none) return; | 1840 | if (file_root_type == .none) return; |
| 1830 | 1841 | ||
| 1831 | log.debug("updateFileNamespace mod={s} sub_file_path={s}", .{ | 1842 | log.debug("updateFileNamespace mod={s} sub_file_path={s}", .{ |
| 1832 | file.mod.fully_qualified_name, | 1843 | file.mod.?.fully_qualified_name, |
| 1833 | file.sub_file_path, | 1844 | file.sub_file_path, |
| 1834 | }); | 1845 | }); |
| 1835 | 1846 | ||
| ... | @@ -1872,211 +1883,464 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { | ... | @@ -1872,211 +1883,464 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1872 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); | 1883 | errdefer zcu.intern_pool.remove(pt.tid, struct_ty); |
| 1873 | } | 1884 | } |
| 1874 | 1885 | ||
| 1875 | pub fn importPkg(pt: Zcu.PerThread, mod: *Module) Allocator.Error!Zcu.ImportFileResult { | 1886 | /// Called by AstGen worker threads when an import is seen. If `new_file` is returned, the caller is |
| 1887 | /// then responsible for queueing a new AstGen job for the new file. | ||
| 1888 | /// Assumes that `comp.mutex` is NOT locked. It will be locked by this function where necessary. | ||
| 1889 | pub fn discoverImport( | ||
| 1890 | pt: Zcu.PerThread, | ||
| 1891 | importer_path: Compilation.Path, | ||
| 1892 | import_string: []const u8, | ||
| 1893 | ) Allocator.Error!union(enum) { | ||
| 1894 | module, | ||
| 1895 | existing_file: Zcu.File.Index, | ||
| 1896 | new_file: struct { | ||
| 1897 | index: Zcu.File.Index, | ||
| 1898 | file: *Zcu.File, | ||
| 1899 | }, | ||
| 1900 | } { | ||
| 1876 | const zcu = pt.zcu; | 1901 | const zcu = pt.zcu; |
| 1877 | const gpa = zcu.gpa; | 1902 | const gpa = zcu.gpa; |
| 1878 | 1903 | ||
| 1879 | // The resolved path is used as the key in the import table, to detect if | 1904 | if (!mem.endsWith(u8, import_string, ".zig") and !mem.endsWith(u8, import_string, ".zon")) { |
| 1880 | // an import refers to the same as another, despite different relative paths | 1905 | return .module; |
| 1881 | // or differently mapped package names. | 1906 | } |
| 1882 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | ||
| 1883 | mod.root.root_dir.path orelse ".", | ||
| 1884 | mod.root.sub_path, | ||
| 1885 | mod.root_src_path, | ||
| 1886 | }); | ||
| 1887 | var keep_resolved_path = false; | ||
| 1888 | defer if (!keep_resolved_path) gpa.free(resolved_path); | ||
| 1889 | 1907 | ||
| 1890 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); | 1908 | const new_path = try importer_path.upJoin(gpa, zcu.comp.dirs, import_string); |
| 1909 | errdefer new_path.deinit(gpa); | ||
| 1910 | |||
| 1911 | // We're about to do a GOP on `import_table`, so we need the mutex. | ||
| 1912 | zcu.comp.mutex.lock(); | ||
| 1913 | defer zcu.comp.mutex.unlock(); | ||
| 1914 | |||
| 1915 | const gop = try zcu.import_table.getOrPutAdapted(gpa, new_path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 1891 | errdefer _ = zcu.import_table.pop(); | 1916 | errdefer _ = zcu.import_table.pop(); |
| 1892 | if (gop.found_existing) { | 1917 | if (gop.found_existing) { |
| 1893 | const file_index = gop.value_ptr.*; | 1918 | new_path.deinit(gpa); // we didn't need it for `File.path` |
| 1894 | const file = zcu.fileByIndex(file_index); | 1919 | return .{ .existing_file = gop.key_ptr.* }; |
| 1895 | try file.addReference(zcu, .{ .root = mod }); | ||
| 1896 | return .{ | ||
| 1897 | .file = file, | ||
| 1898 | .file_index = file_index, | ||
| 1899 | .is_new = false, | ||
| 1900 | .is_pkg = true, | ||
| 1901 | }; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | const ip = &zcu.intern_pool; | ||
| 1905 | if (mod.builtin_file) |builtin_file| { | ||
| 1906 | const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path); | ||
| 1907 | const file_index = try ip.createFile(gpa, pt.tid, .{ | ||
| 1908 | .bin_digest = path_digest, | ||
| 1909 | .file = builtin_file, | ||
| 1910 | .root_type = .none, | ||
| 1911 | }); | ||
| 1912 | keep_resolved_path = true; // It's now owned by import_table. | ||
| 1913 | gop.value_ptr.* = file_index; | ||
| 1914 | try builtin_file.addReference(zcu, .{ .root = mod }); | ||
| 1915 | return .{ | ||
| 1916 | .file = builtin_file, | ||
| 1917 | .file_index = file_index, | ||
| 1918 | .is_new = false, | ||
| 1919 | .is_pkg = true, | ||
| 1920 | }; | ||
| 1921 | } | 1920 | } |
| 1922 | 1921 | ||
| 1923 | const sub_file_path = try gpa.dupe(u8, mod.root_src_path); | 1922 | zcu.import_table.lockPointers(); |
| 1924 | errdefer gpa.free(sub_file_path); | 1923 | defer zcu.import_table.unlockPointers(); |
| 1925 | |||
| 1926 | const comp = zcu.comp; | ||
| 1927 | if (comp.file_system_inputs) |fsi| | ||
| 1928 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 1929 | 1924 | ||
| 1930 | const new_file = try gpa.create(Zcu.File); | 1925 | const new_file = try gpa.create(Zcu.File); |
| 1931 | errdefer gpa.destroy(new_file); | 1926 | errdefer gpa.destroy(new_file); |
| 1932 | 1927 | ||
| 1933 | const path_digest = zcu.computePathDigest(mod, sub_file_path); | 1928 | const new_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ |
| 1934 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 1929 | .bin_digest = new_path.digest(), |
| 1935 | .bin_digest = path_digest, | ||
| 1936 | .file = new_file, | 1930 | .file = new_file, |
| 1937 | .root_type = .none, | 1931 | .root_type = .none, |
| 1938 | }); | 1932 | }); |
| 1939 | keep_resolved_path = true; // It's now owned by import_table. | 1933 | errdefer comptime unreachable; // because we don't remove the file from the internpool |
| 1940 | gop.value_ptr.* = new_file_index; | 1934 | |
| 1935 | gop.key_ptr.* = new_file_index; | ||
| 1941 | new_file.* = .{ | 1936 | new_file.* = .{ |
| 1942 | .sub_file_path = sub_file_path, | 1937 | .status = .never_loaded, |
| 1938 | .path = new_path, | ||
| 1943 | .stat = undefined, | 1939 | .stat = undefined, |
| 1940 | .is_builtin = false, | ||
| 1944 | .source = null, | 1941 | .source = null, |
| 1945 | .tree = null, | 1942 | .tree = null, |
| 1946 | .zir = null, | 1943 | .zir = null, |
| 1947 | .zoir = null, | 1944 | .zoir = null, |
| 1948 | .status = .never_loaded, | 1945 | .mod = null, |
| 1949 | .mod = mod, | 1946 | .sub_file_path = undefined, |
| 1947 | .module_changed = false, | ||
| 1948 | .prev_zir = null, | ||
| 1949 | .zoir_invalidated = false, | ||
| 1950 | }; | 1950 | }; |
| 1951 | 1951 | ||
| 1952 | try new_file.addReference(zcu, .{ .root = mod }); | 1952 | return .{ .new_file = .{ |
| 1953 | return .{ | 1953 | .index = new_file_index, |
| 1954 | .file = new_file, | 1954 | .file = new_file, |
| 1955 | .file_index = new_file_index, | 1955 | } }; |
| 1956 | .is_new = true, | ||
| 1957 | .is_pkg = true, | ||
| 1958 | }; | ||
| 1959 | } | 1956 | } |
| 1960 | 1957 | ||
| 1961 | /// Called from a worker thread during AstGen (with the Compilation mutex held). | 1958 | pub fn doImport( |
| 1962 | /// Also called from Sema during semantic analysis. | ||
| 1963 | /// Does not attempt to load the file from disk; just returns a corresponding `*Zcu.File`. | ||
| 1964 | pub fn importFile( | ||
| 1965 | pt: Zcu.PerThread, | 1959 | pt: Zcu.PerThread, |
| 1966 | cur_file: *Zcu.File, | 1960 | /// This file must have its `mod` populated. |
| 1961 | importer: *Zcu.File, | ||
| 1967 | import_string: []const u8, | 1962 | import_string: []const u8, |
| 1968 | ) error{ | 1963 | ) error{ |
| 1969 | OutOfMemory, | 1964 | OutOfMemory, |
| 1970 | ModuleNotFound, | 1965 | ModuleNotFound, |
| 1971 | ImportOutsideModulePath, | 1966 | IllegalZigImport, |
| 1972 | CurrentWorkingDirectoryUnlinked, | 1967 | }!struct { |
| 1973 | }!Zcu.ImportFileResult { | 1968 | file: Zcu.File.Index, |
| 1969 | module_root: ?*Module, | ||
| 1970 | } { | ||
| 1974 | const zcu = pt.zcu; | 1971 | const zcu = pt.zcu; |
| 1975 | const mod = cur_file.mod; | 1972 | const gpa = zcu.gpa; |
| 1976 | 1973 | const imported_mod: ?*Module = m: { | |
| 1977 | if (std.mem.eql(u8, import_string, "std")) { | 1974 | if (mem.eql(u8, import_string, "std")) break :m zcu.std_mod; |
| 1978 | return pt.importPkg(zcu.std_mod); | 1975 | if (mem.eql(u8, import_string, "root")) break :m zcu.root_mod; |
| 1979 | } | 1976 | if (mem.eql(u8, import_string, "builtin")) { |
| 1980 | if (std.mem.eql(u8, import_string, "root")) { | 1977 | const opts = importer.mod.?.getBuiltinOptions(zcu.comp.config); |
| 1981 | return pt.importPkg(zcu.root_mod); | 1978 | break :m zcu.builtin_modules.get(opts.hash()).?; |
| 1982 | } | 1979 | } |
| 1983 | if (mod.deps.get(import_string)) |pkg| { | 1980 | break :m importer.mod.?.deps.get(import_string); |
| 1984 | return pt.importPkg(pkg); | 1981 | }; |
| 1982 | if (imported_mod) |mod| { | ||
| 1983 | if (zcu.module_roots.get(mod).?.unwrap()) |file_index| { | ||
| 1984 | return .{ | ||
| 1985 | .file = file_index, | ||
| 1986 | .module_root = mod, | ||
| 1987 | }; | ||
| 1988 | } | ||
| 1985 | } | 1989 | } |
| 1986 | if (!std.mem.endsWith(u8, import_string, ".zig") and | 1990 | if (!std.mem.endsWith(u8, import_string, ".zig") and |
| 1987 | !std.mem.endsWith(u8, import_string, ".zon")) | 1991 | !std.mem.endsWith(u8, import_string, ".zon")) |
| 1988 | { | 1992 | { |
| 1989 | return error.ModuleNotFound; | 1993 | return error.ModuleNotFound; |
| 1990 | } | 1994 | } |
| 1995 | const path = try importer.path.upJoin(gpa, zcu.comp.dirs, import_string); | ||
| 1996 | defer path.deinit(gpa); | ||
| 1997 | if (try path.isIllegalZigImport(gpa, zcu.comp.dirs)) { | ||
| 1998 | return error.IllegalZigImport; | ||
| 1999 | } | ||
| 2000 | return .{ | ||
| 2001 | .file = zcu.import_table.getKeyAdapted(path, Zcu.ImportTableAdapter{ .zcu = zcu }).?, | ||
| 2002 | .module_root = null, | ||
| 2003 | }; | ||
| 2004 | } | ||
| 2005 | /// This is called once during `Compilation.create` and never again. "builtin" modules don't yet | ||
| 2006 | /// exist, so are not added to `module_roots` here. They must be added when they are created. | ||
| 2007 | pub fn populateModuleRootTable(pt: Zcu.PerThread) error{ | ||
| 2008 | OutOfMemory, | ||
| 2009 | /// One of the specified modules had its root source file at an illegal path. | ||
| 2010 | IllegalZigImport, | ||
| 2011 | }!void { | ||
| 2012 | const zcu = pt.zcu; | ||
| 1991 | const gpa = zcu.gpa; | 2013 | const gpa = zcu.gpa; |
| 1992 | 2014 | ||
| 1993 | // The resolved path is used as the key in the import table, to detect if | 2015 | // We'll initially add [mod, undefined] pairs, and when we reach the pair while |
| 1994 | // an import refers to the same as another, despite different relative paths | 2016 | // iterating, rewrite the undefined value. |
| 1995 | // or differently mapped package names. | 2017 | const roots = &zcu.module_roots; |
| 1996 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2018 | roots.clearRetainingCapacity(); |
| 1997 | mod.root.root_dir.path orelse ".", | 2019 | |
| 1998 | mod.root.sub_path, | 2020 | // Start with: |
| 1999 | cur_file.sub_file_path, | 2021 | // * `std_mod`, which is the main root of analysis |
| 2000 | "..", | 2022 | // * `root_mod`, which is `@import("root")` |
| 2001 | import_string, | 2023 | // * `main_mod`, which is a special analysis root in tests (and otherwise equal to `root_mod`) |
| 2002 | }); | 2024 | // All other modules will be found by traversing their dependency tables. |
| 2025 | try roots.ensureTotalCapacity(gpa, 3); | ||
| 2026 | roots.putAssumeCapacity(zcu.std_mod, undefined); | ||
| 2027 | roots.putAssumeCapacity(zcu.root_mod, undefined); | ||
| 2028 | roots.putAssumeCapacity(zcu.main_mod, undefined); | ||
| 2029 | var i: usize = 0; | ||
| 2030 | while (i < roots.count()) { | ||
| 2031 | const mod = roots.keys()[i]; | ||
| 2032 | try roots.ensureUnusedCapacity(gpa, mod.deps.count()); | ||
| 2033 | for (mod.deps.values()) |dep| { | ||
| 2034 | const gop = roots.getOrPutAssumeCapacity(dep); | ||
| 2035 | _ = gop; // we want to leave the value undefined if it was added | ||
| 2036 | } | ||
| 2003 | 2037 | ||
| 2004 | var keep_resolved_path = false; | 2038 | const root_file_out = &roots.values()[i]; |
| 2005 | defer if (!keep_resolved_path) gpa.free(resolved_path); | 2039 | roots.lockPointers(); |
| 2040 | defer roots.unlockPointers(); | ||
| 2006 | 2041 | ||
| 2007 | const gop = try zcu.import_table.getOrPut(gpa, resolved_path); | 2042 | i += 1; |
| 2008 | errdefer _ = zcu.import_table.pop(); | 2043 | |
| 2009 | if (gop.found_existing) { | 2044 | if (Zcu.File.modeFromPath(mod.root_src_path) == null) { |
| 2010 | const file_index = gop.value_ptr.*; | 2045 | root_file_out.* = .none; |
| 2011 | return .{ | 2046 | continue; |
| 2012 | .file = zcu.fileByIndex(file_index), | 2047 | } |
| 2013 | .file_index = file_index, | 2048 | |
| 2014 | .is_new = false, | 2049 | const path = try mod.root.join(gpa, zcu.comp.dirs, mod.root_src_path); |
| 2015 | .is_pkg = false, | 2050 | errdefer path.deinit(gpa); |
| 2051 | |||
| 2052 | if (try path.isIllegalZigImport(gpa, zcu.comp.dirs)) { | ||
| 2053 | return error.IllegalZigImport; | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | const gop = try zcu.import_table.getOrPutAdapted(gpa, path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 2057 | errdefer _ = zcu.import_table.pop(); | ||
| 2058 | |||
| 2059 | if (gop.found_existing) { | ||
| 2060 | path.deinit(gpa); | ||
| 2061 | root_file_out.* = gop.key_ptr.*.toOptional(); | ||
| 2062 | continue; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | zcu.import_table.lockPointers(); | ||
| 2066 | defer zcu.import_table.unlockPointers(); | ||
| 2067 | |||
| 2068 | const new_file = try gpa.create(Zcu.File); | ||
| 2069 | errdefer gpa.destroy(new_file); | ||
| 2070 | |||
| 2071 | const new_file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ | ||
| 2072 | .bin_digest = path.digest(), | ||
| 2073 | .file = new_file, | ||
| 2074 | .root_type = .none, | ||
| 2075 | }); | ||
| 2076 | errdefer comptime unreachable; // because we don't remove the file from the internpool | ||
| 2077 | |||
| 2078 | gop.key_ptr.* = new_file_index; | ||
| 2079 | root_file_out.* = new_file_index.toOptional(); | ||
| 2080 | new_file.* = .{ | ||
| 2081 | .status = .never_loaded, | ||
| 2082 | .path = path, | ||
| 2083 | .stat = undefined, | ||
| 2084 | .is_builtin = false, | ||
| 2085 | .source = null, | ||
| 2086 | .tree = null, | ||
| 2087 | .zir = null, | ||
| 2088 | .zoir = null, | ||
| 2089 | .mod = null, | ||
| 2090 | .sub_file_path = undefined, | ||
| 2091 | .module_changed = false, | ||
| 2092 | .prev_zir = null, | ||
| 2093 | .zoir_invalidated = false, | ||
| 2016 | }; | 2094 | }; |
| 2017 | } | 2095 | } |
| 2096 | } | ||
| 2018 | 2097 | ||
| 2019 | const ip = &zcu.intern_pool; | 2098 | /// Clears and re-populates `pt.zcu.alive_files`, and determines the module identity of every alive |
| 2099 | /// file. If a file's module changes, its `module_changed` flag is set for `updateZirRefs` to see. | ||
| 2100 | /// Also clears and re-populates `failed_imports` and `multi_module_err` based on the set of alive | ||
| 2101 | /// files. | ||
| 2102 | /// | ||
| 2103 | /// Live files are also added as file system inputs if necessary. | ||
| 2104 | /// | ||
| 2105 | /// Returns whether there is any live file which is failed. Howewver, this function does *not* | ||
| 2106 | /// modify `pt.zcu.skip_analysis_this_update`. | ||
| 2107 | /// | ||
| 2108 | /// If an error is returned, `pt.zcu.alive_files` might contain undefined values. | ||
| 2109 | pub fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool { | ||
| 2110 | const zcu = pt.zcu; | ||
| 2111 | const comp = zcu.comp; | ||
| 2112 | const gpa = zcu.gpa; | ||
| 2020 | 2113 | ||
| 2021 | const new_file = try gpa.create(Zcu.File); | 2114 | var any_fatal_files = false; |
| 2022 | errdefer gpa.destroy(new_file); | 2115 | zcu.multi_module_err = null; |
| 2116 | zcu.failed_imports.clearRetainingCapacity(); | ||
| 2117 | zcu.alive_files.clearRetainingCapacity(); | ||
| 2118 | |||
| 2119 | // This function will iterate the keys of `alive_files`, adding new entries as it discovers | ||
| 2120 | // imports. Once a file is in `alive_files`, it has its `mod` field up-to-date. If conflicting | ||
| 2121 | // imports are discovered for a file, we will set `multi_module_err`. Crucially, this traversal | ||
| 2122 | // is single-threaded, and depends only on the order of the imports map from AstGen, which makes | ||
| 2123 | // its behavior (in terms of which multi module errors are discovered) entirely consistent in a | ||
| 2124 | // multi-threaded environment (where things like file indices could differ between compiler runs). | ||
| 2125 | |||
| 2126 | // The roots of our file liveness analysis will be the analysis roots. | ||
| 2127 | try zcu.alive_files.ensureTotalCapacity(gpa, zcu.analysis_roots.len); | ||
| 2128 | for (zcu.analysis_roots.slice()) |mod| { | ||
| 2129 | const file_index = zcu.module_roots.get(mod).?.unwrap() orelse continue; | ||
| 2130 | const file = zcu.fileByIndex(file_index); | ||
| 2023 | 2131 | ||
| 2024 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | 2132 | file.mod = mod; |
| 2025 | mod.root.root_dir.path orelse ".", | 2133 | file.sub_file_path = mod.root_src_path; |
| 2026 | mod.root.sub_path, | ||
| 2027 | }); | ||
| 2028 | defer gpa.free(resolved_root_path); | ||
| 2029 | 2134 | ||
| 2030 | const sub_file_path = p: { | 2135 | zcu.alive_files.putAssumeCapacityNoClobber(file_index, .{ .analysis_root = mod }); |
| 2031 | const relative = std.fs.path.relative(gpa, resolved_root_path, resolved_path) catch |err| switch (err) { | 2136 | } |
| 2032 | error.Unexpected => unreachable, | 2137 | |
| 2033 | else => |e| return e, | 2138 | var live_check_idx: usize = 0; |
| 2034 | }; | 2139 | while (live_check_idx < zcu.alive_files.count()) { |
| 2035 | errdefer gpa.free(relative); | 2140 | const file_idx = zcu.alive_files.keys()[live_check_idx]; |
| 2141 | const file = zcu.fileByIndex(file_idx); | ||
| 2142 | live_check_idx += 1; | ||
| 2036 | 2143 | ||
| 2037 | if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) { | 2144 | switch (file.status) { |
| 2038 | break :p relative; | 2145 | .never_loaded => unreachable, // everything reachable is loaded by the AstGen workers |
| 2146 | .retryable_failure, .astgen_failure => any_fatal_files = true, | ||
| 2147 | .success => {}, | ||
| 2039 | } | 2148 | } |
| 2040 | return error.ImportOutsideModulePath; | ||
| 2041 | }; | ||
| 2042 | errdefer gpa.free(sub_file_path); | ||
| 2043 | 2149 | ||
| 2044 | log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{ | 2150 | try comp.appendFileSystemInput(file.path); |
| 2045 | resolved_root_path, resolved_path, sub_file_path, import_string, | 2151 | |
| 2046 | }); | 2152 | switch (file.getMode()) { |
| 2153 | .zig => {}, // continue to logic below | ||
| 2154 | .zon => continue, // ZON can't import anything | ||
| 2155 | } | ||
| 2156 | |||
| 2157 | if (file.status != .success) continue; // ZIR not valid if there was a file failure | ||
| 2158 | |||
| 2159 | const zir = file.zir.?; | ||
| 2160 | const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | ||
| 2161 | if (imports_index == 0) continue; // this Zig file has no imports | ||
| 2162 | const extra = zir.extraData(Zir.Inst.Imports, imports_index); | ||
| 2163 | var extra_index = extra.end; | ||
| 2164 | try zcu.alive_files.ensureUnusedCapacity(gpa, extra.data.imports_len); | ||
| 2165 | for (0..extra.data.imports_len) |_| { | ||
| 2166 | const item = zir.extraData(Zir.Inst.Imports.Item, extra_index); | ||
| 2167 | extra_index = item.end; | ||
| 2168 | const import_path = zir.nullTerminatedString(item.data.name); | ||
| 2169 | |||
| 2170 | if (std.mem.eql(u8, import_path, "builtin")) { | ||
| 2171 | // We've not necessarily generated builtin modules yet, so `doImport` could fail. Instead, | ||
| 2172 | // create the module here. Then, since we know that `builtin.zig` doesn't have an error and | ||
| 2173 | // has no imports other than 'std', we can just continue onto the next import. | ||
| 2174 | try pt.updateBuiltinModule(file.mod.?.getBuiltinOptions(comp.config)); | ||
| 2175 | continue; | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | const res = pt.doImport(file, import_path) catch |err| switch (err) { | ||
| 2179 | error.OutOfMemory => |e| return e, | ||
| 2180 | error.ModuleNotFound => { | ||
| 2181 | // It'd be nice if this were a file-level error, but allowing this turns out to | ||
| 2182 | // be quite important in practice, e.g. for optional dependencies whose import | ||
| 2183 | // is behind a comptime condition. So, the error here happens in `Sema` instead. | ||
| 2184 | continue; | ||
| 2185 | }, | ||
| 2186 | error.IllegalZigImport => { | ||
| 2187 | try zcu.failed_imports.append(gpa, .{ | ||
| 2188 | .file_index = file_idx, | ||
| 2189 | .import_string = item.data.name, | ||
| 2190 | .import_token = item.data.token, | ||
| 2191 | .kind = .illegal_zig_import, | ||
| 2192 | }); | ||
| 2193 | continue; | ||
| 2194 | }, | ||
| 2195 | }; | ||
| 2196 | |||
| 2197 | // If the import was not of a module, we propagate our own module. | ||
| 2198 | const imported_mod = res.module_root orelse file.mod.?; | ||
| 2199 | const imported_file = zcu.fileByIndex(res.file); | ||
| 2200 | |||
| 2201 | const imported_ref: Zcu.File.Reference = .{ .import = .{ | ||
| 2202 | .importer = file_idx, | ||
| 2203 | .tok = item.data.token, | ||
| 2204 | .module = res.module_root, | ||
| 2205 | } }; | ||
| 2206 | |||
| 2207 | const gop = zcu.alive_files.getOrPutAssumeCapacity(res.file); | ||
| 2208 | if (gop.found_existing) { | ||
| 2209 | // This means `imported_file.mod` is already populated. If it doesn't match | ||
| 2210 | // `imported_mod`, then this file exists in multiple modules. | ||
| 2211 | if (imported_file.mod.? != imported_mod) { | ||
| 2212 | // We only report the first multi-module error we see. Thanks to this traversal | ||
| 2213 | // being deterministic, this doesn't raise consistency issues. Moreover, it's a | ||
| 2214 | // useful behavior; we know that this error can be reached *without* realising | ||
| 2215 | // that any other files are multi-module, so it's probably approximately where | ||
| 2216 | // the problem "begins". Any compilation with a multi-module file is likely to | ||
| 2217 | // have a huge number of them by transitive imports, so just reporting this one | ||
| 2218 | // hopefully keeps the error focused. | ||
| 2219 | zcu.multi_module_err = .{ | ||
| 2220 | .file = file_idx, | ||
| 2221 | .modules = .{ imported_file.mod.?, imported_mod }, | ||
| 2222 | .refs = .{ gop.value_ptr.*, imported_ref }, | ||
| 2223 | }; | ||
| 2224 | // If we discover a multi-module error, it's the only error which matters, and we | ||
| 2225 | // can't discern any useful information about the file's own imports; so just do | ||
| 2226 | // an early exit now we've populated `zcu.multi_module_err`. | ||
| 2227 | return any_fatal_files; | ||
| 2228 | } | ||
| 2229 | continue; | ||
| 2230 | } | ||
| 2231 | // We're the first thing we've found referencing `res.file`. | ||
| 2232 | gop.value_ptr.* = imported_ref; | ||
| 2233 | if (imported_file.mod) |m| { | ||
| 2234 | if (m == imported_mod) { | ||
| 2235 | // Great, the module and sub path are already populated correctly. | ||
| 2236 | continue; | ||
| 2237 | } | ||
| 2238 | } | ||
| 2239 | // We need to set the file's module, meaning we also need to compute its sub path. | ||
| 2240 | // This string is externally managed and has a lifetime at least equal to the | ||
| 2241 | // lifetime of `imported_file`. `null` means the file is outside its module root. | ||
| 2242 | switch (imported_file.path.isNested(imported_mod.root)) { | ||
| 2243 | .yes => |sub_path| { | ||
| 2244 | if (imported_file.mod != null) { | ||
| 2245 | // There was a module from a previous update; instruct `updateZirRefs` to | ||
| 2246 | // invalidate everything. | ||
| 2247 | imported_file.module_changed = true; | ||
| 2248 | } | ||
| 2249 | imported_file.mod = imported_mod; | ||
| 2250 | imported_file.sub_file_path = sub_path; | ||
| 2251 | }, | ||
| 2252 | .different_roots, .no => { | ||
| 2253 | try zcu.failed_imports.append(gpa, .{ | ||
| 2254 | .file_index = file_idx, | ||
| 2255 | .import_string = item.data.name, | ||
| 2256 | .import_token = item.data.token, | ||
| 2257 | .kind = .file_outside_module_root, | ||
| 2258 | }); | ||
| 2259 | _ = zcu.alive_files.pop(); // we failed to populate `mod`/`sub_file_path` | ||
| 2260 | }, | ||
| 2261 | } | ||
| 2262 | } | ||
| 2263 | } | ||
| 2047 | 2264 | ||
| 2265 | return any_fatal_files; | ||
| 2266 | } | ||
| 2267 | |||
| 2268 | /// Ensures that the `@import("builtin")` module corresponding to `opts` is available in | ||
| 2269 | /// `builtin_modules`, and that its file is populated. Also ensures the file on disk is | ||
| 2270 | /// up-to-date, setting a misc failure if updating it fails. | ||
| 2271 | /// Asserts that the imported `builtin.zig` has no ZIR errors, and that it has only one | ||
| 2272 | /// import, which is 'std'. | ||
| 2273 | pub fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!void { | ||
| 2274 | const zcu = pt.zcu; | ||
| 2048 | const comp = zcu.comp; | 2275 | const comp = zcu.comp; |
| 2049 | if (comp.file_system_inputs) |fsi| | 2276 | const gpa = zcu.gpa; |
| 2050 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 2051 | 2277 | ||
| 2052 | const path_digest = zcu.computePathDigest(mod, sub_file_path); | 2278 | const gop = try zcu.builtin_modules.getOrPut(gpa, opts.hash()); |
| 2053 | const new_file_index = try ip.createFile(gpa, pt.tid, .{ | 2279 | if (gop.found_existing) return; // the `File` is up-to-date |
| 2054 | .bin_digest = path_digest, | 2280 | errdefer _ = zcu.builtin_modules.pop(); |
| 2055 | .file = new_file, | 2281 | |
| 2056 | .root_type = .none, | 2282 | const mod: *Module = try .createBuiltin(comp.arena, opts, comp.dirs); |
| 2057 | }); | 2283 | assert(std.mem.eql(u8, &mod.getBuiltinOptions(comp.config).hash(), gop.key_ptr)); // builtin is its own builtin |
| 2058 | keep_resolved_path = true; // It's now owned by import_table. | 2284 | |
| 2059 | gop.value_ptr.* = new_file_index; | 2285 | const path = try mod.root.join(gpa, comp.dirs, "builtin.zig"); |
| 2060 | new_file.* = .{ | 2286 | errdefer path.deinit(gpa); |
| 2061 | .sub_file_path = sub_file_path, | ||
| 2062 | 2287 | ||
| 2288 | const file_gop = try zcu.import_table.getOrPutAdapted(gpa, path, Zcu.ImportTableAdapter{ .zcu = zcu }); | ||
| 2289 | // `Compilation.Path.isIllegalZigImport` checks guard file creation, so | ||
| 2290 | // there isn't an `import_table` entry for this path yet. | ||
| 2291 | assert(!file_gop.found_existing); | ||
| 2292 | errdefer _ = zcu.import_table.pop(); | ||
| 2293 | |||
| 2294 | try zcu.module_roots.ensureUnusedCapacity(gpa, 1); | ||
| 2295 | |||
| 2296 | const file = try gpa.create(Zcu.File); | ||
| 2297 | errdefer gpa.destroy(file); | ||
| 2298 | |||
| 2299 | file.* = .{ | ||
| 2063 | .status = .never_loaded, | 2300 | .status = .never_loaded, |
| 2064 | .stat = undefined, | 2301 | .stat = undefined, |
| 2065 | 2302 | .path = path, | |
| 2303 | .is_builtin = true, | ||
| 2066 | .source = null, | 2304 | .source = null, |
| 2067 | .tree = null, | 2305 | .tree = null, |
| 2068 | .zir = null, | 2306 | .zir = null, |
| 2069 | .zoir = null, | 2307 | .zoir = null, |
| 2070 | |||
| 2071 | .mod = mod, | 2308 | .mod = mod, |
| 2309 | .sub_file_path = "builtin.zig", | ||
| 2310 | .module_changed = false, | ||
| 2311 | .prev_zir = null, | ||
| 2312 | .zoir_invalidated = false, | ||
| 2072 | }; | 2313 | }; |
| 2073 | 2314 | ||
| 2074 | return .{ | 2315 | const file_index = try zcu.intern_pool.createFile(gpa, pt.tid, .{ |
| 2075 | .file = new_file, | 2316 | .bin_digest = path.digest(), |
| 2076 | .file_index = new_file_index, | 2317 | .file = file, |
| 2077 | .is_new = true, | 2318 | .root_type = .none, |
| 2078 | .is_pkg = false, | 2319 | }); |
| 2079 | }; | 2320 | |
| 2321 | gop.value_ptr.* = mod; | ||
| 2322 | file_gop.key_ptr.* = file_index; | ||
| 2323 | zcu.module_roots.putAssumeCapacityNoClobber(mod, file_index.toOptional()); | ||
| 2324 | try opts.populateFile(gpa, file); | ||
| 2325 | |||
| 2326 | assert(file.status == .success); | ||
| 2327 | assert(!file.zir.?.hasCompileErrors()); | ||
| 2328 | { | ||
| 2329 | // Check that it has only one import, which is 'std'. | ||
| 2330 | const imports_idx = file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | ||
| 2331 | assert(imports_idx != 0); // there is an import | ||
| 2332 | const extra = file.zir.?.extraData(Zir.Inst.Imports, imports_idx); | ||
| 2333 | assert(extra.data.imports_len == 1); // there is exactly one import | ||
| 2334 | const item = file.zir.?.extraData(Zir.Inst.Imports.Item, extra.end); | ||
| 2335 | const import_path = file.zir.?.nullTerminatedString(item.data.name); | ||
| 2336 | assert(mem.eql(u8, import_path, "std")); // the single import is of 'std' | ||
| 2337 | } | ||
| 2338 | |||
| 2339 | Builtin.updateFileOnDisk(file, comp) catch |err| comp.setMiscFailure( | ||
| 2340 | .write_builtin_zig, | ||
| 2341 | "unable to write '{}': {s}", | ||
| 2342 | .{ file.path.fmt(comp), @errorName(err) }, | ||
| 2343 | ); | ||
| 2080 | } | 2344 | } |
| 2081 | 2345 | ||
| 2082 | pub fn embedFile( | 2346 | pub fn embedFile( |
| ... | @@ -2091,63 +2355,49 @@ pub fn embedFile( | ... | @@ -2091,63 +2355,49 @@ pub fn embedFile( |
| 2091 | const zcu = pt.zcu; | 2355 | const zcu = pt.zcu; |
| 2092 | const gpa = zcu.gpa; | 2356 | const gpa = zcu.gpa; |
| 2093 | 2357 | ||
| 2094 | if (cur_file.mod.deps.get(import_string)) |mod| { | 2358 | const opt_mod: ?*Module = m: { |
| 2095 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2359 | if (mem.eql(u8, import_string, "std")) break :m zcu.std_mod; |
| 2096 | mod.root.root_dir.path orelse ".", | 2360 | if (mem.eql(u8, import_string, "root")) break :m zcu.root_mod; |
| 2097 | mod.root.sub_path, | 2361 | if (mem.eql(u8, import_string, "builtin")) { |
| 2098 | mod.root_src_path, | 2362 | const opts = cur_file.mod.?.getBuiltinOptions(zcu.comp.config); |
| 2099 | }); | 2363 | break :m zcu.builtin_modules.get(opts.hash()).?; |
| 2100 | errdefer gpa.free(resolved_path); | 2364 | } |
| 2101 | 2365 | break :m cur_file.mod.?.deps.get(import_string); | |
| 2102 | const gop = try zcu.embed_table.getOrPut(gpa, resolved_path); | 2366 | }; |
| 2103 | errdefer assert(std.mem.eql(u8, zcu.embed_table.pop().?.key, resolved_path)); | 2367 | if (opt_mod) |mod| { |
| 2368 | const path = try mod.root.join(gpa, zcu.comp.dirs, mod.root_src_path); | ||
| 2369 | errdefer path.deinit(gpa); | ||
| 2104 | 2370 | ||
| 2371 | const gop = try zcu.embed_table.getOrPutAdapted(gpa, path, Zcu.EmbedTableAdapter{}); | ||
| 2105 | if (gop.found_existing) { | 2372 | if (gop.found_existing) { |
| 2106 | gpa.free(resolved_path); // we're not using this key | 2373 | path.deinit(gpa); // we're not using this key |
| 2107 | return @enumFromInt(gop.index); | 2374 | return @enumFromInt(gop.index); |
| 2108 | } | 2375 | } |
| 2109 | 2376 | errdefer _ = zcu.embed_table.pop(); | |
| 2110 | gop.value_ptr.* = try pt.newEmbedFile(mod, mod.root_src_path, resolved_path); | 2377 | gop.key_ptr.* = try pt.newEmbedFile(path); |
| 2111 | return @enumFromInt(gop.index); | 2378 | return @enumFromInt(gop.index); |
| 2112 | } | 2379 | } |
| 2113 | 2380 | ||
| 2114 | // The resolved path is used as the key in the table, to detect if a file | 2381 | const embed_file: *Zcu.EmbedFile, const embed_file_idx: Zcu.EmbedFile.Index = ef: { |
| 2115 | // refers to the same as another, despite different relative paths. | 2382 | const path = try cur_file.path.upJoin(gpa, zcu.comp.dirs, import_string); |
| 2116 | const resolved_path = try std.fs.path.resolve(gpa, &.{ | 2383 | errdefer path.deinit(gpa); |
| 2117 | cur_file.mod.root.root_dir.path orelse ".", | 2384 | const gop = try zcu.embed_table.getOrPutAdapted(gpa, path, Zcu.EmbedTableAdapter{}); |
| 2118 | cur_file.mod.root.sub_path, | 2385 | if (gop.found_existing) { |
| 2119 | cur_file.sub_file_path, | 2386 | path.deinit(gpa); // we're not using this key |
| 2120 | "..", | 2387 | break :ef .{ gop.key_ptr.*, @enumFromInt(gop.index) }; |
| 2121 | import_string, | 2388 | } else { |
| 2122 | }); | 2389 | errdefer _ = zcu.embed_table.pop(); |
| 2123 | errdefer gpa.free(resolved_path); | 2390 | gop.key_ptr.* = try pt.newEmbedFile(path); |
| 2124 | 2391 | break :ef .{ gop.key_ptr.*, @enumFromInt(gop.index) }; | |
| 2125 | const gop = try zcu.embed_table.getOrPut(gpa, resolved_path); | 2392 | } |
| 2126 | errdefer assert(std.mem.eql(u8, zcu.embed_table.pop().?.key, resolved_path)); | ||
| 2127 | |||
| 2128 | if (gop.found_existing) { | ||
| 2129 | gpa.free(resolved_path); // we're not using this key | ||
| 2130 | return @enumFromInt(gop.index); | ||
| 2131 | } | ||
| 2132 | |||
| 2133 | const resolved_root_path = try std.fs.path.resolve(gpa, &.{ | ||
| 2134 | cur_file.mod.root.root_dir.path orelse ".", | ||
| 2135 | cur_file.mod.root.sub_path, | ||
| 2136 | }); | ||
| 2137 | defer gpa.free(resolved_root_path); | ||
| 2138 | |||
| 2139 | const sub_file_path = std.fs.path.relative(gpa, resolved_root_path, resolved_path) catch |err| switch (err) { | ||
| 2140 | error.Unexpected => unreachable, | ||
| 2141 | else => |e| return e, | ||
| 2142 | }; | 2393 | }; |
| 2143 | defer gpa.free(sub_file_path); | ||
| 2144 | 2394 | ||
| 2145 | if (isUpDir(sub_file_path) or std.fs.path.isAbsolute(sub_file_path)) { | 2395 | switch (embed_file.path.isNested(cur_file.mod.?.root)) { |
| 2146 | return error.ImportOutsideModulePath; | 2396 | .yes => {}, |
| 2397 | .different_roots, .no => return error.ImportOutsideModulePath, | ||
| 2147 | } | 2398 | } |
| 2148 | 2399 | ||
| 2149 | gop.value_ptr.* = try pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path); | 2400 | return embed_file_idx; |
| 2150 | return @enumFromInt(gop.index); | ||
| 2151 | } | 2401 | } |
| 2152 | 2402 | ||
| 2153 | pub fn updateEmbedFile( | 2403 | pub fn updateEmbedFile( |
| ... | @@ -2177,7 +2427,10 @@ fn updateEmbedFileInner( | ... | @@ -2177,7 +2427,10 @@ fn updateEmbedFileInner( |
| 2177 | const gpa = zcu.gpa; | 2427 | const gpa = zcu.gpa; |
| 2178 | const ip = &zcu.intern_pool; | 2428 | const ip = &zcu.intern_pool; |
| 2179 | 2429 | ||
| 2180 | var file = try ef.owner.root.openFile(ef.sub_file_path.toSlice(ip), .{}); | 2430 | var file = f: { |
| 2431 | const dir, const sub_path = ef.path.openInfo(zcu.comp.dirs); | ||
| 2432 | break :f try dir.openFile(sub_path, .{}); | ||
| 2433 | }; | ||
| 2181 | defer file.close(); | 2434 | defer file.close(); |
| 2182 | 2435 | ||
| 2183 | const stat: Cache.File.Stat = .fromFs(try file.stat()); | 2436 | const stat: Cache.File.Stat = .fromFs(try file.stat()); |
| ... | @@ -2232,28 +2485,21 @@ fn updateEmbedFileInner( | ... | @@ -2232,28 +2485,21 @@ fn updateEmbedFileInner( |
| 2232 | ef.stat = stat; | 2485 | ef.stat = stat; |
| 2233 | } | 2486 | } |
| 2234 | 2487 | ||
| 2488 | /// Assumes that `path` is allocated into `gpa`. Takes ownership of `path` on success. | ||
| 2235 | fn newEmbedFile( | 2489 | fn newEmbedFile( |
| 2236 | pt: Zcu.PerThread, | 2490 | pt: Zcu.PerThread, |
| 2237 | mod: *Module, | 2491 | path: Compilation.Path, |
| 2238 | /// The path of the file to embed relative to the root of `mod`. | ||
| 2239 | sub_file_path: []const u8, | ||
| 2240 | /// The resolved path of the file to embed. | ||
| 2241 | resolved_path: []const u8, | ||
| 2242 | ) !*Zcu.EmbedFile { | 2492 | ) !*Zcu.EmbedFile { |
| 2243 | const zcu = pt.zcu; | 2493 | const zcu = pt.zcu; |
| 2244 | const comp = zcu.comp; | 2494 | const comp = zcu.comp; |
| 2245 | const gpa = zcu.gpa; | 2495 | const gpa = zcu.gpa; |
| 2246 | const ip = &zcu.intern_pool; | 2496 | const ip = &zcu.intern_pool; |
| 2247 | 2497 | ||
| 2248 | if (comp.file_system_inputs) |fsi| | ||
| 2249 | try comp.appendFileSystemInput(fsi, mod.root, sub_file_path); | ||
| 2250 | |||
| 2251 | const new_file = try gpa.create(Zcu.EmbedFile); | 2498 | const new_file = try gpa.create(Zcu.EmbedFile); |
| 2252 | errdefer gpa.destroy(new_file); | 2499 | errdefer gpa.destroy(new_file); |
| 2253 | 2500 | ||
| 2254 | new_file.* = .{ | 2501 | new_file.* = .{ |
| 2255 | .owner = mod, | 2502 | .path = path, |
| 2256 | .sub_file_path = try ip.getOrPutString(gpa, pt.tid, sub_file_path, .no_embedded_nulls), | ||
| 2257 | .val = .none, | 2503 | .val = .none, |
| 2258 | .err = null, | 2504 | .err = null, |
| 2259 | .stat = undefined, | 2505 | .stat = undefined, |
| ... | @@ -2262,6 +2508,8 @@ fn newEmbedFile( | ... | @@ -2262,6 +2508,8 @@ fn newEmbedFile( |
| 2262 | var opt_ip_str: ?InternPool.String = null; | 2508 | var opt_ip_str: ?InternPool.String = null; |
| 2263 | try pt.updateEmbedFile(new_file, &opt_ip_str); | 2509 | try pt.updateEmbedFile(new_file, &opt_ip_str); |
| 2264 | 2510 | ||
| 2511 | try comp.appendFileSystemInput(path); | ||
| 2512 | |||
| 2265 | // Add the file contents to the `whole` cache manifest if necessary. | 2513 | // Add the file contents to the `whole` cache manifest if necessary. |
| 2266 | cache: { | 2514 | cache: { |
| 2267 | const whole = switch (zcu.comp.cache_use) { | 2515 | const whole = switch (zcu.comp.cache_use) { |
| ... | @@ -2269,17 +2517,18 @@ fn newEmbedFile( | ... | @@ -2269,17 +2517,18 @@ fn newEmbedFile( |
| 2269 | .incremental => break :cache, | 2517 | .incremental => break :cache, |
| 2270 | }; | 2518 | }; |
| 2271 | const man = whole.cache_manifest orelse break :cache; | 2519 | const man = whole.cache_manifest orelse break :cache; |
| 2272 | const ip_str = opt_ip_str orelse break :cache; | 2520 | const ip_str = opt_ip_str orelse break :cache; // this will be a compile error |
| 2273 | |||
| 2274 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); | ||
| 2275 | errdefer gpa.free(copied_resolved_path); | ||
| 2276 | 2521 | ||
| 2277 | const array_len = Value.fromInterned(new_file.val).typeOf(zcu).childType(zcu).arrayLen(zcu); | 2522 | const array_len = Value.fromInterned(new_file.val).typeOf(zcu).childType(zcu).arrayLen(zcu); |
| 2523 | const contents = ip_str.toSlice(array_len, ip); | ||
| 2524 | |||
| 2525 | const path_str = try path.toAbsolute(comp.dirs, gpa); | ||
| 2526 | defer gpa.free(path_str); | ||
| 2278 | 2527 | ||
| 2279 | whole.cache_manifest_mutex.lock(); | 2528 | whole.cache_manifest_mutex.lock(); |
| 2280 | defer whole.cache_manifest_mutex.unlock(); | 2529 | defer whole.cache_manifest_mutex.unlock(); |
| 2281 | 2530 | ||
| 2282 | man.addFilePostContents(copied_resolved_path, ip_str.toSlice(array_len, ip), new_file.stat) catch |err| switch (err) { | 2531 | man.addFilePostContents(path_str, contents, new_file.stat) catch |err| switch (err) { |
| 2283 | error.Unexpected => unreachable, | 2532 | error.Unexpected => unreachable, |
| 2284 | else => |e| return e, | 2533 | else => |e| return e, |
| 2285 | }; | 2534 | }; |
| ... | @@ -2805,7 +3054,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err | ... | @@ -2805,7 +3054,7 @@ pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Err |
| 2805 | 3054 | ||
| 2806 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. | 3055 | /// Removes any entry from `Zcu.failed_files` associated with `file`. Acquires `Compilation.mutex` as needed. |
| 2807 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. | 3056 | /// `file.zir` must be unchanged from the last update, as it is used to determine if there is such an entry. |
| 2808 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | 3057 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file_index: Zcu.File.Index, file: *Zcu.File) void { |
| 2809 | const maybe_has_error = switch (file.status) { | 3058 | const maybe_has_error = switch (file.status) { |
| 2810 | .never_loaded => false, | 3059 | .never_loaded => false, |
| 2811 | .retryable_failure => true, | 3060 | .retryable_failure => true, |
| ... | @@ -2829,9 +3078,9 @@ fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { | ... | @@ -2829,9 +3078,9 @@ fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2829 | 3078 | ||
| 2830 | pt.zcu.comp.mutex.lock(); | 3079 | pt.zcu.comp.mutex.lock(); |
| 2831 | defer pt.zcu.comp.mutex.unlock(); | 3080 | defer pt.zcu.comp.mutex.unlock(); |
| 2832 | if (pt.zcu.failed_files.fetchSwapRemove(file)) |kv| { | 3081 | if (pt.zcu.failed_files.fetchSwapRemove(file_index)) |kv| { |
| 2833 | assert(maybe_has_error); // the runtime safety case above | 3082 | assert(maybe_has_error); // the runtime safety case above |
| 2834 | if (kv.value) |msg| msg.destroy(pt.zcu.gpa); // delete previous error message | 3083 | if (kv.value) |msg| pt.zcu.gpa.free(msg); // delete previous error message |
| 2835 | } | 3084 | } |
| 2836 | } | 3085 | } |
| 2837 | 3086 | ||
| ... | @@ -3009,8 +3258,8 @@ pub fn populateTestFunctions( | ... | @@ -3009,8 +3258,8 @@ pub fn populateTestFunctions( |
| 3009 | const zcu = pt.zcu; | 3258 | const zcu = pt.zcu; |
| 3010 | const gpa = zcu.gpa; | 3259 | const gpa = zcu.gpa; |
| 3011 | const ip = &zcu.intern_pool; | 3260 | const ip = &zcu.intern_pool; |
| 3012 | const builtin_mod = zcu.root_mod.getBuiltinDependency(); | 3261 | const builtin_mod = zcu.builtin_modules.get(zcu.root_mod.getBuiltinOptions(zcu.comp.config).hash()).?; |
| 3013 | const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index; | 3262 | const builtin_file_index = zcu.module_roots.get(builtin_mod).?.unwrap().?; |
| 3014 | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { | 3263 | pt.ensureFileAnalyzed(builtin_file_index) catch |err| switch (err) { |
| 3015 | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt | 3264 | error.AnalysisFail => unreachable, // builtin module is generated so cannot be corrupt |
| 3016 | error.OutOfMemory => |e| return e, | 3265 | error.OutOfMemory => |e| return e, |
| ... | @@ -3213,54 +3462,8 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde | ... | @@ -3213,54 +3462,8 @@ pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Inde |
| 3213 | } | 3462 | } |
| 3214 | } | 3463 | } |
| 3215 | 3464 | ||
| 3216 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. | 3465 | /// Stores an error in `pt.zcu.failed_files` for this file, and sets the file |
| 3217 | pub fn reportRetryableAstGenError( | 3466 | /// status to `retryable_failure`. |
| 3218 | pt: Zcu.PerThread, | ||
| 3219 | src: Zcu.AstGenSrc, | ||
| 3220 | file_index: Zcu.File.Index, | ||
| 3221 | err: anyerror, | ||
| 3222 | ) error{OutOfMemory}!void { | ||
| 3223 | const zcu = pt.zcu; | ||
| 3224 | const gpa = zcu.gpa; | ||
| 3225 | const ip = &zcu.intern_pool; | ||
| 3226 | |||
| 3227 | const file = zcu.fileByIndex(file_index); | ||
| 3228 | file.status = .retryable_failure; | ||
| 3229 | |||
| 3230 | const src_loc: Zcu.LazySrcLoc = switch (src) { | ||
| 3231 | .root => .{ | ||
| 3232 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3233 | .file = file_index, | ||
| 3234 | .inst = .main_struct_inst, | ||
| 3235 | }), | ||
| 3236 | .offset = .entire_file, | ||
| 3237 | }, | ||
| 3238 | .import => |info| .{ | ||
| 3239 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3240 | .file = info.importing_file, | ||
| 3241 | .inst = .main_struct_inst, | ||
| 3242 | }), | ||
| 3243 | .offset = .{ .token_abs = info.import_tok }, | ||
| 3244 | }, | ||
| 3245 | }; | ||
| 3246 | |||
| 3247 | const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}/{s}': {s}", .{ | ||
| 3248 | file.mod.root, file.sub_file_path, @errorName(err), | ||
| 3249 | }); | ||
| 3250 | errdefer err_msg.destroy(gpa); | ||
| 3251 | |||
| 3252 | zcu.comp.mutex.lock(); | ||
| 3253 | defer zcu.comp.mutex.unlock(); | ||
| 3254 | const gop = try zcu.failed_files.getOrPut(gpa, file); | ||
| 3255 | if (gop.found_existing) { | ||
| 3256 | if (gop.value_ptr.*) |old_err_msg| { | ||
| 3257 | old_err_msg.destroy(gpa); | ||
| 3258 | } | ||
| 3259 | } | ||
| 3260 | gop.value_ptr.* = err_msg; | ||
| 3261 | } | ||
| 3262 | |||
| 3263 | /// Sets `File.status` of `file_index` to `retryable_failure`, and stores an error in `pt.zcu.failed_files`. | ||
| 3264 | pub fn reportRetryableFileError( | 3467 | pub fn reportRetryableFileError( |
| 3265 | pt: Zcu.PerThread, | 3468 | pt: Zcu.PerThread, |
| 3266 | file_index: Zcu.File.Index, | 3469 | file_index: Zcu.File.Index, |
| ... | @@ -3269,35 +3472,27 @@ pub fn reportRetryableFileError( | ... | @@ -3269,35 +3472,27 @@ pub fn reportRetryableFileError( |
| 3269 | ) error{OutOfMemory}!void { | 3472 | ) error{OutOfMemory}!void { |
| 3270 | const zcu = pt.zcu; | 3473 | const zcu = pt.zcu; |
| 3271 | const gpa = zcu.gpa; | 3474 | const gpa = zcu.gpa; |
| 3272 | const ip = &zcu.intern_pool; | ||
| 3273 | 3475 | ||
| 3274 | const file = zcu.fileByIndex(file_index); | 3476 | const file = zcu.fileByIndex(file_index); |
| 3477 | |||
| 3275 | file.status = .retryable_failure; | 3478 | file.status = .retryable_failure; |
| 3276 | 3479 | ||
| 3277 | const err_msg = try Zcu.ErrorMsg.create( | 3480 | const msg = try std.fmt.allocPrint(gpa, format, args); |
| 3278 | gpa, | 3481 | errdefer gpa.free(msg); |
| 3279 | .{ | ||
| 3280 | .base_node_inst = try ip.trackZir(gpa, pt.tid, .{ | ||
| 3281 | .file = file_index, | ||
| 3282 | .inst = .main_struct_inst, | ||
| 3283 | }), | ||
| 3284 | .offset = .entire_file, | ||
| 3285 | }, | ||
| 3286 | format, | ||
| 3287 | args, | ||
| 3288 | ); | ||
| 3289 | errdefer err_msg.destroy(gpa); | ||
| 3290 | 3482 | ||
| 3291 | zcu.comp.mutex.lock(); | 3483 | const old_msg: ?[]u8 = old_msg: { |
| 3292 | defer zcu.comp.mutex.unlock(); | 3484 | zcu.comp.mutex.lock(); |
| 3485 | defer zcu.comp.mutex.unlock(); | ||
| 3293 | 3486 | ||
| 3294 | const gop = try zcu.failed_files.getOrPut(gpa, file); | 3487 | const gop = try zcu.failed_files.getOrPut(gpa, file_index); |
| 3295 | if (gop.found_existing) { | 3488 | const old: ?[]u8 = if (gop.found_existing) old: { |
| 3296 | if (gop.value_ptr.*) |old_err_msg| { | 3489 | break :old gop.value_ptr.*; |
| 3297 | old_err_msg.destroy(gpa); | 3490 | } else null; |
| 3298 | } | 3491 | gop.value_ptr.* = msg; |
| 3299 | } | 3492 | |
| 3300 | gop.value_ptr.* = err_msg; | 3493 | break :old_msg old; |
| 3494 | }; | ||
| 3495 | if (old_msg) |m| gpa.free(m); | ||
| 3301 | } | 3496 | } |
| 3302 | 3497 | ||
| 3303 | /// Shortcut for calling `intern_pool.get`. | 3498 | /// Shortcut for calling `intern_pool.get`. |
| ... | @@ -3850,7 +4045,7 @@ fn recreateStructType( | ... | @@ -3850,7 +4045,7 @@ fn recreateStructType( |
| 3850 | 4045 | ||
| 3851 | codegen_type: { | 4046 | codegen_type: { |
| 3852 | if (zcu.comp.config.use_llvm) break :codegen_type; | 4047 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3853 | if (file.mod.strip) break :codegen_type; | 4048 | if (file.mod.?.strip) break :codegen_type; |
| 3854 | // This job depends on any resolve_type_fully jobs queued up before it. | 4049 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3855 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 4050 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 3856 | } | 4051 | } |
| ... | @@ -3946,7 +4141,7 @@ fn recreateUnionType( | ... | @@ -3946,7 +4141,7 @@ fn recreateUnionType( |
| 3946 | 4141 | ||
| 3947 | codegen_type: { | 4142 | codegen_type: { |
| 3948 | if (zcu.comp.config.use_llvm) break :codegen_type; | 4143 | if (zcu.comp.config.use_llvm) break :codegen_type; |
| 3949 | if (file.mod.strip) break :codegen_type; | 4144 | if (file.mod.?.strip) break :codegen_type; |
| 3950 | // This job depends on any resolve_type_fully jobs queued up before it. | 4145 | // This job depends on any resolve_type_fully jobs queued up before it. |
| 3951 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); | 4146 | try zcu.comp.queueJob(.{ .codegen_type = wip_ty.index }); |
| 3952 | } | 4147 | } |
src/arch/aarch64/CodeGen.zig+1-1| ... | @@ -333,7 +333,7 @@ pub fn generate( | ... | @@ -333,7 +333,7 @@ pub fn generate( |
| 333 | const func = zcu.funcInfo(func_index); | 333 | const func = zcu.funcInfo(func_index); |
| 334 | const fn_type = Type.fromInterned(func.ty); | 334 | const fn_type = Type.fromInterned(func.ty); |
| 335 | const file_scope = zcu.navFileScope(func.owner_nav); | 335 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 336 | const target = &file_scope.mod.resolved_target.result; | 336 | const target = &file_scope.mod.?.resolved_target.result; |
| 337 | 337 | ||
| 338 | var branch_stack = std.ArrayList(Branch).init(gpa); | 338 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 339 | defer { | 339 | defer { |
src/arch/arm/CodeGen.zig+1-1| ... | @@ -342,7 +342,7 @@ pub fn generate( | ... | @@ -342,7 +342,7 @@ pub fn generate( |
| 342 | const func = zcu.funcInfo(func_index); | 342 | const func = zcu.funcInfo(func_index); |
| 343 | const func_ty = Type.fromInterned(func.ty); | 343 | const func_ty = Type.fromInterned(func.ty); |
| 344 | const file_scope = zcu.navFileScope(func.owner_nav); | 344 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 345 | const target = &file_scope.mod.resolved_target.result; | 345 | const target = &file_scope.mod.?.resolved_target.result; |
| 346 | 346 | ||
| 347 | var branch_stack = std.ArrayList(Branch).init(gpa); | 347 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 348 | defer { | 348 | defer { |
src/arch/riscv64/CodeGen.zig+1-1| ... | @@ -767,7 +767,7 @@ pub fn generate( | ... | @@ -767,7 +767,7 @@ pub fn generate( |
| 767 | const ip = &zcu.intern_pool; | 767 | const ip = &zcu.intern_pool; |
| 768 | const func = zcu.funcInfo(func_index); | 768 | const func = zcu.funcInfo(func_index); |
| 769 | const fn_type = Type.fromInterned(func.ty); | 769 | const fn_type = Type.fromInterned(func.ty); |
| 770 | const mod = zcu.navFileScope(func.owner_nav).mod; | 770 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 771 | 771 | ||
| 772 | var branch_stack = std.ArrayList(Branch).init(gpa); | 772 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 773 | defer { | 773 | defer { |
src/arch/sparc64/CodeGen.zig+1-1| ... | @@ -275,7 +275,7 @@ pub fn generate( | ... | @@ -275,7 +275,7 @@ pub fn generate( |
| 275 | const func = zcu.funcInfo(func_index); | 275 | const func = zcu.funcInfo(func_index); |
| 276 | const func_ty = Type.fromInterned(func.ty); | 276 | const func_ty = Type.fromInterned(func.ty); |
| 277 | const file_scope = zcu.navFileScope(func.owner_nav); | 277 | const file_scope = zcu.navFileScope(func.owner_nav); |
| 278 | const target = &file_scope.mod.resolved_target.result; | 278 | const target = &file_scope.mod.?.resolved_target.result; |
| 279 | 279 | ||
| 280 | var branch_stack = std.ArrayList(Branch).init(gpa); | 280 | var branch_stack = std.ArrayList(Branch).init(gpa); |
| 281 | defer { | 281 | defer { |
src/arch/wasm/CodeGen.zig+1-1| ... | @@ -1268,7 +1268,7 @@ pub fn function( | ... | @@ -1268,7 +1268,7 @@ pub fn function( |
| 1268 | const gpa = zcu.gpa; | 1268 | const gpa = zcu.gpa; |
| 1269 | const cg = zcu.funcInfo(func_index); | 1269 | const cg = zcu.funcInfo(func_index); |
| 1270 | const file_scope = zcu.navFileScope(cg.owner_nav); | 1270 | const file_scope = zcu.navFileScope(cg.owner_nav); |
| 1271 | const target = &file_scope.mod.resolved_target.result; | 1271 | const target = &file_scope.mod.?.resolved_target.result; |
| 1272 | const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu); | 1272 | const fn_ty = zcu.navValue(cg.owner_nav).typeOf(zcu); |
| 1273 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1273 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 1274 | const ip = &zcu.intern_pool; | 1274 | const ip = &zcu.intern_pool; |
src/arch/x86_64/CodeGen.zig+1-1| ... | @@ -888,7 +888,7 @@ pub fn generate( | ... | @@ -888,7 +888,7 @@ pub fn generate( |
| 888 | const ip = &zcu.intern_pool; | 888 | const ip = &zcu.intern_pool; |
| 889 | const func = zcu.funcInfo(func_index); | 889 | const func = zcu.funcInfo(func_index); |
| 890 | const fn_type: Type = .fromInterned(func.ty); | 890 | const fn_type: Type = .fromInterned(func.ty); |
| 891 | const mod = zcu.navFileScope(func.owner_nav).mod; | 891 | const mod = zcu.navFileScope(func.owner_nav).mod.?; |
| 892 | 892 | ||
| 893 | var function: CodeGen = .{ | 893 | var function: CodeGen = .{ |
| 894 | .gpa = gpa, | 894 | .gpa = gpa, |
src/codegen.zig+4-4| ... | @@ -56,7 +56,7 @@ pub fn generateFunction( | ... | @@ -56,7 +56,7 @@ pub fn generateFunction( |
| 56 | ) CodeGenError!void { | 56 | ) CodeGenError!void { |
| 57 | const zcu = pt.zcu; | 57 | const zcu = pt.zcu; |
| 58 | const func = zcu.funcInfo(func_index); | 58 | const func = zcu.funcInfo(func_index); |
| 59 | const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result; | 59 | const target = zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| 60 | switch (target_util.zigBackend(target, false)) { | 60 | switch (target_util.zigBackend(target, false)) { |
| 61 | else => unreachable, | 61 | else => unreachable, |
| 62 | inline .stage2_aarch64, | 62 | inline .stage2_aarch64, |
| ... | @@ -81,7 +81,7 @@ pub fn generateLazyFunction( | ... | @@ -81,7 +81,7 @@ pub fn generateLazyFunction( |
| 81 | ) CodeGenError!void { | 81 | ) CodeGenError!void { |
| 82 | const zcu = pt.zcu; | 82 | const zcu = pt.zcu; |
| 83 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| | 83 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| |
| 84 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.resolved_target.result | 84 | zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result |
| 85 | else | 85 | else |
| 86 | zcu.getTarget(); | 86 | zcu.getTarget(); |
| 87 | switch (target_util.zigBackend(target, false)) { | 87 | switch (target_util.zigBackend(target, false)) { |
| ... | @@ -722,7 +722,7 @@ fn lowerNavRef( | ... | @@ -722,7 +722,7 @@ fn lowerNavRef( |
| 722 | const zcu = pt.zcu; | 722 | const zcu = pt.zcu; |
| 723 | const gpa = zcu.gpa; | 723 | const gpa = zcu.gpa; |
| 724 | const ip = &zcu.intern_pool; | 724 | const ip = &zcu.intern_pool; |
| 725 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 725 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 726 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); | 726 | const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8); |
| 727 | const is_obj = lf.comp.config.output_mode == .Obj; | 727 | const is_obj = lf.comp.config.output_mode == .Obj; |
| 728 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); | 728 | const nav_ty = Type.fromInterned(ip.getNav(nav_index).typeOf(ip)); |
| ... | @@ -884,7 +884,7 @@ fn genNavRef( | ... | @@ -884,7 +884,7 @@ fn genNavRef( |
| 884 | else | 884 | else |
| 885 | .{ false, .none, nav.isThreadlocal(ip) }; | 885 | .{ false, .none, nav.isThreadlocal(ip) }; |
| 886 | 886 | ||
| 887 | const single_threaded = zcu.navFileScope(nav_index).mod.single_threaded; | 887 | const single_threaded = zcu.navFileScope(nav_index).mod.?.single_threaded; |
| 888 | const name = nav.name; | 888 | const name = nav.name; |
| 889 | if (lf.cast(.elf)) |elf_file| { | 889 | if (lf.cast(.elf)) |elf_file| { |
| 890 | const zo = elf_file.zigObjectPtr().?; | 890 | const zo = elf_file.zigObjectPtr().?; |
src/codegen/c.zig+1-1| ... | @@ -2670,7 +2670,7 @@ pub fn genTypeDecl( | ... | @@ -2670,7 +2670,7 @@ pub fn genTypeDecl( |
| 2670 | _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{}); | 2670 | _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{}); |
| 2671 | try writer.writeByte(';'); | 2671 | try writer.writeByte(';'); |
| 2672 | const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip); | 2672 | const file_scope = ty.typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip); |
| 2673 | if (!zcu.fileByIndex(file_scope).mod.strip) try writer.print(" /* {} */", .{ | 2673 | if (!zcu.fileByIndex(file_scope).mod.?.strip) try writer.print(" /* {} */", .{ |
| 2674 | ty.containerTypeName(ip).fmt(ip), | 2674 | ty.containerTypeName(ip).fmt(ip), |
| 2675 | }); | 2675 | }); |
| 2676 | try writer.writeByte('\n'); | 2676 | try writer.writeByte('\n'); |
src/codegen/llvm.zig+17-30| ... | @@ -587,13 +587,8 @@ pub const Object = struct { | ... | @@ -587,13 +587,8 @@ pub const Object = struct { |
| 587 | // into the garbage can by converting into absolute paths. What | 587 | // into the garbage can by converting into absolute paths. What |
| 588 | // a terrible tragedy. | 588 | // a terrible tragedy. |
| 589 | const compile_unit_dir = blk: { | 589 | const compile_unit_dir = blk: { |
| 590 | if (comp.zcu) |zcu| m: { | 590 | const zcu = comp.zcu orelse break :blk comp.dirs.cwd; |
| 591 | const d = try zcu.main_mod.root.joinString(arena, ""); | 591 | break :blk try zcu.main_mod.root.toAbsolute(comp.dirs, arena); |
| 592 | if (d.len == 0) break :m; | ||
| 593 | if (std.fs.path.isAbsolute(d)) break :blk d; | ||
| 594 | break :blk std.fs.realpathAlloc(arena, d) catch break :blk d; | ||
| 595 | } | ||
| 596 | break :blk try std.process.getCwdAlloc(arena); | ||
| 597 | }; | 592 | }; |
| 598 | 593 | ||
| 599 | const debug_file = try builder.debugFile( | 594 | const debug_file = try builder.debugFile( |
| ... | @@ -1135,7 +1130,7 @@ pub const Object = struct { | ... | @@ -1135,7 +1130,7 @@ pub const Object = struct { |
| 1135 | const func = zcu.funcInfo(func_index); | 1130 | const func = zcu.funcInfo(func_index); |
| 1136 | const nav = ip.getNav(func.owner_nav); | 1131 | const nav = ip.getNav(func.owner_nav); |
| 1137 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); | 1132 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 1138 | const owner_mod = zcu.fileByIndex(file_scope).mod; | 1133 | const owner_mod = zcu.fileByIndex(file_scope).mod.?; |
| 1139 | const fn_ty = Type.fromInterned(func.ty); | 1134 | const fn_ty = Type.fromInterned(func.ty); |
| 1140 | const fn_info = zcu.typeToFunc(fn_ty).?; | 1135 | const fn_info = zcu.typeToFunc(fn_ty).?; |
| 1141 | const target = owner_mod.resolved_target.result; | 1136 | const target = owner_mod.resolved_target.result; |
| ... | @@ -1735,20 +1730,14 @@ pub const Object = struct { | ... | @@ -1735,20 +1730,14 @@ pub const Object = struct { |
| 1735 | const gop = try o.debug_file_map.getOrPut(gpa, file_index); | 1730 | const gop = try o.debug_file_map.getOrPut(gpa, file_index); |
| 1736 | errdefer assert(o.debug_file_map.remove(file_index)); | 1731 | errdefer assert(o.debug_file_map.remove(file_index)); |
| 1737 | if (gop.found_existing) return gop.value_ptr.*; | 1732 | if (gop.found_existing) return gop.value_ptr.*; |
| 1738 | const file = o.pt.zcu.fileByIndex(file_index); | 1733 | const zcu = o.pt.zcu; |
| 1734 | const path = zcu.fileByIndex(file_index).path; | ||
| 1735 | const abs_path = try path.toAbsolute(zcu.comp.dirs, gpa); | ||
| 1736 | defer gpa.free(abs_path); | ||
| 1737 | |||
| 1739 | gop.value_ptr.* = try o.builder.debugFile( | 1738 | gop.value_ptr.* = try o.builder.debugFile( |
| 1740 | try o.builder.metadataString(std.fs.path.basename(file.sub_file_path)), | 1739 | try o.builder.metadataString(std.fs.path.basename(abs_path)), |
| 1741 | dir_path: { | 1740 | try o.builder.metadataString(std.fs.path.dirname(abs_path) orelse ""), |
| 1742 | const sub_path = std.fs.path.dirname(file.sub_file_path) orelse ""; | ||
| 1743 | const dir_path = try file.mod.root.joinString(gpa, sub_path); | ||
| 1744 | defer gpa.free(dir_path); | ||
| 1745 | if (std.fs.path.isAbsolute(dir_path)) | ||
| 1746 | break :dir_path try o.builder.metadataString(dir_path); | ||
| 1747 | var abs_buffer: [std.fs.max_path_bytes]u8 = undefined; | ||
| 1748 | const abs_path = std.fs.realpath(dir_path, &abs_buffer) catch | ||
| 1749 | break :dir_path try o.builder.metadataString(dir_path); | ||
| 1750 | break :dir_path try o.builder.metadataString(abs_path); | ||
| 1751 | }, | ||
| 1752 | ); | 1741 | ); |
| 1753 | return gop.value_ptr.*; | 1742 | return gop.value_ptr.*; |
| 1754 | } | 1743 | } |
| ... | @@ -2646,11 +2635,9 @@ pub const Object = struct { | ... | @@ -2646,11 +2635,9 @@ pub const Object = struct { |
| 2646 | const zcu = pt.zcu; | 2635 | const zcu = pt.zcu; |
| 2647 | const ip = &zcu.intern_pool; | 2636 | const ip = &zcu.intern_pool; |
| 2648 | 2637 | ||
| 2649 | const std_mod = zcu.std_mod; | 2638 | const std_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?; |
| 2650 | const std_file_imported = pt.importPkg(std_mod) catch unreachable; | ||
| 2651 | |||
| 2652 | const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls); | 2639 | const builtin_str = try ip.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls); |
| 2653 | const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_imported.file_index)); | 2640 | const std_file_root_type = Type.fromInterned(zcu.fileRootType(std_file_index)); |
| 2654 | const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu)); | 2641 | const std_namespace = ip.namespacePtr(std_file_root_type.getNamespaceIndex(zcu)); |
| 2655 | const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?; | 2642 | const builtin_nav = std_namespace.pub_decls.getKeyAdapted(builtin_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }).?; |
| 2656 | 2643 | ||
| ... | @@ -2683,7 +2670,7 @@ pub const Object = struct { | ... | @@ -2683,7 +2670,7 @@ pub const Object = struct { |
| 2683 | const ip = &zcu.intern_pool; | 2670 | const ip = &zcu.intern_pool; |
| 2684 | const gpa = o.gpa; | 2671 | const gpa = o.gpa; |
| 2685 | const nav = ip.getNav(nav_index); | 2672 | const nav = ip.getNav(nav_index); |
| 2686 | const owner_mod = zcu.navFileScope(nav_index).mod; | 2673 | const owner_mod = zcu.navFileScope(nav_index).mod.?; |
| 2687 | const ty: Type = .fromInterned(nav.typeOf(ip)); | 2674 | const ty: Type = .fromInterned(nav.typeOf(ip)); |
| 2688 | const gop = try o.nav_map.getOrPut(gpa, nav_index); | 2675 | const gop = try o.nav_map.getOrPut(gpa, nav_index); |
| 2689 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; | 2676 | if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; |
| ... | @@ -3013,7 +3000,7 @@ pub const Object = struct { | ... | @@ -3013,7 +3000,7 @@ pub const Object = struct { |
| 3013 | if (is_extern) { | 3000 | if (is_extern) { |
| 3014 | variable_index.setLinkage(.external, &o.builder); | 3001 | variable_index.setLinkage(.external, &o.builder); |
| 3015 | variable_index.setUnnamedAddr(.default, &o.builder); | 3002 | variable_index.setUnnamedAddr(.default, &o.builder); |
| 3016 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.single_threaded) | 3003 | if (is_threadlocal and !zcu.navFileScope(nav_index).mod.?.single_threaded) |
| 3017 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 3004 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 3018 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); | 3005 | if (is_weak_linkage) variable_index.setLinkage(.extern_weak, &o.builder); |
| 3019 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); | 3006 | if (is_dll_import) variable_index.setDllStorageClass(.dllimport, &o.builder); |
| ... | @@ -4514,7 +4501,7 @@ pub const NavGen = struct { | ... | @@ -4514,7 +4501,7 @@ pub const NavGen = struct { |
| 4514 | err_msg: ?*Zcu.ErrorMsg, | 4501 | err_msg: ?*Zcu.ErrorMsg, |
| 4515 | 4502 | ||
| 4516 | fn ownerModule(ng: NavGen) *Package.Module { | 4503 | fn ownerModule(ng: NavGen) *Package.Module { |
| 4517 | return ng.object.pt.zcu.navFileScope(ng.nav_index).mod; | 4504 | return ng.object.pt.zcu.navFileScope(ng.nav_index).mod.?; |
| 4518 | } | 4505 | } |
| 4519 | 4506 | ||
| 4520 | fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error { | 4507 | fn todo(ng: *NavGen, comptime format: []const u8, args: anytype) Error { |
| ... | @@ -4557,7 +4544,7 @@ pub const NavGen = struct { | ... | @@ -4557,7 +4544,7 @@ pub const NavGen = struct { |
| 4557 | }, &o.builder); | 4544 | }, &o.builder); |
| 4558 | 4545 | ||
| 4559 | const file_scope = zcu.navFileScopeIndex(nav_index); | 4546 | const file_scope = zcu.navFileScopeIndex(nav_index); |
| 4560 | const mod = zcu.fileByIndex(file_scope).mod; | 4547 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 4561 | if (is_threadlocal and !mod.single_threaded) | 4548 | if (is_threadlocal and !mod.single_threaded) |
| 4562 | variable_index.setThreadLocal(.generaldynamic, &o.builder); | 4549 | variable_index.setThreadLocal(.generaldynamic, &o.builder); |
| 4563 | 4550 | ||
| ... | @@ -5121,7 +5108,7 @@ pub const FuncGen = struct { | ... | @@ -5121,7 +5108,7 @@ pub const FuncGen = struct { |
| 5121 | const func = zcu.funcInfo(inline_func); | 5108 | const func = zcu.funcInfo(inline_func); |
| 5122 | const nav = ip.getNav(func.owner_nav); | 5109 | const nav = ip.getNav(func.owner_nav); |
| 5123 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); | 5110 | const file_scope = zcu.navFileScopeIndex(func.owner_nav); |
| 5124 | const mod = zcu.fileByIndex(file_scope).mod; | 5111 | const mod = zcu.fileByIndex(file_scope).mod.?; |
| 5125 | 5112 | ||
| 5126 | self.file = try o.getDebugFile(file_scope); | 5113 | self.file = try o.getDebugFile(file_scope); |
| 5127 | 5114 |
src/codegen/spirv.zig+1-1| ... | @@ -201,7 +201,7 @@ pub const Object = struct { | ... | @@ -201,7 +201,7 @@ pub const Object = struct { |
| 201 | ) !void { | 201 | ) !void { |
| 202 | const zcu = pt.zcu; | 202 | const zcu = pt.zcu; |
| 203 | const gpa = zcu.gpa; | 203 | const gpa = zcu.gpa; |
| 204 | const structured_cfg = zcu.navFileScope(nav_index).mod.structured_cfg; | 204 | const structured_cfg = zcu.navFileScope(nav_index).mod.?.structured_cfg; |
| 205 | 205 | ||
| 206 | var nav_gen = NavGen{ | 206 | var nav_gen = NavGen{ |
| 207 | .gpa = gpa, | 207 | .gpa = gpa, |
src/crash_report.zig+13-27| ... | @@ -86,15 +86,12 @@ fn dumpStatusReport() !void { | ... | @@ -86,15 +86,12 @@ fn dumpStatusReport() !void { |
| 86 | 86 | ||
| 87 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse { | 87 | const file, const src_base_node = Zcu.LazySrcLoc.resolveBaseNode(block.src_base_inst, zcu) orelse { |
| 88 | const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool)); | 88 | const file = zcu.fileByIndex(block.src_base_inst.resolveFile(&zcu.intern_pool)); |
| 89 | try stderr.writeAll("Analyzing lost instruction in file '"); | 89 | try stderr.print("Analyzing lost instruction in file '{}'. This should not happen!\n\n", .{file.path.fmt(zcu.comp)}); |
| 90 | try writeFilePath(file, stderr); | ||
| 91 | try stderr.writeAll("'. This should not happen!\n\n"); | ||
| 92 | return; | 90 | return; |
| 93 | }; | 91 | }; |
| 94 | 92 | ||
| 95 | try stderr.writeAll("Analyzing "); | 93 | try stderr.writeAll("Analyzing "); |
| 96 | try writeFilePath(file, stderr); | 94 | try stderr.print("Analyzing '{}'\n", .{file.path.fmt(zcu.comp)}); |
| 97 | try stderr.writeAll("\n"); | ||
| 98 | 95 | ||
| 99 | print_zir.renderInstructionContext( | 96 | print_zir.renderInstructionContext( |
| 100 | allocator, | 97 | allocator, |
| ... | @@ -108,23 +105,24 @@ fn dumpStatusReport() !void { | ... | @@ -108,23 +105,24 @@ fn dumpStatusReport() !void { |
| 108 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), | 105 | error.OutOfMemory => try stderr.writeAll(" <out of memory dumping zir>\n"), |
| 109 | else => |e| return e, | 106 | else => |e| return e, |
| 110 | }; | 107 | }; |
| 111 | try stderr.writeAll(" For full context, use the command\n zig ast-check -t "); | 108 | try stderr.print( |
| 112 | try writeFilePath(file, stderr); | 109 | \\ For full context, use the command |
| 113 | try stderr.writeAll("\n\n"); | 110 | \\ zig ast-check -t {} |
| 111 | \\ | ||
| 112 | \\ | ||
| 113 | , .{file.path.fmt(zcu.comp)}); | ||
| 114 | 114 | ||
| 115 | var parent = anal.parent; | 115 | var parent = anal.parent; |
| 116 | while (parent) |curr| { | 116 | while (parent) |curr| { |
| 117 | fba.reset(); | 117 | fba.reset(); |
| 118 | try stderr.writeAll(" in "); | 118 | const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool)); |
| 119 | const cur_block_file, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse { | 119 | try stderr.print(" in {}\n", .{cur_block_file.path.fmt(zcu.comp)}); |
| 120 | const cur_block_file = zcu.fileByIndex(curr.block.src_base_inst.resolveFile(&zcu.intern_pool)); | 120 | _, const cur_block_src_base_node = Zcu.LazySrcLoc.resolveBaseNode(curr.block.src_base_inst, zcu) orelse { |
| 121 | try writeFilePath(cur_block_file, stderr); | 121 | try stderr.writeAll(" > [lost instruction; this should not happen]\n"); |
| 122 | try stderr.writeAll("\n > [lost instruction; this should not happen]\n"); | ||
| 123 | parent = curr.parent; | 122 | parent = curr.parent; |
| 124 | continue; | 123 | continue; |
| 125 | }; | 124 | }; |
| 126 | try writeFilePath(cur_block_file, stderr); | 125 | try stderr.writeAll(" > "); |
| 127 | try stderr.writeAll("\n > "); | ||
| 128 | print_zir.renderSingleInstruction( | 126 | print_zir.renderSingleInstruction( |
| 129 | allocator, | 127 | allocator, |
| 130 | curr.body[curr.body_index], | 128 | curr.body[curr.body_index], |
| ... | @@ -146,18 +144,6 @@ fn dumpStatusReport() !void { | ... | @@ -146,18 +144,6 @@ fn dumpStatusReport() !void { |
| 146 | 144 | ||
| 147 | var crash_heap: [16 * 4096]u8 = undefined; | 145 | var crash_heap: [16 * 4096]u8 = undefined; |
| 148 | 146 | ||
| 149 | fn writeFilePath(file: *Zcu.File, writer: anytype) !void { | ||
| 150 | if (file.mod.root.root_dir.path) |path| { | ||
| 151 | try writer.writeAll(path); | ||
| 152 | try writer.writeAll(std.fs.path.sep_str); | ||
| 153 | } | ||
| 154 | if (file.mod.root.sub_path.len > 0) { | ||
| 155 | try writer.writeAll(file.mod.root.sub_path); | ||
| 156 | try writer.writeAll(std.fs.path.sep_str); | ||
| 157 | } | ||
| 158 | try writer.writeAll(file.sub_file_path); | ||
| 159 | } | ||
| 160 | |||
| 161 | pub fn compilerPanic(msg: []const u8, maybe_ret_addr: ?usize) noreturn { | 147 | pub fn compilerPanic(msg: []const u8, maybe_ret_addr: ?usize) noreturn { |
| 162 | @branchHint(.cold); | 148 | @branchHint(.cold); |
| 163 | PanicSwitch.preDispatch(); | 149 | PanicSwitch.preDispatch(); |
src/introspect.zig+129-60| ... | @@ -1,15 +1,18 @@ | ... | @@ -1,15 +1,18 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const Allocator = mem.Allocator; | ||
| 4 | const os = std.os; | 5 | const os = std.os; |
| 5 | const fs = std.fs; | 6 | const fs = std.fs; |
| 7 | const Cache = std.Build.Cache; | ||
| 6 | const Compilation = @import("Compilation.zig"); | 8 | const Compilation = @import("Compilation.zig"); |
| 9 | const Package = @import("Package.zig"); | ||
| 7 | const build_options = @import("build_options"); | 10 | const build_options = @import("build_options"); |
| 8 | 11 | ||
| 9 | /// Returns the sub_path that worked, or `null` if none did. | 12 | /// Returns the sub_path that worked, or `null` if none did. |
| 10 | /// The path of the returned Directory is relative to `base`. | 13 | /// The path of the returned Directory is relative to `base`. |
| 11 | /// The handle of the returned Directory is open. | 14 | /// The handle of the returned Directory is open. |
| 12 | fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | 15 | fn testZigInstallPrefix(base_dir: fs.Dir) ?Cache.Directory { |
| 13 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; | 16 | const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; |
| 14 | 17 | ||
| 15 | zig_dir: { | 18 | zig_dir: { |
| ... | @@ -21,7 +24,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | ... | @@ -21,7 +24,7 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { |
| 21 | break :zig_dir; | 24 | break :zig_dir; |
| 22 | }; | 25 | }; |
| 23 | file.close(); | 26 | file.close(); |
| 24 | return Compilation.Directory{ .handle = test_zig_dir, .path = lib_zig }; | 27 | return .{ .handle = test_zig_dir, .path = lib_zig }; |
| 25 | } | 28 | } |
| 26 | 29 | ||
| 27 | // Try lib/std/std.zig | 30 | // Try lib/std/std.zig |
| ... | @@ -31,37 +34,50 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { | ... | @@ -31,37 +34,50 @@ fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { |
| 31 | return null; | 34 | return null; |
| 32 | }; | 35 | }; |
| 33 | file.close(); | 36 | file.close(); |
| 34 | return Compilation.Directory{ .handle = test_zig_dir, .path = "lib" }; | 37 | return .{ .handle = test_zig_dir, .path = "lib" }; |
| 35 | } | ||
| 36 | |||
| 37 | /// This is a small wrapper around selfExePathAlloc that adds support for WASI | ||
| 38 | /// based on a hard-coded Preopen directory ("/zig") | ||
| 39 | pub fn findZigExePath(allocator: mem.Allocator) ![]u8 { | ||
| 40 | if (builtin.os.tag == .wasi) { | ||
| 41 | @compileError("this function is unsupported on WASI"); | ||
| 42 | } | ||
| 43 | |||
| 44 | return fs.selfExePathAlloc(allocator); | ||
| 45 | } | 38 | } |
| 46 | 39 | ||
| 47 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 40 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. |
| 48 | pub fn findZigLibDir(gpa: mem.Allocator) !Compilation.Directory { | 41 | pub fn findZigLibDir(gpa: Allocator) !Cache.Directory { |
| 49 | const self_exe_path = try findZigExePath(gpa); | 42 | const cwd_path = try getResolvedCwd(gpa); |
| 43 | defer gpa.free(cwd_path); | ||
| 44 | const self_exe_path = try fs.selfExePathAlloc(gpa); | ||
| 50 | defer gpa.free(self_exe_path); | 45 | defer gpa.free(self_exe_path); |
| 51 | 46 | ||
| 52 | return findZigLibDirFromSelfExe(gpa, self_exe_path); | 47 | return findZigLibDirFromSelfExe(gpa, cwd_path, self_exe_path); |
| 53 | } | 48 | } |
| 54 | 49 | ||
| 55 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | 50 | /// Like `std.process.getCwdAlloc`, but also resolves the path with `std.fs.path.resolve`. This |
| 56 | pub fn findZigLibDirFromSelfExe( | 51 | /// means the path has no repeated separators, no "." or ".." components, and no trailing separator. |
| 57 | allocator: mem.Allocator, | 52 | /// On WASI, "" is returned instead of ".". |
| 58 | self_exe_path: []const u8, | 53 | pub fn getResolvedCwd(gpa: Allocator) error{ |
| 59 | ) error{ | ||
| 60 | OutOfMemory, | 54 | OutOfMemory, |
| 61 | FileNotFound, | ||
| 62 | CurrentWorkingDirectoryUnlinked, | 55 | CurrentWorkingDirectoryUnlinked, |
| 63 | Unexpected, | 56 | Unexpected, |
| 64 | }!Compilation.Directory { | 57 | }![]u8 { |
| 58 | if (builtin.target.os.tag == .wasi) { | ||
| 59 | if (std.debug.runtime_safety) { | ||
| 60 | const cwd = try std.process.getCwdAlloc(gpa); | ||
| 61 | defer gpa.free(cwd); | ||
| 62 | std.debug.assert(mem.eql(u8, cwd, ".")); | ||
| 63 | } | ||
| 64 | return ""; | ||
| 65 | } | ||
| 66 | const cwd = try std.process.getCwdAlloc(gpa); | ||
| 67 | defer gpa.free(cwd); | ||
| 68 | const resolved = try fs.path.resolve(gpa, &.{cwd}); | ||
| 69 | std.debug.assert(fs.path.isAbsolute(resolved)); | ||
| 70 | return resolved; | ||
| 71 | } | ||
| 72 | |||
| 73 | /// Both the directory handle and the path are newly allocated resources which the caller now owns. | ||
| 74 | pub fn findZigLibDirFromSelfExe( | ||
| 75 | allocator: Allocator, | ||
| 76 | /// The return value of `getResolvedCwd`. | ||
| 77 | /// Passed as an argument to avoid pointlessly repeating the call. | ||
| 78 | cwd_path: []const u8, | ||
| 79 | self_exe_path: []const u8, | ||
| 80 | ) error{ OutOfMemory, FileNotFound }!Cache.Directory { | ||
| 65 | const cwd = fs.cwd(); | 81 | const cwd = fs.cwd(); |
| 66 | var cur_path: []const u8 = self_exe_path; | 82 | var cur_path: []const u8 = self_exe_path; |
| 67 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { | 83 | while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { |
| ... | @@ -69,18 +85,20 @@ pub fn findZigLibDirFromSelfExe( | ... | @@ -69,18 +85,20 @@ pub fn findZigLibDirFromSelfExe( |
| 69 | defer base_dir.close(); | 85 | defer base_dir.close(); |
| 70 | 86 | ||
| 71 | const sub_directory = testZigInstallPrefix(base_dir) orelse continue; | 87 | const sub_directory = testZigInstallPrefix(base_dir) orelse continue; |
| 72 | const p = try fs.path.join(allocator, &[_][]const u8{ dirname, sub_directory.path.? }); | 88 | const p = try fs.path.join(allocator, &.{ dirname, sub_directory.path.? }); |
| 73 | defer allocator.free(p); | 89 | defer allocator.free(p); |
| 74 | return Compilation.Directory{ | 90 | |
| 91 | const resolved = try resolvePath(allocator, cwd_path, &.{p}); | ||
| 92 | return .{ | ||
| 75 | .handle = sub_directory.handle, | 93 | .handle = sub_directory.handle, |
| 76 | .path = try resolvePath(allocator, p), | 94 | .path = if (resolved.len == 0) null else resolved, |
| 77 | }; | 95 | }; |
| 78 | } | 96 | } |
| 79 | return error.FileNotFound; | 97 | return error.FileNotFound; |
| 80 | } | 98 | } |
| 81 | 99 | ||
| 82 | /// Caller owns returned memory. | 100 | /// Caller owns returned memory. |
| 83 | pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { | 101 | pub fn resolveGlobalCacheDir(allocator: Allocator) ![]u8 { |
| 84 | if (builtin.os.tag == .wasi) | 102 | if (builtin.os.tag == .wasi) |
| 85 | @compileError("on WASI the global cache dir must be resolved with preopens"); | 103 | @compileError("on WASI the global cache dir must be resolved with preopens"); |
| 86 | 104 | ||
| ... | @@ -91,56 +109,107 @@ pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { | ... | @@ -91,56 +109,107 @@ pub fn resolveGlobalCacheDir(allocator: mem.Allocator) ![]u8 { |
| 91 | if (builtin.os.tag != .windows) { | 109 | if (builtin.os.tag != .windows) { |
| 92 | if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| { | 110 | if (std.zig.EnvVar.XDG_CACHE_HOME.getPosix()) |cache_root| { |
| 93 | if (cache_root.len > 0) { | 111 | if (cache_root.len > 0) { |
| 94 | return fs.path.join(allocator, &[_][]const u8{ cache_root, appname }); | 112 | return fs.path.join(allocator, &.{ cache_root, appname }); |
| 95 | } | 113 | } |
| 96 | } | 114 | } |
| 97 | if (std.zig.EnvVar.HOME.getPosix()) |home| { | 115 | if (std.zig.EnvVar.HOME.getPosix()) |home| { |
| 98 | return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname }); | 116 | return fs.path.join(allocator, &.{ home, ".cache", appname }); |
| 99 | } | 117 | } |
| 100 | } | 118 | } |
| 101 | 119 | ||
| 102 | return fs.getAppDataDir(allocator, appname); | 120 | return fs.getAppDataDir(allocator, appname); |
| 103 | } | 121 | } |
| 104 | 122 | ||
| 105 | /// Similar to std.fs.path.resolve, with a few important differences: | 123 | /// Similar to `fs.path.resolve`, but converts to a cwd-relative path, or, if that would |
| 106 | /// * If the input is an absolute path, check it against the cwd and try to | 124 | /// start with a relative up-dir (".."), an absolute path based on the cwd. Also, the cwd |
| 107 | /// convert it to a relative path. | 125 | /// returns the empty string ("") instead of ".". |
| 108 | /// * If the resulting path would start with a relative up-dir ("../"), instead | ||
| 109 | /// return an absolute path based on the cwd. | ||
| 110 | /// * When targeting WASI, fail with an error message if an absolute path is | ||
| 111 | /// used. | ||
| 112 | pub fn resolvePath( | 126 | pub fn resolvePath( |
| 113 | ally: mem.Allocator, | 127 | gpa: Allocator, |
| 114 | p: []const u8, | 128 | /// The return value of `getResolvedCwd`. |
| 115 | ) error{ | 129 | /// Passed as an argument to avoid pointlessly repeating the call. |
| 116 | OutOfMemory, | 130 | cwd_resolved: []const u8, |
| 117 | CurrentWorkingDirectoryUnlinked, | 131 | paths: []const []const u8, |
| 118 | Unexpected, | 132 | ) Allocator.Error![]u8 { |
| 119 | }![]u8 { | 133 | if (builtin.target.os.tag == .wasi) { |
| 120 | if (fs.path.isAbsolute(p)) { | 134 | std.debug.assert(mem.eql(u8, cwd_resolved, "")); |
| 121 | const cwd_path = try std.process.getCwdAlloc(ally); | 135 | const res = try fs.path.resolve(gpa, paths); |
| 122 | defer ally.free(cwd_path); | 136 | if (mem.eql(u8, res, ".")) { |
| 123 | const relative = try fs.path.relative(ally, cwd_path, p); | 137 | gpa.free(res); |
| 124 | if (isUpDir(relative)) { | 138 | return ""; |
| 125 | ally.free(relative); | ||
| 126 | return ally.dupe(u8, p); | ||
| 127 | } else { | ||
| 128 | return relative; | ||
| 129 | } | 139 | } |
| 140 | return res; | ||
| 141 | } | ||
| 142 | |||
| 143 | // Heuristic for a fast path: if no component is absolute and ".." never appears, we just need to resolve `paths`. | ||
| 144 | for (paths) |p| { | ||
| 145 | if (fs.path.isAbsolute(p)) break; // absolute path | ||
| 146 | if (mem.indexOf(u8, p, "..") != null) break; // may contain up-dir | ||
| 130 | } else { | 147 | } else { |
| 131 | const resolved = try fs.path.resolve(ally, &.{p}); | 148 | // no absolute path, no "..". |
| 132 | if (isUpDir(resolved)) { | 149 | const res = try fs.path.resolve(gpa, paths); |
| 133 | ally.free(resolved); | 150 | if (mem.eql(u8, res, ".")) { |
| 134 | const cwd_path = try std.process.getCwdAlloc(ally); | 151 | gpa.free(res); |
| 135 | defer ally.free(cwd_path); | 152 | return ""; |
| 136 | return fs.path.resolve(ally, &.{ cwd_path, p }); | ||
| 137 | } else { | ||
| 138 | return resolved; | ||
| 139 | } | 153 | } |
| 154 | std.debug.assert(!fs.path.isAbsolute(res)); | ||
| 155 | std.debug.assert(!isUpDir(res)); | ||
| 156 | return res; | ||
| 157 | } | ||
| 158 | |||
| 159 | // The fast path failed; resolve the whole thing. | ||
| 160 | // Optimization: `paths` often has just one element. | ||
| 161 | const path_resolved = switch (paths.len) { | ||
| 162 | 0 => unreachable, | ||
| 163 | 1 => try fs.path.resolve(gpa, &.{ cwd_resolved, paths[0] }), | ||
| 164 | else => r: { | ||
| 165 | const all_paths = try gpa.alloc([]const u8, paths.len + 1); | ||
| 166 | defer gpa.free(all_paths); | ||
| 167 | all_paths[0] = cwd_resolved; | ||
| 168 | @memcpy(all_paths[1..], paths); | ||
| 169 | break :r try fs.path.resolve(gpa, all_paths); | ||
| 170 | }, | ||
| 171 | }; | ||
| 172 | errdefer gpa.free(path_resolved); | ||
| 173 | |||
| 174 | std.debug.assert(fs.path.isAbsolute(path_resolved)); | ||
| 175 | std.debug.assert(fs.path.isAbsolute(cwd_resolved)); | ||
| 176 | |||
| 177 | if (!std.mem.startsWith(u8, path_resolved, cwd_resolved)) return path_resolved; // not in cwd | ||
| 178 | if (path_resolved.len == cwd_resolved.len) { | ||
| 179 | // equal to cwd | ||
| 180 | gpa.free(path_resolved); | ||
| 181 | return ""; | ||
| 140 | } | 182 | } |
| 183 | if (path_resolved[cwd_resolved.len] != std.fs.path.sep) return path_resolved; // not in cwd (last component differs) | ||
| 184 | |||
| 185 | // in cwd; extract sub path | ||
| 186 | const sub_path = try gpa.dupe(u8, path_resolved[cwd_resolved.len + 1 ..]); | ||
| 187 | gpa.free(path_resolved); | ||
| 188 | return sub_path; | ||
| 141 | } | 189 | } |
| 142 | 190 | ||
| 143 | /// TODO move this to std.fs.path | 191 | /// TODO move this to std.fs.path |
| 144 | pub fn isUpDir(p: []const u8) bool { | 192 | pub fn isUpDir(p: []const u8) bool { |
| 145 | return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep); | 193 | return mem.startsWith(u8, p, "..") and (p.len == 2 or p[2] == fs.path.sep); |
| 146 | } | 194 | } |
| 195 | |||
| 196 | pub const default_local_zig_cache_basename = ".zig-cache"; | ||
| 197 | |||
| 198 | /// Searches upwards from `cwd` for a directory containing a `build.zig` file. | ||
| 199 | /// If such a directory is found, returns the path to it joined to the `.zig_cache` name. | ||
| 200 | /// Otherwise, returns `null`, indicating no suitable local cache location. | ||
| 201 | pub fn resolveSuitableLocalCacheDir(arena: Allocator, cwd: []const u8) Allocator.Error!?[]u8 { | ||
| 202 | var cur_dir = cwd; | ||
| 203 | while (true) { | ||
| 204 | const joined = try fs.path.join(arena, &.{ cur_dir, Package.build_zig_basename }); | ||
| 205 | if (fs.cwd().access(joined, .{})) |_| { | ||
| 206 | return try fs.path.join(arena, &.{ cur_dir, default_local_zig_cache_basename }); | ||
| 207 | } else |err| switch (err) { | ||
| 208 | error.FileNotFound => { | ||
| 209 | cur_dir = fs.path.dirname(cur_dir) orelse return null; | ||
| 210 | continue; | ||
| 211 | }, | ||
| 212 | else => return null, | ||
| 213 | } | ||
| 214 | } | ||
| 215 | } |
src/libs/freebsd.zig+16-22| ... | @@ -34,7 +34,7 @@ pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile { | ... | @@ -34,7 +34,7 @@ pub fn needsCrt0(output_mode: std.builtin.OutputMode) ?CrtFile { |
| 34 | 34 | ||
| 35 | fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 35 | fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 36 | return path.join(arena, &.{ | 36 | return path.join(arena, &.{ |
| 37 | comp.zig_lib_directory.path.?, | 37 | comp.dirs.zig_lib.path.?, |
| 38 | "libc" ++ path.sep_str ++ "include", | 38 | "libc" ++ path.sep_str ++ "include", |
| 39 | sub_path, | 39 | sub_path, |
| 40 | }); | 40 | }); |
| ... | @@ -42,7 +42,7 @@ fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]co | ... | @@ -42,7 +42,7 @@ fn includePath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]co |
| 42 | 42 | ||
| 43 | fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 43 | fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 44 | return path.join(arena, &.{ | 44 | return path.join(arena, &.{ |
| 45 | comp.zig_lib_directory.path.?, | 45 | comp.dirs.zig_lib.path.?, |
| 46 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "csu", | 46 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "csu", |
| 47 | sub_path, | 47 | sub_path, |
| 48 | }); | 48 | }); |
| ... | @@ -50,7 +50,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const | ... | @@ -50,7 +50,7 @@ fn csuPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const |
| 50 | 50 | ||
| 51 | fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 51 | fn libcPath(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 52 | return path.join(arena, &.{ | 52 | return path.join(arena, &.{ |
| 53 | comp.zig_lib_directory.path.?, | 53 | comp.dirs.zig_lib.path.?, |
| 54 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "libc", | 54 | "libc" ++ path.sep_str ++ "freebsd" ++ path.sep_str ++ "lib" ++ path.sep_str ++ "libc", |
| 55 | sub_path, | 55 | sub_path, |
| 56 | }); | 56 | }); |
| ... | @@ -438,11 +438,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -438,11 +438,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 438 | // Use the global cache directory. | 438 | // Use the global cache directory. |
| 439 | var cache: Cache = .{ | 439 | var cache: Cache = .{ |
| 440 | .gpa = gpa, | 440 | .gpa = gpa, |
| 441 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 441 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 442 | }; | 442 | }; |
| 443 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 443 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 444 | cache.addPrefix(comp.zig_lib_directory); | 444 | cache.addPrefix(comp.dirs.zig_lib); |
| 445 | cache.addPrefix(comp.global_cache_directory); | 445 | cache.addPrefix(comp.dirs.global_cache); |
| 446 | defer cache.manifest_dir.close(); | 446 | defer cache.manifest_dir.close(); |
| 447 | 447 | ||
| 448 | var man = cache.obtain(); | 448 | var man = cache.obtain(); |
| ... | @@ -452,7 +452,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -452,7 +452,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 452 | man.hash.add(target.abi); | 452 | man.hash.add(target.abi); |
| 453 | man.hash.add(target_version); | 453 | man.hash.add(target_version); |
| 454 | 454 | ||
| 455 | const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path}); | 455 | const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path}); |
| 456 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); | 456 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); |
| 457 | 457 | ||
| 458 | if (try man.hit()) { | 458 | if (try man.hit()) { |
| ... | @@ -461,7 +461,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -461,7 +461,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 461 | return queueSharedObjects(comp, .{ | 461 | return queueSharedObjects(comp, .{ |
| 462 | .lock = man.toOwnedLock(), | 462 | .lock = man.toOwnedLock(), |
| 463 | .dir_path = .{ | 463 | .dir_path = .{ |
| 464 | .root_dir = comp.global_cache_directory, | 464 | .root_dir = comp.dirs.global_cache, |
| 465 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 465 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 466 | }, | 466 | }, |
| 467 | }); | 467 | }); |
| ... | @@ -470,9 +470,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -470,9 +470,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 470 | const digest = man.final(); | 470 | const digest = man.final(); |
| 471 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); | 471 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); |
| 472 | 472 | ||
| 473 | var o_directory: Compilation.Directory = .{ | 473 | var o_directory: Cache.Directory = .{ |
| 474 | .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}), | 474 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 475 | .path = try comp.global_cache_directory.join(arena, &.{o_sub_path}), | 475 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 476 | }; | 476 | }; |
| 477 | defer o_directory.handle.close(); | 477 | defer o_directory.handle.close(); |
| 478 | 478 | ||
| ... | @@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -974,7 +974,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 974 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc. | 974 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "stdthreads", etc. |
| 975 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; | 975 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; |
| 976 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); | 976 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); |
| 977 | try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node); | 977 | try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); |
| 978 | } | 978 | } |
| 979 | 979 | ||
| 980 | man.writeManifest() catch |err| { | 980 | man.writeManifest() catch |err| { |
| ... | @@ -984,7 +984,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -984,7 +984,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 984 | return queueSharedObjects(comp, .{ | 984 | return queueSharedObjects(comp, .{ |
| 985 | .lock = man.toOwnedLock(), | 985 | .lock = man.toOwnedLock(), |
| 986 | .dir_path = .{ | 986 | .dir_path = .{ |
| 987 | .root_dir = comp.global_cache_directory, | 987 | .root_dir = comp.dirs.global_cache, |
| 988 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 988 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 989 | }, | 989 | }, |
| 990 | }); | 990 | }); |
| ... | @@ -1023,8 +1023,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { | ... | @@ -1023,8 +1023,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { |
| 1023 | fn buildSharedLib( | 1023 | fn buildSharedLib( |
| 1024 | comp: *Compilation, | 1024 | comp: *Compilation, |
| 1025 | arena: Allocator, | 1025 | arena: Allocator, |
| 1026 | zig_cache_directory: Compilation.Directory, | 1026 | bin_directory: Cache.Directory, |
| 1027 | bin_directory: Compilation.Directory, | ||
| 1028 | asm_file_basename: []const u8, | 1027 | asm_file_basename: []const u8, |
| 1029 | lib: Lib, | 1028 | lib: Lib, |
| 1030 | prog_node: std.Progress.Node, | 1029 | prog_node: std.Progress.Node, |
| ... | @@ -1057,9 +1056,8 @@ fn buildSharedLib( | ... | @@ -1057,9 +1056,8 @@ fn buildSharedLib( |
| 1057 | }); | 1056 | }); |
| 1058 | 1057 | ||
| 1059 | const root_mod = try Module.create(arena, .{ | 1058 | const root_mod = try Module.create(arena, .{ |
| 1060 | .global_cache_directory = comp.global_cache_directory, | ||
| 1061 | .paths = .{ | 1059 | .paths = .{ |
| 1062 | .root = .{ .root_dir = comp.zig_lib_directory }, | 1060 | .root = .zig_lib_root, |
| 1063 | .root_src_path = "", | 1061 | .root_src_path = "", |
| 1064 | }, | 1062 | }, |
| 1065 | .fully_qualified_name = "root", | 1063 | .fully_qualified_name = "root", |
| ... | @@ -1079,8 +1077,6 @@ fn buildSharedLib( | ... | @@ -1079,8 +1077,6 @@ fn buildSharedLib( |
| 1079 | .global = config, | 1077 | .global = config, |
| 1080 | .cc_argv = &.{}, | 1078 | .cc_argv = &.{}, |
| 1081 | .parent = null, | 1079 | .parent = null, |
| 1082 | .builtin_mod = null, | ||
| 1083 | .builtin_modules = null, // there is only one module in this compilation | ||
| 1084 | }); | 1080 | }); |
| 1085 | 1081 | ||
| 1086 | const c_source_files = [1]Compilation.CSourceFile{ | 1082 | const c_source_files = [1]Compilation.CSourceFile{ |
| ... | @@ -1091,9 +1087,7 @@ fn buildSharedLib( | ... | @@ -1091,9 +1087,7 @@ fn buildSharedLib( |
| 1091 | }; | 1087 | }; |
| 1092 | 1088 | ||
| 1093 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 1089 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 1094 | .local_cache_directory = zig_cache_directory, | 1090 | .dirs = comp.dirs.withoutLocalCache(), |
| 1095 | .global_cache_directory = comp.global_cache_directory, | ||
| 1096 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 1097 | .thread_pool = comp.thread_pool, | 1091 | .thread_pool = comp.thread_pool, |
| 1098 | .self_exe_path = comp.self_exe_path, | 1092 | .self_exe_path = comp.self_exe_path, |
| 1099 | .cache_mode = .incremental, | 1093 | .cache_mode = .incremental, |
src/libs/glibc.zig+19-29| ... | @@ -365,7 +365,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ | ... | @@ -365,7 +365,7 @@ fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![ |
| 365 | const s = path.sep_str; | 365 | const s = path.sep_str; |
| 366 | 366 | ||
| 367 | var result = std.ArrayList(u8).init(arena); | 367 | var result = std.ArrayList(u8).init(arena); |
| 368 | try result.appendSlice(comp.zig_lib_directory.path.?); | 368 | try result.appendSlice(comp.dirs.zig_lib.path orelse "."); |
| 369 | try result.appendSlice(s ++ "libc" ++ s ++ "glibc" ++ s ++ "sysdeps" ++ s); | 369 | try result.appendSlice(s ++ "libc" ++ s ++ "glibc" ++ s ++ "sysdeps" ++ s); |
| 370 | if (is_sparc) { | 370 | if (is_sparc) { |
| 371 | if (is_64) { | 371 | if (is_64) { |
| ... | @@ -439,7 +439,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -439,7 +439,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 439 | } | 439 | } |
| 440 | if (opt_nptl) |nptl| { | 440 | if (opt_nptl) |nptl| { |
| 441 | try args.append("-I"); | 441 | try args.append("-I"); |
| 442 | try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc_glibc ++ "sysdeps", nptl })); | 442 | try args.append(try path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", lib_libc_glibc ++ "sysdeps", nptl })); |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | try args.append("-I"); | 445 | try args.append("-I"); |
| ... | @@ -459,11 +459,11 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -459,11 +459,11 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 459 | try args.append(try lib_path(comp, arena, lib_libc_glibc ++ "sysdeps" ++ s ++ "generic")); | 459 | try args.append(try lib_path(comp, arena, lib_libc_glibc ++ "sysdeps" ++ s ++ "generic")); |
| 460 | 460 | ||
| 461 | try args.append("-I"); | 461 | try args.append("-I"); |
| 462 | try args.append(try path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, lib_libc ++ "glibc" })); | 462 | try args.append(try path.join(arena, &[_][]const u8{ comp.dirs.zig_lib.path orelse ".", lib_libc ++ "glibc" })); |
| 463 | 463 | ||
| 464 | try args.append("-I"); | 464 | try args.append("-I"); |
| 465 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{ | 465 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-{s}-{s}", .{ |
| 466 | comp.zig_lib_directory.path.?, @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi), | 466 | comp.dirs.zig_lib.path orelse ".", @tagName(target.cpu.arch), @tagName(target.os.tag), @tagName(target.abi), |
| 467 | })); | 467 | })); |
| 468 | 468 | ||
| 469 | try args.append("-I"); | 469 | try args.append("-I"); |
| ... | @@ -472,7 +472,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ | ... | @@ -472,7 +472,7 @@ fn add_include_dirs(comp: *Compilation, arena: Allocator, args: *std.ArrayList([ |
| 472 | const arch_name = std.zig.target.osArchName(target); | 472 | const arch_name = std.zig.target.osArchName(target); |
| 473 | try args.append("-I"); | 473 | try args.append("-I"); |
| 474 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{ | 474 | try args.append(try std.fmt.allocPrint(arena, "{s}" ++ s ++ "libc" ++ s ++ "include" ++ s ++ "{s}-linux-any", .{ |
| 475 | comp.zig_lib_directory.path.?, arch_name, | 475 | comp.dirs.zig_lib.path orelse ".", arch_name, |
| 476 | })); | 476 | })); |
| 477 | 477 | ||
| 478 | try args.append("-I"); | 478 | try args.append("-I"); |
| ... | @@ -626,15 +626,11 @@ fn add_include_dirs_arch( | ... | @@ -626,15 +626,11 @@ fn add_include_dirs_arch( |
| 626 | } | 626 | } |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | fn path_from_lib(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | ||
| 630 | return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path }); | ||
| 631 | } | ||
| 632 | |||
| 633 | const lib_libc = "libc" ++ path.sep_str; | 629 | const lib_libc = "libc" ++ path.sep_str; |
| 634 | const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str; | 630 | const lib_libc_glibc = lib_libc ++ "glibc" ++ path.sep_str; |
| 635 | 631 | ||
| 636 | fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { | 632 | fn lib_path(comp: *Compilation, arena: Allocator, sub_path: []const u8) ![]const u8 { |
| 637 | return path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, sub_path }); | 633 | return path.join(arena, &.{ comp.dirs.zig_lib.path orelse ".", sub_path }); |
| 638 | } | 634 | } |
| 639 | 635 | ||
| 640 | pub const BuiltSharedObjects = struct { | 636 | pub const BuiltSharedObjects = struct { |
| ... | @@ -678,11 +674,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -678,11 +674,11 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 678 | // Use the global cache directory. | 674 | // Use the global cache directory. |
| 679 | var cache: Cache = .{ | 675 | var cache: Cache = .{ |
| 680 | .gpa = gpa, | 676 | .gpa = gpa, |
| 681 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 677 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 682 | }; | 678 | }; |
| 683 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); | 679 | cache.addPrefix(.{ .path = null, .handle = fs.cwd() }); |
| 684 | cache.addPrefix(comp.zig_lib_directory); | 680 | cache.addPrefix(comp.dirs.zig_lib); |
| 685 | cache.addPrefix(comp.global_cache_directory); | 681 | cache.addPrefix(comp.dirs.global_cache); |
| 686 | defer cache.manifest_dir.close(); | 682 | defer cache.manifest_dir.close(); |
| 687 | 683 | ||
| 688 | var man = cache.obtain(); | 684 | var man = cache.obtain(); |
| ... | @@ -692,7 +688,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -692,7 +688,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 692 | man.hash.add(target.abi); | 688 | man.hash.add(target.abi); |
| 693 | man.hash.add(target_version); | 689 | man.hash.add(target_version); |
| 694 | 690 | ||
| 695 | const full_abilists_path = try comp.zig_lib_directory.join(arena, &.{abilists_path}); | 691 | const full_abilists_path = try comp.dirs.zig_lib.join(arena, &.{abilists_path}); |
| 696 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); | 692 | const abilists_index = try man.addFile(full_abilists_path, abilists_max_size); |
| 697 | 693 | ||
| 698 | if (try man.hit()) { | 694 | if (try man.hit()) { |
| ... | @@ -701,7 +697,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -701,7 +697,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 701 | return queueSharedObjects(comp, .{ | 697 | return queueSharedObjects(comp, .{ |
| 702 | .lock = man.toOwnedLock(), | 698 | .lock = man.toOwnedLock(), |
| 703 | .dir_path = .{ | 699 | .dir_path = .{ |
| 704 | .root_dir = comp.global_cache_directory, | 700 | .root_dir = comp.dirs.global_cache, |
| 705 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 701 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 706 | }, | 702 | }, |
| 707 | }); | 703 | }); |
| ... | @@ -710,9 +706,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -710,9 +706,9 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 710 | const digest = man.final(); | 706 | const digest = man.final(); |
| 711 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); | 707 | const o_sub_path = try path.join(arena, &[_][]const u8{ "o", &digest }); |
| 712 | 708 | ||
| 713 | var o_directory: Compilation.Directory = .{ | 709 | var o_directory: Cache.Directory = .{ |
| 714 | .handle = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}), | 710 | .handle = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}), |
| 715 | .path = try comp.global_cache_directory.join(arena, &.{o_sub_path}), | 711 | .path = try comp.dirs.global_cache.join(arena, &.{o_sub_path}), |
| 716 | }; | 712 | }; |
| 717 | defer o_directory.handle.close(); | 713 | defer o_directory.handle.close(); |
| 718 | 714 | ||
| ... | @@ -1112,7 +1108,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -1112,7 +1108,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1112 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. | 1108 | var lib_name_buf: [32]u8 = undefined; // Larger than each of the names "c", "pthread", etc. |
| 1113 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; | 1109 | const asm_file_basename = std.fmt.bufPrint(&lib_name_buf, "{s}.s", .{lib.name}) catch unreachable; |
| 1114 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); | 1110 | try o_directory.handle.writeFile(.{ .sub_path = asm_file_basename, .data = stubs_asm.items }); |
| 1115 | try buildSharedLib(comp, arena, comp.global_cache_directory, o_directory, asm_file_basename, lib, prog_node); | 1111 | try buildSharedLib(comp, arena, o_directory, asm_file_basename, lib, prog_node); |
| 1116 | } | 1112 | } |
| 1117 | 1113 | ||
| 1118 | man.writeManifest() catch |err| { | 1114 | man.writeManifest() catch |err| { |
| ... | @@ -1122,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye | ... | @@ -1122,7 +1118,7 @@ pub fn buildSharedObjects(comp: *Compilation, prog_node: std.Progress.Node) anye |
| 1122 | return queueSharedObjects(comp, .{ | 1118 | return queueSharedObjects(comp, .{ |
| 1123 | .lock = man.toOwnedLock(), | 1119 | .lock = man.toOwnedLock(), |
| 1124 | .dir_path = .{ | 1120 | .dir_path = .{ |
| 1125 | .root_dir = comp.global_cache_directory, | 1121 | .root_dir = comp.dirs.global_cache, |
| 1126 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), | 1122 | .sub_path = try gpa.dupe(u8, "o" ++ fs.path.sep_str ++ digest), |
| 1127 | }, | 1123 | }, |
| 1128 | }); | 1124 | }); |
| ... | @@ -1174,8 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { | ... | @@ -1174,8 +1170,7 @@ fn queueSharedObjects(comp: *Compilation, so_files: BuiltSharedObjects) void { |
| 1174 | fn buildSharedLib( | 1170 | fn buildSharedLib( |
| 1175 | comp: *Compilation, | 1171 | comp: *Compilation, |
| 1176 | arena: Allocator, | 1172 | arena: Allocator, |
| 1177 | zig_cache_directory: Compilation.Directory, | 1173 | bin_directory: Cache.Directory, |
| 1178 | bin_directory: Compilation.Directory, | ||
| 1179 | asm_file_basename: []const u8, | 1174 | asm_file_basename: []const u8, |
| 1180 | lib: Lib, | 1175 | lib: Lib, |
| 1181 | prog_node: std.Progress.Node, | 1176 | prog_node: std.Progress.Node, |
| ... | @@ -1208,9 +1203,8 @@ fn buildSharedLib( | ... | @@ -1208,9 +1203,8 @@ fn buildSharedLib( |
| 1208 | }); | 1203 | }); |
| 1209 | 1204 | ||
| 1210 | const root_mod = try Module.create(arena, .{ | 1205 | const root_mod = try Module.create(arena, .{ |
| 1211 | .global_cache_directory = comp.global_cache_directory, | ||
| 1212 | .paths = .{ | 1206 | .paths = .{ |
| 1213 | .root = .{ .root_dir = comp.zig_lib_directory }, | 1207 | .root = .zig_lib_root, |
| 1214 | .root_src_path = "", | 1208 | .root_src_path = "", |
| 1215 | }, | 1209 | }, |
| 1216 | .fully_qualified_name = "root", | 1210 | .fully_qualified_name = "root", |
| ... | @@ -1230,8 +1224,6 @@ fn buildSharedLib( | ... | @@ -1230,8 +1224,6 @@ fn buildSharedLib( |
| 1230 | .global = config, | 1224 | .global = config, |
| 1231 | .cc_argv = &.{}, | 1225 | .cc_argv = &.{}, |
| 1232 | .parent = null, | 1226 | .parent = null, |
| 1233 | .builtin_mod = null, | ||
| 1234 | .builtin_modules = null, // there is only one module in this compilation | ||
| 1235 | }); | 1227 | }); |
| 1236 | 1228 | ||
| 1237 | const c_source_files = [1]Compilation.CSourceFile{ | 1229 | const c_source_files = [1]Compilation.CSourceFile{ |
| ... | @@ -1242,9 +1234,7 @@ fn buildSharedLib( | ... | @@ -1242,9 +1234,7 @@ fn buildSharedLib( |
| 1242 | }; | 1234 | }; |
| 1243 | 1235 | ||
| 1244 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 1236 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 1245 | .local_cache_directory = zig_cache_directory, | 1237 | .dirs = comp.dirs.withoutLocalCache(), |
| 1246 | .global_cache_directory = comp.global_cache_directory, | ||
| 1247 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 1248 | .thread_pool = comp.thread_pool, | 1238 | .thread_pool = comp.thread_pool, |
| 1249 | .self_exe_path = comp.self_exe_path, | 1239 | .self_exe_path = comp.self_exe_path, |
| 1250 | .cache_mode = .incremental, | 1240 | .cache_mode = .incremental, |
src/libs/libcxx.zig+13-23| ... | @@ -134,10 +134,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -134,10 +134,10 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 134 | .basename = basename, | 134 | .basename = basename, |
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" }); | 137 | const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); |
| 138 | const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }); | 138 | const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); |
| 139 | const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" }); | 139 | const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); |
| 140 | const cxx_libc_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "libc" }); | 140 | const cxx_libc_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "libc" }); |
| 141 | 141 | ||
| 142 | const optimize_mode = comp.compilerRtOptMode(); | 142 | const optimize_mode = comp.compilerRtOptMode(); |
| 143 | const strip = comp.compilerRtStrip(); | 143 | const strip = comp.compilerRtStrip(); |
| ... | @@ -164,9 +164,8 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -164,9 +164,8 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | const root_mod = Module.create(arena, .{ | 166 | const root_mod = Module.create(arena, .{ |
| 167 | .global_cache_directory = comp.global_cache_directory, | ||
| 168 | .paths = .{ | 167 | .paths = .{ |
| 169 | .root = .{ .root_dir = comp.zig_lib_directory }, | 168 | .root = .zig_lib_root, |
| 170 | .root_src_path = "", | 169 | .root_src_path = "", |
| 171 | }, | 170 | }, |
| 172 | .fully_qualified_name = "root", | 171 | .fully_qualified_name = "root", |
| ... | @@ -188,8 +187,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -188,8 +187,6 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 188 | .global = config, | 187 | .global = config, |
| 189 | .cc_argv = &.{}, | 188 | .cc_argv = &.{}, |
| 190 | .parent = null, | 189 | .parent = null, |
| 191 | .builtin_mod = null, | ||
| 192 | .builtin_modules = null, // there is only one module in this compilation | ||
| 193 | }) catch |err| { | 190 | }) catch |err| { |
| 194 | comp.setMiscFailure( | 191 | comp.setMiscFailure( |
| 195 | .libcxx, | 192 | .libcxx, |
| ... | @@ -258,7 +255,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -258,7 +255,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 258 | try cache_exempt_flags.append(cxx_libc_include_path); | 255 | try cache_exempt_flags.append(cxx_libc_include_path); |
| 259 | 256 | ||
| 260 | c_source_files.appendAssumeCapacity(.{ | 257 | c_source_files.appendAssumeCapacity(.{ |
| 261 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }), | 258 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", cxx_src }), |
| 262 | .extra_flags = cflags.items, | 259 | .extra_flags = cflags.items, |
| 263 | .cache_exempt_flags = cache_exempt_flags.items, | 260 | .cache_exempt_flags = cache_exempt_flags.items, |
| 264 | .owner = root_mod, | 261 | .owner = root_mod, |
| ... | @@ -266,9 +263,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! | ... | @@ -266,9 +263,7 @@ pub fn buildLibCxx(comp: *Compilation, prog_node: std.Progress.Node) BuildError! |
| 266 | } | 263 | } |
| 267 | 264 | ||
| 268 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 265 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 269 | .local_cache_directory = comp.global_cache_directory, | 266 | .dirs = comp.dirs.withoutLocalCache(), |
| 270 | .global_cache_directory = comp.global_cache_directory, | ||
| 271 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 272 | .self_exe_path = comp.self_exe_path, | 267 | .self_exe_path = comp.self_exe_path, |
| 273 | .cache_mode = .whole, | 268 | .cache_mode = .whole, |
| 274 | .config = config, | 269 | .config = config, |
| ... | @@ -344,9 +339,9 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -344,9 +339,9 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 344 | .basename = basename, | 339 | .basename = basename, |
| 345 | }; | 340 | }; |
| 346 | 341 | ||
| 347 | const cxxabi_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", "include" }); | 342 | const cxxabi_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", "include" }); |
| 348 | const cxx_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "include" }); | 343 | const cxx_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "include" }); |
| 349 | const cxx_src_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", "src" }); | 344 | const cxx_src_include_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxx", "src" }); |
| 350 | 345 | ||
| 351 | const optimize_mode = comp.compilerRtOptMode(); | 346 | const optimize_mode = comp.compilerRtOptMode(); |
| 352 | const strip = comp.compilerRtStrip(); | 347 | const strip = comp.compilerRtStrip(); |
| ... | @@ -378,9 +373,8 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -378,9 +373,8 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 378 | }; | 373 | }; |
| 379 | 374 | ||
| 380 | const root_mod = Module.create(arena, .{ | 375 | const root_mod = Module.create(arena, .{ |
| 381 | .global_cache_directory = comp.global_cache_directory, | ||
| 382 | .paths = .{ | 376 | .paths = .{ |
| 383 | .root = .{ .root_dir = comp.zig_lib_directory }, | 377 | .root = .zig_lib_root, |
| 384 | .root_src_path = "", | 378 | .root_src_path = "", |
| 385 | }, | 379 | }, |
| 386 | .fully_qualified_name = "root", | 380 | .fully_qualified_name = "root", |
| ... | @@ -403,8 +397,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -403,8 +397,6 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 403 | .global = config, | 397 | .global = config, |
| 404 | .cc_argv = &.{}, | 398 | .cc_argv = &.{}, |
| 405 | .parent = null, | 399 | .parent = null, |
| 406 | .builtin_mod = null, | ||
| 407 | .builtin_modules = null, // there is only one module in this compilation | ||
| 408 | }) catch |err| { | 400 | }) catch |err| { |
| 409 | comp.setMiscFailure( | 401 | comp.setMiscFailure( |
| 410 | .libcxxabi, | 402 | .libcxxabi, |
| ... | @@ -459,7 +451,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -459,7 +451,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 459 | try cache_exempt_flags.append(cxx_src_include_path); | 451 | try cache_exempt_flags.append(cxx_src_include_path); |
| 460 | 452 | ||
| 461 | c_source_files.appendAssumeCapacity(.{ | 453 | c_source_files.appendAssumeCapacity(.{ |
| 462 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }), | 454 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libcxxabi", cxxabi_src }), |
| 463 | .extra_flags = cflags.items, | 455 | .extra_flags = cflags.items, |
| 464 | .cache_exempt_flags = cache_exempt_flags.items, | 456 | .cache_exempt_flags = cache_exempt_flags.items, |
| 465 | .owner = root_mod, | 457 | .owner = root_mod, |
| ... | @@ -467,9 +459,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -467,9 +459,7 @@ pub fn buildLibCxxAbi(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 467 | } | 459 | } |
| 468 | 460 | ||
| 469 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 461 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 470 | .local_cache_directory = comp.global_cache_directory, | 462 | .dirs = comp.dirs.withoutLocalCache(), |
| 471 | .global_cache_directory = comp.global_cache_directory, | ||
| 472 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 473 | .self_exe_path = comp.self_exe_path, | 463 | .self_exe_path = comp.self_exe_path, |
| 474 | .cache_mode = .whole, | 464 | .cache_mode = .whole, |
| 475 | .config = config, | 465 | .config = config, |
src/libs/libtsan.zig+12-20| ... | @@ -84,9 +84,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -84,9 +84,8 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | const root_mod = Module.create(arena, .{ | 86 | const root_mod = Module.create(arena, .{ |
| 87 | .global_cache_directory = comp.global_cache_directory, | ||
| 88 | .paths = .{ | 87 | .paths = .{ |
| 89 | .root = .{ .root_dir = comp.zig_lib_directory }, | 88 | .root = .zig_lib_root, |
| 90 | .root_src_path = "", | 89 | .root_src_path = "", |
| 91 | }, | 90 | }, |
| 92 | .fully_qualified_name = "root", | 91 | .fully_qualified_name = "root", |
| ... | @@ -110,8 +109,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -110,8 +109,6 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 110 | .global = config, | 109 | .global = config, |
| 111 | .cc_argv = &common_flags, | 110 | .cc_argv = &common_flags, |
| 112 | .parent = null, | 111 | .parent = null, |
| 113 | .builtin_mod = null, | ||
| 114 | .builtin_modules = null, // there is only one module in this compilation | ||
| 115 | }) catch |err| { | 112 | }) catch |err| { |
| 116 | comp.setMiscFailure( | 113 | comp.setMiscFailure( |
| 117 | .libtsan, | 114 | .libtsan, |
| ... | @@ -124,7 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -124,7 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 124 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); | 121 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 125 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); | 122 | try c_source_files.ensureUnusedCapacity(tsan_sources.len); |
| 126 | 123 | ||
| 127 | const tsan_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{"libtsan"}); | 124 | const tsan_include_path = try comp.dirs.zig_lib.join(arena, &.{"libtsan"}); |
| 128 | for (tsan_sources) |tsan_src| { | 125 | for (tsan_sources) |tsan_src| { |
| 129 | var cflags = std.ArrayList([]const u8).init(arena); | 126 | var cflags = std.ArrayList([]const u8).init(arena); |
| 130 | 127 | ||
| ... | @@ -134,7 +131,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -134,7 +131,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 134 | try addCcArgs(target, &cflags); | 131 | try addCcArgs(target, &cflags); |
| 135 | 132 | ||
| 136 | c_source_files.appendAssumeCapacity(.{ | 133 | c_source_files.appendAssumeCapacity(.{ |
| 137 | .src_path = try comp.zig_lib_directory.join(arena, &.{ "libtsan", tsan_src }), | 134 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 138 | .extra_flags = cflags.items, | 135 | .extra_flags = cflags.items, |
| 139 | .owner = root_mod, | 136 | .owner = root_mod, |
| 140 | }); | 137 | }); |
| ... | @@ -155,7 +152,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -155,7 +152,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 155 | try addCcArgs(target, &cflags); | 152 | try addCcArgs(target, &cflags); |
| 156 | 153 | ||
| 157 | c_source_files.appendAssumeCapacity(.{ | 154 | c_source_files.appendAssumeCapacity(.{ |
| 158 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", tsan_src }), | 155 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", tsan_src }), |
| 159 | .extra_flags = cflags.items, | 156 | .extra_flags = cflags.items, |
| 160 | .owner = root_mod, | 157 | .owner = root_mod, |
| 161 | }); | 158 | }); |
| ... | @@ -179,14 +176,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -179,14 +176,14 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 179 | try cflags.append("-DNDEBUG"); | 176 | try cflags.append("-DNDEBUG"); |
| 180 | 177 | ||
| 181 | c_source_files.appendAssumeCapacity(.{ | 178 | c_source_files.appendAssumeCapacity(.{ |
| 182 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libtsan", asm_source }), | 179 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libtsan", asm_source }), |
| 183 | .extra_flags = cflags.items, | 180 | .extra_flags = cflags.items, |
| 184 | .owner = root_mod, | 181 | .owner = root_mod, |
| 185 | }); | 182 | }); |
| 186 | } | 183 | } |
| 187 | 184 | ||
| 188 | try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len); | 185 | try c_source_files.ensureUnusedCapacity(sanitizer_common_sources.len); |
| 189 | const sanitizer_common_include_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 186 | const sanitizer_common_include_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 190 | "libtsan", "sanitizer_common", | 187 | "libtsan", "sanitizer_common", |
| 191 | }); | 188 | }); |
| 192 | for (sanitizer_common_sources) |common_src| { | 189 | for (sanitizer_common_sources) |common_src| { |
| ... | @@ -200,7 +197,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -200,7 +197,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 200 | try addCcArgs(target, &cflags); | 197 | try addCcArgs(target, &cflags); |
| 201 | 198 | ||
| 202 | c_source_files.appendAssumeCapacity(.{ | 199 | c_source_files.appendAssumeCapacity(.{ |
| 203 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 200 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 204 | "libtsan", "sanitizer_common", common_src, | 201 | "libtsan", "sanitizer_common", common_src, |
| 205 | }), | 202 | }), |
| 206 | .extra_flags = cflags.items, | 203 | .extra_flags = cflags.items, |
| ... | @@ -224,7 +221,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -224,7 +221,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 224 | try addCcArgs(target, &cflags); | 221 | try addCcArgs(target, &cflags); |
| 225 | 222 | ||
| 226 | c_source_files.appendAssumeCapacity(.{ | 223 | c_source_files.appendAssumeCapacity(.{ |
| 227 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 224 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 228 | "libtsan", "sanitizer_common", c_src, | 225 | "libtsan", "sanitizer_common", c_src, |
| 229 | }), | 226 | }), |
| 230 | .extra_flags = cflags.items, | 227 | .extra_flags = cflags.items, |
| ... | @@ -242,7 +239,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -242,7 +239,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 242 | try addCcArgs(target, &cflags); | 239 | try addCcArgs(target, &cflags); |
| 243 | 240 | ||
| 244 | c_source_files.appendAssumeCapacity(.{ | 241 | c_source_files.appendAssumeCapacity(.{ |
| 245 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 242 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 246 | "libtsan", "sanitizer_common", c_src, | 243 | "libtsan", "sanitizer_common", c_src, |
| 247 | }), | 244 | }), |
| 248 | .extra_flags = cflags.items, | 245 | .extra_flags = cflags.items, |
| ... | @@ -250,10 +247,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -250,10 +247,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 250 | }); | 247 | }); |
| 251 | } | 248 | } |
| 252 | 249 | ||
| 253 | const interception_include_path = try comp.zig_lib_directory.join( | 250 | const interception_include_path = try comp.dirs.zig_lib.join(arena, &.{"interception"}); |
| 254 | arena, | ||
| 255 | &[_][]const u8{"interception"}, | ||
| 256 | ); | ||
| 257 | 251 | ||
| 258 | try c_source_files.ensureUnusedCapacity(interception_sources.len); | 252 | try c_source_files.ensureUnusedCapacity(interception_sources.len); |
| 259 | for (interception_sources) |c_src| { | 253 | for (interception_sources) |c_src| { |
| ... | @@ -268,7 +262,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -268,7 +262,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 268 | try addCcArgs(target, &cflags); | 262 | try addCcArgs(target, &cflags); |
| 269 | 263 | ||
| 270 | c_source_files.appendAssumeCapacity(.{ | 264 | c_source_files.appendAssumeCapacity(.{ |
| 271 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 265 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 272 | "libtsan", "interception", c_src, | 266 | "libtsan", "interception", c_src, |
| 273 | }), | 267 | }), |
| 274 | .extra_flags = cflags.items, | 268 | .extra_flags = cflags.items, |
| ... | @@ -285,9 +279,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo | ... | @@ -285,9 +279,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: std.Progress.Node) BuildError!vo |
| 285 | // Workaround for https://github.com/llvm/llvm-project/issues/97627 | 279 | // Workaround for https://github.com/llvm/llvm-project/issues/97627 |
| 286 | const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null; | 280 | const headerpad_size: ?u32 = if (target.os.tag.isDarwin()) 32 else null; |
| 287 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 281 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 288 | .local_cache_directory = comp.global_cache_directory, | 282 | .dirs = comp.dirs.withoutLocalCache(), |
| 289 | .global_cache_directory = comp.global_cache_directory, | ||
| 290 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 291 | .thread_pool = comp.thread_pool, | 283 | .thread_pool = comp.thread_pool, |
| 292 | .self_exe_path = comp.self_exe_path, | 284 | .self_exe_path = comp.self_exe_path, |
| 293 | .cache_mode = .whole, | 285 | .cache_mode = .whole, |
src/libs/libunwind.zig+4-9| ... | @@ -50,9 +50,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -50,9 +50,8 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 50 | return error.SubCompilationFailed; | 50 | return error.SubCompilationFailed; |
| 51 | }; | 51 | }; |
| 52 | const root_mod = Module.create(arena, .{ | 52 | const root_mod = Module.create(arena, .{ |
| 53 | .global_cache_directory = comp.global_cache_directory, | ||
| 54 | .paths = .{ | 53 | .paths = .{ |
| 55 | .root = .{ .root_dir = comp.zig_lib_directory }, | 54 | .root = .zig_lib_root, |
| 56 | .root_src_path = "", | 55 | .root_src_path = "", |
| 57 | }, | 56 | }, |
| 58 | .fully_qualified_name = "root", | 57 | .fully_qualified_name = "root", |
| ... | @@ -76,8 +75,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -76,8 +75,6 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 76 | .global = config, | 75 | .global = config, |
| 77 | .cc_argv = &.{}, | 76 | .cc_argv = &.{}, |
| 78 | .parent = null, | 77 | .parent = null, |
| 79 | .builtin_mod = null, | ||
| 80 | .builtin_modules = null, // there is only one module in this compilation | ||
| 81 | }) catch |err| { | 78 | }) catch |err| { |
| 82 | comp.setMiscFailure( | 79 | comp.setMiscFailure( |
| 83 | .libunwind, | 80 | .libunwind, |
| ... | @@ -118,7 +115,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -118,7 +115,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 118 | else => unreachable, // See `unwind_src_list`. | 115 | else => unreachable, // See `unwind_src_list`. |
| 119 | } | 116 | } |
| 120 | try cflags.append("-I"); | 117 | try cflags.append("-I"); |
| 121 | try cflags.append(try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libunwind", "include" })); | 118 | try cflags.append(try comp.dirs.zig_lib.join(arena, &.{ "libunwind", "include" })); |
| 122 | try cflags.append("-D_LIBUNWIND_HIDE_SYMBOLS"); | 119 | try cflags.append("-D_LIBUNWIND_HIDE_SYMBOLS"); |
| 123 | try cflags.append("-Wa,--noexecstack"); | 120 | try cflags.append("-Wa,--noexecstack"); |
| 124 | try cflags.append("-fvisibility=hidden"); | 121 | try cflags.append("-fvisibility=hidden"); |
| ... | @@ -148,16 +145,14 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr | ... | @@ -148,16 +145,14 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: std.Progress.Node) BuildErr |
| 148 | } | 145 | } |
| 149 | 146 | ||
| 150 | c_source_files[i] = .{ | 147 | c_source_files[i] = .{ |
| 151 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}), | 148 | .src_path = try comp.dirs.zig_lib.join(arena, &.{unwind_src}), |
| 152 | .extra_flags = cflags.items, | 149 | .extra_flags = cflags.items, |
| 153 | .owner = root_mod, | 150 | .owner = root_mod, |
| 154 | }; | 151 | }; |
| 155 | } | 152 | } |
| 156 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ | 153 | const sub_compilation = Compilation.create(comp.gpa, arena, .{ |
| 154 | .dirs = comp.dirs.withoutLocalCache(), | ||
| 157 | .self_exe_path = comp.self_exe_path, | 155 | .self_exe_path = comp.self_exe_path, |
| 158 | .local_cache_directory = comp.global_cache_directory, | ||
| 159 | .global_cache_directory = comp.global_cache_directory, | ||
| 160 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 161 | .config = config, | 156 | .config = config, |
| 162 | .root_mod = root_mod, | 157 | .root_mod = root_mod, |
| 163 | .cache_mode = .whole, | 158 | .cache_mode = .whole, |
src/libs/mingw.zig+23-23| ... | @@ -40,7 +40,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -40,7 +40,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 40 | } | 40 | } |
| 41 | var files = [_]Compilation.CSourceFile{ | 41 | var files = [_]Compilation.CSourceFile{ |
| 42 | .{ | 42 | .{ |
| 43 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 43 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 44 | "libc", "mingw", "crt", "crtexe.c", | 44 | "libc", "mingw", "crt", "crtexe.c", |
| 45 | }), | 45 | }), |
| 46 | .extra_flags = args.items, | 46 | .extra_flags = args.items, |
| ... | @@ -57,7 +57,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -57,7 +57,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 57 | try addCrtCcArgs(comp, arena, &args); | 57 | try addCrtCcArgs(comp, arena, &args); |
| 58 | var files = [_]Compilation.CSourceFile{ | 58 | var files = [_]Compilation.CSourceFile{ |
| 59 | .{ | 59 | .{ |
| 60 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 60 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 61 | "libc", "mingw", "crt", "crtdll.c", | 61 | "libc", "mingw", "crt", "crtdll.c", |
| 62 | }), | 62 | }), |
| 63 | .extra_flags = args.items, | 63 | .extra_flags = args.items, |
| ... | @@ -78,7 +78,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -78,7 +78,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 78 | 78 | ||
| 79 | for (mingw32_generic_src) |dep| { | 79 | for (mingw32_generic_src) |dep| { |
| 80 | try c_source_files.append(.{ | 80 | try c_source_files.append(.{ |
| 81 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 81 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 82 | "libc", "mingw", dep, | 82 | "libc", "mingw", dep, |
| 83 | }), | 83 | }), |
| 84 | .extra_flags = crt_args.items, | 84 | .extra_flags = crt_args.items, |
| ... | @@ -88,7 +88,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -88,7 +88,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 88 | if (target.cpu.arch.isX86()) { | 88 | if (target.cpu.arch.isX86()) { |
| 89 | for (mingw32_x86_src) |dep| { | 89 | for (mingw32_x86_src) |dep| { |
| 90 | try c_source_files.append(.{ | 90 | try c_source_files.append(.{ |
| 91 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 91 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 92 | "libc", "mingw", dep, | 92 | "libc", "mingw", dep, |
| 93 | }), | 93 | }), |
| 94 | .extra_flags = crt_args.items, | 94 | .extra_flags = crt_args.items, |
| ... | @@ -98,7 +98,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -98,7 +98,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 98 | if (target.cpu.arch == .x86) { | 98 | if (target.cpu.arch == .x86) { |
| 99 | for (mingw32_x86_32_src) |dep| { | 99 | for (mingw32_x86_32_src) |dep| { |
| 100 | try c_source_files.append(.{ | 100 | try c_source_files.append(.{ |
| 101 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 101 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 102 | "libc", "mingw", dep, | 102 | "libc", "mingw", dep, |
| 103 | }), | 103 | }), |
| 104 | .extra_flags = crt_args.items, | 104 | .extra_flags = crt_args.items, |
| ... | @@ -109,7 +109,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -109,7 +109,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 109 | } else if (target.cpu.arch == .thumb) { | 109 | } else if (target.cpu.arch == .thumb) { |
| 110 | for (mingw32_arm_src) |dep| { | 110 | for (mingw32_arm_src) |dep| { |
| 111 | try c_source_files.append(.{ | 111 | try c_source_files.append(.{ |
| 112 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 112 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 113 | "libc", "mingw", dep, | 113 | "libc", "mingw", dep, |
| 114 | }), | 114 | }), |
| 115 | .extra_flags = crt_args.items, | 115 | .extra_flags = crt_args.items, |
| ... | @@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -118,7 +118,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 118 | } | 118 | } |
| 119 | for (mingw32_arm32_src) |dep| { | 119 | for (mingw32_arm32_src) |dep| { |
| 120 | try c_source_files.append(.{ | 120 | try c_source_files.append(.{ |
| 121 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 121 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 122 | "libc", "mingw", dep, | 122 | "libc", "mingw", dep, |
| 123 | }), | 123 | }), |
| 124 | .extra_flags = crt_args.items, | 124 | .extra_flags = crt_args.items, |
| ... | @@ -128,7 +128,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -128,7 +128,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 128 | } else if (target.cpu.arch == .aarch64) { | 128 | } else if (target.cpu.arch == .aarch64) { |
| 129 | for (mingw32_arm_src) |dep| { | 129 | for (mingw32_arm_src) |dep| { |
| 130 | try c_source_files.append(.{ | 130 | try c_source_files.append(.{ |
| 131 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 131 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 132 | "libc", "mingw", dep, | 132 | "libc", "mingw", dep, |
| 133 | }), | 133 | }), |
| 134 | .extra_flags = crt_args.items, | 134 | .extra_flags = crt_args.items, |
| ... | @@ -137,7 +137,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -137,7 +137,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 137 | } | 137 | } |
| 138 | for (mingw32_arm64_src) |dep| { | 138 | for (mingw32_arm64_src) |dep| { |
| 139 | try c_source_files.append(.{ | 139 | try c_source_files.append(.{ |
| 140 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 140 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 141 | "libc", "mingw", dep, | 141 | "libc", "mingw", dep, |
| 142 | }), | 142 | }), |
| 143 | .extra_flags = crt_args.items, | 143 | .extra_flags = crt_args.items, |
| ... | @@ -164,7 +164,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -164,7 +164,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 164 | 164 | ||
| 165 | for (mingw32_winpthreads_src) |dep| { | 165 | for (mingw32_winpthreads_src) |dep| { |
| 166 | try c_source_files.append(.{ | 166 | try c_source_files.append(.{ |
| 167 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 167 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 168 | "libc", "mingw", dep, | 168 | "libc", "mingw", dep, |
| 169 | }), | 169 | }), |
| 170 | .extra_flags = winpthreads_args.items, | 170 | .extra_flags = winpthreads_args.items, |
| ... | @@ -192,7 +192,7 @@ fn addCcArgs( | ... | @@ -192,7 +192,7 @@ fn addCcArgs( |
| 192 | "-D__USE_MINGW_ANSI_STDIO=0", | 192 | "-D__USE_MINGW_ANSI_STDIO=0", |
| 193 | 193 | ||
| 194 | "-isystem", | 194 | "-isystem", |
| 195 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "any-windows-any" }), | 195 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "any-windows-any" }), |
| 196 | }); | 196 | }); |
| 197 | } | 197 | } |
| 198 | 198 | ||
| ... | @@ -219,7 +219,7 @@ fn addCrtCcArgs( | ... | @@ -219,7 +219,7 @@ fn addCrtCcArgs( |
| 219 | "-DHAVE_CONFIG_H", | 219 | "-DHAVE_CONFIG_H", |
| 220 | 220 | ||
| 221 | "-I", | 221 | "-I", |
| 222 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "include" }), | 222 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "include" }), |
| 223 | }); | 223 | }); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| ... | @@ -232,7 +232,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -232,7 +232,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 232 | defer arena_allocator.deinit(); | 232 | defer arena_allocator.deinit(); |
| 233 | const arena = arena_allocator.allocator(); | 233 | const arena = arena_allocator.allocator(); |
| 234 | 234 | ||
| 235 | const def_file_path = findDef(arena, comp.getTarget(), comp.zig_lib_directory, lib_name) catch |err| switch (err) { | 235 | const def_file_path = findDef(arena, comp.getTarget(), comp.dirs.zig_lib, lib_name) catch |err| switch (err) { |
| 236 | error.FileNotFound => { | 236 | error.FileNotFound => { |
| 237 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); | 237 | log.debug("no {s}.def file available to make a DLL import {s}.lib", .{ lib_name, lib_name }); |
| 238 | // In this case we will end up putting foo.lib onto the linker line and letting the linker | 238 | // In this case we will end up putting foo.lib onto the linker line and letting the linker |
| ... | @@ -247,15 +247,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -247,15 +247,15 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 247 | // Use the global cache directory. | 247 | // Use the global cache directory. |
| 248 | var cache: Cache = .{ | 248 | var cache: Cache = .{ |
| 249 | .gpa = gpa, | 249 | .gpa = gpa, |
| 250 | .manifest_dir = try comp.global_cache_directory.handle.makeOpenPath("h", .{}), | 250 | .manifest_dir = try comp.dirs.global_cache.handle.makeOpenPath("h", .{}), |
| 251 | }; | 251 | }; |
| 252 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); | 252 | cache.addPrefix(.{ .path = null, .handle = std.fs.cwd() }); |
| 253 | cache.addPrefix(comp.zig_lib_directory); | 253 | cache.addPrefix(comp.dirs.zig_lib); |
| 254 | cache.addPrefix(comp.global_cache_directory); | 254 | cache.addPrefix(comp.dirs.global_cache); |
| 255 | defer cache.manifest_dir.close(); | 255 | defer cache.manifest_dir.close(); |
| 256 | 256 | ||
| 257 | cache.hash.addBytes(build_options.version); | 257 | cache.hash.addBytes(build_options.version); |
| 258 | cache.hash.addOptionalBytes(comp.zig_lib_directory.path); | 258 | cache.hash.addOptionalBytes(comp.dirs.zig_lib.path); |
| 259 | cache.hash.add(target.cpu.arch); | 259 | cache.hash.add(target.cpu.arch); |
| 260 | 260 | ||
| 261 | var man = cache.obtain(); | 261 | var man = cache.obtain(); |
| ... | @@ -276,7 +276,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -276,7 +276,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 276 | try comp.crt_files.ensureUnusedCapacity(gpa, 1); | 276 | try comp.crt_files.ensureUnusedCapacity(gpa, 1); |
| 277 | comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{ | 277 | comp.crt_files.putAssumeCapacityNoClobber(final_lib_basename, .{ |
| 278 | .full_object_path = .{ | 278 | .full_object_path = .{ |
| 279 | .root_dir = comp.global_cache_directory, | 279 | .root_dir = comp.dirs.global_cache, |
| 280 | .sub_path = sub_path, | 280 | .sub_path = sub_path, |
| 281 | }, | 281 | }, |
| 282 | .lock = man.toOwnedLock(), | 282 | .lock = man.toOwnedLock(), |
| ... | @@ -286,11 +286,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -286,11 +286,11 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 286 | 286 | ||
| 287 | const digest = man.final(); | 287 | const digest = man.final(); |
| 288 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); | 288 | const o_sub_path = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest }); |
| 289 | var o_dir = try comp.global_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 289 | var o_dir = try comp.dirs.global_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 290 | defer o_dir.close(); | 290 | defer o_dir.close(); |
| 291 | 291 | ||
| 292 | const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name}); | 292 | const final_def_basename = try std.fmt.allocPrint(arena, "{s}.def", .{lib_name}); |
| 293 | const def_final_path = try comp.global_cache_directory.join(arena, &[_][]const u8{ | 293 | const def_final_path = try comp.dirs.global_cache.join(arena, &[_][]const u8{ |
| 294 | "o", &digest, final_def_basename, | 294 | "o", &digest, final_def_basename, |
| 295 | }); | 295 | }); |
| 296 | 296 | ||
| ... | @@ -306,7 +306,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -306,7 +306,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 306 | var aro_comp = aro.Compilation.init(gpa, std.fs.cwd()); | 306 | var aro_comp = aro.Compilation.init(gpa, std.fs.cwd()); |
| 307 | defer aro_comp.deinit(); | 307 | defer aro_comp.deinit(); |
| 308 | 308 | ||
| 309 | const include_dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", "def-include" }); | 309 | const include_dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "mingw", "def-include" }); |
| 310 | 310 | ||
| 311 | if (comp.verbose_cc) print: { | 311 | if (comp.verbose_cc) print: { |
| 312 | std.debug.lockStdErr(); | 312 | std.debug.lockStdErr(); |
| ... | @@ -350,7 +350,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -350,7 +350,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 350 | if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; | 350 | if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; |
| 351 | const llvm_bindings = @import("../codegen/llvm/bindings.zig"); | 351 | const llvm_bindings = @import("../codegen/llvm/bindings.zig"); |
| 352 | const def_final_path_z = try arena.dupeZ(u8, def_final_path); | 352 | const def_final_path_z = try arena.dupeZ(u8, def_final_path); |
| 353 | const lib_final_path_z = try comp.global_cache_directory.joinZ(arena, &.{lib_final_path}); | 353 | const lib_final_path_z = try comp.dirs.global_cache.joinZ(arena, &.{lib_final_path}); |
| 354 | if (llvm_bindings.WriteImportLibrary( | 354 | if (llvm_bindings.WriteImportLibrary( |
| 355 | def_final_path_z.ptr, | 355 | def_final_path_z.ptr, |
| 356 | @intFromEnum(target.toCoffMachine()), | 356 | @intFromEnum(target.toCoffMachine()), |
| ... | @@ -370,7 +370,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { | ... | @@ -370,7 +370,7 @@ pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void { |
| 370 | defer comp.mutex.unlock(); | 370 | defer comp.mutex.unlock(); |
| 371 | try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{ | 371 | try comp.crt_files.putNoClobber(gpa, final_lib_basename, .{ |
| 372 | .full_object_path = .{ | 372 | .full_object_path = .{ |
| 373 | .root_dir = comp.global_cache_directory, | 373 | .root_dir = comp.dirs.global_cache, |
| 374 | .sub_path = lib_final_path, | 374 | .sub_path = lib_final_path, |
| 375 | }, | 375 | }, |
| 376 | .lock = man.toOwnedLock(), | 376 | .lock = man.toOwnedLock(), |
src/libs/musl.zig+16-21| ... | @@ -34,7 +34,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -34,7 +34,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 34 | try args.append("-DCRT"); | 34 | try args.append("-DCRT"); |
| 35 | var files = [_]Compilation.CSourceFile{ | 35 | var files = [_]Compilation.CSourceFile{ |
| 36 | .{ | 36 | .{ |
| 37 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 37 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 38 | "libc", "musl", "crt", "crt1.c", | 38 | "libc", "musl", "crt", "crt1.c", |
| 39 | }), | 39 | }), |
| 40 | .extra_flags = args.items, | 40 | .extra_flags = args.items, |
| ... | @@ -54,7 +54,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -54,7 +54,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 54 | try args.append("-DCRT"); | 54 | try args.append("-DCRT"); |
| 55 | var files = [_]Compilation.CSourceFile{ | 55 | var files = [_]Compilation.CSourceFile{ |
| 56 | .{ | 56 | .{ |
| 57 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 57 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 58 | "libc", "musl", "crt", "rcrt1.c", | 58 | "libc", "musl", "crt", "rcrt1.c", |
| 59 | }), | 59 | }), |
| 60 | .extra_flags = args.items, | 60 | .extra_flags = args.items, |
| ... | @@ -75,7 +75,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -75,7 +75,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 75 | try args.append("-DCRT"); | 75 | try args.append("-DCRT"); |
| 76 | var files = [_]Compilation.CSourceFile{ | 76 | var files = [_]Compilation.CSourceFile{ |
| 77 | .{ | 77 | .{ |
| 78 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 78 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 79 | "libc", "musl", "crt", "Scrt1.c", | 79 | "libc", "musl", "crt", "Scrt1.c", |
| 80 | }), | 80 | }), |
| 81 | .extra_flags = args.items, | 81 | .extra_flags = args.items, |
| ... | @@ -165,7 +165,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -165,7 +165,7 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 165 | try addCcArgs(comp, arena, &args, ext == .o3); | 165 | try addCcArgs(comp, arena, &args, ext == .o3); |
| 166 | const c_source_file = try c_source_files.addOne(); | 166 | const c_source_file = try c_source_files.addOne(); |
| 167 | c_source_file.* = .{ | 167 | c_source_file.* = .{ |
| 168 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }), | 168 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", src_file }), |
| 169 | .extra_flags = args.items, | 169 | .extra_flags = args.items, |
| 170 | .owner = undefined, | 170 | .owner = undefined, |
| 171 | }; | 171 | }; |
| ... | @@ -220,9 +220,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -220,9 +220,8 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 220 | &.{ arch_define, family_define }; | 220 | &.{ arch_define, family_define }; |
| 221 | 221 | ||
| 222 | const root_mod = try Module.create(arena, .{ | 222 | const root_mod = try Module.create(arena, .{ |
| 223 | .global_cache_directory = comp.global_cache_directory, | ||
| 224 | .paths = .{ | 223 | .paths = .{ |
| 225 | .root = .{ .root_dir = comp.zig_lib_directory }, | 224 | .root = .zig_lib_root, |
| 226 | .root_src_path = "", | 225 | .root_src_path = "", |
| 227 | }, | 226 | }, |
| 228 | .fully_qualified_name = "root", | 227 | .fully_qualified_name = "root", |
| ... | @@ -242,14 +241,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -242,14 +241,10 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 242 | .global = config, | 241 | .global = config, |
| 243 | .cc_argv = cc_argv, | 242 | .cc_argv = cc_argv, |
| 244 | .parent = null, | 243 | .parent = null, |
| 245 | .builtin_mod = null, | ||
| 246 | .builtin_modules = null, // there is only one module in this compilation | ||
| 247 | }); | 244 | }); |
| 248 | 245 | ||
| 249 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ | 246 | const sub_compilation = try Compilation.create(comp.gpa, arena, .{ |
| 250 | .local_cache_directory = comp.global_cache_directory, | 247 | .dirs = comp.dirs.withoutLocalCache(), |
| 251 | .global_cache_directory = comp.global_cache_directory, | ||
| 252 | .zig_lib_directory = comp.zig_lib_directory, | ||
| 253 | .self_exe_path = comp.self_exe_path, | 248 | .self_exe_path = comp.self_exe_path, |
| 254 | .cache_mode = .whole, | 249 | .cache_mode = .whole, |
| 255 | .config = config, | 250 | .config = config, |
| ... | @@ -266,9 +261,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro | ... | @@ -266,9 +261,9 @@ pub fn buildCrtFile(comp: *Compilation, in_crt_file: CrtFile, prog_node: std.Pro |
| 266 | .verbose_cimport = comp.verbose_cimport, | 261 | .verbose_cimport = comp.verbose_cimport, |
| 267 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, | 262 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 268 | .clang_passthrough_mode = comp.clang_passthrough_mode, | 263 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| 269 | .c_source_files = &[_]Compilation.CSourceFile{ | 264 | .c_source_files = &.{ |
| 270 | .{ | 265 | .{ |
| 271 | .src_path = try comp.zig_lib_directory.join(arena, &.{ "libc", "musl", "libc.S" }), | 266 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "libc.S" }), |
| 272 | .owner = root_mod, | 267 | .owner = root_mod, |
| 273 | }, | 268 | }, |
| 274 | }, | 269 | }, |
| ... | @@ -411,25 +406,25 @@ fn addCcArgs( | ... | @@ -411,25 +406,25 @@ fn addCcArgs( |
| 411 | "-D_XOPEN_SOURCE=700", | 406 | "-D_XOPEN_SOURCE=700", |
| 412 | 407 | ||
| 413 | "-I", | 408 | "-I", |
| 414 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", arch_name }), | 409 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", arch_name }), |
| 415 | 410 | ||
| 416 | "-I", | 411 | "-I", |
| 417 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "arch", "generic" }), | 412 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "arch", "generic" }), |
| 418 | 413 | ||
| 419 | "-I", | 414 | "-I", |
| 420 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "include" }), | 415 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "include" }), |
| 421 | 416 | ||
| 422 | "-I", | 417 | "-I", |
| 423 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "src", "internal" }), | 418 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "src", "internal" }), |
| 424 | 419 | ||
| 425 | "-I", | 420 | "-I", |
| 426 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "include" }), | 421 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "musl", "include" }), |
| 427 | 422 | ||
| 428 | "-I", | 423 | "-I", |
| 429 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }), | 424 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }), |
| 430 | 425 | ||
| 431 | "-I", | 426 | "-I", |
| 432 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }), | 427 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }), |
| 433 | 428 | ||
| 434 | o_arg, | 429 | o_arg, |
| 435 | 430 | ||
| ... | @@ -444,7 +439,7 @@ fn addCcArgs( | ... | @@ -444,7 +439,7 @@ fn addCcArgs( |
| 444 | 439 | ||
| 445 | fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { | 440 | fn start_asm_path(comp: *Compilation, arena: Allocator, basename: []const u8) ![]const u8 { |
| 446 | const target = comp.getTarget(); | 441 | const target = comp.getTarget(); |
| 447 | return comp.zig_lib_directory.join(arena, &[_][]const u8{ | 442 | return comp.dirs.zig_lib.join(arena, &.{ |
| 448 | "libc", "musl", "crt", std.zig.target.muslArchName(target.cpu.arch, target.abi), basename, | 443 | "libc", "musl", "crt", std.zig.target.muslArchName(target.cpu.arch, target.abi), basename, |
| 449 | }); | 444 | }); |
| 450 | } | 445 | } |
src/libs/wasi_libc.zig+27-27| ... | @@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -81,7 +81,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 81 | try addLibcBottomHalfIncludes(comp, arena, &args); | 81 | try addLibcBottomHalfIncludes(comp, arena, &args); |
| 82 | var files = [_]Compilation.CSourceFile{ | 82 | var files = [_]Compilation.CSourceFile{ |
| 83 | .{ | 83 | .{ |
| 84 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 84 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 85 | "libc", try sanitize(arena, crt1_reactor_src_file), | 85 | "libc", try sanitize(arena, crt1_reactor_src_file), |
| 86 | }), | 86 | }), |
| 87 | .extra_flags = args.items, | 87 | .extra_flags = args.items, |
| ... | @@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -96,7 +96,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 96 | try addLibcBottomHalfIncludes(comp, arena, &args); | 96 | try addLibcBottomHalfIncludes(comp, arena, &args); |
| 97 | var files = [_]Compilation.CSourceFile{ | 97 | var files = [_]Compilation.CSourceFile{ |
| 98 | .{ | 98 | .{ |
| 99 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 99 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 100 | "libc", try sanitize(arena, crt1_command_src_file), | 100 | "libc", try sanitize(arena, crt1_command_src_file), |
| 101 | }), | 101 | }), |
| 102 | .extra_flags = args.items, | 102 | .extra_flags = args.items, |
| ... | @@ -114,7 +114,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -114,7 +114,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 114 | try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true }); | 114 | try addCCArgs(comp, arena, &args, .{ .want_O3 = true, .no_strict_aliasing = true }); |
| 115 | for (emmalloc_src_files) |file_path| { | 115 | for (emmalloc_src_files) |file_path| { |
| 116 | try libc_sources.append(.{ | 116 | try libc_sources.append(.{ |
| 117 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 117 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 118 | "libc", try sanitize(arena, file_path), | 118 | "libc", try sanitize(arena, file_path), |
| 119 | }), | 119 | }), |
| 120 | .extra_flags = args.items, | 120 | .extra_flags = args.items, |
| ... | @@ -131,7 +131,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -131,7 +131,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 131 | 131 | ||
| 132 | for (libc_bottom_half_src_files) |file_path| { | 132 | for (libc_bottom_half_src_files) |file_path| { |
| 133 | try libc_sources.append(.{ | 133 | try libc_sources.append(.{ |
| 134 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 134 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 135 | "libc", try sanitize(arena, file_path), | 135 | "libc", try sanitize(arena, file_path), |
| 136 | }), | 136 | }), |
| 137 | .extra_flags = args.items, | 137 | .extra_flags = args.items, |
| ... | @@ -148,7 +148,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -148,7 +148,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 148 | 148 | ||
| 149 | for (libc_top_half_src_files) |file_path| { | 149 | for (libc_top_half_src_files) |file_path| { |
| 150 | try libc_sources.append(.{ | 150 | try libc_sources.append(.{ |
| 151 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 151 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 152 | "libc", try sanitize(arena, file_path), | 152 | "libc", try sanitize(arena, file_path), |
| 153 | }), | 153 | }), |
| 154 | .extra_flags = args.items, | 154 | .extra_flags = args.items, |
| ... | @@ -168,7 +168,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -168,7 +168,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 168 | var emu_dl_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 168 | var emu_dl_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 169 | for (emulated_dl_src_files) |file_path| { | 169 | for (emulated_dl_src_files) |file_path| { |
| 170 | try emu_dl_sources.append(.{ | 170 | try emu_dl_sources.append(.{ |
| 171 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 171 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 172 | "libc", try sanitize(arena, file_path), | 172 | "libc", try sanitize(arena, file_path), |
| 173 | }), | 173 | }), |
| 174 | .extra_flags = args.items, | 174 | .extra_flags = args.items, |
| ... | @@ -186,7 +186,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -186,7 +186,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 186 | var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 186 | var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 187 | for (emulated_process_clocks_src_files) |file_path| { | 187 | for (emulated_process_clocks_src_files) |file_path| { |
| 188 | try emu_clocks_sources.append(.{ | 188 | try emu_clocks_sources.append(.{ |
| 189 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 189 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 190 | "libc", try sanitize(arena, file_path), | 190 | "libc", try sanitize(arena, file_path), |
| 191 | }), | 191 | }), |
| 192 | .extra_flags = args.items, | 192 | .extra_flags = args.items, |
| ... | @@ -203,7 +203,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -203,7 +203,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 203 | var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 203 | var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 204 | for (emulated_getpid_src_files) |file_path| { | 204 | for (emulated_getpid_src_files) |file_path| { |
| 205 | try emu_getpid_sources.append(.{ | 205 | try emu_getpid_sources.append(.{ |
| 206 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 206 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 207 | "libc", try sanitize(arena, file_path), | 207 | "libc", try sanitize(arena, file_path), |
| 208 | }), | 208 | }), |
| 209 | .extra_flags = args.items, | 209 | .extra_flags = args.items, |
| ... | @@ -220,7 +220,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -220,7 +220,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 220 | var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena); | 220 | var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena); |
| 221 | for (emulated_mman_src_files) |file_path| { | 221 | for (emulated_mman_src_files) |file_path| { |
| 222 | try emu_mman_sources.append(.{ | 222 | try emu_mman_sources.append(.{ |
| 223 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 223 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 224 | "libc", try sanitize(arena, file_path), | 224 | "libc", try sanitize(arena, file_path), |
| 225 | }), | 225 | }), |
| 226 | .extra_flags = args.items, | 226 | .extra_flags = args.items, |
| ... | @@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -238,7 +238,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 238 | 238 | ||
| 239 | for (emulated_signal_bottom_half_src_files) |file_path| { | 239 | for (emulated_signal_bottom_half_src_files) |file_path| { |
| 240 | try emu_signal_sources.append(.{ | 240 | try emu_signal_sources.append(.{ |
| 241 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 241 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 242 | "libc", try sanitize(arena, file_path), | 242 | "libc", try sanitize(arena, file_path), |
| 243 | }), | 243 | }), |
| 244 | .extra_flags = args.items, | 244 | .extra_flags = args.items, |
| ... | @@ -255,7 +255,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre | ... | @@ -255,7 +255,7 @@ pub fn buildCrtFile(comp: *Compilation, crt_file: CrtFile, prog_node: std.Progre |
| 255 | 255 | ||
| 256 | for (emulated_signal_top_half_src_files) |file_path| { | 256 | for (emulated_signal_top_half_src_files) |file_path| { |
| 257 | try emu_signal_sources.append(.{ | 257 | try emu_signal_sources.append(.{ |
| 258 | .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 258 | .src_path = try comp.dirs.zig_lib.join(arena, &.{ |
| 259 | "libc", try sanitize(arena, file_path), | 259 | "libc", try sanitize(arena, file_path), |
| 260 | }), | 260 | }), |
| 261 | .extra_flags = args.items, | 261 | .extra_flags = args.items, |
| ... | @@ -316,10 +316,10 @@ fn addCCArgs( | ... | @@ -316,10 +316,10 @@ fn addCCArgs( |
| 316 | "/", | 316 | "/", |
| 317 | 317 | ||
| 318 | "-iwithsysroot", | 318 | "-iwithsysroot", |
| 319 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", triple }), | 319 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", triple }), |
| 320 | 320 | ||
| 321 | "-iwithsysroot", | 321 | "-iwithsysroot", |
| 322 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "include", "generic-musl" }), | 322 | try comp.dirs.zig_lib.join(arena, &.{ "libc", "include", "generic-musl" }), |
| 323 | 323 | ||
| 324 | "-DBULK_MEMORY_THRESHOLD=32", | 324 | "-DBULK_MEMORY_THRESHOLD=32", |
| 325 | }); | 325 | }); |
| ... | @@ -336,7 +336,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -336,7 +336,7 @@ fn addLibcBottomHalfIncludes( |
| 336 | ) error{OutOfMemory}!void { | 336 | ) error{OutOfMemory}!void { |
| 337 | try args.appendSlice(&[_][]const u8{ | 337 | try args.appendSlice(&[_][]const u8{ |
| 338 | "-I", | 338 | "-I", |
| 339 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 339 | try comp.dirs.zig_lib.join(arena, &.{ |
| 340 | "libc", | 340 | "libc", |
| 341 | "wasi", | 341 | "wasi", |
| 342 | "libc-bottom-half", | 342 | "libc-bottom-half", |
| ... | @@ -345,7 +345,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -345,7 +345,7 @@ fn addLibcBottomHalfIncludes( |
| 345 | }), | 345 | }), |
| 346 | 346 | ||
| 347 | "-I", | 347 | "-I", |
| 348 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 348 | try comp.dirs.zig_lib.join(arena, &.{ |
| 349 | "libc", | 349 | "libc", |
| 350 | "wasi", | 350 | "wasi", |
| 351 | "libc-bottom-half", | 351 | "libc-bottom-half", |
| ... | @@ -355,7 +355,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -355,7 +355,7 @@ fn addLibcBottomHalfIncludes( |
| 355 | }), | 355 | }), |
| 356 | 356 | ||
| 357 | "-I", | 357 | "-I", |
| 358 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 358 | try comp.dirs.zig_lib.join(arena, &.{ |
| 359 | "libc", | 359 | "libc", |
| 360 | "wasi", | 360 | "wasi", |
| 361 | "libc-bottom-half", | 361 | "libc-bottom-half", |
| ... | @@ -364,7 +364,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -364,7 +364,7 @@ fn addLibcBottomHalfIncludes( |
| 364 | }), | 364 | }), |
| 365 | 365 | ||
| 366 | "-I", | 366 | "-I", |
| 367 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 367 | try comp.dirs.zig_lib.join(arena, &.{ |
| 368 | "libc", | 368 | "libc", |
| 369 | "wasi", | 369 | "wasi", |
| 370 | "libc-top-half", | 370 | "libc-top-half", |
| ... | @@ -374,7 +374,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -374,7 +374,7 @@ fn addLibcBottomHalfIncludes( |
| 374 | }), | 374 | }), |
| 375 | 375 | ||
| 376 | "-I", | 376 | "-I", |
| 377 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 377 | try comp.dirs.zig_lib.join(arena, &.{ |
| 378 | "libc", | 378 | "libc", |
| 379 | "musl", | 379 | "musl", |
| 380 | "src", | 380 | "src", |
| ... | @@ -382,7 +382,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -382,7 +382,7 @@ fn addLibcBottomHalfIncludes( |
| 382 | }), | 382 | }), |
| 383 | 383 | ||
| 384 | "-I", | 384 | "-I", |
| 385 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 385 | try comp.dirs.zig_lib.join(arena, &.{ |
| 386 | "libc", | 386 | "libc", |
| 387 | "wasi", | 387 | "wasi", |
| 388 | "libc-top-half", | 388 | "libc-top-half", |
| ... | @@ -392,7 +392,7 @@ fn addLibcBottomHalfIncludes( | ... | @@ -392,7 +392,7 @@ fn addLibcBottomHalfIncludes( |
| 392 | }), | 392 | }), |
| 393 | 393 | ||
| 394 | "-I", | 394 | "-I", |
| 395 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 395 | try comp.dirs.zig_lib.join(arena, &.{ |
| 396 | "libc", | 396 | "libc", |
| 397 | "musl", | 397 | "musl", |
| 398 | "src", | 398 | "src", |
| ... | @@ -408,7 +408,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -408,7 +408,7 @@ fn addLibcTopHalfIncludes( |
| 408 | ) error{OutOfMemory}!void { | 408 | ) error{OutOfMemory}!void { |
| 409 | try args.appendSlice(&[_][]const u8{ | 409 | try args.appendSlice(&[_][]const u8{ |
| 410 | "-I", | 410 | "-I", |
| 411 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 411 | try comp.dirs.zig_lib.join(arena, &.{ |
| 412 | "libc", | 412 | "libc", |
| 413 | "wasi", | 413 | "wasi", |
| 414 | "libc-top-half", | 414 | "libc-top-half", |
| ... | @@ -418,7 +418,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -418,7 +418,7 @@ fn addLibcTopHalfIncludes( |
| 418 | }), | 418 | }), |
| 419 | 419 | ||
| 420 | "-I", | 420 | "-I", |
| 421 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 421 | try comp.dirs.zig_lib.join(arena, &.{ |
| 422 | "libc", | 422 | "libc", |
| 423 | "musl", | 423 | "musl", |
| 424 | "src", | 424 | "src", |
| ... | @@ -426,7 +426,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -426,7 +426,7 @@ fn addLibcTopHalfIncludes( |
| 426 | }), | 426 | }), |
| 427 | 427 | ||
| 428 | "-I", | 428 | "-I", |
| 429 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 429 | try comp.dirs.zig_lib.join(arena, &.{ |
| 430 | "libc", | 430 | "libc", |
| 431 | "wasi", | 431 | "wasi", |
| 432 | "libc-top-half", | 432 | "libc-top-half", |
| ... | @@ -436,7 +436,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -436,7 +436,7 @@ fn addLibcTopHalfIncludes( |
| 436 | }), | 436 | }), |
| 437 | 437 | ||
| 438 | "-I", | 438 | "-I", |
| 439 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 439 | try comp.dirs.zig_lib.join(arena, &.{ |
| 440 | "libc", | 440 | "libc", |
| 441 | "musl", | 441 | "musl", |
| 442 | "src", | 442 | "src", |
| ... | @@ -444,7 +444,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -444,7 +444,7 @@ fn addLibcTopHalfIncludes( |
| 444 | }), | 444 | }), |
| 445 | 445 | ||
| 446 | "-I", | 446 | "-I", |
| 447 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 447 | try comp.dirs.zig_lib.join(arena, &.{ |
| 448 | "libc", | 448 | "libc", |
| 449 | "wasi", | 449 | "wasi", |
| 450 | "libc-top-half", | 450 | "libc-top-half", |
| ... | @@ -454,7 +454,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -454,7 +454,7 @@ fn addLibcTopHalfIncludes( |
| 454 | }), | 454 | }), |
| 455 | 455 | ||
| 456 | "-I", | 456 | "-I", |
| 457 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 457 | try comp.dirs.zig_lib.join(arena, &.{ |
| 458 | "libc", | 458 | "libc", |
| 459 | "musl", | 459 | "musl", |
| 460 | "arch", | 460 | "arch", |
| ... | @@ -462,7 +462,7 @@ fn addLibcTopHalfIncludes( | ... | @@ -462,7 +462,7 @@ fn addLibcTopHalfIncludes( |
| 462 | }), | 462 | }), |
| 463 | 463 | ||
| 464 | "-I", | 464 | "-I", |
| 465 | try comp.zig_lib_directory.join(arena, &[_][]const u8{ | 465 | try comp.dirs.zig_lib.join(arena, &.{ |
| 466 | "libc", | 466 | "libc", |
| 467 | "wasi", | 467 | "wasi", |
| 468 | "libc-top-half", | 468 | "libc-top-half", |
src/link.zig+3-3| ... | @@ -1675,8 +1675,8 @@ pub fn spawnLld( | ... | @@ -1675,8 +1675,8 @@ pub fn spawnLld( |
| 1675 | const rand_int = std.crypto.random.int(u64); | 1675 | const rand_int = std.crypto.random.int(u64); |
| 1676 | const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; | 1676 | const rsp_path = "tmp" ++ s ++ std.fmt.hex(rand_int) ++ ".rsp"; |
| 1677 | 1677 | ||
| 1678 | const rsp_file = try comp.local_cache_directory.handle.createFileZ(rsp_path, .{}); | 1678 | const rsp_file = try comp.dirs.local_cache.handle.createFileZ(rsp_path, .{}); |
| 1679 | defer comp.local_cache_directory.handle.deleteFileZ(rsp_path) catch |err| | 1679 | defer comp.dirs.local_cache.handle.deleteFileZ(rsp_path) catch |err| |
| 1680 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); | 1680 | log.warn("failed to delete response file {s}: {s}", .{ rsp_path, @errorName(err) }); |
| 1681 | { | 1681 | { |
| 1682 | defer rsp_file.close(); | 1682 | defer rsp_file.close(); |
| ... | @@ -1700,7 +1700,7 @@ pub fn spawnLld( | ... | @@ -1700,7 +1700,7 @@ pub fn spawnLld( |
| 1700 | var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint( | 1700 | var rsp_child = std.process.Child.init(&.{ argv[0], argv[1], try std.fmt.allocPrint( |
| 1701 | arena, | 1701 | arena, |
| 1702 | "@{s}", | 1702 | "@{s}", |
| 1703 | .{try comp.local_cache_directory.join(arena, &.{rsp_path})}, | 1703 | .{try comp.dirs.local_cache.join(arena, &.{rsp_path})}, |
| 1704 | ) }, arena); | 1704 | ) }, arena); |
| 1705 | if (comp.clang_passthrough_mode) { | 1705 | if (comp.clang_passthrough_mode) { |
| 1706 | rsp_child.stdin_behavior = .Inherit; | 1706 | rsp_child.stdin_behavior = .Inherit; |
src/link/C.zig+4-4| ... | @@ -206,7 +206,7 @@ pub fn updateFunc( | ... | @@ -206,7 +206,7 @@ pub fn updateFunc( |
| 206 | .dg = .{ | 206 | .dg = .{ |
| 207 | .gpa = gpa, | 207 | .gpa = gpa, |
| 208 | .pt = pt, | 208 | .pt = pt, |
| 209 | .mod = zcu.navFileScope(func.owner_nav).mod, | 209 | .mod = zcu.navFileScope(func.owner_nav).mod.?, |
| 210 | .error_msg = null, | 210 | .error_msg = null, |
| 211 | .pass = .{ .nav = func.owner_nav }, | 211 | .pass = .{ .nav = func.owner_nav }, |
| 212 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, | 212 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, |
| ... | @@ -337,7 +337,7 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l | ... | @@ -337,7 +337,7 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l |
| 337 | .dg = .{ | 337 | .dg = .{ |
| 338 | .gpa = gpa, | 338 | .gpa = gpa, |
| 339 | .pt = pt, | 339 | .pt = pt, |
| 340 | .mod = zcu.navFileScope(nav_index).mod, | 340 | .mod = zcu.navFileScope(nav_index).mod.?, |
| 341 | .error_msg = null, | 341 | .error_msg = null, |
| 342 | .pass = .{ .nav = nav_index }, | 342 | .pass = .{ .nav = nav_index }, |
| 343 | .is_naked_fn = false, | 343 | .is_naked_fn = false, |
| ... | @@ -490,7 +490,7 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: | ... | @@ -490,7 +490,7 @@ pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: |
| 490 | 490 | ||
| 491 | for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock( | 491 | for (self.navs.keys(), self.navs.values()) |nav, *av_block| try self.flushAvBlock( |
| 492 | pt, | 492 | pt, |
| 493 | zcu.navFileScope(nav).mod, | 493 | zcu.navFileScope(nav).mod.?, |
| 494 | &f, | 494 | &f, |
| 495 | av_block, | 495 | av_block, |
| 496 | self.exported_navs.getPtr(nav), | 496 | self.exported_navs.getPtr(nav), |
| ... | @@ -846,7 +846,7 @@ pub fn updateExports( | ... | @@ -846,7 +846,7 @@ pub fn updateExports( |
| 846 | const gpa = zcu.gpa; | 846 | const gpa = zcu.gpa; |
| 847 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { | 847 | const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { |
| 848 | .nav => |nav| .{ | 848 | .nav => |nav| .{ |
| 849 | zcu.navFileScope(nav).mod, | 849 | zcu.navFileScope(nav).mod.?, |
| 850 | .{ .nav = nav }, | 850 | .{ .nav = nav }, |
| 851 | self.navs.getPtr(nav).?, | 851 | self.navs.getPtr(nav).?, |
| 852 | (try self.exported_navs.getOrPut(gpa, nav)).value_ptr, | 852 | (try self.exported_navs.getOrPut(gpa, nav)).value_ptr, |
src/link/Coff.zig+1-1| ... | @@ -1392,7 +1392,7 @@ fn updateNavCode( | ... | @@ -1392,7 +1392,7 @@ fn updateNavCode( |
| 1392 | 1392 | ||
| 1393 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); | 1393 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); |
| 1394 | 1394 | ||
| 1395 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 1395 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1396 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 1396 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 1397 | .none => target_util.defaultFunctionAlignment(target), | 1397 | .none => target_util.defaultFunctionAlignment(target), |
| 1398 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 1398 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
src/link/Dwarf.zig+17-27| ... | @@ -34,9 +34,7 @@ pub const UpdateError = error{ | ... | @@ -34,9 +34,7 @@ pub const UpdateError = error{ |
| 34 | std.fs.File.PReadError || | 34 | std.fs.File.PReadError || |
| 35 | std.fs.File.PWriteError; | 35 | std.fs.File.PWriteError; |
| 36 | 36 | ||
| 37 | pub const FlushError = | 37 | pub const FlushError = UpdateError; |
| 38 | UpdateError || | ||
| 39 | std.process.GetCwdError; | ||
| 40 | 38 | ||
| 41 | pub const RelocError = | 39 | pub const RelocError = |
| 42 | std.fs.File.PWriteError; | 40 | std.fs.File.PWriteError; |
| ... | @@ -967,7 +965,7 @@ const Entry = struct { | ... | @@ -967,7 +965,7 @@ const Entry = struct { |
| 967 | const ip = &zcu.intern_pool; | 965 | const ip = &zcu.intern_pool; |
| 968 | for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| { | 966 | for (dwarf.types.keys(), dwarf.types.values()) |ty, other_entry| { |
| 969 | const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index| | 967 | const ty_unit: Unit.Index = if (Type.fromInterned(ty).typeDeclInst(zcu)) |inst_index| |
| 970 | dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod) catch unreachable | 968 | dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) catch unreachable |
| 971 | else | 969 | else |
| 972 | .main; | 970 | .main; |
| 973 | if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry) | 971 | if (sec.getUnit(ty_unit) == unit and unit.getEntry(other_entry) == entry) |
| ... | @@ -977,7 +975,7 @@ const Entry = struct { | ... | @@ -977,7 +975,7 @@ const Entry = struct { |
| 977 | }); | 975 | }); |
| 978 | } | 976 | } |
| 979 | for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| { | 977 | for (dwarf.navs.keys(), dwarf.navs.values()) |nav, other_entry| { |
| 980 | const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod) catch unreachable; | 978 | const nav_unit = dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav).srcInst(ip).resolveFile(ip)).mod.?) catch unreachable; |
| 981 | if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry) | 979 | if (sec.getUnit(nav_unit) == unit and unit.getEntry(other_entry) == entry) |
| 982 | log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }); | 980 | log.err("missing Nav({}({d}))", .{ ip.getNav(nav).fqn.fmt(ip), @intFromEnum(nav) }); |
| 983 | } | 981 | } |
| ... | @@ -1620,7 +1618,7 @@ pub const WipNav = struct { | ... | @@ -1620,7 +1618,7 @@ pub const WipNav = struct { |
| 1620 | 1618 | ||
| 1621 | const new_func_info = zcu.funcInfo(func); | 1619 | const new_func_info = zcu.funcInfo(func); |
| 1622 | const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav); | 1620 | const new_file = zcu.navFileScopeIndex(new_func_info.owner_nav); |
| 1623 | const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod); | 1621 | const new_unit = try dwarf.getUnit(zcu.fileByIndex(new_file).mod.?); |
| 1624 | 1622 | ||
| 1625 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); | 1623 | const dlw = wip_nav.debug_line.writer(dwarf.gpa); |
| 1626 | if (dwarf.incremental()) { | 1624 | if (dwarf.incremental()) { |
| ... | @@ -1810,7 +1808,7 @@ pub const WipNav = struct { | ... | @@ -1810,7 +1808,7 @@ pub const WipNav = struct { |
| 1810 | fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } { | 1808 | fn getNavEntry(wip_nav: *WipNav, nav_index: InternPool.Nav.Index) UpdateError!struct { Unit.Index, Entry.Index } { |
| 1811 | const zcu = wip_nav.pt.zcu; | 1809 | const zcu = wip_nav.pt.zcu; |
| 1812 | const ip = &zcu.intern_pool; | 1810 | const ip = &zcu.intern_pool; |
| 1813 | const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod); | 1811 | const unit = try wip_nav.dwarf.getUnit(zcu.fileByIndex(ip.getNav(nav_index).srcInst(ip).resolveFile(ip)).mod.?); |
| 1814 | const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index); | 1812 | const gop = try wip_nav.dwarf.navs.getOrPut(wip_nav.dwarf.gpa, nav_index); |
| 1815 | if (gop.found_existing) return .{ unit, gop.value_ptr.* }; | 1813 | if (gop.found_existing) return .{ unit, gop.value_ptr.* }; |
| 1816 | const entry = try wip_nav.dwarf.addCommonEntry(unit); | 1814 | const entry = try wip_nav.dwarf.addCommonEntry(unit); |
| ... | @@ -1828,7 +1826,7 @@ pub const WipNav = struct { | ... | @@ -1828,7 +1826,7 @@ pub const WipNav = struct { |
| 1828 | const ip = &zcu.intern_pool; | 1826 | const ip = &zcu.intern_pool; |
| 1829 | const maybe_inst_index = ty.typeDeclInst(zcu); | 1827 | const maybe_inst_index = ty.typeDeclInst(zcu); |
| 1830 | const unit = if (maybe_inst_index) |inst_index| | 1828 | const unit = if (maybe_inst_index) |inst_index| |
| 1831 | try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod) | 1829 | try wip_nav.dwarf.getUnit(zcu.fileByIndex(inst_index.resolveFile(ip)).mod.?) |
| 1832 | else | 1830 | else |
| 1833 | .main; | 1831 | .main; |
| 1834 | const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern()); | 1832 | const gop = try wip_nav.dwarf.types.getOrPut(wip_nav.dwarf.gpa, ty.toIntern()); |
| ... | @@ -2386,7 +2384,7 @@ fn initWipNavInner( | ... | @@ -2386,7 +2384,7 @@ fn initWipNavInner( |
| 2386 | else => {}, | 2384 | else => {}, |
| 2387 | } | 2385 | } |
| 2388 | 2386 | ||
| 2389 | const unit = try dwarf.getUnit(file.mod); | 2387 | const unit = try dwarf.getUnit(file.mod.?); |
| 2390 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); | 2388 | const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index); |
| 2391 | errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop(); | 2389 | errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop(); |
| 2392 | if (nav_gop.found_existing) { | 2390 | if (nav_gop.found_existing) { |
| ... | @@ -2514,7 +2512,7 @@ fn initWipNavInner( | ... | @@ -2514,7 +2512,7 @@ fn initWipNavInner( |
| 2514 | try wip_nav.infoAddrSym(sym_index, 0); | 2512 | try wip_nav.infoAddrSym(sym_index, 0); |
| 2515 | wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len); | 2513 | wip_nav.func_high_pc = @intCast(wip_nav.debug_info.items.len); |
| 2516 | try diw.writeInt(u32, 0, dwarf.endian); | 2514 | try diw.writeInt(u32, 0, dwarf.endian); |
| 2517 | const target = file.mod.resolved_target.result; | 2515 | const target = file.mod.?.resolved_target.result; |
| 2518 | try uleb128(diw, switch (nav.status.fully_resolved.alignment) { | 2516 | try uleb128(diw, switch (nav.status.fully_resolved.alignment) { |
| 2519 | .none => target_info.defaultFunctionAlignment(target), | 2517 | .none => target_info.defaultFunctionAlignment(target), |
| 2520 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), | 2518 | else => |a| a.maxStrict(target_info.minFunctionAlignment(target)), |
| ... | @@ -2726,7 +2724,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -2726,7 +2724,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 2726 | var wip_nav: WipNav = .{ | 2724 | var wip_nav: WipNav = .{ |
| 2727 | .dwarf = dwarf, | 2725 | .dwarf = dwarf, |
| 2728 | .pt = pt, | 2726 | .pt = pt, |
| 2729 | .unit = try dwarf.getUnit(file.mod), | 2727 | .unit = try dwarf.getUnit(file.mod.?), |
| 2730 | .entry = undefined, | 2728 | .entry = undefined, |
| 2731 | .any_children = false, | 2729 | .any_children = false, |
| 2732 | .func = .none, | 2730 | .func = .none, |
| ... | @@ -4044,7 +4042,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP | ... | @@ -4044,7 +4042,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP |
| 4044 | 4042 | ||
| 4045 | const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; | 4043 | const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?; |
| 4046 | const file = zcu.fileByIndex(inst_info.file); | 4044 | const file = zcu.fileByIndex(inst_info.file); |
| 4047 | const unit = try dwarf.getUnit(file.mod); | 4045 | const unit = try dwarf.getUnit(file.mod.?); |
| 4048 | const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file); | 4046 | const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file); |
| 4049 | if (inst_info.inst == .main_struct_inst) { | 4047 | if (inst_info.inst == .main_struct_inst) { |
| 4050 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index); | 4048 | const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index); |
| ... | @@ -4348,7 +4346,7 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI | ... | @@ -4348,7 +4346,7 @@ pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedI |
| 4348 | var line_buf: [4]u8 = undefined; | 4346 | var line_buf: [4]u8 = undefined; |
| 4349 | std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian); | 4347 | std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian); |
| 4350 | 4348 | ||
| 4351 | const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod) orelse return); | 4349 | const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod.?) orelse return); |
| 4352 | const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return); | 4350 | const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return); |
| 4353 | try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf)); | 4351 | try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf)); |
| 4354 | } | 4352 | } |
| ... | @@ -4418,18 +4416,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4418,18 +4416,10 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4418 | try wip_nav.updateLazy(.unneeded); | 4416 | try wip_nav.updateLazy(.unneeded); |
| 4419 | } | 4417 | } |
| 4420 | 4418 | ||
| 4421 | { | 4419 | for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| { |
| 4422 | const cwd = try std.process.getCwdAlloc(dwarf.gpa); | 4420 | const root_dir_path = try mod.root.toAbsolute(zcu.comp.dirs, dwarf.gpa); |
| 4423 | defer dwarf.gpa.free(cwd); | 4421 | defer dwarf.gpa.free(root_dir_path); |
| 4424 | for (dwarf.mods.keys(), dwarf.mods.values()) |mod, *mod_info| { | 4422 | mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); |
| 4425 | const root_dir_path = try std.fs.path.resolve(dwarf.gpa, &.{ | ||
| 4426 | cwd, | ||
| 4427 | mod.root.root_dir.path orelse "", | ||
| 4428 | mod.root.sub_path, | ||
| 4429 | }); | ||
| 4430 | defer dwarf.gpa.free(root_dir_path); | ||
| 4431 | mod_info.root_dir_path = try dwarf.debug_line_str.addString(dwarf, root_dir_path); | ||
| 4432 | } | ||
| 4433 | } | 4423 | } |
| 4434 | 4424 | ||
| 4435 | var header = std.ArrayList(u8).init(dwarf.gpa); | 4425 | var header = std.ArrayList(u8).init(dwarf.gpa); |
| ... | @@ -4687,7 +4677,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4687,7 +4677,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4687 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | 4677 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); |
| 4688 | dwarf.writeInt( | 4678 | dwarf.writeInt( |
| 4689 | header.addManyAsSliceAssumeCapacity(dir_index_info.bytes), | 4679 | header.addManyAsSliceAssumeCapacity(dir_index_info.bytes), |
| 4690 | mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod).?).?, | 4680 | mod_info.dirs.getIndex(dwarf.getUnitIfExists(file.mod.?).?) orelse 0, |
| 4691 | ); | 4681 | ); |
| 4692 | unit.cross_section_relocs.appendAssumeCapacity(.{ | 4682 | unit.cross_section_relocs.appendAssumeCapacity(.{ |
| 4693 | .source_off = @intCast(header.items.len), | 4683 | .source_off = @intCast(header.items.len), |
| ... | @@ -4695,7 +4685,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | ... | @@ -4695,7 +4685,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { |
| 4695 | .target_unit = StringSection.unit, | 4685 | .target_unit = StringSection.unit, |
| 4696 | .target_entry = (try dwarf.debug_line_str.addString( | 4686 | .target_entry = (try dwarf.debug_line_str.addString( |
| 4697 | dwarf, | 4687 | dwarf, |
| 4698 | if (file.mod.builtin_file == file) file.source.? else "", | 4688 | if (file.is_builtin) file.source.? else "", |
| 4699 | )).toOptional(), | 4689 | )).toOptional(), |
| 4700 | }); | 4690 | }); |
| 4701 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); | 4691 | header.appendNTimesAssumeCapacity(0, dwarf.sectionOffsetBytes()); |
src/link/Elf/ZigObject.zig+2-2| ... | @@ -1201,7 +1201,7 @@ fn getNavShdrIndex( | ... | @@ -1201,7 +1201,7 @@ fn getNavShdrIndex( |
| 1201 | return osec; | 1201 | return osec; |
| 1202 | } | 1202 | } |
| 1203 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) | 1203 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) |
| 1204 | return switch (zcu.navFileScope(nav_index).mod.optimize_mode) { | 1204 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1205 | .Debug, .ReleaseSafe => { | 1205 | .Debug, .ReleaseSafe => { |
| 1206 | if (self.data_index) |symbol_index| | 1206 | if (self.data_index) |symbol_index| |
| 1207 | return self.symbol(symbol_index).outputShndx(elf_file).?; | 1207 | return self.symbol(symbol_index).outputShndx(elf_file).?; |
| ... | @@ -1271,7 +1271,7 @@ fn updateNavCode( | ... | @@ -1271,7 +1271,7 @@ fn updateNavCode( |
| 1271 | 1271 | ||
| 1272 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); | 1272 | log.debug("updateNavCode {}({d})", .{ nav.fqn.fmt(ip), nav_index }); |
| 1273 | 1273 | ||
| 1274 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 1274 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 1275 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 1275 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 1276 | .none => target_util.defaultFunctionAlignment(target), | 1276 | .none => target_util.defaultFunctionAlignment(target), |
| 1277 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 1277 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
src/link/MachO.zig+3-3| ... | @@ -867,11 +867,11 @@ pub fn resolveLibSystem( | ... | @@ -867,11 +867,11 @@ pub fn resolveLibSystem( |
| 867 | success: { | 867 | success: { |
| 868 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { | 868 | if (self.sdk_layout) |sdk_layout| switch (sdk_layout) { |
| 869 | .sdk => { | 869 | .sdk => { |
| 870 | const dir = try fs.path.join(arena, &[_][]const u8{ comp.sysroot.?, "usr", "lib" }); | 870 | const dir = try fs.path.join(arena, &.{ comp.sysroot.?, "usr", "lib" }); |
| 871 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; | 871 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; |
| 872 | }, | 872 | }, |
| 873 | .vendored => { | 873 | .vendored => { |
| 874 | const dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "darwin" }); | 874 | const dir = try comp.dirs.zig_lib.join(arena, &.{ "libc", "darwin" }); |
| 875 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; | 875 | if (try accessLibPath(arena, &test_path, &checked_paths, dir, "System")) break :success; |
| 876 | }, | 876 | }, |
| 877 | }; | 877 | }; |
| ... | @@ -4406,7 +4406,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi | ... | @@ -4406,7 +4406,7 @@ fn inferSdkVersion(comp: *Compilation, sdk_layout: SdkLayout) ?std.SemanticVersi |
| 4406 | 4406 | ||
| 4407 | const sdk_dir = switch (sdk_layout) { | 4407 | const sdk_dir = switch (sdk_layout) { |
| 4408 | .sdk => comp.sysroot.?, | 4408 | .sdk => comp.sysroot.?, |
| 4409 | .vendored => fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null, | 4409 | .vendored => fs.path.join(arena, &.{ comp.dirs.zig_lib.path.?, "libc", "darwin" }) catch return null, |
| 4410 | }; | 4410 | }; |
| 4411 | if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { | 4411 | if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| { |
| 4412 | return parseSdkVersion(ver); | 4412 | return parseSdkVersion(ver); |
src/link/MachO/ZigObject.zig+2-2| ... | @@ -954,7 +954,7 @@ fn updateNavCode( | ... | @@ -954,7 +954,7 @@ fn updateNavCode( |
| 954 | 954 | ||
| 955 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); | 955 | log.debug("updateNavCode {} 0x{x}", .{ nav.fqn.fmt(ip), nav_index }); |
| 956 | 956 | ||
| 957 | const target = zcu.navFileScope(nav_index).mod.resolved_target.result; | 957 | const target = zcu.navFileScope(nav_index).mod.?.resolved_target.result; |
| 958 | const required_alignment = switch (pt.navAlignment(nav_index)) { | 958 | const required_alignment = switch (pt.navAlignment(nav_index)) { |
| 959 | .none => target_util.defaultFunctionAlignment(target), | 959 | .none => target_util.defaultFunctionAlignment(target), |
| 960 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), | 960 | else => |a| a.maxStrict(target_util.minFunctionAlignment(target)), |
| ... | @@ -1184,7 +1184,7 @@ fn getNavOutputSection( | ... | @@ -1184,7 +1184,7 @@ fn getNavOutputSection( |
| 1184 | } | 1184 | } |
| 1185 | if (is_const) return macho_file.zig_const_sect_index.?; | 1185 | if (is_const) return macho_file.zig_const_sect_index.?; |
| 1186 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) | 1186 | if (nav_init != .none and Value.fromInterned(nav_init).isUndefDeep(zcu)) |
| 1187 | return switch (zcu.navFileScope(nav_index).mod.optimize_mode) { | 1187 | return switch (zcu.navFileScope(nav_index).mod.?.optimize_mode) { |
| 1188 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, | 1188 | .Debug, .ReleaseSafe => macho_file.zig_data_sect_index.?, |
| 1189 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, | 1189 | .ReleaseFast, .ReleaseSmall => macho_file.zig_bss_sect_index.?, |
| 1190 | }; | 1190 | }; |
src/link/Plan9.zig+9-13| ... | @@ -315,8 +315,9 @@ pub fn createEmpty( | ... | @@ -315,8 +315,9 @@ pub fn createEmpty( |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void { | 317 | fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void { |
| 318 | const gpa = self.base.comp.gpa; | 318 | const comp = self.base.comp; |
| 319 | const zcu = self.base.comp.zcu.?; | 319 | const gpa = comp.gpa; |
| 320 | const zcu = comp.zcu.?; | ||
| 320 | const file_scope = zcu.navFileScopeIndex(nav_index); | 321 | const file_scope = zcu.navFileScopeIndex(nav_index); |
| 321 | const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope); | 322 | const fn_map_res = try self.fn_nav_table.getOrPut(gpa, file_scope); |
| 322 | if (fn_map_res.found_existing) { | 323 | if (fn_map_res.found_existing) { |
| ... | @@ -345,14 +346,11 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void | ... | @@ -345,14 +346,11 @@ fn putFn(self: *Plan9, nav_index: InternPool.Nav.Index, out: FnNavOutput) !void |
| 345 | try a.writer().writeInt(u16, 1, .big); | 346 | try a.writer().writeInt(u16, 1, .big); |
| 346 | 347 | ||
| 347 | // getting the full file path | 348 | // getting the full file path |
| 348 | // TODO don't call getcwd here, that is inappropriate | 349 | { |
| 349 | var buf: [std.fs.max_path_bytes]u8 = undefined; | 350 | const full_path = try file.path.toAbsolute(comp.dirs, gpa); |
| 350 | const full_path = try std.fs.path.join(arena, &.{ | 351 | defer gpa.free(full_path); |
| 351 | file.mod.root.root_dir.path orelse try std.posix.getcwd(&buf), | 352 | try self.addPathComponents(full_path, &a); |
| 352 | file.mod.root.sub_path, | 353 | } |
| 353 | file.sub_file_path, | ||
| 354 | }); | ||
| 355 | try self.addPathComponents(full_path, &a); | ||
| 356 | 354 | ||
| 357 | // null terminate | 355 | // null terminate |
| 358 | try a.append(0); | 356 | try a.append(0); |
| ... | @@ -437,9 +435,7 @@ pub fn updateFunc( | ... | @@ -437,9 +435,7 @@ pub fn updateFunc( |
| 437 | .start_line = dbg_info_output.start_line.?, | 435 | .start_line = dbg_info_output.start_line.?, |
| 438 | .end_line = dbg_info_output.end_line, | 436 | .end_line = dbg_info_output.end_line, |
| 439 | }; | 437 | }; |
| 440 | // The awkward error handling here is due to putFn calling `std.posix.getcwd` which it should not do. | 438 | try self.putFn(func.owner_nav, out); |
| 441 | self.putFn(func.owner_nav, out) catch |err| | ||
| 442 | return zcu.codegenFail(func.owner_nav, "failed to put fn: {s}", .{@errorName(err)}); | ||
| 443 | return self.updateFinish(pt, func.owner_nav); | 439 | return self.updateFinish(pt, func.owner_nav); |
| 444 | } | 440 | } |
| 445 | 441 |
src/main.zig+228-549| ... | @@ -63,19 +63,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t { | ... | @@ -63,19 +63,7 @@ pub fn wasi_cwd() std.os.wasi.fd_t { |
| 63 | return cwd_fd; | 63 | return cwd_fd; |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | fn getWasiPreopen(name: []const u8) Directory { | 66 | const fatal = std.process.fatal; |
| 67 | return .{ | ||
| 68 | .path = name, | ||
| 69 | .handle = .{ | ||
| 70 | .fd = wasi_preopens.find(name) orelse fatal("WASI preopen not found: '{s}'", .{name}), | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | } | ||
| 74 | |||
| 75 | pub fn fatal(comptime format: []const u8, args: anytype) noreturn { | ||
| 76 | std.log.err(format, args); | ||
| 77 | process.exit(1); | ||
| 78 | } | ||
| 79 | 67 | ||
| 80 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. | 68 | /// Shaming all the locations that inappropriately use an O(N) search algorithm. |
| 81 | /// Please delete this and fix the compilation errors! | 69 | /// Please delete this and fix the compilation errors! |
| ... | @@ -136,7 +124,6 @@ const debug_usage = normal_usage ++ | ... | @@ -136,7 +124,6 @@ const debug_usage = normal_usage ++ |
| 136 | ; | 124 | ; |
| 137 | 125 | ||
| 138 | const usage = if (build_options.enable_debug_extensions) debug_usage else normal_usage; | 126 | const usage = if (build_options.enable_debug_extensions) debug_usage else normal_usage; |
| 139 | const default_local_zig_cache_basename = ".zig-cache"; | ||
| 140 | 127 | ||
| 141 | var log_scopes: std.ArrayListUnmanaged([]const u8) = .empty; | 128 | var log_scopes: std.ArrayListUnmanaged([]const u8) = .empty; |
| 142 | 129 | ||
| ... | @@ -377,13 +364,13 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -377,13 +364,13 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 377 | dev.check(.help_command); | 364 | dev.check(.help_command); |
| 378 | return io.getStdOut().writeAll(usage); | 365 | return io.getStdOut().writeAll(usage); |
| 379 | } else if (mem.eql(u8, cmd, "ast-check")) { | 366 | } else if (mem.eql(u8, cmd, "ast-check")) { |
| 380 | return cmdAstCheck(gpa, arena, cmd_args); | 367 | return cmdAstCheck(arena, cmd_args); |
| 381 | } else if (mem.eql(u8, cmd, "detect-cpu")) { | 368 | } else if (mem.eql(u8, cmd, "detect-cpu")) { |
| 382 | return cmdDetectCpu(gpa, arena, cmd_args); | 369 | return cmdDetectCpu(cmd_args); |
| 383 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) { | 370 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "changelist")) { |
| 384 | return cmdChangelist(gpa, arena, cmd_args); | 371 | return cmdChangelist(arena, cmd_args); |
| 385 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { | 372 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "dump-zir")) { |
| 386 | return cmdDumpZir(gpa, arena, cmd_args); | 373 | return cmdDumpZir(arena, cmd_args); |
| 387 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "llvm-ints")) { | 374 | } else if (build_options.enable_debug_extensions and mem.eql(u8, cmd, "llvm-ints")) { |
| 388 | return cmdDumpLlvmInts(gpa, arena, cmd_args); | 375 | return cmdDumpLlvmInts(gpa, arena, cmd_args); |
| 389 | } else { | 376 | } else { |
| ... | @@ -809,7 +796,8 @@ const Framework = struct { | ... | @@ -809,7 +796,8 @@ const Framework = struct { |
| 809 | }; | 796 | }; |
| 810 | 797 | ||
| 811 | const CliModule = struct { | 798 | const CliModule = struct { |
| 812 | paths: Package.Module.CreateOptions.Paths, | 799 | root_path: []const u8, |
| 800 | root_src_path: []const u8, | ||
| 813 | cc_argv: []const []const u8, | 801 | cc_argv: []const []const u8, |
| 814 | inherited: Package.Module.CreateOptions.Inherited, | 802 | inherited: Package.Module.CreateOptions.Inherited, |
| 815 | target_arch_os_abi: ?[]const u8, | 803 | target_arch_os_abi: ?[]const u8, |
| ... | @@ -976,7 +964,7 @@ fn buildOutputType( | ... | @@ -976,7 +964,7 @@ fn buildOutputType( |
| 976 | // error output consistent. "root" is special. | 964 | // error output consistent. "root" is special. |
| 977 | var create_module: CreateModule = .{ | 965 | var create_module: CreateModule = .{ |
| 978 | // Populated just before the call to `createModule`. | 966 | // Populated just before the call to `createModule`. |
| 979 | .global_cache_directory = undefined, | 967 | .dirs = undefined, |
| 980 | .object_format = null, | 968 | .object_format = null, |
| 981 | .dynamic_linker = null, | 969 | .dynamic_linker = null, |
| 982 | .modules = .{}, | 970 | .modules = .{}, |
| ... | @@ -1859,7 +1847,7 @@ fn buildOutputType( | ... | @@ -1859,7 +1847,7 @@ fn buildOutputType( |
| 1859 | } else root_src_file = arg; | 1847 | } else root_src_file = arg; |
| 1860 | }, | 1848 | }, |
| 1861 | .def, .unknown => { | 1849 | .def, .unknown => { |
| 1862 | if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) { | 1850 | if (std.ascii.eqlIgnoreCase(".xml", fs.path.extension(arg))) { |
| 1863 | warn("embedded manifest files must have the extension '.manifest'", .{}); | 1851 | warn("embedded manifest files must have the extension '.manifest'", .{}); |
| 1864 | } | 1852 | } |
| 1865 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); | 1853 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); |
| ... | @@ -2924,13 +2912,14 @@ fn buildOutputType( | ... | @@ -2924,13 +2912,14 @@ fn buildOutputType( |
| 2924 | } | 2912 | } |
| 2925 | 2913 | ||
| 2926 | implicit_root_mod: { | 2914 | implicit_root_mod: { |
| 2927 | const unresolved_src_path = b: { | 2915 | const src_path = b: { |
| 2928 | if (root_src_file) |src_path| { | 2916 | if (root_src_file) |src_path| { |
| 2929 | if (create_module.modules.count() != 0) { | 2917 | if (create_module.modules.count() != 0) { |
| 2930 | fatal("main module provided both by '-M{s}={}{s}' and by positional argument '{s}'", .{ | 2918 | fatal("main module provided both by '-M{s}={s}{c}{s}' and by positional argument '{s}'", .{ |
| 2931 | create_module.modules.keys()[0], | 2919 | create_module.modules.keys()[0], |
| 2932 | create_module.modules.values()[0].paths.root, | 2920 | create_module.modules.values()[0].root_path, |
| 2933 | create_module.modules.values()[0].paths.root_src_path, | 2921 | fs.path.sep, |
| 2922 | create_module.modules.values()[0].root_src_path, | ||
| 2934 | src_path, | 2923 | src_path, |
| 2935 | }); | 2924 | }); |
| 2936 | } | 2925 | } |
| ... | @@ -2987,20 +2976,14 @@ fn buildOutputType( | ... | @@ -2987,20 +2976,14 @@ fn buildOutputType( |
| 2987 | if (mod_opts.error_tracing == true) | 2976 | if (mod_opts.error_tracing == true) |
| 2988 | create_module.opts.any_error_tracing = true; | 2977 | create_module.opts.any_error_tracing = true; |
| 2989 | 2978 | ||
| 2990 | const src_path = try introspect.resolvePath(arena, unresolved_src_path); | ||
| 2991 | const name = switch (arg_mode) { | 2979 | const name = switch (arg_mode) { |
| 2992 | .zig_test => "test", | 2980 | .zig_test => "test", |
| 2993 | .build, .cc, .cpp, .translate_c, .zig_test_obj, .run => fs.path.stem(fs.path.basename(src_path)), | 2981 | .build, .cc, .cpp, .translate_c, .zig_test_obj, .run => fs.path.stem(fs.path.basename(src_path)), |
| 2994 | }; | 2982 | }; |
| 2995 | 2983 | ||
| 2996 | try create_module.modules.put(arena, name, .{ | 2984 | try create_module.modules.put(arena, name, .{ |
| 2997 | .paths = .{ | 2985 | .root_path = fs.path.dirname(src_path) orelse ".", |
| 2998 | .root = .{ | 2986 | .root_src_path = fs.path.basename(src_path), |
| 2999 | .root_dir = Cache.Directory.cwd(), | ||
| 3000 | .sub_path = fs.path.dirname(src_path) orelse "", | ||
| 3001 | }, | ||
| 3002 | .root_src_path = fs.path.basename(src_path), | ||
| 3003 | }, | ||
| 3004 | .cc_argv = try cc_argv.toOwnedSlice(arena), | 2987 | .cc_argv = try cc_argv.toOwnedSlice(arena), |
| 3005 | .inherited = mod_opts, | 2988 | .inherited = mod_opts, |
| 3006 | .target_arch_os_abi = target_arch_os_abi, | 2989 | .target_arch_os_abi = target_arch_os_abi, |
| ... | @@ -3036,85 +3019,50 @@ fn buildOutputType( | ... | @@ -3036,85 +3019,50 @@ fn buildOutputType( |
| 3036 | }); | 3019 | }); |
| 3037 | } | 3020 | } |
| 3038 | 3021 | ||
| 3039 | const self_exe_path: ?[]const u8 = if (!process.can_spawn) | 3022 | const self_exe_path = switch (native_os) { |
| 3040 | null | 3023 | .wasi => {}, |
| 3041 | else | 3024 | else => fs.selfExePathAlloc(arena) catch |err| { |
| 3042 | introspect.findZigExePath(arena) catch |err| { | ||
| 3043 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); | 3025 | fatal("unable to find zig self exe path: {s}", .{@errorName(err)}); |
| 3044 | }; | 3026 | }, |
| 3045 | |||
| 3046 | var zig_lib_directory: Directory = d: { | ||
| 3047 | if (override_lib_dir) |unresolved_lib_dir| { | ||
| 3048 | const lib_dir = try introspect.resolvePath(arena, unresolved_lib_dir); | ||
| 3049 | break :d .{ | ||
| 3050 | .path = lib_dir, | ||
| 3051 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 3052 | fatal("unable to open zig lib directory '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 3053 | }, | ||
| 3054 | }; | ||
| 3055 | } else if (native_os == .wasi) { | ||
| 3056 | break :d getWasiPreopen("/lib"); | ||
| 3057 | } else if (self_exe_path) |p| { | ||
| 3058 | break :d introspect.findZigLibDirFromSelfExe(arena, p) catch |err| { | ||
| 3059 | fatal("unable to find zig installation directory '{s}': {s}", .{ p, @errorName(err) }); | ||
| 3060 | }; | ||
| 3061 | } else { | ||
| 3062 | unreachable; | ||
| 3063 | } | ||
| 3064 | }; | 3027 | }; |
| 3065 | defer zig_lib_directory.handle.close(); | ||
| 3066 | 3028 | ||
| 3067 | var global_cache_directory: Directory = l: { | 3029 | // This `init` calls `fatal` on error. |
| 3068 | if (override_global_cache_dir) |p| { | 3030 | var dirs: Compilation.Directories = .init( |
| 3069 | break :l .{ | 3031 | arena, |
| 3070 | .handle = try fs.cwd().makeOpenPath(p, .{}), | 3032 | override_lib_dir, |
| 3071 | .path = p, | 3033 | override_global_cache_dir, |
| 3034 | s: { | ||
| 3035 | if (override_local_cache_dir) |p| break :s .{ .override = p }; | ||
| 3036 | break :s switch (arg_mode) { | ||
| 3037 | .run => .global, | ||
| 3038 | else => .search, | ||
| 3072 | }; | 3039 | }; |
| 3073 | } | 3040 | }, |
| 3074 | if (native_os == .wasi) { | 3041 | if (native_os == .wasi) wasi_preopens, |
| 3075 | break :l getWasiPreopen("/cache"); | 3042 | self_exe_path, |
| 3076 | } | 3043 | ); |
| 3077 | const p = try introspect.resolveGlobalCacheDir(arena); | 3044 | defer dirs.deinit(); |
| 3078 | break :l .{ | ||
| 3079 | .handle = try fs.cwd().makeOpenPath(p, .{}), | ||
| 3080 | .path = p, | ||
| 3081 | }; | ||
| 3082 | }; | ||
| 3083 | defer global_cache_directory.handle.close(); | ||
| 3084 | 3045 | ||
| 3085 | if (linker_optimization) |o| { | 3046 | if (linker_optimization) |o| { |
| 3086 | warn("ignoring deprecated linker optimization setting '{s}'", .{o}); | 3047 | warn("ignoring deprecated linker optimization setting '{s}'", .{o}); |
| 3087 | } | 3048 | } |
| 3088 | 3049 | ||
| 3089 | create_module.global_cache_directory = global_cache_directory; | 3050 | create_module.dirs = dirs; |
| 3090 | create_module.opts.emit_llvm_ir = emit_llvm_ir != .no; | 3051 | create_module.opts.emit_llvm_ir = emit_llvm_ir != .no; |
| 3091 | create_module.opts.emit_llvm_bc = emit_llvm_bc != .no; | 3052 | create_module.opts.emit_llvm_bc = emit_llvm_bc != .no; |
| 3092 | create_module.opts.emit_bin = emit_bin != .no; | 3053 | create_module.opts.emit_bin = emit_bin != .no; |
| 3093 | create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0; | 3054 | create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0; |
| 3094 | 3055 | ||
| 3095 | var builtin_modules: std.StringHashMapUnmanaged(*Package.Module) = .empty; | 3056 | const main_mod = try createModule(gpa, arena, &create_module, 0, null, color); |
| 3096 | // `builtin_modules` allocated into `arena`, so no deinit | ||
| 3097 | const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory, &builtin_modules, color); | ||
| 3098 | for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| { | 3057 | for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| { |
| 3099 | if (cli_mod.resolved == null) | 3058 | if (cli_mod.resolved == null) |
| 3100 | fatal("module '{s}' declared but not used", .{key}); | 3059 | fatal("module '{s}' declared but not used", .{key}); |
| 3101 | } | 3060 | } |
| 3102 | 3061 | ||
| 3103 | // When you're testing std, the main module is std. In that case, | 3062 | // When you're testing std, the main module is std, and we need to avoid duplicating the module. |
| 3104 | // we'll just set the std module to the main one, since avoiding | 3063 | const main_mod_is_std = main_mod.root.root == .zig_lib and |
| 3105 | // the errors caused by duplicating it is more effort than it's | 3064 | mem.eql(u8, main_mod.root.sub_path, "std") and |
| 3106 | // worth. | 3065 | mem.eql(u8, main_mod.root_src_path, "std.zig"); |
| 3107 | const main_mod_is_std = m: { | ||
| 3108 | const std_path = try fs.path.resolve(arena, &.{ | ||
| 3109 | zig_lib_directory.path orelse ".", "std", "std.zig", | ||
| 3110 | }); | ||
| 3111 | const main_path = try fs.path.resolve(arena, &.{ | ||
| 3112 | main_mod.root.root_dir.path orelse ".", | ||
| 3113 | main_mod.root.sub_path, | ||
| 3114 | main_mod.root_src_path, | ||
| 3115 | }); | ||
| 3116 | break :m mem.eql(u8, main_path, std_path); | ||
| 3117 | }; | ||
| 3118 | 3066 | ||
| 3119 | const std_mod = m: { | 3067 | const std_mod = m: { |
| 3120 | if (main_mod_is_std) break :m main_mod; | 3068 | if (main_mod_is_std) break :m main_mod; |
| ... | @@ -3126,12 +3074,8 @@ fn buildOutputType( | ... | @@ -3126,12 +3074,8 @@ fn buildOutputType( |
| 3126 | .zig_test, .zig_test_obj => root_mod: { | 3074 | .zig_test, .zig_test_obj => root_mod: { |
| 3127 | const test_mod = if (test_runner_path) |test_runner| test_mod: { | 3075 | const test_mod = if (test_runner_path) |test_runner| test_mod: { |
| 3128 | const test_mod = try Package.Module.create(arena, .{ | 3076 | const test_mod = try Package.Module.create(arena, .{ |
| 3129 | .global_cache_directory = global_cache_directory, | ||
| 3130 | .paths = .{ | 3077 | .paths = .{ |
| 3131 | .root = .{ | 3078 | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(test_runner) orelse "."}), |
| 3132 | .root_dir = Cache.Directory.cwd(), | ||
| 3133 | .sub_path = fs.path.dirname(test_runner) orelse "", | ||
| 3134 | }, | ||
| 3135 | .root_src_path = fs.path.basename(test_runner), | 3079 | .root_src_path = fs.path.basename(test_runner), |
| 3136 | }, | 3080 | }, |
| 3137 | .fully_qualified_name = "root", | 3081 | .fully_qualified_name = "root", |
| ... | @@ -3139,18 +3083,12 @@ fn buildOutputType( | ... | @@ -3139,18 +3083,12 @@ fn buildOutputType( |
| 3139 | .inherited = .{}, | 3083 | .inherited = .{}, |
| 3140 | .global = create_module.resolved_options, | 3084 | .global = create_module.resolved_options, |
| 3141 | .parent = main_mod, | 3085 | .parent = main_mod, |
| 3142 | .builtin_mod = main_mod.getBuiltinDependency(), | ||
| 3143 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 3144 | }); | 3086 | }); |
| 3145 | test_mod.deps = try main_mod.deps.clone(arena); | 3087 | test_mod.deps = try main_mod.deps.clone(arena); |
| 3146 | break :test_mod test_mod; | 3088 | break :test_mod test_mod; |
| 3147 | } else try Package.Module.create(arena, .{ | 3089 | } else try Package.Module.create(arena, .{ |
| 3148 | .global_cache_directory = global_cache_directory, | ||
| 3149 | .paths = .{ | 3090 | .paths = .{ |
| 3150 | .root = .{ | 3091 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 3151 | .root_dir = zig_lib_directory, | ||
| 3152 | .sub_path = "compiler", | ||
| 3153 | }, | ||
| 3154 | .root_src_path = "test_runner.zig", | 3092 | .root_src_path = "test_runner.zig", |
| 3155 | }, | 3093 | }, |
| 3156 | .fully_qualified_name = "root", | 3094 | .fully_qualified_name = "root", |
| ... | @@ -3158,8 +3096,6 @@ fn buildOutputType( | ... | @@ -3158,8 +3096,6 @@ fn buildOutputType( |
| 3158 | .inherited = .{}, | 3096 | .inherited = .{}, |
| 3159 | .global = create_module.resolved_options, | 3097 | .global = create_module.resolved_options, |
| 3160 | .parent = main_mod, | 3098 | .parent = main_mod, |
| 3161 | .builtin_mod = main_mod.getBuiltinDependency(), | ||
| 3162 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 3163 | }); | 3099 | }); |
| 3164 | 3100 | ||
| 3165 | break :root_mod test_mod; | 3101 | break :root_mod test_mod; |
| ... | @@ -3469,50 +3405,6 @@ fn buildOutputType( | ... | @@ -3469,50 +3405,6 @@ fn buildOutputType( |
| 3469 | }); | 3405 | }); |
| 3470 | defer thread_pool.deinit(); | 3406 | defer thread_pool.deinit(); |
| 3471 | 3407 | ||
| 3472 | var cleanup_local_cache_dir: ?fs.Dir = null; | ||
| 3473 | defer if (cleanup_local_cache_dir) |*dir| dir.close(); | ||
| 3474 | |||
| 3475 | var local_cache_directory: Directory = l: { | ||
| 3476 | if (override_local_cache_dir) |local_cache_dir_path| { | ||
| 3477 | const dir = try fs.cwd().makeOpenPath(local_cache_dir_path, .{}); | ||
| 3478 | cleanup_local_cache_dir = dir; | ||
| 3479 | break :l .{ | ||
| 3480 | .handle = dir, | ||
| 3481 | .path = local_cache_dir_path, | ||
| 3482 | }; | ||
| 3483 | } | ||
| 3484 | if (arg_mode == .run) { | ||
| 3485 | break :l global_cache_directory; | ||
| 3486 | } | ||
| 3487 | |||
| 3488 | // search upwards from cwd until we find directory with build.zig | ||
| 3489 | const cwd_path = try process.getCwdAlloc(arena); | ||
| 3490 | var dirname: []const u8 = cwd_path; | ||
| 3491 | while (true) { | ||
| 3492 | const joined_path = try fs.path.join(arena, &.{ | ||
| 3493 | dirname, Package.build_zig_basename, | ||
| 3494 | }); | ||
| 3495 | if (fs.cwd().access(joined_path, .{})) |_| { | ||
| 3496 | const cache_dir_path = try fs.path.join(arena, &.{ dirname, default_local_zig_cache_basename }); | ||
| 3497 | const dir = try fs.cwd().makeOpenPath(cache_dir_path, .{}); | ||
| 3498 | cleanup_local_cache_dir = dir; | ||
| 3499 | break :l .{ .handle = dir, .path = cache_dir_path }; | ||
| 3500 | } else |err| switch (err) { | ||
| 3501 | error.FileNotFound => { | ||
| 3502 | dirname = fs.path.dirname(dirname) orelse { | ||
| 3503 | break :l global_cache_directory; | ||
| 3504 | }; | ||
| 3505 | continue; | ||
| 3506 | }, | ||
| 3507 | else => break :l global_cache_directory, | ||
| 3508 | } | ||
| 3509 | } | ||
| 3510 | |||
| 3511 | // Otherwise we really don't have a reasonable place to put the local cache directory, | ||
| 3512 | // so we utilize the global one. | ||
| 3513 | break :l global_cache_directory; | ||
| 3514 | }; | ||
| 3515 | |||
| 3516 | for (create_module.c_source_files.items) |*src| { | 3408 | for (create_module.c_source_files.items) |*src| { |
| 3517 | if (!mem.eql(u8, src.src_path, "-")) continue; | 3409 | if (!mem.eql(u8, src.src_path, "-")) continue; |
| 3518 | 3410 | ||
| ... | @@ -3524,14 +3416,14 @@ fn buildOutputType( | ... | @@ -3524,14 +3416,14 @@ fn buildOutputType( |
| 3524 | const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ | 3416 | const dump_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-dump-stdin{s}", .{ |
| 3525 | std.crypto.random.int(u64), ext.canonicalName(target), | 3417 | std.crypto.random.int(u64), ext.canonicalName(target), |
| 3526 | }); | 3418 | }); |
| 3527 | try local_cache_directory.handle.makePath("tmp"); | 3419 | try dirs.local_cache.handle.makePath("tmp"); |
| 3528 | 3420 | ||
| 3529 | // Note that in one of the happy paths, execve() is used to switch to | 3421 | // Note that in one of the happy paths, execve() is used to switch to |
| 3530 | // clang in which case any cleanup logic that exists for this temporary | 3422 | // clang in which case any cleanup logic that exists for this temporary |
| 3531 | // file will not run and this temp file will be leaked. The filename | 3423 | // file will not run and this temp file will be leaked. The filename |
| 3532 | // will be a hash of its contents — so multiple invocations of | 3424 | // will be a hash of its contents — so multiple invocations of |
| 3533 | // `zig cc -` will result in the same temp file name. | 3425 | // `zig cc -` will result in the same temp file name. |
| 3534 | var f = try local_cache_directory.handle.createFile(dump_path, .{}); | 3426 | var f = try dirs.local_cache.handle.createFile(dump_path, .{}); |
| 3535 | defer f.close(); | 3427 | defer f.close(); |
| 3536 | 3428 | ||
| 3537 | // Re-using the hasher from Cache, since the functional requirements | 3429 | // Re-using the hasher from Cache, since the functional requirements |
| ... | @@ -3550,10 +3442,10 @@ fn buildOutputType( | ... | @@ -3550,10 +3442,10 @@ fn buildOutputType( |
| 3550 | std.fmt.fmtSliceHexLower(&bin_digest), | 3442 | std.fmt.fmtSliceHexLower(&bin_digest), |
| 3551 | ext.canonicalName(target), | 3443 | ext.canonicalName(target), |
| 3552 | }); | 3444 | }); |
| 3553 | try local_cache_directory.handle.rename(dump_path, sub_path); | 3445 | try dirs.local_cache.handle.rename(dump_path, sub_path); |
| 3554 | 3446 | ||
| 3555 | // Convert `sub_path` to be relative to current working directory. | 3447 | // Convert `sub_path` to be relative to current working directory. |
| 3556 | src.src_path = try local_cache_directory.join(arena, &.{sub_path}); | 3448 | src.src_path = try dirs.local_cache.join(arena, &.{sub_path}); |
| 3557 | } | 3449 | } |
| 3558 | 3450 | ||
| 3559 | if (build_options.have_llvm and emit_asm != .no) { | 3451 | if (build_options.have_llvm and emit_asm != .no) { |
| ... | @@ -3595,11 +3487,12 @@ fn buildOutputType( | ... | @@ -3595,11 +3487,12 @@ fn buildOutputType( |
| 3595 | defer file_system_inputs.deinit(gpa); | 3487 | defer file_system_inputs.deinit(gpa); |
| 3596 | 3488 | ||
| 3597 | const comp = Compilation.create(gpa, arena, .{ | 3489 | const comp = Compilation.create(gpa, arena, .{ |
| 3598 | .zig_lib_directory = zig_lib_directory, | 3490 | .dirs = dirs, |
| 3599 | .local_cache_directory = local_cache_directory, | ||
| 3600 | .global_cache_directory = global_cache_directory, | ||
| 3601 | .thread_pool = &thread_pool, | 3491 | .thread_pool = &thread_pool, |
| 3602 | .self_exe_path = self_exe_path, | 3492 | .self_exe_path = switch (native_os) { |
| 3493 | .wasi => null, | ||
| 3494 | else => self_exe_path, | ||
| 3495 | }, | ||
| 3603 | .config = create_module.resolved_options, | 3496 | .config = create_module.resolved_options, |
| 3604 | .root_name = root_name, | 3497 | .root_name = root_name, |
| 3605 | .sysroot = create_module.sysroot, | 3498 | .sysroot = create_module.sysroot, |
| ... | @@ -3757,14 +3650,17 @@ fn buildOutputType( | ... | @@ -3757,14 +3650,17 @@ fn buildOutputType( |
| 3757 | error.ExportTableAndImportTableConflict => { | 3650 | error.ExportTableAndImportTableConflict => { |
| 3758 | fatal("--import-table and --export-table may not be used together", .{}); | 3651 | fatal("--import-table and --export-table may not be used together", .{}); |
| 3759 | }, | 3652 | }, |
| 3653 | error.IllegalZigImport => { | ||
| 3654 | fatal("this compiler implementation does not support importing the root source file of a provided module", .{}); | ||
| 3655 | }, | ||
| 3760 | else => fatal("unable to create compilation: {s}", .{@errorName(err)}), | 3656 | else => fatal("unable to create compilation: {s}", .{@errorName(err)}), |
| 3761 | }; | 3657 | }; |
| 3762 | var comp_destroyed = false; | 3658 | var comp_destroyed = false; |
| 3763 | defer if (!comp_destroyed) comp.destroy(); | 3659 | defer if (!comp_destroyed) comp.destroy(); |
| 3764 | 3660 | ||
| 3765 | if (show_builtin) { | 3661 | if (show_builtin) { |
| 3766 | const builtin_mod = comp.root_mod.getBuiltinDependency(); | 3662 | const builtin_opts = comp.root_mod.getBuiltinOptions(comp.config); |
| 3767 | const source = builtin_mod.builtin_file.?.source.?; | 3663 | const source = try builtin_opts.generate(arena); |
| 3768 | return std.io.getStdOut().writeAll(source); | 3664 | return std.io.getStdOut().writeAll(source); |
| 3769 | } | 3665 | } |
| 3770 | switch (listen) { | 3666 | switch (listen) { |
| ... | @@ -3844,7 +3740,7 @@ fn buildOutputType( | ... | @@ -3844,7 +3740,7 @@ fn buildOutputType( |
| 3844 | c_code_directory.path orelse ".", c_code_loc.basename, | 3740 | c_code_directory.path orelse ".", c_code_loc.basename, |
| 3845 | }); | 3741 | }); |
| 3846 | try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" }); | 3742 | try test_exec_args.appendSlice(arena, &.{ self_exe_path, "run" }); |
| 3847 | if (zig_lib_directory.path) |p| { | 3743 | if (dirs.zig_lib.path) |p| { |
| 3848 | try test_exec_args.appendSlice(arena, &.{ "-I", p }); | 3744 | try test_exec_args.appendSlice(arena, &.{ "-I", p }); |
| 3849 | } | 3745 | } |
| 3850 | 3746 | ||
| ... | @@ -3875,7 +3771,7 @@ fn buildOutputType( | ... | @@ -3875,7 +3771,7 @@ fn buildOutputType( |
| 3875 | gpa, | 3771 | gpa, |
| 3876 | arena, | 3772 | arena, |
| 3877 | test_exec_args.items, | 3773 | test_exec_args.items, |
| 3878 | self_exe_path.?, | 3774 | self_exe_path, |
| 3879 | arg_mode, | 3775 | arg_mode, |
| 3880 | &target, | 3776 | &target, |
| 3881 | &comp_destroyed, | 3777 | &comp_destroyed, |
| ... | @@ -3890,7 +3786,7 @@ fn buildOutputType( | ... | @@ -3890,7 +3786,7 @@ fn buildOutputType( |
| 3890 | } | 3786 | } |
| 3891 | 3787 | ||
| 3892 | const CreateModule = struct { | 3788 | const CreateModule = struct { |
| 3893 | global_cache_directory: Cache.Directory, | 3789 | dirs: Compilation.Directories, |
| 3894 | modules: std.StringArrayHashMapUnmanaged(CliModule), | 3790 | modules: std.StringArrayHashMapUnmanaged(CliModule), |
| 3895 | opts: Compilation.Config.Options, | 3791 | opts: Compilation.Config.Options, |
| 3896 | dynamic_linker: ?[]const u8, | 3792 | dynamic_linker: ?[]const u8, |
| ... | @@ -3937,8 +3833,6 @@ fn createModule( | ... | @@ -3937,8 +3833,6 @@ fn createModule( |
| 3937 | create_module: *CreateModule, | 3833 | create_module: *CreateModule, |
| 3938 | index: usize, | 3834 | index: usize, |
| 3939 | parent: ?*Package.Module, | 3835 | parent: ?*Package.Module, |
| 3940 | zig_lib_directory: Cache.Directory, | ||
| 3941 | builtin_modules: *std.StringHashMapUnmanaged(*Package.Module), | ||
| 3942 | color: std.zig.Color, | 3836 | color: std.zig.Color, |
| 3943 | ) Allocator.Error!*Package.Module { | 3837 | ) Allocator.Error!*Package.Module { |
| 3944 | const cli_mod = &create_module.modules.values()[index]; | 3838 | const cli_mod = &create_module.modules.values()[index]; |
| ... | @@ -4069,7 +3963,7 @@ fn createModule( | ... | @@ -4069,7 +3963,7 @@ fn createModule( |
| 4069 | } | 3963 | } |
| 4070 | 3964 | ||
| 4071 | if (target.isMinGW()) { | 3965 | if (target.isMinGW()) { |
| 4072 | const exists = mingw.libExists(arena, target, zig_lib_directory, lib_name) catch |err| { | 3966 | const exists = mingw.libExists(arena, target, create_module.dirs.zig_lib, lib_name) catch |err| { |
| 4073 | fatal("failed to check zig installation for DLL import libs: {s}", .{ | 3967 | fatal("failed to check zig installation for DLL import libs: {s}", .{ |
| 4074 | @errorName(err), | 3968 | @errorName(err), |
| 4075 | }); | 3969 | }); |
| ... | @@ -4225,17 +4119,19 @@ fn createModule( | ... | @@ -4225,17 +4119,19 @@ fn createModule( |
| 4225 | }; | 4119 | }; |
| 4226 | } | 4120 | } |
| 4227 | 4121 | ||
| 4122 | const root: Compilation.Path = try .fromUnresolved(arena, create_module.dirs, &.{cli_mod.root_path}); | ||
| 4123 | |||
| 4228 | const mod = Package.Module.create(arena, .{ | 4124 | const mod = Package.Module.create(arena, .{ |
| 4229 | .global_cache_directory = create_module.global_cache_directory, | 4125 | .paths = .{ |
| 4230 | .paths = cli_mod.paths, | 4126 | .root = root, |
| 4127 | .root_src_path = cli_mod.root_src_path, | ||
| 4128 | }, | ||
| 4231 | .fully_qualified_name = name, | 4129 | .fully_qualified_name = name, |
| 4232 | 4130 | ||
| 4233 | .cc_argv = cli_mod.cc_argv, | 4131 | .cc_argv = cli_mod.cc_argv, |
| 4234 | .inherited = cli_mod.inherited, | 4132 | .inherited = cli_mod.inherited, |
| 4235 | .global = create_module.resolved_options, | 4133 | .global = create_module.resolved_options, |
| 4236 | .parent = parent, | 4134 | .parent = parent, |
| 4237 | .builtin_mod = null, | ||
| 4238 | .builtin_modules = builtin_modules, | ||
| 4239 | }) catch |err| switch (err) { | 4135 | }) catch |err| switch (err) { |
| 4240 | error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}), | 4136 | error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}), |
| 4241 | error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}), | 4137 | error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}), |
| ... | @@ -4258,7 +4154,7 @@ fn createModule( | ... | @@ -4258,7 +4154,7 @@ fn createModule( |
| 4258 | for (cli_mod.deps) |dep| { | 4154 | for (cli_mod.deps) |dep| { |
| 4259 | const dep_index = create_module.modules.getIndex(dep.value) orelse | 4155 | const dep_index = create_module.modules.getIndex(dep.value) orelse |
| 4260 | fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key }); | 4156 | fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key }); |
| 4261 | const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, zig_lib_directory, builtin_modules, color); | 4157 | const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, color); |
| 4262 | try mod.deps.put(arena, dep.key, dep_mod); | 4158 | try mod.deps.put(arena, dep.key, dep_mod); |
| 4263 | } | 4159 | } |
| 4264 | 4160 | ||
| ... | @@ -4544,15 +4440,13 @@ fn runOrTestHotSwap( | ... | @@ -4544,15 +4440,13 @@ fn runOrTestHotSwap( |
| 4544 | // tmp zig-cache and use it to spawn the child process. This way we are free to update | 4440 | // tmp zig-cache and use it to spawn the child process. This way we are free to update |
| 4545 | // the binary with each requested hot update. | 4441 | // the binary with each requested hot update. |
| 4546 | .windows => blk: { | 4442 | .windows => blk: { |
| 4547 | try lf.emit.root_dir.handle.copyFile(lf.emit.sub_path, comp.local_cache_directory.handle, lf.emit.sub_path, .{}); | 4443 | try lf.emit.root_dir.handle.copyFile(lf.emit.sub_path, comp.dirs.local_cache.handle, lf.emit.sub_path, .{}); |
| 4548 | break :blk try fs.path.join(gpa, &[_][]const u8{ | 4444 | break :blk try fs.path.join(gpa, &.{ comp.dirs.local_cache.path orelse ".", lf.emit.sub_path }); |
| 4549 | comp.local_cache_directory.path orelse ".", lf.emit.sub_path, | ||
| 4550 | }); | ||
| 4551 | }, | 4445 | }, |
| 4552 | 4446 | ||
| 4553 | // A naive `directory.join` here will indeed get the correct path to the binary, | 4447 | // A naive `directory.join` here will indeed get the correct path to the binary, |
| 4554 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. | 4448 | // however, in the case of cwd, we actually want `./foo` so that the path can be executed. |
| 4555 | else => try fs.path.join(gpa, &[_][]const u8{ | 4449 | else => try fs.path.join(gpa, &.{ |
| 4556 | lf.emit.root_dir.path orelse ".", lf.emit.sub_path, | 4450 | lf.emit.root_dir.path orelse ".", lf.emit.sub_path, |
| 4557 | }), | 4451 | }), |
| 4558 | }; | 4452 | }; |
| ... | @@ -4679,7 +4573,7 @@ fn cmdTranslateC( | ... | @@ -4679,7 +4573,7 @@ fn cmdTranslateC( |
| 4679 | }, | 4573 | }, |
| 4680 | } | 4574 | } |
| 4681 | 4575 | ||
| 4682 | var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{}); | 4576 | var zig_cache_tmp_dir = try comp.dirs.local_cache.handle.makeOpenPath("tmp", .{}); |
| 4683 | defer zig_cache_tmp_dir.close(); | 4577 | defer zig_cache_tmp_dir.close(); |
| 4684 | 4578 | ||
| 4685 | const ext = Compilation.classifyFileExt(c_source_file.src_path); | 4579 | const ext = Compilation.classifyFileExt(c_source_file.src_path); |
| ... | @@ -4735,7 +4629,7 @@ fn cmdTranslateC( | ... | @@ -4735,7 +4629,7 @@ fn cmdTranslateC( |
| 4735 | new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); | 4629 | new_argv[argv.items.len + i] = try arena.dupeZ(u8, arg); |
| 4736 | } | 4630 | } |
| 4737 | 4631 | ||
| 4738 | const c_headers_dir_path_z = try comp.zig_lib_directory.joinZ(arena, &[_][]const u8{"include"}); | 4632 | const c_headers_dir_path_z = try comp.dirs.zig_lib.joinZ(arena, &.{"include"}); |
| 4739 | var errors = std.zig.ErrorBundle.empty; | 4633 | var errors = std.zig.ErrorBundle.empty; |
| 4740 | var tree = translate_c.translate( | 4634 | var tree = translate_c.translate( |
| 4741 | comp.gpa, | 4635 | comp.gpa, |
| ... | @@ -4787,7 +4681,7 @@ fn cmdTranslateC( | ... | @@ -4787,7 +4681,7 @@ fn cmdTranslateC( |
| 4787 | 4681 | ||
| 4788 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest }); | 4682 | const o_sub_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest }); |
| 4789 | 4683 | ||
| 4790 | var o_dir = try comp.local_cache_directory.handle.makeOpenPath(o_sub_path, .{}); | 4684 | var o_dir = try comp.dirs.local_cache.handle.makeOpenPath(o_sub_path, .{}); |
| 4791 | defer o_dir.close(); | 4685 | defer o_dir.close(); |
| 4792 | 4686 | ||
| 4793 | var zig_file = try o_dir.createFile(translated_zig_basename, .{}); | 4687 | var zig_file = try o_dir.createFile(translated_zig_basename, .{}); |
| ... | @@ -4808,9 +4702,9 @@ fn cmdTranslateC( | ... | @@ -4808,9 +4702,9 @@ fn cmdTranslateC( |
| 4808 | p.digest = bin_digest; | 4702 | p.digest = bin_digest; |
| 4809 | p.errors = std.zig.ErrorBundle.empty; | 4703 | p.errors = std.zig.ErrorBundle.empty; |
| 4810 | } else { | 4704 | } else { |
| 4811 | const out_zig_path = try fs.path.join(arena, &[_][]const u8{ "o", &hex_digest, translated_zig_basename }); | 4705 | const out_zig_path = try fs.path.join(arena, &.{ "o", &hex_digest, translated_zig_basename }); |
| 4812 | const zig_file = comp.local_cache_directory.handle.openFile(out_zig_path, .{}) catch |err| { | 4706 | const zig_file = comp.dirs.local_cache.handle.openFile(out_zig_path, .{}) catch |err| { |
| 4813 | const path = comp.local_cache_directory.path orelse "."; | 4707 | const path = comp.dirs.local_cache.path orelse "."; |
| 4814 | fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, fs.path.sep_str, out_zig_path, @errorName(err) }); | 4708 | fatal("unable to open cached translated zig file '{s}{s}{s}': {s}", .{ path, fs.path.sep_str, out_zig_path, @errorName(err) }); |
| 4815 | }; | 4709 | }; |
| 4816 | defer zig_file.close(); | 4710 | defer zig_file.close(); |
| ... | @@ -4854,7 +4748,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4854,7 +4748,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4854 | var templates = findTemplates(gpa, arena); | 4748 | var templates = findTemplates(gpa, arena); |
| 4855 | defer templates.deinit(); | 4749 | defer templates.deinit(); |
| 4856 | 4750 | ||
| 4857 | const cwd_path = try process.getCwdAlloc(arena); | 4751 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 4858 | const cwd_basename = fs.path.basename(cwd_path); | 4752 | const cwd_basename = fs.path.basename(cwd_path); |
| 4859 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); | 4753 | const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename); |
| 4860 | 4754 | ||
| ... | @@ -4952,7 +4846,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -4952,7 +4846,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4952 | const argv_index_exe = child_argv.items.len; | 4846 | const argv_index_exe = child_argv.items.len; |
| 4953 | _ = try child_argv.addOne(); | 4847 | _ = try child_argv.addOne(); |
| 4954 | 4848 | ||
| 4955 | const self_exe_path = try introspect.findZigExePath(arena); | 4849 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 4956 | try child_argv.append(self_exe_path); | 4850 | try child_argv.append(self_exe_path); |
| 4957 | 4851 | ||
| 4958 | const argv_index_zig_lib_dir = child_argv.items.len; | 4852 | const argv_index_zig_lib_dir = child_argv.items.len; |
| ... | @@ -5169,60 +5063,30 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5169,60 +5063,30 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5169 | 5063 | ||
| 5170 | process.raiseFileDescriptorLimit(); | 5064 | process.raiseFileDescriptorLimit(); |
| 5171 | 5065 | ||
| 5172 | var zig_lib_directory: Directory = if (override_lib_dir) |lib_dir| .{ | 5066 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 5173 | .path = lib_dir, | ||
| 5174 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | ||
| 5175 | fatal("unable to open zig lib directory from 'zig-lib-dir' argument: '{s}': {s}", .{ lib_dir, @errorName(err) }); | ||
| 5176 | }, | ||
| 5177 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | ||
| 5178 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | ||
| 5179 | }; | ||
| 5180 | defer zig_lib_directory.handle.close(); | ||
| 5181 | |||
| 5182 | const cwd_path = try process.getCwdAlloc(arena); | ||
| 5183 | child_argv.items[argv_index_zig_lib_dir] = zig_lib_directory.path orelse cwd_path; | ||
| 5184 | |||
| 5185 | const build_root = try findBuildRoot(arena, .{ | 5067 | const build_root = try findBuildRoot(arena, .{ |
| 5186 | .cwd_path = cwd_path, | 5068 | .cwd_path = cwd_path, |
| 5187 | .build_file = build_file, | 5069 | .build_file = build_file, |
| 5188 | }); | 5070 | }); |
| 5189 | child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; | ||
| 5190 | |||
| 5191 | var global_cache_directory: Directory = l: { | ||
| 5192 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); | ||
| 5193 | const dir = fs.cwd().makeOpenPath(p, .{}) catch |err| { | ||
| 5194 | const base_msg = "unable to open or create the global Zig cache at '{s}': {s}.{s}"; | ||
| 5195 | const extra = "\nIf this location is not writable then consider specifying an " ++ | ||
| 5196 | "alternative with the ZIG_GLOBAL_CACHE_DIR environment variable or the " ++ | ||
| 5197 | "--global-cache-dir option."; | ||
| 5198 | const show_extra = err == error.AccessDenied or err == error.ReadOnlyFileSystem; | ||
| 5199 | fatal(base_msg, .{ p, @errorName(err), if (show_extra) extra else "" }); | ||
| 5200 | }; | ||
| 5201 | break :l .{ | ||
| 5202 | .handle = dir, | ||
| 5203 | .path = p, | ||
| 5204 | }; | ||
| 5205 | }; | ||
| 5206 | defer global_cache_directory.handle.close(); | ||
| 5207 | 5071 | ||
| 5208 | child_argv.items[argv_index_global_cache_dir] = global_cache_directory.path orelse cwd_path; | 5072 | // This `init` calls `fatal` on error. |
| 5209 | 5073 | var dirs: Compilation.Directories = .init( | |
| 5210 | var local_cache_directory: Directory = l: { | 5074 | arena, |
| 5211 | if (override_local_cache_dir) |local_cache_dir_path| { | 5075 | override_lib_dir, |
| 5212 | break :l .{ | 5076 | override_global_cache_dir, |
| 5213 | .handle = try fs.cwd().makeOpenPath(local_cache_dir_path, .{}), | 5077 | .{ .override = path: { |
| 5214 | .path = local_cache_dir_path, | 5078 | if (override_local_cache_dir) |d| break :path d; |
| 5215 | }; | 5079 | break :path try build_root.directory.join(arena, &.{introspect.default_local_zig_cache_basename}); |
| 5216 | } | 5080 | } }, |
| 5217 | const cache_dir_path = try build_root.directory.join(arena, &.{default_local_zig_cache_basename}); | 5081 | {}, |
| 5218 | break :l .{ | 5082 | self_exe_path, |
| 5219 | .handle = try build_root.directory.handle.makeOpenPath(default_local_zig_cache_basename, .{}), | 5083 | ); |
| 5220 | .path = cache_dir_path, | 5084 | defer dirs.deinit(); |
| 5221 | }; | ||
| 5222 | }; | ||
| 5223 | defer local_cache_directory.handle.close(); | ||
| 5224 | 5085 | ||
| 5225 | child_argv.items[argv_index_cache_dir] = local_cache_directory.path orelse cwd_path; | 5086 | child_argv.items[argv_index_zig_lib_dir] = dirs.zig_lib.path orelse cwd_path; |
| 5087 | child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; | ||
| 5088 | child_argv.items[argv_index_global_cache_dir] = dirs.global_cache.path orelse cwd_path; | ||
| 5089 | child_argv.items[argv_index_cache_dir] = dirs.local_cache.path orelse cwd_path; | ||
| 5226 | 5090 | ||
| 5227 | var thread_pool: ThreadPool = undefined; | 5091 | var thread_pool: ThreadPool = undefined; |
| 5228 | try thread_pool.init(.{ | 5092 | try thread_pool.init(.{ |
| ... | @@ -5250,16 +5114,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5250,16 +5114,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5250 | // big block here to ensure the cleanup gets run when we extract out our argv. | 5114 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5251 | { | 5115 | { |
| 5252 | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_build_runner) |runner| .{ | 5116 | const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_build_runner) |runner| .{ |
| 5253 | .root = .{ | 5117 | .root = try .fromUnresolved(arena, dirs, &.{fs.path.dirname(runner) orelse "."}), |
| 5254 | .root_dir = Cache.Directory.cwd(), | ||
| 5255 | .sub_path = fs.path.dirname(runner) orelse "", | ||
| 5256 | }, | ||
| 5257 | .root_src_path = fs.path.basename(runner), | 5118 | .root_src_path = fs.path.basename(runner), |
| 5258 | } else .{ | 5119 | } else .{ |
| 5259 | .root = .{ | 5120 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5260 | .root_dir = zig_lib_directory, | ||
| 5261 | .sub_path = "compiler", | ||
| 5262 | }, | ||
| 5263 | .root_src_path = "build_runner.zig", | 5121 | .root_src_path = "build_runner.zig", |
| 5264 | }; | 5122 | }; |
| 5265 | 5123 | ||
| ... | @@ -5272,7 +5130,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5272,7 +5130,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5272 | }); | 5130 | }); |
| 5273 | 5131 | ||
| 5274 | const root_mod = try Package.Module.create(arena, .{ | 5132 | const root_mod = try Package.Module.create(arena, .{ |
| 5275 | .global_cache_directory = global_cache_directory, | ||
| 5276 | .paths = main_mod_paths, | 5133 | .paths = main_mod_paths, |
| 5277 | .fully_qualified_name = "root", | 5134 | .fully_qualified_name = "root", |
| 5278 | .cc_argv = &.{}, | 5135 | .cc_argv = &.{}, |
| ... | @@ -5281,16 +5138,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5281,16 +5138,11 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5281 | }, | 5138 | }, |
| 5282 | .global = config, | 5139 | .global = config, |
| 5283 | .parent = null, | 5140 | .parent = null, |
| 5284 | .builtin_mod = null, | ||
| 5285 | .builtin_modules = null, // all modules will inherit this one's builtin | ||
| 5286 | }); | 5141 | }); |
| 5287 | 5142 | ||
| 5288 | const builtin_mod = root_mod.getBuiltinDependency(); | ||
| 5289 | |||
| 5290 | const build_mod = try Package.Module.create(arena, .{ | 5143 | const build_mod = try Package.Module.create(arena, .{ |
| 5291 | .global_cache_directory = global_cache_directory, | ||
| 5292 | .paths = .{ | 5144 | .paths = .{ |
| 5293 | .root = .{ .root_dir = build_root.directory }, | 5145 | .root = try .fromUnresolved(arena, dirs, &.{build_root.directory.path orelse "."}), |
| 5294 | .root_src_path = build_root.build_zig_basename, | 5146 | .root_src_path = build_root.build_zig_basename, |
| 5295 | }, | 5147 | }, |
| 5296 | .fully_qualified_name = "root.@build", | 5148 | .fully_qualified_name = "root.@build", |
| ... | @@ -5298,8 +5150,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5298,8 +5150,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5298 | .inherited = .{}, | 5150 | .inherited = .{}, |
| 5299 | .global = config, | 5151 | .global = config, |
| 5300 | .parent = root_mod, | 5152 | .parent = root_mod, |
| 5301 | .builtin_mod = builtin_mod, | ||
| 5302 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5303 | }); | 5153 | }); |
| 5304 | 5154 | ||
| 5305 | var cleanup_build_dir: ?fs.Dir = null; | 5155 | var cleanup_build_dir: ?fs.Dir = null; |
| ... | @@ -5312,7 +5162,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5312,7 +5162,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5312 | var job_queue: Package.Fetch.JobQueue = .{ | 5162 | var job_queue: Package.Fetch.JobQueue = .{ |
| 5313 | .http_client = &http_client, | 5163 | .http_client = &http_client, |
| 5314 | .thread_pool = &thread_pool, | 5164 | .thread_pool = &thread_pool, |
| 5315 | .global_cache = global_cache_directory, | 5165 | .global_cache = dirs.global_cache, |
| 5316 | .read_only = false, | 5166 | .read_only = false, |
| 5317 | .recursive = true, | 5167 | .recursive = true, |
| 5318 | .debug_hash = false, | 5168 | .debug_hash = false, |
| ... | @@ -5340,14 +5190,16 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5340,14 +5190,16 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5340 | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); | 5190 | try job_queue.all_fetches.ensureUnusedCapacity(gpa, 1); |
| 5341 | try job_queue.table.ensureUnusedCapacity(gpa, 1); | 5191 | try job_queue.table.ensureUnusedCapacity(gpa, 1); |
| 5342 | 5192 | ||
| 5193 | const phantom_package_root: Cache.Path = .{ .root_dir = build_root.directory }; | ||
| 5194 | |||
| 5343 | var fetch: Package.Fetch = .{ | 5195 | var fetch: Package.Fetch = .{ |
| 5344 | .arena = std.heap.ArenaAllocator.init(gpa), | 5196 | .arena = std.heap.ArenaAllocator.init(gpa), |
| 5345 | .location = .{ .relative_path = build_mod.root }, | 5197 | .location = .{ .relative_path = phantom_package_root }, |
| 5346 | .location_tok = 0, | 5198 | .location_tok = 0, |
| 5347 | .hash_tok = .none, | 5199 | .hash_tok = .none, |
| 5348 | .name_tok = 0, | 5200 | .name_tok = 0, |
| 5349 | .lazy_status = .eager, | 5201 | .lazy_status = .eager, |
| 5350 | .parent_package_root = build_mod.root, | 5202 | .parent_package_root = phantom_package_root, |
| 5351 | .parent_manifest_ast = null, | 5203 | .parent_manifest_ast = null, |
| 5352 | .prog_node = fetch_prog_node, | 5204 | .prog_node = fetch_prog_node, |
| 5353 | .job_queue = &job_queue, | 5205 | .job_queue = &job_queue, |
| ... | @@ -5371,7 +5223,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5371,7 +5223,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5371 | job_queue.all_fetches.appendAssumeCapacity(&fetch); | 5223 | job_queue.all_fetches.appendAssumeCapacity(&fetch); |
| 5372 | 5224 | ||
| 5373 | job_queue.table.putAssumeCapacityNoClobber( | 5225 | job_queue.table.putAssumeCapacityNoClobber( |
| 5374 | Package.Fetch.relativePathDigest(build_mod.root, global_cache_directory), | 5226 | Package.Fetch.relativePathDigest(phantom_package_root, dirs.global_cache), |
| 5375 | &fetch, | 5227 | &fetch, |
| 5376 | ); | 5228 | ); |
| 5377 | 5229 | ||
| ... | @@ -5397,9 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5397,9 +5249,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5397 | arena, | 5249 | arena, |
| 5398 | source_buf.items, | 5250 | source_buf.items, |
| 5399 | root_mod, | 5251 | root_mod, |
| 5400 | global_cache_directory, | 5252 | dirs, |
| 5401 | local_cache_directory, | ||
| 5402 | builtin_mod, | ||
| 5403 | config, | 5253 | config, |
| 5404 | ); | 5254 | ); |
| 5405 | 5255 | ||
| ... | @@ -5416,10 +5266,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5416,10 +5266,10 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5416 | if (!f.has_build_zig) | 5266 | if (!f.has_build_zig) |
| 5417 | continue; | 5267 | continue; |
| 5418 | const hash_slice = hash.toSlice(); | 5268 | const hash_slice = hash.toSlice(); |
| 5269 | const mod_root_path = try f.package_root.toString(arena); | ||
| 5419 | const m = try Package.Module.create(arena, .{ | 5270 | const m = try Package.Module.create(arena, .{ |
| 5420 | .global_cache_directory = global_cache_directory, | ||
| 5421 | .paths = .{ | 5271 | .paths = .{ |
| 5422 | .root = try f.package_root.clone(arena), | 5272 | .root = try .fromUnresolved(arena, dirs, &.{mod_root_path}), |
| 5423 | .root_src_path = Package.build_zig_basename, | 5273 | .root_src_path = Package.build_zig_basename, |
| 5424 | }, | 5274 | }, |
| 5425 | .fully_qualified_name = try std.fmt.allocPrint( | 5275 | .fully_qualified_name = try std.fmt.allocPrint( |
| ... | @@ -5431,8 +5281,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5431,8 +5281,6 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5431 | .inherited = .{}, | 5281 | .inherited = .{}, |
| 5432 | .global = config, | 5282 | .global = config, |
| 5433 | .parent = root_mod, | 5283 | .parent = root_mod, |
| 5434 | .builtin_mod = builtin_mod, | ||
| 5435 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5436 | }); | 5284 | }); |
| 5437 | const hash_cloned = try arena.dupe(u8, hash_slice); | 5285 | const hash_cloned = try arena.dupe(u8, hash_slice); |
| 5438 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); | 5286 | deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m); |
| ... | @@ -5449,7 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5449,7 +5297,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5449 | for (dep_names, man.dependencies.values()) |name, dep| { | 5297 | for (dep_names, man.dependencies.values()) |name, dep| { |
| 5450 | const dep_digest = Package.Fetch.depDigest( | 5298 | const dep_digest = Package.Fetch.depDigest( |
| 5451 | f.package_root, | 5299 | f.package_root, |
| 5452 | global_cache_directory, | 5300 | dirs.global_cache, |
| 5453 | dep, | 5301 | dep, |
| 5454 | ) orelse continue; | 5302 | ) orelse continue; |
| 5455 | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; | 5303 | const dep_mod = job_queue.table.get(dep_digest).?.module orelse continue; |
| ... | @@ -5461,18 +5309,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5461,18 +5309,14 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5461 | } else try createEmptyDependenciesModule( | 5309 | } else try createEmptyDependenciesModule( |
| 5462 | arena, | 5310 | arena, |
| 5463 | root_mod, | 5311 | root_mod, |
| 5464 | global_cache_directory, | 5312 | dirs, |
| 5465 | local_cache_directory, | ||
| 5466 | builtin_mod, | ||
| 5467 | config, | 5313 | config, |
| 5468 | ); | 5314 | ); |
| 5469 | 5315 | ||
| 5470 | try root_mod.deps.put(arena, "@build", build_mod); | 5316 | try root_mod.deps.put(arena, "@build", build_mod); |
| 5471 | 5317 | ||
| 5472 | const comp = Compilation.create(gpa, arena, .{ | 5318 | const comp = Compilation.create(gpa, arena, .{ |
| 5473 | .zig_lib_directory = zig_lib_directory, | 5319 | .dirs = dirs, |
| 5474 | .local_cache_directory = local_cache_directory, | ||
| 5475 | .global_cache_directory = global_cache_directory, | ||
| 5476 | .root_name = "build", | 5320 | .root_name = "build", |
| 5477 | .config = config, | 5321 | .config = config, |
| 5478 | .root_mod = root_mod, | 5322 | .root_mod = root_mod, |
| ... | @@ -5507,7 +5351,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5507,7 +5351,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5507 | // above, and thus the output file is already closed. | 5351 | // above, and thus the output file is already closed. |
| 5508 | //try comp.makeBinFileExecutable(); | 5352 | //try comp.makeBinFileExecutable(); |
| 5509 | child_argv.items[argv_index_exe] = | 5353 | child_argv.items[argv_index_exe] = |
| 5510 | try local_cache_directory.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); | 5354 | try dirs.local_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); |
| 5511 | } | 5355 | } |
| 5512 | 5356 | ||
| 5513 | if (process.can_spawn) { | 5357 | if (process.can_spawn) { |
| ... | @@ -5539,12 +5383,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -5539,12 +5383,12 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 5539 | // that are missing. | 5383 | // that are missing. |
| 5540 | const s = fs.path.sep_str; | 5384 | const s = fs.path.sep_str; |
| 5541 | const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce; | 5385 | const tmp_sub_path = "tmp" ++ s ++ results_tmp_file_nonce; |
| 5542 | const stdout = local_cache_directory.handle.readFileAlloc(arena, tmp_sub_path, 50 * 1024 * 1024) catch |err| { | 5386 | const stdout = dirs.local_cache.handle.readFileAlloc(arena, tmp_sub_path, 50 * 1024 * 1024) catch |err| { |
| 5543 | fatal("unable to read results of configure phase from '{}{s}': {s}", .{ | 5387 | fatal("unable to read results of configure phase from '{}{s}': {s}", .{ |
| 5544 | local_cache_directory, tmp_sub_path, @errorName(err), | 5388 | dirs.local_cache, tmp_sub_path, @errorName(err), |
| 5545 | }); | 5389 | }); |
| 5546 | }; | 5390 | }; |
| 5547 | local_cache_directory.handle.deleteFile(tmp_sub_path) catch {}; | 5391 | dirs.local_cache.handle.deleteFile(tmp_sub_path) catch {}; |
| 5548 | 5392 | ||
| 5549 | var it = mem.splitScalar(u8, stdout, '\n'); | 5393 | var it = mem.splitScalar(u8, stdout, '\n'); |
| 5550 | var any_errors = false; | 5394 | var any_errors = false; |
| ... | @@ -5633,7 +5477,7 @@ fn jitCmd( | ... | @@ -5633,7 +5477,7 @@ fn jitCmd( |
| 5633 | .basename = exe_basename, | 5477 | .basename = exe_basename, |
| 5634 | }; | 5478 | }; |
| 5635 | 5479 | ||
| 5636 | const self_exe_path = introspect.findZigExePath(arena) catch |err| { | 5480 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { |
| 5637 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); | 5481 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| 5638 | }; | 5482 | }; |
| 5639 | 5483 | ||
| ... | @@ -5645,24 +5489,16 @@ fn jitCmd( | ... | @@ -5645,24 +5489,16 @@ fn jitCmd( |
| 5645 | const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); | 5489 | const override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena); |
| 5646 | const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); | 5490 | const override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); |
| 5647 | 5491 | ||
| 5648 | var zig_lib_directory: Directory = if (override_lib_dir) |lib_dir| .{ | 5492 | // This `init` calls `fatal` on error. |
| 5649 | .path = lib_dir, | 5493 | var dirs: Compilation.Directories = .init( |
| 5650 | .handle = fs.cwd().openDir(lib_dir, .{}) catch |err| { | 5494 | arena, |
| 5651 | fatal("unable to open zig lib directory from 'zig-lib-dir' argument: '{s}': {s}", .{ lib_dir, @errorName(err) }); | 5495 | override_lib_dir, |
| 5652 | }, | 5496 | override_global_cache_dir, |
| 5653 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 5497 | .global, |
| 5654 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | 5498 | if (native_os == .wasi) wasi_preopens, |
| 5655 | }; | 5499 | self_exe_path, |
| 5656 | defer zig_lib_directory.handle.close(); | 5500 | ); |
| 5657 | 5501 | defer dirs.deinit(); | |
| 5658 | var global_cache_directory: Directory = l: { | ||
| 5659 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); | ||
| 5660 | break :l .{ | ||
| 5661 | .handle = try fs.cwd().makeOpenPath(p, .{}), | ||
| 5662 | .path = p, | ||
| 5663 | }; | ||
| 5664 | }; | ||
| 5665 | defer global_cache_directory.handle.close(); | ||
| 5666 | 5502 | ||
| 5667 | var thread_pool: ThreadPool = undefined; | 5503 | var thread_pool: ThreadPool = undefined; |
| 5668 | try thread_pool.init(.{ | 5504 | try thread_pool.init(.{ |
| ... | @@ -5680,10 +5516,7 @@ fn jitCmd( | ... | @@ -5680,10 +5516,7 @@ fn jitCmd( |
| 5680 | // big block here to ensure the cleanup gets run when we extract out our argv. | 5516 | // big block here to ensure the cleanup gets run when we extract out our argv. |
| 5681 | { | 5517 | { |
| 5682 | const main_mod_paths: Package.Module.CreateOptions.Paths = .{ | 5518 | const main_mod_paths: Package.Module.CreateOptions.Paths = .{ |
| 5683 | .root = .{ | 5519 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler"), |
| 5684 | .root_dir = zig_lib_directory, | ||
| 5685 | .sub_path = "compiler", | ||
| 5686 | }, | ||
| 5687 | .root_src_path = options.root_src_path, | 5520 | .root_src_path = options.root_src_path, |
| 5688 | }; | 5521 | }; |
| 5689 | 5522 | ||
| ... | @@ -5698,7 +5531,6 @@ fn jitCmd( | ... | @@ -5698,7 +5531,6 @@ fn jitCmd( |
| 5698 | }); | 5531 | }); |
| 5699 | 5532 | ||
| 5700 | const root_mod = try Package.Module.create(arena, .{ | 5533 | const root_mod = try Package.Module.create(arena, .{ |
| 5701 | .global_cache_directory = global_cache_directory, | ||
| 5702 | .paths = main_mod_paths, | 5534 | .paths = main_mod_paths, |
| 5703 | .fully_qualified_name = "root", | 5535 | .fully_qualified_name = "root", |
| 5704 | .cc_argv = &.{}, | 5536 | .cc_argv = &.{}, |
| ... | @@ -5709,18 +5541,12 @@ fn jitCmd( | ... | @@ -5709,18 +5541,12 @@ fn jitCmd( |
| 5709 | }, | 5541 | }, |
| 5710 | .global = config, | 5542 | .global = config, |
| 5711 | .parent = null, | 5543 | .parent = null, |
| 5712 | .builtin_mod = null, | ||
| 5713 | .builtin_modules = null, // all modules will inherit this one's builtin | ||
| 5714 | }); | 5544 | }); |
| 5715 | 5545 | ||
| 5716 | if (options.depend_on_aro) { | 5546 | if (options.depend_on_aro) { |
| 5717 | const aro_mod = try Package.Module.create(arena, .{ | 5547 | const aro_mod = try Package.Module.create(arena, .{ |
| 5718 | .global_cache_directory = global_cache_directory, | ||
| 5719 | .paths = .{ | 5548 | .paths = .{ |
| 5720 | .root = .{ | 5549 | .root = try .fromRoot(arena, dirs, .zig_lib, "compiler/aro"), |
| 5721 | .root_dir = zig_lib_directory, | ||
| 5722 | .sub_path = "compiler/aro", | ||
| 5723 | }, | ||
| 5724 | .root_src_path = "aro.zig", | 5550 | .root_src_path = "aro.zig", |
| 5725 | }, | 5551 | }, |
| 5726 | .fully_qualified_name = "aro", | 5552 | .fully_qualified_name = "aro", |
| ... | @@ -5732,16 +5558,12 @@ fn jitCmd( | ... | @@ -5732,16 +5558,12 @@ fn jitCmd( |
| 5732 | }, | 5558 | }, |
| 5733 | .global = config, | 5559 | .global = config, |
| 5734 | .parent = null, | 5560 | .parent = null, |
| 5735 | .builtin_mod = root_mod.getBuiltinDependency(), | ||
| 5736 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 5737 | }); | 5561 | }); |
| 5738 | try root_mod.deps.put(arena, "aro", aro_mod); | 5562 | try root_mod.deps.put(arena, "aro", aro_mod); |
| 5739 | } | 5563 | } |
| 5740 | 5564 | ||
| 5741 | const comp = Compilation.create(gpa, arena, .{ | 5565 | const comp = Compilation.create(gpa, arena, .{ |
| 5742 | .zig_lib_directory = zig_lib_directory, | 5566 | .dirs = dirs, |
| 5743 | .local_cache_directory = global_cache_directory, | ||
| 5744 | .global_cache_directory = global_cache_directory, | ||
| 5745 | .root_name = options.cmd_name, | 5567 | .root_name = options.cmd_name, |
| 5746 | .config = config, | 5568 | .config = config, |
| 5747 | .root_mod = root_mod, | 5569 | .root_mod = root_mod, |
| ... | @@ -5778,16 +5600,16 @@ fn jitCmd( | ... | @@ -5778,16 +5600,16 @@ fn jitCmd( |
| 5778 | }; | 5600 | }; |
| 5779 | } | 5601 | } |
| 5780 | 5602 | ||
| 5781 | const exe_path = try global_cache_directory.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); | 5603 | const exe_path = try dirs.global_cache.join(arena, &.{comp.cache_use.whole.bin_sub_path.?}); |
| 5782 | child_argv.appendAssumeCapacity(exe_path); | 5604 | child_argv.appendAssumeCapacity(exe_path); |
| 5783 | } | 5605 | } |
| 5784 | 5606 | ||
| 5785 | if (options.prepend_zig_lib_dir_path) | 5607 | if (options.prepend_zig_lib_dir_path) |
| 5786 | child_argv.appendAssumeCapacity(zig_lib_directory.path.?); | 5608 | child_argv.appendAssumeCapacity(dirs.zig_lib.path.?); |
| 5787 | if (options.prepend_zig_exe_path) | 5609 | if (options.prepend_zig_exe_path) |
| 5788 | child_argv.appendAssumeCapacity(self_exe_path); | 5610 | child_argv.appendAssumeCapacity(self_exe_path); |
| 5789 | if (options.prepend_global_cache_path) | 5611 | if (options.prepend_global_cache_path) |
| 5790 | child_argv.appendAssumeCapacity(global_cache_directory.path.?); | 5612 | child_argv.appendAssumeCapacity(dirs.global_cache.path.?); |
| 5791 | 5613 | ||
| 5792 | child_argv.appendSliceAssumeCapacity(args); | 5614 | child_argv.appendSliceAssumeCapacity(args); |
| 5793 | 5615 | ||
| ... | @@ -6270,7 +6092,6 @@ const usage_ast_check = | ... | @@ -6270,7 +6092,6 @@ const usage_ast_check = |
| 6270 | ; | 6092 | ; |
| 6271 | 6093 | ||
| 6272 | fn cmdAstCheck( | 6094 | fn cmdAstCheck( |
| 6273 | gpa: Allocator, | ||
| 6274 | arena: Allocator, | 6095 | arena: Allocator, |
| 6275 | args: []const []const u8, | 6096 | args: []const []const u8, |
| 6276 | ) !void { | 6097 | ) !void { |
| ... | @@ -6281,7 +6102,7 @@ fn cmdAstCheck( | ... | @@ -6281,7 +6102,7 @@ fn cmdAstCheck( |
| 6281 | var color: Color = .auto; | 6102 | var color: Color = .auto; |
| 6282 | var want_output_text = false; | 6103 | var want_output_text = false; |
| 6283 | var force_zon = false; | 6104 | var force_zon = false; |
| 6284 | var zig_source_file: ?[]const u8 = null; | 6105 | var zig_source_path: ?[]const u8 = null; |
| 6285 | 6106 | ||
| 6286 | var i: usize = 0; | 6107 | var i: usize = 0; |
| 6287 | while (i < args.len) : (i += 1) { | 6108 | while (i < args.len) : (i += 1) { |
| ... | @@ -6306,96 +6127,55 @@ fn cmdAstCheck( | ... | @@ -6306,96 +6127,55 @@ fn cmdAstCheck( |
| 6306 | } else { | 6127 | } else { |
| 6307 | fatal("unrecognized parameter: '{s}'", .{arg}); | 6128 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 6308 | } | 6129 | } |
| 6309 | } else if (zig_source_file == null) { | 6130 | } else if (zig_source_path == null) { |
| 6310 | zig_source_file = arg; | 6131 | zig_source_path = arg; |
| 6311 | } else { | 6132 | } else { |
| 6312 | fatal("extra positional parameter: '{s}'", .{arg}); | 6133 | fatal("extra positional parameter: '{s}'", .{arg}); |
| 6313 | } | 6134 | } |
| 6314 | } | 6135 | } |
| 6315 | 6136 | ||
| 6316 | var file: Zcu.File = .{ | 6137 | const display_path = zig_source_path orelse "<stdin>"; |
| 6317 | .status = .never_loaded, | 6138 | const source: [:0]const u8 = s: { |
| 6318 | .sub_file_path = undefined, | 6139 | var f = if (zig_source_path) |p| file: { |
| 6319 | .stat = undefined, | 6140 | break :file fs.cwd().openFile(p, .{}) catch |err| { |
| 6320 | .source = null, | 6141 | fatal("unable to open file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6321 | .tree = null, | 6142 | }; |
| 6322 | .zir = null, | 6143 | } else io.getStdIn(); |
| 6323 | .zoir = null, | 6144 | defer if (zig_source_path != null) f.close(); |
| 6324 | .mod = undefined, | 6145 | break :s std.zig.readSourceFileToEndAlloc(arena, f, null) catch |err| { |
| 6325 | }; | 6146 | fatal("unable to load file '{s}' for ast-check: {s}", .{ display_path, @errorName(err) }); |
| 6326 | if (zig_source_file) |file_name| { | ||
| 6327 | var f = fs.cwd().openFile(file_name, .{}) catch |err| { | ||
| 6328 | fatal("unable to open file for ast-check '{s}': {s}", .{ file_name, @errorName(err) }); | ||
| 6329 | }; | ||
| 6330 | defer f.close(); | ||
| 6331 | |||
| 6332 | const stat = try f.stat(); | ||
| 6333 | |||
| 6334 | if (stat.size > std.zig.max_src_size) | ||
| 6335 | return error.FileTooBig; | ||
| 6336 | |||
| 6337 | const source = try arena.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0); | ||
| 6338 | const amt = try f.readAll(source); | ||
| 6339 | if (amt != stat.size) | ||
| 6340 | return error.UnexpectedEndOfFile; | ||
| 6341 | |||
| 6342 | file.sub_file_path = file_name; | ||
| 6343 | file.source = source; | ||
| 6344 | file.stat = .{ | ||
| 6345 | .size = stat.size, | ||
| 6346 | .inode = stat.inode, | ||
| 6347 | .mtime = stat.mtime, | ||
| 6348 | }; | ||
| 6349 | } else { | ||
| 6350 | const stdin = io.getStdIn(); | ||
| 6351 | const source = std.zig.readSourceFileToEndAlloc(arena, stdin, null) catch |err| { | ||
| 6352 | fatal("unable to read stdin: {}", .{err}); | ||
| 6353 | }; | 6147 | }; |
| 6354 | file.sub_file_path = "<stdin>"; | 6148 | }; |
| 6355 | file.source = source; | ||
| 6356 | file.stat.size = source.len; | ||
| 6357 | } | ||
| 6358 | 6149 | ||
| 6359 | const mode: Ast.Mode = mode: { | 6150 | const mode: Ast.Mode = mode: { |
| 6360 | if (force_zon) break :mode .zon; | 6151 | if (force_zon) break :mode .zon; |
| 6361 | if (zig_source_file) |name| { | 6152 | if (zig_source_path) |path| { |
| 6362 | if (mem.endsWith(u8, name, ".zon")) { | 6153 | if (mem.endsWith(u8, path, ".zon")) { |
| 6363 | break :mode .zon; | 6154 | break :mode .zon; |
| 6364 | } | 6155 | } |
| 6365 | } | 6156 | } |
| 6366 | break :mode .zig; | 6157 | break :mode .zig; |
| 6367 | }; | 6158 | }; |
| 6368 | 6159 | ||
| 6369 | file.mod = try Package.Module.createLimited(arena, .{ | 6160 | const tree = try Ast.parse(arena, source, mode); |
| 6370 | .root = Path.cwd(), | ||
| 6371 | .root_src_path = file.sub_file_path, | ||
| 6372 | .fully_qualified_name = "root", | ||
| 6373 | }); | ||
| 6374 | |||
| 6375 | file.tree = try Ast.parse(gpa, file.source.?, mode); | ||
| 6376 | defer file.tree.?.deinit(gpa); | ||
| 6377 | 6161 | ||
| 6378 | switch (mode) { | 6162 | switch (mode) { |
| 6379 | .zig => { | 6163 | .zig => { |
| 6380 | file.zir = try AstGen.generate(gpa, file.tree.?); | 6164 | const zir = try AstGen.generate(arena, tree); |
| 6381 | defer file.zir.?.deinit(gpa); | ||
| 6382 | 6165 | ||
| 6383 | if (file.zir.?.hasCompileErrors()) { | 6166 | if (zir.hasCompileErrors()) { |
| 6384 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6167 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6385 | try wip_errors.init(gpa); | 6168 | try wip_errors.init(arena); |
| 6386 | defer wip_errors.deinit(); | 6169 | try wip_errors.addZirErrorMessages(zir, tree, source, display_path); |
| 6387 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6388 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6170 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6389 | defer error_bundle.deinit(gpa); | ||
| 6390 | error_bundle.renderToStdErr(color.renderOptions()); | 6171 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6391 | 6172 | if (zir.loweringFailed()) { | |
| 6392 | if (file.zir.?.loweringFailed()) { | ||
| 6393 | process.exit(1); | 6173 | process.exit(1); |
| 6394 | } | 6174 | } |
| 6395 | } | 6175 | } |
| 6396 | 6176 | ||
| 6397 | if (!want_output_text) { | 6177 | if (!want_output_text) { |
| 6398 | if (file.zir.?.hasCompileErrors()) { | 6178 | if (zir.hasCompileErrors()) { |
| 6399 | process.exit(1); | 6179 | process.exit(1); |
| 6400 | } else { | 6180 | } else { |
| 6401 | return cleanExit(); | 6181 | return cleanExit(); |
| ... | @@ -6407,20 +6187,20 @@ fn cmdAstCheck( | ... | @@ -6407,20 +6187,20 @@ fn cmdAstCheck( |
| 6407 | 6187 | ||
| 6408 | { | 6188 | { |
| 6409 | const token_bytes = @sizeOf(Ast.TokenList) + | 6189 | const token_bytes = @sizeOf(Ast.TokenList) + |
| 6410 | file.tree.?.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); | 6190 | tree.tokens.len * (@sizeOf(std.zig.Token.Tag) + @sizeOf(Ast.ByteOffset)); |
| 6411 | const tree_bytes = @sizeOf(Ast) + file.tree.?.nodes.len * | 6191 | const tree_bytes = @sizeOf(Ast) + tree.nodes.len * |
| 6412 | (@sizeOf(Ast.Node.Tag) + | 6192 | (@sizeOf(Ast.Node.Tag) + |
| 6413 | @sizeOf(Ast.TokenIndex) + | 6193 | @sizeOf(Ast.TokenIndex) + |
| 6414 | // Here we don't use @sizeOf(Ast.Node.Data) because it would include | 6194 | // Here we don't use @sizeOf(Ast.Node.Data) because it would include |
| 6415 | // the debug safety tag but we want to measure release size. | 6195 | // the debug safety tag but we want to measure release size. |
| 6416 | 8); | 6196 | 8); |
| 6417 | const instruction_bytes = file.zir.?.instructions.len * | 6197 | const instruction_bytes = zir.instructions.len * |
| 6418 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include | 6198 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| 6419 | // the debug safety tag but we want to measure release size. | 6199 | // the debug safety tag but we want to measure release size. |
| 6420 | (@sizeOf(Zir.Inst.Tag) + 8); | 6200 | (@sizeOf(Zir.Inst.Tag) + 8); |
| 6421 | const extra_bytes = file.zir.?.extra.len * @sizeOf(u32); | 6201 | const extra_bytes = zir.extra.len * @sizeOf(u32); |
| 6422 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + | 6202 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6423 | file.zir.?.string_bytes.len * @sizeOf(u8); | 6203 | zir.string_bytes.len * @sizeOf(u8); |
| 6424 | const stdout = io.getStdOut(); | 6204 | const stdout = io.getStdOut(); |
| 6425 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; | 6205 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; |
| 6426 | // zig fmt: off | 6206 | // zig fmt: off |
| ... | @@ -6434,44 +6214,33 @@ fn cmdAstCheck( | ... | @@ -6434,44 +6214,33 @@ fn cmdAstCheck( |
| 6434 | \\# Extra Data Items: {d} ({}) | 6214 | \\# Extra Data Items: {d} ({}) |
| 6435 | \\ | 6215 | \\ |
| 6436 | , .{ | 6216 | , .{ |
| 6437 | fmtIntSizeBin(file.source.?.len), | 6217 | fmtIntSizeBin(source.len), |
| 6438 | file.tree.?.tokens.len, fmtIntSizeBin(token_bytes), | 6218 | tree.tokens.len, fmtIntSizeBin(token_bytes), |
| 6439 | file.tree.?.nodes.len, fmtIntSizeBin(tree_bytes), | 6219 | tree.nodes.len, fmtIntSizeBin(tree_bytes), |
| 6440 | fmtIntSizeBin(total_bytes), | 6220 | fmtIntSizeBin(total_bytes), |
| 6441 | file.zir.?.instructions.len, fmtIntSizeBin(instruction_bytes), | 6221 | zir.instructions.len, fmtIntSizeBin(instruction_bytes), |
| 6442 | fmtIntSizeBin(file.zir.?.string_bytes.len), | 6222 | fmtIntSizeBin(zir.string_bytes.len), |
| 6443 | file.zir.?.extra.len, fmtIntSizeBin(extra_bytes), | 6223 | zir.extra.len, fmtIntSizeBin(extra_bytes), |
| 6444 | }); | 6224 | }); |
| 6445 | // zig fmt: on | 6225 | // zig fmt: on |
| 6446 | } | 6226 | } |
| 6447 | 6227 | ||
| 6448 | try @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut()); | 6228 | try @import("print_zir.zig").renderAsTextToFile(arena, tree, zir, io.getStdOut()); |
| 6449 | 6229 | ||
| 6450 | if (file.zir.?.hasCompileErrors()) { | 6230 | if (zir.hasCompileErrors()) { |
| 6451 | process.exit(1); | 6231 | process.exit(1); |
| 6452 | } else { | 6232 | } else { |
| 6453 | return cleanExit(); | 6233 | return cleanExit(); |
| 6454 | } | 6234 | } |
| 6455 | }, | 6235 | }, |
| 6456 | .zon => { | 6236 | .zon => { |
| 6457 | const zoir = try ZonGen.generate(gpa, file.tree.?, .{}); | 6237 | const zoir = try ZonGen.generate(arena, tree, .{}); |
| 6458 | defer zoir.deinit(gpa); | ||
| 6459 | |||
| 6460 | if (zoir.hasCompileErrors()) { | 6238 | if (zoir.hasCompileErrors()) { |
| 6461 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6239 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6462 | try wip_errors.init(gpa); | 6240 | try wip_errors.init(arena); |
| 6463 | defer wip_errors.deinit(); | 6241 | try wip_errors.addZoirErrorMessages(zoir, tree, source, display_path); |
| 6464 | |||
| 6465 | { | ||
| 6466 | const src_path = try file.fullPath(gpa); | ||
| 6467 | defer gpa.free(src_path); | ||
| 6468 | try wip_errors.addZoirErrorMessages(zoir, file.tree.?, file.source.?, src_path); | ||
| 6469 | } | ||
| 6470 | |||
| 6471 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6242 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6472 | defer error_bundle.deinit(gpa); | ||
| 6473 | error_bundle.renderToStdErr(color.renderOptions()); | 6243 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6474 | |||
| 6475 | process.exit(1); | 6244 | process.exit(1); |
| 6476 | } | 6245 | } |
| 6477 | 6246 | ||
| ... | @@ -6489,16 +6258,9 @@ fn cmdAstCheck( | ... | @@ -6489,16 +6258,9 @@ fn cmdAstCheck( |
| 6489 | } | 6258 | } |
| 6490 | } | 6259 | } |
| 6491 | 6260 | ||
| 6492 | fn cmdDetectCpu( | 6261 | fn cmdDetectCpu(args: []const []const u8) !void { |
| 6493 | gpa: Allocator, | ||
| 6494 | arena: Allocator, | ||
| 6495 | args: []const []const u8, | ||
| 6496 | ) !void { | ||
| 6497 | dev.check(.detect_cpu_command); | 6262 | dev.check(.detect_cpu_command); |
| 6498 | 6263 | ||
| 6499 | _ = gpa; | ||
| 6500 | _ = arena; | ||
| 6501 | |||
| 6502 | const detect_cpu_usage = | 6264 | const detect_cpu_usage = |
| 6503 | \\Usage: zig detect-cpu [--llvm] | 6265 | \\Usage: zig detect-cpu [--llvm] |
| 6504 | \\ | 6266 | \\ |
| ... | @@ -6676,13 +6438,11 @@ fn cmdDumpLlvmInts( | ... | @@ -6676,13 +6438,11 @@ fn cmdDumpLlvmInts( |
| 6676 | 6438 | ||
| 6677 | /// This is only enabled for debug builds. | 6439 | /// This is only enabled for debug builds. |
| 6678 | fn cmdDumpZir( | 6440 | fn cmdDumpZir( |
| 6679 | gpa: Allocator, | ||
| 6680 | arena: Allocator, | 6441 | arena: Allocator, |
| 6681 | args: []const []const u8, | 6442 | args: []const []const u8, |
| 6682 | ) !void { | 6443 | ) !void { |
| 6683 | dev.check(.dump_zir_command); | 6444 | dev.check(.dump_zir_command); |
| 6684 | 6445 | ||
| 6685 | _ = arena; | ||
| 6686 | const Zir = std.zig.Zir; | 6446 | const Zir = std.zig.Zir; |
| 6687 | 6447 | ||
| 6688 | const cache_file = args[0]; | 6448 | const cache_file = args[0]; |
| ... | @@ -6692,26 +6452,16 @@ fn cmdDumpZir( | ... | @@ -6692,26 +6452,16 @@ fn cmdDumpZir( |
| 6692 | }; | 6452 | }; |
| 6693 | defer f.close(); | 6453 | defer f.close(); |
| 6694 | 6454 | ||
| 6695 | var file: Zcu.File = .{ | 6455 | const zir = try Zcu.loadZirCache(arena, f); |
| 6696 | .status = .never_loaded, | ||
| 6697 | .sub_file_path = undefined, | ||
| 6698 | .stat = undefined, | ||
| 6699 | .source = null, | ||
| 6700 | .tree = null, | ||
| 6701 | .zir = try Zcu.loadZirCache(gpa, f), | ||
| 6702 | .zoir = null, | ||
| 6703 | .mod = undefined, | ||
| 6704 | }; | ||
| 6705 | defer file.zir.?.deinit(gpa); | ||
| 6706 | 6456 | ||
| 6707 | { | 6457 | { |
| 6708 | const instruction_bytes = file.zir.?.instructions.len * | 6458 | const instruction_bytes = zir.instructions.len * |
| 6709 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include | 6459 | // Here we don't use @sizeOf(Zir.Inst.Data) because it would include |
| 6710 | // the debug safety tag but we want to measure release size. | 6460 | // the debug safety tag but we want to measure release size. |
| 6711 | (@sizeOf(Zir.Inst.Tag) + 8); | 6461 | (@sizeOf(Zir.Inst.Tag) + 8); |
| 6712 | const extra_bytes = file.zir.?.extra.len * @sizeOf(u32); | 6462 | const extra_bytes = zir.extra.len * @sizeOf(u32); |
| 6713 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + | 6463 | const total_bytes = @sizeOf(Zir) + instruction_bytes + extra_bytes + |
| 6714 | file.zir.?.string_bytes.len * @sizeOf(u8); | 6464 | zir.string_bytes.len * @sizeOf(u8); |
| 6715 | const stdout = io.getStdOut(); | 6465 | const stdout = io.getStdOut(); |
| 6716 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; | 6466 | const fmtIntSizeBin = std.fmt.fmtIntSizeBin; |
| 6717 | // zig fmt: off | 6467 | // zig fmt: off |
| ... | @@ -6723,19 +6473,18 @@ fn cmdDumpZir( | ... | @@ -6723,19 +6473,18 @@ fn cmdDumpZir( |
| 6723 | \\ | 6473 | \\ |
| 6724 | , .{ | 6474 | , .{ |
| 6725 | fmtIntSizeBin(total_bytes), | 6475 | fmtIntSizeBin(total_bytes), |
| 6726 | file.zir.?.instructions.len, fmtIntSizeBin(instruction_bytes), | 6476 | zir.instructions.len, fmtIntSizeBin(instruction_bytes), |
| 6727 | fmtIntSizeBin(file.zir.?.string_bytes.len), | 6477 | fmtIntSizeBin(zir.string_bytes.len), |
| 6728 | file.zir.?.extra.len, fmtIntSizeBin(extra_bytes), | 6478 | zir.extra.len, fmtIntSizeBin(extra_bytes), |
| 6729 | }); | 6479 | }); |
| 6730 | // zig fmt: on | 6480 | // zig fmt: on |
| 6731 | } | 6481 | } |
| 6732 | 6482 | ||
| 6733 | return @import("print_zir.zig").renderAsTextToFile(gpa, &file, io.getStdOut()); | 6483 | return @import("print_zir.zig").renderAsTextToFile(arena, null, zir, io.getStdOut()); |
| 6734 | } | 6484 | } |
| 6735 | 6485 | ||
| 6736 | /// This is only enabled for debug builds. | 6486 | /// This is only enabled for debug builds. |
| 6737 | fn cmdChangelist( | 6487 | fn cmdChangelist( |
| 6738 | gpa: Allocator, | ||
| 6739 | arena: Allocator, | 6488 | arena: Allocator, |
| 6740 | args: []const []const u8, | 6489 | args: []const []const u8, |
| 6741 | ) !void { | 6490 | ) !void { |
| ... | @@ -6744,101 +6493,50 @@ fn cmdChangelist( | ... | @@ -6744,101 +6493,50 @@ fn cmdChangelist( |
| 6744 | const color: Color = .auto; | 6493 | const color: Color = .auto; |
| 6745 | const Zir = std.zig.Zir; | 6494 | const Zir = std.zig.Zir; |
| 6746 | 6495 | ||
| 6747 | const old_source_file = args[0]; | 6496 | const old_source_path = args[0]; |
| 6748 | const new_source_file = args[1]; | 6497 | const new_source_path = args[1]; |
| 6749 | 6498 | ||
| 6750 | var f = fs.cwd().openFile(old_source_file, .{}) catch |err| { | 6499 | const old_source = source: { |
| 6751 | fatal("unable to open old source file for comparison '{s}': {s}", .{ old_source_file, @errorName(err) }); | 6500 | var f = fs.cwd().openFile(old_source_path, .{}) catch |err| |
| 6501 | fatal("unable to open old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | ||
| 6502 | defer f.close(); | ||
| 6503 | break :source std.zig.readSourceFileToEndAlloc(arena, f, std.zig.max_src_size) catch |err| | ||
| 6504 | fatal("unable to read old source file '{s}': {s}", .{ old_source_path, @errorName(err) }); | ||
| 6752 | }; | 6505 | }; |
| 6753 | defer f.close(); | 6506 | const new_source = source: { |
| 6754 | 6507 | var f = fs.cwd().openFile(new_source_path, .{}) catch |err| | |
| 6755 | const stat = try f.stat(); | 6508 | fatal("unable to open new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6756 | 6509 | defer f.close(); | |
| 6757 | if (stat.size > std.zig.max_src_size) | 6510 | break :source std.zig.readSourceFileToEndAlloc(arena, f, std.zig.max_src_size) catch |err| |
| 6758 | return error.FileTooBig; | 6511 | fatal("unable to read new source file '{s}': {s}", .{ new_source_path, @errorName(err) }); |
| 6759 | |||
| 6760 | var file: Zcu.File = .{ | ||
| 6761 | .status = .never_loaded, | ||
| 6762 | .sub_file_path = old_source_file, | ||
| 6763 | .stat = .{ | ||
| 6764 | .size = stat.size, | ||
| 6765 | .inode = stat.inode, | ||
| 6766 | .mtime = stat.mtime, | ||
| 6767 | }, | ||
| 6768 | .source = null, | ||
| 6769 | .tree = null, | ||
| 6770 | .zir = null, | ||
| 6771 | .zoir = null, | ||
| 6772 | .mod = undefined, | ||
| 6773 | }; | 6512 | }; |
| 6774 | 6513 | ||
| 6775 | file.mod = try Package.Module.createLimited(arena, .{ | 6514 | const old_tree = try Ast.parse(arena, old_source, .zig); |
| 6776 | .root = Path.cwd(), | 6515 | const old_zir = try AstGen.generate(arena, old_tree); |
| 6777 | .root_src_path = file.sub_file_path, | ||
| 6778 | .fully_qualified_name = "root", | ||
| 6779 | }); | ||
| 6780 | |||
| 6781 | const source = try arena.allocSentinel(u8, @as(usize, @intCast(stat.size)), 0); | ||
| 6782 | const amt = try f.readAll(source); | ||
| 6783 | if (amt != stat.size) | ||
| 6784 | return error.UnexpectedEndOfFile; | ||
| 6785 | file.source = source; | ||
| 6786 | |||
| 6787 | file.tree = try Ast.parse(gpa, file.source.?, .zig); | ||
| 6788 | defer file.tree.?.deinit(gpa); | ||
| 6789 | |||
| 6790 | file.zir = try AstGen.generate(gpa, file.tree.?); | ||
| 6791 | defer file.zir.?.deinit(gpa); | ||
| 6792 | 6516 | ||
| 6793 | if (file.zir.?.loweringFailed()) { | 6517 | if (old_zir.loweringFailed()) { |
| 6794 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6518 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6795 | try wip_errors.init(gpa); | 6519 | try wip_errors.init(arena); |
| 6796 | defer wip_errors.deinit(); | 6520 | try wip_errors.addZirErrorMessages(old_zir, old_tree, old_source, old_source_path); |
| 6797 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6798 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6521 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6799 | defer error_bundle.deinit(gpa); | ||
| 6800 | error_bundle.renderToStdErr(color.renderOptions()); | 6522 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6801 | process.exit(1); | 6523 | process.exit(1); |
| 6802 | } | 6524 | } |
| 6803 | 6525 | ||
| 6804 | var new_f = fs.cwd().openFile(new_source_file, .{}) catch |err| { | 6526 | const new_tree = try Ast.parse(arena, new_source, .zig); |
| 6805 | fatal("unable to open new source file for comparison '{s}': {s}", .{ new_source_file, @errorName(err) }); | 6527 | const new_zir = try AstGen.generate(arena, new_tree); |
| 6806 | }; | ||
| 6807 | defer new_f.close(); | ||
| 6808 | |||
| 6809 | const new_stat = try new_f.stat(); | ||
| 6810 | |||
| 6811 | if (new_stat.size > std.zig.max_src_size) | ||
| 6812 | return error.FileTooBig; | ||
| 6813 | |||
| 6814 | const new_source = try arena.allocSentinel(u8, @as(usize, @intCast(new_stat.size)), 0); | ||
| 6815 | const new_amt = try new_f.readAll(new_source); | ||
| 6816 | if (new_amt != new_stat.size) | ||
| 6817 | return error.UnexpectedEndOfFile; | ||
| 6818 | 6528 | ||
| 6819 | var new_tree = try Ast.parse(gpa, new_source, .zig); | 6529 | if (new_zir.loweringFailed()) { |
| 6820 | defer new_tree.deinit(gpa); | ||
| 6821 | |||
| 6822 | var old_zir = file.zir.?; | ||
| 6823 | defer old_zir.deinit(gpa); | ||
| 6824 | file.zir = null; | ||
| 6825 | file.zir = try AstGen.generate(gpa, new_tree); | ||
| 6826 | |||
| 6827 | if (file.zir.?.loweringFailed()) { | ||
| 6828 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; | 6530 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| 6829 | try wip_errors.init(gpa); | 6531 | try wip_errors.init(arena); |
| 6830 | defer wip_errors.deinit(); | 6532 | try wip_errors.addZirErrorMessages(new_zir, new_tree, new_source, new_source_path); |
| 6831 | try Compilation.addZirErrorMessages(&wip_errors, &file); | ||
| 6832 | var error_bundle = try wip_errors.toOwnedBundle(""); | 6533 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| 6833 | defer error_bundle.deinit(gpa); | ||
| 6834 | error_bundle.renderToStdErr(color.renderOptions()); | 6534 | error_bundle.renderToStdErr(color.renderOptions()); |
| 6835 | process.exit(1); | 6535 | process.exit(1); |
| 6836 | } | 6536 | } |
| 6837 | 6537 | ||
| 6838 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; | 6538 | var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .empty; |
| 6839 | defer inst_map.deinit(gpa); | 6539 | try Zcu.mapOldZirToNew(arena, old_zir, new_zir, &inst_map); |
| 6840 | |||
| 6841 | try Zcu.mapOldZirToNew(gpa, old_zir, file.zir.?, &inst_map); | ||
| 6842 | 6540 | ||
| 6843 | var bw = io.bufferedWriter(io.getStdOut().writer()); | 6541 | var bw = io.bufferedWriter(io.getStdOut().writer()); |
| 6844 | const stdout = bw.writer(); | 6542 | const stdout = bw.writer(); |
| ... | @@ -7315,7 +7013,7 @@ fn cmdFetch( | ... | @@ -7315,7 +7013,7 @@ fn cmdFetch( |
| 7315 | }, | 7013 | }, |
| 7316 | }; | 7014 | }; |
| 7317 | 7015 | ||
| 7318 | const cwd_path = try process.getCwdAlloc(arena); | 7016 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 7319 | 7017 | ||
| 7320 | var build_root = try findBuildRoot(arena, .{ | 7018 | var build_root = try findBuildRoot(arena, .{ |
| 7321 | .cwd_path = cwd_path, | 7019 | .cwd_path = cwd_path, |
| ... | @@ -7447,9 +7145,7 @@ fn cmdFetch( | ... | @@ -7447,9 +7145,7 @@ fn cmdFetch( |
| 7447 | fn createEmptyDependenciesModule( | 7145 | fn createEmptyDependenciesModule( |
| 7448 | arena: Allocator, | 7146 | arena: Allocator, |
| 7449 | main_mod: *Package.Module, | 7147 | main_mod: *Package.Module, |
| 7450 | global_cache_directory: Cache.Directory, | 7148 | dirs: Compilation.Directories, |
| 7451 | local_cache_directory: Cache.Directory, | ||
| 7452 | builtin_mod: *Package.Module, | ||
| 7453 | global_options: Compilation.Config, | 7149 | global_options: Compilation.Config, |
| 7454 | ) !void { | 7150 | ) !void { |
| 7455 | var source = std.ArrayList(u8).init(arena); | 7151 | var source = std.ArrayList(u8).init(arena); |
| ... | @@ -7458,9 +7154,7 @@ fn createEmptyDependenciesModule( | ... | @@ -7458,9 +7154,7 @@ fn createEmptyDependenciesModule( |
| 7458 | arena, | 7154 | arena, |
| 7459 | source.items, | 7155 | source.items, |
| 7460 | main_mod, | 7156 | main_mod, |
| 7461 | global_cache_directory, | 7157 | dirs, |
| 7462 | local_cache_directory, | ||
| 7463 | builtin_mod, | ||
| 7464 | global_options, | 7158 | global_options, |
| 7465 | ); | 7159 | ); |
| 7466 | } | 7160 | } |
| ... | @@ -7471,9 +7165,7 @@ fn createDependenciesModule( | ... | @@ -7471,9 +7165,7 @@ fn createDependenciesModule( |
| 7471 | arena: Allocator, | 7165 | arena: Allocator, |
| 7472 | source: []const u8, | 7166 | source: []const u8, |
| 7473 | main_mod: *Package.Module, | 7167 | main_mod: *Package.Module, |
| 7474 | global_cache_directory: Cache.Directory, | 7168 | dirs: Compilation.Directories, |
| 7475 | local_cache_directory: Cache.Directory, | ||
| 7476 | builtin_mod: *Package.Module, | ||
| 7477 | global_options: Compilation.Config, | 7169 | global_options: Compilation.Config, |
| 7478 | ) !*Package.Module { | 7170 | ) !*Package.Module { |
| 7479 | // Atomically create the file in a directory named after the hash of its contents. | 7171 | // Atomically create the file in a directory named after the hash of its contents. |
| ... | @@ -7481,7 +7173,7 @@ fn createDependenciesModule( | ... | @@ -7481,7 +7173,7 @@ fn createDependenciesModule( |
| 7481 | const rand_int = std.crypto.random.int(u64); | 7173 | const rand_int = std.crypto.random.int(u64); |
| 7482 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); | 7174 | const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ std.fmt.hex(rand_int); |
| 7483 | { | 7175 | { |
| 7484 | var tmp_dir = try local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{}); | 7176 | var tmp_dir = try dirs.local_cache.handle.makeOpenPath(tmp_dir_sub_path, .{}); |
| 7485 | defer tmp_dir.close(); | 7177 | defer tmp_dir.close(); |
| 7486 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); | 7178 | try tmp_dir.writeFile(.{ .sub_path = basename, .data = source }); |
| 7487 | } | 7179 | } |
| ... | @@ -7493,18 +7185,14 @@ fn createDependenciesModule( | ... | @@ -7493,18 +7185,14 @@ fn createDependenciesModule( |
| 7493 | 7185 | ||
| 7494 | const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); | 7186 | const o_dir_sub_path = try arena.dupe(u8, "o" ++ fs.path.sep_str ++ hex_digest); |
| 7495 | try Package.Fetch.renameTmpIntoCache( | 7187 | try Package.Fetch.renameTmpIntoCache( |
| 7496 | local_cache_directory.handle, | 7188 | dirs.local_cache.handle, |
| 7497 | tmp_dir_sub_path, | 7189 | tmp_dir_sub_path, |
| 7498 | o_dir_sub_path, | 7190 | o_dir_sub_path, |
| 7499 | ); | 7191 | ); |
| 7500 | 7192 | ||
| 7501 | const deps_mod = try Package.Module.create(arena, .{ | 7193 | const deps_mod = try Package.Module.create(arena, .{ |
| 7502 | .global_cache_directory = global_cache_directory, | ||
| 7503 | .paths = .{ | 7194 | .paths = .{ |
| 7504 | .root = .{ | 7195 | .root = try .fromRoot(arena, dirs, .local_cache, o_dir_sub_path), |
| 7505 | .root_dir = local_cache_directory, | ||
| 7506 | .sub_path = o_dir_sub_path, | ||
| 7507 | }, | ||
| 7508 | .root_src_path = basename, | 7196 | .root_src_path = basename, |
| 7509 | }, | 7197 | }, |
| 7510 | .fully_qualified_name = "root.@dependencies", | 7198 | .fully_qualified_name = "root.@dependencies", |
| ... | @@ -7512,8 +7200,6 @@ fn createDependenciesModule( | ... | @@ -7512,8 +7200,6 @@ fn createDependenciesModule( |
| 7512 | .cc_argv = &.{}, | 7200 | .cc_argv = &.{}, |
| 7513 | .inherited = .{}, | 7201 | .inherited = .{}, |
| 7514 | .global = global_options, | 7202 | .global = global_options, |
| 7515 | .builtin_mod = builtin_mod, | ||
| 7516 | .builtin_modules = null, // `builtin_mod` is specified | ||
| 7517 | }); | 7203 | }); |
| 7518 | try main_mod.deps.put(arena, "@dependencies", deps_mod); | 7204 | try main_mod.deps.put(arena, "@dependencies", deps_mod); |
| 7519 | return deps_mod; | 7205 | return deps_mod; |
| ... | @@ -7536,7 +7222,7 @@ const FindBuildRootOptions = struct { | ... | @@ -7536,7 +7222,7 @@ const FindBuildRootOptions = struct { |
| 7536 | }; | 7222 | }; |
| 7537 | 7223 | ||
| 7538 | fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { | 7224 | fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { |
| 7539 | const cwd_path = options.cwd_path orelse try process.getCwdAlloc(arena); | 7225 | const cwd_path = options.cwd_path orelse try introspect.getResolvedCwd(arena); |
| 7540 | const build_zig_basename = if (options.build_file) |bf| | 7226 | const build_zig_basename = if (options.build_file) |bf| |
| 7541 | fs.path.basename(bf) | 7227 | fs.path.basename(bf) |
| 7542 | else | 7228 | else |
| ... | @@ -7723,10 +7409,13 @@ const Templates = struct { | ... | @@ -7723,10 +7409,13 @@ const Templates = struct { |
| 7723 | }; | 7409 | }; |
| 7724 | 7410 | ||
| 7725 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { | 7411 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { |
| 7726 | const self_exe_path = introspect.findZigExePath(arena) catch |err| { | 7412 | const cwd_path = introspect.getResolvedCwd(arena) catch |err| { |
| 7413 | fatal("unable to get cwd: {s}", .{@errorName(err)}); | ||
| 7414 | }; | ||
| 7415 | const self_exe_path = fs.selfExePathAlloc(arena) catch |err| { | ||
| 7727 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); | 7416 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| 7728 | }; | 7417 | }; |
| 7729 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 7418 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| { |
| 7730 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); | 7419 | fatal("unable to find zig installation directory '{s}': {s}", .{ self_exe_path, @errorName(err) }); |
| 7731 | }; | 7420 | }; |
| 7732 | 7421 | ||
| ... | @@ -7783,8 +7472,8 @@ fn handleModArg( | ... | @@ -7783,8 +7472,8 @@ fn handleModArg( |
| 7783 | const gop = try create_module.modules.getOrPut(arena, mod_name); | 7472 | const gop = try create_module.modules.getOrPut(arena, mod_name); |
| 7784 | 7473 | ||
| 7785 | if (gop.found_existing) { | 7474 | if (gop.found_existing) { |
| 7786 | fatal("unable to add module '{s}': already exists as '{s}'", .{ | 7475 | fatal("unable to add module '{s}': already exists as '{s}{c}{s}'", .{ |
| 7787 | mod_name, gop.value_ptr.paths.root_src_path, | 7476 | mod_name, gop.value_ptr.root_path, fs.path.sep, gop.value_ptr.root_src_path, |
| 7788 | }); | 7477 | }); |
| 7789 | } | 7478 | } |
| 7790 | 7479 | ||
| ... | @@ -7811,24 +7500,14 @@ fn handleModArg( | ... | @@ -7811,24 +7500,14 @@ fn handleModArg( |
| 7811 | if (mod_opts.error_tracing == true) | 7500 | if (mod_opts.error_tracing == true) |
| 7812 | create_module.opts.any_error_tracing = true; | 7501 | create_module.opts.any_error_tracing = true; |
| 7813 | 7502 | ||
| 7503 | const root_path: []const u8, const root_src_path: []const u8 = if (opt_root_src_orig) |path| root: { | ||
| 7504 | create_module.opts.have_zcu = true; | ||
| 7505 | break :root .{ fs.path.dirname(path) orelse ".", fs.path.basename(path) }; | ||
| 7506 | } else .{ ".", "" }; | ||
| 7507 | |||
| 7814 | gop.value_ptr.* = .{ | 7508 | gop.value_ptr.* = .{ |
| 7815 | .paths = p: { | 7509 | .root_path = root_path, |
| 7816 | if (opt_root_src_orig) |root_src_orig| { | 7510 | .root_src_path = root_src_path, |
| 7817 | create_module.opts.have_zcu = true; | ||
| 7818 | const root_src = try introspect.resolvePath(arena, root_src_orig); | ||
| 7819 | break :p .{ | ||
| 7820 | .root = .{ | ||
| 7821 | .root_dir = Cache.Directory.cwd(), | ||
| 7822 | .sub_path = fs.path.dirname(root_src) orelse "", | ||
| 7823 | }, | ||
| 7824 | .root_src_path = fs.path.basename(root_src), | ||
| 7825 | }; | ||
| 7826 | } | ||
| 7827 | break :p .{ | ||
| 7828 | .root = .{ .root_dir = Cache.Directory.cwd() }, | ||
| 7829 | .root_src_path = "", | ||
| 7830 | }; | ||
| 7831 | }, | ||
| 7832 | .cc_argv = try cc_argv.toOwnedSlice(arena), | 7511 | .cc_argv = try cc_argv.toOwnedSlice(arena), |
| 7833 | .inherited = mod_opts.*, | 7512 | .inherited = mod_opts.*, |
| 7834 | .target_arch_os_abi = target_arch_os_abi.*, | 7513 | .target_arch_os_abi = target_arch_os_abi.*, |
src/print_env.zig+4-3| ... | @@ -2,13 +2,14 @@ const std = @import("std"); | ... | @@ -2,13 +2,14 @@ const std = @import("std"); |
| 2 | const build_options = @import("build_options"); | 2 | const build_options = @import("build_options"); |
| 3 | const introspect = @import("introspect.zig"); | 3 | const introspect = @import("introspect.zig"); |
| 4 | const Allocator = std.mem.Allocator; | 4 | const Allocator = std.mem.Allocator; |
| 5 | const fatal = @import("main.zig").fatal; | 5 | const fatal = std.process.fatal; |
| 6 | 6 | ||
| 7 | pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void { | 7 | pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Writer) !void { |
| 8 | _ = args; | 8 | _ = args; |
| 9 | const self_exe_path = try introspect.findZigExePath(arena); | 9 | const cwd_path = try introspect.getResolvedCwd(arena); |
| 10 | const self_exe_path = try std.fs.selfExePathAlloc(arena); | ||
| 10 | 11 | ||
| 11 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | 12 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, cwd_path, self_exe_path) catch |err| { |
| 12 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); | 13 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); |
| 13 | }; | 14 | }; |
| 14 | defer zig_lib_directory.handle.close(); | 15 | defer zig_lib_directory.handle.close(); |
src/print_targets.zig+1-1| ... | @@ -3,13 +3,13 @@ const fs = std.fs; | ... | @@ -3,13 +3,13 @@ const fs = std.fs; |
| 3 | const io = std.io; | 3 | const io = std.io; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const meta = std.meta; | 5 | const meta = std.meta; |
| 6 | const fatal = std.process.fatal; | ||
| 6 | const Allocator = std.mem.Allocator; | 7 | const Allocator = std.mem.Allocator; |
| 7 | const Target = std.Target; | 8 | const Target = std.Target; |
| 8 | const target = @import("target.zig"); | 9 | const target = @import("target.zig"); |
| 9 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 10 | const glibc = @import("libs/glibc.zig"); | 11 | const glibc = @import("libs/glibc.zig"); |
| 11 | const introspect = @import("introspect.zig"); | 12 | const introspect = @import("introspect.zig"); |
| 12 | const fatal = @import("main.zig").fatal; | ||
| 13 | 13 | ||
| 14 | pub fn cmdTargets( | 14 | pub fn cmdTargets( |
| 15 | allocator: Allocator, | 15 | allocator: Allocator, |
src/print_zir.zig+14-13| ... | @@ -12,7 +12,8 @@ const LazySrcLoc = Zcu.LazySrcLoc; | ... | @@ -12,7 +12,8 @@ const LazySrcLoc = Zcu.LazySrcLoc; |
| 12 | /// Write human-readable, debug formatted ZIR code to a file. | 12 | /// Write human-readable, debug formatted ZIR code to a file. |
| 13 | pub fn renderAsTextToFile( | 13 | pub fn renderAsTextToFile( |
| 14 | gpa: Allocator, | 14 | gpa: Allocator, |
| 15 | scope_file: *Zcu.File, | 15 | tree: ?Ast, |
| 16 | zir: Zir, | ||
| 16 | fs_file: std.fs.File, | 17 | fs_file: std.fs.File, |
| 17 | ) !void { | 18 | ) !void { |
| 18 | var arena = std.heap.ArenaAllocator.init(gpa); | 19 | var arena = std.heap.ArenaAllocator.init(gpa); |
| ... | @@ -21,8 +22,8 @@ pub fn renderAsTextToFile( | ... | @@ -21,8 +22,8 @@ pub fn renderAsTextToFile( |
| 21 | var writer: Writer = .{ | 22 | var writer: Writer = .{ |
| 22 | .gpa = gpa, | 23 | .gpa = gpa, |
| 23 | .arena = arena.allocator(), | 24 | .arena = arena.allocator(), |
| 24 | .file = scope_file, | 25 | .tree = tree, |
| 25 | .code = scope_file.zir.?, | 26 | .code = zir, |
| 26 | .indent = 0, | 27 | .indent = 0, |
| 27 | .parent_decl_node = .root, | 28 | .parent_decl_node = .root, |
| 28 | .recurse_decls = true, | 29 | .recurse_decls = true, |
| ... | @@ -36,18 +37,18 @@ pub fn renderAsTextToFile( | ... | @@ -36,18 +37,18 @@ pub fn renderAsTextToFile( |
| 36 | try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)}); | 37 | try stream.print("%{d} ", .{@intFromEnum(main_struct_inst)}); |
| 37 | try writer.writeInstToStream(stream, main_struct_inst); | 38 | try writer.writeInstToStream(stream, main_struct_inst); |
| 38 | try stream.writeAll("\n"); | 39 | try stream.writeAll("\n"); |
| 39 | const imports_index = scope_file.zir.?.extra[@intFromEnum(Zir.ExtraIndex.imports)]; | 40 | const imports_index = zir.extra[@intFromEnum(Zir.ExtraIndex.imports)]; |
| 40 | if (imports_index != 0) { | 41 | if (imports_index != 0) { |
| 41 | try stream.writeAll("Imports:\n"); | 42 | try stream.writeAll("Imports:\n"); |
| 42 | 43 | ||
| 43 | const extra = scope_file.zir.?.extraData(Zir.Inst.Imports, imports_index); | 44 | const extra = zir.extraData(Zir.Inst.Imports, imports_index); |
| 44 | var extra_index = extra.end; | 45 | var extra_index = extra.end; |
| 45 | 46 | ||
| 46 | for (0..extra.data.imports_len) |_| { | 47 | for (0..extra.data.imports_len) |_| { |
| 47 | const item = scope_file.zir.?.extraData(Zir.Inst.Imports.Item, extra_index); | 48 | const item = zir.extraData(Zir.Inst.Imports.Item, extra_index); |
| 48 | extra_index = item.end; | 49 | extra_index = item.end; |
| 49 | 50 | ||
| 50 | const import_path = scope_file.zir.?.nullTerminatedString(item.data.name); | 51 | const import_path = zir.nullTerminatedString(item.data.name); |
| 51 | try stream.print(" @import(\"{}\") ", .{ | 52 | try stream.print(" @import(\"{}\") ", .{ |
| 52 | std.zig.fmtEscapes(import_path), | 53 | std.zig.fmtEscapes(import_path), |
| 53 | }); | 54 | }); |
| ... | @@ -74,7 +75,7 @@ pub fn renderInstructionContext( | ... | @@ -74,7 +75,7 @@ pub fn renderInstructionContext( |
| 74 | var writer: Writer = .{ | 75 | var writer: Writer = .{ |
| 75 | .gpa = gpa, | 76 | .gpa = gpa, |
| 76 | .arena = arena.allocator(), | 77 | .arena = arena.allocator(), |
| 77 | .file = scope_file, | 78 | .tree = scope_file.tree, |
| 78 | .code = scope_file.zir.?, | 79 | .code = scope_file.zir.?, |
| 79 | .indent = if (indent < 2) 2 else indent, | 80 | .indent = if (indent < 2) 2 else indent, |
| 80 | .parent_decl_node = parent_decl_node, | 81 | .parent_decl_node = parent_decl_node, |
| ... | @@ -106,7 +107,7 @@ pub fn renderSingleInstruction( | ... | @@ -106,7 +107,7 @@ pub fn renderSingleInstruction( |
| 106 | var writer: Writer = .{ | 107 | var writer: Writer = .{ |
| 107 | .gpa = gpa, | 108 | .gpa = gpa, |
| 108 | .arena = arena.allocator(), | 109 | .arena = arena.allocator(), |
| 109 | .file = scope_file, | 110 | .tree = scope_file.tree, |
| 110 | .code = scope_file.zir.?, | 111 | .code = scope_file.zir.?, |
| 111 | .indent = indent, | 112 | .indent = indent, |
| 112 | .parent_decl_node = parent_decl_node, | 113 | .parent_decl_node = parent_decl_node, |
| ... | @@ -121,7 +122,7 @@ pub fn renderSingleInstruction( | ... | @@ -121,7 +122,7 @@ pub fn renderSingleInstruction( |
| 121 | const Writer = struct { | 122 | const Writer = struct { |
| 122 | gpa: Allocator, | 123 | gpa: Allocator, |
| 123 | arena: Allocator, | 124 | arena: Allocator, |
| 124 | file: *Zcu.File, | 125 | tree: ?Ast, |
| 125 | code: Zir, | 126 | code: Zir, |
| 126 | indent: u32, | 127 | indent: u32, |
| 127 | parent_decl_node: Ast.Node.Index, | 128 | parent_decl_node: Ast.Node.Index, |
| ... | @@ -2761,7 +2762,7 @@ const Writer = struct { | ... | @@ -2761,7 +2762,7 @@ const Writer = struct { |
| 2761 | } | 2762 | } |
| 2762 | 2763 | ||
| 2763 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void { | 2764 | fn writeSrcNode(self: *Writer, stream: anytype, src_node: Ast.Node.Offset) !void { |
| 2764 | const tree = self.file.tree orelse return; | 2765 | const tree = self.tree orelse return; |
| 2765 | const abs_node = src_node.toAbsolute(self.parent_decl_node); | 2766 | const abs_node = src_node.toAbsolute(self.parent_decl_node); |
| 2766 | const src_span = tree.nodeToSpan(abs_node); | 2767 | const src_span = tree.nodeToSpan(abs_node); |
| 2767 | const start = self.line_col_cursor.find(tree.source, src_span.start); | 2768 | const start = self.line_col_cursor.find(tree.source, src_span.start); |
| ... | @@ -2773,7 +2774,7 @@ const Writer = struct { | ... | @@ -2773,7 +2774,7 @@ const Writer = struct { |
| 2773 | } | 2774 | } |
| 2774 | 2775 | ||
| 2775 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void { | 2776 | fn writeSrcTok(self: *Writer, stream: anytype, src_tok: Ast.TokenOffset) !void { |
| 2776 | const tree = self.file.tree orelse return; | 2777 | const tree = self.tree orelse return; |
| 2777 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); | 2778 | const abs_tok = src_tok.toAbsolute(tree.firstToken(self.parent_decl_node)); |
| 2778 | const span_start = tree.tokenStart(abs_tok); | 2779 | const span_start = tree.tokenStart(abs_tok); |
| 2779 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); | 2780 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(abs_tok).len)); |
| ... | @@ -2786,7 +2787,7 @@ const Writer = struct { | ... | @@ -2786,7 +2787,7 @@ const Writer = struct { |
| 2786 | } | 2787 | } |
| 2787 | 2788 | ||
| 2788 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void { | 2789 | fn writeSrcTokAbs(self: *Writer, stream: anytype, src_tok: Ast.TokenIndex) !void { |
| 2789 | const tree = self.file.tree orelse return; | 2790 | const tree = self.tree orelse return; |
| 2790 | const span_start = tree.tokenStart(src_tok); | 2791 | const span_start = tree.tokenStart(src_tok); |
| 2791 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); | 2792 | const span_end = span_start + @as(u32, @intCast(tree.tokenSlice(src_tok).len)); |
| 2792 | const start = self.line_col_cursor.find(tree.source, span_start); | 2793 | const start = self.line_col_cursor.find(tree.source, span_start); |
test/cases/compile_errors/bad_import.zig+2-3| ... | @@ -3,7 +3,6 @@ const bogus = @import( | ... | @@ -3,7 +3,6 @@ const bogus = @import( |
| 3 | ); | 3 | ); |
| 4 | 4 | ||
| 5 | // error | 5 | // error |
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | 6 | // |
| 9 | // bogus-does-not-exist.zig': FileNotFound | 7 | // bogus-does-not-exist.zig:1:1: error: unable to load 'bogus-does-not-exist.zig': FileNotFound |
| 8 | // :2:5: note: file imported here |
test/cases/compile_errors/import_of_missing_module.zig created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | const foo = @import("foo"); | ||
| 2 | comptime { | ||
| 3 | _ = foo; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // | ||
| 8 | // :1:21: error: no module named 'foo' available within module 'root' | ||
test/cases/compile_errors/import_of_missing_package.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | const foo = @import("foo"); | ||
| 2 | comptime { | ||
| 3 | _ = foo; | ||
| 4 | } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage2 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // :1:21: error: no module named 'foo' available within module root | ||
test/cases/compile_errors/import_outside_module_path.zig created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | comptime { | ||
| 2 | _ = @import("../a.zig"); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // | ||
| 7 | // :2:17: error: import of file outside module path | ||
test/cases/compile_errors/import_outside_package.zig deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | export fn a() usize { | ||
| 2 | return @import("../../above.zig").len; | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // target=native | ||
| 7 | // | ||
| 8 | // :2:20: error: import of file outside module path: '../../above.zig' | ||
test/cases/compile_errors/import_outside_package_path.zig deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | comptime { | ||
| 2 | _ = @import("../a.zig"); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:17: error: import of file outside module path: '../a.zig' | ||
test/compile_errors.zig+4-3| ... | @@ -126,9 +126,10 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { | ... | @@ -126,9 +126,10 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { |
| 126 | \\ _ = @import("foo.zig"); | 126 | \\ _ = @import("foo.zig"); |
| 127 | \\} | 127 | \\} |
| 128 | , &[_][]const u8{ | 128 | , &[_][]const u8{ |
| 129 | ":1:1: error: file exists in multiple modules", | 129 | ":1:1: error: file exists in modules 'foo' and 'root'", |
| 130 | ":1:1: note: root of module foo", | 130 | ":1:1: note: files must belong to only one module", |
| 131 | ":3:17: note: imported from module root", | 131 | ":1:1: note: file is the root of module 'foo'", |
| 132 | ":3:17: note: file is imported here by the root of module 'root'", | ||
| 132 | }); | 133 | }); |
| 133 | case.addSourceFile("foo.zig", | 134 | case.addSourceFile("foo.zig", |
| 134 | \\const dummy = 0; | 135 | \\const dummy = 0; |
test/incremental/bad_import created+35| ... | @@ -0,0 +1,35 @@ | ||
| 1 | #target=x86_64-linux-selfhosted | ||
| 2 | #target=x86_64-linux-cbe | ||
| 3 | #target=x86_64-windows-cbe | ||
| 4 | #target=wasm32-wasi-selfhosted | ||
| 5 | |||
| 6 | #update=initial version | ||
| 7 | #file=main.zig | ||
| 8 | pub fn main() !void { | ||
| 9 | _ = @import("foo.zig"); | ||
| 10 | try std.io.getStdOut().writeAll("success\n"); | ||
| 11 | } | ||
| 12 | const std = @import("std"); | ||
| 13 | #file=foo.zig | ||
| 14 | comptime { | ||
| 15 | _ = @import("bad.zig"); | ||
| 16 | } | ||
| 17 | #expect_error=bad.zig:1:1: error: unable to load 'bad.zig': FileNotFound | ||
| 18 | #expect_error=foo.zig:2:17: note: file imported here | ||
| 19 | |||
| 20 | #update=change bad import | ||
| 21 | #file=foo.zig | ||
| 22 | comptime { | ||
| 23 | _ = @import("this_is/not_real.zig"); | ||
| 24 | } | ||
| 25 | #expect_error=this_is/not_real.zig:1:1: error: unable to load 'not_real.zig': FileNotFound | ||
| 26 | #expect_error=foo.zig:2:17: note: file imported here | ||
| 27 | |||
| 28 | #update=remove import of 'foo.zig' | ||
| 29 | #file=main.zig | ||
| 30 | pub fn main() !void { | ||
| 31 | //_ = @import("foo.zig"); | ||
| 32 | try std.io.getStdOut().writeAll("success\n"); | ||
| 33 | } | ||
| 34 | const std = @import("std"); | ||
| 35 | #expect_stdout="success\n" | ||
test/incremental/change_module created+65| ... | @@ -0,0 +1,65 @@ | ||
| 1 | #target=x86_64-linux-selfhosted | ||
| 2 | #target=x86_64-linux-cbe | ||
| 3 | #target=x86_64-windows-cbe | ||
| 4 | #target=wasm32-wasi-selfhosted | ||
| 5 | #module=foo=foo.zig | ||
| 6 | |||
| 7 | #update=initial version | ||
| 8 | #file=main.zig | ||
| 9 | pub fn main() void { | ||
| 10 | _ = @import("foo"); | ||
| 11 | //_ = @import("other.zig"); | ||
| 12 | } | ||
| 13 | #file=foo.zig | ||
| 14 | comptime { | ||
| 15 | _ = @import("other.zig"); | ||
| 16 | } | ||
| 17 | #file=other.zig | ||
| 18 | fn f() void { | ||
| 19 | @compileLog(@src().module); | ||
| 20 | } | ||
| 21 | comptime { | ||
| 22 | f(); | ||
| 23 | } | ||
| 24 | #expect_error=other.zig:2:5: error: found compile log statement | ||
| 25 | #expect_compile_log=@as([:0]const u8, "foo"[0..3]) | ||
| 26 | |||
| 27 | #update=change module of other.zig | ||
| 28 | #file=main.zig | ||
| 29 | pub fn main() void { | ||
| 30 | _ = @import("foo"); | ||
| 31 | _ = @import("other.zig"); | ||
| 32 | } | ||
| 33 | #file=foo.zig | ||
| 34 | comptime { | ||
| 35 | //_ = @import("other.zig"); | ||
| 36 | } | ||
| 37 | #expect_error=other.zig:2:5: error: found compile log statement | ||
| 38 | #expect_compile_log=@as([:0]const u8, "root"[0..4]) | ||
| 39 | |||
| 40 | #update=put other.zig in both modules | ||
| 41 | #file=main.zig | ||
| 42 | pub fn main() void { | ||
| 43 | _ = @import("foo"); | ||
| 44 | _ = @import("other.zig"); | ||
| 45 | } | ||
| 46 | #file=foo.zig | ||
| 47 | comptime { | ||
| 48 | _ = @import("other.zig"); | ||
| 49 | } | ||
| 50 | #expect_error=foo.zig:1:1: error: file exists in modules 'root' and 'foo' | ||
| 51 | #expect_error=foo.zig:1:1: note: files must belong to only one module | ||
| 52 | #expect_error=main.zig:3:17: note: file is imported here by the root of module 'root' | ||
| 53 | #expect_error=foo.zig:2:17: note: file is imported here by the root of module 'foo' | ||
| 54 | |||
| 55 | #update=put other.zig in no modules | ||
| 56 | #file=main.zig | ||
| 57 | pub fn main() void { | ||
| 58 | _ = @import("foo"); | ||
| 59 | //_ = @import("other.zig"); | ||
| 60 | } | ||
| 61 | #file=foo.zig | ||
| 62 | comptime { | ||
| 63 | //_ = @import("other.zig"); | ||
| 64 | } | ||
| 65 | #expect_stdout="" | ||
test/incremental/change_zon_file+4-2| ... | @@ -20,7 +20,8 @@ pub fn main() !void { | ... | @@ -20,7 +20,8 @@ pub fn main() !void { |
| 20 | 20 | ||
| 21 | #update=delete file | 21 | #update=delete file |
| 22 | #rm_file=message.zon | 22 | #rm_file=message.zon |
| 23 | #expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound | 23 | #expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound |
| 24 | #expect_error=main.zig:2:37: note: file imported here | ||
| 24 | 25 | ||
| 25 | #update=remove reference to ZON file | 26 | #update=remove reference to ZON file |
| 26 | #file=main.zig | 27 | #file=main.zig |
| ... | @@ -29,7 +30,8 @@ const message: []const u8 = @import("message.zon"); | ... | @@ -29,7 +30,8 @@ const message: []const u8 = @import("message.zon"); |
| 29 | pub fn main() !void { | 30 | pub fn main() !void { |
| 30 | try std.io.getStdOut().writeAll("a hardcoded string\n"); | 31 | try std.io.getStdOut().writeAll("a hardcoded string\n"); |
| 31 | } | 32 | } |
| 32 | #expect_error=message.zon:1:1: error: unable to load './message.zon': FileNotFound | 33 | #expect_error=message.zon:1:1: error: unable to load 'message.zon': FileNotFound |
| 34 | #expect_error=main.zig:2:37: note: file imported here | ||
| 33 | 35 | ||
| 34 | #update=recreate ZON file | 36 | #update=recreate ZON file |
| 35 | #file=message.zon | 37 | #file=message.zon |
test/standalone/dep_recursive/test.zig-1| ... | @@ -1,5 +1,4 @@ | ... | @@ -1,5 +1,4 @@ |
| 1 | const foo = @import("foo"); | 1 | const foo = @import("foo"); |
| 2 | const shared = @import("shared"); | ||
| 3 | const assert = @import("std").debug.assert; | 2 | const assert = @import("std").debug.assert; |
| 4 | 3 | ||
| 5 | pub fn main() void { | 4 | pub fn main() void { |
tools/incr-check.zig+37-7| ... | @@ -106,7 +106,6 @@ pub fn main() !void { | ... | @@ -106,7 +106,6 @@ pub fn main() !void { |
| 106 | try child_args.appendSlice(arena, &.{ | 106 | try child_args.appendSlice(arena, &.{ |
| 107 | resolved_zig_exe, | 107 | resolved_zig_exe, |
| 108 | "build-exe", | 108 | "build-exe", |
| 109 | case.root_source_file, | ||
| 110 | "-fincremental", | 109 | "-fincremental", |
| 111 | "-fno-ubsan-rt", | 110 | "-fno-ubsan-rt", |
| 112 | "-target", | 111 | "-target", |
| ... | @@ -135,6 +134,13 @@ pub fn main() !void { | ... | @@ -135,6 +134,13 @@ pub fn main() !void { |
| 135 | if (debug_link) { | 134 | if (debug_link) { |
| 136 | try child_args.appendSlice(arena, &.{ "--debug-log", "link", "--debug-log", "link_state", "--debug-log", "link_relocs" }); | 135 | try child_args.appendSlice(arena, &.{ "--debug-log", "link", "--debug-log", "link_state", "--debug-log", "link_relocs" }); |
| 137 | } | 136 | } |
| 137 | for (case.modules) |mod| { | ||
| 138 | try child_args.appendSlice(arena, &.{ "--dep", mod.name }); | ||
| 139 | } | ||
| 140 | try child_args.append(arena, try std.fmt.allocPrint(arena, "-Mroot={s}", .{case.root_source_file})); | ||
| 141 | for (case.modules) |mod| { | ||
| 142 | try child_args.append(arena, try std.fmt.allocPrint(arena, "-M{s}={s}", .{ mod.name, mod.file })); | ||
| 143 | } | ||
| 138 | 144 | ||
| 139 | const zig_prog_node = target_prog_node.start("zig build-exe", 0); | 145 | const zig_prog_node = target_prog_node.start("zig build-exe", 0); |
| 140 | defer zig_prog_node.end(); | 146 | defer zig_prog_node.end(); |
| ... | @@ -308,9 +314,8 @@ const Eval = struct { | ... | @@ -308,9 +314,8 @@ const Eval = struct { |
| 308 | const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len]; | 314 | const digest = body[@sizeOf(EbpHdr)..][0..Cache.bin_digest_len]; |
| 309 | const result_dir = ".local-cache" ++ std.fs.path.sep_str ++ "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*); | 315 | const result_dir = ".local-cache" ++ std.fs.path.sep_str ++ "o" ++ std.fs.path.sep_str ++ Cache.binToHex(digest.*); |
| 310 | 316 | ||
| 311 | const name = std.fs.path.stem(std.fs.path.basename(eval.case.root_source_file)); | ||
| 312 | const bin_name = try std.zig.binNameAlloc(arena, .{ | 317 | const bin_name = try std.zig.binNameAlloc(arena, .{ |
| 313 | .root_name = name, | 318 | .root_name = "root", // corresponds to the module name "root" |
| 314 | .target = eval.target.resolved, | 319 | .target = eval.target.resolved, |
| 315 | .output_mode = .Exe, | 320 | .output_mode = .Exe, |
| 316 | }); | 321 | }); |
| ... | @@ -359,7 +364,7 @@ const Eval = struct { | ... | @@ -359,7 +364,7 @@ const Eval = struct { |
| 359 | error_bundle.renderToStdErr(color.renderOptions()); | 364 | error_bundle.renderToStdErr(color.renderOptions()); |
| 360 | eval.fatal("update '{s}': more errors than expected", .{update.name}); | 365 | eval.fatal("update '{s}': more errors than expected", .{update.name}); |
| 361 | } | 366 | } |
| 362 | eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx); | 367 | try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], false, err_idx); |
| 363 | expected_idx += 1; | 368 | expected_idx += 1; |
| 364 | 369 | ||
| 365 | for (error_bundle.getNotes(err_idx)) |note_idx| { | 370 | for (error_bundle.getNotes(err_idx)) |note_idx| { |
| ... | @@ -368,7 +373,7 @@ const Eval = struct { | ... | @@ -368,7 +373,7 @@ const Eval = struct { |
| 368 | error_bundle.renderToStdErr(color.renderOptions()); | 373 | error_bundle.renderToStdErr(color.renderOptions()); |
| 369 | eval.fatal("update '{s}': more error notes than expected", .{update.name}); | 374 | eval.fatal("update '{s}': more error notes than expected", .{update.name}); |
| 370 | } | 375 | } |
| 371 | eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx); | 376 | try eval.checkOneError(update, error_bundle, expected.errors[expected_idx], true, note_idx); |
| 372 | expected_idx += 1; | 377 | expected_idx += 1; |
| 373 | } | 378 | } |
| 374 | } | 379 | } |
| ... | @@ -387,13 +392,21 @@ const Eval = struct { | ... | @@ -387,13 +392,21 @@ const Eval = struct { |
| 387 | expected: Case.ExpectedError, | 392 | expected: Case.ExpectedError, |
| 388 | is_note: bool, | 393 | is_note: bool, |
| 389 | err_idx: std.zig.ErrorBundle.MessageIndex, | 394 | err_idx: std.zig.ErrorBundle.MessageIndex, |
| 390 | ) void { | 395 | ) Allocator.Error!void { |
| 391 | const err = eb.getErrorMessage(err_idx); | 396 | const err = eb.getErrorMessage(err_idx); |
| 392 | if (err.src_loc == .none) @panic("TODO error message with no source location"); | 397 | if (err.src_loc == .none) @panic("TODO error message with no source location"); |
| 393 | if (err.count != 1) @panic("TODO error message with count>1"); | 398 | if (err.count != 1) @panic("TODO error message with count>1"); |
| 394 | const msg = eb.nullTerminatedString(err.msg); | 399 | const msg = eb.nullTerminatedString(err.msg); |
| 395 | const src = eb.getSourceLocation(err.src_loc); | 400 | const src = eb.getSourceLocation(err.src_loc); |
| 396 | const filename = eb.nullTerminatedString(src.src_path); | 401 | const raw_filename = eb.nullTerminatedString(src.src_path); |
| 402 | |||
| 403 | // We need to replace backslashes for consistency between platforms. | ||
| 404 | const filename = name: { | ||
| 405 | if (std.mem.indexOfScalar(u8, raw_filename, '\\') == null) break :name raw_filename; | ||
| 406 | const copied = try eval.arena.dupe(u8, raw_filename); | ||
| 407 | std.mem.replaceScalar(u8, copied, '\\', '/'); | ||
| 408 | break :name copied; | ||
| 409 | }; | ||
| 397 | 410 | ||
| 398 | if (expected.is_note != is_note or | 411 | if (expected.is_note != is_note or |
| 399 | !std.mem.eql(u8, expected.filename, filename) or | 412 | !std.mem.eql(u8, expected.filename, filename) or |
| ... | @@ -605,6 +618,7 @@ const Case = struct { | ... | @@ -605,6 +618,7 @@ const Case = struct { |
| 605 | updates: []Update, | 618 | updates: []Update, |
| 606 | root_source_file: []const u8, | 619 | root_source_file: []const u8, |
| 607 | targets: []const Target, | 620 | targets: []const Target, |
| 621 | modules: []const Module, | ||
| 608 | 622 | ||
| 609 | const Target = struct { | 623 | const Target = struct { |
| 610 | query: []const u8, | 624 | query: []const u8, |
| ... | @@ -626,6 +640,11 @@ const Case = struct { | ... | @@ -626,6 +640,11 @@ const Case = struct { |
| 626 | }; | 640 | }; |
| 627 | }; | 641 | }; |
| 628 | 642 | ||
| 643 | const Module = struct { | ||
| 644 | name: []const u8, | ||
| 645 | file: []const u8, | ||
| 646 | }; | ||
| 647 | |||
| 629 | const Update = struct { | 648 | const Update = struct { |
| 630 | name: []const u8, | 649 | name: []const u8, |
| 631 | outcome: Outcome, | 650 | outcome: Outcome, |
| ... | @@ -660,6 +679,7 @@ const Case = struct { | ... | @@ -660,6 +679,7 @@ const Case = struct { |
| 660 | const fatal = std.process.fatal; | 679 | const fatal = std.process.fatal; |
| 661 | 680 | ||
| 662 | var targets: std.ArrayListUnmanaged(Target) = .empty; | 681 | var targets: std.ArrayListUnmanaged(Target) = .empty; |
| 682 | var modules: std.ArrayListUnmanaged(Module) = .empty; | ||
| 663 | var updates: std.ArrayListUnmanaged(Update) = .empty; | 683 | var updates: std.ArrayListUnmanaged(Update) = .empty; |
| 664 | var changes: std.ArrayListUnmanaged(FullContents) = .empty; | 684 | var changes: std.ArrayListUnmanaged(FullContents) = .empty; |
| 665 | var deletes: std.ArrayListUnmanaged([]const u8) = .empty; | 685 | var deletes: std.ArrayListUnmanaged([]const u8) = .empty; |
| ... | @@ -698,6 +718,15 @@ const Case = struct { | ... | @@ -698,6 +718,15 @@ const Case = struct { |
| 698 | .resolved = resolved, | 718 | .resolved = resolved, |
| 699 | .backend = backend, | 719 | .backend = backend, |
| 700 | }); | 720 | }); |
| 721 | } else if (std.mem.eql(u8, key, "module")) { | ||
| 722 | const split_idx = std.mem.indexOfScalar(u8, val, '=') orelse | ||
| 723 | fatal("line {d}: module does not include file", .{line_n}); | ||
| 724 | const name = val[0..split_idx]; | ||
| 725 | const file = val[split_idx + 1 ..]; | ||
| 726 | try modules.append(arena, .{ | ||
| 727 | .name = name, | ||
| 728 | .file = file, | ||
| 729 | }); | ||
| 701 | } else if (std.mem.eql(u8, key, "update")) { | 730 | } else if (std.mem.eql(u8, key, "update")) { |
| 702 | if (updates.items.len > 0) { | 731 | if (updates.items.len > 0) { |
| 703 | const last_update = &updates.items[updates.items.len - 1]; | 732 | const last_update = &updates.items[updates.items.len - 1]; |
| ... | @@ -811,6 +840,7 @@ const Case = struct { | ... | @@ -811,6 +840,7 @@ const Case = struct { |
| 811 | .updates = updates.items, | 840 | .updates = updates.items, |
| 812 | .root_source_file = root_source_file orelse fatal("missing root source file", .{}), | 841 | .root_source_file = root_source_file orelse fatal("missing root source file", .{}), |
| 813 | .targets = targets.items, // arena so no need for toOwnedSlice | 842 | .targets = targets.items, // arena so no need for toOwnedSlice |
| 843 | .modules = modules.items, | ||
| 814 | }; | 844 | }; |
| 815 | } | 845 | } |
| 816 | }; | 846 | }; |