| author | |
| committer | |
| log | 20f3b0efff76cb3c611b72c1c1862490aef79b80 |
| tree | a7480ae1b27776576f12392a798c18c2fb293be5 |
| parent | c25742010d69e0e56f1fda99f1b986be52165e3b |
15 files changed, 1486 insertions(+), 1486 deletions(-)
CMakeLists.txt+17-17| ... | ... | @@ -434,8 +434,8 @@ find_package(Threads) |
| 434 | 434 | # CMake doesn't let us create an empty executable, so we hang on to this one separately. |
| 435 | 435 | set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp") |
| 436 | 436 | |
| 437 | # This is our shim which will be replaced by libuserland written in Zig. | |
| 438 | set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp") | |
| 437 | # This is our shim which will be replaced by libstage2 written in Zig. | |
| 438 | set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/stage2.cpp") | |
| 439 | 439 | |
| 440 | 440 | if(ZIG_ENABLE_MEM_PROFILE) |
| 441 | 441 | set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp") |
| ... | ... | @@ -599,38 +599,38 @@ set_target_properties(zig0 PROPERTIES |
| 599 | 599 | target_link_libraries(zig0 compiler) |
| 600 | 600 | |
| 601 | 601 | if(MSVC) |
| 602 | set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib") | |
| 602 | set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/stage2.lib") | |
| 603 | 603 | else() |
| 604 | set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a") | |
| 604 | set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libstage2.a") | |
| 605 | 605 | endif() |
| 606 | 606 | if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") |
| 607 | set(LIBUSERLAND_RELEASE_ARG "") | |
| 607 | set(LIBSTAGE2_RELEASE_ARG "") | |
| 608 | 608 | else() |
| 609 | set(LIBUSERLAND_RELEASE_ARG --release-fast --strip) | |
| 609 | set(LIBSTAGE2_RELEASE_ARG --release-fast --strip) | |
| 610 | 610 | endif() |
| 611 | 611 | if(WIN32) |
| 612 | set(LIBUSERLAND_WINDOWS_ARGS "-lntdll") | |
| 612 | set(LIBSTAGE2_WINDOWS_ARGS "-lntdll") | |
| 613 | 613 | else() |
| 614 | set(LIBUSERLAND_WINDOWS_ARGS "") | |
| 614 | set(LIBSTAGE2_WINDOWS_ARGS "") | |
| 615 | 615 | endif() |
| 616 | 616 | |
| 617 | set(BUILD_LIBUSERLAND_ARGS "build-lib" | |
| 617 | set(BUILD_LIBSTAGE2_ARGS "build-lib" | |
| 618 | 618 | --override-lib-dir "${CMAKE_SOURCE_DIR}/lib" |
| 619 | 619 | --cache on |
| 620 | 620 | --output-dir "${CMAKE_BINARY_DIR}" |
| 621 | ${LIBUSERLAND_RELEASE_ARG} | |
| 622 | "src-self-hosted/stage1.zig" | |
| 621 | ${LIBSTAGE2_RELEASE_ARG} | |
| 622 | "src-self-hosted/stage2.zig" | |
| 623 | 623 | --disable-gen-h |
| 624 | 624 | --bundle-compiler-rt |
| 625 | 625 | -fPIC |
| 626 | 626 | -lc |
| 627 | ${LIBUSERLAND_WINDOWS_ARGS} | |
| 627 | ${LIBSTAGE2_WINDOWS_ARGS} | |
| 628 | 628 | ) |
| 629 | 629 | |
| 630 | add_custom_target(zig_build_libuserland ALL | |
| 631 | COMMAND zig0 ${BUILD_LIBUSERLAND_ARGS} | |
| 630 | add_custom_target(zig_build_libstage2 ALL | |
| 631 | COMMAND zig0 ${BUILD_LIBSTAGE2_ARGS} | |
| 632 | 632 | DEPENDS zig0 |
| 633 | BYPRODUCTS "${LIBUSERLAND}" | |
| 633 | BYPRODUCTS "${LIBSTAGE2}" | |
| 634 | 634 | WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" |
| 635 | 635 | ) |
| 636 | 636 | add_executable(zig "${ZIG_MAIN_SRC}") |
| ... | ... | @@ -639,13 +639,13 @@ set_target_properties(zig PROPERTIES |
| 639 | 639 | COMPILE_FLAGS ${EXE_CFLAGS} |
| 640 | 640 | LINK_FLAGS ${EXE_LDFLAGS} |
| 641 | 641 | ) |
| 642 | target_link_libraries(zig compiler "${LIBUSERLAND}") | |
| 642 | target_link_libraries(zig compiler "${LIBSTAGE2}") | |
| 643 | 643 | if(MSVC) |
| 644 | 644 | target_link_libraries(zig ntdll.lib) |
| 645 | 645 | elseif(MINGW) |
| 646 | 646 | target_link_libraries(zig ntdll) |
| 647 | 647 | endif() |
| 648 | add_dependencies(zig zig_build_libuserland) | |
| 648 | add_dependencies(zig zig_build_libstage2) | |
| 649 | 649 | |
| 650 | 650 | install(TARGETS zig DESTINATION bin) |
| 651 | 651 |
cmake/install.cmake+2-2| ... | ... | @@ -19,9 +19,9 @@ if(_result) |
| 19 | 19 | message(":: ERROR: ${_result}") |
| 20 | 20 | message(":: (execute_process)") |
| 21 | 21 | |
| 22 | string(REPLACE ";" " " s_INSTALL_LIBUSERLAND_ARGS "${ZIG_INSTALL_ARGS}") | |
| 22 | string(REPLACE ";" " " s_INSTALL_LIBSTAGE2_ARGS "${ZIG_INSTALL_ARGS}") | |
| 23 | 23 | message("::") |
| 24 | message(":: argv: ${zig_EXE} ${s_INSTALL_LIBUSERLAND_ARGS}") | |
| 24 | message(":: argv: ${zig_EXE} ${s_INSTALL_LIBSTAGE2_ARGS}") | |
| 25 | 25 | |
| 26 | 26 | set(_args ${zig_EXE} ${ZIG_INSTALL_ARGS}) |
| 27 | 27 | list(LENGTH _args _len) |
src-self-hosted/stage1.zig deleted-1033| ... | ... | @@ -1,1033 +0,0 @@ |
| 1 | // This is Zig code that is used by both stage1 and stage2. | |
| 2 | // The prototypes in src/userland.h must match these definitions. | |
| 3 | ||
| 4 | const std = @import("std"); | |
| 5 | const io = std.io; | |
| 6 | const mem = std.mem; | |
| 7 | const fs = std.fs; | |
| 8 | const process = std.process; | |
| 9 | const Allocator = mem.Allocator; | |
| 10 | const ArrayList = std.ArrayList; | |
| 11 | const Buffer = std.Buffer; | |
| 12 | const Target = std.Target; | |
| 13 | const self_hosted_main = @import("main.zig"); | |
| 14 | const errmsg = @import("errmsg.zig"); | |
| 15 | const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer; | |
| 16 | const assert = std.debug.assert; | |
| 17 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; | |
| 18 | ||
| 19 | var stderr_file: fs.File = undefined; | |
| 20 | var stderr: *io.OutStream(fs.File.WriteError) = undefined; | |
| 21 | var stdout: *io.OutStream(fs.File.WriteError) = undefined; | |
| 22 | ||
| 23 | comptime { | |
| 24 | _ = @import("dep_tokenizer.zig"); | |
| 25 | } | |
| 26 | ||
| 27 | // ABI warning | |
| 28 | export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { | |
| 29 | const info_zen = @import("main.zig").info_zen; | |
| 30 | ptr.* = info_zen; | |
| 31 | len.* = info_zen.len; | |
| 32 | } | |
| 33 | ||
| 34 | // ABI warning | |
| 35 | export fn stage2_panic(ptr: [*]const u8, len: usize) void { | |
| 36 | @panic(ptr[0..len]); | |
| 37 | } | |
| 38 | ||
| 39 | // ABI warning | |
| 40 | const Error = extern enum { | |
| 41 | None, | |
| 42 | OutOfMemory, | |
| 43 | InvalidFormat, | |
| 44 | SemanticAnalyzeFail, | |
| 45 | AccessDenied, | |
| 46 | Interrupted, | |
| 47 | SystemResources, | |
| 48 | FileNotFound, | |
| 49 | FileSystem, | |
| 50 | FileTooBig, | |
| 51 | DivByZero, | |
| 52 | Overflow, | |
| 53 | PathAlreadyExists, | |
| 54 | Unexpected, | |
| 55 | ExactDivRemainder, | |
| 56 | NegativeDenominator, | |
| 57 | ShiftedOutOneBits, | |
| 58 | CCompileErrors, | |
| 59 | EndOfFile, | |
| 60 | IsDir, | |
| 61 | NotDir, | |
| 62 | UnsupportedOperatingSystem, | |
| 63 | SharingViolation, | |
| 64 | PipeBusy, | |
| 65 | PrimitiveTypeNotFound, | |
| 66 | CacheUnavailable, | |
| 67 | PathTooLong, | |
| 68 | CCompilerCannotFindFile, | |
| 69 | NoCCompilerInstalled, | |
| 70 | ReadingDepFile, | |
| 71 | InvalidDepFile, | |
| 72 | MissingArchitecture, | |
| 73 | MissingOperatingSystem, | |
| 74 | UnknownArchitecture, | |
| 75 | UnknownOperatingSystem, | |
| 76 | UnknownABI, | |
| 77 | InvalidFilename, | |
| 78 | DiskQuota, | |
| 79 | DiskSpace, | |
| 80 | UnexpectedWriteFailure, | |
| 81 | UnexpectedSeekFailure, | |
| 82 | UnexpectedFileTruncationFailure, | |
| 83 | Unimplemented, | |
| 84 | OperationAborted, | |
| 85 | BrokenPipe, | |
| 86 | NoSpaceLeft, | |
| 87 | NotLazy, | |
| 88 | IsAsync, | |
| 89 | ImportOutsidePkgPath, | |
| 90 | UnknownCpu, | |
| 91 | UnknownSubArchitecture, | |
| 92 | UnknownCpuFeature, | |
| 93 | InvalidCpuFeatures, | |
| 94 | InvalidLlvmCpuFeaturesFormat, | |
| 95 | UnknownApplicationBinaryInterface, | |
| 96 | ASTUnitFailure, | |
| 97 | BadPathName, | |
| 98 | SymLinkLoop, | |
| 99 | ProcessFdQuotaExceeded, | |
| 100 | SystemFdQuotaExceeded, | |
| 101 | NoDevice, | |
| 102 | DeviceBusy, | |
| 103 | UnableToSpawnCCompiler, | |
| 104 | CCompilerExitCode, | |
| 105 | CCompilerCrashed, | |
| 106 | CCompilerCannotFindHeaders, | |
| 107 | LibCRuntimeNotFound, | |
| 108 | LibCStdLibHeaderNotFound, | |
| 109 | LibCKernel32LibNotFound, | |
| 110 | UnsupportedArchitecture, | |
| 111 | }; | |
| 112 | ||
| 113 | const FILE = std.c.FILE; | |
| 114 | const ast = std.zig.ast; | |
| 115 | const translate_c = @import("translate_c.zig"); | |
| 116 | ||
| 117 | /// Args should have a null terminating last arg. | |
| 118 | export fn stage2_translate_c( | |
| 119 | out_ast: **ast.Tree, | |
| 120 | out_errors_ptr: *[*]translate_c.ClangErrMsg, | |
| 121 | out_errors_len: *usize, | |
| 122 | args_begin: [*]?[*]const u8, | |
| 123 | args_end: [*]?[*]const u8, | |
| 124 | resources_path: [*:0]const u8, | |
| 125 | ) Error { | |
| 126 | var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0]; | |
| 127 | out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) { | |
| 128 | error.SemanticAnalyzeFail => { | |
| 129 | out_errors_ptr.* = errors.ptr; | |
| 130 | out_errors_len.* = errors.len; | |
| 131 | return .CCompileErrors; | |
| 132 | }, | |
| 133 | error.ASTUnitFailure => return .ASTUnitFailure, | |
| 134 | error.OutOfMemory => return .OutOfMemory, | |
| 135 | }; | |
| 136 | return .None; | |
| 137 | } | |
| 138 | ||
| 139 | export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void { | |
| 140 | translate_c.freeErrors(errors_ptr[0..errors_len]); | |
| 141 | } | |
| 142 | ||
| 143 | export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { | |
| 144 | const c_out_stream = &std.io.COutStream.init(output_file).stream; | |
| 145 | _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { | |
| 146 | error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode | |
| 147 | error.SystemResources => return .SystemResources, | |
| 148 | error.OperationAborted => return .OperationAborted, | |
| 149 | error.BrokenPipe => return .BrokenPipe, | |
| 150 | error.DiskQuota => return .DiskQuota, | |
| 151 | error.FileTooBig => return .FileTooBig, | |
| 152 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 153 | error.AccessDenied => return .AccessDenied, | |
| 154 | error.OutOfMemory => return .OutOfMemory, | |
| 155 | error.Unexpected => return .Unexpected, | |
| 156 | error.InputOutput => return .FileSystem, | |
| 157 | }; | |
| 158 | return .None; | |
| 159 | } | |
| 160 | ||
| 161 | // TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377, | |
| 162 | // we use a blocking implementation. | |
| 163 | export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int { | |
| 164 | if (std.debug.runtime_safety) { | |
| 165 | fmtMain(argc, argv) catch unreachable; | |
| 166 | } else { | |
| 167 | fmtMain(argc, argv) catch |e| { | |
| 168 | std.debug.warn("{}\n", .{@errorName(e)}); | |
| 169 | return -1; | |
| 170 | }; | |
| 171 | } | |
| 172 | return 0; | |
| 173 | } | |
| 174 | ||
| 175 | fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void { | |
| 176 | const allocator = std.heap.c_allocator; | |
| 177 | var args_list = std.ArrayList([]const u8).init(allocator); | |
| 178 | const argc_usize = @intCast(usize, argc); | |
| 179 | var arg_i: usize = 0; | |
| 180 | while (arg_i < argc_usize) : (arg_i += 1) { | |
| 181 | try args_list.append(mem.toSliceConst(u8, argv[arg_i])); | |
| 182 | } | |
| 183 | ||
| 184 | stdout = &std.io.getStdOut().outStream().stream; | |
| 185 | stderr_file = std.io.getStdErr(); | |
| 186 | stderr = &stderr_file.outStream().stream; | |
| 187 | ||
| 188 | const args = args_list.toSliceConst()[2..]; | |
| 189 | ||
| 190 | var color: errmsg.Color = .Auto; | |
| 191 | var stdin_flag: bool = false; | |
| 192 | var check_flag: bool = false; | |
| 193 | var input_files = ArrayList([]const u8).init(allocator); | |
| 194 | ||
| 195 | { | |
| 196 | var i: usize = 0; | |
| 197 | while (i < args.len) : (i += 1) { | |
| 198 | const arg = args[i]; | |
| 199 | if (mem.startsWith(u8, arg, "-")) { | |
| 200 | if (mem.eql(u8, arg, "--help")) { | |
| 201 | try stdout.write(self_hosted_main.usage_fmt); | |
| 202 | process.exit(0); | |
| 203 | } else if (mem.eql(u8, arg, "--color")) { | |
| 204 | if (i + 1 >= args.len) { | |
| 205 | try stderr.write("expected [auto|on|off] after --color\n"); | |
| 206 | process.exit(1); | |
| 207 | } | |
| 208 | i += 1; | |
| 209 | const next_arg = args[i]; | |
| 210 | if (mem.eql(u8, next_arg, "auto")) { | |
| 211 | color = .Auto; | |
| 212 | } else if (mem.eql(u8, next_arg, "on")) { | |
| 213 | color = .On; | |
| 214 | } else if (mem.eql(u8, next_arg, "off")) { | |
| 215 | color = .Off; | |
| 216 | } else { | |
| 217 | try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg}); | |
| 218 | process.exit(1); | |
| 219 | } | |
| 220 | } else if (mem.eql(u8, arg, "--stdin")) { | |
| 221 | stdin_flag = true; | |
| 222 | } else if (mem.eql(u8, arg, "--check")) { | |
| 223 | check_flag = true; | |
| 224 | } else { | |
| 225 | try stderr.print("unrecognized parameter: '{}'", .{arg}); | |
| 226 | process.exit(1); | |
| 227 | } | |
| 228 | } else { | |
| 229 | try input_files.append(arg); | |
| 230 | } | |
| 231 | } | |
| 232 | } | |
| 233 | ||
| 234 | if (stdin_flag) { | |
| 235 | if (input_files.len != 0) { | |
| 236 | try stderr.write("cannot use --stdin with positional arguments\n"); | |
| 237 | process.exit(1); | |
| 238 | } | |
| 239 | ||
| 240 | const stdin_file = io.getStdIn(); | |
| 241 | var stdin = stdin_file.inStream(); | |
| 242 | ||
| 243 | const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size); | |
| 244 | defer allocator.free(source_code); | |
| 245 | ||
| 246 | const tree = std.zig.parse(allocator, source_code) catch |err| { | |
| 247 | try stderr.print("error parsing stdin: {}\n", .{err}); | |
| 248 | process.exit(1); | |
| 249 | }; | |
| 250 | defer tree.deinit(); | |
| 251 | ||
| 252 | var error_it = tree.errors.iterator(0); | |
| 253 | while (error_it.next()) |parse_error| { | |
| 254 | try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color); | |
| 255 | } | |
| 256 | if (tree.errors.len != 0) { | |
| 257 | process.exit(1); | |
| 258 | } | |
| 259 | if (check_flag) { | |
| 260 | const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree); | |
| 261 | const code = if (anything_changed) @as(u8, 1) else @as(u8, 0); | |
| 262 | process.exit(code); | |
| 263 | } | |
| 264 | ||
| 265 | _ = try std.zig.render(allocator, stdout, tree); | |
| 266 | return; | |
| 267 | } | |
| 268 | ||
| 269 | if (input_files.len == 0) { | |
| 270 | try stderr.write("expected at least one source file argument\n"); | |
| 271 | process.exit(1); | |
| 272 | } | |
| 273 | ||
| 274 | var fmt = Fmt{ | |
| 275 | .seen = Fmt.SeenMap.init(allocator), | |
| 276 | .any_error = false, | |
| 277 | .color = color, | |
| 278 | .allocator = allocator, | |
| 279 | }; | |
| 280 | ||
| 281 | for (input_files.toSliceConst()) |file_path| { | |
| 282 | try fmtPath(&fmt, file_path, check_flag); | |
| 283 | } | |
| 284 | if (fmt.any_error) { | |
| 285 | process.exit(1); | |
| 286 | } | |
| 287 | } | |
| 288 | ||
| 289 | const FmtError = error{ | |
| 290 | SystemResources, | |
| 291 | OperationAborted, | |
| 292 | IoPending, | |
| 293 | BrokenPipe, | |
| 294 | Unexpected, | |
| 295 | WouldBlock, | |
| 296 | FileClosed, | |
| 297 | DestinationAddressRequired, | |
| 298 | DiskQuota, | |
| 299 | FileTooBig, | |
| 300 | InputOutput, | |
| 301 | NoSpaceLeft, | |
| 302 | AccessDenied, | |
| 303 | OutOfMemory, | |
| 304 | RenameAcrossMountPoints, | |
| 305 | ReadOnlyFileSystem, | |
| 306 | LinkQuotaExceeded, | |
| 307 | FileBusy, | |
| 308 | } || fs.File.OpenError; | |
| 309 | ||
| 310 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | |
| 311 | if (fmt.seen.exists(file_path)) return; | |
| 312 | try fmt.seen.put(file_path); | |
| 313 | ||
| 314 | const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) { | |
| 315 | error.IsDir, error.AccessDenied => { | |
| 316 | // TODO make event based (and dir.next()) | |
| 317 | var dir = try fs.cwd().openDirList(file_path); | |
| 318 | defer dir.close(); | |
| 319 | ||
| 320 | var dir_it = dir.iterate(); | |
| 321 | ||
| 322 | while (try dir_it.next()) |entry| { | |
| 323 | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { | |
| 324 | const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); | |
| 325 | try fmtPath(fmt, full_path, check_mode); | |
| 326 | } | |
| 327 | } | |
| 328 | return; | |
| 329 | }, | |
| 330 | else => { | |
| 331 | // TODO lock stderr printing | |
| 332 | try stderr.print("unable to open '{}': {}\n", .{ file_path, err }); | |
| 333 | fmt.any_error = true; | |
| 334 | return; | |
| 335 | }, | |
| 336 | }; | |
| 337 | defer fmt.allocator.free(source_code); | |
| 338 | ||
| 339 | const tree = std.zig.parse(fmt.allocator, source_code) catch |err| { | |
| 340 | try stderr.print("error parsing file '{}': {}\n", .{ file_path, err }); | |
| 341 | fmt.any_error = true; | |
| 342 | return; | |
| 343 | }; | |
| 344 | defer tree.deinit(); | |
| 345 | ||
| 346 | var error_it = tree.errors.iterator(0); | |
| 347 | while (error_it.next()) |parse_error| { | |
| 348 | try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color); | |
| 349 | } | |
| 350 | if (tree.errors.len != 0) { | |
| 351 | fmt.any_error = true; | |
| 352 | return; | |
| 353 | } | |
| 354 | ||
| 355 | if (check_mode) { | |
| 356 | const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree); | |
| 357 | if (anything_changed) { | |
| 358 | try stderr.print("{}\n", .{file_path}); | |
| 359 | fmt.any_error = true; | |
| 360 | } | |
| 361 | } else { | |
| 362 | const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path); | |
| 363 | defer baf.destroy(); | |
| 364 | ||
| 365 | const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree); | |
| 366 | if (anything_changed) { | |
| 367 | try stderr.print("{}\n", .{file_path}); | |
| 368 | try baf.finish(); | |
| 369 | } | |
| 370 | } | |
| 371 | } | |
| 372 | ||
| 373 | const Fmt = struct { | |
| 374 | seen: SeenMap, | |
| 375 | any_error: bool, | |
| 376 | color: errmsg.Color, | |
| 377 | allocator: *mem.Allocator, | |
| 378 | ||
| 379 | const SeenMap = std.BufSet; | |
| 380 | }; | |
| 381 | ||
| 382 | fn printErrMsgToFile( | |
| 383 | allocator: *mem.Allocator, | |
| 384 | parse_error: *const ast.Error, | |
| 385 | tree: *ast.Tree, | |
| 386 | path: []const u8, | |
| 387 | file: fs.File, | |
| 388 | color: errmsg.Color, | |
| 389 | ) !void { | |
| 390 | const color_on = switch (color) { | |
| 391 | .Auto => file.isTty(), | |
| 392 | .On => true, | |
| 393 | .Off => false, | |
| 394 | }; | |
| 395 | const lok_token = parse_error.loc(); | |
| 396 | const span = errmsg.Span{ | |
| 397 | .first = lok_token, | |
| 398 | .last = lok_token, | |
| 399 | }; | |
| 400 | ||
| 401 | const first_token = tree.tokens.at(span.first); | |
| 402 | const last_token = tree.tokens.at(span.last); | |
| 403 | const start_loc = tree.tokenLocationPtr(0, first_token); | |
| 404 | const end_loc = tree.tokenLocationPtr(first_token.end, last_token); | |
| 405 | ||
| 406 | var text_buf = try std.Buffer.initSize(allocator, 0); | |
| 407 | var out_stream = &std.io.BufferOutStream.init(&text_buf).stream; | |
| 408 | try parse_error.render(&tree.tokens, out_stream); | |
| 409 | const text = text_buf.toOwnedSlice(); | |
| 410 | ||
| 411 | const stream = &file.outStream().stream; | |
| 412 | try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text }); | |
| 413 | ||
| 414 | if (!color_on) return; | |
| 415 | ||
| 416 | // Print \r and \t as one space each so that column counts line up | |
| 417 | for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| { | |
| 418 | try stream.writeByte(switch (byte) { | |
| 419 | '\r', '\t' => ' ', | |
| 420 | else => byte, | |
| 421 | }); | |
| 422 | } | |
| 423 | try stream.writeByte('\n'); | |
| 424 | try stream.writeByteNTimes(' ', start_loc.column); | |
| 425 | try stream.writeByteNTimes('~', last_token.end - first_token.start); | |
| 426 | try stream.writeByte('\n'); | |
| 427 | } | |
| 428 | ||
| 429 | export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { | |
| 430 | const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer"); | |
| 431 | t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]); | |
| 432 | return stage2_DepTokenizer{ | |
| 433 | .handle = t, | |
| 434 | }; | |
| 435 | } | |
| 436 | ||
| 437 | export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { | |
| 438 | self.handle.deinit(); | |
| 439 | } | |
| 440 | ||
| 441 | export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { | |
| 442 | const otoken = self.handle.next() catch { | |
| 443 | const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); | |
| 444 | return stage2_DepNextResult{ | |
| 445 | .type_id = .error_, | |
| 446 | .textz = textz.toSlice().ptr, | |
| 447 | }; | |
| 448 | }; | |
| 449 | const token = otoken orelse { | |
| 450 | return stage2_DepNextResult{ | |
| 451 | .type_id = .null_, | |
| 452 | .textz = undefined, | |
| 453 | }; | |
| 454 | }; | |
| 455 | const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); | |
| 456 | return stage2_DepNextResult{ | |
| 457 | .type_id = switch (token.id) { | |
| 458 | .target => .target, | |
| 459 | .prereq => .prereq, | |
| 460 | }, | |
| 461 | .textz = textz.toSlice().ptr, | |
| 462 | }; | |
| 463 | } | |
| 464 | ||
| 465 | const stage2_DepTokenizer = extern struct { | |
| 466 | handle: *DepTokenizer, | |
| 467 | }; | |
| 468 | ||
| 469 | const stage2_DepNextResult = extern struct { | |
| 470 | type_id: TypeId, | |
| 471 | ||
| 472 | // when type_id == error --> error text | |
| 473 | // when type_id == null --> undefined | |
| 474 | // when type_id == target --> target pathname | |
| 475 | // when type_id == prereq --> prereq pathname | |
| 476 | textz: [*]const u8, | |
| 477 | ||
| 478 | const TypeId = extern enum { | |
| 479 | error_, | |
| 480 | null_, | |
| 481 | target, | |
| 482 | prereq, | |
| 483 | }; | |
| 484 | }; | |
| 485 | ||
| 486 | // ABI warning | |
| 487 | export fn stage2_attach_segfault_handler() void { | |
| 488 | if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) { | |
| 489 | std.debug.attachSegfaultHandler(); | |
| 490 | } | |
| 491 | } | |
| 492 | ||
| 493 | // ABI warning | |
| 494 | export fn stage2_progress_create() *std.Progress { | |
| 495 | const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); | |
| 496 | ptr.* = std.Progress{}; | |
| 497 | return ptr; | |
| 498 | } | |
| 499 | ||
| 500 | // ABI warning | |
| 501 | export fn stage2_progress_destroy(progress: *std.Progress) void { | |
| 502 | std.heap.c_allocator.destroy(progress); | |
| 503 | } | |
| 504 | ||
| 505 | // ABI warning | |
| 506 | export fn stage2_progress_start_root( | |
| 507 | progress: *std.Progress, | |
| 508 | name_ptr: [*]const u8, | |
| 509 | name_len: usize, | |
| 510 | estimated_total_items: usize, | |
| 511 | ) *std.Progress.Node { | |
| 512 | return progress.start( | |
| 513 | name_ptr[0..name_len], | |
| 514 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 515 | ) catch @panic("timer unsupported"); | |
| 516 | } | |
| 517 | ||
| 518 | // ABI warning | |
| 519 | export fn stage2_progress_disable_tty(progress: *std.Progress) void { | |
| 520 | progress.terminal = null; | |
| 521 | } | |
| 522 | ||
| 523 | // ABI warning | |
| 524 | export fn stage2_progress_start( | |
| 525 | node: *std.Progress.Node, | |
| 526 | name_ptr: [*]const u8, | |
| 527 | name_len: usize, | |
| 528 | estimated_total_items: usize, | |
| 529 | ) *std.Progress.Node { | |
| 530 | const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); | |
| 531 | child_node.* = node.start( | |
| 532 | name_ptr[0..name_len], | |
| 533 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 534 | ); | |
| 535 | child_node.activate(); | |
| 536 | return child_node; | |
| 537 | } | |
| 538 | ||
| 539 | // ABI warning | |
| 540 | export fn stage2_progress_end(node: *std.Progress.Node) void { | |
| 541 | node.end(); | |
| 542 | if (&node.context.root != node) { | |
| 543 | std.heap.c_allocator.destroy(node); | |
| 544 | } | |
| 545 | } | |
| 546 | ||
| 547 | // ABI warning | |
| 548 | export fn stage2_progress_complete_one(node: *std.Progress.Node) void { | |
| 549 | node.completeOne(); | |
| 550 | } | |
| 551 | ||
| 552 | // ABI warning | |
| 553 | export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void { | |
| 554 | node.completed_items = done_count; | |
| 555 | node.estimated_total_items = total_count; | |
| 556 | node.activate(); | |
| 557 | node.context.maybeRefresh(); | |
| 558 | } | |
| 559 | ||
| 560 | fn cpuFeaturesFromLLVM( | |
| 561 | arch: Target.Arch, | |
| 562 | llvm_cpu_name_z: ?[*:0]const u8, | |
| 563 | llvm_cpu_features_opt: ?[*:0]const u8, | |
| 564 | ) !Target.CpuFeatures { | |
| 565 | var result = arch.getBaselineCpuFeatures(); | |
| 566 | ||
| 567 | if (llvm_cpu_name_z) |cpu_name_z| { | |
| 568 | const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z); | |
| 569 | ||
| 570 | for (arch.allCpus()) |cpu| { | |
| 571 | const this_llvm_name = cpu.llvm_name orelse continue; | |
| 572 | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { | |
| 573 | // Here we use the non-dependencies-populated set, | |
| 574 | // so that subtracting features later in this function | |
| 575 | // affect the prepopulated set. | |
| 576 | result = Target.CpuFeatures{ | |
| 577 | .cpu = cpu, | |
| 578 | .features = cpu.features, | |
| 579 | }; | |
| 580 | break; | |
| 581 | } | |
| 582 | } | |
| 583 | } | |
| 584 | ||
| 585 | const all_features = arch.allFeaturesList(); | |
| 586 | ||
| 587 | if (llvm_cpu_features_opt) |llvm_cpu_features| { | |
| 588 | var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ","); | |
| 589 | while (it.next()) |decorated_llvm_feat| { | |
| 590 | var op: enum { | |
| 591 | add, | |
| 592 | sub, | |
| 593 | } = undefined; | |
| 594 | var llvm_feat: []const u8 = undefined; | |
| 595 | if (mem.startsWith(u8, decorated_llvm_feat, "+")) { | |
| 596 | op = .add; | |
| 597 | llvm_feat = decorated_llvm_feat[1..]; | |
| 598 | } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { | |
| 599 | op = .sub; | |
| 600 | llvm_feat = decorated_llvm_feat[1..]; | |
| 601 | } else { | |
| 602 | return error.InvalidLlvmCpuFeaturesFormat; | |
| 603 | } | |
| 604 | for (all_features) |feature, index_usize| { | |
| 605 | const this_llvm_name = feature.llvm_name orelse continue; | |
| 606 | if (mem.eql(u8, llvm_feat, this_llvm_name)) { | |
| 607 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | |
| 608 | switch (op) { | |
| 609 | .add => result.features.addFeature(index), | |
| 610 | .sub => result.features.removeFeature(index), | |
| 611 | } | |
| 612 | break; | |
| 613 | } | |
| 614 | } | |
| 615 | } | |
| 616 | } | |
| 617 | ||
| 618 | result.features.populateDependencies(all_features); | |
| 619 | return result; | |
| 620 | } | |
| 621 | ||
| 622 | // ABI warning | |
| 623 | export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int { | |
| 624 | cmdTargets(zig_triple) catch |err| { | |
| 625 | std.debug.warn("unable to list targets: {}\n", .{@errorName(err)}); | |
| 626 | return -1; | |
| 627 | }; | |
| 628 | return 0; | |
| 629 | } | |
| 630 | ||
| 631 | fn cmdTargets(zig_triple: [*:0]const u8) !void { | |
| 632 | var target = try Target.parse(mem.toSliceConst(u8, zig_triple)); | |
| 633 | target.Cross.cpu_features = blk: { | |
| 634 | const llvm = @import("llvm.zig"); | |
| 635 | const llvm_cpu_name = llvm.GetHostCPUName(); | |
| 636 | const llvm_cpu_features = llvm.GetNativeFeatures(); | |
| 637 | break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features); | |
| 638 | }; | |
| 639 | return @import("print_targets.zig").cmdTargets( | |
| 640 | std.heap.c_allocator, | |
| 641 | &[0][]u8{}, | |
| 642 | &std.io.getStdOut().outStream().stream, | |
| 643 | target, | |
| 644 | ); | |
| 645 | } | |
| 646 | ||
| 647 | const Stage2CpuFeatures = struct { | |
| 648 | allocator: *mem.Allocator, | |
| 649 | cpu_features: Target.CpuFeatures, | |
| 650 | ||
| 651 | llvm_features_str: ?[*:0]const u8, | |
| 652 | ||
| 653 | builtin_str: [:0]const u8, | |
| 654 | cache_hash: [:0]const u8, | |
| 655 | ||
| 656 | const Self = @This(); | |
| 657 | ||
| 658 | fn createFromNative(allocator: *mem.Allocator) !*Self { | |
| 659 | const arch = Target.current.getArch(); | |
| 660 | const llvm = @import("llvm.zig"); | |
| 661 | const llvm_cpu_name = llvm.GetHostCPUName(); | |
| 662 | const llvm_cpu_features = llvm.GetNativeFeatures(); | |
| 663 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name, llvm_cpu_features); | |
| 664 | return createFromCpuFeatures(allocator, arch, cpu_features); | |
| 665 | } | |
| 666 | ||
| 667 | fn createFromCpuFeatures( | |
| 668 | allocator: *mem.Allocator, | |
| 669 | arch: Target.Arch, | |
| 670 | cpu_features: Target.CpuFeatures, | |
| 671 | ) !*Self { | |
| 672 | const self = try allocator.create(Self); | |
| 673 | errdefer allocator.destroy(self); | |
| 674 | ||
| 675 | const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{ | |
| 676 | cpu_features.cpu.name, | |
| 677 | cpu_features.features.asBytes(), | |
| 678 | }); | |
| 679 | errdefer allocator.free(cache_hash); | |
| 680 | ||
| 681 | const generic_arch_name = arch.genericName(); | |
| 682 | var builtin_str_buffer = try std.Buffer.allocPrint(allocator, | |
| 683 | \\CpuFeatures{{ | |
| 684 | \\ .cpu = &Target.{}.cpu.{}, | |
| 685 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ | |
| 686 | \\ | |
| 687 | , .{ | |
| 688 | generic_arch_name, | |
| 689 | cpu_features.cpu.name, | |
| 690 | generic_arch_name, | |
| 691 | generic_arch_name, | |
| 692 | }); | |
| 693 | defer builtin_str_buffer.deinit(); | |
| 694 | ||
| 695 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | |
| 696 | defer llvm_features_buffer.deinit(); | |
| 697 | ||
| 698 | for (arch.allFeaturesList()) |feature, index_usize| { | |
| 699 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | |
| 700 | const is_enabled = cpu_features.features.isEnabled(index); | |
| 701 | ||
| 702 | if (feature.llvm_name) |llvm_name| { | |
| 703 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | |
| 704 | try llvm_features_buffer.appendByte(plus_or_minus); | |
| 705 | try llvm_features_buffer.append(llvm_name); | |
| 706 | try llvm_features_buffer.append(","); | |
| 707 | } | |
| 708 | ||
| 709 | if (is_enabled) { | |
| 710 | // TODO some kind of "zig identifier escape" function rather than | |
| 711 | // unconditionally using @"" syntax | |
| 712 | try builtin_str_buffer.append(" .@\""); | |
| 713 | try builtin_str_buffer.append(feature.name); | |
| 714 | try builtin_str_buffer.append("\",\n"); | |
| 715 | } | |
| 716 | } | |
| 717 | ||
| 718 | try builtin_str_buffer.append( | |
| 719 | \\ }), | |
| 720 | \\}; | |
| 721 | \\ | |
| 722 | ); | |
| 723 | ||
| 724 | assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")); | |
| 725 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | |
| 726 | ||
| 727 | self.* = Self{ | |
| 728 | .allocator = allocator, | |
| 729 | .cpu_features = cpu_features, | |
| 730 | .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr, | |
| 731 | .builtin_str = builtin_str_buffer.toOwnedSlice(), | |
| 732 | .cache_hash = cache_hash, | |
| 733 | }; | |
| 734 | return self; | |
| 735 | } | |
| 736 | ||
| 737 | fn destroy(self: *Self) void { | |
| 738 | self.allocator.free(self.cache_hash); | |
| 739 | self.allocator.free(self.builtin_str); | |
| 740 | // TODO if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str); | |
| 741 | self.allocator.destroy(self); | |
| 742 | } | |
| 743 | }; | |
| 744 | ||
| 745 | // ABI warning | |
| 746 | export fn stage2_cpu_features_parse( | |
| 747 | result: **Stage2CpuFeatures, | |
| 748 | zig_triple: ?[*:0]const u8, | |
| 749 | cpu_name: ?[*:0]const u8, | |
| 750 | cpu_features: ?[*:0]const u8, | |
| 751 | ) Error { | |
| 752 | result.* = stage2ParseCpuFeatures(zig_triple, cpu_name, cpu_features) catch |err| switch (err) { | |
| 753 | error.OutOfMemory => return .OutOfMemory, | |
| 754 | error.UnknownArchitecture => return .UnknownArchitecture, | |
| 755 | error.UnknownSubArchitecture => return .UnknownSubArchitecture, | |
| 756 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, | |
| 757 | error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, | |
| 758 | error.MissingOperatingSystem => return .MissingOperatingSystem, | |
| 759 | error.MissingArchitecture => return .MissingArchitecture, | |
| 760 | error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat, | |
| 761 | error.InvalidCpuFeatures => return .InvalidCpuFeatures, | |
| 762 | }; | |
| 763 | return .None; | |
| 764 | } | |
| 765 | ||
| 766 | fn stage2ParseCpuFeatures( | |
| 767 | zig_triple_oz: ?[*:0]const u8, | |
| 768 | cpu_name_oz: ?[*:0]const u8, | |
| 769 | cpu_features_oz: ?[*:0]const u8, | |
| 770 | ) !*Stage2CpuFeatures { | |
| 771 | const zig_triple_z = zig_triple_oz orelse return Stage2CpuFeatures.createFromNative(std.heap.c_allocator); | |
| 772 | const target = try Target.parse(mem.toSliceConst(u8, zig_triple_z)); | |
| 773 | const arch = target.Cross.arch; | |
| 774 | ||
| 775 | const cpu = if (cpu_name_oz) |cpu_name_z| blk: { | |
| 776 | const cpu_name = mem.toSliceConst(u8, cpu_name_z); | |
| 777 | break :blk arch.parseCpu(cpu_name) catch |err| switch (err) { | |
| 778 | error.UnknownCpu => { | |
| 779 | std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ | |
| 780 | cpu_name, | |
| 781 | @tagName(arch), | |
| 782 | }); | |
| 783 | for (arch.allCpus()) |cpu| { | |
| 784 | std.debug.warn(" {}\n", .{cpu.name}); | |
| 785 | } | |
| 786 | process.exit(1); | |
| 787 | }, | |
| 788 | else => |e| return e, | |
| 789 | }; | |
| 790 | } else target.Cross.cpu_features.cpu; | |
| 791 | ||
| 792 | var set = if (cpu_features_oz) |cpu_features_z| blk: { | |
| 793 | const cpu_features = mem.toSliceConst(u8, cpu_features_z); | |
| 794 | break :blk arch.parseCpuFeatureSet(cpu, cpu_features) catch |err| switch (err) { | |
| 795 | error.UnknownCpuFeature => { | |
| 796 | std.debug.warn( | |
| 797 | \\Unknown CPU features specified. | |
| 798 | \\Available CPU features for architecture '{}': | |
| 799 | \\ | |
| 800 | , .{@tagName(arch)}); | |
| 801 | for (arch.allFeaturesList()) |feature| { | |
| 802 | std.debug.warn(" {}\n", .{feature.name}); | |
| 803 | } | |
| 804 | process.exit(1); | |
| 805 | }, | |
| 806 | else => |e| return e, | |
| 807 | }; | |
| 808 | } else cpu.features; | |
| 809 | ||
| 810 | if (arch.subArchFeature()) |index| { | |
| 811 | set.addFeature(index); | |
| 812 | } | |
| 813 | set.populateDependencies(arch.allFeaturesList()); | |
| 814 | ||
| 815 | return Stage2CpuFeatures.createFromCpuFeatures(std.heap.c_allocator, arch, .{ | |
| 816 | .cpu = cpu, | |
| 817 | .features = set, | |
| 818 | }); | |
| 819 | } | |
| 820 | ||
| 821 | // ABI warning | |
| 822 | export fn stage2_cpu_features_get_cache_hash( | |
| 823 | cpu_features: *const Stage2CpuFeatures, | |
| 824 | ptr: *[*:0]const u8, | |
| 825 | len: *usize, | |
| 826 | ) void { | |
| 827 | ptr.* = cpu_features.cache_hash.ptr; | |
| 828 | len.* = cpu_features.cache_hash.len; | |
| 829 | } | |
| 830 | ||
| 831 | // ABI warning | |
| 832 | export fn stage2_cpu_features_get_builtin_str( | |
| 833 | cpu_features: *const Stage2CpuFeatures, | |
| 834 | ptr: *[*:0]const u8, | |
| 835 | len: *usize, | |
| 836 | ) void { | |
| 837 | ptr.* = cpu_features.builtin_str.ptr; | |
| 838 | len.* = cpu_features.builtin_str.len; | |
| 839 | } | |
| 840 | ||
| 841 | // ABI warning | |
| 842 | export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 { | |
| 843 | return if (cpu_features.cpu_features.cpu.llvm_name) |s| s.ptr else null; | |
| 844 | } | |
| 845 | ||
| 846 | // ABI warning | |
| 847 | export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 { | |
| 848 | return cpu_features.llvm_features_str; | |
| 849 | } | |
| 850 | ||
| 851 | // ABI warning | |
| 852 | const Stage2LibCInstallation = extern struct { | |
| 853 | include_dir: [*:0]const u8, | |
| 854 | include_dir_len: usize, | |
| 855 | sys_include_dir: [*:0]const u8, | |
| 856 | sys_include_dir_len: usize, | |
| 857 | crt_dir: [*:0]const u8, | |
| 858 | crt_dir_len: usize, | |
| 859 | static_crt_dir: [*:0]const u8, | |
| 860 | static_crt_dir_len: usize, | |
| 861 | msvc_lib_dir: [*:0]const u8, | |
| 862 | msvc_lib_dir_len: usize, | |
| 863 | kernel32_lib_dir: [*:0]const u8, | |
| 864 | kernel32_lib_dir_len: usize, | |
| 865 | ||
| 866 | fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void { | |
| 867 | if (libc.include_dir) |s| { | |
| 868 | self.include_dir = s.ptr; | |
| 869 | self.include_dir_len = s.len; | |
| 870 | } else { | |
| 871 | self.include_dir = ""; | |
| 872 | self.include_dir_len = 0; | |
| 873 | } | |
| 874 | if (libc.sys_include_dir) |s| { | |
| 875 | self.sys_include_dir = s.ptr; | |
| 876 | self.sys_include_dir_len = s.len; | |
| 877 | } else { | |
| 878 | self.sys_include_dir = ""; | |
| 879 | self.sys_include_dir_len = 0; | |
| 880 | } | |
| 881 | if (libc.crt_dir) |s| { | |
| 882 | self.crt_dir = s.ptr; | |
| 883 | self.crt_dir_len = s.len; | |
| 884 | } else { | |
| 885 | self.crt_dir = ""; | |
| 886 | self.crt_dir_len = 0; | |
| 887 | } | |
| 888 | if (libc.static_crt_dir) |s| { | |
| 889 | self.static_crt_dir = s.ptr; | |
| 890 | self.static_crt_dir_len = s.len; | |
| 891 | } else { | |
| 892 | self.static_crt_dir = ""; | |
| 893 | self.static_crt_dir_len = 0; | |
| 894 | } | |
| 895 | if (libc.msvc_lib_dir) |s| { | |
| 896 | self.msvc_lib_dir = s.ptr; | |
| 897 | self.msvc_lib_dir_len = s.len; | |
| 898 | } else { | |
| 899 | self.msvc_lib_dir = ""; | |
| 900 | self.msvc_lib_dir_len = 0; | |
| 901 | } | |
| 902 | if (libc.kernel32_lib_dir) |s| { | |
| 903 | self.kernel32_lib_dir = s.ptr; | |
| 904 | self.kernel32_lib_dir_len = s.len; | |
| 905 | } else { | |
| 906 | self.kernel32_lib_dir = ""; | |
| 907 | self.kernel32_lib_dir_len = 0; | |
| 908 | } | |
| 909 | } | |
| 910 | ||
| 911 | fn toStage2(self: Stage2LibCInstallation) LibCInstallation { | |
| 912 | var libc: LibCInstallation = .{}; | |
| 913 | if (self.include_dir_len != 0) { | |
| 914 | libc.include_dir = self.include_dir[0..self.include_dir_len :0]; | |
| 915 | } | |
| 916 | if (self.sys_include_dir_len != 0) { | |
| 917 | libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0]; | |
| 918 | } | |
| 919 | if (self.crt_dir_len != 0) { | |
| 920 | libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0]; | |
| 921 | } | |
| 922 | if (self.static_crt_dir_len != 0) { | |
| 923 | libc.static_crt_dir = self.static_crt_dir[0..self.static_crt_dir_len :0]; | |
| 924 | } | |
| 925 | if (self.msvc_lib_dir_len != 0) { | |
| 926 | libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0]; | |
| 927 | } | |
| 928 | if (self.kernel32_lib_dir_len != 0) { | |
| 929 | libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0]; | |
| 930 | } | |
| 931 | return libc; | |
| 932 | } | |
| 933 | }; | |
| 934 | ||
| 935 | // ABI warning | |
| 936 | export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error { | |
| 937 | stderr_file = std.io.getStdErr(); | |
| 938 | stderr = &stderr_file.outStream().stream; | |
| 939 | const libc_file = mem.toSliceConst(u8, libc_file_z); | |
| 940 | var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) { | |
| 941 | error.ParseError => return .SemanticAnalyzeFail, | |
| 942 | error.DiskQuota => return .DiskQuota, | |
| 943 | error.FileTooBig => return .FileTooBig, | |
| 944 | error.InputOutput => return .FileSystem, | |
| 945 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 946 | error.AccessDenied => return .AccessDenied, | |
| 947 | error.BrokenPipe => return .BrokenPipe, | |
| 948 | error.SystemResources => return .SystemResources, | |
| 949 | error.OperationAborted => return .OperationAborted, | |
| 950 | error.WouldBlock => unreachable, | |
| 951 | error.Unexpected => return .Unexpected, | |
| 952 | error.EndOfStream => return .EndOfFile, | |
| 953 | error.IsDir => return .IsDir, | |
| 954 | error.ConnectionResetByPeer => unreachable, | |
| 955 | error.OutOfMemory => return .OutOfMemory, | |
| 956 | error.Unseekable => unreachable, | |
| 957 | error.SharingViolation => return .SharingViolation, | |
| 958 | error.PathAlreadyExists => unreachable, | |
| 959 | error.FileNotFound => return .FileNotFound, | |
| 960 | error.PipeBusy => return .PipeBusy, | |
| 961 | error.NameTooLong => return .PathTooLong, | |
| 962 | error.InvalidUtf8 => return .BadPathName, | |
| 963 | error.BadPathName => return .BadPathName, | |
| 964 | error.SymLinkLoop => return .SymLinkLoop, | |
| 965 | error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded, | |
| 966 | error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded, | |
| 967 | error.NoDevice => return .NoDevice, | |
| 968 | error.NotDir => return .NotDir, | |
| 969 | error.DeviceBusy => return .DeviceBusy, | |
| 970 | }; | |
| 971 | stage1_libc.initFromStage2(libc); | |
| 972 | return .None; | |
| 973 | } | |
| 974 | ||
| 975 | // ABI warning | |
| 976 | export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error { | |
| 977 | var libc = LibCInstallation.findNative(std.heap.c_allocator) catch |err| switch (err) { | |
| 978 | error.OutOfMemory => return .OutOfMemory, | |
| 979 | error.FileSystem => return .FileSystem, | |
| 980 | error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, | |
| 981 | error.CCompilerExitCode => return .CCompilerExitCode, | |
| 982 | error.CCompilerCrashed => return .CCompilerCrashed, | |
| 983 | error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders, | |
| 984 | error.LibCRuntimeNotFound => return .LibCRuntimeNotFound, | |
| 985 | error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound, | |
| 986 | error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound, | |
| 987 | error.UnsupportedArchitecture => return .UnsupportedArchitecture, | |
| 988 | }; | |
| 989 | stage1_libc.initFromStage2(libc); | |
| 990 | return .None; | |
| 991 | } | |
| 992 | ||
| 993 | // ABI warning | |
| 994 | export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error { | |
| 995 | var libc = stage1_libc.toStage2(); | |
| 996 | const c_out_stream = &std.io.COutStream.init(output_file).stream; | |
| 997 | libc.render(c_out_stream) catch |err| switch (err) { | |
| 998 | error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode | |
| 999 | error.SystemResources => return .SystemResources, | |
| 1000 | error.OperationAborted => return .OperationAborted, | |
| 1001 | error.BrokenPipe => return .BrokenPipe, | |
| 1002 | error.DiskQuota => return .DiskQuota, | |
| 1003 | error.FileTooBig => return .FileTooBig, | |
| 1004 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 1005 | error.AccessDenied => return .AccessDenied, | |
| 1006 | error.Unexpected => return .Unexpected, | |
| 1007 | error.InputOutput => return .FileSystem, | |
| 1008 | }; | |
| 1009 | return .None; | |
| 1010 | } | |
| 1011 | ||
| 1012 | // ABI warning | |
| 1013 | export fn stage2_libc_cc_print_file_name( | |
| 1014 | out_ptr: *[*:0]u8, | |
| 1015 | out_len: *usize, | |
| 1016 | o_file: [*:0]const u8, | |
| 1017 | want_dirname: bool, | |
| 1018 | ) Error { | |
| 1019 | const result = @import("libc_installation.zig").ccPrintFileName( | |
| 1020 | std.heap.c_allocator, | |
| 1021 | mem.toSliceConst(u8, o_file), | |
| 1022 | if (want_dirname) .only_dir else .full_path, | |
| 1023 | ) catch |err| switch (err) { | |
| 1024 | error.OutOfMemory => return .OutOfMemory, | |
| 1025 | error.LibCRuntimeNotFound => return .FileNotFound, | |
| 1026 | error.CCompilerExitCode => return .CCompilerExitCode, | |
| 1027 | error.CCompilerCrashed => return .CCompilerCrashed, | |
| 1028 | error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, | |
| 1029 | }; | |
| 1030 | out_ptr.* = result.ptr; | |
| 1031 | out_len.* = result.len; | |
| 1032 | return .None; | |
| 1033 | } |
src-self-hosted/stage2.zig created+1033| ... | ... | @@ -0,0 +1,1033 @@ |
| 1 | // This is Zig code that is used by both stage1 and stage2. | |
| 2 | // The prototypes in src/userland.h must match these definitions. | |
| 3 | ||
| 4 | const std = @import("std"); | |
| 5 | const io = std.io; | |
| 6 | const mem = std.mem; | |
| 7 | const fs = std.fs; | |
| 8 | const process = std.process; | |
| 9 | const Allocator = mem.Allocator; | |
| 10 | const ArrayList = std.ArrayList; | |
| 11 | const Buffer = std.Buffer; | |
| 12 | const Target = std.Target; | |
| 13 | const self_hosted_main = @import("main.zig"); | |
| 14 | const errmsg = @import("errmsg.zig"); | |
| 15 | const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer; | |
| 16 | const assert = std.debug.assert; | |
| 17 | const LibCInstallation = @import("libc_installation.zig").LibCInstallation; | |
| 18 | ||
| 19 | var stderr_file: fs.File = undefined; | |
| 20 | var stderr: *io.OutStream(fs.File.WriteError) = undefined; | |
| 21 | var stdout: *io.OutStream(fs.File.WriteError) = undefined; | |
| 22 | ||
| 23 | comptime { | |
| 24 | _ = @import("dep_tokenizer.zig"); | |
| 25 | } | |
| 26 | ||
| 27 | // ABI warning | |
| 28 | export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { | |
| 29 | const info_zen = @import("main.zig").info_zen; | |
| 30 | ptr.* = info_zen; | |
| 31 | len.* = info_zen.len; | |
| 32 | } | |
| 33 | ||
| 34 | // ABI warning | |
| 35 | export fn stage2_panic(ptr: [*]const u8, len: usize) void { | |
| 36 | @panic(ptr[0..len]); | |
| 37 | } | |
| 38 | ||
| 39 | // ABI warning | |
| 40 | const Error = extern enum { | |
| 41 | None, | |
| 42 | OutOfMemory, | |
| 43 | InvalidFormat, | |
| 44 | SemanticAnalyzeFail, | |
| 45 | AccessDenied, | |
| 46 | Interrupted, | |
| 47 | SystemResources, | |
| 48 | FileNotFound, | |
| 49 | FileSystem, | |
| 50 | FileTooBig, | |
| 51 | DivByZero, | |
| 52 | Overflow, | |
| 53 | PathAlreadyExists, | |
| 54 | Unexpected, | |
| 55 | ExactDivRemainder, | |
| 56 | NegativeDenominator, | |
| 57 | ShiftedOutOneBits, | |
| 58 | CCompileErrors, | |
| 59 | EndOfFile, | |
| 60 | IsDir, | |
| 61 | NotDir, | |
| 62 | UnsupportedOperatingSystem, | |
| 63 | SharingViolation, | |
| 64 | PipeBusy, | |
| 65 | PrimitiveTypeNotFound, | |
| 66 | CacheUnavailable, | |
| 67 | PathTooLong, | |
| 68 | CCompilerCannotFindFile, | |
| 69 | NoCCompilerInstalled, | |
| 70 | ReadingDepFile, | |
| 71 | InvalidDepFile, | |
| 72 | MissingArchitecture, | |
| 73 | MissingOperatingSystem, | |
| 74 | UnknownArchitecture, | |
| 75 | UnknownOperatingSystem, | |
| 76 | UnknownABI, | |
| 77 | InvalidFilename, | |
| 78 | DiskQuota, | |
| 79 | DiskSpace, | |
| 80 | UnexpectedWriteFailure, | |
| 81 | UnexpectedSeekFailure, | |
| 82 | UnexpectedFileTruncationFailure, | |
| 83 | Unimplemented, | |
| 84 | OperationAborted, | |
| 85 | BrokenPipe, | |
| 86 | NoSpaceLeft, | |
| 87 | NotLazy, | |
| 88 | IsAsync, | |
| 89 | ImportOutsidePkgPath, | |
| 90 | UnknownCpu, | |
| 91 | UnknownSubArchitecture, | |
| 92 | UnknownCpuFeature, | |
| 93 | InvalidCpuFeatures, | |
| 94 | InvalidLlvmCpuFeaturesFormat, | |
| 95 | UnknownApplicationBinaryInterface, | |
| 96 | ASTUnitFailure, | |
| 97 | BadPathName, | |
| 98 | SymLinkLoop, | |
| 99 | ProcessFdQuotaExceeded, | |
| 100 | SystemFdQuotaExceeded, | |
| 101 | NoDevice, | |
| 102 | DeviceBusy, | |
| 103 | UnableToSpawnCCompiler, | |
| 104 | CCompilerExitCode, | |
| 105 | CCompilerCrashed, | |
| 106 | CCompilerCannotFindHeaders, | |
| 107 | LibCRuntimeNotFound, | |
| 108 | LibCStdLibHeaderNotFound, | |
| 109 | LibCKernel32LibNotFound, | |
| 110 | UnsupportedArchitecture, | |
| 111 | }; | |
| 112 | ||
| 113 | const FILE = std.c.FILE; | |
| 114 | const ast = std.zig.ast; | |
| 115 | const translate_c = @import("translate_c.zig"); | |
| 116 | ||
| 117 | /// Args should have a null terminating last arg. | |
| 118 | export fn stage2_translate_c( | |
| 119 | out_ast: **ast.Tree, | |
| 120 | out_errors_ptr: *[*]translate_c.ClangErrMsg, | |
| 121 | out_errors_len: *usize, | |
| 122 | args_begin: [*]?[*]const u8, | |
| 123 | args_end: [*]?[*]const u8, | |
| 124 | resources_path: [*:0]const u8, | |
| 125 | ) Error { | |
| 126 | var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0]; | |
| 127 | out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) { | |
| 128 | error.SemanticAnalyzeFail => { | |
| 129 | out_errors_ptr.* = errors.ptr; | |
| 130 | out_errors_len.* = errors.len; | |
| 131 | return .CCompileErrors; | |
| 132 | }, | |
| 133 | error.ASTUnitFailure => return .ASTUnitFailure, | |
| 134 | error.OutOfMemory => return .OutOfMemory, | |
| 135 | }; | |
| 136 | return .None; | |
| 137 | } | |
| 138 | ||
| 139 | export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void { | |
| 140 | translate_c.freeErrors(errors_ptr[0..errors_len]); | |
| 141 | } | |
| 142 | ||
| 143 | export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error { | |
| 144 | const c_out_stream = &std.io.COutStream.init(output_file).stream; | |
| 145 | _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) { | |
| 146 | error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode | |
| 147 | error.SystemResources => return .SystemResources, | |
| 148 | error.OperationAborted => return .OperationAborted, | |
| 149 | error.BrokenPipe => return .BrokenPipe, | |
| 150 | error.DiskQuota => return .DiskQuota, | |
| 151 | error.FileTooBig => return .FileTooBig, | |
| 152 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 153 | error.AccessDenied => return .AccessDenied, | |
| 154 | error.OutOfMemory => return .OutOfMemory, | |
| 155 | error.Unexpected => return .Unexpected, | |
| 156 | error.InputOutput => return .FileSystem, | |
| 157 | }; | |
| 158 | return .None; | |
| 159 | } | |
| 160 | ||
| 161 | // TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377, | |
| 162 | // we use a blocking implementation. | |
| 163 | export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int { | |
| 164 | if (std.debug.runtime_safety) { | |
| 165 | fmtMain(argc, argv) catch unreachable; | |
| 166 | } else { | |
| 167 | fmtMain(argc, argv) catch |e| { | |
| 168 | std.debug.warn("{}\n", .{@errorName(e)}); | |
| 169 | return -1; | |
| 170 | }; | |
| 171 | } | |
| 172 | return 0; | |
| 173 | } | |
| 174 | ||
| 175 | fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void { | |
| 176 | const allocator = std.heap.c_allocator; | |
| 177 | var args_list = std.ArrayList([]const u8).init(allocator); | |
| 178 | const argc_usize = @intCast(usize, argc); | |
| 179 | var arg_i: usize = 0; | |
| 180 | while (arg_i < argc_usize) : (arg_i += 1) { | |
| 181 | try args_list.append(mem.toSliceConst(u8, argv[arg_i])); | |
| 182 | } | |
| 183 | ||
| 184 | stdout = &std.io.getStdOut().outStream().stream; | |
| 185 | stderr_file = std.io.getStdErr(); | |
| 186 | stderr = &stderr_file.outStream().stream; | |
| 187 | ||
| 188 | const args = args_list.toSliceConst()[2..]; | |
| 189 | ||
| 190 | var color: errmsg.Color = .Auto; | |
| 191 | var stdin_flag: bool = false; | |
| 192 | var check_flag: bool = false; | |
| 193 | var input_files = ArrayList([]const u8).init(allocator); | |
| 194 | ||
| 195 | { | |
| 196 | var i: usize = 0; | |
| 197 | while (i < args.len) : (i += 1) { | |
| 198 | const arg = args[i]; | |
| 199 | if (mem.startsWith(u8, arg, "-")) { | |
| 200 | if (mem.eql(u8, arg, "--help")) { | |
| 201 | try stdout.write(self_hosted_main.usage_fmt); | |
| 202 | process.exit(0); | |
| 203 | } else if (mem.eql(u8, arg, "--color")) { | |
| 204 | if (i + 1 >= args.len) { | |
| 205 | try stderr.write("expected [auto|on|off] after --color\n"); | |
| 206 | process.exit(1); | |
| 207 | } | |
| 208 | i += 1; | |
| 209 | const next_arg = args[i]; | |
| 210 | if (mem.eql(u8, next_arg, "auto")) { | |
| 211 | color = .Auto; | |
| 212 | } else if (mem.eql(u8, next_arg, "on")) { | |
| 213 | color = .On; | |
| 214 | } else if (mem.eql(u8, next_arg, "off")) { | |
| 215 | color = .Off; | |
| 216 | } else { | |
| 217 | try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg}); | |
| 218 | process.exit(1); | |
| 219 | } | |
| 220 | } else if (mem.eql(u8, arg, "--stdin")) { | |
| 221 | stdin_flag = true; | |
| 222 | } else if (mem.eql(u8, arg, "--check")) { | |
| 223 | check_flag = true; | |
| 224 | } else { | |
| 225 | try stderr.print("unrecognized parameter: '{}'", .{arg}); | |
| 226 | process.exit(1); | |
| 227 | } | |
| 228 | } else { | |
| 229 | try input_files.append(arg); | |
| 230 | } | |
| 231 | } | |
| 232 | } | |
| 233 | ||
| 234 | if (stdin_flag) { | |
| 235 | if (input_files.len != 0) { | |
| 236 | try stderr.write("cannot use --stdin with positional arguments\n"); | |
| 237 | process.exit(1); | |
| 238 | } | |
| 239 | ||
| 240 | const stdin_file = io.getStdIn(); | |
| 241 | var stdin = stdin_file.inStream(); | |
| 242 | ||
| 243 | const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size); | |
| 244 | defer allocator.free(source_code); | |
| 245 | ||
| 246 | const tree = std.zig.parse(allocator, source_code) catch |err| { | |
| 247 | try stderr.print("error parsing stdin: {}\n", .{err}); | |
| 248 | process.exit(1); | |
| 249 | }; | |
| 250 | defer tree.deinit(); | |
| 251 | ||
| 252 | var error_it = tree.errors.iterator(0); | |
| 253 | while (error_it.next()) |parse_error| { | |
| 254 | try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color); | |
| 255 | } | |
| 256 | if (tree.errors.len != 0) { | |
| 257 | process.exit(1); | |
| 258 | } | |
| 259 | if (check_flag) { | |
| 260 | const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree); | |
| 261 | const code = if (anything_changed) @as(u8, 1) else @as(u8, 0); | |
| 262 | process.exit(code); | |
| 263 | } | |
| 264 | ||
| 265 | _ = try std.zig.render(allocator, stdout, tree); | |
| 266 | return; | |
| 267 | } | |
| 268 | ||
| 269 | if (input_files.len == 0) { | |
| 270 | try stderr.write("expected at least one source file argument\n"); | |
| 271 | process.exit(1); | |
| 272 | } | |
| 273 | ||
| 274 | var fmt = Fmt{ | |
| 275 | .seen = Fmt.SeenMap.init(allocator), | |
| 276 | .any_error = false, | |
| 277 | .color = color, | |
| 278 | .allocator = allocator, | |
| 279 | }; | |
| 280 | ||
| 281 | for (input_files.toSliceConst()) |file_path| { | |
| 282 | try fmtPath(&fmt, file_path, check_flag); | |
| 283 | } | |
| 284 | if (fmt.any_error) { | |
| 285 | process.exit(1); | |
| 286 | } | |
| 287 | } | |
| 288 | ||
| 289 | const FmtError = error{ | |
| 290 | SystemResources, | |
| 291 | OperationAborted, | |
| 292 | IoPending, | |
| 293 | BrokenPipe, | |
| 294 | Unexpected, | |
| 295 | WouldBlock, | |
| 296 | FileClosed, | |
| 297 | DestinationAddressRequired, | |
| 298 | DiskQuota, | |
| 299 | FileTooBig, | |
| 300 | InputOutput, | |
| 301 | NoSpaceLeft, | |
| 302 | AccessDenied, | |
| 303 | OutOfMemory, | |
| 304 | RenameAcrossMountPoints, | |
| 305 | ReadOnlyFileSystem, | |
| 306 | LinkQuotaExceeded, | |
| 307 | FileBusy, | |
| 308 | } || fs.File.OpenError; | |
| 309 | ||
| 310 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | |
| 311 | if (fmt.seen.exists(file_path)) return; | |
| 312 | try fmt.seen.put(file_path); | |
| 313 | ||
| 314 | const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) { | |
| 315 | error.IsDir, error.AccessDenied => { | |
| 316 | // TODO make event based (and dir.next()) | |
| 317 | var dir = try fs.cwd().openDirList(file_path); | |
| 318 | defer dir.close(); | |
| 319 | ||
| 320 | var dir_it = dir.iterate(); | |
| 321 | ||
| 322 | while (try dir_it.next()) |entry| { | |
| 323 | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { | |
| 324 | const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); | |
| 325 | try fmtPath(fmt, full_path, check_mode); | |
| 326 | } | |
| 327 | } | |
| 328 | return; | |
| 329 | }, | |
| 330 | else => { | |
| 331 | // TODO lock stderr printing | |
| 332 | try stderr.print("unable to open '{}': {}\n", .{ file_path, err }); | |
| 333 | fmt.any_error = true; | |
| 334 | return; | |
| 335 | }, | |
| 336 | }; | |
| 337 | defer fmt.allocator.free(source_code); | |
| 338 | ||
| 339 | const tree = std.zig.parse(fmt.allocator, source_code) catch |err| { | |
| 340 | try stderr.print("error parsing file '{}': {}\n", .{ file_path, err }); | |
| 341 | fmt.any_error = true; | |
| 342 | return; | |
| 343 | }; | |
| 344 | defer tree.deinit(); | |
| 345 | ||
| 346 | var error_it = tree.errors.iterator(0); | |
| 347 | while (error_it.next()) |parse_error| { | |
| 348 | try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color); | |
| 349 | } | |
| 350 | if (tree.errors.len != 0) { | |
| 351 | fmt.any_error = true; | |
| 352 | return; | |
| 353 | } | |
| 354 | ||
| 355 | if (check_mode) { | |
| 356 | const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree); | |
| 357 | if (anything_changed) { | |
| 358 | try stderr.print("{}\n", .{file_path}); | |
| 359 | fmt.any_error = true; | |
| 360 | } | |
| 361 | } else { | |
| 362 | const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path); | |
| 363 | defer baf.destroy(); | |
| 364 | ||
| 365 | const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree); | |
| 366 | if (anything_changed) { | |
| 367 | try stderr.print("{}\n", .{file_path}); | |
| 368 | try baf.finish(); | |
| 369 | } | |
| 370 | } | |
| 371 | } | |
| 372 | ||
| 373 | const Fmt = struct { | |
| 374 | seen: SeenMap, | |
| 375 | any_error: bool, | |
| 376 | color: errmsg.Color, | |
| 377 | allocator: *mem.Allocator, | |
| 378 | ||
| 379 | const SeenMap = std.BufSet; | |
| 380 | }; | |
| 381 | ||
| 382 | fn printErrMsgToFile( | |
| 383 | allocator: *mem.Allocator, | |
| 384 | parse_error: *const ast.Error, | |
| 385 | tree: *ast.Tree, | |
| 386 | path: []const u8, | |
| 387 | file: fs.File, | |
| 388 | color: errmsg.Color, | |
| 389 | ) !void { | |
| 390 | const color_on = switch (color) { | |
| 391 | .Auto => file.isTty(), | |
| 392 | .On => true, | |
| 393 | .Off => false, | |
| 394 | }; | |
| 395 | const lok_token = parse_error.loc(); | |
| 396 | const span = errmsg.Span{ | |
| 397 | .first = lok_token, | |
| 398 | .last = lok_token, | |
| 399 | }; | |
| 400 | ||
| 401 | const first_token = tree.tokens.at(span.first); | |
| 402 | const last_token = tree.tokens.at(span.last); | |
| 403 | const start_loc = tree.tokenLocationPtr(0, first_token); | |
| 404 | const end_loc = tree.tokenLocationPtr(first_token.end, last_token); | |
| 405 | ||
| 406 | var text_buf = try std.Buffer.initSize(allocator, 0); | |
| 407 | var out_stream = &std.io.BufferOutStream.init(&text_buf).stream; | |
| 408 | try parse_error.render(&tree.tokens, out_stream); | |
| 409 | const text = text_buf.toOwnedSlice(); | |
| 410 | ||
| 411 | const stream = &file.outStream().stream; | |
| 412 | try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text }); | |
| 413 | ||
| 414 | if (!color_on) return; | |
| 415 | ||
| 416 | // Print \r and \t as one space each so that column counts line up | |
| 417 | for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| { | |
| 418 | try stream.writeByte(switch (byte) { | |
| 419 | '\r', '\t' => ' ', | |
| 420 | else => byte, | |
| 421 | }); | |
| 422 | } | |
| 423 | try stream.writeByte('\n'); | |
| 424 | try stream.writeByteNTimes(' ', start_loc.column); | |
| 425 | try stream.writeByteNTimes('~', last_token.end - first_token.start); | |
| 426 | try stream.writeByte('\n'); | |
| 427 | } | |
| 428 | ||
| 429 | export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { | |
| 430 | const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer"); | |
| 431 | t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]); | |
| 432 | return stage2_DepTokenizer{ | |
| 433 | .handle = t, | |
| 434 | }; | |
| 435 | } | |
| 436 | ||
| 437 | export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { | |
| 438 | self.handle.deinit(); | |
| 439 | } | |
| 440 | ||
| 441 | export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { | |
| 442 | const otoken = self.handle.next() catch { | |
| 443 | const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); | |
| 444 | return stage2_DepNextResult{ | |
| 445 | .type_id = .error_, | |
| 446 | .textz = textz.toSlice().ptr, | |
| 447 | }; | |
| 448 | }; | |
| 449 | const token = otoken orelse { | |
| 450 | return stage2_DepNextResult{ | |
| 451 | .type_id = .null_, | |
| 452 | .textz = undefined, | |
| 453 | }; | |
| 454 | }; | |
| 455 | const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); | |
| 456 | return stage2_DepNextResult{ | |
| 457 | .type_id = switch (token.id) { | |
| 458 | .target => .target, | |
| 459 | .prereq => .prereq, | |
| 460 | }, | |
| 461 | .textz = textz.toSlice().ptr, | |
| 462 | }; | |
| 463 | } | |
| 464 | ||
| 465 | const stage2_DepTokenizer = extern struct { | |
| 466 | handle: *DepTokenizer, | |
| 467 | }; | |
| 468 | ||
| 469 | const stage2_DepNextResult = extern struct { | |
| 470 | type_id: TypeId, | |
| 471 | ||
| 472 | // when type_id == error --> error text | |
| 473 | // when type_id == null --> undefined | |
| 474 | // when type_id == target --> target pathname | |
| 475 | // when type_id == prereq --> prereq pathname | |
| 476 | textz: [*]const u8, | |
| 477 | ||
| 478 | const TypeId = extern enum { | |
| 479 | error_, | |
| 480 | null_, | |
| 481 | target, | |
| 482 | prereq, | |
| 483 | }; | |
| 484 | }; | |
| 485 | ||
| 486 | // ABI warning | |
| 487 | export fn stage2_attach_segfault_handler() void { | |
| 488 | if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) { | |
| 489 | std.debug.attachSegfaultHandler(); | |
| 490 | } | |
| 491 | } | |
| 492 | ||
| 493 | // ABI warning | |
| 494 | export fn stage2_progress_create() *std.Progress { | |
| 495 | const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory"); | |
| 496 | ptr.* = std.Progress{}; | |
| 497 | return ptr; | |
| 498 | } | |
| 499 | ||
| 500 | // ABI warning | |
| 501 | export fn stage2_progress_destroy(progress: *std.Progress) void { | |
| 502 | std.heap.c_allocator.destroy(progress); | |
| 503 | } | |
| 504 | ||
| 505 | // ABI warning | |
| 506 | export fn stage2_progress_start_root( | |
| 507 | progress: *std.Progress, | |
| 508 | name_ptr: [*]const u8, | |
| 509 | name_len: usize, | |
| 510 | estimated_total_items: usize, | |
| 511 | ) *std.Progress.Node { | |
| 512 | return progress.start( | |
| 513 | name_ptr[0..name_len], | |
| 514 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 515 | ) catch @panic("timer unsupported"); | |
| 516 | } | |
| 517 | ||
| 518 | // ABI warning | |
| 519 | export fn stage2_progress_disable_tty(progress: *std.Progress) void { | |
| 520 | progress.terminal = null; | |
| 521 | } | |
| 522 | ||
| 523 | // ABI warning | |
| 524 | export fn stage2_progress_start( | |
| 525 | node: *std.Progress.Node, | |
| 526 | name_ptr: [*]const u8, | |
| 527 | name_len: usize, | |
| 528 | estimated_total_items: usize, | |
| 529 | ) *std.Progress.Node { | |
| 530 | const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory"); | |
| 531 | child_node.* = node.start( | |
| 532 | name_ptr[0..name_len], | |
| 533 | if (estimated_total_items == 0) null else estimated_total_items, | |
| 534 | ); | |
| 535 | child_node.activate(); | |
| 536 | return child_node; | |
| 537 | } | |
| 538 | ||
| 539 | // ABI warning | |
| 540 | export fn stage2_progress_end(node: *std.Progress.Node) void { | |
| 541 | node.end(); | |
| 542 | if (&node.context.root != node) { | |
| 543 | std.heap.c_allocator.destroy(node); | |
| 544 | } | |
| 545 | } | |
| 546 | ||
| 547 | // ABI warning | |
| 548 | export fn stage2_progress_complete_one(node: *std.Progress.Node) void { | |
| 549 | node.completeOne(); | |
| 550 | } | |
| 551 | ||
| 552 | // ABI warning | |
| 553 | export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void { | |
| 554 | node.completed_items = done_count; | |
| 555 | node.estimated_total_items = total_count; | |
| 556 | node.activate(); | |
| 557 | node.context.maybeRefresh(); | |
| 558 | } | |
| 559 | ||
| 560 | fn cpuFeaturesFromLLVM( | |
| 561 | arch: Target.Arch, | |
| 562 | llvm_cpu_name_z: ?[*:0]const u8, | |
| 563 | llvm_cpu_features_opt: ?[*:0]const u8, | |
| 564 | ) !Target.CpuFeatures { | |
| 565 | var result = arch.getBaselineCpuFeatures(); | |
| 566 | ||
| 567 | if (llvm_cpu_name_z) |cpu_name_z| { | |
| 568 | const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z); | |
| 569 | ||
| 570 | for (arch.allCpus()) |cpu| { | |
| 571 | const this_llvm_name = cpu.llvm_name orelse continue; | |
| 572 | if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) { | |
| 573 | // Here we use the non-dependencies-populated set, | |
| 574 | // so that subtracting features later in this function | |
| 575 | // affect the prepopulated set. | |
| 576 | result = Target.CpuFeatures{ | |
| 577 | .cpu = cpu, | |
| 578 | .features = cpu.features, | |
| 579 | }; | |
| 580 | break; | |
| 581 | } | |
| 582 | } | |
| 583 | } | |
| 584 | ||
| 585 | const all_features = arch.allFeaturesList(); | |
| 586 | ||
| 587 | if (llvm_cpu_features_opt) |llvm_cpu_features| { | |
| 588 | var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ","); | |
| 589 | while (it.next()) |decorated_llvm_feat| { | |
| 590 | var op: enum { | |
| 591 | add, | |
| 592 | sub, | |
| 593 | } = undefined; | |
| 594 | var llvm_feat: []const u8 = undefined; | |
| 595 | if (mem.startsWith(u8, decorated_llvm_feat, "+")) { | |
| 596 | op = .add; | |
| 597 | llvm_feat = decorated_llvm_feat[1..]; | |
| 598 | } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) { | |
| 599 | op = .sub; | |
| 600 | llvm_feat = decorated_llvm_feat[1..]; | |
| 601 | } else { | |
| 602 | return error.InvalidLlvmCpuFeaturesFormat; | |
| 603 | } | |
| 604 | for (all_features) |feature, index_usize| { | |
| 605 | const this_llvm_name = feature.llvm_name orelse continue; | |
| 606 | if (mem.eql(u8, llvm_feat, this_llvm_name)) { | |
| 607 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | |
| 608 | switch (op) { | |
| 609 | .add => result.features.addFeature(index), | |
| 610 | .sub => result.features.removeFeature(index), | |
| 611 | } | |
| 612 | break; | |
| 613 | } | |
| 614 | } | |
| 615 | } | |
| 616 | } | |
| 617 | ||
| 618 | result.features.populateDependencies(all_features); | |
| 619 | return result; | |
| 620 | } | |
| 621 | ||
| 622 | // ABI warning | |
| 623 | export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int { | |
| 624 | cmdTargets(zig_triple) catch |err| { | |
| 625 | std.debug.warn("unable to list targets: {}\n", .{@errorName(err)}); | |
| 626 | return -1; | |
| 627 | }; | |
| 628 | return 0; | |
| 629 | } | |
| 630 | ||
| 631 | fn cmdTargets(zig_triple: [*:0]const u8) !void { | |
| 632 | var target = try Target.parse(mem.toSliceConst(u8, zig_triple)); | |
| 633 | target.Cross.cpu_features = blk: { | |
| 634 | const llvm = @import("llvm.zig"); | |
| 635 | const llvm_cpu_name = llvm.GetHostCPUName(); | |
| 636 | const llvm_cpu_features = llvm.GetNativeFeatures(); | |
| 637 | break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features); | |
| 638 | }; | |
| 639 | return @import("print_targets.zig").cmdTargets( | |
| 640 | std.heap.c_allocator, | |
| 641 | &[0][]u8{}, | |
| 642 | &std.io.getStdOut().outStream().stream, | |
| 643 | target, | |
| 644 | ); | |
| 645 | } | |
| 646 | ||
| 647 | const Stage2CpuFeatures = struct { | |
| 648 | allocator: *mem.Allocator, | |
| 649 | cpu_features: Target.CpuFeatures, | |
| 650 | ||
| 651 | llvm_features_str: ?[*:0]const u8, | |
| 652 | ||
| 653 | builtin_str: [:0]const u8, | |
| 654 | cache_hash: [:0]const u8, | |
| 655 | ||
| 656 | const Self = @This(); | |
| 657 | ||
| 658 | fn createFromNative(allocator: *mem.Allocator) !*Self { | |
| 659 | const arch = Target.current.getArch(); | |
| 660 | const llvm = @import("llvm.zig"); | |
| 661 | const llvm_cpu_name = llvm.GetHostCPUName(); | |
| 662 | const llvm_cpu_features = llvm.GetNativeFeatures(); | |
| 663 | const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name, llvm_cpu_features); | |
| 664 | return createFromCpuFeatures(allocator, arch, cpu_features); | |
| 665 | } | |
| 666 | ||
| 667 | fn createFromCpuFeatures( | |
| 668 | allocator: *mem.Allocator, | |
| 669 | arch: Target.Arch, | |
| 670 | cpu_features: Target.CpuFeatures, | |
| 671 | ) !*Self { | |
| 672 | const self = try allocator.create(Self); | |
| 673 | errdefer allocator.destroy(self); | |
| 674 | ||
| 675 | const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{ | |
| 676 | cpu_features.cpu.name, | |
| 677 | cpu_features.features.asBytes(), | |
| 678 | }); | |
| 679 | errdefer allocator.free(cache_hash); | |
| 680 | ||
| 681 | const generic_arch_name = arch.genericName(); | |
| 682 | var builtin_str_buffer = try std.Buffer.allocPrint(allocator, | |
| 683 | \\CpuFeatures{{ | |
| 684 | \\ .cpu = &Target.{}.cpu.{}, | |
| 685 | \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{ | |
| 686 | \\ | |
| 687 | , .{ | |
| 688 | generic_arch_name, | |
| 689 | cpu_features.cpu.name, | |
| 690 | generic_arch_name, | |
| 691 | generic_arch_name, | |
| 692 | }); | |
| 693 | defer builtin_str_buffer.deinit(); | |
| 694 | ||
| 695 | var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); | |
| 696 | defer llvm_features_buffer.deinit(); | |
| 697 | ||
| 698 | for (arch.allFeaturesList()) |feature, index_usize| { | |
| 699 | const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); | |
| 700 | const is_enabled = cpu_features.features.isEnabled(index); | |
| 701 | ||
| 702 | if (feature.llvm_name) |llvm_name| { | |
| 703 | const plus_or_minus = "-+"[@boolToInt(is_enabled)]; | |
| 704 | try llvm_features_buffer.appendByte(plus_or_minus); | |
| 705 | try llvm_features_buffer.append(llvm_name); | |
| 706 | try llvm_features_buffer.append(","); | |
| 707 | } | |
| 708 | ||
| 709 | if (is_enabled) { | |
| 710 | // TODO some kind of "zig identifier escape" function rather than | |
| 711 | // unconditionally using @"" syntax | |
| 712 | try builtin_str_buffer.append(" .@\""); | |
| 713 | try builtin_str_buffer.append(feature.name); | |
| 714 | try builtin_str_buffer.append("\",\n"); | |
| 715 | } | |
| 716 | } | |
| 717 | ||
| 718 | try builtin_str_buffer.append( | |
| 719 | \\ }), | |
| 720 | \\}; | |
| 721 | \\ | |
| 722 | ); | |
| 723 | ||
| 724 | assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")); | |
| 725 | llvm_features_buffer.shrink(llvm_features_buffer.len() - 1); | |
| 726 | ||
| 727 | self.* = Self{ | |
| 728 | .allocator = allocator, | |
| 729 | .cpu_features = cpu_features, | |
| 730 | .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr, | |
| 731 | .builtin_str = builtin_str_buffer.toOwnedSlice(), | |
| 732 | .cache_hash = cache_hash, | |
| 733 | }; | |
| 734 | return self; | |
| 735 | } | |
| 736 | ||
| 737 | fn destroy(self: *Self) void { | |
| 738 | self.allocator.free(self.cache_hash); | |
| 739 | self.allocator.free(self.builtin_str); | |
| 740 | // TODO if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str); | |
| 741 | self.allocator.destroy(self); | |
| 742 | } | |
| 743 | }; | |
| 744 | ||
| 745 | // ABI warning | |
| 746 | export fn stage2_cpu_features_parse( | |
| 747 | result: **Stage2CpuFeatures, | |
| 748 | zig_triple: ?[*:0]const u8, | |
| 749 | cpu_name: ?[*:0]const u8, | |
| 750 | cpu_features: ?[*:0]const u8, | |
| 751 | ) Error { | |
| 752 | result.* = stage2ParseCpuFeatures(zig_triple, cpu_name, cpu_features) catch |err| switch (err) { | |
| 753 | error.OutOfMemory => return .OutOfMemory, | |
| 754 | error.UnknownArchitecture => return .UnknownArchitecture, | |
| 755 | error.UnknownSubArchitecture => return .UnknownSubArchitecture, | |
| 756 | error.UnknownOperatingSystem => return .UnknownOperatingSystem, | |
| 757 | error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface, | |
| 758 | error.MissingOperatingSystem => return .MissingOperatingSystem, | |
| 759 | error.MissingArchitecture => return .MissingArchitecture, | |
| 760 | error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat, | |
| 761 | error.InvalidCpuFeatures => return .InvalidCpuFeatures, | |
| 762 | }; | |
| 763 | return .None; | |
| 764 | } | |
| 765 | ||
| 766 | fn stage2ParseCpuFeatures( | |
| 767 | zig_triple_oz: ?[*:0]const u8, | |
| 768 | cpu_name_oz: ?[*:0]const u8, | |
| 769 | cpu_features_oz: ?[*:0]const u8, | |
| 770 | ) !*Stage2CpuFeatures { | |
| 771 | const zig_triple_z = zig_triple_oz orelse return Stage2CpuFeatures.createFromNative(std.heap.c_allocator); | |
| 772 | const target = try Target.parse(mem.toSliceConst(u8, zig_triple_z)); | |
| 773 | const arch = target.Cross.arch; | |
| 774 | ||
| 775 | const cpu = if (cpu_name_oz) |cpu_name_z| blk: { | |
| 776 | const cpu_name = mem.toSliceConst(u8, cpu_name_z); | |
| 777 | break :blk arch.parseCpu(cpu_name) catch |err| switch (err) { | |
| 778 | error.UnknownCpu => { | |
| 779 | std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ | |
| 780 | cpu_name, | |
| 781 | @tagName(arch), | |
| 782 | }); | |
| 783 | for (arch.allCpus()) |cpu| { | |
| 784 | std.debug.warn(" {}\n", .{cpu.name}); | |
| 785 | } | |
| 786 | process.exit(1); | |
| 787 | }, | |
| 788 | else => |e| return e, | |
| 789 | }; | |
| 790 | } else target.Cross.cpu_features.cpu; | |
| 791 | ||
| 792 | var set = if (cpu_features_oz) |cpu_features_z| blk: { | |
| 793 | const cpu_features = mem.toSliceConst(u8, cpu_features_z); | |
| 794 | break :blk arch.parseCpuFeatureSet(cpu, cpu_features) catch |err| switch (err) { | |
| 795 | error.UnknownCpuFeature => { | |
| 796 | std.debug.warn( | |
| 797 | \\Unknown CPU features specified. | |
| 798 | \\Available CPU features for architecture '{}': | |
| 799 | \\ | |
| 800 | , .{@tagName(arch)}); | |
| 801 | for (arch.allFeaturesList()) |feature| { | |
| 802 | std.debug.warn(" {}\n", .{feature.name}); | |
| 803 | } | |
| 804 | process.exit(1); | |
| 805 | }, | |
| 806 | else => |e| return e, | |
| 807 | }; | |
| 808 | } else cpu.features; | |
| 809 | ||
| 810 | if (arch.subArchFeature()) |index| { | |
| 811 | set.addFeature(index); | |
| 812 | } | |
| 813 | set.populateDependencies(arch.allFeaturesList()); | |
| 814 | ||
| 815 | return Stage2CpuFeatures.createFromCpuFeatures(std.heap.c_allocator, arch, .{ | |
| 816 | .cpu = cpu, | |
| 817 | .features = set, | |
| 818 | }); | |
| 819 | } | |
| 820 | ||
| 821 | // ABI warning | |
| 822 | export fn stage2_cpu_features_get_cache_hash( | |
| 823 | cpu_features: *const Stage2CpuFeatures, | |
| 824 | ptr: *[*:0]const u8, | |
| 825 | len: *usize, | |
| 826 | ) void { | |
| 827 | ptr.* = cpu_features.cache_hash.ptr; | |
| 828 | len.* = cpu_features.cache_hash.len; | |
| 829 | } | |
| 830 | ||
| 831 | // ABI warning | |
| 832 | export fn stage2_cpu_features_get_builtin_str( | |
| 833 | cpu_features: *const Stage2CpuFeatures, | |
| 834 | ptr: *[*:0]const u8, | |
| 835 | len: *usize, | |
| 836 | ) void { | |
| 837 | ptr.* = cpu_features.builtin_str.ptr; | |
| 838 | len.* = cpu_features.builtin_str.len; | |
| 839 | } | |
| 840 | ||
| 841 | // ABI warning | |
| 842 | export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 { | |
| 843 | return if (cpu_features.cpu_features.cpu.llvm_name) |s| s.ptr else null; | |
| 844 | } | |
| 845 | ||
| 846 | // ABI warning | |
| 847 | export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 { | |
| 848 | return cpu_features.llvm_features_str; | |
| 849 | } | |
| 850 | ||
| 851 | // ABI warning | |
| 852 | const Stage2LibCInstallation = extern struct { | |
| 853 | include_dir: [*:0]const u8, | |
| 854 | include_dir_len: usize, | |
| 855 | sys_include_dir: [*:0]const u8, | |
| 856 | sys_include_dir_len: usize, | |
| 857 | crt_dir: [*:0]const u8, | |
| 858 | crt_dir_len: usize, | |
| 859 | static_crt_dir: [*:0]const u8, | |
| 860 | static_crt_dir_len: usize, | |
| 861 | msvc_lib_dir: [*:0]const u8, | |
| 862 | msvc_lib_dir_len: usize, | |
| 863 | kernel32_lib_dir: [*:0]const u8, | |
| 864 | kernel32_lib_dir_len: usize, | |
| 865 | ||
| 866 | fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void { | |
| 867 | if (libc.include_dir) |s| { | |
| 868 | self.include_dir = s.ptr; | |
| 869 | self.include_dir_len = s.len; | |
| 870 | } else { | |
| 871 | self.include_dir = ""; | |
| 872 | self.include_dir_len = 0; | |
| 873 | } | |
| 874 | if (libc.sys_include_dir) |s| { | |
| 875 | self.sys_include_dir = s.ptr; | |
| 876 | self.sys_include_dir_len = s.len; | |
| 877 | } else { | |
| 878 | self.sys_include_dir = ""; | |
| 879 | self.sys_include_dir_len = 0; | |
| 880 | } | |
| 881 | if (libc.crt_dir) |s| { | |
| 882 | self.crt_dir = s.ptr; | |
| 883 | self.crt_dir_len = s.len; | |
| 884 | } else { | |
| 885 | self.crt_dir = ""; | |
| 886 | self.crt_dir_len = 0; | |
| 887 | } | |
| 888 | if (libc.static_crt_dir) |s| { | |
| 889 | self.static_crt_dir = s.ptr; | |
| 890 | self.static_crt_dir_len = s.len; | |
| 891 | } else { | |
| 892 | self.static_crt_dir = ""; | |
| 893 | self.static_crt_dir_len = 0; | |
| 894 | } | |
| 895 | if (libc.msvc_lib_dir) |s| { | |
| 896 | self.msvc_lib_dir = s.ptr; | |
| 897 | self.msvc_lib_dir_len = s.len; | |
| 898 | } else { | |
| 899 | self.msvc_lib_dir = ""; | |
| 900 | self.msvc_lib_dir_len = 0; | |
| 901 | } | |
| 902 | if (libc.kernel32_lib_dir) |s| { | |
| 903 | self.kernel32_lib_dir = s.ptr; | |
| 904 | self.kernel32_lib_dir_len = s.len; | |
| 905 | } else { | |
| 906 | self.kernel32_lib_dir = ""; | |
| 907 | self.kernel32_lib_dir_len = 0; | |
| 908 | } | |
| 909 | } | |
| 910 | ||
| 911 | fn toStage2(self: Stage2LibCInstallation) LibCInstallation { | |
| 912 | var libc: LibCInstallation = .{}; | |
| 913 | if (self.include_dir_len != 0) { | |
| 914 | libc.include_dir = self.include_dir[0..self.include_dir_len :0]; | |
| 915 | } | |
| 916 | if (self.sys_include_dir_len != 0) { | |
| 917 | libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0]; | |
| 918 | } | |
| 919 | if (self.crt_dir_len != 0) { | |
| 920 | libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0]; | |
| 921 | } | |
| 922 | if (self.static_crt_dir_len != 0) { | |
| 923 | libc.static_crt_dir = self.static_crt_dir[0..self.static_crt_dir_len :0]; | |
| 924 | } | |
| 925 | if (self.msvc_lib_dir_len != 0) { | |
| 926 | libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0]; | |
| 927 | } | |
| 928 | if (self.kernel32_lib_dir_len != 0) { | |
| 929 | libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0]; | |
| 930 | } | |
| 931 | return libc; | |
| 932 | } | |
| 933 | }; | |
| 934 | ||
| 935 | // ABI warning | |
| 936 | export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error { | |
| 937 | stderr_file = std.io.getStdErr(); | |
| 938 | stderr = &stderr_file.outStream().stream; | |
| 939 | const libc_file = mem.toSliceConst(u8, libc_file_z); | |
| 940 | var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) { | |
| 941 | error.ParseError => return .SemanticAnalyzeFail, | |
| 942 | error.DiskQuota => return .DiskQuota, | |
| 943 | error.FileTooBig => return .FileTooBig, | |
| 944 | error.InputOutput => return .FileSystem, | |
| 945 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 946 | error.AccessDenied => return .AccessDenied, | |
| 947 | error.BrokenPipe => return .BrokenPipe, | |
| 948 | error.SystemResources => return .SystemResources, | |
| 949 | error.OperationAborted => return .OperationAborted, | |
| 950 | error.WouldBlock => unreachable, | |
| 951 | error.Unexpected => return .Unexpected, | |
| 952 | error.EndOfStream => return .EndOfFile, | |
| 953 | error.IsDir => return .IsDir, | |
| 954 | error.ConnectionResetByPeer => unreachable, | |
| 955 | error.OutOfMemory => return .OutOfMemory, | |
| 956 | error.Unseekable => unreachable, | |
| 957 | error.SharingViolation => return .SharingViolation, | |
| 958 | error.PathAlreadyExists => unreachable, | |
| 959 | error.FileNotFound => return .FileNotFound, | |
| 960 | error.PipeBusy => return .PipeBusy, | |
| 961 | error.NameTooLong => return .PathTooLong, | |
| 962 | error.InvalidUtf8 => return .BadPathName, | |
| 963 | error.BadPathName => return .BadPathName, | |
| 964 | error.SymLinkLoop => return .SymLinkLoop, | |
| 965 | error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded, | |
| 966 | error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded, | |
| 967 | error.NoDevice => return .NoDevice, | |
| 968 | error.NotDir => return .NotDir, | |
| 969 | error.DeviceBusy => return .DeviceBusy, | |
| 970 | }; | |
| 971 | stage1_libc.initFromStage2(libc); | |
| 972 | return .None; | |
| 973 | } | |
| 974 | ||
| 975 | // ABI warning | |
| 976 | export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error { | |
| 977 | var libc = LibCInstallation.findNative(std.heap.c_allocator) catch |err| switch (err) { | |
| 978 | error.OutOfMemory => return .OutOfMemory, | |
| 979 | error.FileSystem => return .FileSystem, | |
| 980 | error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, | |
| 981 | error.CCompilerExitCode => return .CCompilerExitCode, | |
| 982 | error.CCompilerCrashed => return .CCompilerCrashed, | |
| 983 | error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders, | |
| 984 | error.LibCRuntimeNotFound => return .LibCRuntimeNotFound, | |
| 985 | error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound, | |
| 986 | error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound, | |
| 987 | error.UnsupportedArchitecture => return .UnsupportedArchitecture, | |
| 988 | }; | |
| 989 | stage1_libc.initFromStage2(libc); | |
| 990 | return .None; | |
| 991 | } | |
| 992 | ||
| 993 | // ABI warning | |
| 994 | export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error { | |
| 995 | var libc = stage1_libc.toStage2(); | |
| 996 | const c_out_stream = &std.io.COutStream.init(output_file).stream; | |
| 997 | libc.render(c_out_stream) catch |err| switch (err) { | |
| 998 | error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode | |
| 999 | error.SystemResources => return .SystemResources, | |
| 1000 | error.OperationAborted => return .OperationAborted, | |
| 1001 | error.BrokenPipe => return .BrokenPipe, | |
| 1002 | error.DiskQuota => return .DiskQuota, | |
| 1003 | error.FileTooBig => return .FileTooBig, | |
| 1004 | error.NoSpaceLeft => return .NoSpaceLeft, | |
| 1005 | error.AccessDenied => return .AccessDenied, | |
| 1006 | error.Unexpected => return .Unexpected, | |
| 1007 | error.InputOutput => return .FileSystem, | |
| 1008 | }; | |
| 1009 | return .None; | |
| 1010 | } | |
| 1011 | ||
| 1012 | // ABI warning | |
| 1013 | export fn stage2_libc_cc_print_file_name( | |
| 1014 | out_ptr: *[*:0]u8, | |
| 1015 | out_len: *usize, | |
| 1016 | o_file: [*:0]const u8, | |
| 1017 | want_dirname: bool, | |
| 1018 | ) Error { | |
| 1019 | const result = @import("libc_installation.zig").ccPrintFileName( | |
| 1020 | std.heap.c_allocator, | |
| 1021 | mem.toSliceConst(u8, o_file), | |
| 1022 | if (want_dirname) .only_dir else .full_path, | |
| 1023 | ) catch |err| switch (err) { | |
| 1024 | error.OutOfMemory => return .OutOfMemory, | |
| 1025 | error.LibCRuntimeNotFound => return .FileNotFound, | |
| 1026 | error.CCompilerExitCode => return .CCompilerExitCode, | |
| 1027 | error.CCompilerCrashed => return .CCompilerCrashed, | |
| 1028 | error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, | |
| 1029 | }; | |
| 1030 | out_ptr.* = result.ptr; | |
| 1031 | out_len.* = result.len; | |
| 1032 | return .None; | |
| 1033 | } |
src/cache_hash.cpp+1-1| ... | ... | @@ -5,7 +5,7 @@ |
| 5 | 5 | * See http://opensource.org/licenses/MIT |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | #include "userland.h" | |
| 8 | #include "stage2.h" | |
| 9 | 9 | #include "cache_hash.hpp" |
| 10 | 10 | #include "all_types.hpp" |
| 11 | 11 | #include "buffer.hpp" |
src/codegen.cpp+1-1| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | #include "target.hpp" |
| 19 | 19 | #include "util.hpp" |
| 20 | 20 | #include "zig_llvm.h" |
| 21 | #include "userland.h" | |
| 21 | #include "stage2.h" | |
| 22 | 22 | #include "dump_analysis.hpp" |
| 23 | 23 | #include "softfloat.hpp" |
| 24 | 24 | #include "mem_profile.hpp" |
src/codegen.hpp+1-1| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #include "parser.hpp" |
| 12 | 12 | #include "errmsg.hpp" |
| 13 | 13 | #include "target.hpp" |
| 14 | #include "userland.h" | |
| 14 | #include "stage2.h" | |
| 15 | 15 | |
| 16 | 16 | #include <stdio.h> |
| 17 | 17 |
src/error.hpp+1-1| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | #ifndef ERROR_HPP |
| 9 | 9 | #define ERROR_HPP |
| 10 | 10 | |
| 11 | #include "userland.h" | |
| 11 | #include "stage2.h" | |
| 12 | 12 | |
| 13 | 13 | const char *err_str(Error err); |
| 14 | 14 |
src/main.cpp+1-1| ... | ... | @@ -14,7 +14,7 @@ |
| 14 | 14 | #include "heap.hpp" |
| 15 | 15 | #include "os.hpp" |
| 16 | 16 | #include "target.hpp" |
| 17 | #include "userland.h" | |
| 17 | #include "stage2.h" | |
| 18 | 18 | #include "glibc.hpp" |
| 19 | 19 | #include "dump_analysis.hpp" |
| 20 | 20 | #include "mem_profile.hpp" |
src/stage2.cpp created+179| ... | ... | @@ -0,0 +1,179 @@ |
| 1 | // This file is a shim for zig1. The real implementations of these are in | |
| 2 | // src-self-hosted/stage1.zig | |
| 3 | ||
| 4 | #include "stage2.h" | |
| 5 | #include "util.hpp" | |
| 6 | #include "zig_llvm.h" | |
| 7 | #include <stdio.h> | |
| 8 | #include <stdlib.h> | |
| 9 | #include <string.h> | |
| 10 | ||
| 11 | Error stage2_translate_c(struct Stage2Ast **out_ast, | |
| 12 | struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, | |
| 13 | const char **args_begin, const char **args_end, const char *resources_path) | |
| 14 | { | |
| 15 | const char *msg = "stage0 called stage2_translate_c"; | |
| 16 | stage2_panic(msg, strlen(msg)); | |
| 17 | } | |
| 18 | ||
| 19 | void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) { | |
| 20 | const char *msg = "stage0 called stage2_free_clang_errors"; | |
| 21 | stage2_panic(msg, strlen(msg)); | |
| 22 | } | |
| 23 | ||
| 24 | void stage2_zen(const char **ptr, size_t *len) { | |
| 25 | const char *msg = "stage0 called stage2_zen"; | |
| 26 | stage2_panic(msg, strlen(msg)); | |
| 27 | } | |
| 28 | ||
| 29 | void stage2_attach_segfault_handler(void) { } | |
| 30 | ||
| 31 | void stage2_panic(const char *ptr, size_t len) { | |
| 32 | fwrite(ptr, 1, len, stderr); | |
| 33 | fprintf(stderr, "\n"); | |
| 34 | fflush(stderr); | |
| 35 | abort(); | |
| 36 | } | |
| 37 | ||
| 38 | void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) { | |
| 39 | const char *msg = "stage0 called stage2_render_ast"; | |
| 40 | stage2_panic(msg, strlen(msg)); | |
| 41 | } | |
| 42 | ||
| 43 | int stage2_fmt(int argc, char **argv) { | |
| 44 | const char *msg = "stage0 called stage2_fmt"; | |
| 45 | stage2_panic(msg, strlen(msg)); | |
| 46 | } | |
| 47 | ||
| 48 | stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) { | |
| 49 | const char *msg = "stage0 called stage2_DepTokenizer_init"; | |
| 50 | stage2_panic(msg, strlen(msg)); | |
| 51 | } | |
| 52 | ||
| 53 | void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) { | |
| 54 | const char *msg = "stage0 called stage2_DepTokenizer_deinit"; | |
| 55 | stage2_panic(msg, strlen(msg)); | |
| 56 | } | |
| 57 | ||
| 58 | stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) { | |
| 59 | const char *msg = "stage0 called stage2_DepTokenizer_next"; | |
| 60 | stage2_panic(msg, strlen(msg)); | |
| 61 | } | |
| 62 | ||
| 63 | ||
| 64 | struct Stage2Progress { | |
| 65 | int trash; | |
| 66 | }; | |
| 67 | ||
| 68 | struct Stage2ProgressNode { | |
| 69 | int trash; | |
| 70 | }; | |
| 71 | ||
| 72 | Stage2Progress *stage2_progress_create(void) { | |
| 73 | return nullptr; | |
| 74 | } | |
| 75 | ||
| 76 | void stage2_progress_destroy(Stage2Progress *progress) {} | |
| 77 | ||
| 78 | Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 79 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 80 | { | |
| 81 | return nullptr; | |
| 82 | } | |
| 83 | Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 84 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 85 | { | |
| 86 | return nullptr; | |
| 87 | } | |
| 88 | void stage2_progress_end(Stage2ProgressNode *node) {} | |
| 89 | void stage2_progress_complete_one(Stage2ProgressNode *node) {} | |
| 90 | void stage2_progress_disable_tty(Stage2Progress *progress) {} | |
| 91 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} | |
| 92 | ||
| 93 | struct Stage2CpuFeatures { | |
| 94 | const char *llvm_cpu_name; | |
| 95 | const char *llvm_cpu_features; | |
| 96 | const char *builtin_str; | |
| 97 | const char *cache_hash; | |
| 98 | }; | |
| 99 | ||
| 100 | Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_triple, | |
| 101 | const char *cpu_name, const char *cpu_features) | |
| 102 | { | |
| 103 | if (zig_triple == nullptr) { | |
| 104 | Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>(); | |
| 105 | result->llvm_cpu_name = ZigLLVMGetHostCPUName(); | |
| 106 | result->llvm_cpu_features = ZigLLVMGetNativeFeatures(); | |
| 107 | result->builtin_str = "arch.getBaselineCpuFeatures();\n"; | |
| 108 | result->cache_hash = "native\n\n"; | |
| 109 | *out = result; | |
| 110 | return ErrorNone; | |
| 111 | } | |
| 112 | if (cpu_name == nullptr && cpu_features == nullptr) { | |
| 113 | Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>(); | |
| 114 | result->builtin_str = "arch.getBaselineCpuFeatures();\n"; | |
| 115 | result->cache_hash = "\n\n"; | |
| 116 | *out = result; | |
| 117 | return ErrorNone; | |
| 118 | } | |
| 119 | ||
| 120 | const char *msg = "stage0 called stage2_cpu_features_parse with non-null cpu name or features"; | |
| 121 | stage2_panic(msg, strlen(msg)); | |
| 122 | } | |
| 123 | ||
| 124 | void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features, | |
| 125 | const char **ptr, size_t *len) | |
| 126 | { | |
| 127 | *ptr = cpu_features->cache_hash; | |
| 128 | *len = strlen(cpu_features->cache_hash); | |
| 129 | } | |
| 130 | const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) { | |
| 131 | return cpu_features->llvm_cpu_name; | |
| 132 | } | |
| 133 | const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) { | |
| 134 | return cpu_features->llvm_cpu_features; | |
| 135 | } | |
| 136 | void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features, | |
| 137 | const char **ptr, size_t *len) | |
| 138 | { | |
| 139 | *ptr = cpu_features->builtin_str; | |
| 140 | *len = strlen(cpu_features->builtin_str); | |
| 141 | } | |
| 142 | ||
| 143 | int stage2_cmd_targets(const char *zig_triple) { | |
| 144 | const char *msg = "stage0 called stage2_cmd_targets"; | |
| 145 | stage2_panic(msg, strlen(msg)); | |
| 146 | } | |
| 147 | ||
| 148 | enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) { | |
| 149 | libc->include_dir = "/dummy/include"; | |
| 150 | libc->include_dir_len = strlen(libc->include_dir); | |
| 151 | libc->sys_include_dir = "/dummy/sys/include"; | |
| 152 | libc->sys_include_dir_len = strlen(libc->sys_include_dir); | |
| 153 | libc->crt_dir = ""; | |
| 154 | libc->crt_dir_len = strlen(libc->crt_dir); | |
| 155 | libc->static_crt_dir = ""; | |
| 156 | libc->static_crt_dir_len = strlen(libc->static_crt_dir); | |
| 157 | libc->msvc_lib_dir = ""; | |
| 158 | libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir); | |
| 159 | libc->kernel32_lib_dir = ""; | |
| 160 | libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir); | |
| 161 | return ErrorNone; | |
| 162 | } | |
| 163 | ||
| 164 | enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) { | |
| 165 | const char *msg = "stage0 called stage2_libc_render"; | |
| 166 | stage2_panic(msg, strlen(msg)); | |
| 167 | } | |
| 168 | ||
| 169 | enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { | |
| 170 | const char *msg = "stage0 called stage2_libc_find_native"; | |
| 171 | stage2_panic(msg, strlen(msg)); | |
| 172 | } | |
| 173 | ||
| 174 | enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 175 | const char *o_file, bool want_dirname) | |
| 176 | { | |
| 177 | const char *msg = "stage0 called stage2_libc_cc_print_file_name"; | |
| 178 | stage2_panic(msg, strlen(msg)); | |
| 179 | } |
src/stage2.h created+248| ... | ... | @@ -0,0 +1,248 @@ |
| 1 | /* | |
| 2 | * Copyright (c) 2019 Andrew Kelley | |
| 3 | * | |
| 4 | * This file is part of zig, which is MIT licensed. | |
| 5 | * See http://opensource.org/licenses/MIT | |
| 6 | */ | |
| 7 | ||
| 8 | #ifndef ZIG_STAGE2_H | |
| 9 | #define ZIG_STAGE2_H | |
| 10 | ||
| 11 | #include <stddef.h> | |
| 12 | #include <stdint.h> | |
| 13 | #include <stdio.h> | |
| 14 | ||
| 15 | #ifdef __cplusplus | |
| 16 | #define ZIG_EXTERN_C extern "C" | |
| 17 | #else | |
| 18 | #define ZIG_EXTERN_C | |
| 19 | #endif | |
| 20 | ||
| 21 | #if defined(_MSC_VER) | |
| 22 | #define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn) | |
| 23 | #else | |
| 24 | #define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn)) | |
| 25 | #endif | |
| 26 | ||
| 27 | // ABI warning: the types and declarations in this file must match both those in | |
| 28 | // stage2.cpp and src-self-hosted/stage2.zig. | |
| 29 | ||
| 30 | // ABI warning | |
| 31 | enum Error { | |
| 32 | ErrorNone, | |
| 33 | ErrorNoMem, | |
| 34 | ErrorInvalidFormat, | |
| 35 | ErrorSemanticAnalyzeFail, | |
| 36 | ErrorAccess, | |
| 37 | ErrorInterrupted, | |
| 38 | ErrorSystemResources, | |
| 39 | ErrorFileNotFound, | |
| 40 | ErrorFileSystem, | |
| 41 | ErrorFileTooBig, | |
| 42 | ErrorDivByZero, | |
| 43 | ErrorOverflow, | |
| 44 | ErrorPathAlreadyExists, | |
| 45 | ErrorUnexpected, | |
| 46 | ErrorExactDivRemainder, | |
| 47 | ErrorNegativeDenominator, | |
| 48 | ErrorShiftedOutOneBits, | |
| 49 | ErrorCCompileErrors, | |
| 50 | ErrorEndOfFile, | |
| 51 | ErrorIsDir, | |
| 52 | ErrorNotDir, | |
| 53 | ErrorUnsupportedOperatingSystem, | |
| 54 | ErrorSharingViolation, | |
| 55 | ErrorPipeBusy, | |
| 56 | ErrorPrimitiveTypeNotFound, | |
| 57 | ErrorCacheUnavailable, | |
| 58 | ErrorPathTooLong, | |
| 59 | ErrorCCompilerCannotFindFile, | |
| 60 | ErrorNoCCompilerInstalled, | |
| 61 | ErrorReadingDepFile, | |
| 62 | ErrorInvalidDepFile, | |
| 63 | ErrorMissingArchitecture, | |
| 64 | ErrorMissingOperatingSystem, | |
| 65 | ErrorUnknownArchitecture, | |
| 66 | ErrorUnknownOperatingSystem, | |
| 67 | ErrorUnknownABI, | |
| 68 | ErrorInvalidFilename, | |
| 69 | ErrorDiskQuota, | |
| 70 | ErrorDiskSpace, | |
| 71 | ErrorUnexpectedWriteFailure, | |
| 72 | ErrorUnexpectedSeekFailure, | |
| 73 | ErrorUnexpectedFileTruncationFailure, | |
| 74 | ErrorUnimplemented, | |
| 75 | ErrorOperationAborted, | |
| 76 | ErrorBrokenPipe, | |
| 77 | ErrorNoSpaceLeft, | |
| 78 | ErrorNotLazy, | |
| 79 | ErrorIsAsync, | |
| 80 | ErrorImportOutsidePkgPath, | |
| 81 | ErrorUnknownCpu, | |
| 82 | ErrorUnknownSubArchitecture, | |
| 83 | ErrorUnknownCpuFeature, | |
| 84 | ErrorInvalidCpuFeatures, | |
| 85 | ErrorInvalidLlvmCpuFeaturesFormat, | |
| 86 | ErrorUnknownApplicationBinaryInterface, | |
| 87 | ErrorASTUnitFailure, | |
| 88 | ErrorBadPathName, | |
| 89 | ErrorSymLinkLoop, | |
| 90 | ErrorProcessFdQuotaExceeded, | |
| 91 | ErrorSystemFdQuotaExceeded, | |
| 92 | ErrorNoDevice, | |
| 93 | ErrorDeviceBusy, | |
| 94 | ErrorUnableToSpawnCCompiler, | |
| 95 | ErrorCCompilerExitCode, | |
| 96 | ErrorCCompilerCrashed, | |
| 97 | ErrorCCompilerCannotFindHeaders, | |
| 98 | ErrorLibCRuntimeNotFound, | |
| 99 | ErrorLibCStdLibHeaderNotFound, | |
| 100 | ErrorLibCKernel32LibNotFound, | |
| 101 | ErrorUnsupportedArchitecture, | |
| 102 | }; | |
| 103 | ||
| 104 | // ABI warning | |
| 105 | struct Stage2ErrorMsg { | |
| 106 | const char *filename_ptr; // can be null | |
| 107 | size_t filename_len; | |
| 108 | const char *msg_ptr; | |
| 109 | size_t msg_len; | |
| 110 | const char *source; // valid until the ASTUnit is freed. can be null | |
| 111 | unsigned line; // 0 based | |
| 112 | unsigned column; // 0 based | |
| 113 | unsigned offset; // byte offset into source | |
| 114 | }; | |
| 115 | ||
| 116 | // ABI warning | |
| 117 | struct Stage2Ast; | |
| 118 | ||
| 119 | // ABI warning | |
| 120 | ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast, | |
| 121 | struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, | |
| 122 | const char **args_begin, const char **args_end, const char *resources_path); | |
| 123 | ||
| 124 | // ABI warning | |
| 125 | ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len); | |
| 126 | ||
| 127 | // ABI warning | |
| 128 | ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); | |
| 129 | ||
| 130 | // ABI warning | |
| 131 | ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len); | |
| 132 | ||
| 133 | // ABI warning | |
| 134 | ZIG_EXTERN_C void stage2_attach_segfault_handler(void); | |
| 135 | ||
| 136 | // ABI warning | |
| 137 | ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); | |
| 138 | ||
| 139 | // ABI warning | |
| 140 | ZIG_EXTERN_C int stage2_fmt(int argc, char **argv); | |
| 141 | ||
| 142 | // ABI warning | |
| 143 | struct stage2_DepTokenizer { | |
| 144 | void *handle; | |
| 145 | }; | |
| 146 | ||
| 147 | // ABI warning | |
| 148 | struct stage2_DepNextResult { | |
| 149 | enum TypeId { | |
| 150 | error, | |
| 151 | null, | |
| 152 | target, | |
| 153 | prereq, | |
| 154 | }; | |
| 155 | ||
| 156 | TypeId type_id; | |
| 157 | ||
| 158 | // when ent == error --> error text | |
| 159 | // when ent == null --> undefined | |
| 160 | // when ent == target --> target pathname | |
| 161 | // when ent == prereq --> prereq pathname | |
| 162 | const char *textz; | |
| 163 | }; | |
| 164 | ||
| 165 | // ABI warning | |
| 166 | ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len); | |
| 167 | ||
| 168 | // ABI warning | |
| 169 | ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self); | |
| 170 | ||
| 171 | // ABI warning | |
| 172 | ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self); | |
| 173 | ||
| 174 | // ABI warning | |
| 175 | struct Stage2Progress; | |
| 176 | // ABI warning | |
| 177 | struct Stage2ProgressNode; | |
| 178 | // ABI warning | |
| 179 | ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); | |
| 180 | // ABI warning | |
| 181 | ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress); | |
| 182 | // ABI warning | |
| 183 | ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress); | |
| 184 | // ABI warning | |
| 185 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 186 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 187 | // ABI warning | |
| 188 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 189 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 190 | // ABI warning | |
| 191 | ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); | |
| 192 | // ABI warning | |
| 193 | ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); | |
| 194 | // ABI warning | |
| 195 | ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node, | |
| 196 | size_t completed_count, size_t estimated_total_items); | |
| 197 | ||
| 198 | // ABI warning | |
| 199 | struct Stage2CpuFeatures; | |
| 200 | ||
| 201 | // ABI warning | |
| 202 | ZIG_EXTERN_C enum Error stage2_cpu_features_parse(struct Stage2CpuFeatures **result, | |
| 203 | const char *zig_triple, const char *cpu_name, const char *cpu_features); | |
| 204 | ||
| 205 | // ABI warning | |
| 206 | ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const struct Stage2CpuFeatures *cpu_features); | |
| 207 | ||
| 208 | // ABI warning | |
| 209 | ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const struct Stage2CpuFeatures *cpu_features); | |
| 210 | ||
| 211 | // ABI warning | |
| 212 | ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const struct Stage2CpuFeatures *cpu_features, | |
| 213 | const char **ptr, size_t *len); | |
| 214 | ||
| 215 | // ABI warning | |
| 216 | ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatures *cpu_features, | |
| 217 | const char **ptr, size_t *len); | |
| 218 | ||
| 219 | // ABI warning | |
| 220 | ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple); | |
| 221 | ||
| 222 | // ABI warning | |
| 223 | struct Stage2LibCInstallation { | |
| 224 | const char *include_dir; | |
| 225 | size_t include_dir_len; | |
| 226 | const char *sys_include_dir; | |
| 227 | size_t sys_include_dir_len; | |
| 228 | const char *crt_dir; | |
| 229 | size_t crt_dir_len; | |
| 230 | const char *static_crt_dir; | |
| 231 | size_t static_crt_dir_len; | |
| 232 | const char *msvc_lib_dir; | |
| 233 | size_t msvc_lib_dir_len; | |
| 234 | const char *kernel32_lib_dir; | |
| 235 | size_t kernel32_lib_dir_len; | |
| 236 | }; | |
| 237 | ||
| 238 | // ABI warning | |
| 239 | ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file); | |
| 240 | // ABI warning | |
| 241 | ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file); | |
| 242 | // ABI warning | |
| 243 | ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc); | |
| 244 | // ABI warning | |
| 245 | ZIG_EXTERN_C enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 246 | const char *o_file, bool want_dirname); | |
| 247 | ||
| 248 | #endif |
src/userland.cpp deleted-179| ... | ... | @@ -1,179 +0,0 @@ |
| 1 | // This file is a shim for zig1. The real implementations of these are in | |
| 2 | // src-self-hosted/stage1.zig | |
| 3 | ||
| 4 | #include "userland.h" | |
| 5 | #include "util.hpp" | |
| 6 | #include "zig_llvm.h" | |
| 7 | #include <stdio.h> | |
| 8 | #include <stdlib.h> | |
| 9 | #include <string.h> | |
| 10 | ||
| 11 | Error stage2_translate_c(struct Stage2Ast **out_ast, | |
| 12 | struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, | |
| 13 | const char **args_begin, const char **args_end, const char *resources_path) | |
| 14 | { | |
| 15 | const char *msg = "stage0 called stage2_translate_c"; | |
| 16 | stage2_panic(msg, strlen(msg)); | |
| 17 | } | |
| 18 | ||
| 19 | void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) { | |
| 20 | const char *msg = "stage0 called stage2_free_clang_errors"; | |
| 21 | stage2_panic(msg, strlen(msg)); | |
| 22 | } | |
| 23 | ||
| 24 | void stage2_zen(const char **ptr, size_t *len) { | |
| 25 | const char *msg = "stage0 called stage2_zen"; | |
| 26 | stage2_panic(msg, strlen(msg)); | |
| 27 | } | |
| 28 | ||
| 29 | void stage2_attach_segfault_handler(void) { } | |
| 30 | ||
| 31 | void stage2_panic(const char *ptr, size_t len) { | |
| 32 | fwrite(ptr, 1, len, stderr); | |
| 33 | fprintf(stderr, "\n"); | |
| 34 | fflush(stderr); | |
| 35 | abort(); | |
| 36 | } | |
| 37 | ||
| 38 | void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) { | |
| 39 | const char *msg = "stage0 called stage2_render_ast"; | |
| 40 | stage2_panic(msg, strlen(msg)); | |
| 41 | } | |
| 42 | ||
| 43 | int stage2_fmt(int argc, char **argv) { | |
| 44 | const char *msg = "stage0 called stage2_fmt"; | |
| 45 | stage2_panic(msg, strlen(msg)); | |
| 46 | } | |
| 47 | ||
| 48 | stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) { | |
| 49 | const char *msg = "stage0 called stage2_DepTokenizer_init"; | |
| 50 | stage2_panic(msg, strlen(msg)); | |
| 51 | } | |
| 52 | ||
| 53 | void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) { | |
| 54 | const char *msg = "stage0 called stage2_DepTokenizer_deinit"; | |
| 55 | stage2_panic(msg, strlen(msg)); | |
| 56 | } | |
| 57 | ||
| 58 | stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) { | |
| 59 | const char *msg = "stage0 called stage2_DepTokenizer_next"; | |
| 60 | stage2_panic(msg, strlen(msg)); | |
| 61 | } | |
| 62 | ||
| 63 | ||
| 64 | struct Stage2Progress { | |
| 65 | int trash; | |
| 66 | }; | |
| 67 | ||
| 68 | struct Stage2ProgressNode { | |
| 69 | int trash; | |
| 70 | }; | |
| 71 | ||
| 72 | Stage2Progress *stage2_progress_create(void) { | |
| 73 | return nullptr; | |
| 74 | } | |
| 75 | ||
| 76 | void stage2_progress_destroy(Stage2Progress *progress) {} | |
| 77 | ||
| 78 | Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 79 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 80 | { | |
| 81 | return nullptr; | |
| 82 | } | |
| 83 | Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 84 | const char *name_ptr, size_t name_len, size_t estimated_total_items) | |
| 85 | { | |
| 86 | return nullptr; | |
| 87 | } | |
| 88 | void stage2_progress_end(Stage2ProgressNode *node) {} | |
| 89 | void stage2_progress_complete_one(Stage2ProgressNode *node) {} | |
| 90 | void stage2_progress_disable_tty(Stage2Progress *progress) {} | |
| 91 | void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){} | |
| 92 | ||
| 93 | struct Stage2CpuFeatures { | |
| 94 | const char *llvm_cpu_name; | |
| 95 | const char *llvm_cpu_features; | |
| 96 | const char *builtin_str; | |
| 97 | const char *cache_hash; | |
| 98 | }; | |
| 99 | ||
| 100 | Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_triple, | |
| 101 | const char *cpu_name, const char *cpu_features) | |
| 102 | { | |
| 103 | if (zig_triple == nullptr) { | |
| 104 | Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>(); | |
| 105 | result->llvm_cpu_name = ZigLLVMGetHostCPUName(); | |
| 106 | result->llvm_cpu_features = ZigLLVMGetNativeFeatures(); | |
| 107 | result->builtin_str = "arch.getBaselineCpuFeatures();\n"; | |
| 108 | result->cache_hash = "native\n\n"; | |
| 109 | *out = result; | |
| 110 | return ErrorNone; | |
| 111 | } | |
| 112 | if (cpu_name == nullptr && cpu_features == nullptr) { | |
| 113 | Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>(); | |
| 114 | result->builtin_str = "arch.getBaselineCpuFeatures();\n"; | |
| 115 | result->cache_hash = "\n\n"; | |
| 116 | *out = result; | |
| 117 | return ErrorNone; | |
| 118 | } | |
| 119 | ||
| 120 | const char *msg = "stage0 called stage2_cpu_features_parse with non-null cpu name or features"; | |
| 121 | stage2_panic(msg, strlen(msg)); | |
| 122 | } | |
| 123 | ||
| 124 | void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features, | |
| 125 | const char **ptr, size_t *len) | |
| 126 | { | |
| 127 | *ptr = cpu_features->cache_hash; | |
| 128 | *len = strlen(cpu_features->cache_hash); | |
| 129 | } | |
| 130 | const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) { | |
| 131 | return cpu_features->llvm_cpu_name; | |
| 132 | } | |
| 133 | const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) { | |
| 134 | return cpu_features->llvm_cpu_features; | |
| 135 | } | |
| 136 | void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features, | |
| 137 | const char **ptr, size_t *len) | |
| 138 | { | |
| 139 | *ptr = cpu_features->builtin_str; | |
| 140 | *len = strlen(cpu_features->builtin_str); | |
| 141 | } | |
| 142 | ||
| 143 | int stage2_cmd_targets(const char *zig_triple) { | |
| 144 | const char *msg = "stage0 called stage2_cmd_targets"; | |
| 145 | stage2_panic(msg, strlen(msg)); | |
| 146 | } | |
| 147 | ||
| 148 | enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) { | |
| 149 | libc->include_dir = "/dummy/include"; | |
| 150 | libc->include_dir_len = strlen(libc->include_dir); | |
| 151 | libc->sys_include_dir = "/dummy/sys/include"; | |
| 152 | libc->sys_include_dir_len = strlen(libc->sys_include_dir); | |
| 153 | libc->crt_dir = ""; | |
| 154 | libc->crt_dir_len = strlen(libc->crt_dir); | |
| 155 | libc->static_crt_dir = ""; | |
| 156 | libc->static_crt_dir_len = strlen(libc->static_crt_dir); | |
| 157 | libc->msvc_lib_dir = ""; | |
| 158 | libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir); | |
| 159 | libc->kernel32_lib_dir = ""; | |
| 160 | libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir); | |
| 161 | return ErrorNone; | |
| 162 | } | |
| 163 | ||
| 164 | enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) { | |
| 165 | const char *msg = "stage0 called stage2_libc_render"; | |
| 166 | stage2_panic(msg, strlen(msg)); | |
| 167 | } | |
| 168 | ||
| 169 | enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { | |
| 170 | const char *msg = "stage0 called stage2_libc_find_native"; | |
| 171 | stage2_panic(msg, strlen(msg)); | |
| 172 | } | |
| 173 | ||
| 174 | enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 175 | const char *o_file, bool want_dirname) | |
| 176 | { | |
| 177 | const char *msg = "stage0 called stage2_libc_cc_print_file_name"; | |
| 178 | stage2_panic(msg, strlen(msg)); | |
| 179 | } |
src/userland.h deleted-248| ... | ... | @@ -1,248 +0,0 @@ |
| 1 | /* | |
| 2 | * Copyright (c) 2019 Andrew Kelley | |
| 3 | * | |
| 4 | * This file is part of zig, which is MIT licensed. | |
| 5 | * See http://opensource.org/licenses/MIT | |
| 6 | */ | |
| 7 | ||
| 8 | #ifndef ZIG_USERLAND_H | |
| 9 | #define ZIG_USERLAND_H | |
| 10 | ||
| 11 | #include <stddef.h> | |
| 12 | #include <stdint.h> | |
| 13 | #include <stdio.h> | |
| 14 | ||
| 15 | #ifdef __cplusplus | |
| 16 | #define ZIG_EXTERN_C extern "C" | |
| 17 | #else | |
| 18 | #define ZIG_EXTERN_C | |
| 19 | #endif | |
| 20 | ||
| 21 | #if defined(_MSC_VER) | |
| 22 | #define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn) | |
| 23 | #else | |
| 24 | #define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn)) | |
| 25 | #endif | |
| 26 | ||
| 27 | // ABI warning: the types and declarations in this file must match both those in | |
| 28 | // userland.cpp and src-self-hosted/stage1.zig. | |
| 29 | ||
| 30 | // ABI warning | |
| 31 | enum Error { | |
| 32 | ErrorNone, | |
| 33 | ErrorNoMem, | |
| 34 | ErrorInvalidFormat, | |
| 35 | ErrorSemanticAnalyzeFail, | |
| 36 | ErrorAccess, | |
| 37 | ErrorInterrupted, | |
| 38 | ErrorSystemResources, | |
| 39 | ErrorFileNotFound, | |
| 40 | ErrorFileSystem, | |
| 41 | ErrorFileTooBig, | |
| 42 | ErrorDivByZero, | |
| 43 | ErrorOverflow, | |
| 44 | ErrorPathAlreadyExists, | |
| 45 | ErrorUnexpected, | |
| 46 | ErrorExactDivRemainder, | |
| 47 | ErrorNegativeDenominator, | |
| 48 | ErrorShiftedOutOneBits, | |
| 49 | ErrorCCompileErrors, | |
| 50 | ErrorEndOfFile, | |
| 51 | ErrorIsDir, | |
| 52 | ErrorNotDir, | |
| 53 | ErrorUnsupportedOperatingSystem, | |
| 54 | ErrorSharingViolation, | |
| 55 | ErrorPipeBusy, | |
| 56 | ErrorPrimitiveTypeNotFound, | |
| 57 | ErrorCacheUnavailable, | |
| 58 | ErrorPathTooLong, | |
| 59 | ErrorCCompilerCannotFindFile, | |
| 60 | ErrorNoCCompilerInstalled, | |
| 61 | ErrorReadingDepFile, | |
| 62 | ErrorInvalidDepFile, | |
| 63 | ErrorMissingArchitecture, | |
| 64 | ErrorMissingOperatingSystem, | |
| 65 | ErrorUnknownArchitecture, | |
| 66 | ErrorUnknownOperatingSystem, | |
| 67 | ErrorUnknownABI, | |
| 68 | ErrorInvalidFilename, | |
| 69 | ErrorDiskQuota, | |
| 70 | ErrorDiskSpace, | |
| 71 | ErrorUnexpectedWriteFailure, | |
| 72 | ErrorUnexpectedSeekFailure, | |
| 73 | ErrorUnexpectedFileTruncationFailure, | |
| 74 | ErrorUnimplemented, | |
| 75 | ErrorOperationAborted, | |
| 76 | ErrorBrokenPipe, | |
| 77 | ErrorNoSpaceLeft, | |
| 78 | ErrorNotLazy, | |
| 79 | ErrorIsAsync, | |
| 80 | ErrorImportOutsidePkgPath, | |
| 81 | ErrorUnknownCpu, | |
| 82 | ErrorUnknownSubArchitecture, | |
| 83 | ErrorUnknownCpuFeature, | |
| 84 | ErrorInvalidCpuFeatures, | |
| 85 | ErrorInvalidLlvmCpuFeaturesFormat, | |
| 86 | ErrorUnknownApplicationBinaryInterface, | |
| 87 | ErrorASTUnitFailure, | |
| 88 | ErrorBadPathName, | |
| 89 | ErrorSymLinkLoop, | |
| 90 | ErrorProcessFdQuotaExceeded, | |
| 91 | ErrorSystemFdQuotaExceeded, | |
| 92 | ErrorNoDevice, | |
| 93 | ErrorDeviceBusy, | |
| 94 | ErrorUnableToSpawnCCompiler, | |
| 95 | ErrorCCompilerExitCode, | |
| 96 | ErrorCCompilerCrashed, | |
| 97 | ErrorCCompilerCannotFindHeaders, | |
| 98 | ErrorLibCRuntimeNotFound, | |
| 99 | ErrorLibCStdLibHeaderNotFound, | |
| 100 | ErrorLibCKernel32LibNotFound, | |
| 101 | ErrorUnsupportedArchitecture, | |
| 102 | }; | |
| 103 | ||
| 104 | // ABI warning | |
| 105 | struct Stage2ErrorMsg { | |
| 106 | const char *filename_ptr; // can be null | |
| 107 | size_t filename_len; | |
| 108 | const char *msg_ptr; | |
| 109 | size_t msg_len; | |
| 110 | const char *source; // valid until the ASTUnit is freed. can be null | |
| 111 | unsigned line; // 0 based | |
| 112 | unsigned column; // 0 based | |
| 113 | unsigned offset; // byte offset into source | |
| 114 | }; | |
| 115 | ||
| 116 | // ABI warning | |
| 117 | struct Stage2Ast; | |
| 118 | ||
| 119 | // ABI warning | |
| 120 | ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast, | |
| 121 | struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len, | |
| 122 | const char **args_begin, const char **args_end, const char *resources_path); | |
| 123 | ||
| 124 | // ABI warning | |
| 125 | ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len); | |
| 126 | ||
| 127 | // ABI warning | |
| 128 | ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file); | |
| 129 | ||
| 130 | // ABI warning | |
| 131 | ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len); | |
| 132 | ||
| 133 | // ABI warning | |
| 134 | ZIG_EXTERN_C void stage2_attach_segfault_handler(void); | |
| 135 | ||
| 136 | // ABI warning | |
| 137 | ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len); | |
| 138 | ||
| 139 | // ABI warning | |
| 140 | ZIG_EXTERN_C int stage2_fmt(int argc, char **argv); | |
| 141 | ||
| 142 | // ABI warning | |
| 143 | struct stage2_DepTokenizer { | |
| 144 | void *handle; | |
| 145 | }; | |
| 146 | ||
| 147 | // ABI warning | |
| 148 | struct stage2_DepNextResult { | |
| 149 | enum TypeId { | |
| 150 | error, | |
| 151 | null, | |
| 152 | target, | |
| 153 | prereq, | |
| 154 | }; | |
| 155 | ||
| 156 | TypeId type_id; | |
| 157 | ||
| 158 | // when ent == error --> error text | |
| 159 | // when ent == null --> undefined | |
| 160 | // when ent == target --> target pathname | |
| 161 | // when ent == prereq --> prereq pathname | |
| 162 | const char *textz; | |
| 163 | }; | |
| 164 | ||
| 165 | // ABI warning | |
| 166 | ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len); | |
| 167 | ||
| 168 | // ABI warning | |
| 169 | ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self); | |
| 170 | ||
| 171 | // ABI warning | |
| 172 | ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self); | |
| 173 | ||
| 174 | // ABI warning | |
| 175 | struct Stage2Progress; | |
| 176 | // ABI warning | |
| 177 | struct Stage2ProgressNode; | |
| 178 | // ABI warning | |
| 179 | ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void); | |
| 180 | // ABI warning | |
| 181 | ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress); | |
| 182 | // ABI warning | |
| 183 | ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress); | |
| 184 | // ABI warning | |
| 185 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress, | |
| 186 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 187 | // ABI warning | |
| 188 | ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node, | |
| 189 | const char *name_ptr, size_t name_len, size_t estimated_total_items); | |
| 190 | // ABI warning | |
| 191 | ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node); | |
| 192 | // ABI warning | |
| 193 | ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node); | |
| 194 | // ABI warning | |
| 195 | ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node, | |
| 196 | size_t completed_count, size_t estimated_total_items); | |
| 197 | ||
| 198 | // ABI warning | |
| 199 | struct Stage2CpuFeatures; | |
| 200 | ||
| 201 | // ABI warning | |
| 202 | ZIG_EXTERN_C enum Error stage2_cpu_features_parse(struct Stage2CpuFeatures **result, | |
| 203 | const char *zig_triple, const char *cpu_name, const char *cpu_features); | |
| 204 | ||
| 205 | // ABI warning | |
| 206 | ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const struct Stage2CpuFeatures *cpu_features); | |
| 207 | ||
| 208 | // ABI warning | |
| 209 | ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const struct Stage2CpuFeatures *cpu_features); | |
| 210 | ||
| 211 | // ABI warning | |
| 212 | ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const struct Stage2CpuFeatures *cpu_features, | |
| 213 | const char **ptr, size_t *len); | |
| 214 | ||
| 215 | // ABI warning | |
| 216 | ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatures *cpu_features, | |
| 217 | const char **ptr, size_t *len); | |
| 218 | ||
| 219 | // ABI warning | |
| 220 | ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple); | |
| 221 | ||
| 222 | // ABI warning | |
| 223 | struct Stage2LibCInstallation { | |
| 224 | const char *include_dir; | |
| 225 | size_t include_dir_len; | |
| 226 | const char *sys_include_dir; | |
| 227 | size_t sys_include_dir_len; | |
| 228 | const char *crt_dir; | |
| 229 | size_t crt_dir_len; | |
| 230 | const char *static_crt_dir; | |
| 231 | size_t static_crt_dir_len; | |
| 232 | const char *msvc_lib_dir; | |
| 233 | size_t msvc_lib_dir_len; | |
| 234 | const char *kernel32_lib_dir; | |
| 235 | size_t kernel32_lib_dir_len; | |
| 236 | }; | |
| 237 | ||
| 238 | // ABI warning | |
| 239 | ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file); | |
| 240 | // ABI warning | |
| 241 | ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file); | |
| 242 | // ABI warning | |
| 243 | ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc); | |
| 244 | // ABI warning | |
| 245 | ZIG_EXTERN_C enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 246 | const char *o_file, bool want_dirname); | |
| 247 | ||
| 248 | #endif |
src/util.cpp+1-1| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | #include "util.hpp" |
| 9 | #include "userland.h" | |
| 9 | #include "stage2.h" | |
| 10 | 10 | |
| 11 | 11 | #include <stdio.h> |
| 12 | 12 | #include <stdarg.h> |
src/zig_clang.h+1-1| ... | ... | @@ -8,7 +8,7 @@ |
| 8 | 8 | #ifndef ZIG_ZIG_CLANG_H |
| 9 | 9 | #define ZIG_ZIG_CLANG_H |
| 10 | 10 | |
| 11 | #include "userland.h" | |
| 11 | #include "stage2.h" | |
| 12 | 12 | #include <inttypes.h> |
| 13 | 13 | #include <stdbool.h> |
| 14 | 14 |