╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Builtin.zig ──────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
53 @setEvalBranchQuota(4000); 54 try buffer.print( 55 \\const std = @import("std"); 56 \\pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable; 57 \\pub const zig_version_string = "{s}"; 58 \\pub const zig_backend = std.lang.CompilerBackend.{f}; 59 \\ 60 \\pub const output_mode: std.lang.OutputMode = .{f}; 61 \\pub const link_mode: std.lang.LinkMode = .{f}; 62 \\pub const unwind_tables: std.lang.UnwindTables = .{f}; 63 \\pub const is_test = {}; 64 \\pub const single_threaded = {}; 65 \\/// Deprecated; to be removed in 0.18.0. Use `target.abi` instead. 66 \\pub const abi: std.Target.Abi = .{f}; 67 \\/// Deprecated; to be removed in 0.18.0. Use `target.cpu` instead. 68 \\pub const cpu: std.Target.Cpu = .{{ 69 \\ .arch = .{f}, 70 \\ .model = &std.Target.{f}.cpu.{f}, 71 \\ .features = std.Target.{f}.featureSet(&.{{ 72 \\ 73 , .{ 74 build_options.version, 75 std.zig.fmtIdPU(@tagName(zig_backend)), 76 std.zig.fmtIdPU(@tagName(opts.output_mode)), 77 std.zig.fmtIdPU(@tagName(opts.link_mode)), 78 std.zig.fmtIdPU(@tagName(opts.unwind_tables)), 79 opts.is_test, 80 opts.single_threaded, 81 std.zig.fmtIdPU(@tagName(target.abi)), 82 std.zig.fmtIdPU(@tagName(target.cpu.arch)), 83 std.zig.fmtIdPU(arch_family_name), 84 std.zig.fmtIdPU(target.cpu.model.name), 85 std.zig.fmtIdPU(arch_family_name), 86 }); 87 88 for (target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| { 89 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize)); 90 const is_enabled = target.cpu.features.isEnabled(index); 91 if (is_enabled) { 92 try buffer.print(" .{f},\n", .{std.zig.fmtIdPU(feature.name)}); 93 } 94 } 95 try buffer.print( 96 \\ }}), 97 \\}}; 98 \\/// Deprecated; to be removed in 0.18.0. Use `target.os` instead. 99 \\pub const os: std.Target.Os = .{{ 100 \\ .tag = .{f}, 101 \\ .version_range = .{{ 102 , 103 .{std.zig.fmtIdPU(@tagName(target.os.tag))}, 104 ); 105 106 switch (target.os.versionRange()) { 107 .none => try buffer.appendSlice(" .none = {} },\n"), 108 .semver => |semver| try buffer.print( 109 \\ .semver = .{{ 110 \\ .min = .{{ 111 \\ .major = {}, 112 \\ .minor = {}, 113 \\ .patch = {}, 114 \\ }}, 115 \\ .max = .{{ 116 \\ .major = {}, 117 \\ .minor = {}, 118 \\ .patch = {}, 119 \\ }}, 120 \\ }}}}, 121 \\ 122 , .{ 123 semver.min.major, 124 semver.min.minor, 125 semver.min.patch, 126 127 semver.max.major, 128 semver.max.minor, 129 semver.max.patch, 130 }), 131 .linux => |linux| try buffer.print( 132 \\ .linux = .{{ 133 \\ .range = .{{ 134 \\ .min = .{{ 135 \\ .major = {}, 136 \\ .minor = {}, 137 \\ .patch = {}, 138 \\ }}, 139 \\ .max = .{{ 140 \\ .major = {}, 141 \\ .minor = {}, 142 \\ .patch = {}, 143 \\ }}, 144 \\ }}, 145 \\ .glibc = .{{ 146 \\ .major = {}, 147 \\ .minor = {}, 148 \\ .patch = {}, 149 \\ }}, 150 \\ .android = {}, 151 \\ }}}}, 152 \\ 153 , .{ 154 linux.range.min.major, 155 linux.range.min.minor, 156 linux.range.min.patch, 157 158 linux.range.max.major, 159 linux.range.max.minor, 160 linux.range.max.patch, 161 162 linux.glibc.major, 163 linux.glibc.minor, 164 linux.glibc.patch, 165 166 linux.android, 167 }), 168 .hurd => |hurd| try buffer.print( 169 \\ .hurd = .{{ 170 \\ .range = .{{ 171 \\ .min = .{{ 172 \\ .major = {}, 173 \\ .minor = {}, 174 \\ .patch = {}, 175 \\ }}, 176 \\ .max = .{{ 177 \\ .major = {}, 178 \\ .minor = {}, 179 \\ .patch = {}, 180 \\ }}, 181 \\ }}, 182 \\ .glibc = .{{ 183 \\ .major = {}, 184 \\ .minor = {}, 185 \\ .patch = {}, 186 \\ }}, 187 \\ }}}}, 188 \\ 189 , .{ 190 hurd.range.min.major, 191 hurd.range.min.minor, 192 hurd.range.min.patch, 193 194 hurd.range.max.major, 195 hurd.range.max.minor, 196 hurd.range.max.patch, 197 198 hurd.glibc.major, 199 hurd.glibc.minor, 200 hurd.glibc.patch, 201 }), 202 .windows => |windows| try buffer.print( 203 \\ .windows = .{{ 204 \\ .min = {f}, 205 \\ .max = {f}, 206 \\ }}}}, 207 \\ 208 , .{ windows.min, windows.max }), 209 } 210 try buffer.appendSlice( 211 \\}; 212 \\pub const target: std.Target = .{ 213 \\ .cpu = cpu, 214 \\ .os = os, 215 \\ .abi = abi, 216 \\ .ofmt = object_format, 217 \\ 218 ); 219 220 if (target.dynamic_linker.get()) |dl| { 221 try buffer.print( 222 \\ .dynamic_linker = .init("{s}"), 223 \\}}; 224 \\ 225 , .{dl}); 226 } else { 227 try buffer.appendSlice( 228 \\ .dynamic_linker = .none, 229 \\}; 230 \\ 231 ); 232 } 233 234 // This is so that compiler_rt and libc.zig libraries know whether they 235 // will eventually be linked with libc. They make different decisions 236 // about what to export depending on whether another libc will be linked 237 // in. For example, compiler_rt will not export the __chkstk symbol if it 238 // knows libc will provide it, and likewise c.zig will not export memcpy. 239 const link_libc = opts.link_libc; 240 241 try buffer.print( 242 \\/// Deprecated; to be removed in 0.18.0. Use `target.ofmt` instead. 243 \\pub const object_format: std.Target.ObjectFormat = .{f}; 244 \\/// Deprecated, to be removed after 0.18.0 245 \\pub const mode = optimize; 246 \\pub const optimize: std.lang.Optimize = .{f}; 247 \\pub const link_libc = {}; 248 \\pub const link_libcpp = {}; 249 \\pub const have_error_return_tracing = {}; 250 \\pub const valgrind_support = {}; 251 \\pub const sanitize_thread = {}; 252 \\pub const fuzz = {}; 253 \\pub const position_independent_code = {}; 254 \\pub const position_independent_executable = {}; 255 \\pub const strip_debug_info = {}; 256 \\pub const code_model: std.lang.CodeModel = .{f}; 257 \\pub const omit_frame_pointer = {}; 258 \\ 259 , .{ 260 std.zig.fmtIdPU(@tagName(target.ofmt)), 261 std.zig.fmtIdPU(@tagName(opts.optimize_mode)), 262 link_libc, 263 opts.link_libcpp, 264 opts.error_tracing, 265 opts.valgrind, 266 opts.sanitize_thread, 267 opts.fuzz, 268 opts.pic, 269 opts.pie, 270 opts.strip, 271 std.zig.fmtIdPU(@tagName(opts.code_model)), 272 opts.omit_frame_pointer, 273 }); 274 275 if (target.os.tag == .wasi) { 276 try buffer.print( 277 \\pub const wasi_exec_model: std.lang.WasiExecModel = .{f}; 278 \\ 279 , .{std.zig.fmtIdPU(@tagName(opts.wasi_exec_model))}); 280 } 281 282 if (opts.is_test) { 283 try buffer.appendSlice( 284 \\pub var test_functions: []const std.lang.TestFn = &.{}; // overwritten later 285 \\ 286 ); 287 } 288 } 289 290 /// This essentially takes the place of `Zcu.PerThread.updateFile`, but for 'builtin' modules. 291 /// Instead of reading the file from disk, its contents are generated in-memory. 292 pub fn populateFile(opts: @This(), gpa: Allocator, file: *File) Allocator.Error!void { 293 assert(file.is_builtin); 294 assert(file.status == .never_loaded); 295 assert(file.source == null); 296 assert(file.tree == null); 297 assert(file.zir == null); 298 299 file.source = try opts.generate(gpa); 300 301 log.debug("parsing and generating 'builtin.zig'", .{}); 302 303 file.tree = try std.zig.Ast.parse(gpa, file.source.?, .{}); 304 assert(file.tree.?.errors.len == 0); // builtin.zig must parse 305 306 file.zir = try AstGen.generate(gpa, file.tree.?); 307 assert(!file.zir.?.hasCompileErrors()); // builtin.zig must not have astgen errors 308 file.status = .success; 309 } 310 311 /// After `populateFile` succeeds, call this function to write the generated file out to disk 312 /// if necessary. This is useful for external tooling such as debuggers. 313 /// Assumes that `file.mod` is correctly set to the builtin module. 314 pub fn updateFileOnDisk(file: *File, comp: *Compilation) !void { 315 assert(file.is_builtin); 316 assert(file.status == .success); 317 assert(file.source != null); 318 319 const root_dir, const sub_path = file.path.openInfo(comp.dirs); 320 const io = comp.io; 321 322 if (root_dir.statFile(io, sub_path, .{})) |stat| { 323 if (stat.size != file.source.?.len) { 324 std.log.warn( 325 "the cached file '{f}' had the wrong size. Expected {d}, found {d}. " ++ 326 "Overwriting with correct file contents now", 327 .{ file.path.fmt(comp), file.source.?.len, stat.size }, 328 ); 329 } else { 330 file.stat = .{ 331 .size = stat.size, 332 .inode = stat.inode, 333 .mtime = stat.mtime, 334 }; 335 return; 336 } 337 } else |err| switch (err) { 338 error.FileNotFound => {}, 339 340 error.WouldBlock => unreachable, // not asking for non-blocking I/O 341 error.BadPathName => unreachable, // it's always "o/digest/builtin.zig" 342 error.NameTooLong => unreachable, // it's always "o/digest/builtin.zig" 343 344 // We don't expect the file to be a pipe, but can't mark `error.PipeBusy` as `unreachable`, 345 // because the user could always replace the file on disk. 346 else => |e| return e, 347 } 348 349 // `make_path` matters because the dir hasn't actually been created yet. 350 var af = try root_dir.createFileAtomic(io, sub_path, .{ .make_path = true, .replace = true }); 351 defer af.deinit(io); 352 try af.file.writeStreamingAll(io, file.source.?); 353 af.replace(io) catch |err| switch (err) { 354 error.AccessDenied => switch (builtin.os.tag) { 355 .windows => { 356 // Very likely happened due to another process or thread 357 // simultaneously creating the same, correct builtin.zig file. 358 // This is not a problem; ignore it. 359 }, 360 else => return err, 361 }, 362 else => return err, 363 }; 364 365 file.stat = .{ 366 .size = file.source.?.len, 367 .inode = 0, // dummy value 368 .mtime = .zero, // dummy value 369 }; 370 } 371 372 const builtin = @import("builtin"); 373 const std = @import("std"); 374 const Allocator = std.mem.Allocator; 375 const Cache = std.Build.Cache; 376 const build_options = @import("build_options"); 377 const Module = @import("Module.zig"); 378 const assert = std.debug.assert; 379 const AstGen = std.zig.AstGen; 380 const File = @import("Zcu.zig").File; 381 const Compilation = @import("Compilation.zig"); 382 const log = std.log.scoped(.builtin); 383