authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 16:30:40-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 16:30:40-05:00
logf33bf48af7d9c99d532864f8a6c3f695ad5bbd21
treefa39bd6b654178e653d06e1c79f22ad1d29cd526
parent64365bc5d7b1e2c507806ee8976acc3479ad7862
parent416a547cdb8dbbf3d2e7ce32132f0a25f2a8607e
signaturelock-open Commit is signed but in an unrecognized format.

Merge remote-tracking branch 'origin/master' into llvm10


173 files changed, 8079 insertions(+), 8445 deletions(-)

CMakeLists.txt+59-39
......@@ -240,8 +240,8 @@ find_package(Threads)
240240# CMake doesn't let us create an empty executable, so we hang on to this one separately.
241241set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
242242
243# This is our shim which will be replaced by libuserland written in Zig.
244set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
243# This is our shim which will be replaced by libstage2 written in Zig.
244set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/stage2.cpp")
245245
246246if(ZIG_ENABLE_MEM_PROFILE)
247247 set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp")
......@@ -263,7 +263,6 @@ set(ZIG_SOURCES
263263 "${CMAKE_SOURCE_DIR}/src/heap.cpp"
264264 "${CMAKE_SOURCE_DIR}/src/ir.cpp"
265265 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
266 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
267266 "${CMAKE_SOURCE_DIR}/src/link.cpp"
268267 "${CMAKE_SOURCE_DIR}/src/mem.cpp"
269268 "${CMAKE_SOURCE_DIR}/src/os.cpp"
......@@ -377,27 +376,27 @@ set_target_properties(opt_c_util PROPERTIES
377376 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
378377)
379378
380add_library(compiler STATIC ${ZIG_SOURCES})
381set_target_properties(compiler PROPERTIES
379add_library(zigcompiler STATIC ${ZIG_SOURCES})
380set_target_properties(zigcompiler PROPERTIES
382381 COMPILE_FLAGS ${EXE_CFLAGS}
383382 LINK_FLAGS ${EXE_LDFLAGS}
384383)
385target_link_libraries(compiler LINK_PUBLIC
384target_link_libraries(zigcompiler LINK_PUBLIC
386385 zig_cpp
387386 opt_c_util
388387 ${SOFTFLOAT_LIBRARIES}
389388 ${CMAKE_THREAD_LIBS_INIT}
390389)
391390if(NOT MSVC)
392 target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
391 target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
393392endif()
394393
395394if(ZIG_DIA_GUIDS_LIB)
396 target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
395 target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
397396endif()
398397
399398if(MSVC OR MINGW)
400 target_link_libraries(compiler LINK_PUBLIC version)
399 target_link_libraries(zigcompiler LINK_PUBLIC version)
401400endif()
402401
403402add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
......@@ -405,40 +404,43 @@ set_target_properties(zig0 PROPERTIES
405404 COMPILE_FLAGS ${EXE_CFLAGS}
406405 LINK_FLAGS ${EXE_LDFLAGS}
407406)
408target_link_libraries(zig0 compiler)
407target_link_libraries(zig0 zigcompiler)
409408
410409if(MSVC)
411 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib")
410 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib")
412411else()
413 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a")
412 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a")
414413endif()
415414if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
416 set(LIBUSERLAND_RELEASE_MODE "false")
415 set(LIBSTAGE2_RELEASE_ARG "")
417416else()
418 set(LIBUSERLAND_RELEASE_MODE "true")
417 set(LIBSTAGE2_RELEASE_ARG --release-fast --strip)
418endif()
419if(WIN32)
420 set(LIBSTAGE2_WINDOWS_ARGS "-lntdll")
421else()
422 set(LIBSTAGE2_WINDOWS_ARGS "")
419423endif()
420424
421set(BUILD_LIBUSERLAND_ARGS "build"
425set(BUILD_LIBSTAGE2_ARGS "build-lib"
426 "src-self-hosted/stage2.zig"
427 -mcpu=baseline
428 --name zigstage2
422429 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
423 "-Doutput-dir=${CMAKE_BINARY_DIR}"
424 "-Drelease=${LIBUSERLAND_RELEASE_MODE}"
425 "-Dlib-files-only"
426 --prefix "${CMAKE_INSTALL_PREFIX}"
427 libuserland
430 --cache on
431 --output-dir "${CMAKE_BINARY_DIR}"
432 ${LIBSTAGE2_RELEASE_ARG}
433 --disable-gen-h
434 --bundle-compiler-rt
435 -fPIC
436 -lc
437 ${LIBSTAGE2_WINDOWS_ARGS}
428438)
429439
430# When using Visual Studio build system generator we default to libuserland install.
431if(MSVC)
432 set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL "Disable copying lib/ files to install prefix")
433 if(NOT ZIG_SKIP_INSTALL_LIB_FILES)
434 set(BUILD_LIBUSERLAND_ARGS ${BUILD_LIBUSERLAND_ARGS} install)
435 endif()
436endif()
437
438add_custom_target(zig_build_libuserland ALL
439 COMMAND zig0 ${BUILD_LIBUSERLAND_ARGS}
440add_custom_target(zig_build_libstage2 ALL
441 COMMAND zig0 ${BUILD_LIBSTAGE2_ARGS}
440442 DEPENDS zig0
441 BYPRODUCTS "${LIBUSERLAND}"
443 BYPRODUCTS "${LIBSTAGE2}"
442444 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
443445)
444446add_executable(zig "${ZIG_MAIN_SRC}")
......@@ -447,22 +449,40 @@ set_target_properties(zig PROPERTIES
447449 COMPILE_FLAGS ${EXE_CFLAGS}
448450 LINK_FLAGS ${EXE_LDFLAGS}
449451)
450target_link_libraries(zig compiler "${LIBUSERLAND}")
452target_link_libraries(zig zigcompiler "${LIBSTAGE2}")
451453if(MSVC)
452454 target_link_libraries(zig ntdll.lib)
453455elseif(MINGW)
454456 target_link_libraries(zig ntdll)
455457endif()
456add_dependencies(zig zig_build_libuserland)
458add_dependencies(zig zig_build_libstage2)
457459
458460install(TARGETS zig DESTINATION bin)
459461
460# CODE has no effect with Visual Studio build system generator.
461if(NOT MSVC)
462 get_target_property(zig0_BINARY_DIR zig0 BINARY_DIR)
463 install(CODE "set(zig0_EXE \"${zig0_BINARY_DIR}/zig0\")")
464 install(CODE "set(INSTALL_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\" install)")
465 install(CODE "set(BUILD_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\")")
462set(ZIG_INSTALL_ARGS "build"
463 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
464 "-Dlib-files-only"
465 --prefix "${CMAKE_INSTALL_PREFIX}"
466 install
467)
468
469# CODE has no effect with Visual Studio build system generator, therefore
470# when using Visual Studio build system generator we resort to running
471# `zig build install` during the build phase.
472if(MSVC)
473 set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL
474 "Windows-only: Disable copying lib/ files to install prefix during the build phase")
475 if(NOT ZIG_SKIP_INSTALL_LIB_FILES)
476 add_custom_target(zig_install_lib_files ALL
477 COMMAND zig ${ZIG_INSTALL_ARGS}
478 DEPENDS zig
479 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
480 )
481 endif()
482else()
483 get_target_property(zig_BINARY_DIR zig BINARY_DIR)
484 install(CODE "set(zig_EXE \"${zig_BINARY_DIR}/zig\")")
485 install(CODE "set(ZIG_INSTALL_ARGS \"${ZIG_INSTALL_ARGS}\")")
466486 install(CODE "set(CMAKE_SOURCE_DIR \"${CMAKE_SOURCE_DIR}\")")
467487 install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install.cmake)
468488endif()
build.zig+1-28
......@@ -65,8 +65,6 @@ pub fn build(b: *Builder) !void {
6565 try configureStage2(b, test_stage2, ctx);
6666 try configureStage2(b, exe, ctx);
6767
68 addLibUserlandStep(b, mode);
69
7068 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
7169 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
7270 const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;
......@@ -176,7 +174,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
176174}
177175
178176fn fileExists(filename: []const u8) !bool {
179 fs.File.access(filename) catch |err| switch (err) {
177 fs.cwd().access(filename, .{}) catch |err| switch (err) {
180178 error.FileNotFound => return false,
181179 else => return err,
182180 };
......@@ -379,28 +377,3 @@ const Context = struct {
379377 dia_guids_lib: []const u8,
380378 llvm: LibraryDep,
381379};
382
383fn addLibUserlandStep(b: *Builder, mode: builtin.Mode) void {
384 const artifact = b.addStaticLibrary("userland", "src-self-hosted/stage1.zig");
385 artifact.disable_gen_h = true;
386 artifact.bundle_compiler_rt = true;
387 artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
388 artifact.setBuildMode(mode);
389 artifact.force_pic = true;
390 if (mode != .Debug) {
391 artifact.strip = true;
392 }
393 artifact.linkSystemLibrary("c");
394 if (builtin.os == .windows) {
395 artifact.linkSystemLibrary("ntdll");
396 }
397 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");
398 libuserland_step.dependOn(&artifact.step);
399
400 const output_dir = b.option(
401 []const u8,
402 "output-dir",
403 "For libuserland step, where to put the output",
404 ) orelse return;
405 artifact.setOutputDir(output_dir);
406}
ci/srht/freebsd_script+7-24
......@@ -34,38 +34,21 @@ release/bin/zig build test-behavior
3434# release/bin/zig build test-std
3535
3636release/bin/zig build test-compiler-rt
37
38# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
39# See https://github.com/ziglang/zig/issues/3210
40# release/bin/zig build test-compare-output
41
42# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
43# See https://github.com/ziglang/zig/issues/3210
44# release/bin/zig build test-standalone
45
37release/bin/zig build test-compare-output
38release/bin/zig build test-standalone
4639release/bin/zig build test-stack-traces
4740release/bin/zig build test-cli
4841release/bin/zig build test-asm-link
4942release/bin/zig build test-runtime-safety
50
51# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
52# See https://github.com/ziglang/zig/issues/3210
53# release/bin/zig build test-translate-c
54
43release/bin/zig build test-translate-c
44release/bin/zig build test-run-translated-c
5545release/bin/zig build test-gen-h
56
57# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
58# See https://github.com/ziglang/zig/issues/3210
59# release/bin/zig build test-compile-errors
60
61# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
62# See https://github.com/ziglang/zig/issues/3210
63# release/bin/zig build docs
46release/bin/zig build test-compile-errors
47release/bin/zig build docs
6448
6549if [ -f ~/.s3cfg ]; then
6650 mv ../LICENSE release/
67 # Enable when `release/bin/zig build docs` passes without "out of memory" or failures
68 #mv ../zig-cache/langref.html release/
51 mv ../zig-cache/langref.html release/
6952 mv release/bin/zig release/
7053 rmdir release/bin
7154
cmake/install.cmake+6-6
......@@ -1,16 +1,16 @@
11message("-- Installing: ${CMAKE_INSTALL_PREFIX}/lib")
22
3if(NOT EXISTS ${zig0_EXE})
3if(NOT EXISTS ${zig_EXE})
44 message("::")
55 message(":: ERROR: Executable not found")
66 message(":: (execute_process)")
77 message("::")
8 message(":: executable: ${zig0_EXE}")
8 message(":: executable: ${zig_EXE}")
99 message("::")
1010 message(FATAL_ERROR)
1111endif()
1212
13execute_process(COMMAND ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS}
13execute_process(COMMAND ${zig_EXE} ${ZIG_INSTALL_ARGS}
1414 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
1515 RESULT_VARIABLE _result
1616)
......@@ -19,11 +19,11 @@ if(_result)
1919 message(":: ERROR: ${_result}")
2020 message(":: (execute_process)")
2121
22 string(REPLACE ";" " " s_INSTALL_LIBUSERLAND_ARGS "${INSTALL_LIBUSERLAND_ARGS}")
22 string(REPLACE ";" " " s_INSTALL_LIBSTAGE2_ARGS "${ZIG_INSTALL_ARGS}")
2323 message("::")
24 message(":: argv: ${zig0_EXE} ${s_INSTALL_LIBUSERLAND_ARGS} install")
24 message(":: argv: ${zig_EXE} ${s_INSTALL_LIBSTAGE2_ARGS}")
2525
26 set(_args ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS})
26 set(_args ${zig_EXE} ${ZIG_INSTALL_ARGS})
2727 list(LENGTH _args _len)
2828 math(EXPR _len "${_len} - 1")
2929 message("::")
doc/langref.html.in+23-153
......@@ -550,7 +550,7 @@ pub fn main() void {
550550 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
551551 integer type is {#syntax#}65535{#endsyntax#}.
552552 </p>
553 {#see_also|Integers|Floats|void|Errors|@IntType#}
553 {#see_also|Integers|Floats|void|Errors|@Type#}
554554 {#header_close#}
555555 {#header_open|Primitive Values#}
556556 <div class="table-wrapper">
......@@ -2025,7 +2025,8 @@ test "volatile" {
20252025 conversions are not possible.
20262026 </p>
20272027 {#code_begin|test#}
2028const assert = @import("std").debug.assert;
2028const std = @import("std");
2029const assert = std.debug.assert;
20292030
20302031test "pointer casting" {
20312032 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };
......@@ -2034,7 +2035,7 @@ test "pointer casting" {
20342035
20352036 // Even this example is contrived - there are better ways to do the above than
20362037 // pointer casting. For example, using a slice narrowing cast:
2037 const u32_value = @bytesToSlice(u32, bytes[0..])[0];
2038 const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0];
20382039 assert(u32_value == 0x12121212);
20392040
20402041 // And even another way, the most straightforward way to do it:
......@@ -2114,16 +2115,16 @@ test "function alignment" {
21142115 {#link|safety check|Incorrect Pointer Alignment#}:
21152116 </p>
21162117 {#code_begin|test_safety|incorrect alignment#}
2117const assert = @import("std").debug.assert;
2118const std = @import("std");
21182119
21192120test "pointer alignment safety" {
21202121 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
2121 const bytes = @sliceToBytes(array[0..]);
2122 assert(foo(bytes) == 0x11111111);
2122 const bytes = std.mem.sliceAsBytes(array[0..]);
2123 std.debug.assert(foo(bytes) == 0x11111111);
21232124}
21242125fn foo(bytes: []u8) u32 {
21252126 const slice4 = bytes[1..5];
2126 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
2127 const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
21272128 return int_slice[0];
21282129}
21292130 {#code_end#}
......@@ -2249,7 +2250,7 @@ test "slice widening" {
22492250 // Zig supports slice widening and slice narrowing. Cast a slice of u8
22502251 // to a slice of anything else, and Zig will perform the length conversion.
22512252 const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };
2252 const slice = @bytesToSlice(u32, array[0..]);
2253 const slice = mem.bytesAsSlice(u32, array[0..]);
22532254 assert(slice.len == 2);
22542255 assert(slice[0] == 0x12121212);
22552256 assert(slice[1] == 0x13131313);
......@@ -2809,14 +2810,10 @@ test "@TagType" {
28092810 assert(@TagType(Small) == u2);
28102811}
28112812
2812// @memberCount tells how many fields an enum has:
2813test "@memberCount" {
2814 assert(@memberCount(Small) == 4);
2815}
2816
2817// @memberName tells the name of a field in an enum:
2818test "@memberName" {
2819 assert(mem.eql(u8, @memberName(Small, 1), "Two"));
2813// @typeInfo tells us the field count and the fields names:
2814test "@typeInfo" {
2815 assert(@typeInfo(Small).Enum.fields.len == 4);
2816 assert(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "Two"));
28202817}
28212818
28222819// @tagName gives a []const u8 representation of an enum value:
......@@ -2824,7 +2821,7 @@ test "@tagName" {
28242821 assert(mem.eql(u8, @tagName(Small.Three), "Three"));
28252822}
28262823 {#code_end#}
2827 {#see_also|@memberName|@memberCount|@tagName|@sizeOf#}
2824 {#see_also|@typeInfo|@tagName|@sizeOf#}
28282825
28292826 {#header_open|extern enum#}
28302827 <p>
......@@ -5186,7 +5183,6 @@ test "coercion of zero bit types" {
51865183 <li>{#link|@bitCast#} - change type but maintain bit representation</li>
51875184 <li>{#link|@alignCast#} - make a pointer have more alignment</li>
51885185 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li>
5189 <li>{#link|@bytesToSlice#} - convert a slice of bytes to a slice of another type</li>
51905186 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li>
51915187 <li>{#link|@errSetCast#} - convert to a smaller error set</li>
51925188 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li>
......@@ -5199,7 +5195,6 @@ test "coercion of zero bit types" {
51995195 <li>{#link|@intToPtr#} - convert an address to a pointer</li>
52005196 <li>{#link|@ptrCast#} - convert between pointer types</li>
52015197 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li>
5202 <li>{#link|@sliceToBytes#} - convert a slice of anything to a slice of bytes</li>
52035198 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li>
52045199 </ul>
52055200 {#header_close#}
......@@ -6672,18 +6667,6 @@ comptime {
66726667 </p>
66736668 {#see_also|Alignment#}
66746669 {#header_close#}
6675 {#header_open|@ArgType#}
6676 <pre>{#syntax#}@ArgType(comptime T: type, comptime n: usize) type{#endsyntax#}</pre>
6677 <p>
6678 This builtin function takes a function type and returns the type of the parameter at index {#syntax#}n{#endsyntax#}.
6679 </p>
6680 <p>
6681 {#syntax#}T{#endsyntax#} must be a function type.
6682 </p>
6683 <p>
6684 Note: This function is deprecated. Use {#link|@typeInfo#} instead.
6685 </p>
6686 {#header_close#}
66876670
66886671 {#header_open|@as#}
66896672 <pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre>
......@@ -6817,7 +6800,7 @@ async fn func(y: *i32) void {
68176800 Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.
68186801 </p>
68196802 <p>
6820 Asserts that {#syntax#}@typeId(DestType) != @import("builtin").TypeId.Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this.
6803 Asserts that {#syntax#}@typeInfo(DestType) != .Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this.
68216804 </p>
68226805 <p>
68236806 Can be used for these things for example:
......@@ -6929,18 +6912,6 @@ async fn func(y: *i32) void {
69296912 {#see_also|@bitOffsetOf#}
69306913 {#header_close#}
69316914
6932 {#header_open|@bytesToSlice#}
6933 <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre>
6934 <p>
6935 Converts a slice of bytes or array of bytes into a slice of {#syntax#}Element{#endsyntax#}.
6936 The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter.
6937 </p>
6938 <p>
6939 Attempting to convert a number of bytes with a length that does not evenly divide into a slice of
6940 elements results in safety-protected {#link|Undefined Behavior#}.
6941 </p>
6942 {#header_close#}
6943
69446915 {#header_open|@call#}
69456916 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>
69466917 <p>
......@@ -7248,7 +7219,7 @@ test "main" {
72487219 <p>
72497220 Floored division. Rounds toward negative infinity. For unsigned integers it is
72507221 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and
7251 {#syntax#}!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
7222 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
72527223 </p>
72537224 <ul>
72547225 <li>{#syntax#}@divFloor(-5, 3) == -2{#endsyntax#}</li>
......@@ -7262,7 +7233,7 @@ test "main" {
72627233 <p>
72637234 Truncated division. Rounds toward zero. For unsigned integers it is
72647235 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and
7265 {#syntax#}!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
7236 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
72667237 </p>
72677238 <ul>
72687239 <li>{#syntax#}@divTrunc(-5, 3) == -1{#endsyntax#}</li>
......@@ -7320,7 +7291,7 @@ test "main" {
73207291 {#header_close#}
73217292
73227293 {#header_open|@errorToInt#}
7323 <pre>{#syntax#}@errorToInt(err: var) @IntType(false, @sizeOf(anyerror) * 8){#endsyntax#}</pre>
7294 <pre>{#syntax#}@errorToInt(err: var) std.meta.IntType(false, @sizeOf(anyerror) * 8){#endsyntax#}</pre>
73247295 <p>
73257296 Supports the following types:
73267297 </p>
......@@ -7365,7 +7336,7 @@ comptime {
73657336 @export(internalName, .{ .name = "foo", .linkage = .Strong });
73667337}
73677338
7368extern fn internalName() void {}
7339fn internalName() callconv(.C) void {}
73697340 {#code_end#}
73707341 <p>This is equivalent to:</p>
73717342 {#code_begin|obj#}
......@@ -7614,7 +7585,7 @@ test "@hasDecl" {
76147585 {#header_close#}
76157586
76167587 {#header_open|@intToError#}
7617 <pre>{#syntax#}@intToError(value: @IntType(false, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>
7588 <pre>{#syntax#}@intToError(value: std.meta.IntType(false, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>
76187589 <p>
76197590 Converts from the integer representation of an error into {#link|The Global Error Set#} type.
76207591 </p>
......@@ -7647,44 +7618,6 @@ test "@hasDecl" {
76477618 </p>
76487619 {#header_close#}
76497620
7650 {#header_open|@IntType#}
7651 <pre>{#syntax#}@IntType(comptime is_signed: bool, comptime bit_count: u16) type{#endsyntax#}</pre>
7652 <p>
7653 This function returns an integer type with the given signness and bit count. The maximum
7654 bit count for an integer type is {#syntax#}65535{#endsyntax#}.
7655 </p>
7656 <p>
7657 Deprecated. Use {#link|@Type#}.
7658 </p>
7659 {#header_close#}
7660
7661 {#header_open|@memberCount#}
7662 <pre>{#syntax#}@memberCount(comptime T: type) comptime_int{#endsyntax#}</pre>
7663 <p>
7664 This function returns the number of members in a struct, enum, or union type.
7665 </p>
7666 <p>
7667 The result is a compile time constant.
7668 </p>
7669 <p>
7670 It does not include functions, variables, or constants.
7671 </p>
7672 {#header_close#}
7673 {#header_open|@memberName#}
7674 <pre>{#syntax#}@memberName(comptime T: type, comptime index: usize) [N]u8{#endsyntax#}</pre>
7675 <p>Returns the field name of a struct, union, or enum.</p>
7676 <p>
7677 The result is a compile time constant.
7678 </p>
7679 <p>
7680 It does not include functions, variables, or constants.
7681 </p>
7682 {#header_close#}
7683 {#header_open|@memberType#}
7684 <pre>{#syntax#}@memberType(comptime T: type, comptime index: usize) type{#endsyntax#}</pre>
7685 <p>Returns the field type of a struct or union.</p>
7686 {#header_close#}
7687
76887621 {#header_open|@memcpy#}
76897622 <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}</pre>
76907623 <p>
......@@ -8067,14 +8000,6 @@ test "@setRuntimeSafety" {
80678000 {#see_also|@bitSizeOf|@typeInfo#}
80688001 {#header_close#}
80698002
8070 {#header_open|@sliceToBytes#}
8071 <pre>{#syntax#}@sliceToBytes(value: var) []u8{#endsyntax#}</pre>
8072 <p>
8073 Converts a slice or array to a slice of {#syntax#}u8{#endsyntax#}. The resulting slice has the same
8074 {#link|pointer|Pointers#} properties as the parameter.
8075 </p>
8076 {#header_close#}
8077
80788003 {#header_open|@splat#}
80798004 <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>
80808005 <p>
......@@ -8388,43 +8313,6 @@ test "integer truncation" {
83888313 <li>{#link|struct#}</li>
83898314 </ul>
83908315 {#header_close#}
8391
8392 {#header_open|@typeId#}
8393 <pre>{#syntax#}@typeId(comptime T: type) @import("builtin").TypeId{#endsyntax#}</pre>
8394 <p>
8395 Returns which kind of type something is. Possible values:
8396 </p>
8397 {#code_begin|syntax#}
8398pub const TypeId = enum {
8399 Type,
8400 Void,
8401 Bool,
8402 NoReturn,
8403 Int,
8404 Float,
8405 Pointer,
8406 Array,
8407 Struct,
8408 ComptimeFloat,
8409 ComptimeInt,
8410 Undefined,
8411 Null,
8412 Optional,
8413 ErrorUnion,
8414 ErrorSet,
8415 Enum,
8416 Union,
8417 Fn,
8418 BoundFn,
8419 Opaque,
8420 Frame,
8421 AnyFrame,
8422 Vector,
8423 EnumLiteral,
8424};
8425 {#code_end#}
8426 {#header_close#}
8427
84288316 {#header_open|@typeInfo#}
84298317 <pre>{#syntax#}@typeInfo(comptime T: type) @import("std").builtin.TypeInfo{#endsyntax#}</pre>
84308318 <p>
......@@ -8885,25 +8773,6 @@ pub fn main() void {
88858773 var b: u32 = 3;
88868774 var c = @divExact(a, b);
88878775 std.debug.warn("value: {}\n", .{c});
8888}
8889 {#code_end#}
8890 {#header_close#}
8891 {#header_open|Slice Widen Remainder#}
8892 <p>At compile-time:</p>
8893 {#code_begin|test_err|unable to convert#}
8894comptime {
8895 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8896 var slice = @bytesToSlice(u32, bytes[0..]);
8897}
8898 {#code_end#}
8899 <p>At runtime:</p>
8900 {#code_begin|exe_err#}
8901const std = @import("std");
8902
8903pub fn main() void {
8904 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8905 var slice = @bytesToSlice(u32, bytes[0..]);
8906 std.debug.warn("value: {}\n", .{slice[0]});
89078776}
89088777 {#code_end#}
89098778 {#header_close#}
......@@ -9085,14 +8954,15 @@ comptime {
90858954 {#code_end#}
90868955 <p>At runtime:</p>
90878956 {#code_begin|exe_err#}
8957const mem = @import("std").mem;
90888958pub fn main() !void {
90898959 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
9090 const bytes = @sliceToBytes(array[0..]);
8960 const bytes = mem.sliceAsBytes(array[0..]);
90918961 if (foo(bytes) != 0x11111111) return error.Wrong;
90928962}
90938963fn foo(bytes: []u8) u32 {
90948964 const slice4 = bytes[1..5];
9095 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
8965 const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4));
90968966 return int_slice[0];
90978967}
90988968 {#code_end#}
lib/std/array_list.zig+25
......@@ -188,6 +188,14 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
188188 self.len += items.len;
189189 }
190190
191 /// Append a value to the list `n` times. Allocates more memory
192 /// as necessary.
193 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
194 const old_len = self.len;
195 try self.resize(self.len + n);
196 mem.set(T, self.items[old_len..self.len], value);
197 }
198
191199 /// Adjust the list's length to `new_len`. Doesn't initialize
192200 /// added items if any.
193201 pub fn resize(self: *Self, new_len: usize) !void {
......@@ -311,6 +319,23 @@ test "std.ArrayList.basic" {
311319 testing.expect(list.pop() == 33);
312320}
313321
322test "std.ArrayList.appendNTimes" {
323 var list = ArrayList(i32).init(testing.allocator);
324 defer list.deinit();
325
326 try list.appendNTimes(2, 10);
327 testing.expectEqual(@as(usize, 10), list.len);
328 for (list.toSlice()) |element| {
329 testing.expectEqual(@as(i32, 2), element);
330 }
331}
332
333test "std.ArrayList.appendNTimes with failing allocator" {
334 var list = ArrayList(i32).init(testing.failing_allocator);
335 defer list.deinit();
336 testing.expectError(error.OutOfMemory, list.appendNTimes(2, 10));
337}
338
314339test "std.ArrayList.orderedRemove" {
315340 var list = ArrayList(i32).init(testing.allocator);
316341 defer list.deinit();
lib/std/buffer.zig+12
......@@ -147,6 +147,10 @@ pub const Buffer = struct {
147147 try self.resize(m.len);
148148 mem.copy(u8, self.list.toSlice(), m);
149149 }
150
151 pub fn print(self: *Buffer, comptime fmt: []const u8, args: var) !void {
152 return std.fmt.format(self, error{OutOfMemory}, Buffer.append, fmt, args);
153 }
150154};
151155
152156test "simple Buffer" {
......@@ -190,3 +194,11 @@ test "Buffer.initCapacity" {
190194 testing.expect(buf.capacity() == old_cap);
191195 testing.expect(mem.eql(u8, buf.toSliceConst(), "hello"));
192196}
197
198test "Buffer.print" {
199 var buf = try Buffer.init(testing.allocator, "");
200 defer buf.deinit();
201
202 try buf.print("Hello {} the {}", .{ 2, "world" });
203 testing.expect(buf.eql("Hello 2 the world"));
204}
lib/std/build.zig+35-158
......@@ -27,9 +27,6 @@ pub const Builder = struct {
2727 install_tls: TopLevelStep,
2828 uninstall_tls: TopLevelStep,
2929 allocator: *Allocator,
30 native_system_lib_paths: ArrayList([]const u8),
31 native_system_include_dirs: ArrayList([]const u8),
32 native_system_rpaths: ArrayList([]const u8),
3330 user_input_options: UserInputOptionsMap,
3431 available_options_map: AvailableOptionsMap,
3532 available_options_list: ArrayList(AvailableOption),
......@@ -41,6 +38,7 @@ pub const Builder = struct {
4138 verbose_ir: bool,
4239 verbose_llvm_ir: bool,
4340 verbose_cimport: bool,
41 verbose_llvm_cpu_features: bool,
4442 invalid_user_input: bool,
4543 zig_exe: []const u8,
4644 default_step: *Step,
......@@ -137,11 +135,9 @@ pub const Builder = struct {
137135 .verbose_ir = false,
138136 .verbose_llvm_ir = false,
139137 .verbose_cimport = false,
138 .verbose_llvm_cpu_features = false,
140139 .invalid_user_input = false,
141140 .allocator = allocator,
142 .native_system_lib_paths = ArrayList([]const u8).init(allocator),
143 .native_system_include_dirs = ArrayList([]const u8).init(allocator),
144 .native_system_rpaths = ArrayList([]const u8).init(allocator),
145141 .user_input_options = UserInputOptionsMap.init(allocator),
146142 .available_options_map = AvailableOptionsMap.init(allocator),
147143 .available_options_list = ArrayList(AvailableOption).init(allocator),
......@@ -172,15 +168,11 @@ pub const Builder = struct {
172168 };
173169 try self.top_level_steps.append(&self.install_tls);
174170 try self.top_level_steps.append(&self.uninstall_tls);
175 self.detectNativeSystemPaths();
176171 self.default_step = &self.install_tls.step;
177172 return self;
178173 }
179174
180175 pub fn destroy(self: *Builder) void {
181 self.native_system_lib_paths.deinit();
182 self.native_system_include_dirs.deinit();
183 self.native_system_rpaths.deinit();
184176 self.env_map.deinit();
185177 self.top_level_steps.deinit();
186178 self.allocator.destroy(self);
......@@ -347,18 +339,6 @@ pub const Builder = struct {
347339 };
348340 }
349341
350 pub fn addNativeSystemIncludeDir(self: *Builder, path: []const u8) void {
351 self.native_system_include_dirs.append(path) catch unreachable;
352 }
353
354 pub fn addNativeSystemRPath(self: *Builder, path: []const u8) void {
355 self.native_system_rpaths.append(path) catch unreachable;
356 }
357
358 pub fn addNativeSystemLibPath(self: *Builder, path: []const u8) void {
359 self.native_system_lib_paths.append(path) catch unreachable;
360 }
361
362342 pub fn make(self: *Builder, step_names: []const []const u8) !void {
363343 try self.makePath(self.cache_root);
364344
......@@ -433,87 +413,6 @@ pub const Builder = struct {
433413 return error.InvalidStepName;
434414 }
435415
436 fn detectNativeSystemPaths(self: *Builder) void {
437 var is_nixos = false;
438 if (process.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
439 is_nixos = true;
440 var it = mem.tokenize(nix_cflags_compile, " ");
441 while (true) {
442 const word = it.next() orelse break;
443 if (mem.eql(u8, word, "-isystem")) {
444 const include_path = it.next() orelse {
445 warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n", .{});
446 break;
447 };
448 self.addNativeSystemIncludeDir(include_path);
449 } else {
450 warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", .{word});
451 break;
452 }
453 }
454 } else |err| {
455 assert(err == error.EnvironmentVariableNotFound);
456 }
457 if (process.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
458 is_nixos = true;
459 var it = mem.tokenize(nix_ldflags, " ");
460 while (true) {
461 const word = it.next() orelse break;
462 if (mem.eql(u8, word, "-rpath")) {
463 const rpath = it.next() orelse {
464 warn("Expected argument after -rpath in NIX_LDFLAGS\n", .{});
465 break;
466 };
467 self.addNativeSystemRPath(rpath);
468 } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
469 const lib_path = word[2..];
470 self.addNativeSystemLibPath(lib_path);
471 } else {
472 warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", .{word});
473 break;
474 }
475 }
476 } else |err| {
477 assert(err == error.EnvironmentVariableNotFound);
478 }
479 if (is_nixos) return;
480 switch (builtin.os) {
481 .windows => {},
482 else => {
483 const triple = (Target{
484 .Cross = CrossTarget{
485 .arch = builtin.arch,
486 .os = builtin.os,
487 .abi = builtin.abi,
488 .cpu_features = builtin.cpu_features,
489 },
490 }).linuxTriple(self.allocator);
491
492 // TODO: $ ld --verbose | grep SEARCH_DIR
493 // the output contains some paths that end with lib64, maybe include them too?
494 // also, what is the best possible order of things?
495
496 self.addNativeSystemIncludeDir("/usr/local/include");
497 self.addNativeSystemLibPath("/usr/local/lib");
498 self.addNativeSystemLibPath("/usr/local/lib64");
499
500 self.addNativeSystemIncludeDir(self.fmt("/usr/include/{}", .{triple}));
501 self.addNativeSystemLibPath(self.fmt("/usr/lib/{}", .{triple}));
502
503 self.addNativeSystemIncludeDir("/usr/include");
504 self.addNativeSystemLibPath("/lib");
505 self.addNativeSystemLibPath("/lib64");
506 self.addNativeSystemLibPath("/usr/lib");
507 self.addNativeSystemLibPath("/usr/lib64");
508
509 // example: on a 64-bit debian-based linux distro, with zlib installed from apt:
510 // zlib.h is in /usr/include (added above)
511 // libz.so.1 is in /lib/x86_64-linux-gnu (added here)
512 self.addNativeSystemLibPath(self.fmt("/lib/{}", .{triple}));
513 },
514 }
515 }
516
517416 pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
518417 const type_id = comptime typeToEnum(T);
519418 const available_option = AvailableOption{
......@@ -638,7 +537,7 @@ pub const Builder = struct {
638537 return Target.Native;
639538 } else {
640539 const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
641 return Target.parse(target_str) catch unreachable; // TODO better error message for bad target
540 return Target.parse(.{ .arch_os_abi = target_str }) catch unreachable; // TODO better error message for bad target
642541 }
643542 }
644543
......@@ -710,13 +609,13 @@ pub const Builder = struct {
710609 }
711610
712611 fn typeToEnum(comptime T: type) TypeId {
713 return switch (@typeId(T)) {
714 builtin.TypeId.Int => TypeId.Int,
715 builtin.TypeId.Float => TypeId.Float,
716 builtin.TypeId.Bool => TypeId.Bool,
612 return switch (@typeInfo(T)) {
613 .Int => .Int,
614 .Float => .Float,
615 .Bool => .Bool,
717616 else => switch (T) {
718 []const u8 => TypeId.String,
719 []const []const u8 => TypeId.List,
617 []const u8 => .String,
618 []const []const u8 => .List,
720619 else => @compileError("Unsupported type: " ++ @typeName(T)),
721620 },
722621 };
......@@ -728,11 +627,11 @@ pub const Builder = struct {
728627
729628 pub fn typeIdName(id: TypeId) []const u8 {
730629 return switch (id) {
731 TypeId.Bool => "bool",
732 TypeId.Int => "int",
733 TypeId.Float => "float",
734 TypeId.String => "string",
735 TypeId.List => "list",
630 .Bool => "bool",
631 .Int => "int",
632 .Float => "float",
633 .String => "string",
634 .List => "list",
736635 };
737636 }
738637
......@@ -1155,6 +1054,9 @@ pub const LibExeObjStep = struct {
11551054 frameworks: BufSet,
11561055 verbose_link: bool,
11571056 verbose_cc: bool,
1057 emit_llvm_ir: bool = false,
1058 emit_asm: bool = false,
1059 emit_bin: bool = true,
11581060 disable_gen_h: bool,
11591061 bundle_compiler_rt: bool,
11601062 disable_stack_probing: bool,
......@@ -1182,7 +1084,6 @@ pub const LibExeObjStep = struct {
11821084 include_dirs: ArrayList(IncludeDir),
11831085 c_macros: ArrayList([]const u8),
11841086 output_dir: ?[]const u8,
1185 need_system_paths: bool,
11861087 is_linking_libc: bool = false,
11871088 vcpkg_bin_path: ?[]const u8 = null,
11881089
......@@ -1320,7 +1221,6 @@ pub const LibExeObjStep = struct {
13201221 .disable_stack_probing = false,
13211222 .disable_sanitize_c = false,
13221223 .output_dir = null,
1323 .need_system_paths = false,
13241224 .single_threaded = false,
13251225 .installed_path = null,
13261226 .install_step = null,
......@@ -1496,7 +1396,6 @@ pub const LibExeObjStep = struct {
14961396 /// Prefer to use `linkSystemLibrary` instead.
14971397 pub fn linkSystemLibraryName(self: *LibExeObjStep, name: []const u8) void {
14981398 self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;
1499 self.need_system_paths = true;
15001399 }
15011400
15021401 /// This links against a system library, exclusively using pkg-config to find the library.
......@@ -1940,6 +1839,11 @@ pub const LibExeObjStep = struct {
19401839 if (builder.verbose_llvm_ir) zig_args.append("--verbose-llvm-ir") catch unreachable;
19411840 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;
19421841 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;
1842 if (builder.verbose_llvm_cpu_features) zig_args.append("--verbose-llvm-cpu-features") catch unreachable;
1843
1844 if (self.emit_llvm_ir) try zig_args.append("-femit-llvm-ir");
1845 if (self.emit_asm) try zig_args.append("-femit-asm");
1846 if (!self.emit_bin) try zig_args.append("-fno-emit-bin");
19431847
19441848 if (self.strip) {
19451849 try zig_args.append("--strip");
......@@ -2008,43 +1912,33 @@ pub const LibExeObjStep = struct {
20081912 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
20091913
20101914 const all_features = self.target.getArch().allFeaturesList();
2011 var populated_cpu_features = cross.cpu_features.cpu.features;
2012 if (self.target.getArch().subArchFeature()) |sub_arch_index| {
2013 populated_cpu_features.addFeature(sub_arch_index);
2014 }
1915 var populated_cpu_features = cross.cpu.model.features;
20151916 populated_cpu_features.populateDependencies(all_features);
20161917
2017 if (populated_cpu_features.eql(cross.cpu_features.features)) {
1918 if (populated_cpu_features.eql(cross.cpu.features)) {
20181919 // The CPU name alone is sufficient.
20191920 // If it is the baseline CPU, no command line args are required.
2020 if (cross.cpu_features.cpu != self.target.getArch().getBaselineCpuFeatures().cpu) {
2021 try zig_args.append("-target-cpu");
2022 try zig_args.append(cross.cpu_features.cpu.name);
1921 if (cross.cpu.model != Target.Cpu.baseline(self.target.getArch()).model) {
1922 try zig_args.append("-mcpu");
1923 try zig_args.append(cross.cpu.model.name);
20231924 }
20241925 } else {
2025 try zig_args.append("-target-cpu");
2026 try zig_args.append(cross.cpu_features.cpu.name);
1926 var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
1927 try mcpu_buffer.append(cross.cpu.model.name);
20271928
2028 try zig_args.append("-target-feature");
2029 var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
20301929 for (all_features) |feature, i_usize| {
20311930 const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
20321931 const in_cpu_set = populated_cpu_features.isEnabled(i);
2033 const in_actual_set = cross.cpu_features.features.isEnabled(i);
1932 const in_actual_set = cross.cpu.features.isEnabled(i);
20341933 if (in_cpu_set and !in_actual_set) {
2035 try feature_str_buffer.appendByte('-');
2036 try feature_str_buffer.append(feature.name);
2037 try feature_str_buffer.appendByte(',');
1934 try mcpu_buffer.appendByte('-');
1935 try mcpu_buffer.append(feature.name);
20381936 } else if (!in_cpu_set and in_actual_set) {
2039 try feature_str_buffer.appendByte('+');
2040 try feature_str_buffer.append(feature.name);
2041 try feature_str_buffer.appendByte(',');
1937 try mcpu_buffer.appendByte('+');
1938 try mcpu_buffer.append(feature.name);
20421939 }
20431940 }
2044 if (mem.endsWith(u8, feature_str_buffer.toSliceConst(), ",")) {
2045 feature_str_buffer.shrink(feature_str_buffer.len() - 1);
2046 }
2047 try zig_args.append(feature_str_buffer.toSliceConst());
1941 try zig_args.append(mcpu_buffer.toSliceConst());
20481942 }
20491943 },
20501944 }
......@@ -2152,23 +2046,6 @@ pub const LibExeObjStep = struct {
21522046 try zig_args.append(lib_path);
21532047 }
21542048
2155 if (self.need_system_paths and self.target == Target.Native) {
2156 for (builder.native_system_include_dirs.toSliceConst()) |include_path| {
2157 zig_args.append("-isystem") catch unreachable;
2158 zig_args.append(builder.pathFromRoot(include_path)) catch unreachable;
2159 }
2160
2161 for (builder.native_system_rpaths.toSliceConst()) |rpath| {
2162 zig_args.append("-rpath") catch unreachable;
2163 zig_args.append(rpath) catch unreachable;
2164 }
2165
2166 for (builder.native_system_lib_paths.toSliceConst()) |lib_path| {
2167 zig_args.append("--library-path") catch unreachable;
2168 zig_args.append(lib_path) catch unreachable;
2169 }
2170 }
2171
21722049 for (self.c_macros.toSliceConst()) |c_macro| {
21732050 try zig_args.append("-D");
21742051 try zig_args.append(c_macro);
lib/std/builtin.zig+2-5
......@@ -6,8 +6,8 @@ pub const Target = std.Target;
66/// Deprecated: use `std.Target.Os`.
77pub const Os = std.Target.Os;
88
9/// Deprecated: use `std.Target.Arch`.
10pub const Arch = std.Target.Arch;
9/// Deprecated: use `std.Target.Cpu.Arch`.
10pub const Arch = std.Target.Cpu.Arch;
1111
1212/// Deprecated: use `std.Target.Abi`.
1313pub const Abi = std.Target.Abi;
......@@ -18,9 +18,6 @@ pub const ObjectFormat = std.Target.ObjectFormat;
1818/// Deprecated: use `std.Target.SubSystem`.
1919pub const SubSystem = std.Target.SubSystem;
2020
21/// Deprecated: use `std.Target.CpuFeatures`.
22pub const CpuFeatures = std.Target.CpuFeatures;
23
2421/// Deprecated: use `std.Target.Cpu`.
2522pub const Cpu = std.Target.Cpu;
2623
lib/std/c.zig+3
......@@ -62,6 +62,8 @@ pub fn versionCheck(glibc_version: builtin.Version) type {
6262 };
6363}
6464
65pub extern "c" var environ: [*:null]?[*:0]u8;
66
6567pub extern "c" fn fopen(filename: [*:0]const u8, modes: [*:0]const u8) ?*FILE;
6668pub extern "c" fn fclose(stream: *FILE) c_int;
6769pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
......@@ -96,6 +98,7 @@ pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
9698pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;
9799pub extern "c" fn fork() c_int;
98100pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;
101pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int;
99102pub extern "c" fn pipe(fds: *[2]fd_t) c_int;
100103pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
101104pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int;
lib/std/c/tokenizer.zig+2
......@@ -616,6 +616,7 @@ pub const Tokenizer = struct {
616616 },
617617 .BackSlash => switch (c) {
618618 '\n' => {
619 result.start = self.index + 1;
619620 state = .Start;
620621 },
621622 '\r' => {
......@@ -631,6 +632,7 @@ pub const Tokenizer = struct {
631632 },
632633 .BackSlashCr => switch (c) {
633634 '\n' => {
635 result.start = self.index + 1;
634636 state = .Start;
635637 },
636638 else => {
lib/std/child_process.zig+40-16
......@@ -48,7 +48,10 @@ pub const ChildProcess = struct {
4848 cwd: ?[]const u8,
4949
5050 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,
51
52 expand_arg0: Arg0Expand,
53
54 pub const Arg0Expand = os.Arg0Expand;
5255
5356 pub const SpawnError = error{
5457 OutOfMemory,
......@@ -90,7 +93,6 @@ pub const ChildProcess = struct {
9093 .handle = undefined,
9194 .thread_handle = undefined,
9295 .err_pipe = undefined,
93 .llnode = undefined,
9496 .term = null,
9597 .env_map = null,
9698 .cwd = null,
......@@ -102,6 +104,7 @@ pub const ChildProcess = struct {
102104 .stdin_behavior = StdIo.Inherit,
103105 .stdout_behavior = StdIo.Inherit,
104106 .stderr_behavior = StdIo.Inherit,
107 .expand_arg0 = .no_expand,
105108 };
106109 errdefer allocator.destroy(child);
107110 return child;
......@@ -174,34 +177,56 @@ pub const ChildProcess = struct {
174177
175178 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
176179 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
180 /// TODO deprecate in favor of exec2
177181 pub fn exec(
178182 allocator: *mem.Allocator,
179183 argv: []const []const u8,
180184 cwd: ?[]const u8,
181185 env_map: ?*const BufMap,
182 max_output_size: usize,
186 max_output_bytes: usize,
183187 ) !ExecResult {
184 const child = try ChildProcess.init(argv, allocator);
188 return exec2(.{
189 .allocator = allocator,
190 .argv = argv,
191 .cwd = cwd,
192 .env_map = env_map,
193 .max_output_bytes = max_output_bytes,
194 });
195 }
196
197 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
198 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
199 /// TODO rename to exec
200 pub fn exec2(args: struct {
201 allocator: *mem.Allocator,
202 argv: []const []const u8,
203 cwd: ?[]const u8 = null,
204 env_map: ?*const BufMap = null,
205 max_output_bytes: usize = 50 * 1024,
206 expand_arg0: Arg0Expand = .no_expand,
207 }) !ExecResult {
208 const child = try ChildProcess.init(args.argv, args.allocator);
185209 defer child.deinit();
186210
187 child.stdin_behavior = ChildProcess.StdIo.Ignore;
188 child.stdout_behavior = ChildProcess.StdIo.Pipe;
189 child.stderr_behavior = ChildProcess.StdIo.Pipe;
190 child.cwd = cwd;
191 child.env_map = env_map;
211 child.stdin_behavior = .Ignore;
212 child.stdout_behavior = .Pipe;
213 child.stderr_behavior = .Pipe;
214 child.cwd = args.cwd;
215 child.env_map = args.env_map;
216 child.expand_arg0 = args.expand_arg0;
192217
193218 try child.spawn();
194219
195 var stdout = Buffer.initNull(allocator);
196 var stderr = Buffer.initNull(allocator);
220 var stdout = Buffer.initNull(args.allocator);
221 var stderr = Buffer.initNull(args.allocator);
197222 defer Buffer.deinit(&stdout);
198223 defer Buffer.deinit(&stderr);
199224
200225 var stdout_file_in_stream = child.stdout.?.inStream();
201226 var stderr_file_in_stream = child.stderr.?.inStream();
202227
203 try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
204 try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);
228 try stdout_file_in_stream.stream.readAllBuffer(&stdout, args.max_output_bytes);
229 try stderr_file_in_stream.stream.readAllBuffer(&stderr, args.max_output_bytes);
205230
206231 return ExecResult{
207232 .term = try child.wait(),
......@@ -420,7 +445,7 @@ pub const ChildProcess = struct {
420445 os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
421446 }
422447
423 const err = os.execvpe(self.allocator, self.argv, env_map);
448 const err = os.execvpe_expandArg0(self.allocator, self.expand_arg0, self.argv, env_map);
424449 forkChildErrReport(err_pipe[1], err);
425450 }
426451
......@@ -453,7 +478,6 @@ pub const ChildProcess = struct {
453478
454479 self.pid = pid;
455480 self.err_pipe = err_pipe;
456 self.llnode = TailQueue(*ChildProcess).Node.init(self);
457481 self.term = null;
458482
459483 if (self.stdin_behavior == StdIo.Pipe) {
......@@ -827,7 +851,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
827851 os.exit(1);
828852}
829853
830const ErrInt = @IntType(false, @sizeOf(anyerror) * 8);
854const ErrInt = std.meta.IntType(false, @sizeOf(anyerror) * 8);
831855
832856fn writeIntFd(fd: i32, value: ErrInt) !void {
833857 const file = File{
lib/std/crypto.zig+31
......@@ -57,3 +57,34 @@ test "crypto" {
5757 _ = @import("crypto/sha3.zig");
5858 _ = @import("crypto/x25519.zig");
5959}
60
61test "issue #4532: no index out of bounds" {
62 const types = [_]type{
63 Md5,
64 Sha1,
65 Sha224,
66 Sha256,
67 Sha384,
68 Sha512,
69 Blake2s224,
70 Blake2s256,
71 Blake2b384,
72 Blake2b512,
73 };
74
75 inline for (types) |Hasher| {
76 var block = [_]u8{'#'} ** Hasher.block_length;
77 var out1: [Hasher.digest_length]u8 = undefined;
78 var out2: [Hasher.digest_length]u8 = undefined;
79
80 var h = Hasher.init();
81 h.update(block[0..]);
82 h.final(out1[0..]);
83 h.reset();
84 h.update(block[0..1]);
85 h.update(block[1..]);
86 h.final(out2[0..]);
87
88 std.testing.expectEqual(out1, out2);
89 }
90}
lib/std/crypto/blake2.zig+2-2
......@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) type {
9494 var off: usize = 0;
9595
9696 // Partial buffer exists from previous update. Copy into buffer then hash.
97 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
97 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
9898 off += 64 - d.buf_len;
9999 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
100100 d.t += 64;
......@@ -331,7 +331,7 @@ fn Blake2b(comptime out_len: usize) type {
331331 var off: usize = 0;
332332
333333 // Partial buffer exists from previous update. Copy into buffer then hash.
334 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
334 if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
335335 off += 128 - d.buf_len;
336336 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
337337 d.t += 128;
lib/std/crypto/gimli.zig+2-2
......@@ -24,11 +24,11 @@ pub const State = struct {
2424 const Self = @This();
2525
2626 pub fn toSlice(self: *Self) []u8 {
27 return @sliceToBytes(self.data[0..]);
27 return mem.sliceAsBytes(self.data[0..]);
2828 }
2929
3030 pub fn toSliceConst(self: *Self) []const u8 {
31 return @sliceToBytes(self.data[0..]);
31 return mem.sliceAsBytes(self.data[0..]);
3232 }
3333
3434 pub fn permute(self: *Self) void {
lib/std/crypto/md5.zig+1-1
......@@ -63,7 +63,7 @@ pub const Md5 = struct {
6363 var off: usize = 0;
6464
6565 // Partial buffer exists from previous update. Copy into buffer then hash.
66 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
66 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
6767 off += 64 - d.buf_len;
6868 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
6969
lib/std/crypto/sha1.zig+1-1
......@@ -61,7 +61,7 @@ pub const Sha1 = struct {
6161 var off: usize = 0;
6262
6363 // Partial buffer exists from previous update. Copy into buffer then hash.
64 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
64 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
6565 off += 64 - d.buf_len;
6666 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
6767
lib/std/crypto/sha2.zig+2-2
......@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
116116 var off: usize = 0;
117117
118118 // Partial buffer exists from previous update. Copy into buffer then hash.
119 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
119 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
120120 off += 64 - d.buf_len;
121121 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
122122
......@@ -458,7 +458,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
458458 var off: usize = 0;
459459
460460 // Partial buffer exists from previous update. Copy into buffer then hash.
461 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
461 if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
462462 off += 128 - d.buf_len;
463463 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
464464
lib/std/cstr.zig+1-1
......@@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct {
7272 errdefer allocator.free(buf);
7373
7474 var write_index = index_size;
75 const index_buf = @bytesToSlice(?[*]u8, buf);
75 const index_buf = mem.bytesAsSlice(?[*]u8, buf);
7676
7777 var i: usize = 0;
7878 for (slices) |slice| {
lib/std/debug/leb128.zig+6-6
......@@ -2,7 +2,7 @@ const std = @import("std");
22const testing = std.testing;
33
44pub fn readULEB128(comptime T: type, in_stream: var) !T {
5 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
5 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
66
77 var result: T = 0;
88 var shift: usize = 0;
......@@ -27,7 +27,7 @@ pub fn readULEB128(comptime T: type, in_stream: var) !T {
2727}
2828
2929pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
30 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
30 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
3131
3232 var result: T = 0;
3333 var shift: usize = 0;
......@@ -55,8 +55,8 @@ pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
5555}
5656
5757pub fn readILEB128(comptime T: type, in_stream: var) !T {
58 const UT = @IntType(false, T.bit_count);
59 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
58 const UT = std.meta.IntType(false, T.bit_count);
59 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
6060
6161 var result: UT = 0;
6262 var shift: usize = 0;
......@@ -87,8 +87,8 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {
8787}
8888
8989pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
90 const UT = @IntType(false, T.bit_count);
91 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
90 const UT = std.meta.IntType(false, T.bit_count);
91 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
9292
9393 var result: UT = 0;
9494 var shift: usize = 0;
lib/std/event.zig+2
......@@ -1,6 +1,7 @@
11pub const Channel = @import("event/channel.zig").Channel;
22pub const Future = @import("event/future.zig").Future;
33pub const Group = @import("event/group.zig").Group;
4pub const Batch = @import("event/batch.zig").Batch;
45pub const Lock = @import("event/lock.zig").Lock;
56pub const Locked = @import("event/locked.zig").Locked;
67pub const RwLock = @import("event/rwlock.zig").RwLock;
......@@ -11,6 +12,7 @@ test "import event tests" {
1112 _ = @import("event/channel.zig");
1213 _ = @import("event/future.zig");
1314 _ = @import("event/group.zig");
15 _ = @import("event/batch.zig");
1416 _ = @import("event/lock.zig");
1517 _ = @import("event/locked.zig");
1618 _ = @import("event/rwlock.zig");
lib/std/event/batch.zig created+139
......@@ -0,0 +1,139 @@
1const std = @import("../std.zig");
2const testing = std.testing;
3
4/// Performs multiple async functions in parallel, without heap allocation.
5/// Async function frames are managed externally to this abstraction, and
6/// passed in via the `add` function. Once all the jobs are added, call `wait`.
7/// This API is *not* thread-safe. The object must be accessed from one thread at
8/// a time, however, it need not be the same thread.
9pub fn Batch(
10 /// The return value for each job.
11 /// If a job slot was re-used due to maxed out concurrency, then its result
12 /// value will be overwritten. The values can be accessed with the `results` field.
13 comptime Result: type,
14 /// How many jobs to run in parallel.
15 comptime max_jobs: comptime_int,
16 /// Controls whether the `add` and `wait` functions will be async functions.
17 comptime async_behavior: enum {
18 /// Observe the value of `std.io.is_async` to decide whether `add`
19 /// and `wait` will be async functions. Asserts that the jobs do not suspend when
20 /// `std.io.mode == .blocking`. This is a generally safe assumption, and the
21 /// usual recommended option for this parameter.
22 auto_async,
23
24 /// Always uses the `noasync` keyword when using `await` on the jobs,
25 /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
26 never_async,
27
28 /// `add` and `wait` use regular `await` keyword, making them async functions.
29 always_async,
30 },
31) type {
32 return struct {
33 jobs: [max_jobs]Job,
34 next_job_index: usize,
35 collected_result: CollectedResult,
36
37 const Job = struct {
38 frame: ?anyframe->Result,
39 result: Result,
40 };
41
42 const Self = @This();
43
44 const CollectedResult = switch (@typeInfo(Result)) {
45 .ErrorUnion => Result,
46 else => void,
47 };
48
49 const async_ok = switch (async_behavior) {
50 .auto_async => std.io.is_async,
51 .never_async => false,
52 .always_async => true,
53 };
54
55 pub fn init() Self {
56 return Self{
57 .jobs = [1]Job{
58 .{
59 .frame = null,
60 .result = undefined,
61 },
62 } ** max_jobs,
63 .next_job_index = 0,
64 .collected_result = {},
65 };
66 }
67
68 /// Add a frame to the Batch. If all jobs are in-flight, then this function
69 /// waits until one completes.
70 /// This function is *not* thread-safe. It must be called from one thread at
71 /// a time, however, it need not be the same thread.
72 /// TODO: "select" language feature to use the next available slot, rather than
73 /// awaiting the next index.
74 pub fn add(self: *Self, frame: anyframe->Result) void {
75 const job = &self.jobs[self.next_job_index];
76 self.next_job_index = (self.next_job_index + 1) % max_jobs;
77 if (job.frame) |existing| {
78 job.result = if (async_ok) await existing else noasync await existing;
79 if (CollectedResult != void) {
80 job.result catch |err| {
81 self.collected_result = err;
82 };
83 }
84 }
85 job.frame = frame;
86 }
87
88 /// Wait for all the jobs to complete.
89 /// Safe to call any number of times.
90 /// If `Result` is an error union, this function returns the last error that occurred, if any.
91 /// Unlike the `results` field, the return value of `wait` will report any error that occurred;
92 /// hitting max parallelism will not compromise the result.
93 /// This function is *not* thread-safe. It must be called from one thread at
94 /// a time, however, it need not be the same thread.
95 pub fn wait(self: *Self) CollectedResult {
96 for (self.jobs) |*job| if (job.frame) |f| {
97 job.result = if (async_ok) await f else noasync await f;
98 if (CollectedResult != void) {
99 job.result catch |err| {
100 self.collected_result = err;
101 };
102 }
103 job.frame = null;
104 };
105 return self.collected_result;
106 }
107 };
108}
109
110test "std.event.Batch" {
111 var count: usize = 0;
112 var batch = Batch(void, 2, .auto_async).init();
113 batch.add(&async sleepALittle(&count));
114 batch.add(&async increaseByTen(&count));
115 batch.wait();
116 testing.expect(count == 11);
117
118 var another = Batch(anyerror!void, 2, .auto_async).init();
119 another.add(&async somethingElse());
120 another.add(&async doSomethingThatFails());
121 testing.expectError(error.ItBroke, another.wait());
122}
123
124fn sleepALittle(count: *usize) void {
125 std.time.sleep(1 * std.time.millisecond);
126 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
127}
128
129fn increaseByTen(count: *usize) void {
130 var i: usize = 0;
131 while (i < 10) : (i += 1) {
132 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
133 }
134}
135
136fn doSomethingThatFails() anyerror!void {}
137fn somethingElse() anyerror!void {
138 return error.ItBroke;
139}
lib/std/event/group.zig+5
......@@ -5,6 +5,11 @@ const testing = std.testing;
55const Allocator = std.mem.Allocator;
66
77/// ReturnType must be `void` or `E!void`
8/// TODO This API was created back with the old design of async/await, when calling any
9/// async function required an allocator. There is an ongoing experiment to transition
10/// all uses of this API to the simpler and more resource-aware `std.event.Batch` API.
11/// If the transition goes well, all usages of `Group` will be gone, and this API
12/// will be deleted.
813pub fn Group(comptime ReturnType: type) type {
914 return struct {
1015 frame_stack: Stack,
lib/std/event/loop.zig+13-12
......@@ -12,15 +12,18 @@ const maxInt = std.math.maxInt;
1212const Thread = std.Thread;
1313
1414pub const Loop = struct {
15 allocator: *mem.Allocator,
1615 next_tick_queue: std.atomic.Queue(anyframe),
1716 os_data: OsData,
1817 final_resume_node: ResumeNode,
1918 pending_event_count: usize,
2019 extra_threads: []*Thread,
2120
22 // pre-allocated eventfds. all permanently active.
23 // this is how we send promises to be resumed on other threads.
21 /// For resources that have the same lifetime as the `Loop`.
22 /// This is only used by `Loop` for the thread pool and associated resources.
23 arena: std.heap.ArenaAllocator,
24
25 /// Pre-allocated eventfds. All permanently active.
26 /// This is how `Loop` sends promises to be resumed on other threads.
2427 available_eventfd_resume_nodes: std.atomic.Stack(ResumeNode.EventFd),
2528 eventfd_resume_nodes: []std.atomic.Stack(ResumeNode.EventFd).Node,
2629
......@@ -127,11 +130,9 @@ pub const Loop = struct {
127130 /// Thread count is the total thread count. The thread pool size will be
128131 /// max(thread_count - 1, 0)
129132 pub fn initThreadPool(self: *Loop, thread_count: usize) !void {
130 // TODO: https://github.com/ziglang/zig/issues/3539
131 const allocator = std.heap.page_allocator;
132133 self.* = Loop{
134 .arena = std.heap.ArenaAllocator.init(std.heap.page_allocator),
133135 .pending_event_count = 1,
134 .allocator = allocator,
135136 .os_data = undefined,
136137 .next_tick_queue = std.atomic.Queue(anyframe).init(),
137138 .extra_threads = undefined,
......@@ -143,17 +144,17 @@ pub const Loop = struct {
143144 .overlapped = ResumeNode.overlapped_init,
144145 },
145146 };
147 errdefer self.arena.deinit();
148
146149 // We need at least one of these in case the fs thread wants to use onNextTick
147150 const extra_thread_count = thread_count - 1;
148151 const resume_node_count = std.math.max(extra_thread_count, 1);
149 self.eventfd_resume_nodes = try self.allocator.alloc(
152 self.eventfd_resume_nodes = try self.arena.allocator.alloc(
150153 std.atomic.Stack(ResumeNode.EventFd).Node,
151154 resume_node_count,
152155 );
153 errdefer self.allocator.free(self.eventfd_resume_nodes);
154156
155 self.extra_threads = try self.allocator.alloc(*Thread, extra_thread_count);
156 errdefer self.allocator.free(self.extra_threads);
157 self.extra_threads = try self.arena.allocator.alloc(*Thread, extra_thread_count);
157158
158159 try self.initOsData(extra_thread_count);
159160 errdefer self.deinitOsData();
......@@ -161,7 +162,8 @@ pub const Loop = struct {
161162
162163 pub fn deinit(self: *Loop) void {
163164 self.deinitOsData();
164 self.allocator.free(self.extra_threads);
165 self.arena.deinit();
166 self.* = undefined;
165167 }
166168
167169 const InitOsDataError = os.EpollCreateError || mem.Allocator.Error || os.EventFdError ||
......@@ -407,7 +409,6 @@ pub const Loop = struct {
407409 noasync os.close(self.os_data.final_eventfd);
408410 while (self.available_eventfd_resume_nodes.pop()) |node| noasync os.close(node.data.eventfd);
409411 noasync os.close(self.os_data.epollfd);
410 self.allocator.free(self.eventfd_resume_nodes);
411412 },
412413 .macosx, .freebsd, .netbsd, .dragonfly => {
413414 noasync os.close(self.os_data.kqfd);
lib/std/fifo.zig+4-4
......@@ -101,7 +101,7 @@ pub fn LinearFifo(
101101 }
102102 }
103103 { // set unused area to undefined
104 const unused = @sliceToBytes(self.buf[self.count..]);
104 const unused = mem.sliceAsBytes(self.buf[self.count..]);
105105 @memset(unused.ptr, undefined, unused.len);
106106 }
107107 }
......@@ -166,12 +166,12 @@ pub fn LinearFifo(
166166 { // set old range to undefined. Note: may be wrapped around
167167 const slice = self.readableSliceMut(0);
168168 if (slice.len >= count) {
169 const unused = @sliceToBytes(slice[0..count]);
169 const unused = mem.sliceAsBytes(slice[0..count]);
170170 @memset(unused.ptr, undefined, unused.len);
171171 } else {
172 const unused = @sliceToBytes(slice[0..]);
172 const unused = mem.sliceAsBytes(slice[0..]);
173173 @memset(unused.ptr, undefined, unused.len);
174 const unused2 = @sliceToBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);
174 const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);
175175 @memset(unused2.ptr, undefined, unused2.len);
176176 }
177177 }
lib/std/fmt.zig+12-12
......@@ -82,7 +82,7 @@ pub fn format(
8282 comptime fmt: []const u8,
8383 args: var,
8484) Errors!void {
85 const ArgSetType = @IntType(false, 32);
85 const ArgSetType = u32;
8686 if (@typeInfo(@TypeOf(args)) != .Struct) {
8787 @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args)));
8888 }
......@@ -405,7 +405,7 @@ pub fn formatType(
405405 try format(context, Errors, output, "@{x}", .{@ptrToInt(&value)});
406406 }
407407 },
408 .Struct => {
408 .Struct => |StructT| {
409409 if (comptime std.meta.trait.hasFn("format")(T)) {
410410 return value.format(fmt, options, context, Errors, output);
411411 }
......@@ -416,27 +416,28 @@ pub fn formatType(
416416 }
417417 comptime var field_i = 0;
418418 try output(context, "{");
419 inline while (field_i < @memberCount(T)) : (field_i += 1) {
419 inline for (StructT.fields) |f| {
420420 if (field_i == 0) {
421421 try output(context, " .");
422422 } else {
423423 try output(context, ", .");
424424 }
425 try output(context, @memberName(T, field_i));
425 try output(context, f.name);
426426 try output(context, " = ");
427 try formatType(@field(value, @memberName(T, field_i)), fmt, options, context, Errors, output, max_depth - 1);
427 try formatType(@field(value, f.name), fmt, options, context, Errors, output, max_depth - 1);
428 field_i += 1;
428429 }
429430 try output(context, " }");
430431 },
431432 .Pointer => |ptr_info| switch (ptr_info.size) {
432433 .One => switch (@typeInfo(ptr_info.child)) {
433 builtin.TypeId.Array => |info| {
434 .Array => |info| {
434435 if (info.child == u8) {
435436 return formatText(value, fmt, options, context, Errors, output);
436437 }
437438 return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) });
438439 },
439 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
440 .Enum, .Union, .Struct => {
440441 return formatType(value.*, fmt, options, context, Errors, output, max_depth);
441442 },
442443 else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }),
......@@ -509,7 +510,7 @@ fn formatValue(
509510 }
510511
511512 const T = @TypeOf(value);
512 switch (@typeId(T)) {
513 switch (@typeInfo(T)) {
513514 .Float => return formatFloatValue(value, fmt, options, context, Errors, output),
514515 .Int, .ComptimeInt => return formatIntValue(value, fmt, options, context, Errors, output),
515516 .Bool => return output(context, if (value) "true" else "false"),
......@@ -757,8 +758,6 @@ pub fn formatFloatDecimal(
757758 } else {
758759 try output(context, ".0");
759760 }
760 } else {
761 try output(context, "0");
762761 }
763762
764763 return;
......@@ -945,7 +944,7 @@ fn formatIntSigned(
945944 .fill = options.fill,
946945 };
947946
948 const uint = @IntType(false, @TypeOf(value).bit_count);
947 const uint = std.meta.IntType(false, @TypeOf(value).bit_count);
949948 if (value < 0) {
950949 const minus_sign: u8 = '-';
951950 try output(context, @as(*const [1]u8, &minus_sign)[0..]);
......@@ -973,7 +972,7 @@ fn formatIntUnsigned(
973972 assert(base >= 2);
974973 var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;
975974 const min_int_bits = comptime math.max(@TypeOf(value).bit_count, @TypeOf(base).bit_count);
976 const MinInt = @IntType(@TypeOf(value).is_signed, min_int_bits);
975 const MinInt = std.meta.IntType(@TypeOf(value).is_signed, min_int_bits);
977976 var a: MinInt = value;
978977 var index: usize = buf.len;
979978
......@@ -1399,6 +1398,7 @@ test "float.special" {
13991398
14001399test "float.decimal" {
14011400 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
1401 try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
14021402 try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
14031403 try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
14041404 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
lib/std/fmt/parse_float.zig+1-1
......@@ -389,7 +389,7 @@ test "fmt.parseFloat" {
389389 const epsilon = 1e-7;
390390
391391 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
392 const Z = @IntType(false, T.bit_count);
392 const Z = std.meta.IntType(false, T.bit_count);
393393
394394 testing.expectError(error.InvalidCharacter, parseFloat(T, ""));
395395 testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));
lib/std/fs.zig+52-7
......@@ -96,7 +96,6 @@ pub fn updateFile(source_path: []const u8, dest_path: []const u8) !PrevStatus {
9696/// atime, and mode of the source file so that the next call to `updateFile` will not need a copy.
9797/// Returns the previous status of the file before updating.
9898/// If any of the directories do not exist for dest_path, they are created.
99/// TODO https://github.com/ziglang/zig/issues/2885
10099pub fn updateFileMode(source_path: []const u8, dest_path: []const u8, mode: ?File.Mode) !PrevStatus {
101100 const my_cwd = cwd();
102101
......@@ -818,6 +817,13 @@ pub const Dir = struct {
818817 ) File.OpenError!File {
819818 const w = os.windows;
820819
820 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
821 return error.IsDir;
822 }
823 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
824 return error.IsDir;
825 }
826
821827 var result = File{
822828 .handle = undefined,
823829 .io_mode = .blocking,
......@@ -839,12 +845,6 @@ pub const Dir = struct {
839845 .SecurityDescriptor = null,
840846 .SecurityQualityOfService = null,
841847 };
842 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
843 return error.IsDir;
844 }
845 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
846 return error.IsDir;
847 }
848848 var io: w.IO_STATUS_BLOCK = undefined;
849849 const rc = w.ntdll.NtCreateFile(
850850 &result.handle,
......@@ -864,6 +864,7 @@ pub const Dir = struct {
864864 .OBJECT_NAME_INVALID => unreachable,
865865 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
866866 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
867 .NO_MEDIA_IN_DEVICE => return error.NoDevice,
867868 .INVALID_PARAMETER => unreachable,
868869 .SHARING_VIOLATION => return error.SharingViolation,
869870 .ACCESS_DENIED => return error.AccessDenied,
......@@ -1323,6 +1324,50 @@ pub const Dir = struct {
13231324 defer file.close();
13241325 try file.write(data);
13251326 }
1327
1328 pub const AccessError = os.AccessError;
1329
1330 /// Test accessing `path`.
1331 /// `path` is UTF8-encoded.
1332 /// Be careful of Time-Of-Check-Time-Of-Use race conditions when using this function.
1333 /// For example, instead of testing if a file exists and then opening it, just
1334 /// open it and handle the error for file not found.
1335 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {
1336 if (builtin.os == .windows) {
1337 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
1338 return self.accessW(&sub_path_w, flags);
1339 }
1340 const path_c = try os.toPosixPath(sub_path);
1341 return self.accessZ(&path_c, flags);
1342 }
1343
1344 /// Same as `access` except the path parameter is null-terminated.
1345 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {
1346 if (builtin.os == .windows) {
1347 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path);
1348 return self.accessW(&sub_path_w, flags);
1349 }
1350 const os_mode = if (flags.write and flags.read)
1351 @as(u32, os.R_OK | os.W_OK)
1352 else if (flags.write)
1353 @as(u32, os.W_OK)
1354 else
1355 @as(u32, os.F_OK);
1356 const result = if (need_async_thread)
1357 std.event.Loop.instance.?.faccessatZ(self.fd, sub_path, os_mode)
1358 else
1359 os.faccessatZ(self.fd, sub_path, os_mode, 0);
1360 return result;
1361 }
1362
1363 /// Same as `access` except asserts the target OS is Windows and the path parameter is
1364 /// * WTF-16 encoded
1365 /// * null-terminated
1366 /// * NtDll prefixed
1367 /// TODO currently this ignores `flags`.
1368 pub fn accessW(self: Dir, sub_path_w: [*:0]const u16, flags: File.OpenFlags) AccessError!void {
1369 return os.faccessatW(self.fd, sub_path_w, 0, 0);
1370 }
13261371};
13271372
13281373/// Returns an handle to the current working directory that is open for traversal.
lib/std/fs/file.zig-25
......@@ -60,31 +60,6 @@ pub const File = struct {
6060 mode: Mode = default_mode,
6161 };
6262
63 /// Test for the existence of `path`.
64 /// `path` is UTF8-encoded.
65 /// In general it is recommended to avoid this function. For example,
66 /// instead of testing if a file exists and then opening it, just
67 /// open it and handle the error for file not found.
68 /// TODO: deprecate this and move it to `std.fs.Dir`.
69 /// TODO: integrate with async I/O
70 pub fn access(path: []const u8) !void {
71 return os.access(path, os.F_OK);
72 }
73
74 /// Same as `access` except the parameter is null-terminated.
75 /// TODO: deprecate this and move it to `std.fs.Dir`.
76 /// TODO: integrate with async I/O
77 pub fn accessC(path: [*:0]const u8) !void {
78 return os.accessC(path, os.F_OK);
79 }
80
81 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
82 /// TODO: deprecate this and move it to `std.fs.Dir`.
83 /// TODO: integrate with async I/O
84 pub fn accessW(path: [*:0]const u16) !void {
85 return os.accessW(path, os.F_OK);
86 }
87
8863 /// Upon success, the stream is in an uninitialized state. To continue using it,
8964 /// you must use the open() function.
9065 pub fn close(self: File) void {
lib/std/fs/watch.zig+1-1
......@@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool {
2626}
2727
2828fn hashString(s: []const u16) u32 {
29 return @truncate(u32, std.hash.Wyhash.hash(0, @sliceToBytes(s)));
29 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceAsBytes(s)));
3030}
3131
3232const WatchEventError = error{
lib/std/hash/auto_hash.zig+1-1
......@@ -93,7 +93,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
9393 // TODO Check if the situation is better after #561 is resolved.
9494 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),
9595
96 .Float => |info| hash(hasher, @bitCast(@IntType(false, info.bits), key), strat),
96 .Float => |info| hash(hasher, @bitCast(std.meta.IntType(false, info.bits), key), strat),
9797
9898 .Bool => hash(hasher, @boolToInt(key), strat),
9999 .Enum => hash(hasher, @enumToInt(key), strat),
lib/std/hash/wyhash.zig+1-1
......@@ -10,7 +10,7 @@ const primes = [_]u64{
1010};
1111
1212fn read_bytes(comptime bytes: u8, data: []const u8) u64 {
13 const T = @IntType(false, 8 * bytes);
13 const T = std.meta.IntType(false, 8 * bytes);
1414 return mem.readIntSliceLittle(T, data[0..bytes]);
1515}
1616
lib/std/heap.zig+4-4
......@@ -283,14 +283,14 @@ const WasmPageAllocator = struct {
283283
284284 fn getBit(self: FreeBlock, idx: usize) PageStatus {
285285 const bit_offset = 0;
286 return @intToEnum(PageStatus, Io.get(@sliceToBytes(self.data), idx, bit_offset));
286 return @intToEnum(PageStatus, Io.get(mem.sliceAsBytes(self.data), idx, bit_offset));
287287 }
288288
289289 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {
290290 const bit_offset = 0;
291291 var i: usize = 0;
292292 while (i < len) : (i += 1) {
293 Io.set(@sliceToBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));
293 Io.set(mem.sliceAsBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));
294294 }
295295 }
296296
......@@ -552,7 +552,7 @@ pub const ArenaAllocator = struct {
552552 if (len >= actual_min_size) break;
553553 }
554554 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
555 const buf_node_slice = @bytesToSlice(BufNode, buf[0..@sizeOf(BufNode)]);
555 const buf_node_slice = mem.bytesAsSlice(BufNode, buf[0..@sizeOf(BufNode)]);
556556 const buf_node = &buf_node_slice[0];
557557 buf_node.* = BufNode{
558558 .data = buf,
......@@ -1015,7 +1015,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
10151015 // very near usize?
10161016 if (mem.page_size << 2 > maxInt(usize)) return;
10171017
1018 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));
1018 const USizeShift = std.meta.IntType(false, std.math.log2(usize.bit_count));
10191019 const large_align = @as(u29, mem.page_size << 2);
10201020
10211021 var align_mask: usize = undefined;
lib/std/io.zig+94-219
......@@ -121,76 +121,37 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
121121
122122 unbuffered_in_stream: *Stream,
123123
124 buffer: [buffer_size]u8,
125 start_index: usize,
126 end_index: usize,
124 const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size });
125 fifo: FifoType,
127126
128127 pub fn init(unbuffered_in_stream: *Stream) Self {
129128 return Self{
130129 .unbuffered_in_stream = unbuffered_in_stream,
131 .buffer = undefined,
132
133 // Initialize these two fields to buffer_size so that
134 // in `readFn` we treat the state as being able to read
135 // more from the unbuffered stream. If we set them to 0
136 // and 0, the code would think we already hit EOF.
137 .start_index = buffer_size,
138 .end_index = buffer_size,
139
130 .fifo = FifoType.init(),
140131 .stream = Stream{ .readFn = readFn },
141132 };
142133 }
143134
144135 fn readFn(in_stream: *Stream, dest: []u8) !usize {
145136 const self = @fieldParentPtr(Self, "stream", in_stream);
146
147 // Hot path for one byte reads
148 if (dest.len == 1 and self.end_index > self.start_index) {
149 dest[0] = self.buffer[self.start_index];
150 self.start_index += 1;
151 return 1;
152 }
153
154137 var dest_index: usize = 0;
155 while (true) {
156 const dest_space = dest.len - dest_index;
157 if (dest_space == 0) {
158 return dest_index;
159 }
160 const amt_buffered = self.end_index - self.start_index;
161 if (amt_buffered == 0) {
162 assert(self.end_index <= buffer_size);
163 // Make sure the last read actually gave us some data
164 if (self.end_index == 0) {
138 while (dest_index < dest.len) {
139 const written = self.fifo.read(dest[dest_index..]);
140 if (written == 0) {
141 // fifo empty, fill it
142 const writable = self.fifo.writableSlice(0);
143 assert(writable.len > 0);
144 const n = try self.unbuffered_in_stream.read(writable);
145 if (n == 0) {
165146 // reading from the unbuffered stream returned nothing
166147 // so we have nothing left to read.
167148 return dest_index;
168149 }
169 // we can read more data from the unbuffered stream
170 if (dest_space < buffer_size) {
171 self.start_index = 0;
172 self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]);
173
174 // Shortcut
175 if (self.end_index >= dest_space) {
176 mem.copy(u8, dest[dest_index..], self.buffer[0..dest_space]);
177 self.start_index = dest_space;
178 return dest.len;
179 }
180 } else {
181 // asking for so much data that buffering is actually less efficient.
182 // forward the request directly to the unbuffered stream
183 const amt_read = try self.unbuffered_in_stream.read(dest[dest_index..]);
184 return dest_index + amt_read;
185 }
150 self.fifo.update(n);
186151 }
187
188 const copy_amount = math.min(dest_space, amt_buffered);
189 const copy_end_index = self.start_index + copy_amount;
190 mem.copy(u8, dest[dest_index..], self.buffer[self.start_index..copy_end_index]);
191 self.start_index = copy_end_index;
192 dest_index += copy_amount;
152 dest_index += written;
193153 }
154 return dest.len;
194155 }
195156 };
196157}
......@@ -235,7 +196,7 @@ test "io.BufferedInStream" {
235196
236197/// Creates a stream which supports 'un-reading' data, so that it can be read again.
237198/// This makes look-ahead style parsing much easier.
238pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) type {
199pub fn PeekStream(comptime buffer_type: std.fifo.LinearFifoBufferType, comptime InStreamError: type) type {
239200 return struct {
240201 const Self = @This();
241202 pub const Error = InStreamError;
......@@ -244,57 +205,57 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
244205 stream: Stream,
245206 base: *Stream,
246207
247 // Right now the look-ahead space is statically allocated, but a version with dynamic allocation
248 // is not too difficult to derive from this.
249 buffer: [buffer_size]u8,
250 index: usize,
251 at_end: bool,
252
253 pub fn init(base: *Stream) Self {
254 return Self{
255 .base = base,
256 .buffer = undefined,
257 .index = 0,
258 .at_end = false,
259 .stream = Stream{ .readFn = readFn },
260 };
261 }
208 const FifoType = std.fifo.LinearFifo(u8, buffer_type);
209 fifo: FifoType,
210
211 pub usingnamespace switch (buffer_type) {
212 .Static => struct {
213 pub fn init(base: *Stream) Self {
214 return .{
215 .base = base,
216 .fifo = FifoType.init(),
217 .stream = Stream{ .readFn = readFn },
218 };
219 }
220 },
221 .Slice => struct {
222 pub fn init(base: *Stream, buf: []u8) Self {
223 return .{
224 .base = base,
225 .fifo = FifoType.init(buf),
226 .stream = Stream{ .readFn = readFn },
227 };
228 }
229 },
230 .Dynamic => struct {
231 pub fn init(base: *Stream, allocator: *mem.Allocator) Self {
232 return .{
233 .base = base,
234 .fifo = FifoType.init(allocator),
235 .stream = Stream{ .readFn = readFn },
236 };
237 }
238 },
239 };
262240
263 pub fn putBackByte(self: *Self, byte: u8) void {
264 self.buffer[self.index] = byte;
265 self.index += 1;
241 pub fn putBackByte(self: *Self, byte: u8) !void {
242 try self.putBack(&[_]u8{byte});
266243 }
267244
268 pub fn putBack(self: *Self, bytes: []const u8) void {
269 var pos = bytes.len;
270 while (pos != 0) {
271 pos -= 1;
272 self.putBackByte(bytes[pos]);
273 }
245 pub fn putBack(self: *Self, bytes: []const u8) !void {
246 try self.fifo.unget(bytes);
274247 }
275248
276249 fn readFn(in_stream: *Stream, dest: []u8) Error!usize {
277250 const self = @fieldParentPtr(Self, "stream", in_stream);
278251
279252 // copy over anything putBack()'d
280 var pos: usize = 0;
281 while (pos < dest.len and self.index != 0) {
282 dest[pos] = self.buffer[self.index - 1];
283 self.index -= 1;
284 pos += 1;
285 }
286
287 if (pos == dest.len or self.at_end) {
288 return pos;
289 }
253 var dest_index = self.fifo.read(dest);
254 if (dest_index == dest.len) return dest_index;
290255
291256 // ask the backing stream for more
292 const left = dest.len - pos;
293 const read = try self.base.read(dest[pos..]);
294 assert(read <= left);
295
296 self.at_end = (read < left);
297 return pos + read;
257 dest_index += try self.base.read(dest[dest_index..]);
258 return dest_index;
298259 }
299260 };
300261}
......@@ -376,7 +337,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
376337 assert(u_bit_count >= bits);
377338 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
378339 };
379 const Buf = @IntType(false, buf_bit_count);
340 const Buf = std.meta.IntType(false, buf_bit_count);
380341 const BufShift = math.Log2Int(Buf);
381342
382343 out_bits.* = @as(usize, 0);
......@@ -607,52 +568,33 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr
607568
608569 unbuffered_out_stream: *Stream,
609570
610 buffer: [buffer_size]u8,
611 index: usize,
571 const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size });
572 fifo: FifoType,
612573
613574 pub fn init(unbuffered_out_stream: *Stream) Self {
614575 return Self{
615576 .unbuffered_out_stream = unbuffered_out_stream,
616 .buffer = undefined,
617 .index = 0,
577 .fifo = FifoType.init(),
618578 .stream = Stream{ .writeFn = writeFn },
619579 };
620580 }
621581
622582 pub fn flush(self: *Self) !void {
623 try self.unbuffered_out_stream.write(self.buffer[0..self.index]);
624 self.index = 0;
583 while (true) {
584 const slice = self.fifo.readableSlice(0);
585 if (slice.len == 0) break;
586 try self.unbuffered_out_stream.write(slice);
587 self.fifo.discard(slice.len);
588 }
625589 }
626590
627591 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
628592 const self = @fieldParentPtr(Self, "stream", out_stream);
629
630 if (bytes.len == 1) {
631 // This is not required logic but a shorter path
632 // for single byte writes
633 self.buffer[self.index] = bytes[0];
634 self.index += 1;
635 if (self.index == buffer_size) {
636 try self.flush();
637 }
638 return;
639 } else if (bytes.len >= self.buffer.len) {
593 if (bytes.len >= self.fifo.writableLength()) {
640594 try self.flush();
641595 return self.unbuffered_out_stream.write(bytes);
642596 }
643 var src_index: usize = 0;
644
645 while (src_index < bytes.len) {
646 const dest_space_left = self.buffer.len - self.index;
647 const copy_amt = math.min(dest_space_left, bytes.len - src_index);
648 mem.copy(u8, self.buffer[self.index..], bytes[src_index .. src_index + copy_amt]);
649 self.index += copy_amt;
650 assert(self.index <= self.buffer.len);
651 if (self.index == self.buffer.len) {
652 try self.flush();
653 }
654 src_index += copy_amt;
655 }
597 self.fifo.writeAssumeCapacity(bytes);
656598 }
657599 };
658600}
......@@ -717,7 +659,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {
717659 assert(u_bit_count >= bits);
718660 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
719661 };
720 const Buf = @IntType(false, buf_bit_count);
662 const Buf = std.meta.IntType(false, buf_bit_count);
721663 const BufShift = math.Log2Int(Buf);
722664
723665 const buf_value = @intCast(Buf, value);
......@@ -848,73 +790,6 @@ pub const BufferedAtomicFile = struct {
848790 }
849791};
850792
851pub fn readLine(buf: *std.Buffer) ![]u8 {
852 var stdin_stream = getStdIn().inStream();
853 return readLineFrom(&stdin_stream.stream, buf);
854}
855
856/// Reads all characters until the next newline into buf, and returns
857/// a slice of the characters read (excluding the newline character(s)).
858pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
859 const start = buf.len();
860 while (true) {
861 const byte = try stream.readByte();
862 switch (byte) {
863 '\r' => {
864 // trash the following \n
865 _ = try stream.readByte();
866 return buf.toSlice()[start..];
867 },
868 '\n' => return buf.toSlice()[start..],
869 else => try buf.appendByte(byte),
870 }
871 }
872}
873
874test "io.readLineFrom" {
875 var buf = try std.Buffer.initSize(testing.allocator, 0);
876 defer buf.deinit();
877 var mem_stream = SliceInStream.init(
878 \\Line 1
879 \\Line 22
880 \\Line 333
881 );
882 const stream = &mem_stream.stream;
883
884 testing.expectEqualSlices(u8, "Line 1", try readLineFrom(stream, &buf));
885 testing.expectEqualSlices(u8, "Line 22", try readLineFrom(stream, &buf));
886 testing.expectError(error.EndOfStream, readLineFrom(stream, &buf));
887 testing.expectEqualSlices(u8, "Line 1Line 22Line 333", buf.toSlice());
888}
889
890pub fn readLineSlice(slice: []u8) ![]u8 {
891 var stdin_stream = getStdIn().inStream();
892 return readLineSliceFrom(&stdin_stream.stream, slice);
893}
894
895/// Reads all characters until the next newline into slice, and returns
896/// a slice of the characters read (excluding the newline character(s)).
897pub fn readLineSliceFrom(stream: var, slice: []u8) ![]u8 {
898 // We cannot use Buffer.fromOwnedSlice, as it wants to append a null byte
899 // after taking ownership, which would always require an allocation.
900 var buf = std.Buffer{ .list = std.ArrayList(u8).fromOwnedSlice(testing.failing_allocator, slice) };
901 try buf.resize(0);
902 return try readLineFrom(stream, &buf);
903}
904
905test "io.readLineSliceFrom" {
906 var buf: [7]u8 = undefined;
907 var mem_stream = SliceInStream.init(
908 \\Line 1
909 \\Line 22
910 \\Line 333
911 );
912 const stream = &mem_stream.stream;
913
914 testing.expectEqualSlices(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]));
915 testing.expectError(error.OutOfMemory, readLineSliceFrom(stream, buf[0..]));
916}
917
918793pub const Packing = enum {
919794 /// Pack data to byte alignment
920795 Byte,
......@@ -956,12 +831,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
956831
957832 //@BUG: inferred error issue. See: #1386
958833 fn deserializeInt(self: *Self, comptime T: type) (Error || error{EndOfStream})!T {
959 comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));
834 comptime assert(trait.is(.Int)(T) or trait.is(.Float)(T));
960835
961836 const u8_bit_count = 8;
962837 const t_bit_count = comptime meta.bitCount(T);
963838
964 const U = @IntType(false, t_bit_count);
839 const U = std.meta.IntType(false, t_bit_count);
965840 const Log2U = math.Log2Int(U);
966841 const int_size = (U.bit_count + 7) / 8;
967842
......@@ -976,7 +851,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
976851
977852 if (int_size == 1) {
978853 if (t_bit_count == 8) return @bitCast(T, buffer[0]);
979 const PossiblySignedByte = @IntType(T.is_signed, 8);
854 const PossiblySignedByte = std.meta.IntType(T.is_signed, 8);
980855 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));
981856 }
982857
......@@ -1005,9 +880,9 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1005880 /// Deserializes data into the type pointed to by `ptr`
1006881 pub fn deserializeInto(self: *Self, ptr: var) !void {
1007882 const T = @TypeOf(ptr);
1008 comptime assert(trait.is(builtin.TypeId.Pointer)(T));
883 comptime assert(trait.is(.Pointer)(T));
1009884
1010 if (comptime trait.isSlice(T) or comptime trait.isPtrTo(builtin.TypeId.Array)(T)) {
885 if (comptime trait.isSlice(T) or comptime trait.isPtrTo(.Array)(T)) {
1011886 for (ptr) |*v|
1012887 try self.deserializeInto(v);
1013888 return;
......@@ -1016,7 +891,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1016891 comptime assert(trait.isSingleItemPtr(T));
1017892
1018893 const C = comptime meta.Child(T);
1019 const child_type_id = @typeId(C);
894 const child_type_id = @typeInfo(C);
1020895
1021896 //custom deserializer: fn(self: *Self, deserializer: var) !void
1022897 if (comptime trait.hasFn("deserialize")(C)) return C.deserialize(ptr, self);
......@@ -1027,10 +902,10 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1027902 }
1028903
1029904 switch (child_type_id) {
1030 builtin.TypeId.Void => return,
1031 builtin.TypeId.Bool => ptr.* = (try self.deserializeInt(u1)) > 0,
1032 builtin.TypeId.Float, builtin.TypeId.Int => ptr.* = try self.deserializeInt(C),
1033 builtin.TypeId.Struct => {
905 .Void => return,
906 .Bool => ptr.* = (try self.deserializeInt(u1)) > 0,
907 .Float, .Int => ptr.* = try self.deserializeInt(C),
908 .Struct => {
1034909 const info = @typeInfo(C).Struct;
1035910
1036911 inline for (info.fields) |*field_info| {
......@@ -1040,7 +915,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1040915 if (FieldType == void or FieldType == u0) continue;
1041916
1042917 //it doesn't make any sense to read pointers
1043 if (comptime trait.is(builtin.TypeId.Pointer)(FieldType)) {
918 if (comptime trait.is(.Pointer)(FieldType)) {
1044919 @compileError("Will not " ++ "read field " ++ name ++ " of struct " ++
1045920 @typeName(C) ++ " because it " ++ "is of pointer-type " ++
1046921 @typeName(FieldType) ++ ".");
......@@ -1049,7 +924,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1049924 try self.deserializeInto(&@field(ptr, name));
1050925 }
1051926 },
1052 builtin.TypeId.Union => {
927 .Union => {
1053928 const info = @typeInfo(C).Union;
1054929 if (info.tag_type) |TagType| {
1055930 //we avoid duplicate iteration over the enum tags
......@@ -1073,7 +948,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1073948 @compileError("Cannot meaningfully deserialize " ++ @typeName(C) ++
1074949 " because it is an untagged union. Use a custom deserialize().");
1075950 },
1076 builtin.TypeId.Optional => {
951 .Optional => {
1077952 const OC = comptime meta.Child(C);
1078953 const exists = (try self.deserializeInt(u1)) > 0;
1079954 if (!exists) {
......@@ -1085,7 +960,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1085960 const val_ptr = &ptr.*.?;
1086961 try self.deserializeInto(val_ptr);
1087962 },
1088 builtin.TypeId.Enum => {
963 .Enum => {
1089964 var value = try self.deserializeInt(@TagType(C));
1090965 ptr.* = try meta.intToEnum(C, value);
1091966 },
......@@ -1134,12 +1009,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
11341009
11351010 fn serializeInt(self: *Self, value: var) Error!void {
11361011 const T = @TypeOf(value);
1137 comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));
1012 comptime assert(trait.is(.Int)(T) or trait.is(.Float)(T));
11381013
11391014 const t_bit_count = comptime meta.bitCount(T);
11401015 const u8_bit_count = comptime meta.bitCount(u8);
11411016
1142 const U = @IntType(false, t_bit_count);
1017 const U = std.meta.IntType(false, t_bit_count);
11431018 const Log2U = math.Log2Int(U);
11441019 const int_size = (U.bit_count + 7) / 8;
11451020
......@@ -1183,11 +1058,11 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
11831058 return;
11841059 }
11851060
1186 switch (@typeId(T)) {
1187 builtin.TypeId.Void => return,
1188 builtin.TypeId.Bool => try self.serializeInt(@as(u1, @boolToInt(value))),
1189 builtin.TypeId.Float, builtin.TypeId.Int => try self.serializeInt(value),
1190 builtin.TypeId.Struct => {
1061 switch (@typeInfo(T)) {
1062 .Void => return,
1063 .Bool => try self.serializeInt(@as(u1, @boolToInt(value))),
1064 .Float, .Int => try self.serializeInt(value),
1065 .Struct => {
11911066 const info = @typeInfo(T);
11921067
11931068 inline for (info.Struct.fields) |*field_info| {
......@@ -1197,7 +1072,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
11971072 if (FieldType == void or FieldType == u0) continue;
11981073
11991074 //It doesn't make sense to write pointers
1200 if (comptime trait.is(builtin.TypeId.Pointer)(FieldType)) {
1075 if (comptime trait.is(.Pointer)(FieldType)) {
12011076 @compileError("Will not " ++ "serialize field " ++ name ++
12021077 " of struct " ++ @typeName(T) ++ " because it " ++
12031078 "is of pointer-type " ++ @typeName(FieldType) ++ ".");
......@@ -1205,7 +1080,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
12051080 try self.serialize(@field(value, name));
12061081 }
12071082 },
1208 builtin.TypeId.Union => {
1083 .Union => {
12091084 const info = @typeInfo(T).Union;
12101085 if (info.tag_type) |TagType| {
12111086 const active_tag = meta.activeTag(value);
......@@ -1226,7 +1101,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
12261101 @compileError("Cannot meaningfully serialize " ++ @typeName(T) ++
12271102 " because it is an untagged union. Use a custom serialize().");
12281103 },
1229 builtin.TypeId.Optional => {
1104 .Optional => {
12301105 if (value == null) {
12311106 try self.serializeInt(@as(u1, @boolToInt(false)));
12321107 return;
......@@ -1237,10 +1112,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
12371112 const val_ptr = &value.?;
12381113 try self.serialize(val_ptr.*);
12391114 },
1240 builtin.TypeId.Enum => {
1115 .Enum => {
12411116 try self.serializeInt(@enumToInt(value));
12421117 },
1243 else => @compileError("Cannot serialize " ++ @tagName(@typeId(T)) ++ " types (unimplemented)."),
1118 else => @compileError("Cannot serialize " ++ @tagName(@typeInfo(T)) ++ " types (unimplemented)."),
12441119 }
12451120 }
12461121 };
lib/std/io/in_stream.zig+1-1
......@@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type {
235235 // Only extern and packed structs have defined in-memory layout.
236236 comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);
237237 var res: [1]T = undefined;
238 try self.readNoEof(@sliceToBytes(res[0..]));
238 try self.readNoEof(mem.sliceAsBytes(res[0..]));
239239 return res[0];
240240 }
241241
lib/std/io/test.zig+13-11
......@@ -5,6 +5,7 @@ const meta = std.meta;
55const trait = std.trait;
66const DefaultPrng = std.rand.DefaultPrng;
77const expect = std.testing.expect;
8const expectEqual = std.testing.expectEqual;
89const expectError = std.testing.expectError;
910const mem = std.mem;
1011const fs = std.fs;
......@@ -44,8 +45,8 @@ test "write a file, read it, then delete it" {
4445 defer file.close();
4546
4647 const file_size = try file.getEndPos();
47 const expected_file_size = "begin".len + data.len + "end".len;
48 expect(file_size == expected_file_size);
48 const expected_file_size: u64 = "begin".len + data.len + "end".len;
49 expectEqual(expected_file_size, file_size);
4950
5051 var file_in_stream = file.inStream();
5152 var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream);
......@@ -93,12 +94,12 @@ test "SliceInStream" {
9394test "PeekStream" {
9495 const bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
9596 var ss = io.SliceInStream.init(&bytes);
96 var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);
97 var ps = io.PeekStream(.{ .Static = 2 }, io.SliceInStream.Error).init(&ss.stream);
9798
9899 var dest: [4]u8 = undefined;
99100
100 ps.putBackByte(9);
101 ps.putBackByte(10);
101 try ps.putBackByte(9);
102 try ps.putBackByte(10);
102103
103104 var read = try ps.stream.read(dest[0..4]);
104105 expect(read == 4);
......@@ -114,8 +115,8 @@ test "PeekStream" {
114115 expect(read == 2);
115116 expect(mem.eql(u8, dest[0..2], bytes[6..8]));
116117
117 ps.putBackByte(11);
118 ps.putBackByte(12);
118 try ps.putBackByte(11);
119 try ps.putBackByte(12);
119120
120121 read = try ps.stream.read(dest[0..4]);
121122 expect(read == 2);
......@@ -317,6 +318,7 @@ test "BitStreams with File Stream" {
317318}
318319
319320fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
321 @setEvalBranchQuota(1500);
320322 //@NOTE: if this test is taking too long, reduce the maximum tested bitsize
321323 const max_test_bitsize = 128;
322324
......@@ -340,8 +342,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
340342
341343 comptime var i = 0;
342344 inline while (i <= max_test_bitsize) : (i += 1) {
343 const U = @IntType(false, i);
344 const S = @IntType(true, i);
345 const U = std.meta.IntType(false, i);
346 const S = std.meta.IntType(true, i);
345347 try serializer.serializeInt(@as(U, i));
346348 if (i != 0) try serializer.serializeInt(@as(S, -1)) else try serializer.serialize(@as(S, 0));
347349 }
......@@ -349,8 +351,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
349351
350352 i = 0;
351353 inline while (i <= max_test_bitsize) : (i += 1) {
352 const U = @IntType(false, i);
353 const S = @IntType(true, i);
354 const U = std.meta.IntType(false, i);
355 const S = std.meta.IntType(true, i);
354356 const x = try deserializer.deserializeInt(U);
355357 const y = try deserializer.deserializeInt(S);
356358 expect(x == @as(U, i));
lib/std/json.zig+822-3
......@@ -19,6 +19,74 @@ const StringEscapes = union(enum) {
1919 },
2020};
2121
22/// Checks to see if a string matches what it would be as a json-encoded string
23/// Assumes that `encoded` is a well-formed json string
24fn encodesTo(decoded: []const u8, encoded: []const u8) bool {
25 var i: usize = 0;
26 var j: usize = 0;
27 while (i < decoded.len) {
28 if (j >= encoded.len) return false;
29 if (encoded[j] != '\\') {
30 if (decoded[i] != encoded[j]) return false;
31 j += 1;
32 i += 1;
33 } else {
34 const escape_type = encoded[j + 1];
35 if (escape_type != 'u') {
36 const t: u8 = switch (escape_type) {
37 '\\' => '\\',
38 '/' => '/',
39 'n' => '\n',
40 'r' => '\r',
41 't' => '\t',
42 'f' => 12,
43 'b' => 8,
44 '"' => '"',
45 else => unreachable,
46 };
47 if (decoded[i] != t) return false;
48 j += 2;
49 i += 1;
50 } else {
51 var codepoint = std.fmt.parseInt(u21, encoded[j + 2 .. j + 6], 16) catch unreachable;
52 j += 6;
53 if (codepoint >= 0xD800 and codepoint < 0xDC00) {
54 // surrogate pair
55 assert(encoded[j] == '\\');
56 assert(encoded[j + 1] == 'u');
57 const low_surrogate = std.fmt.parseInt(u21, encoded[j + 2 .. j + 6], 16) catch unreachable;
58 codepoint = 0x10000 + (((codepoint & 0x03ff) << 10) | (low_surrogate & 0x03ff));
59 j += 6;
60 }
61 var buf: [4]u8 = undefined;
62 const len = std.unicode.utf8Encode(codepoint, &buf) catch unreachable;
63 if (i + len > decoded.len) return false;
64 if (!mem.eql(u8, decoded[i .. i + len], buf[0..len])) return false;
65 i += len;
66 }
67 }
68 }
69 assert(i == decoded.len);
70 assert(j == encoded.len);
71 return true;
72}
73
74test "encodesTo" {
75 // same
76 testing.expectEqual(true, encodesTo("false", "false"));
77 // totally different
78 testing.expectEqual(false, encodesTo("false", "true"));
79 // differnt lengths
80 testing.expectEqual(false, encodesTo("false", "other"));
81 // with escape
82 testing.expectEqual(true, encodesTo("\\", "\\\\"));
83 testing.expectEqual(true, encodesTo("with\nescape", "with\\nescape"));
84 // with unicode
85 testing.expectEqual(true, encodesTo("ą", "\\u0105"));
86 testing.expectEqual(true, encodesTo("😂", "\\ud83d\\ude02"));
87 testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02"));
88}
89
2290/// A single token slice into the parent string.
2391///
2492/// Use `token.slice()` on the input at the current position to get the current slice.
......@@ -1026,10 +1094,8 @@ pub const TokenStream = struct {
10261094
10271095 pub fn next(self: *TokenStream) Error!?Token {
10281096 if (self.token) |token| {
1029 // TODO: Audit this pattern once #2915 is closed
1030 const copy = token;
10311097 self.token = null;
1032 return copy;
1098 return token;
10331099 }
10341100
10351101 var t1: ?Token = undefined;
......@@ -1203,6 +1269,493 @@ pub const Value = union(enum) {
12031269 }
12041270};
12051271
1272pub const ParseOptions = struct {
1273 allocator: ?*Allocator = null,
1274
1275 /// Behaviour when a duplicate field is encountered.
1276 duplicate_field_behavior: enum {
1277 UseFirst,
1278 Error,
1279 UseLast,
1280 } = .Error,
1281};
1282
1283fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: ParseOptions) !T {
1284 switch (@typeInfo(T)) {
1285 .Bool => {
1286 return switch (token) {
1287 .True => true,
1288 .False => false,
1289 else => error.UnexpectedToken,
1290 };
1291 },
1292 .Float, .ComptimeFloat => {
1293 const numberToken = switch (token) {
1294 .Number => |n| n,
1295 else => return error.UnexpectedToken,
1296 };
1297 return try std.fmt.parseFloat(T, numberToken.slice(tokens.slice, tokens.i - 1));
1298 },
1299 .Int, .ComptimeInt => {
1300 const numberToken = switch (token) {
1301 .Number => |n| n,
1302 else => return error.UnexpectedToken,
1303 };
1304 if (!numberToken.is_integer) return error.UnexpectedToken;
1305 return try std.fmt.parseInt(T, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1306 },
1307 .Optional => |optionalInfo| {
1308 if (token == .Null) {
1309 return null;
1310 } else {
1311 return try parseInternal(optionalInfo.child, token, tokens, options);
1312 }
1313 },
1314 .Enum => |enumInfo| {
1315 switch (token) {
1316 .Number => |numberToken| {
1317 if (!numberToken.is_integer) return error.UnexpectedToken;
1318 const n = try std.fmt.parseInt(enumInfo.tag_type, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1319 return try std.meta.intToEnum(T, n);
1320 },
1321 .String => |stringToken| {
1322 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1323 switch (stringToken.escapes) {
1324 .None => return std.meta.stringToEnum(T, source_slice) orelse return error.InvalidEnumTag,
1325 .Some => {
1326 inline for (enumInfo.fields) |field| {
1327 if (field.name.len == stringToken.decodedLength() and encodesTo(field.name, source_slice)) {
1328 return @field(T, field.name);
1329 }
1330 }
1331 return error.InvalidEnumTag;
1332 },
1333 }
1334 },
1335 else => return error.UnexpectedToken,
1336 }
1337 },
1338 .Union => |unionInfo| {
1339 if (unionInfo.tag_type) |_| {
1340 // try each of the union fields until we find one that matches
1341 inline for (unionInfo.fields) |u_field| {
1342 if (parseInternal(u_field.field_type, token, tokens, options)) |value| {
1343 return @unionInit(T, u_field.name, value);
1344 } else |err| {
1345 // Bubble up error.OutOfMemory
1346 // Parsing some types won't have OutOfMemory in their
1347 // error-sets, for the condition to be valid, merge it in.
1348 if (@as(@TypeOf(err) || error{OutOfMemory}, err) == error.OutOfMemory) return err;
1349 // otherwise continue through the `inline for`
1350 }
1351 }
1352 return error.NoUnionMembersMatched;
1353 } else {
1354 @compileError("Unable to parse into untagged union '" ++ @typeName(T) ++ "'");
1355 }
1356 },
1357 .Struct => |structInfo| {
1358 switch (token) {
1359 .ObjectBegin => {},
1360 else => return error.UnexpectedToken,
1361 }
1362 var r: T = undefined;
1363 var fields_seen = [_]bool{false} ** structInfo.fields.len;
1364 errdefer {
1365 inline for (structInfo.fields) |field, i| {
1366 if (fields_seen[i]) {
1367 parseFree(field.field_type, @field(r, field.name), options);
1368 }
1369 }
1370 }
1371
1372 while (true) {
1373 switch ((try tokens.next()) orelse return error.UnexpectedEndOfJson) {
1374 .ObjectEnd => break,
1375 .String => |stringToken| {
1376 const key_source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1377 var found = false;
1378 inline for (structInfo.fields) |field, i| {
1379 // TODO: using switches here segfault the compiler (#2727?)
1380 if ((stringToken.escapes == .None and mem.eql(u8, field.name, key_source_slice)) or (stringToken.escapes == .Some and (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)))) {
1381 // if (switch (stringToken.escapes) {
1382 // .None => mem.eql(u8, field.name, key_source_slice),
1383 // .Some => (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)),
1384 // }) {
1385 if (fields_seen[i]) {
1386 // switch (options.duplicate_field_behavior) {
1387 // .UseFirst => {},
1388 // .Error => {},
1389 // .UseLast => {},
1390 // }
1391 if (options.duplicate_field_behavior == .UseFirst) {
1392 break;
1393 } else if (options.duplicate_field_behavior == .Error) {
1394 return error.DuplicateJSONField;
1395 } else if (options.duplicate_field_behavior == .UseLast) {
1396 parseFree(field.field_type, @field(r, field.name), options);
1397 }
1398 }
1399 @field(r, field.name) = try parse(field.field_type, tokens, options);
1400 fields_seen[i] = true;
1401 found = true;
1402 break;
1403 }
1404 }
1405 if (!found) return error.UnknownField;
1406 },
1407 else => return error.UnexpectedToken,
1408 }
1409 }
1410 inline for (structInfo.fields) |field, i| {
1411 if (!fields_seen[i]) {
1412 if (field.default_value) |default| {
1413 @field(r, field.name) = default;
1414 } else {
1415 return error.MissingField;
1416 }
1417 }
1418 }
1419 return r;
1420 },
1421 .Array => |arrayInfo| {
1422 switch (token) {
1423 .ArrayBegin => {
1424 var r: T = undefined;
1425 var i: usize = 0;
1426 errdefer {
1427 while (true) : (i -= 1) {
1428 parseFree(arrayInfo.child, r[i], options);
1429 if (i == 0) break;
1430 }
1431 }
1432 while (i < r.len) : (i += 1) {
1433 r[i] = try parse(arrayInfo.child, tokens, options);
1434 }
1435 const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1436 switch (tok) {
1437 .ArrayEnd => {},
1438 else => return error.UnexpectedToken,
1439 }
1440 return r;
1441 },
1442 .String => |stringToken| {
1443 if (arrayInfo.child != u8) return error.UnexpectedToken;
1444 var r: T = undefined;
1445 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1446 switch (stringToken.escapes) {
1447 .None => mem.copy(u8, &r, source_slice),
1448 .Some => try unescapeString(&r, source_slice),
1449 }
1450 return r;
1451 },
1452 else => return error.UnexpectedToken,
1453 }
1454 },
1455 .Pointer => |ptrInfo| {
1456 const allocator = options.allocator orelse return error.AllocatorRequired;
1457 switch (ptrInfo.size) {
1458 .One => {
1459 const r: T = allocator.create(ptrInfo.child);
1460 r.* = try parseInternal(ptrInfo.child, token, tokens, options);
1461 return r;
1462 },
1463 .Slice => {
1464 switch (token) {
1465 .ArrayBegin => {
1466 var arraylist = std.ArrayList(ptrInfo.child).init(allocator);
1467 errdefer {
1468 while (arraylist.popOrNull()) |v| {
1469 parseFree(ptrInfo.child, v, options);
1470 }
1471 arraylist.deinit();
1472 }
1473
1474 while (true) {
1475 const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1476 switch (tok) {
1477 .ArrayEnd => break,
1478 else => {},
1479 }
1480
1481 try arraylist.ensureCapacity(arraylist.len + 1);
1482 const v = try parseInternal(ptrInfo.child, tok, tokens, options);
1483 arraylist.appendAssumeCapacity(v);
1484 }
1485 return arraylist.toOwnedSlice();
1486 },
1487 .String => |stringToken| {
1488 if (ptrInfo.child != u8) return error.UnexpectedToken;
1489 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1490 switch (stringToken.escapes) {
1491 .None => return mem.dupe(allocator, u8, source_slice),
1492 .Some => |some_escapes| {
1493 const output = try allocator.alloc(u8, stringToken.decodedLength());
1494 errdefer allocator.free(output);
1495 try unescapeString(output, source_slice);
1496 return output;
1497 },
1498 }
1499 },
1500 else => return error.UnexpectedToken,
1501 }
1502 },
1503 else => @compileError("Unable to parse into type '" ++ @typeName(T) ++ "'"),
1504 }
1505 },
1506 else => @compileError("Unable to parse into type '" ++ @typeName(T) ++ "'"),
1507 }
1508 unreachable;
1509}
1510
1511pub fn parse(comptime T: type, tokens: *TokenStream, options: ParseOptions) !T {
1512 const token = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1513 return parseInternal(T, token, tokens, options);
1514}
1515
1516/// Releases resources created by `parse`.
1517/// Should be called with the same type and `ParseOptions` that were passed to `parse`
1518pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
1519 switch (@typeInfo(T)) {
1520 .Bool, .Float, .ComptimeFloat, .Int, .ComptimeInt, .Enum => {},
1521 .Optional => {
1522 if (value) |v| {
1523 return parseFree(@TypeOf(v), v, options);
1524 }
1525 },
1526 .Union => |unionInfo| {
1527 if (unionInfo.tag_type) |UnionTagType| {
1528 inline for (unionInfo.fields) |u_field| {
1529 if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
1530 parseFree(u_field.field_type, @field(value, u_field.name), options);
1531 break;
1532 }
1533 }
1534 } else {
1535 unreachable;
1536 }
1537 },
1538 .Struct => |structInfo| {
1539 inline for (structInfo.fields) |field| {
1540 parseFree(field.field_type, @field(value, field.name), options);
1541 }
1542 },
1543 .Array => |arrayInfo| {
1544 for (value) |v| {
1545 parseFree(arrayInfo.child, v, options);
1546 }
1547 },
1548 .Pointer => |ptrInfo| {
1549 const allocator = options.allocator orelse unreachable;
1550 switch (ptrInfo.size) {
1551 .One => {
1552 parseFree(ptrInfo.child, value.*, options);
1553 allocator.destroy(v);
1554 },
1555 .Slice => {
1556 for (value) |v| {
1557 parseFree(ptrInfo.child, v, options);
1558 }
1559 allocator.free(value);
1560 },
1561 else => unreachable,
1562 }
1563 },
1564 else => unreachable,
1565 }
1566}
1567
1568test "parse" {
1569 testing.expectEqual(false, try parse(bool, &TokenStream.init("false"), ParseOptions{}));
1570 testing.expectEqual(true, try parse(bool, &TokenStream.init("true"), ParseOptions{}));
1571 testing.expectEqual(@as(u1, 1), try parse(u1, &TokenStream.init("1"), ParseOptions{}));
1572 testing.expectError(error.Overflow, parse(u1, &TokenStream.init("50"), ParseOptions{}));
1573 testing.expectEqual(@as(u64, 42), try parse(u64, &TokenStream.init("42"), ParseOptions{}));
1574 testing.expectEqual(@as(f64, 42), try parse(f64, &TokenStream.init("42.0"), ParseOptions{}));
1575 testing.expectEqual(@as(?bool, null), try parse(?bool, &TokenStream.init("null"), ParseOptions{}));
1576 testing.expectEqual(@as(?bool, true), try parse(?bool, &TokenStream.init("true"), ParseOptions{}));
1577
1578 testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("\"foo\""), ParseOptions{}));
1579 testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("[102, 111, 111]"), ParseOptions{}));
1580}
1581
1582test "parse into enum" {
1583 const T = extern enum {
1584 Foo = 42,
1585 Bar,
1586 @"with\\escape",
1587 };
1588 testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("\"Foo\""), ParseOptions{}));
1589 testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("42"), ParseOptions{}));
1590 testing.expectEqual(@as(T, .@"with\\escape"), try parse(T, &TokenStream.init("\"with\\\\escape\""), ParseOptions{}));
1591 testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("5"), ParseOptions{}));
1592 testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("\"Qux\""), ParseOptions{}));
1593}
1594
1595test "parse into that allocates a slice" {
1596 testing.expectError(error.AllocatorRequired, parse([]u8, &TokenStream.init("\"foo\""), ParseOptions{}));
1597
1598 const options = ParseOptions{ .allocator = testing.allocator };
1599 {
1600 const r = try parse([]u8, &TokenStream.init("\"foo\""), options);
1601 defer parseFree([]u8, r, options);
1602 testing.expectEqualSlices(u8, "foo", r);
1603 }
1604 {
1605 const r = try parse([]u8, &TokenStream.init("[102, 111, 111]"), options);
1606 defer parseFree([]u8, r, options);
1607 testing.expectEqualSlices(u8, "foo", r);
1608 }
1609 {
1610 const r = try parse([]u8, &TokenStream.init("\"with\\\\escape\""), options);
1611 defer parseFree([]u8, r, options);
1612 testing.expectEqualSlices(u8, "with\\escape", r);
1613 }
1614}
1615
1616test "parse into tagged union" {
1617 {
1618 const T = union(enum) {
1619 int: i32,
1620 float: f64,
1621 string: []const u8,
1622 };
1623 testing.expectEqual(T{ .float = 1.5 }, try parse(T, &TokenStream.init("1.5"), ParseOptions{}));
1624 }
1625
1626 { // if union matches string member, fails with NoUnionMembersMatched rather than AllocatorRequired
1627 // Note that this behaviour wasn't necessarily by design, but was
1628 // what fell out of the implementation and may result in interesting
1629 // API breakage if changed
1630 const T = union(enum) {
1631 int: i32,
1632 float: f64,
1633 string: []const u8,
1634 };
1635 testing.expectError(error.NoUnionMembersMatched, parse(T, &TokenStream.init("\"foo\""), ParseOptions{}));
1636 }
1637
1638 { // failing allocations should be bubbled up instantly without trying next member
1639 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 0);
1640 const options = ParseOptions{ .allocator = &fail_alloc.allocator };
1641 const T = union(enum) {
1642 // both fields here match the input
1643 string: []const u8,
1644 array: [3]u8,
1645 };
1646 testing.expectError(error.OutOfMemory, parse(T, &TokenStream.init("[1,2,3]"), options));
1647 }
1648
1649 {
1650 // if multiple matches possible, takes first option
1651 const T = union(enum) {
1652 x: u8,
1653 y: u8,
1654 };
1655 testing.expectEqual(T{ .x = 42 }, try parse(T, &TokenStream.init("42"), ParseOptions{}));
1656 }
1657}
1658
1659test "parseFree descends into tagged union" {
1660 // tagged unions are broken on arm64: https://github.com/ziglang/zig/issues/4492
1661 if (std.builtin.arch == .aarch64) return error.SkipZigTest;
1662
1663 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 1);
1664 const options = ParseOptions{ .allocator = &fail_alloc.allocator };
1665 const T = union(enum) {
1666 int: i32,
1667 float: f64,
1668 string: []const u8,
1669 };
1670 // use a string with unicode escape so we know result can't be a reference to global constant
1671 const r = try parse(T, &TokenStream.init("\"with\\u0105unicode\""), options);
1672 testing.expectEqual(@TagType(T).string, @as(@TagType(T), r));
1673 testing.expectEqualSlices(u8, "withąunicode", r.string);
1674 testing.expectEqual(@as(usize, 0), fail_alloc.deallocations);
1675 parseFree(T, r, options);
1676 testing.expectEqual(@as(usize, 1), fail_alloc.deallocations);
1677}
1678
1679test "parse into struct with no fields" {
1680 const T = struct {};
1681 testing.expectEqual(T{}, try parse(T, &TokenStream.init("{}"), ParseOptions{}));
1682}
1683
1684test "parse into struct with misc fields" {
1685 @setEvalBranchQuota(10000);
1686 const options = ParseOptions{ .allocator = testing.allocator };
1687 const T = struct {
1688 int: i64,
1689 float: f64,
1690 @"with\\escape": bool,
1691 @"withąunicode😂": bool,
1692 language: []const u8,
1693 optional: ?bool,
1694 default_field: i32 = 42,
1695 static_array: [3]f64,
1696 dynamic_array: []f64,
1697
1698 const Bar = struct {
1699 nested: []const u8,
1700 };
1701 complex: Bar,
1702
1703 const Baz = struct {
1704 foo: []const u8,
1705 };
1706 veryComplex: []Baz,
1707
1708 const Union = union(enum) {
1709 x: u8,
1710 float: f64,
1711 string: []const u8,
1712 };
1713 a_union: Union,
1714 };
1715 const r = try parse(T, &TokenStream.init(
1716 \\{
1717 \\ "int": 420,
1718 \\ "float": 3.14,
1719 \\ "with\\escape": true,
1720 \\ "with\u0105unicode\ud83d\ude02": false,
1721 \\ "language": "zig",
1722 \\ "optional": null,
1723 \\ "static_array": [66.6, 420.420, 69.69],
1724 \\ "dynamic_array": [66.6, 420.420, 69.69],
1725 \\ "complex": {
1726 \\ "nested": "zig"
1727 \\ },
1728 \\ "veryComplex": [
1729 \\ {
1730 \\ "foo": "zig"
1731 \\ }, {
1732 \\ "foo": "rocks"
1733 \\ }
1734 \\ ],
1735 \\ "a_union": 100000
1736 \\}
1737 ), options);
1738 defer parseFree(T, r, options);
1739 testing.expectEqual(@as(i64, 420), r.int);
1740 testing.expectEqual(@as(f64, 3.14), r.float);
1741 testing.expectEqual(true, r.@"with\\escape");
1742 testing.expectEqual(false, r.@"withąunicode😂");
1743 testing.expectEqualSlices(u8, "zig", r.language);
1744 testing.expectEqual(@as(?bool, null), r.optional);
1745 testing.expectEqual(@as(i32, 42), r.default_field);
1746 testing.expectEqual(@as(f64, 66.6), r.static_array[0]);
1747 testing.expectEqual(@as(f64, 420.420), r.static_array[1]);
1748 testing.expectEqual(@as(f64, 69.69), r.static_array[2]);
1749 testing.expectEqual(@as(usize, 3), r.dynamic_array.len);
1750 testing.expectEqual(@as(f64, 66.6), r.dynamic_array[0]);
1751 testing.expectEqual(@as(f64, 420.420), r.dynamic_array[1]);
1752 testing.expectEqual(@as(f64, 69.69), r.dynamic_array[2]);
1753 testing.expectEqualSlices(u8, r.complex.nested, "zig");
1754 testing.expectEqualSlices(u8, "zig", r.veryComplex[0].foo);
1755 testing.expectEqualSlices(u8, "rocks", r.veryComplex[1].foo);
1756 testing.expectEqual(T.Union{ .float = 100000 }, r.a_union);
1757}
1758
12061759/// A non-stream JSON parser which constructs a tree of Value's.
12071760pub const Parser = struct {
12081761 allocator: *Allocator,
......@@ -1688,3 +2241,269 @@ test "string copy option" {
16882241 }
16892242 testing.expect(found_nocopy);
16902243}
2244
2245pub const StringifyOptions = struct {
2246 // TODO: indentation options?
2247 // TODO: make escaping '/' in strings optional?
2248 // TODO: allow picking if []u8 is string or array?
2249};
2250
2251pub fn stringify(
2252 value: var,
2253 options: StringifyOptions,
2254 context: var,
2255 comptime Errors: type,
2256 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
2257) Errors!void {
2258 const T = @TypeOf(value);
2259 switch (@typeInfo(T)) {
2260 .Float, .ComptimeFloat => {
2261 return std.fmt.formatFloatScientific(value, std.fmt.FormatOptions{}, context, Errors, output);
2262 },
2263 .Int, .ComptimeInt => {
2264 return std.fmt.formatIntValue(value, "", std.fmt.FormatOptions{}, context, Errors, output);
2265 },
2266 .Bool => {
2267 return output(context, if (value) "true" else "false");
2268 },
2269 .Optional => {
2270 if (value) |payload| {
2271 return try stringify(payload, options, context, Errors, output);
2272 } else {
2273 return output(context, "null");
2274 }
2275 },
2276 .Enum => {
2277 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2278 return value.jsonStringify(options, context, Errors, output);
2279 }
2280
2281 @compileError("Unable to stringify enum '" ++ @typeName(T) ++ "'");
2282 },
2283 .Union => {
2284 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2285 return value.jsonStringify(options, context, Errors, output);
2286 }
2287
2288 const info = @typeInfo(T).Union;
2289 if (info.tag_type) |UnionTagType| {
2290 inline for (info.fields) |u_field| {
2291 if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
2292 return try stringify(@field(value, u_field.name), options, context, Errors, output);
2293 }
2294 }
2295 } else {
2296 @compileError("Unable to stringify untagged union '" ++ @typeName(T) ++ "'");
2297 }
2298 },
2299 .Struct => |S| {
2300 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2301 return value.jsonStringify(options, context, Errors, output);
2302 }
2303
2304 try output(context, "{");
2305 comptime var field_output = false;
2306 inline for (S.fields) |Field, field_i| {
2307 // don't include void fields
2308 if (Field.field_type == void) continue;
2309
2310 if (!field_output) {
2311 field_output = true;
2312 } else {
2313 try output(context, ",");
2314 }
2315
2316 try stringify(Field.name, options, context, Errors, output);
2317 try output(context, ":");
2318 try stringify(@field(value, Field.name), options, context, Errors, output);
2319 }
2320 try output(context, "}");
2321 return;
2322 },
2323 .Pointer => |ptr_info| switch (ptr_info.size) {
2324 .One => {
2325 // TODO: avoid loops?
2326 return try stringify(value.*, options, context, Errors, output);
2327 },
2328 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
2329 .Slice => {
2330 if (ptr_info.child == u8 and std.unicode.utf8ValidateSlice(value)) {
2331 try output(context, "\"");
2332 var i: usize = 0;
2333 while (i < value.len) : (i += 1) {
2334 switch (value[i]) {
2335 // normal ascii characters
2336 0x20...0x21, 0x23...0x2E, 0x30...0x5B, 0x5D...0x7F => try output(context, value[i .. i + 1]),
2337 // control characters with short escapes
2338 '\\' => try output(context, "\\\\"),
2339 '\"' => try output(context, "\\\""),
2340 '/' => try output(context, "\\/"),
2341 0x8 => try output(context, "\\b"),
2342 0xC => try output(context, "\\f"),
2343 '\n' => try output(context, "\\n"),
2344 '\r' => try output(context, "\\r"),
2345 '\t' => try output(context, "\\t"),
2346 else => {
2347 const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
2348 const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
2349 if (codepoint <= 0xFFFF) {
2350 // If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF),
2351 // then it may be represented as a six-character sequence: a reverse solidus, followed
2352 // by the lowercase letter u, followed by four hexadecimal digits that encode the character's code point.
2353 try output(context, "\\u");
2354 try std.fmt.formatIntValue(codepoint, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2355 } else {
2356 // To escape an extended character that is not in the Basic Multilingual Plane,
2357 // the character is represented as a 12-character sequence, encoding the UTF-16 surrogate pair.
2358 const high = @intCast(u16, (codepoint - 0x10000) >> 10) + 0xD800;
2359 const low = @intCast(u16, codepoint & 0x3FF) + 0xDC00;
2360 try output(context, "\\u");
2361 try std.fmt.formatIntValue(high, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2362 try output(context, "\\u");
2363 try std.fmt.formatIntValue(low, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2364 }
2365 i += ulen - 1;
2366 },
2367 }
2368 }
2369 try output(context, "\"");
2370 return;
2371 }
2372
2373 try output(context, "[");
2374 for (value) |x, i| {
2375 if (i != 0) {
2376 try output(context, ",");
2377 }
2378 try stringify(x, options, context, Errors, output);
2379 }
2380 try output(context, "]");
2381 return;
2382 },
2383 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2384 },
2385 .Array => |info| {
2386 return try stringify(value[0..], options, context, Errors, output);
2387 },
2388 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2389 }
2390 unreachable;
2391}
2392
2393fn teststringify(expected: []const u8, value: var) !void {
2394 const TestStringifyContext = struct {
2395 expected_remaining: []const u8,
2396 fn testStringifyWrite(context: *@This(), bytes: []const u8) !void {
2397 if (context.expected_remaining.len < bytes.len) {
2398 std.debug.warn(
2399 \\====== expected this output: =========
2400 \\{}
2401 \\======== instead found this: =========
2402 \\{}
2403 \\======================================
2404 , .{
2405 context.expected_remaining,
2406 bytes,
2407 });
2408 return error.TooMuchData;
2409 }
2410 if (!mem.eql(u8, context.expected_remaining[0..bytes.len], bytes)) {
2411 std.debug.warn(
2412 \\====== expected this output: =========
2413 \\{}
2414 \\======== instead found this: =========
2415 \\{}
2416 \\======================================
2417 , .{
2418 context.expected_remaining[0..bytes.len],
2419 bytes,
2420 });
2421 return error.DifferentData;
2422 }
2423 context.expected_remaining = context.expected_remaining[bytes.len..];
2424 }
2425 };
2426 var buf: [100]u8 = undefined;
2427 var context = TestStringifyContext{ .expected_remaining = expected };
2428 try stringify(value, StringifyOptions{}, &context, error{
2429 TooMuchData,
2430 DifferentData,
2431 }, TestStringifyContext.testStringifyWrite);
2432 if (context.expected_remaining.len > 0) return error.NotEnoughData;
2433}
2434
2435test "stringify basic types" {
2436 try teststringify("false", false);
2437 try teststringify("true", true);
2438 try teststringify("null", @as(?u8, null));
2439 try teststringify("null", @as(?*u32, null));
2440 try teststringify("42", 42);
2441 try teststringify("4.2e+01", 42.0);
2442 try teststringify("42", @as(u8, 42));
2443 try teststringify("42", @as(u128, 42));
2444 try teststringify("4.2e+01", @as(f32, 42));
2445 try teststringify("4.2e+01", @as(f64, 42));
2446}
2447
2448test "stringify string" {
2449 try teststringify("\"hello\"", "hello");
2450 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r");
2451 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}");
2452 try teststringify("\"with unicode\\u0080\"", "with unicode\u{80}");
2453 try teststringify("\"with unicode\\u00ff\"", "with unicode\u{FF}");
2454 try teststringify("\"with unicode\\u0100\"", "with unicode\u{100}");
2455 try teststringify("\"with unicode\\u0800\"", "with unicode\u{800}");
2456 try teststringify("\"with unicode\\u8000\"", "with unicode\u{8000}");
2457 try teststringify("\"with unicode\\ud799\"", "with unicode\u{D799}");
2458 try teststringify("\"with unicode\\ud800\\udc00\"", "with unicode\u{10000}");
2459 try teststringify("\"with unicode\\udbff\\udfff\"", "with unicode\u{10FFFF}");
2460}
2461
2462test "stringify tagged unions" {
2463 try teststringify("42", union(enum) {
2464 Foo: u32,
2465 Bar: bool,
2466 }{ .Foo = 42 });
2467}
2468
2469test "stringify struct" {
2470 try teststringify("{\"foo\":42}", struct {
2471 foo: u32,
2472 }{ .foo = 42 });
2473}
2474
2475test "stringify struct with void field" {
2476 try teststringify("{\"foo\":42}", struct {
2477 foo: u32,
2478 bar: void = {},
2479 }{ .foo = 42 });
2480}
2481
2482test "stringify array of structs" {
2483 const MyStruct = struct {
2484 foo: u32,
2485 };
2486 try teststringify("[{\"foo\":42},{\"foo\":100},{\"foo\":1000}]", [_]MyStruct{
2487 MyStruct{ .foo = 42 },
2488 MyStruct{ .foo = 100 },
2489 MyStruct{ .foo = 1000 },
2490 });
2491}
2492
2493test "stringify struct with custom stringifier" {
2494 try teststringify("[\"something special\",42]", struct {
2495 foo: u32,
2496 const Self = @This();
2497 pub fn jsonStringify(
2498 value: Self,
2499 options: StringifyOptions,
2500 context: var,
2501 comptime Errors: type,
2502 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
2503 ) !void {
2504 try output(context, "[\"something special\",");
2505 try stringify(42, options, context, Errors, output);
2506 try output(context, "]");
2507 }
2508 }{ .foo = 42 });
2509}
lib/std/math.zig+26-28
......@@ -1,6 +1,4 @@
1const builtin = @import("builtin");
21const std = @import("std.zig");
3const TypeId = builtin.TypeId;
42const assert = std.debug.assert;
53const testing = std.testing;
64
......@@ -89,7 +87,7 @@ pub const snan = @import("math/nan.zig").snan;
8987pub const inf = @import("math/inf.zig").inf;
9088
9189pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool {
92 assert(@typeId(T) == TypeId.Float);
90 assert(@typeInfo(T) == .Float);
9391 return fabs(x - y) < epsilon;
9492}
9593
......@@ -198,7 +196,7 @@ test "" {
198196}
199197
200198pub fn floatMantissaBits(comptime T: type) comptime_int {
201 assert(@typeId(T) == builtin.TypeId.Float);
199 assert(@typeInfo(T) == .Float);
202200
203201 return switch (T.bit_count) {
204202 16 => 10,
......@@ -211,7 +209,7 @@ pub fn floatMantissaBits(comptime T: type) comptime_int {
211209}
212210
213211pub fn floatExponentBits(comptime T: type) comptime_int {
214 assert(@typeId(T) == builtin.TypeId.Float);
212 assert(@typeInfo(T) == .Float);
215213
216214 return switch (T.bit_count) {
217215 16 => 5,
......@@ -446,7 +444,7 @@ pub fn Log2Int(comptime T: type) type {
446444 count += 1;
447445 }
448446
449 return @IntType(false, count);
447 return std.meta.IntType(false, count);
450448}
451449
452450pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
......@@ -462,7 +460,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
462460 if (is_signed) {
463461 magnitude_bits += 1;
464462 }
465 return @IntType(is_signed, magnitude_bits);
463 return std.meta.IntType(is_signed, magnitude_bits);
466464}
467465
468466test "math.IntFittingRange" {
......@@ -526,7 +524,7 @@ fn testOverflow() void {
526524
527525pub fn absInt(x: var) !@TypeOf(x) {
528526 const T = @TypeOf(x);
529 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
527 comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
530528 comptime assert(T.is_signed); // must pass a signed integer to absInt
531529
532530 if (x == minInt(@TypeOf(x))) {
......@@ -560,7 +558,7 @@ fn testAbsFloat() void {
560558pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
561559 @setRuntimeSafety(false);
562560 if (denominator == 0) return error.DivisionByZero;
563 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
561 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
564562 return @divTrunc(numerator, denominator);
565563}
566564
......@@ -581,7 +579,7 @@ fn testDivTrunc() void {
581579pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
582580 @setRuntimeSafety(false);
583581 if (denominator == 0) return error.DivisionByZero;
584 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
582 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
585583 return @divFloor(numerator, denominator);
586584}
587585
......@@ -602,7 +600,7 @@ fn testDivFloor() void {
602600pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
603601 @setRuntimeSafety(false);
604602 if (denominator == 0) return error.DivisionByZero;
605 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
603 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
606604 const result = @divTrunc(numerator, denominator);
607605 if (result * denominator != numerator) return error.UnexpectedRemainder;
608606 return result;
......@@ -676,13 +674,13 @@ pub fn absCast(x: var) t: {
676674 if (@TypeOf(x) == comptime_int) {
677675 break :t comptime_int;
678676 } else {
679 break :t @IntType(false, @TypeOf(x).bit_count);
677 break :t std.meta.IntType(false, @TypeOf(x).bit_count);
680678 }
681679} {
682680 if (@TypeOf(x) == comptime_int) {
683681 return if (x < 0) -x else x;
684682 }
685 const uint = @IntType(false, @TypeOf(x).bit_count);
683 const uint = std.meta.IntType(false, @TypeOf(x).bit_count);
686684 if (x >= 0) return @intCast(uint, x);
687685
688686 return @intCast(uint, -(x + 1)) + 1;
......@@ -703,10 +701,10 @@ test "math.absCast" {
703701
704702/// Returns the negation of the integer parameter.
705703/// Result is a signed integer.
706pub fn negateCast(x: var) !@IntType(true, @TypeOf(x).bit_count) {
704pub fn negateCast(x: var) !std.meta.IntType(true, @TypeOf(x).bit_count) {
707705 if (@TypeOf(x).is_signed) return negate(x);
708706
709 const int = @IntType(true, @TypeOf(x).bit_count);
707 const int = std.meta.IntType(true, @TypeOf(x).bit_count);
710708 if (x > -minInt(int)) return error.Overflow;
711709
712710 if (x == -minInt(int)) return minInt(int);
......@@ -727,8 +725,8 @@ test "math.negateCast" {
727725/// Cast an integer to a different integer type. If the value doesn't fit,
728726/// return an error.
729727pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
730 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
731 comptime assert(@typeId(@TypeOf(x)) == builtin.TypeId.Int); // must pass an integer
728 comptime assert(@typeInfo(T) == .Int); // must pass an integer
729 comptime assert(@typeInfo(@TypeOf(x)) == .Int); // must pass an integer
732730 if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) {
733731 return error.Overflow;
734732 } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) {
......@@ -792,11 +790,11 @@ fn testFloorPowerOfTwo() void {
792790/// Returns the next power of two (if the value is not already a power of two).
793791/// Only unsigned integers can be used. Zero is not an allowed input.
794792/// Result is a type with 1 more bit than the input type.
795pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T.bit_count + 1) {
796 comptime assert(@typeId(T) == builtin.TypeId.Int);
793pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) std.meta.IntType(T.is_signed, T.bit_count + 1) {
794 comptime assert(@typeInfo(T) == .Int);
797795 comptime assert(!T.is_signed);
798796 assert(value != 0);
799 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
797 comptime const PromotedType = std.meta.IntType(T.is_signed, T.bit_count + 1);
800798 comptime const shiftType = std.math.Log2Int(PromotedType);
801799 return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
802800}
......@@ -805,9 +803,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
805803/// Only unsigned integers can be used. Zero is not an allowed input.
806804/// If the value doesn't fit, returns an error.
807805pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {
808 comptime assert(@typeId(T) == builtin.TypeId.Int);
806 comptime assert(@typeInfo(T) == .Int);
809807 comptime assert(!T.is_signed);
810 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
808 comptime const PromotedType = std.meta.IntType(T.is_signed, T.bit_count + 1);
811809 comptime const overflowBit = @as(PromotedType, 1) << T.bit_count;
812810 var x = ceilPowerOfTwoPromote(T, value);
813811 if (overflowBit & x != 0) {
......@@ -878,10 +876,10 @@ test "std.math.log2_int_ceil" {
878876
879877pub fn lossyCast(comptime T: type, value: var) T {
880878 switch (@typeInfo(@TypeOf(value))) {
881 builtin.TypeId.Int => return @intToFloat(T, value),
882 builtin.TypeId.Float => return @floatCast(T, value),
883 builtin.TypeId.ComptimeInt => return @as(T, value),
884 builtin.TypeId.ComptimeFloat => return @as(T, value),
879 .Int => return @intToFloat(T, value),
880 .Float => return @floatCast(T, value),
881 .ComptimeInt => return @as(T, value),
882 .ComptimeFloat => return @as(T, value),
885883 else => @compileError("bad type"),
886884 }
887885}
......@@ -949,8 +947,8 @@ test "max value type" {
949947 testing.expect(x == 2147483647);
950948}
951949
952pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) {
953 const ResultInt = @IntType(T.is_signed, T.bit_count * 2);
950pub fn mulWide(comptime T: type, a: T, b: T) std.meta.IntType(T.is_signed, T.bit_count * 2) {
951 const ResultInt = std.meta.IntType(T.is_signed, T.bit_count * 2);
954952 return @as(ResultInt, a) * @as(ResultInt, b);
955953}
956954
lib/std/math/big/int.zig+7-10
......@@ -1,5 +1,4 @@
11const std = @import("../../std.zig");
2const builtin = @import("builtin");
32const debug = std.debug;
43const testing = std.testing;
54const math = std.math;
......@@ -9,10 +8,8 @@ const ArrayList = std.ArrayList;
98const maxInt = std.math.maxInt;
109const minInt = std.math.minInt;
1110
12const TypeId = builtin.TypeId;
13
1411pub const Limb = usize;
15pub const DoubleLimb = @IntType(false, 2 * Limb.bit_count);
12pub const DoubleLimb = std.meta.IntType(false, 2 * Limb.bit_count);
1613pub const Log2Limb = math.Log2Int(Limb);
1714
1815comptime {
......@@ -270,8 +267,8 @@ pub const Int = struct {
270267 const T = @TypeOf(value);
271268
272269 switch (@typeInfo(T)) {
273 TypeId.Int => |info| {
274 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
270 .Int => |info| {
271 const UT = if (T.is_signed) std.meta.IntType(false, T.bit_count - 1) else T;
275272
276273 try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb));
277274 self.metadata = 0;
......@@ -294,7 +291,7 @@ pub const Int = struct {
294291 }
295292 }
296293 },
297 TypeId.ComptimeInt => {
294 .ComptimeInt => {
298295 comptime var w_value = if (value < 0) -value else value;
299296
300297 const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1;
......@@ -332,9 +329,9 @@ pub const Int = struct {
332329 ///
333330 /// Returns an error if self cannot be narrowed into the requested type without truncation.
334331 pub fn to(self: Int, comptime T: type) ConvertError!T {
335 switch (@typeId(T)) {
336 TypeId.Int => {
337 const UT = @IntType(false, T.bit_count);
332 switch (@typeInfo(T)) {
333 .Int => {
334 const UT = std.meta.IntType(false, T.bit_count);
338335
339336 if (self.bitCountTwosComp() > T.bit_count) {
340337 return error.TargetTooSmall;
lib/std/math/big/rational.zig+6-9
......@@ -1,5 +1,4 @@
11const std = @import("../../std.zig");
2const builtin = @import("builtin");
32const debug = std.debug;
43const math = std.math;
54const mem = std.mem;
......@@ -7,8 +6,6 @@ const testing = std.testing;
76const Allocator = mem.Allocator;
87const ArrayList = std.ArrayList;
98
10const TypeId = builtin.TypeId;
11
129const bn = @import("int.zig");
1310const Limb = bn.Limb;
1411const DoubleLimb = bn.DoubleLimb;
......@@ -129,9 +126,9 @@ pub const Rational = struct {
129126 /// completely represent the provided float.
130127 pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {
131128 // Translated from golang.go/src/math/big/rat.go.
132 debug.assert(@typeId(T) == builtin.TypeId.Float);
129 debug.assert(@typeInfo(T) == .Float);
133130
134 const UnsignedIntType = @IntType(false, T.bit_count);
131 const UnsignedIntType = std.meta.IntType(false, T.bit_count);
135132 const f_bits = @bitCast(UnsignedIntType, f);
136133
137134 const exponent_bits = math.floatExponentBits(T);
......@@ -187,10 +184,10 @@ pub const Rational = struct {
187184 pub fn toFloat(self: Rational, comptime T: type) !T {
188185 // Translated from golang.go/src/math/big/rat.go.
189186 // TODO: Indicate whether the result is not exact.
190 debug.assert(@typeId(T) == builtin.TypeId.Float);
187 debug.assert(@typeInfo(T) == .Float);
191188
192189 const fsize = T.bit_count;
193 const BitReprType = @IntType(false, T.bit_count);
190 const BitReprType = std.meta.IntType(false, T.bit_count);
194191
195192 const msize = math.floatMantissaBits(T);
196193 const msize1 = msize + 1;
......@@ -465,7 +462,7 @@ pub const Rational = struct {
465462 }
466463};
467464
468const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count);
465const SignedDoubleLimb = std.meta.IntType(true, DoubleLimb.bit_count);
469466
470467fn gcd(rma: *Int, x: Int, y: Int) !void {
471468 rma.assertWritable();
......@@ -653,7 +650,7 @@ test "big.rational gcd one large" {
653650}
654651
655652fn extractLowBits(a: Int, comptime T: type) T {
656 testing.expect(@typeId(T) == builtin.TypeId.Int);
653 testing.expect(@typeInfo(T) == .Int);
657654
658655 if (T.bit_count <= Limb.bit_count) {
659656 return @truncate(T, a.limbs[0]);
lib/std/math/cos.zig+1-1
......@@ -44,7 +44,7 @@ const pi4c = 2.69515142907905952645E-15;
4444const m4pi = 1.273239544735162542821171882678754627704620361328125;
4545
4646fn cos_(comptime T: type, x_: T) T {
47 const I = @IntType(true, T.bit_count);
47 const I = std.meta.IntType(true, T.bit_count);
4848
4949 var x = x_;
5050 if (math.isNan(x) or math.isInf(x)) {
lib/std/math/ln.zig+5-7
......@@ -7,8 +7,6 @@
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
1210
1311/// Returns the natural logarithm of x.
1412///
......@@ -19,21 +17,21 @@ const TypeId = builtin.TypeId;
1917/// - ln(nan) = nan
2018pub fn ln(x: var) @TypeOf(x) {
2119 const T = @TypeOf(x);
22 switch (@typeId(T)) {
23 TypeId.ComptimeFloat => {
20 switch (@typeInfo(T)) {
21 .ComptimeFloat => {
2422 return @as(comptime_float, ln_64(x));
2523 },
26 TypeId.Float => {
24 .Float => {
2725 return switch (T) {
2826 f32 => ln_32(x),
2927 f64 => ln_64(x),
3028 else => @compileError("ln not implemented for " ++ @typeName(T)),
3129 };
3230 },
33 TypeId.ComptimeInt => {
31 .ComptimeInt => {
3432 return @as(comptime_int, math.floor(ln_64(@as(f64, x))));
3533 },
36 TypeId.Int => {
34 .Int => {
3735 return @as(T, math.floor(ln_64(@as(f64, x))));
3836 },
3937 else => @compileError("ln not implemented for " ++ @typeName(T)),
lib/std/math/log.zig+6-8
......@@ -6,8 +6,6 @@
66
77const std = @import("../std.zig");
88const math = std.math;
9const builtin = @import("builtin");
10const TypeId = builtin.TypeId;
119const expect = std.testing.expect;
1210
1311/// Returns the logarithm of x for the provided base.
......@@ -16,24 +14,24 @@ pub fn log(comptime T: type, base: T, x: T) T {
1614 return math.log2(x);
1715 } else if (base == 10) {
1816 return math.log10(x);
19 } else if ((@typeId(T) == TypeId.Float or @typeId(T) == TypeId.ComptimeFloat) and base == math.e) {
17 } else if ((@typeInfo(T) == .Float or @typeInfo(T) == .ComptimeFloat) and base == math.e) {
2018 return math.ln(x);
2119 }
2220
2321 const float_base = math.lossyCast(f64, base);
24 switch (@typeId(T)) {
25 TypeId.ComptimeFloat => {
22 switch (@typeInfo(T)) {
23 .ComptimeFloat => {
2624 return @as(comptime_float, math.ln(@as(f64, x)) / math.ln(float_base));
2725 },
28 TypeId.ComptimeInt => {
26 .ComptimeInt => {
2927 return @as(comptime_int, math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));
3028 },
31 builtin.TypeId.Int => {
29 .Int => {
3230 // TODO implement integer log without using float math
3331 return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base)));
3432 },
3533
36 builtin.TypeId.Float => {
34 .Float => {
3735 switch (T) {
3836 f32 => return @floatCast(f32, math.ln(@as(f64, x)) / math.ln(float_base)),
3937 f64 => return math.ln(x) / math.ln(float_base),
lib/std/math/log10.zig+5-7
......@@ -7,8 +7,6 @@
77const std = @import("../std.zig");
88const math = std.math;
99const testing = std.testing;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
1210const maxInt = std.math.maxInt;
1311
1412/// Returns the base-10 logarithm of x.
......@@ -20,21 +18,21 @@ const maxInt = std.math.maxInt;
2018/// - log10(nan) = nan
2119pub fn log10(x: var) @TypeOf(x) {
2220 const T = @TypeOf(x);
23 switch (@typeId(T)) {
24 TypeId.ComptimeFloat => {
21 switch (@typeInfo(T)) {
22 .ComptimeFloat => {
2523 return @as(comptime_float, log10_64(x));
2624 },
27 TypeId.Float => {
25 .Float => {
2826 return switch (T) {
2927 f32 => log10_32(x),
3028 f64 => log10_64(x),
3129 else => @compileError("log10 not implemented for " ++ @typeName(T)),
3230 };
3331 },
34 TypeId.ComptimeInt => {
32 .ComptimeInt => {
3533 return @as(comptime_int, math.floor(log10_64(@as(f64, x))));
3634 },
37 TypeId.Int => {
35 .Int => {
3836 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));
3937 },
4038 else => @compileError("log10 not implemented for " ++ @typeName(T)),
lib/std/math/log2.zig+5-7
......@@ -7,8 +7,6 @@
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
1210const maxInt = std.math.maxInt;
1311
1412/// Returns the base-2 logarithm of x.
......@@ -20,18 +18,18 @@ const maxInt = std.math.maxInt;
2018/// - log2(nan) = nan
2119pub fn log2(x: var) @TypeOf(x) {
2220 const T = @TypeOf(x);
23 switch (@typeId(T)) {
24 TypeId.ComptimeFloat => {
21 switch (@typeInfo(T)) {
22 .ComptimeFloat => {
2523 return @as(comptime_float, log2_64(x));
2624 },
27 TypeId.Float => {
25 .Float => {
2826 return switch (T) {
2927 f32 => log2_32(x),
3028 f64 => log2_64(x),
3129 else => @compileError("log2 not implemented for " ++ @typeName(T)),
3230 };
3331 },
34 TypeId.ComptimeInt => comptime {
32 .ComptimeInt => comptime {
3533 var result = 0;
3634 var x_shifted = x;
3735 while (b: {
......@@ -40,7 +38,7 @@ pub fn log2(x: var) @TypeOf(x) {
4038 }) : (result += 1) {}
4139 return result;
4240 },
43 TypeId.Int => {
41 .Int => {
4442 return math.log2_int(T, x);
4543 },
4644 else => @compileError("log2 not implemented for " ++ @typeName(T)),
lib/std/math/pow.zig+1-1
......@@ -145,7 +145,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
145145 var xe = r2.exponent;
146146 var x1 = r2.significand;
147147
148 var i = @floatToInt(@IntType(true, T.bit_count), yi);
148 var i = @floatToInt(std.meta.IntType(true, T.bit_count), yi);
149149 while (i != 0) : (i >>= 1) {
150150 const overflow_shift = math.floatExponentBits(T) + 1;
151151 if (xe < -(1 << overflow_shift) or (1 << overflow_shift) < xe) {
lib/std/math/sin.zig+1-1
......@@ -45,7 +45,7 @@ const pi4c = 2.69515142907905952645E-15;
4545const m4pi = 1.273239544735162542821171882678754627704620361328125;
4646
4747fn sin_(comptime T: type, x_: T) T {
48 const I = @IntType(true, T.bit_count);
48 const I = std.meta.IntType(true, T.bit_count);
4949
5050 var x = x_;
5151 if (x == 0 or math.isNan(x)) {
lib/std/math/sqrt.zig+3-3
......@@ -31,7 +31,7 @@ pub fn sqrt(x: var) Sqrt(@TypeOf(x)) {
3131 }
3232}
3333
34fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
34fn sqrt_int(comptime T: type, value: T) std.meta.IntType(false, T.bit_count / 2) {
3535 var op = value;
3636 var res: T = 0;
3737 var one: T = 1 << (T.bit_count - 2);
......@@ -50,7 +50,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
5050 one >>= 2;
5151 }
5252
53 const ResultType = @IntType(false, T.bit_count / 2);
53 const ResultType = std.meta.IntType(false, T.bit_count / 2);
5454 return @intCast(ResultType, res);
5555}
5656
......@@ -66,7 +66,7 @@ test "math.sqrt_int" {
6666/// Returns the return type `sqrt` will return given an operand of type `T`.
6767pub fn Sqrt(comptime T: type) type {
6868 return switch (@typeInfo(T)) {
69 .Int => |int| @IntType(false, int.bits / 2),
69 .Int => |int| std.meta.IntType(false, int.bits / 2),
7070 else => T,
7171 };
7272}
lib/std/math/tan.zig+1-1
......@@ -38,7 +38,7 @@ const pi4c = 2.69515142907905952645E-15;
3838const m4pi = 1.273239544735162542821171882678754627704620361328125;
3939
4040fn tan_(comptime T: type, x_: T) T {
41 const I = @IntType(true, T.bit_count);
41 const I = std.meta.IntType(true, T.bit_count);
4242
4343 var x = x_;
4444 if (x == 0 or math.isNan(x)) {
lib/std/mem.zig+287-18
......@@ -132,7 +132,7 @@ pub const Allocator = struct {
132132 // their own frame with @Frame(func).
133133 return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n];
134134 } else {
135 return @bytesToSlice(T, @alignCast(a, byte_slice));
135 return mem.bytesAsSlice(T, @alignCast(a, byte_slice));
136136 }
137137 }
138138
......@@ -173,7 +173,7 @@ pub const Allocator = struct {
173173 return @as([*]align(new_alignment) T, undefined)[0..0];
174174 }
175175
176 const old_byte_slice = @sliceToBytes(old_mem);
176 const old_byte_slice = mem.sliceAsBytes(old_mem);
177177 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
178178 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
179179 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
......@@ -181,7 +181,7 @@ pub const Allocator = struct {
181181 if (new_n > old_mem.len) {
182182 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);
183183 }
184 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));
184 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
185185 }
186186
187187 /// Prefer calling realloc to shrink if you can tolerate failure, such as
......@@ -221,18 +221,18 @@ pub const Allocator = struct {
221221 // new_n <= old_mem.len and the multiplication didn't overflow for that operation.
222222 const byte_count = @sizeOf(T) * new_n;
223223
224 const old_byte_slice = @sliceToBytes(old_mem);
224 const old_byte_slice = mem.sliceAsBytes(old_mem);
225225 @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);
226226 const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
227227 assert(byte_slice.len == byte_count);
228 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));
228 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
229229 }
230230
231231 /// Free an array allocated with `alloc`. To free a single item,
232232 /// see `destroy`.
233233 pub fn free(self: *Allocator, memory: var) void {
234234 const Slice = @typeInfo(@TypeOf(memory)).Pointer;
235 const bytes = @sliceToBytes(memory);
235 const bytes = mem.sliceAsBytes(memory);
236236 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
237237 if (bytes_len == 0) return;
238238 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
......@@ -276,18 +276,67 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
276276 d.* = value;
277277}
278278
279/// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function.
280/// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when
281/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
282/// function used, examine closely - it may be a code smell.
279283/// Zero initializes the type.
280/// This can be used to zero initialize a C-struct.
284/// This can be used to zero initialize a any type for which it makes sense. Structs will be initialized recursively.
281285pub fn zeroes(comptime T: type) T {
282 if (@sizeOf(T) == 0) return T{};
283
284 if (comptime meta.containerLayout(T) != .Extern) {
285 @compileError("TODO: Currently this only works for extern types");
286 switch (@typeInfo(T)) {
287 .ComptimeInt, .Int, .ComptimeFloat, .Float => {
288 return @as(T, 0);
289 },
290 .Enum, .EnumLiteral => {
291 return @intToEnum(T, 0);
292 },
293 .Void => {
294 return {};
295 },
296 .Bool => {
297 return false;
298 },
299 .Optional, .Null => {
300 return null;
301 },
302 .Struct => |struct_info| {
303 if (@sizeOf(T) == 0) return T{};
304 if (comptime meta.containerLayout(T) == .Extern) {
305 var item: T = undefined;
306 @memset(@ptrCast([*]u8, &item), 0, @sizeOf(T));
307 return item;
308 } else {
309 var structure: T = undefined;
310 inline for (struct_info.fields) |field| {
311 @field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
312 }
313 return structure;
314 }
315 },
316 .Pointer => |ptr_info| {
317 switch (ptr_info.size) {
318 .Slice => {
319 return &[_]ptr_info.child{};
320 },
321 .C => {
322 return null;
323 },
324 .One, .Many => {
325 @compileError("Can't set a non nullable pointer to zero.");
326 },
327 }
328 },
329 .Array => |info| {
330 var array: T = undefined;
331 for (array) |*element| {
332 element.* = zeroes(info.child);
333 }
334 return array;
335 },
336 .Vector, .ErrorUnion, .ErrorSet, .Union, .Fn, .BoundFn, .Type, .NoReturn, .Undefined, .Opaque, .Frame, .AnyFrame, => {
337 @compileError("Can't set a "++ @typeName(T) ++" to zero.");
338 },
286339 }
287
288 var item: T = undefined;
289 @memset(@ptrCast([*]u8, &item), 0, @sizeOf(T));
290 return item;
291340}
292341
293342test "mem.zeroes" {
......@@ -301,6 +350,62 @@ test "mem.zeroes" {
301350
302351 testing.expect(a.x == 0);
303352 testing.expect(a.y == 10);
353
354 const ZigStruct = struct {
355 const IntegralTypes = struct {
356 integer_0: i0,
357 integer_8: i8,
358 integer_16: i16,
359 integer_32: i32,
360 integer_64: i64,
361 integer_128: i128,
362 unsigned_0: u0,
363 unsigned_8: u8,
364 unsigned_16: u16,
365 unsigned_32: u32,
366 unsigned_64: u64,
367 unsigned_128: u128,
368
369 float_32: f32,
370 float_64: f64,
371 };
372
373 integral_types: IntegralTypes,
374
375 const Pointers = struct {
376 optional: ?*u8,
377 c_pointer: [*c]u8,
378 slice: []u8,
379 };
380 pointers: Pointers,
381
382 array: [2]u32,
383 optional_int: ?u8,
384 empty: void,
385 };
386
387 const b = zeroes(ZigStruct);
388 testing.expectEqual(@as(i8, 0), b.integral_types.integer_0);
389 testing.expectEqual(@as(i8, 0), b.integral_types.integer_8);
390 testing.expectEqual(@as(i16, 0), b.integral_types.integer_16);
391 testing.expectEqual(@as(i32, 0), b.integral_types.integer_32);
392 testing.expectEqual(@as(i64, 0), b.integral_types.integer_64);
393 testing.expectEqual(@as(i128, 0), b.integral_types.integer_128);
394 testing.expectEqual(@as(u8, 0), b.integral_types.unsigned_0);
395 testing.expectEqual(@as(u8, 0), b.integral_types.unsigned_8);
396 testing.expectEqual(@as(u16, 0), b.integral_types.unsigned_16);
397 testing.expectEqual(@as(u32, 0), b.integral_types.unsigned_32);
398 testing.expectEqual(@as(u64, 0), b.integral_types.unsigned_64);
399 testing.expectEqual(@as(u128, 0), b.integral_types.unsigned_128);
400 testing.expectEqual(@as(f32, 0), b.integral_types.float_32);
401 testing.expectEqual(@as(f64, 0), b.integral_types.float_64);
402 testing.expectEqual(@as(?*u8, null), b.pointers.optional);
403 testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer);
404 testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice);
405 for (b.array) |e| {
406 testing.expectEqual(@as(u32, 0), e);
407 }
408 testing.expectEqual(@as(?u8, null), b.optional_int);
304409}
305410
306411pub fn secureZero(comptime T: type, s: []T) void {
......@@ -387,13 +492,21 @@ pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
387492 return true;
388493}
389494
390/// Copies ::m to newly allocated memory. Caller is responsible to free it.
495/// Copies `m` to newly allocated memory. Caller owns the memory.
391496pub fn dupe(allocator: *Allocator, comptime T: type, m: []const T) ![]T {
392497 const new_buf = try allocator.alloc(T, m.len);
393498 copy(T, new_buf, m);
394499 return new_buf;
395500}
396501
502/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.
503pub fn dupeZ(allocator: *Allocator, comptime T: type, m: []const T) ![:0]T {
504 const new_buf = try allocator.alloc(T, m.len + 1);
505 copy(T, new_buf, m);
506 new_buf[m.len] = 0;
507 return new_buf[0..m.len :0];
508}
509
397510/// Remove values from the beginning of a slice.
398511pub fn trimLeft(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
399512 var begin: usize = 0;
......@@ -700,7 +813,7 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
700813 assert(buffer.len >= @divExact(T.bit_count, 8));
701814
702815 // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
703 const uint = @IntType(false, T.bit_count);
816 const uint = std.meta.IntType(false, T.bit_count);
704817 var bits = @truncate(uint, value);
705818 for (buffer) |*b| {
706819 b.* = @truncate(u8, bits);
......@@ -717,7 +830,7 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
717830 assert(buffer.len >= @divExact(T.bit_count, 8));
718831
719832 // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
720 const uint = @IntType(false, T.bit_count);
833 const uint = std.meta.IntType(false, T.bit_count);
721834 var bits = @truncate(uint, value);
722835 var index: usize = buffer.len;
723836 while (index != 0) {
......@@ -1478,6 +1591,162 @@ test "bytesToValue" {
14781591 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
14791592}
14801593
1594//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1595fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
1596 if (!(trait.isSlice(bytesType) and meta.Child(bytesType) == u8) and !(trait.isPtrTo(.Array)(bytesType) and meta.Child(meta.Child(bytesType)) == u8)) {
1597 @compileError("expected []u8 or *[_]u8, passed " ++ @typeName(bytesType));
1598 }
1599
1600 if (trait.isPtrTo(.Array)(bytesType) and @typeInfo(meta.Child(bytesType)).Array.len % @sizeOf(T) != 0) {
1601 @compileError("number of bytes in " ++ @typeName(bytesType) ++ " is not divisible by size of " ++ @typeName(T));
1602 }
1603
1604 const alignment = meta.alignment(bytesType);
1605
1606 return if (trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
1607}
1608
1609pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
1610 const bytesSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(bytes))) bytes[0..] else bytes;
1611
1612 // let's not give an undefined pointer to @ptrCast
1613 // it may be equal to zero and fail a null check
1614 if (bytesSlice.len == 0) {
1615 return &[0]T{};
1616 }
1617
1618 const bytesType = @TypeOf(bytesSlice);
1619 const alignment = comptime meta.alignment(bytesType);
1620
1621 const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T;
1622
1623 return @ptrCast(castTarget, bytesSlice.ptr)[0..@divExact(bytes.len, @sizeOf(T))];
1624}
1625
1626test "bytesAsSlice" {
1627 const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
1628 const slice = bytesAsSlice(u16, bytes[0..]);
1629 testing.expect(slice.len == 2);
1630 testing.expect(bigToNative(u16, slice[0]) == 0xDEAD);
1631 testing.expect(bigToNative(u16, slice[1]) == 0xBEEF);
1632}
1633
1634test "bytesAsSlice keeps pointer alignment" {
1635 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
1636 const numbers = bytesAsSlice(u32, bytes[0..]);
1637 comptime testing.expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
1638}
1639
1640test "bytesAsSlice on a packed struct" {
1641 const F = packed struct {
1642 a: u8,
1643 };
1644
1645 var b = [1]u8{9};
1646 var f = bytesAsSlice(F, &b);
1647 testing.expect(f[0].a == 9);
1648}
1649
1650test "bytesAsSlice with specified alignment" {
1651 var bytes align(4) = [_]u8{
1652 0x33,
1653 0x33,
1654 0x33,
1655 0x33,
1656 };
1657 const slice: []u32 = std.mem.bytesAsSlice(u32, bytes[0..]);
1658 testing.expect(slice[0] == 0x33333333);
1659}
1660
1661//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1662fn SliceAsBytesReturnType(comptime sliceType: type) type {
1663 if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) {
1664 @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType));
1665 }
1666
1667 const alignment = meta.alignment(sliceType);
1668
1669 return if (trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
1670}
1671
1672pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
1673 const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
1674
1675 // let's not give an undefined pointer to @ptrCast
1676 // it may be equal to zero and fail a null check
1677 if (actualSlice.len == 0) {
1678 return &[0]u8{};
1679 }
1680
1681 const sliceType = @TypeOf(actualSlice);
1682 const alignment = comptime meta.alignment(sliceType);
1683
1684 const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
1685
1686 return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))];
1687}
1688
1689test "sliceAsBytes" {
1690 const bytes = [_]u16{ 0xDEAD, 0xBEEF };
1691 const slice = sliceAsBytes(bytes[0..]);
1692 testing.expect(slice.len == 4);
1693 testing.expect(eql(u8, slice, switch (builtin.endian) {
1694 .Big => "\xDE\xAD\xBE\xEF",
1695 .Little => "\xAD\xDE\xEF\xBE",
1696 }));
1697}
1698
1699test "sliceAsBytes packed struct at runtime and comptime" {
1700 const Foo = packed struct {
1701 a: u4,
1702 b: u4,
1703 };
1704 const S = struct {
1705 fn doTheTest() void {
1706 var foo: Foo = undefined;
1707 var slice = sliceAsBytes(@as(*[1]Foo, &foo)[0..1]);
1708 slice[0] = 0x13;
1709 switch (builtin.endian) {
1710 .Big => {
1711 testing.expect(foo.a == 0x1);
1712 testing.expect(foo.b == 0x3);
1713 },
1714 .Little => {
1715 testing.expect(foo.a == 0x3);
1716 testing.expect(foo.b == 0x1);
1717 },
1718 }
1719 }
1720 };
1721 S.doTheTest();
1722 comptime S.doTheTest();
1723}
1724
1725test "sliceAsBytes and bytesAsSlice back" {
1726 testing.expect(@sizeOf(i32) == 4);
1727
1728 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
1729 const big_thing_slice: []i32 = big_thing_array[0..];
1730
1731 const bytes = sliceAsBytes(big_thing_slice);
1732 testing.expect(bytes.len == 4 * 4);
1733
1734 bytes[4] = 0;
1735 bytes[5] = 0;
1736 bytes[6] = 0;
1737 bytes[7] = 0;
1738 testing.expect(big_thing_slice[1] == 0);
1739
1740 const big_thing_again = bytesAsSlice(i32, bytes);
1741 testing.expect(big_thing_again[2] == 3);
1742
1743 big_thing_again[2] = -1;
1744 testing.expect(bytes[8] == math.maxInt(u8));
1745 testing.expect(bytes[9] == math.maxInt(u8));
1746 testing.expect(bytes[10] == math.maxInt(u8));
1747 testing.expect(bytes[11] == math.maxInt(u8));
1748}
1749
14811750fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
14821751 if (trait.isConstPtr(T))
14831752 return *const [length]meta.Child(meta.Child(T));
lib/std/meta.zig+15-5
......@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {
437437 },
438438 .Pointer => |info| {
439439 return switch (info.size) {
440 .One, .Many, .C, => a == b,
440 .One, .Many, .C => a == b,
441441 .Slice => a.ptr == b.ptr and a.len == b.len,
442442 };
443443 },
......@@ -536,9 +536,8 @@ test "intToEnum with error return" {
536536pub const IntToEnumError = error{InvalidEnumTag};
537537
538538pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag {
539 comptime var i = 0;
540 inline while (i != @memberCount(Tag)) : (i += 1) {
541 const this_tag_value = @field(Tag, @memberName(Tag, i));
539 inline for (@typeInfo(Tag).Enum.fields) |f| {
540 const this_tag_value = @field(Tag, f.name);
542541 if (tag_int == @enumToInt(this_tag_value)) {
543542 return this_tag_value;
544543 }
......@@ -559,7 +558,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {
559558/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.
560559pub fn refAllDecls(comptime T: type) void {
561560 if (!builtin.is_test) return;
562 _ = declarations(T);
561 inline for (declarations(T)) |decl| {
562 _ = decl;
563 }
563564}
564565
565566/// Returns a slice of pointers to public declarations of a namespace.
......@@ -579,3 +580,12 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De
579580 return &array;
580581 }
581582}
583
584pub fn IntType(comptime is_signed: bool, comptime bit_count: u16) type {
585 return @Type(TypeInfo{
586 .Int = .{
587 .is_signed = is_signed,
588 .bits = bit_count,
589 },
590 });
591}
lib/std/meta/trait.zig+22-6
......@@ -1,5 +1,5 @@
11const std = @import("../std.zig");
2const builtin = @import("builtin");
2const builtin = std.builtin;
33const mem = std.mem;
44const debug = std.debug;
55const testing = std.testing;
......@@ -54,7 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {
5454 if (!comptime isContainer(T)) return false;
5555 if (!comptime @hasDecl(T, name)) return false;
5656 const DeclType = @TypeOf(@field(T, name));
57 return @typeId(DeclType) == .Fn;
57 return @typeInfo(DeclType) == .Fn;
5858 }
5959 };
6060 return Closure.trait;
......@@ -105,7 +105,7 @@ test "std.meta.trait.hasField" {
105105pub fn is(comptime id: builtin.TypeId) TraitFn {
106106 const Closure = struct {
107107 pub fn trait(comptime T: type) bool {
108 return id == @typeId(T);
108 return id == @typeInfo(T);
109109 }
110110 };
111111 return Closure.trait;
......@@ -123,7 +123,7 @@ pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
123123 const Closure = struct {
124124 pub fn trait(comptime T: type) bool {
125125 if (!comptime isSingleItemPtr(T)) return false;
126 return id == @typeId(meta.Child(T));
126 return id == @typeInfo(meta.Child(T));
127127 }
128128 };
129129 return Closure.trait;
......@@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" {
135135 testing.expect(!isPtrTo(.Struct)(**struct {}));
136136}
137137
138pub fn isSliceOf(comptime id: builtin.TypeId) TraitFn {
139 const Closure = struct {
140 pub fn trait(comptime T: type) bool {
141 if (!comptime isSlice(T)) return false;
142 return id == @typeInfo(meta.Child(T));
143 }
144 };
145 return Closure.trait;
146}
147
148test "std.meta.trait.isSliceOf" {
149 testing.expect(!isSliceOf(.Struct)(struct {}));
150 testing.expect(isSliceOf(.Struct)([]struct {}));
151 testing.expect(!isSliceOf(.Struct)([][]struct {}));
152}
153
138154///////////Strait trait Fns
139155
140156//@TODO:
......@@ -269,7 +285,7 @@ test "std.meta.trait.isIndexable" {
269285}
270286
271287pub fn isNumber(comptime T: type) bool {
272 return switch (@typeId(T)) {
288 return switch (@typeInfo(T)) {
273289 .Int, .Float, .ComptimeInt, .ComptimeFloat => true,
274290 else => false,
275291 };
......@@ -304,7 +320,7 @@ test "std.meta.trait.isConstPtr" {
304320}
305321
306322pub fn isContainer(comptime T: type) bool {
307 return switch (@typeId(T)) {
323 return switch (@typeInfo(T)) {
308324 .Struct, .Union, .Enum => true,
309325 else => false,
310326 };
lib/std/net.zig+3-3
......@@ -18,7 +18,7 @@ pub const Address = extern union {
1818 in6: os.sockaddr_in6,
1919 un: if (has_unix_sockets) os.sockaddr_un else void,
2020
21 // TODO this crashed the compiler
21 // TODO this crashed the compiler. https://github.com/ziglang/zig/issues/3512
2222 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
2323
2424 pub fn parseIp(name: []const u8, port: u16) !Address {
......@@ -120,7 +120,7 @@ pub const Address = extern union {
120120 ip_slice[10] = 0xff;
121121 ip_slice[11] = 0xff;
122122
123 const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]);
123 const ptr = mem.sliceAsBytes(@as(*const [1]u32, &addr)[0..]);
124124
125125 ip_slice[12] = ptr[0];
126126 ip_slice[13] = ptr[1];
......@@ -164,7 +164,7 @@ pub const Address = extern union {
164164 .addr = undefined,
165165 },
166166 };
167 const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]);
167 const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.in.addr)[0..]);
168168
169169 var x: u8 = 0;
170170 var index: u8 = 0;
lib/std/os.zig+248-40
......@@ -70,6 +70,8 @@ else switch (builtin.os) {
7070pub usingnamespace @import("os/bits.zig");
7171
7272/// See also `getenv`. Populated by startup code before main().
73/// TODO this is a footgun because the value will be undefined when using `zig build-lib`.
74/// https://github.com/ziglang/zig/issues/4524
7375pub var environ: [][*:0]u8 = undefined;
7476
7577/// Populated by startup code before main().
......@@ -916,10 +918,17 @@ pub const ExecveError = error{
916918 NameTooLong,
917919} || UnexpectedError;
918920
921/// Deprecated in favor of `execveZ`.
922pub const execveC = execveZ;
923
919924/// Like `execve` except the parameters are null-terminated,
920925/// matching the syscall API on all targets. This removes the need for an allocator.
921/// This function ignores PATH environment variable. See `execvpeC` for that.
922pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {
926/// This function ignores PATH environment variable. See `execvpeZ` for that.
927pub fn execveZ(
928 path: [*:0]const u8,
929 child_argv: [*:null]const ?[*:0]const u8,
930 envp: [*:null]const ?[*:0]const u8,
931) ExecveError {
923932 switch (errno(system.execve(path, child_argv, envp))) {
924933 0 => unreachable,
925934 EFAULT => unreachable,
......@@ -942,19 +951,42 @@ pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, en
942951 }
943952}
944953
945/// Like `execvpe` except the parameters are null-terminated,
946/// matching the syscall API on all targets. This removes the need for an allocator.
947/// This function also uses the PATH environment variable to get the full path to the executable.
948/// If `file` is an absolute path, this is the same as `execveC`.
949pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {
954/// Deprecated in favor of `execvpeZ`.
955pub const execvpeC = execvpeZ;
956
957pub const Arg0Expand = enum {
958 expand,
959 no_expand,
960};
961
962/// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
963/// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall.
964/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in.
965pub fn execvpeZ_expandArg0(
966 comptime arg0_expand: Arg0Expand,
967 file: [*:0]const u8,
968 child_argv: switch (arg0_expand) {
969 .expand => [*:null]?[*:0]const u8,
970 .no_expand => [*:null]const ?[*:0]const u8,
971 },
972 envp: [*:null]const ?[*:0]const u8,
973) ExecveError {
950974 const file_slice = mem.toSliceConst(u8, file);
951 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveC(file, child_argv, envp);
975 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
952976
953 const PATH = getenv("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
977 const PATH = getenvZ("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
954978 var path_buf: [MAX_PATH_BYTES]u8 = undefined;
955979 var it = mem.tokenize(PATH, ":");
956980 var seen_eacces = false;
957981 var err: ExecveError = undefined;
982
983 // In case of expanding arg0 we must put it back if we return with an error.
984 const prev_arg0 = child_argv[0];
985 defer switch (arg0_expand) {
986 .expand => child_argv[0] = prev_arg0,
987 .no_expand => {},
988 };
989
958990 while (it.next()) |search_path| {
959991 if (path_buf.len < search_path.len + file_slice.len + 1) return error.NameTooLong;
960992 mem.copy(u8, &path_buf, search_path);
......@@ -962,7 +994,12 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e
962994 mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice);
963995 const path_len = search_path.len + file_slice.len + 1;
964996 path_buf[path_len] = 0;
965 err = execveC(path_buf[0..path_len :0].ptr, child_argv, envp);
997 const full_path = path_buf[0..path_len :0].ptr;
998 switch (arg0_expand) {
999 .expand => child_argv[0] = full_path,
1000 .no_expand => {},
1001 }
1002 err = execveZ(full_path, child_argv, envp);
9661003 switch (err) {
9671004 error.AccessDenied => seen_eacces = true,
9681005 error.FileNotFound, error.NotDir => {},
......@@ -973,13 +1010,24 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e
9731010 return err;
9741011}
9751012
976/// This function must allocate memory to add a null terminating bytes on path and each arg.
977/// It must also convert to KEY=VALUE\0 format for environment variables, and include null
978/// pointers after the args and after the environment variables.
979/// `argv_slice[0]` is the executable path.
1013/// Like `execvpe` except the parameters are null-terminated,
1014/// matching the syscall API on all targets. This removes the need for an allocator.
9801015/// This function also uses the PATH environment variable to get the full path to the executable.
981pub fn execvpe(
1016/// If `file` is an absolute path, this is the same as `execveZ`.
1017pub fn execvpeZ(
1018 file: [*:0]const u8,
1019 argv: [*:null]const ?[*:0]const u8,
1020 envp: [*:null]const ?[*:0]const u8,
1021) ExecveError {
1022 return execvpeZ_expandArg0(.no_expand, file, argv, envp);
1023}
1024
1025/// This is the same as `execvpe` except if the `arg0_expand` parameter is set to `.expand`,
1026/// then argv[0] will be replaced with the expanded version of it, after resolving in accordance
1027/// with the PATH environment variable.
1028pub fn execvpe_expandArg0(
9821029 allocator: *mem.Allocator,
1030 arg0_expand: Arg0Expand,
9831031 argv_slice: []const []const u8,
9841032 env_map: *const std.BufMap,
9851033) (ExecveError || error{OutOfMemory}) {
......@@ -1004,7 +1052,23 @@ pub fn execvpe(
10041052 const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);
10051053 defer freeNullDelimitedEnvMap(allocator, envp_buf);
10061054
1007 return execvpeC(argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr);
1055 switch (arg0_expand) {
1056 .expand => return execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr),
1057 .no_expand => return execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr),
1058 }
1059}
1060
1061/// This function must allocate memory to add a null terminating bytes on path and each arg.
1062/// It must also convert to KEY=VALUE\0 format for environment variables, and include null
1063/// pointers after the args and after the environment variables.
1064/// `argv_slice[0]` is the executable path.
1065/// This function also uses the PATH environment variable to get the full path to the executable.
1066pub fn execvpe(
1067 allocator: *mem.Allocator,
1068 argv_slice: []const []const u8,
1069 env_map: *const std.BufMap,
1070) (ExecveError || error{OutOfMemory}) {
1071 return execvpe_expandArg0(allocator, .no_expand, argv_slice, env_map);
10081072}
10091073
10101074pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {
......@@ -1038,9 +1102,37 @@ pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8)
10381102}
10391103
10401104/// Get an environment variable.
1041/// See also `getenvC`.
1042/// TODO make this go through libc when we have it
1105/// See also `getenvZ`.
10431106pub fn getenv(key: []const u8) ?[]const u8 {
1107 if (builtin.link_libc) {
1108 var small_key_buf: [64]u8 = undefined;
1109 if (key.len < small_key_buf.len) {
1110 mem.copy(u8, &small_key_buf, key);
1111 small_key_buf[key.len] = 0;
1112 const key0 = small_key_buf[0..key.len :0];
1113 return getenvZ(key0);
1114 }
1115 // Search the entire `environ` because we don't have a null terminated pointer.
1116 var ptr = std.c.environ;
1117 while (ptr.*) |line| : (ptr += 1) {
1118 var line_i: usize = 0;
1119 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
1120 const this_key = line[0..line_i];
1121
1122 if (!mem.eql(u8, this_key, key)) continue;
1123
1124 var end_i: usize = line_i;
1125 while (line[end_i] != 0) : (end_i += 1) {}
1126 const value = line[line_i + 1 .. end_i];
1127
1128 return value;
1129 }
1130 return null;
1131 }
1132 if (builtin.os == .windows) {
1133 @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
1134 }
1135 // TODO see https://github.com/ziglang/zig/issues/4524
10441136 for (environ) |ptr| {
10451137 var line_i: usize = 0;
10461138 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
......@@ -1056,16 +1148,50 @@ pub fn getenv(key: []const u8) ?[]const u8 {
10561148 return null;
10571149}
10581150
1151/// Deprecated in favor of `getenvZ`.
1152pub const getenvC = getenvZ;
1153
10591154/// Get an environment variable with a null-terminated name.
10601155/// See also `getenv`.
1061pub fn getenvC(key: [*:0]const u8) ?[]const u8 {
1156pub fn getenvZ(key: [*:0]const u8) ?[]const u8 {
10621157 if (builtin.link_libc) {
10631158 const value = system.getenv(key) orelse return null;
10641159 return mem.toSliceConst(u8, value);
10651160 }
1161 if (builtin.os == .windows) {
1162 @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
1163 }
10661164 return getenv(mem.toSliceConst(u8, key));
10671165}
10681166
1167/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
1168/// See also `getenv`.
1169pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 {
1170 if (builtin.os != .windows) {
1171 @compileError("std.os.getenvW is a Windows-only API");
1172 }
1173 const key_slice = mem.toSliceConst(u16, key);
1174 const ptr = windows.peb().ProcessParameters.Environment;
1175 var i: usize = 0;
1176 while (ptr[i] != 0) {
1177 const key_start = i;
1178
1179 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
1180 const this_key = ptr[key_start..i];
1181
1182 if (ptr[i] == '=') i += 1;
1183
1184 const value_start = i;
1185 while (ptr[i] != 0) : (i += 1) {}
1186 const this_value = ptr[value_start..i :0];
1187
1188 if (mem.eql(u16, key_slice, this_key)) return this_value;
1189
1190 i += 1; // skip over null byte
1191 }
1192 return null;
1193}
1194
10691195pub const GetCwdError = error{
10701196 NameTooLong,
10711197 CurrentWorkingDirectoryUnlinked,
......@@ -1726,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool {
17261852
17271853 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
17281854 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];
1729 const name_wide = @bytesToSlice(u16, name_bytes);
1855 const name_wide = mem.bytesAsSlice(u16, name_bytes);
17301856 return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or
17311857 mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
17321858}
......@@ -2452,6 +2578,9 @@ pub const AccessError = error{
24522578 InputOutput,
24532579 SystemResources,
24542580 BadPathName,
2581 FileBusy,
2582 SymLinkLoop,
2583 ReadOnlyFileSystem,
24552584
24562585 /// On Windows, file paths must be valid Unicode.
24572586 InvalidUtf8,
......@@ -2469,8 +2598,11 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
24692598 return accessC(&path_c, mode);
24702599}
24712600
2601/// Deprecated in favor of `accessZ`.
2602pub const accessC = accessZ;
2603
24722604/// Same as `access` except `path` is null-terminated.
2473pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {
2605pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
24742606 if (builtin.os == .windows) {
24752607 const path_w = try windows.cStrToPrefixedFileW(path);
24762608 _ = try windows.GetFileAttributesW(&path_w);
......@@ -2479,12 +2611,11 @@ pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {
24792611 switch (errno(system.access(path, mode))) {
24802612 0 => return,
24812613 EACCES => return error.PermissionDenied,
2482 EROFS => return error.PermissionDenied,
2483 ELOOP => return error.PermissionDenied,
2484 ETXTBSY => return error.PermissionDenied,
2614 EROFS => return error.ReadOnlyFileSystem,
2615 ELOOP => return error.SymLinkLoop,
2616 ETXTBSY => return error.FileBusy,
24852617 ENOTDIR => return error.FileNotFound,
24862618 ENOENT => return error.FileNotFound,
2487
24882619 ENAMETOOLONG => return error.NameTooLong,
24892620 EINVAL => unreachable,
24902621 EFAULT => unreachable,
......@@ -2510,6 +2641,79 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v
25102641 }
25112642}
25122643
2644/// Check user's permissions for a file, based on an open directory handle.
2645/// TODO currently this ignores `mode` and `flags` on Windows.
2646pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
2647 if (builtin.os == .windows) {
2648 const path_w = try windows.sliceToPrefixedFileW(path);
2649 return faccessatW(dirfd, &path_w, mode, flags);
2650 }
2651 const path_c = try toPosixPath(path);
2652 return faccessatZ(dirfd, &path_c, mode, flags);
2653}
2654
2655/// Same as `faccessat` except the path parameter is null-terminated.
2656pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
2657 if (builtin.os == .windows) {
2658 const path_w = try windows.cStrToPrefixedFileW(path);
2659 return faccessatW(dirfd, &path_w, mode, flags);
2660 }
2661 switch (errno(system.faccessat(dirfd, path, mode, flags))) {
2662 0 => return,
2663 EACCES => return error.PermissionDenied,
2664 EROFS => return error.ReadOnlyFileSystem,
2665 ELOOP => return error.SymLinkLoop,
2666 ETXTBSY => return error.FileBusy,
2667 ENOTDIR => return error.FileNotFound,
2668 ENOENT => return error.FileNotFound,
2669 ENAMETOOLONG => return error.NameTooLong,
2670 EINVAL => unreachable,
2671 EFAULT => unreachable,
2672 EIO => return error.InputOutput,
2673 ENOMEM => return error.SystemResources,
2674 else => |err| return unexpectedErrno(err),
2675 }
2676}
2677
2678/// Same as `faccessat` except asserts the target is Windows and the path parameter
2679/// is NtDll-prefixed, null-terminated, WTF-16 encoded.
2680/// TODO currently this ignores `mode` and `flags`
2681pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32) AccessError!void {
2682 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
2683 return;
2684 }
2685 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
2686 return;
2687 }
2688
2689 const path_len_bytes = math.cast(u16, mem.toSliceConst(u16, sub_path_w).len * 2) catch |err| switch (err) {
2690 error.Overflow => return error.NameTooLong,
2691 };
2692 var nt_name = windows.UNICODE_STRING{
2693 .Length = path_len_bytes,
2694 .MaximumLength = path_len_bytes,
2695 .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)),
2696 };
2697 var attr = windows.OBJECT_ATTRIBUTES{
2698 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
2699 .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w)) null else dirfd,
2700 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
2701 .ObjectName = &nt_name,
2702 .SecurityDescriptor = null,
2703 .SecurityQualityOfService = null,
2704 };
2705 var basic_info: windows.FILE_BASIC_INFORMATION = undefined;
2706 switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
2707 .SUCCESS => return,
2708 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
2709 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
2710 .INVALID_PARAMETER => unreachable,
2711 .ACCESS_DENIED => return error.PermissionDenied,
2712 .OBJECT_PATH_SYNTAX_BAD => unreachable,
2713 else => |rc| return windows.unexpectedStatus(rc),
2714 }
2715}
2716
25132717pub const PipeError = error{
25142718 SystemFdQuotaExceeded,
25152719 ProcessFdQuotaExceeded,
......@@ -2844,18 +3048,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
28443048}
28453049
28463050pub fn dl_iterate_phdr(
2847 comptime T: type,
2848 callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,
2849 data: ?*T,
2850) isize {
3051 context: var,
3052 comptime Error: type,
3053 comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
3054) Error!void {
3055 const Context = @TypeOf(context);
3056
28513057 if (builtin.object_format != .elf)
28523058 @compileError("dl_iterate_phdr is not available for this target");
28533059
28543060 if (builtin.link_libc) {
2855 return system.dl_iterate_phdr(
2856 @ptrCast(std.c.dl_iterate_phdr_callback, callback),
2857 @ptrCast(?*c_void, data),
2858 );
3061 switch (system.dl_iterate_phdr(struct {
3062 fn callbackC(info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int {
3063 const context_ptr = @ptrCast(*const Context, @alignCast(@alignOf(*const Context), data));
3064 callback(info, size, context_ptr.*) catch |err| return @errorToInt(err);
3065 return 0;
3066 }
3067 }.callbackC, @intToPtr(?*c_void, @ptrToInt(&context)))) {
3068 0 => return,
3069 else => |err| return @errSetCast(Error, @intToError(@intCast(u16, err))), // TODO don't hardcode u16
3070 }
28593071 }
28603072
28613073 const elf_base = std.process.getBaseAddress();
......@@ -2877,11 +3089,10 @@ pub fn dl_iterate_phdr(
28773089 .dlpi_phnum = ehdr.e_phnum,
28783090 };
28793091
2880 return callback(&info, @sizeOf(dl_phdr_info), data);
3092 return callback(&info, @sizeOf(dl_phdr_info), context);
28813093 }
28823094
28833095 // Last return value from the callback function
2884 var last_r: isize = 0;
28853096 while (it.next()) |entry| {
28863097 var dlpi_phdr: [*]elf.Phdr = undefined;
28873098 var dlpi_phnum: u16 = undefined;
......@@ -2903,11 +3114,8 @@ pub fn dl_iterate_phdr(
29033114 .dlpi_phnum = dlpi_phnum,
29043115 };
29053116
2906 last_r = callback(&info, @sizeOf(dl_phdr_info), data);
2907 if (last_r != 0) break;
3117 try callback(&info, @sizeOf(dl_phdr_info), context);
29083118 }
2909
2910 return last_r;
29113119}
29123120
29133121pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
......@@ -3141,7 +3349,7 @@ pub fn res_mkquery(
31413349 // Make a reasonably unpredictable id
31423350 var ts: timespec = undefined;
31433351 clock_gettime(CLOCK_REALTIME, &ts) catch {};
3144 const UInt = @IntType(false, @TypeOf(ts.tv_nsec).bit_count);
3352 const UInt = std.meta.IntType(false, @TypeOf(ts.tv_nsec).bit_count);
31453353 const unsec = @bitCast(UInt, ts.tv_nsec);
31463354 const id = @truncate(u32, unsec + unsec / 65536);
31473355 q[0] = @truncate(u8, id / 256);
lib/std/os/bits/linux.zig+1-1
......@@ -1004,7 +1004,7 @@ pub const dl_phdr_info = extern struct {
10041004
10051005pub const CPU_SETSIZE = 128;
10061006pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
1007pub const cpu_count_t = @IntType(false, std.math.log2(CPU_SETSIZE * 8));
1007pub const cpu_count_t = std.meta.IntType(false, std.math.log2(CPU_SETSIZE * 8));
10081008
10091009pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
10101010 var sum: cpu_count_t = 0;
lib/std/os/linux/tls.zig+1-1
......@@ -152,7 +152,7 @@ pub fn setThreadPointer(addr: usize) void {
152152 : [addr] "r" (addr)
153153 );
154154 },
155 .arm => |arm| {
155 .arm => {
156156 const rc = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr);
157157 assert(rc == 0);
158158 },
lib/std/os/test.zig+21-12
......@@ -29,7 +29,7 @@ test "makePath, put some files in it, deleteTree" {
2929
3030test "access file" {
3131 try fs.makePath(a, "os_test_tmp");
32 if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {
32 if (fs.cwd().access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| {
3333 @panic("expected error");
3434 } else |err| {
3535 expect(err == error.FileNotFound);
......@@ -165,16 +165,19 @@ test "sigaltstack" {
165165// analyzed
166166const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;
167167
168fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {
169 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
170 return 0;
168const IterFnError = error{
169 MissingPtLoadSegment,
170 MissingLoad,
171 BadElfMagic,
172 FailedConsistencyCheck,
173};
171174
172 var counter = data.?;
175fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
173176 // Count how many libraries are loaded
174177 counter.* += @as(usize, 1);
175178
176179 // The image should contain at least a PT_LOAD segment
177 if (info.dlpi_phnum < 1) return -1;
180 if (info.dlpi_phnum < 1) return error.MissingPtLoadSegment;
178181
179182 // Quick & dirty validation of the phdr pointers, make sure we're not
180183 // pointing to some random gibberish
......@@ -189,17 +192,15 @@ fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {
189192 // Find the ELF header
190193 const elf_header = @intToPtr(*elf.Ehdr, reloc_addr - phdr.p_offset);
191194 // Validate the magic
192 if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return -1;
195 if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return error.BadElfMagic;
193196 // Consistency check
194 if (elf_header.e_phnum != info.dlpi_phnum) return -1;
197 if (elf_header.e_phnum != info.dlpi_phnum) return error.FailedConsistencyCheck;
195198
196199 found_load = true;
197200 break;
198201 }
199202
200 if (!found_load) return -1;
201
202 return 42;
203 if (!found_load) return error.MissingLoad;
203204}
204205
205206test "dl_iterate_phdr" {
......@@ -207,7 +208,7 @@ test "dl_iterate_phdr" {
207208 return error.SkipZigTest;
208209
209210 var counter: usize = 0;
210 expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
211 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
211212 expect(counter != 0);
212213}
213214
......@@ -350,3 +351,11 @@ test "mmap" {
350351
351352 try fs.cwd().deleteFile(test_out_file);
352353}
354
355test "getenv" {
356 if (builtin.os == .windows) {
357 expect(os.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null);
358 } else {
359 expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
360 }
361}
lib/std/os/windows/bits.zig+1-1
......@@ -1187,7 +1187,7 @@ pub const RTL_USER_PROCESS_PARAMETERS = extern struct {
11871187 DllPath: UNICODE_STRING,
11881188 ImagePathName: UNICODE_STRING,
11891189 CommandLine: UNICODE_STRING,
1190 Environment: [*]WCHAR,
1190 Environment: [*:0]WCHAR,
11911191 dwX: ULONG,
11921192 dwY: ULONG,
11931193 dwXSize: ULONG,
lib/std/os/windows/ntdll.zig+6
......@@ -8,6 +8,12 @@ pub extern "NtDll" fn NtQueryInformationFile(
88 Length: ULONG,
99 FileInformationClass: FILE_INFORMATION_CLASS,
1010) callconv(.Stdcall) NTSTATUS;
11
12pub extern "NtDll" fn NtQueryAttributesFile(
13 ObjectAttributes: *OBJECT_ATTRIBUTES,
14 FileAttributes: *FILE_BASIC_INFORMATION,
15) callconv(.Stdcall) NTSTATUS;
16
1117pub extern "NtDll" fn NtCreateFile(
1218 FileHandle: *HANDLE,
1319 DesiredAccess: ACCESS_MASK,
lib/std/packed_int_array.zig+6-6
......@@ -34,13 +34,13 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
3434
3535 //we bitcast the desired Int type to an unsigned version of itself
3636 // to avoid issues with shifting signed ints.
37 const UnInt = @IntType(false, int_bits);
37 const UnInt = std.meta.IntType(false, int_bits);
3838
3939 //The maximum container int type
40 const MinIo = @IntType(false, min_io_bits);
40 const MinIo = std.meta.IntType(false, min_io_bits);
4141
4242 //The minimum container int type
43 const MaxIo = @IntType(false, max_io_bits);
43 const MaxIo = std.meta.IntType(false, max_io_bits);
4444
4545 return struct {
4646 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {
......@@ -322,7 +322,7 @@ test "PackedIntArray" {
322322 inline while (bits <= 256) : (bits += 1) {
323323 //alternate unsigned and signed
324324 const even = bits % 2 == 0;
325 const I = @IntType(even, bits);
325 const I = std.meta.IntType(even, bits);
326326
327327 const PackedArray = PackedIntArray(I, int_count);
328328 const expected_bytes = ((bits * int_count) + 7) / 8;
......@@ -369,7 +369,7 @@ test "PackedIntSlice" {
369369 inline while (bits <= 256) : (bits += 1) {
370370 //alternate unsigned and signed
371371 const even = bits % 2 == 0;
372 const I = @IntType(even, bits);
372 const I = std.meta.IntType(even, bits);
373373 const P = PackedIntSlice(I);
374374
375375 var data = P.init(&buffer, int_count);
......@@ -399,7 +399,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
399399
400400 comptime var bits = 0;
401401 inline while (bits <= max_bits) : (bits += 1) {
402 const Int = @IntType(false, bits);
402 const Int = std.meta.IntType(false, bits);
403403
404404 const PackedArray = PackedIntArray(Int, int_count);
405405 var packed_array = @as(PackedArray, undefined);
lib/std/process.zig+92-42
......@@ -1,5 +1,5 @@
1const builtin = @import("builtin");
21const std = @import("std.zig");
2const builtin = std.builtin;
33const os = std.os;
44const fs = std.fs;
55const BufMap = std.BufMap;
......@@ -31,20 +31,16 @@ test "getCwdAlloc" {
3131 testing.allocator.free(cwd);
3232}
3333
34/// Caller must free result when done.
35/// TODO make this go through libc when we have it
34/// Caller owns resulting `BufMap`.
3635pub fn getEnvMap(allocator: *Allocator) !BufMap {
3736 var result = BufMap.init(allocator);
3837 errdefer result.deinit();
3938
4039 if (builtin.os == .windows) {
41 const ptr = try os.windows.GetEnvironmentStringsW();
42 defer os.windows.FreeEnvironmentStringsW(ptr);
40 const ptr = os.windows.peb().ProcessParameters.Environment;
4341
4442 var i: usize = 0;
45 while (true) {
46 if (ptr[i] == 0) return result;
47
43 while (ptr[i] != 0) {
4844 const key_start = i;
4945
5046 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
......@@ -64,6 +60,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
6460
6561 try result.setMove(key, value);
6662 }
63 return result;
6764 } else if (builtin.os == .wasi) {
6865 var environ_count: usize = undefined;
6966 var environ_buf_size: usize = undefined;
......@@ -95,15 +92,29 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
9592 }
9693 }
9794 return result;
95 } else if (builtin.link_libc) {
96 var ptr = std.c.environ;
97 while (ptr.*) |line| : (ptr += 1) {
98 var line_i: usize = 0;
99 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
100 const key = line[0..line_i];
101
102 var end_i: usize = line_i;
103 while (line[end_i] != 0) : (end_i += 1) {}
104 const value = line[line_i + 1 .. end_i];
105
106 try result.set(key, value);
107 }
108 return result;
98109 } else {
99 for (os.environ) |ptr| {
110 for (os.environ) |line| {
100111 var line_i: usize = 0;
101 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
102 const key = ptr[0..line_i];
112 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
113 const key = line[0..line_i];
103114
104115 var end_i: usize = line_i;
105 while (ptr[end_i] != 0) : (end_i += 1) {}
106 const value = ptr[line_i + 1 .. end_i];
116 while (line[end_i] != 0) : (end_i += 1) {}
117 const value = line[line_i + 1 .. end_i];
107118
108119 try result.set(key, value);
109120 }
......@@ -125,37 +136,20 @@ pub const GetEnvVarOwnedError = error{
125136};
126137
127138/// Caller must free returned memory.
128/// TODO make this go through libc when we have it
129139pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
130140 if (builtin.os == .windows) {
131 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
132 defer allocator.free(key_with_null);
133
134 var buf = try allocator.alloc(u16, 256);
135 defer allocator.free(buf);
136
137 while (true) {
138 const windows_buf_len = math.cast(os.windows.DWORD, buf.len) catch return error.OutOfMemory;
139 const result = os.windows.GetEnvironmentVariableW(
140 key_with_null.ptr,
141 buf.ptr,
142 windows_buf_len,
143 ) catch |err| switch (err) {
144 error.Unexpected => return error.EnvironmentVariableNotFound,
145 else => |e| return e,
146 };
147 if (result > buf.len) {
148 buf = try allocator.realloc(buf, result);
149 continue;
150 }
141 const result_w = blk: {
142 const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
143 defer allocator.free(key_w);
151144
152 return std.unicode.utf16leToUtf8Alloc(allocator, buf[0..result]) catch |err| switch (err) {
153 error.DanglingSurrogateHalf => return error.InvalidUtf8,
154 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
155 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
156 else => |e| return e,
157 };
158 }
145 break :blk std.os.getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
146 };
147 return std.unicode.utf16leToUtf8Alloc(allocator, result_w) catch |err| switch (err) {
148 error.DanglingSurrogateHalf => return error.InvalidUtf8,
149 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
150 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
151 else => |e| return e,
152 };
159153 } else {
160154 const result = os.getenv(key) orelse return error.EnvironmentVariableNotFound;
161155 return mem.dupe(allocator, u8, result);
......@@ -436,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
436430 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
437431 errdefer allocator.free(buf);
438432
439 const result_slice_list = @bytesToSlice([]u8, buf[0..slice_list_bytes]);
433 const result_slice_list = mem.bytesAsSlice([]u8, buf[0..slice_list_bytes]);
440434 const result_contents = buf[slice_list_bytes..];
441435 mem.copy(u8, result_contents, contents_slice);
442436
......@@ -613,3 +607,59 @@ pub fn getBaseAddress() usize {
613607 else => @compileError("Unsupported OS"),
614608 }
615609}
610
611/// Caller owns the result value and each inner slice.
612pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 {
613 switch (builtin.link_mode) {
614 .Static => return &[_][:0]u8{},
615 .Dynamic => {},
616 }
617 const List = std.ArrayList([:0]u8);
618 switch (builtin.os) {
619 .linux,
620 .freebsd,
621 .netbsd,
622 .dragonfly,
623 => {
624 var paths = List.init(allocator);
625 errdefer {
626 const slice = paths.toOwnedSlice();
627 for (slice) |item| {
628 allocator.free(item);
629 }
630 allocator.free(slice);
631 }
632 try os.dl_iterate_phdr(&paths, error{OutOfMemory}, struct {
633 fn callback(info: *os.dl_phdr_info, size: usize, list: *List) !void {
634 const name = info.dlpi_name orelse return;
635 if (name[0] == '/') {
636 const item = try mem.dupeZ(list.allocator, u8, mem.toSliceConst(u8, name));
637 errdefer list.allocator.free(item);
638 try list.append(item);
639 }
640 }
641 }.callback);
642 return paths.toOwnedSlice();
643 },
644 .macosx, .ios, .watchos, .tvos => {
645 var paths = List.init(allocator);
646 errdefer {
647 const slice = paths.toOwnedSlice();
648 for (slice) |item| {
649 allocator.free(item);
650 }
651 allocator.free(slice);
652 }
653 const img_count = std.c._dyld_image_count();
654 var i: u32 = 0;
655 while (i < img_count) : (i += 1) {
656 const name = std.c._dyld_get_image_name(i);
657 const item = try mem.dupeZ(allocator, u8, mem.toSliceConst(u8, name));
658 errdefer allocator.free(item);
659 try paths.append(item);
660 }
661 return paths.toOwnedSlice();
662 },
663 else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
664 }
665}
lib/std/rand.zig+10-10
......@@ -45,8 +45,8 @@ pub const Random = struct {
4545 /// Returns a random int `i` such that `0 <= i <= maxInt(T)`.
4646 /// `i` is evenly distributed.
4747 pub fn int(r: *Random, comptime T: type) T {
48 const UnsignedT = @IntType(false, T.bit_count);
49 const ByteAlignedT = @IntType(false, @divTrunc(T.bit_count + 7, 8) * 8);
48 const UnsignedT = std.meta.IntType(false, T.bit_count);
49 const ByteAlignedT = std.meta.IntType(false, @divTrunc(T.bit_count + 7, 8) * 8);
5050
5151 var rand_bytes: [@sizeOf(ByteAlignedT)]u8 = undefined;
5252 r.bytes(rand_bytes[0..]);
......@@ -85,9 +85,9 @@ pub const Random = struct {
8585 comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation!
8686 assert(0 < less_than);
8787 // Small is typically u32
88 const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32);
88 const Small = std.meta.IntType(false, @divTrunc(T.bit_count + 31, 32) * 32);
8989 // Large is typically u64
90 const Large = @IntType(false, Small.bit_count * 2);
90 const Large = std.meta.IntType(false, Small.bit_count * 2);
9191
9292 // adapted from:
9393 // http://www.pcg-random.org/posts/bounded-rands.html
......@@ -99,7 +99,7 @@ pub const Random = struct {
9999 // TODO: workaround for https://github.com/ziglang/zig/issues/1770
100100 // should be:
101101 // var t: Small = -%less_than;
102 var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), @as(Small, less_than)));
102 var t: Small = @bitCast(Small, -%@bitCast(std.meta.IntType(true, Small.bit_count), @as(Small, less_than)));
103103
104104 if (t >= less_than) {
105105 t -= less_than;
......@@ -145,7 +145,7 @@ pub const Random = struct {
145145 assert(at_least < less_than);
146146 if (T.is_signed) {
147147 // Two's complement makes this math pretty easy.
148 const UnsignedT = @IntType(false, T.bit_count);
148 const UnsignedT = std.meta.IntType(false, T.bit_count);
149149 const lo = @bitCast(UnsignedT, at_least);
150150 const hi = @bitCast(UnsignedT, less_than);
151151 const result = lo +% r.uintLessThanBiased(UnsignedT, hi -% lo);
......@@ -163,7 +163,7 @@ pub const Random = struct {
163163 assert(at_least < less_than);
164164 if (T.is_signed) {
165165 // Two's complement makes this math pretty easy.
166 const UnsignedT = @IntType(false, T.bit_count);
166 const UnsignedT = std.meta.IntType(false, T.bit_count);
167167 const lo = @bitCast(UnsignedT, at_least);
168168 const hi = @bitCast(UnsignedT, less_than);
169169 const result = lo +% r.uintLessThan(UnsignedT, hi -% lo);
......@@ -180,7 +180,7 @@ pub const Random = struct {
180180 assert(at_least <= at_most);
181181 if (T.is_signed) {
182182 // Two's complement makes this math pretty easy.
183 const UnsignedT = @IntType(false, T.bit_count);
183 const UnsignedT = std.meta.IntType(false, T.bit_count);
184184 const lo = @bitCast(UnsignedT, at_least);
185185 const hi = @bitCast(UnsignedT, at_most);
186186 const result = lo +% r.uintAtMostBiased(UnsignedT, hi -% lo);
......@@ -198,7 +198,7 @@ pub const Random = struct {
198198 assert(at_least <= at_most);
199199 if (T.is_signed) {
200200 // Two's complement makes this math pretty easy.
201 const UnsignedT = @IntType(false, T.bit_count);
201 const UnsignedT = std.meta.IntType(false, T.bit_count);
202202 const lo = @bitCast(UnsignedT, at_least);
203203 const hi = @bitCast(UnsignedT, at_most);
204204 const result = lo +% r.uintAtMost(UnsignedT, hi -% lo);
......@@ -281,7 +281,7 @@ pub const Random = struct {
281281/// This function introduces a minor bias.
282282pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
283283 comptime assert(T.is_signed == false);
284 const T2 = @IntType(false, T.bit_count * 2);
284 const T2 = std.meta.IntType(false, T.bit_count * 2);
285285
286286 // adapted from:
287287 // http://www.pcg-random.org/posts/bounded-rands.html
lib/std/special/build_runner.zig+14-11
......@@ -96,6 +96,8 @@ pub fn main() !void {
9696 builder.verbose_cimport = true;
9797 } else if (mem.eql(u8, arg, "--verbose-cc")) {
9898 builder.verbose_cc = true;
99 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
100 builder.verbose_llvm_cpu_features = true;
99101 } else if (mem.eql(u8, arg, "--")) {
100102 builder.args = argsRest(args, arg_idx);
101103 break;
......@@ -126,7 +128,7 @@ pub fn main() !void {
126128}
127129
128130fn runBuild(builder: *Builder) anyerror!void {
129 switch (@typeId(@TypeOf(root.build).ReturnType)) {
131 switch (@typeInfo(@TypeOf(root.build).ReturnType)) {
130132 .Void => root.build(builder),
131133 .ErrorUnion => try root.build(builder),
132134 else => @compileError("expected return type of build to be 'void' or '!void'"),
......@@ -185,16 +187,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
185187 try out_stream.write(
186188 \\
187189 \\Advanced Options:
188 \\ --build-file [file] Override path to build.zig
189 \\ --cache-dir [path] Override path to zig cache directory
190 \\ --override-lib-dir [arg] Override path to Zig lib directory
191 \\ --verbose-tokenize Enable compiler debug output for tokenization
192 \\ --verbose-ast Enable compiler debug output for parsing into an AST
193 \\ --verbose-link Enable compiler debug output for linking
194 \\ --verbose-ir Enable compiler debug output for Zig IR
195 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
196 \\ --verbose-cimport Enable compiler debug output for C imports
197 \\ --verbose-cc Enable compiler debug output for C compilation
190 \\ --build-file [file] Override path to build.zig
191 \\ --cache-dir [path] Override path to zig cache directory
192 \\ --override-lib-dir [arg] Override path to Zig lib directory
193 \\ --verbose-tokenize Enable compiler debug output for tokenization
194 \\ --verbose-ast Enable compiler debug output for parsing into an AST
195 \\ --verbose-link Enable compiler debug output for linking
196 \\ --verbose-ir Enable compiler debug output for Zig IR
197 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
198 \\ --verbose-cimport Enable compiler debug output for C imports
199 \\ --verbose-cc Enable compiler debug output for C compilation
200 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
198201 \\
199202 );
200203}
lib/std/special/c.zig+1-1
......@@ -511,7 +511,7 @@ export fn roundf(a: f32) f32 {
511511fn generic_fmod(comptime T: type, x: T, y: T) T {
512512 @setRuntimeSafety(false);
513513
514 const uint = @IntType(false, T.bit_count);
514 const uint = std.meta.IntType(false, T.bit_count);
515515 const log2uint = math.Log2Int(uint);
516516 const digits = if (T == f32) 23 else 52;
517517 const exp_bits = if (T == f32) 9 else 12;
lib/std/special/compiler_rt/addXf3.zig+7-7
......@@ -54,21 +54,21 @@ pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
5454}
5555
5656// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
57fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
58 const Z = @IntType(false, T.bit_count);
59 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
57fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
58 const Z = std.meta.IntType(false, T.bit_count);
59 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
6060 const significandBits = std.math.floatMantissaBits(T);
6161 const implicitBit = @as(Z, 1) << significandBits;
6262
63 const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
63 const shift = @clz(std.meta.IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
6464 significand.* <<= @intCast(S, shift);
6565 return 1 - shift;
6666}
6767
6868// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
6969fn addXf3(comptime T: type, a: T, b: T) T {
70 const Z = @IntType(false, T.bit_count);
71 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
70 const Z = std.meta.IntType(false, T.bit_count);
71 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
7272
7373 const typeWidth = T.bit_count;
7474 const significandBits = std.math.floatMantissaBits(T);
......@@ -182,7 +182,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
182182 // If partial cancellation occured, we need to left-shift the result
183183 // and adjust the exponent:
184184 if (aSignificand < implicitBit << 3) {
185 const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3));
185 const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.IntType(false, T.bit_count), implicitBit << 3));
186186 aSignificand <<= @intCast(S, shift);
187187 aExponent -= shift;
188188 }
lib/std/special/compiler_rt/compareXf2.zig+3-3
......@@ -22,8 +22,8 @@ const GE = extern enum(i32) {
2222pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
2323 @setRuntimeSafety(builtin.is_test);
2424
25 const srep_t = @IntType(true, T.bit_count);
26 const rep_t = @IntType(false, T.bit_count);
25 const srep_t = std.meta.IntType(true, T.bit_count);
26 const rep_t = std.meta.IntType(false, T.bit_count);
2727
2828 const significandBits = std.math.floatMantissaBits(T);
2929 const exponentBits = std.math.floatExponentBits(T);
......@@ -68,7 +68,7 @@ pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
6868pub fn unordcmp(comptime T: type, a: T, b: T) i32 {
6969 @setRuntimeSafety(builtin.is_test);
7070
71 const rep_t = @IntType(false, T.bit_count);
71 const rep_t = std.meta.IntType(false, T.bit_count);
7272
7373 const significandBits = std.math.floatMantissaBits(T);
7474 const exponentBits = std.math.floatExponentBits(T);
lib/std/special/compiler_rt/divdf3.zig+4-4
......@@ -7,8 +7,8 @@ const builtin = @import("builtin");
77
88pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
99 @setRuntimeSafety(builtin.is_test);
10 const Z = @IntType(false, f64.bit_count);
11 const SignedZ = @IntType(true, f64.bit_count);
10 const Z = std.meta.IntType(false, f64.bit_count);
11 const SignedZ = std.meta.IntType(true, f64.bit_count);
1212
1313 const typeWidth = f64.bit_count;
1414 const significandBits = std.math.floatMantissaBits(f64);
......@@ -312,9 +312,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
312312 }
313313}
314314
315fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
315fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
316316 @setRuntimeSafety(builtin.is_test);
317 const Z = @IntType(false, T.bit_count);
317 const Z = std.meta.IntType(false, T.bit_count);
318318 const significandBits = std.math.floatMantissaBits(T);
319319 const implicitBit = @as(Z, 1) << significandBits;
320320
lib/std/special/compiler_rt/divsf3.zig+3-3
......@@ -7,7 +7,7 @@ const builtin = @import("builtin");
77
88pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
99 @setRuntimeSafety(builtin.is_test);
10 const Z = @IntType(false, f32.bit_count);
10 const Z = std.meta.IntType(false, f32.bit_count);
1111
1212 const typeWidth = f32.bit_count;
1313 const significandBits = std.math.floatMantissaBits(f32);
......@@ -185,9 +185,9 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
185185 }
186186}
187187
188fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
188fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
189189 @setRuntimeSafety(builtin.is_test);
190 const Z = @IntType(false, T.bit_count);
190 const Z = std.meta.IntType(false, T.bit_count);
191191 const significandBits = std.math.floatMantissaBits(T);
192192 const implicitBit = @as(Z, 1) << significandBits;
193193
lib/std/special/compiler_rt/extendXfYf2.zig+3-3
......@@ -30,11 +30,11 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {
3030
3131const CHAR_BIT = 8;
3232
33fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @typeInfo(src_t).Float.bits)) dst_t {
33fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.IntType(false, @typeInfo(src_t).Float.bits)) dst_t {
3434 @setRuntimeSafety(builtin.is_test);
3535
36 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);
37 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);
36 const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits);
37 const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits);
3838 const srcSigBits = std.math.floatMantissaBits(src_t);
3939 const dstSigBits = std.math.floatMantissaBits(dst_t);
4040 const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/fixint.zig+1-1
......@@ -45,7 +45,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
4545 if (exponent < 0) return 0;
4646
4747 // The unsigned result needs to be large enough to handle an fixint_t or rep_t
48 const fixuint_t = @IntType(false, fixint_t.bit_count);
48 const fixuint_t = std.meta.IntType(false, fixint_t.bit_count);
4949 const UintResultType = if (fixint_t.bit_count > rep_t.bit_count) fixuint_t else rep_t;
5050 var uint_result: UintResultType = undefined;
5151
lib/std/special/compiler_rt/fixuint.zig+1-1
......@@ -10,7 +10,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
1010 f128 => u128,
1111 else => unreachable,
1212 };
13 const srep_t = @IntType(true, rep_t.bit_count);
13 const srep_t = @import("std").meta.IntType(true, rep_t.bit_count);
1414 const significandBits = switch (fp_t) {
1515 f32 => 23,
1616 f64 => 52,
lib/std/special/compiler_rt/floatsiXf.zig+2-2
......@@ -5,8 +5,8 @@ const maxInt = std.math.maxInt;
55fn floatsiXf(comptime T: type, a: i32) T {
66 @setRuntimeSafety(builtin.is_test);
77
8 const Z = @IntType(false, T.bit_count);
9 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
8 const Z = std.meta.IntType(false, T.bit_count);
9 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
1010
1111 if (a == 0) {
1212 return @as(T, 0.0);
lib/std/special/compiler_rt/mulXf3.zig+3-3
......@@ -28,7 +28,7 @@ pub fn __aeabi_dmul(a: f64, b: f64) callconv(.C) f64 {
2828
2929fn mulXf3(comptime T: type, a: T, b: T) T {
3030 @setRuntimeSafety(builtin.is_test);
31 const Z = @IntType(false, T.bit_count);
31 const Z = std.meta.IntType(false, T.bit_count);
3232
3333 const typeWidth = T.bit_count;
3434 const significandBits = std.math.floatMantissaBits(T);
......@@ -264,9 +264,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
264264 }
265265}
266266
267fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
267fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
268268 @setRuntimeSafety(builtin.is_test);
269 const Z = @IntType(false, T.bit_count);
269 const Z = std.meta.IntType(false, T.bit_count);
270270 const significandBits = std.math.floatMantissaBits(T);
271271 const implicitBit = @as(Z, 1) << significandBits;
272272
lib/std/special/compiler_rt/negXf2.zig+1-1
......@@ -19,7 +19,7 @@ pub fn __aeabi_dneg(arg: f64) callconv(.AAPCS) f64 {
1919}
2020
2121fn negXf2(comptime T: type, a: T) T {
22 const Z = @IntType(false, T.bit_count);
22 const Z = std.meta.IntType(false, T.bit_count);
2323
2424 const typeWidth = T.bit_count;
2525 const significandBits = std.math.floatMantissaBits(T);
lib/std/special/compiler_rt/truncXfYf2.zig+2-2
......@@ -36,8 +36,8 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 {
3636}
3737
3838inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
39 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);
40 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);
39 const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits);
40 const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits);
4141 const srcSigBits = std.math.floatMantissaBits(src_t);
4242 const dstSigBits = std.math.floatMantissaBits(dst_t);
4343 const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/udivmod.zig+2-2
......@@ -10,8 +10,8 @@ const high = 1 - low;
1010pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?*DoubleInt) DoubleInt {
1111 @setRuntimeSafety(is_test);
1212
13 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));
14 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
13 const SingleInt = @import("std").meta.IntType(false, @divExact(DoubleInt.bit_count, 2));
14 const SignedDoubleInt = @import("std").meta.IntType(true, DoubleInt.bit_count);
1515 const Log2SingleInt = @import("std").math.Log2Int(SingleInt);
1616
1717 const n = @ptrCast(*const [2]SingleInt, &a).*; // TODO issue #421
lib/std/start.zig+8-2
......@@ -21,7 +21,9 @@ comptime {
2121 @export(main, .{ .name = "main", .linkage = .Weak });
2222 }
2323 } else if (builtin.os == .windows) {
24 if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup")) {
24 if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and
25 !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup"))
26 {
2527 @export(WinMainCRTStartup, .{ .name = "WinMainCRTStartup" });
2628 }
2729 } else if (builtin.os == .uefi) {
......@@ -34,7 +36,11 @@ comptime {
3436 }
3537}
3638
37fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, lpReserved: std.os.windows.LPVOID) callconv(.Stdcall) std.os.windows.BOOL {
39fn _DllMainCRTStartup(
40 hinstDLL: std.os.windows.HINSTANCE,
41 fdwReason: std.os.windows.DWORD,
42 lpReserved: std.os.windows.LPVOID,
43) callconv(.Stdcall) std.os.windows.BOOL {
3844 if (@hasDecl(root, "DllMain")) {
3945 return root.DllMain(hinstDLL, fdwReason, lpReserved);
4046 }
lib/std/target.zig+763-650
......@@ -47,6 +47,16 @@ pub const Target = union(enum) {
4747 emscripten,
4848 uefi,
4949 other,
50
51 pub fn parse(text: []const u8) !Os {
52 const info = @typeInfo(Os);
53 inline for (info.Enum.fields) |field| {
54 if (mem.eql(u8, text, field.name)) {
55 return @field(Os, field.name);
56 }
57 }
58 return error.UnknownOperatingSystem;
59 }
5060 };
5161
5262 pub const aarch64 = @import("target/aarch64.zig");
......@@ -65,463 +75,6 @@ pub const Target = union(enum) {
6575 pub const wasm = @import("target/wasm.zig");
6676 pub const x86 = @import("target/x86.zig");
6777
68 pub const Arch = union(enum) {
69 arm: Arm32,
70 armeb: Arm32,
71 aarch64: Arm64,
72 aarch64_be: Arm64,
73 aarch64_32: Arm64,
74 arc,
75 avr,
76 bpfel,
77 bpfeb,
78 hexagon,
79 mips,
80 mipsel,
81 mips64,
82 mips64el,
83 msp430,
84 powerpc,
85 powerpc64,
86 powerpc64le,
87 r600,
88 amdgcn,
89 riscv32,
90 riscv64,
91 sparc,
92 sparcv9,
93 sparcel,
94 s390x,
95 tce,
96 tcele,
97 thumb: Arm32,
98 thumbeb: Arm32,
99 i386,
100 x86_64,
101 xcore,
102 nvptx,
103 nvptx64,
104 le32,
105 le64,
106 amdil,
107 amdil64,
108 hsail,
109 hsail64,
110 spir,
111 spir64,
112 kalimba: Kalimba,
113 shave,
114 lanai,
115 wasm32,
116 wasm64,
117 renderscript32,
118 renderscript64,
119 ve,
120
121 pub const Arm32 = enum {
122 v8_5a,
123 v8_4a,
124 v8_3a,
125 v8_2a,
126 v8_1a,
127 v8a,
128 v8r,
129 v8m_baseline,
130 v8m_mainline,
131 v8_1m_mainline,
132 v7a,
133 v7em,
134 v7m,
135 v7s,
136 v7k,
137 v7ve,
138 v6,
139 v6m,
140 v6k,
141 v6t2,
142 v5,
143 v5te,
144 v4t,
145
146 pub fn version(version: Arm32) comptime_int {
147 return switch (version) {
148 .v8_5a, .v8_4a, .v8_3a, .v8_2a, .v8_1a, .v8a, .v8r, .v8m_baseline, .v8m_mainline, .v8_1m_mainline => 8,
149 .v7a, .v7em, .v7m, .v7s, .v7k, .v7ve => 7,
150 .v6, .v6m, .v6k, .v6t2 => 6,
151 .v5, .v5te => 5,
152 .v4t => 4,
153 };
154 }
155 };
156 pub const Arm64 = enum {
157 v8_5a,
158 v8_4a,
159 v8_3a,
160 v8_2a,
161 v8_1a,
162 v8a,
163 };
164 pub const Kalimba = enum {
165 v5,
166 v4,
167 v3,
168 };
169 pub const Mips = enum {
170 r6,
171 };
172 pub const PPC = enum {
173 spe,
174 };
175
176 pub fn subArchName(arch: Arch) ?[]const u8 {
177 return switch (arch) {
178 .arm, .armeb, .thumb, .thumbeb => |arm32| @tagName(arm32),
179 .aarch64, .aarch64_be, .aarch64_32 => |arm64| @tagName(arm64),
180 .kalimba => |kalimba| @tagName(kalimba),
181 else => return null,
182 };
183 }
184
185 pub fn subArchFeature(arch: Arch) ?Cpu.Feature.Set.Index {
186 return switch (arch) {
187 .arm, .armeb, .thumb, .thumbeb => |arm32| switch (arm32) {
188 .v8_5a => @enumToInt(arm.Feature.armv8_5_a),
189 .v8_4a => @enumToInt(arm.Feature.armv8_4_a),
190 .v8_3a => @enumToInt(arm.Feature.armv8_3_a),
191 .v8_2a => @enumToInt(arm.Feature.armv8_2_a),
192 .v8_1a => @enumToInt(arm.Feature.armv8_1_a),
193 .v8a => @enumToInt(arm.Feature.armv8_a),
194 .v8r => @enumToInt(arm.Feature.armv8_r),
195 .v8m_baseline => @enumToInt(arm.Feature.armv8_m_base),
196 .v8m_mainline => @enumToInt(arm.Feature.armv8_m_main),
197 .v8_1m_mainline => @enumToInt(arm.Feature.armv8_1_m_main),
198 .v7a => @enumToInt(arm.Feature.armv7_a),
199 .v7em => @enumToInt(arm.Feature.armv7e_m),
200 .v7m => @enumToInt(arm.Feature.armv7_m),
201 .v7s => @enumToInt(arm.Feature.armv7s),
202 .v7k => @enumToInt(arm.Feature.armv7k),
203 .v7ve => @enumToInt(arm.Feature.armv7ve),
204 .v6 => @enumToInt(arm.Feature.armv6),
205 .v6m => @enumToInt(arm.Feature.armv6_m),
206 .v6k => @enumToInt(arm.Feature.armv6k),
207 .v6t2 => @enumToInt(arm.Feature.armv6t2),
208 .v5 => @enumToInt(arm.Feature.armv5t),
209 .v5te => @enumToInt(arm.Feature.armv5te),
210 .v4t => @enumToInt(arm.Feature.armv4t),
211 },
212 .aarch64, .aarch64_be, .aarch64_32 => |arm64| switch (arm64) {
213 .v8_5a => @enumToInt(aarch64.Feature.v8_5a),
214 .v8_4a => @enumToInt(aarch64.Feature.v8_4a),
215 .v8_3a => @enumToInt(aarch64.Feature.v8_3a),
216 .v8_2a => @enumToInt(aarch64.Feature.v8_2a),
217 .v8_1a => @enumToInt(aarch64.Feature.v8_1a),
218 .v8a => @enumToInt(aarch64.Feature.v8a),
219 },
220 else => return null,
221 };
222 }
223
224 pub fn isARM(arch: Arch) bool {
225 return switch (arch) {
226 .arm, .armeb => true,
227 else => false,
228 };
229 }
230
231 pub fn isThumb(arch: Arch) bool {
232 return switch (arch) {
233 .thumb, .thumbeb => true,
234 else => false,
235 };
236 }
237
238 pub fn isWasm(arch: Arch) bool {
239 return switch (arch) {
240 .wasm32, .wasm64 => true,
241 else => false,
242 };
243 }
244
245 pub fn isRISCV(arch: Arch) bool {
246 return switch (arch) {
247 .riscv32, .riscv64 => true,
248 else => false,
249 };
250 }
251
252 pub fn isMIPS(arch: Arch) bool {
253 return switch (arch) {
254 .mips, .mipsel, .mips64, .mips64el => true,
255 else => false,
256 };
257 }
258
259 pub fn parseCpu(arch: Arch, cpu_name: []const u8) !*const Cpu {
260 for (arch.allCpus()) |cpu| {
261 if (mem.eql(u8, cpu_name, cpu.name)) {
262 return cpu;
263 }
264 }
265 return error.UnknownCpu;
266 }
267
268 /// Comma-separated list of features, with + or - in front of each feature. This
269 /// form represents a deviation from baseline CPU, which is provided as a parameter.
270 /// Extra commas are ignored.
271 pub fn parseCpuFeatureSet(arch: Arch, cpu: *const Cpu, features_text: []const u8) !Cpu.Feature.Set {
272 const all_features = arch.allFeaturesList();
273 var set = cpu.features;
274 var it = mem.tokenize(features_text, ",");
275 while (it.next()) |item_text| {
276 var feature_name: []const u8 = undefined;
277 var op: enum {
278 add,
279 sub,
280 } = undefined;
281 if (mem.startsWith(u8, item_text, "+")) {
282 op = .add;
283 feature_name = item_text[1..];
284 } else if (mem.startsWith(u8, item_text, "-")) {
285 op = .sub;
286 feature_name = item_text[1..];
287 } else {
288 return error.InvalidCpuFeatures;
289 }
290 for (all_features) |feature, index_usize| {
291 const index = @intCast(Cpu.Feature.Set.Index, index_usize);
292 if (mem.eql(u8, feature_name, feature.name)) {
293 switch (op) {
294 .add => set.addFeature(index),
295 .sub => set.removeFeature(index),
296 }
297 break;
298 }
299 } else {
300 return error.UnknownCpuFeature;
301 }
302 }
303 return set;
304 }
305
306 pub fn toElfMachine(arch: Arch) std.elf.EM {
307 return switch (arch) {
308 .avr => ._AVR,
309 .msp430 => ._MSP430,
310 .arc => ._ARC,
311 .arm => ._ARM,
312 .armeb => ._ARM,
313 .hexagon => ._HEXAGON,
314 .le32 => ._NONE,
315 .mips => ._MIPS,
316 .mipsel => ._MIPS_RS3_LE,
317 .powerpc => ._PPC,
318 .r600 => ._NONE,
319 .riscv32 => ._RISCV,
320 .sparc => ._SPARC,
321 .sparcel => ._SPARC,
322 .tce => ._NONE,
323 .tcele => ._NONE,
324 .thumb => ._ARM,
325 .thumbeb => ._ARM,
326 .i386 => ._386,
327 .xcore => ._XCORE,
328 .nvptx => ._NONE,
329 .amdil => ._NONE,
330 .hsail => ._NONE,
331 .spir => ._NONE,
332 .kalimba => ._CSR_KALIMBA,
333 .shave => ._NONE,
334 .lanai => ._LANAI,
335 .wasm32 => ._NONE,
336 .renderscript32 => ._NONE,
337 .aarch64_32 => ._AARCH64,
338 .aarch64 => ._AARCH64,
339 .aarch64_be => ._AARCH64,
340 .mips64 => ._MIPS,
341 .mips64el => ._MIPS_RS3_LE,
342 .powerpc64 => ._PPC64,
343 .powerpc64le => ._PPC64,
344 .riscv64 => ._RISCV,
345 .x86_64 => ._X86_64,
346 .nvptx64 => ._NONE,
347 .le64 => ._NONE,
348 .amdil64 => ._NONE,
349 .hsail64 => ._NONE,
350 .spir64 => ._NONE,
351 .wasm64 => ._NONE,
352 .renderscript64 => ._NONE,
353 .amdgcn => ._NONE,
354 .bpfel => ._BPF,
355 .bpfeb => ._BPF,
356 .sparcv9 => ._SPARCV9,
357 .s390x => ._S390,
358 .ve => ._NONE,
359 };
360 }
361
362 pub fn endian(arch: Arch) builtin.Endian {
363 return switch (arch) {
364 .avr,
365 .arm,
366 .aarch64_32,
367 .aarch64,
368 .amdgcn,
369 .amdil,
370 .amdil64,
371 .bpfel,
372 .hexagon,
373 .hsail,
374 .hsail64,
375 .kalimba,
376 .le32,
377 .le64,
378 .mipsel,
379 .mips64el,
380 .msp430,
381 .nvptx,
382 .nvptx64,
383 .sparcel,
384 .tcele,
385 .powerpc64le,
386 .r600,
387 .riscv32,
388 .riscv64,
389 .i386,
390 .x86_64,
391 .wasm32,
392 .wasm64,
393 .xcore,
394 .thumb,
395 .spir,
396 .spir64,
397 .renderscript32,
398 .renderscript64,
399 .shave,
400 .ve,
401 => .Little,
402
403 .arc,
404 .armeb,
405 .aarch64_be,
406 .bpfeb,
407 .mips,
408 .mips64,
409 .powerpc,
410 .powerpc64,
411 .thumbeb,
412 .sparc,
413 .sparcv9,
414 .tce,
415 .lanai,
416 .s390x,
417 => .Big,
418 };
419 }
420
421 /// Returns a name that matches the lib/std/target/* directory name.
422 pub fn genericName(arch: Arch) []const u8 {
423 return switch (arch) {
424 .arm, .armeb, .thumb, .thumbeb => "arm",
425 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
426 .avr => "avr",
427 .bpfel, .bpfeb => "bpf",
428 .hexagon => "hexagon",
429 .mips, .mipsel, .mips64, .mips64el => "mips",
430 .msp430 => "msp430",
431 .powerpc, .powerpc64, .powerpc64le => "powerpc",
432 .amdgcn => "amdgpu",
433 .riscv32, .riscv64 => "riscv",
434 .sparc, .sparcv9, .sparcel => "sparc",
435 .s390x => "systemz",
436 .i386, .x86_64 => "x86",
437 .nvptx, .nvptx64 => "nvptx",
438 .wasm32, .wasm64 => "wasm",
439 else => @tagName(arch),
440 };
441 }
442
443 /// All CPU features Zig is aware of, sorted lexicographically by name.
444 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
445 return switch (arch) {
446 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
447 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
448 .avr => &avr.all_features,
449 .bpfel, .bpfeb => &bpf.all_features,
450 .hexagon => &hexagon.all_features,
451 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
452 .msp430 => &msp430.all_features,
453 .powerpc, .powerpc64, .powerpc64le => &powerpc.all_features,
454 .amdgcn => &amdgpu.all_features,
455 .riscv32, .riscv64 => &riscv.all_features,
456 .sparc, .sparcv9, .sparcel => &sparc.all_features,
457 .s390x => &systemz.all_features,
458 .i386, .x86_64 => &x86.all_features,
459 .nvptx, .nvptx64 => &nvptx.all_features,
460 .wasm32, .wasm64 => &wasm.all_features,
461
462 else => &[0]Cpu.Feature{},
463 };
464 }
465
466 /// The "default" set of CPU features for cross-compiling. A conservative set
467 /// of features that is expected to be supported on most available hardware.
468 pub fn getBaselineCpuFeatures(arch: Arch) CpuFeatures {
469 const S = struct {
470 const generic_cpu = Cpu{
471 .name = "generic",
472 .llvm_name = null,
473 .features = Cpu.Feature.Set.empty,
474 };
475 };
476 const cpu = switch (arch) {
477 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
478 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
479 .avr => &avr.cpu.avr1,
480 .bpfel, .bpfeb => &bpf.cpu.generic,
481 .hexagon => &hexagon.cpu.generic,
482 .mips, .mipsel => &mips.cpu.mips32,
483 .mips64, .mips64el => &mips.cpu.mips64,
484 .msp430 => &msp430.cpu.generic,
485 .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
486 .amdgcn => &amdgpu.cpu.generic,
487 .riscv32 => &riscv.cpu.baseline_rv32,
488 .riscv64 => &riscv.cpu.baseline_rv64,
489 .sparc, .sparcv9, .sparcel => &sparc.cpu.generic,
490 .s390x => &systemz.cpu.generic,
491 .i386 => &x86.cpu.pentium4,
492 .x86_64 => &x86.cpu.x86_64,
493 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
494 .wasm32, .wasm64 => &wasm.cpu.generic,
495
496 else => &S.generic_cpu,
497 };
498 return CpuFeatures.initFromCpu(arch, cpu);
499 }
500
501 /// All CPUs Zig is aware of, sorted lexicographically by name.
502 pub fn allCpus(arch: Arch) []const *const Cpu {
503 return switch (arch) {
504 .arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
505 .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
506 .avr => avr.all_cpus,
507 .bpfel, .bpfeb => bpf.all_cpus,
508 .hexagon => hexagon.all_cpus,
509 .mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
510 .msp430 => msp430.all_cpus,
511 .powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
512 .amdgcn => amdgpu.all_cpus,
513 .riscv32, .riscv64 => riscv.all_cpus,
514 .sparc, .sparcv9, .sparcel => sparc.all_cpus,
515 .s390x => systemz.all_cpus,
516 .i386, .x86_64 => x86.all_cpus,
517 .nvptx, .nvptx64 => nvptx.all_cpus,
518 .wasm32, .wasm64 => wasm.all_cpus,
519
520 else => &[0]*const Cpu{},
521 };
522 }
523 };
524
52578 pub const Abi = enum {
52679 none,
52780 gnu,
......@@ -543,11 +96,102 @@ pub const Target = union(enum) {
54396 coreclr,
54497 simulator,
54598 macabi,
99
100 pub fn default(arch: Cpu.Arch, target_os: Os) Abi {
101 switch (arch) {
102 .wasm32, .wasm64 => return .musl,
103 else => {},
104 }
105 switch (target_os) {
106 .freestanding,
107 .ananas,
108 .cloudabi,
109 .dragonfly,
110 .lv2,
111 .solaris,
112 .haiku,
113 .minix,
114 .rtems,
115 .nacl,
116 .cnk,
117 .aix,
118 .cuda,
119 .nvcl,
120 .amdhsa,
121 .ps4,
122 .elfiamcu,
123 .mesa3d,
124 .contiki,
125 .amdpal,
126 .hermit,
127 .other,
128 => return .eabi,
129 .openbsd,
130 .macosx,
131 .freebsd,
132 .ios,
133 .tvos,
134 .watchos,
135 .fuchsia,
136 .kfreebsd,
137 .netbsd,
138 .hurd,
139 => return .gnu,
140 .windows,
141 .uefi,
142 => return .msvc,
143 .linux,
144 .wasi,
145 .emscripten,
146 => return .musl,
147 }
148 }
149
150 pub fn parse(text: []const u8) !Abi {
151 const info = @typeInfo(Abi);
152 inline for (info.Enum.fields) |field| {
153 if (mem.eql(u8, text, field.name)) {
154 return @field(Abi, field.name);
155 }
156 }
157 return error.UnknownApplicationBinaryInterface;
158 }
159 };
160
161 pub const ObjectFormat = enum {
162 unknown,
163 coff,
164 elf,
165 macho,
166 wasm,
167 };
168
169 pub const SubSystem = enum {
170 Console,
171 Windows,
172 Posix,
173 Native,
174 EfiApplication,
175 EfiBootServiceDriver,
176 EfiRom,
177 EfiRuntimeDriver,
178 };
179
180 pub const Cross = struct {
181 cpu: Cpu,
182 os: Os,
183 abi: Abi,
546184 };
547185
548186 pub const Cpu = struct {
549 name: []const u8,
550 llvm_name: ?[:0]const u8,
187 /// Architecture
188 arch: Arch,
189
190 /// The CPU model to target. It has a set of features
191 /// which are overridden with the `features` field.
192 model: *const Model,
193
194 /// An explicit list of the entire CPU feature set. It may differ from the specific CPU model's features.
551195 features: Feature.Set,
552196
553197 pub const Feature = struct {
......@@ -573,10 +217,10 @@ pub const Target = union(enum) {
573217 pub const Set = struct {
574218 ints: [usize_count]usize,
575219
576 pub const needed_bit_count = 175;
220 pub const needed_bit_count = 155;
577221 pub const byte_count = (needed_bit_count + 7) / 8;
578222 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
579 pub const Index = std.math.Log2Int(@IntType(false, usize_count * @bitSizeOf(usize)));
223 pub const Index = std.math.Log2Int(std.meta.IntType(false, usize_count * @bitSizeOf(usize)));
580224 pub const ShiftInt = std.math.Log2Int(usize);
581225
582226 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
......@@ -597,6 +241,12 @@ pub const Target = union(enum) {
597241 set.ints[usize_index] |= @as(usize, 1) << bit_index;
598242 }
599243
244 /// Adds the specified feature set but not its dependencies.
245 pub fn addFeatureSet(set: *Set, other_set: Set) void {
246 set.ints = @as(@Vector(usize_count, usize), set.ints) |
247 @as(@Vector(usize_count, usize), other_set.ints);
248 }
249
600250 /// Removes the specified feature but not its dependents.
601251 pub fn removeFeature(set: *Set, arch_feature_index: Index) void {
602252 const usize_index = arch_feature_index / @bitSizeOf(usize);
......@@ -612,8 +262,7 @@ pub const Target = union(enum) {
612262 for (all_features_list) |feature, index_usize| {
613263 const index = @intCast(Index, index_usize);
614264 if (set.isEnabled(index)) {
615 set.ints = @as(@Vector(usize_count, usize), set.ints) |
616 @as(@Vector(usize_count, usize), feature.dependencies.ints);
265 set.addFeatureSet(feature.dependencies);
617266 }
618267 }
619268 const nothing_changed = mem.eql(usize, &old, &set.ints);
......@@ -648,77 +297,361 @@ pub const Target = union(enum) {
648297 };
649298 }
650299 };
651 };
652300
653 pub const ObjectFormat = enum {
654 unknown,
655 coff,
656 elf,
657 macho,
658 wasm,
659 };
301 pub const Arch = enum {
302 arm,
303 armeb,
304 aarch64,
305 aarch64_be,
306 aarch64_32,
307 arc,
308 avr,
309 bpfel,
310 bpfeb,
311 hexagon,
312 mips,
313 mipsel,
314 mips64,
315 mips64el,
316 msp430,
317 powerpc,
318 powerpc64,
319 powerpc64le,
320 r600,
321 amdgcn,
322 riscv32,
323 riscv64,
324 sparc,
325 sparcv9,
326 sparcel,
327 s390x,
328 tce,
329 tcele,
330 thumb,
331 thumbeb,
332 i386,
333 x86_64,
334 xcore,
335 nvptx,
336 nvptx64,
337 le32,
338 le64,
339 amdil,
340 amdil64,
341 hsail,
342 hsail64,
343 spir,
344 spir64,
345 kalimba,
346 shave,
347 lanai,
348 wasm32,
349 wasm64,
350 renderscript32,
351 renderscript64,
352 ve,
353
354 pub fn isARM(arch: Arch) bool {
355 return switch (arch) {
356 .arm, .armeb => true,
357 else => false,
358 };
359 }
660360
661 pub const SubSystem = enum {
662 Console,
663 Windows,
664 Posix,
665 Native,
666 EfiApplication,
667 EfiBootServiceDriver,
668 EfiRom,
669 EfiRuntimeDriver,
670 };
361 pub fn isThumb(arch: Arch) bool {
362 return switch (arch) {
363 .thumb, .thumbeb => true,
364 else => false,
365 };
366 }
671367
672 pub const Cross = struct {
673 arch: Arch,
674 os: Os,
675 abi: Abi,
676 cpu_features: CpuFeatures,
677 };
368 pub fn isWasm(arch: Arch) bool {
369 return switch (arch) {
370 .wasm32, .wasm64 => true,
371 else => false,
372 };
373 }
678374
679 pub const CpuFeatures = struct {
680 /// The CPU to target. It has a set of features
681 /// which are overridden with the `features` field.
682 cpu: *const Cpu,
375 pub fn isRISCV(arch: Arch) bool {
376 return switch (arch) {
377 .riscv32, .riscv64 => true,
378 else => false,
379 };
380 }
683381
684 /// Explicitly provide the entire CPU feature set.
685 features: Cpu.Feature.Set,
382 pub fn isMIPS(arch: Arch) bool {
383 return switch (arch) {
384 .mips, .mipsel, .mips64, .mips64el => true,
385 else => false,
386 };
387 }
686388
687 pub fn initFromCpu(arch: Arch, cpu: *const Cpu) CpuFeatures {
688 var features = cpu.features;
689 if (arch.subArchFeature()) |sub_arch_index| {
690 features.addFeature(sub_arch_index);
389 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
390 for (arch.allCpuModels()) |cpu| {
391 if (mem.eql(u8, cpu_name, cpu.name)) {
392 return cpu;
393 }
394 }
395 return error.UnknownCpu;
396 }
397
398 pub fn toElfMachine(arch: Arch) std.elf.EM {
399 return switch (arch) {
400 .avr => ._AVR,
401 .msp430 => ._MSP430,
402 .arc => ._ARC,
403 .arm => ._ARM,
404 .armeb => ._ARM,
405 .hexagon => ._HEXAGON,
406 .le32 => ._NONE,
407 .mips => ._MIPS,
408 .mipsel => ._MIPS_RS3_LE,
409 .powerpc => ._PPC,
410 .r600 => ._NONE,
411 .riscv32 => ._RISCV,
412 .sparc => ._SPARC,
413 .sparcel => ._SPARC,
414 .tce => ._NONE,
415 .tcele => ._NONE,
416 .thumb => ._ARM,
417 .thumbeb => ._ARM,
418 .i386 => ._386,
419 .xcore => ._XCORE,
420 .nvptx => ._NONE,
421 .amdil => ._NONE,
422 .hsail => ._NONE,
423 .spir => ._NONE,
424 .kalimba => ._CSR_KALIMBA,
425 .shave => ._NONE,
426 .lanai => ._LANAI,
427 .wasm32 => ._NONE,
428 .renderscript32 => ._NONE,
429 .aarch64_32 => ._AARCH64,
430 .aarch64 => ._AARCH64,
431 .aarch64_be => ._AARCH64,
432 .mips64 => ._MIPS,
433 .mips64el => ._MIPS_RS3_LE,
434 .powerpc64 => ._PPC64,
435 .powerpc64le => ._PPC64,
436 .riscv64 => ._RISCV,
437 .x86_64 => ._X86_64,
438 .nvptx64 => ._NONE,
439 .le64 => ._NONE,
440 .amdil64 => ._NONE,
441 .hsail64 => ._NONE,
442 .spir64 => ._NONE,
443 .wasm64 => ._NONE,
444 .renderscript64 => ._NONE,
445 .amdgcn => ._NONE,
446 .bpfel => ._BPF,
447 .bpfeb => ._BPF,
448 .sparcv9 => ._SPARCV9,
449 .s390x => ._S390,
450 };
451 }
452
453 pub fn endian(arch: Arch) builtin.Endian {
454 return switch (arch) {
455 .avr,
456 .arm,
457 .aarch64_32,
458 .aarch64,
459 .amdgcn,
460 .amdil,
461 .amdil64,
462 .bpfel,
463 .hexagon,
464 .hsail,
465 .hsail64,
466 .kalimba,
467 .le32,
468 .le64,
469 .mipsel,
470 .mips64el,
471 .msp430,
472 .nvptx,
473 .nvptx64,
474 .sparcel,
475 .tcele,
476 .powerpc64le,
477 .r600,
478 .riscv32,
479 .riscv64,
480 .i386,
481 .x86_64,
482 .wasm32,
483 .wasm64,
484 .xcore,
485 .thumb,
486 .spir,
487 .spir64,
488 .renderscript32,
489 .renderscript64,
490 .shave,
491 => .Little,
492
493 .arc,
494 .armeb,
495 .aarch64_be,
496 .bpfeb,
497 .mips,
498 .mips64,
499 .powerpc,
500 .powerpc64,
501 .thumbeb,
502 .sparc,
503 .sparcv9,
504 .tce,
505 .lanai,
506 .s390x,
507 => .Big,
508 };
509 }
510
511 /// Returns a name that matches the lib/std/target/* directory name.
512 pub fn genericName(arch: Arch) []const u8 {
513 return switch (arch) {
514 .arm, .armeb, .thumb, .thumbeb => "arm",
515 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
516 .avr => "avr",
517 .bpfel, .bpfeb => "bpf",
518 .hexagon => "hexagon",
519 .mips, .mipsel, .mips64, .mips64el => "mips",
520 .msp430 => "msp430",
521 .powerpc, .powerpc64, .powerpc64le => "powerpc",
522 .amdgcn => "amdgpu",
523 .riscv32, .riscv64 => "riscv",
524 .sparc, .sparcv9, .sparcel => "sparc",
525 .s390x => "systemz",
526 .i386, .x86_64 => "x86",
527 .nvptx, .nvptx64 => "nvptx",
528 .wasm32, .wasm64 => "wasm",
529 else => @tagName(arch),
530 };
691531 }
692 features.populateDependencies(arch.allFeaturesList());
693 return CpuFeatures{
694 .cpu = cpu,
695 .features = features,
532
533 /// All CPU features Zig is aware of, sorted lexicographically by name.
534 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
535 return switch (arch) {
536 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
537 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
538 .avr => &avr.all_features,
539 .bpfel, .bpfeb => &bpf.all_features,
540 .hexagon => &hexagon.all_features,
541 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
542 .msp430 => &msp430.all_features,
543 .powerpc, .powerpc64, .powerpc64le => &powerpc.all_features,
544 .amdgcn => &amdgpu.all_features,
545 .riscv32, .riscv64 => &riscv.all_features,
546 .sparc, .sparcv9, .sparcel => &sparc.all_features,
547 .s390x => &systemz.all_features,
548 .i386, .x86_64 => &x86.all_features,
549 .nvptx, .nvptx64 => &nvptx.all_features,
550 .wasm32, .wasm64 => &wasm.all_features,
551
552 else => &[0]Cpu.Feature{},
553 };
554 }
555
556 /// All processors Zig is aware of, sorted lexicographically by name.
557 pub fn allCpuModels(arch: Arch) []const *const Cpu.Model {
558 return switch (arch) {
559 .arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
560 .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
561 .avr => avr.all_cpus,
562 .bpfel, .bpfeb => bpf.all_cpus,
563 .hexagon => hexagon.all_cpus,
564 .mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
565 .msp430 => msp430.all_cpus,
566 .powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
567 .amdgcn => amdgpu.all_cpus,
568 .riscv32, .riscv64 => riscv.all_cpus,
569 .sparc, .sparcv9, .sparcel => sparc.all_cpus,
570 .s390x => systemz.all_cpus,
571 .i386, .x86_64 => x86.all_cpus,
572 .nvptx, .nvptx64 => nvptx.all_cpus,
573 .wasm32, .wasm64 => wasm.all_cpus,
574
575 else => &[0]*const Model{},
576 };
577 }
578
579 pub fn parse(text: []const u8) !Arch {
580 const info = @typeInfo(Arch);
581 inline for (info.Enum.fields) |field| {
582 if (mem.eql(u8, text, field.name)) {
583 return @as(Arch, @field(Arch, field.name));
584 }
585 }
586 return error.UnknownArchitecture;
587 }
588 };
589
590 pub const Model = struct {
591 name: []const u8,
592 llvm_name: ?[:0]const u8,
593 features: Feature.Set,
594
595 pub fn toCpu(model: *const Model, arch: Arch) Cpu {
596 var features = model.features;
597 features.populateDependencies(arch.allFeaturesList());
598 return .{
599 .arch = arch,
600 .model = model,
601 .features = features,
602 };
603 }
604 };
605
606 /// The "default" set of CPU features for cross-compiling. A conservative set
607 /// of features that is expected to be supported on most available hardware.
608 pub fn baseline(arch: Arch) Cpu {
609 const S = struct {
610 const generic_model = Model{
611 .name = "generic",
612 .llvm_name = null,
613 .features = Cpu.Feature.Set.empty,
614 };
696615 };
616 const model = switch (arch) {
617 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline,
618 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
619 .avr => &avr.cpu.avr1,
620 .bpfel, .bpfeb => &bpf.cpu.generic,
621 .hexagon => &hexagon.cpu.generic,
622 .mips, .mipsel => &mips.cpu.mips32,
623 .mips64, .mips64el => &mips.cpu.mips64,
624 .msp430 => &msp430.cpu.generic,
625 .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
626 .amdgcn => &amdgpu.cpu.generic,
627 .riscv32 => &riscv.cpu.baseline_rv32,
628 .riscv64 => &riscv.cpu.baseline_rv64,
629 .sparc, .sparcv9, .sparcel => &sparc.cpu.generic,
630 .s390x => &systemz.cpu.generic,
631 .i386 => &x86.cpu.pentium4,
632 .x86_64 => &x86.cpu.x86_64,
633 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
634 .wasm32, .wasm64 => &wasm.cpu.generic,
635
636 else => &S.generic_model,
637 };
638 return model.toCpu(arch);
697639 }
698640 };
699641
700642 pub const current = Target{
701643 .Cross = Cross{
702 .arch = builtin.arch,
644 .cpu = builtin.cpu,
703645 .os = builtin.os,
704646 .abi = builtin.abi,
705 .cpu_features = builtin.cpu_features,
706647 },
707648 };
708649
709650 pub const stack_align = 16;
710651
711 pub fn getCpuFeatures(self: Target) CpuFeatures {
712 return switch (self) {
713 .Native => builtin.cpu_features,
714 .Cross => |cross| cross.cpu_features,
715 };
716 }
717
718652 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
719 return std.fmt.allocPrint(allocator, "{}{}-{}-{}", .{
653 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{
720654 @tagName(self.getArch()),
721 Target.archSubArchName(self.getArch()),
722655 @tagName(self.getOs()),
723656 @tagName(self.getAbi()),
724657 });
......@@ -780,139 +713,115 @@ pub const Target = union(enum) {
780713 });
781714 }
782715
783 /// TODO: Support CPU features here?
784 /// https://github.com/ziglang/zig/issues/4261
785 pub fn parse(text: []const u8) !Target {
786 var it = mem.separate(text, "-");
787 const arch_name = it.next() orelse return error.MissingArchitecture;
788 const os_name = it.next() orelse return error.MissingOperatingSystem;
789 const abi_name = it.next();
790 const arch = try parseArchSub(arch_name);
716 pub const ParseOptions = struct {
717 /// This is sometimes called a "triple". It looks roughly like this:
718 /// riscv64-linux-gnu
719 /// The fields are, respectively:
720 /// * CPU Architecture
721 /// * Operating System
722 /// * C ABI (optional)
723 arch_os_abi: []const u8,
791724
792 var cross = Cross{
793 .arch = arch,
794 .cpu_features = arch.getBaselineCpuFeatures(),
795 .os = try parseOs(os_name),
796 .abi = undefined,
797 };
798 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
799 return Target{ .Cross = cross };
800 }
725 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
726 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
727 /// to remove from the set.
728 cpu_features: []const u8 = "baseline",
801729
802 pub fn defaultAbi(arch: Arch, target_os: Os) Abi {
803 switch (arch) {
804 .wasm32, .wasm64 => return .musl,
805 else => {},
806 }
807 switch (target_os) {
808 .freestanding,
809 .ananas,
810 .cloudabi,
811 .dragonfly,
812 .lv2,
813 .solaris,
814 .haiku,
815 .minix,
816 .rtems,
817 .nacl,
818 .cnk,
819 .aix,
820 .cuda,
821 .nvcl,
822 .amdhsa,
823 .ps4,
824 .elfiamcu,
825 .mesa3d,
826 .contiki,
827 .amdpal,
828 .hermit,
829 .other,
830 => return .eabi,
831 .openbsd,
832 .macosx,
833 .freebsd,
834 .ios,
835 .tvos,
836 .watchos,
837 .fuchsia,
838 .kfreebsd,
839 .netbsd,
840 .hurd,
841 => return .gnu,
842 .windows,
843 .uefi,
844 => return .msvc,
845 .linux,
846 .wasi,
847 .emscripten,
848 => return .musl,
849 }
850 }
730 /// If this is provided, the function will populate some information about parsing failures,
731 /// so that user-friendly error messages can be delivered.
732 diagnostics: ?*Diagnostics = null,
851733
852 pub const ParseArchSubError = error{
853 UnknownArchitecture,
854 UnknownSubArchitecture,
855 };
734 pub const Diagnostics = struct {
735 /// If the architecture was determined, this will be populated.
736 arch: ?Cpu.Arch = null,
856737
857 pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
858 const info = @typeInfo(Arch);
859 inline for (info.Union.fields) |field| {
860 if (mem.startsWith(u8, text, field.name)) {
861 if (field.field_type == void) {
862 return @as(Arch, @field(Arch, field.name));
863 } else {
864 const sub_info = @typeInfo(field.field_type);
865 inline for (sub_info.Enum.fields) |sub_field| {
866 const combined = field.name ++ sub_field.name;
867 if (mem.eql(u8, text, combined)) {
868 return @unionInit(Arch, field.name, @field(field.field_type, sub_field.name));
869 }
870 }
871 return error.UnknownSubArchitecture;
872 }
873 }
874 }
875 return error.UnknownArchitecture;
876 }
738 /// If the OS was determined, this will be populated.
739 os: ?Os = null,
877740
878 pub fn parseOs(text: []const u8) !Os {
879 const info = @typeInfo(Os);
880 inline for (info.Enum.fields) |field| {
881 if (mem.eql(u8, text, field.name)) {
882 return @field(Os, field.name);
883 }
884 }
885 return error.UnknownOperatingSystem;
886 }
741 /// If the ABI was determined, this will be populated.
742 abi: ?Abi = null,
887743
888 pub fn parseAbi(text: []const u8) !Abi {
889 const info = @typeInfo(Abi);
890 inline for (info.Enum.fields) |field| {
891 if (mem.eql(u8, text, field.name)) {
892 return @field(Abi, field.name);
893 }
894 }
895 return error.UnknownApplicationBinaryInterface;
896 }
744 /// If the CPU name was determined, this will be populated.
745 cpu_name: ?[]const u8 = null,
897746
898 fn archSubArchName(arch: Arch) []const u8 {
899 return switch (arch) {
900 .arm => |sub| @tagName(sub),
901 .armeb => |sub| @tagName(sub),
902 .thumb => |sub| @tagName(sub),
903 .thumbeb => |sub| @tagName(sub),
904 .aarch64 => |sub| @tagName(sub),
905 .aarch64_be => |sub| @tagName(sub),
906 .kalimba => |sub| @tagName(sub),
907 else => "",
747 /// If error.UnknownCpuFeature is returned, this will be populated.
748 unknown_feature_name: ?[]const u8 = null,
908749 };
909 }
750 };
910751
911 pub fn subArchName(self: Target) []const u8 {
912 switch (self) {
913 .Native => return archSubArchName(builtin.arch),
914 .Cross => |cross| return archSubArchName(cross.arch),
752 pub fn parse(args: ParseOptions) !Target {
753 var dummy_diags: ParseOptions.Diagnostics = undefined;
754 var diags = args.diagnostics orelse &dummy_diags;
755
756 var it = mem.separate(args.arch_os_abi, "-");
757 const arch_name = it.next() orelse return error.MissingArchitecture;
758 const arch = try Cpu.Arch.parse(arch_name);
759 diags.arch = arch;
760
761 const os_name = it.next() orelse return error.MissingOperatingSystem;
762 const os = try Os.parse(os_name);
763 diags.os = os;
764
765 const abi_name = it.next();
766 const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);
767 diags.abi = abi;
768
769 if (it.next() != null) return error.UnexpectedExtraField;
770
771 const all_features = arch.allFeaturesList();
772 var index: usize = 0;
773 while (index < args.cpu_features.len and
774 args.cpu_features[index] != '+' and
775 args.cpu_features[index] != '-')
776 {
777 index += 1;
915778 }
779 const cpu_name = args.cpu_features[0..index];
780 diags.cpu_name = cpu_name;
781
782 const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: {
783 const cpu_model = try arch.parseCpuModel(cpu_name);
784
785 var set = cpu_model.features;
786 while (index < args.cpu_features.len) {
787 const op = args.cpu_features[index];
788 index += 1;
789 const start = index;
790 while (index < args.cpu_features.len and
791 args.cpu_features[index] != '+' and
792 args.cpu_features[index] != '-')
793 {
794 index += 1;
795 }
796 const feature_name = args.cpu_features[start..index];
797 for (all_features) |feature, feat_index_usize| {
798 const feat_index = @intCast(Cpu.Feature.Set.Index, feat_index_usize);
799 if (mem.eql(u8, feature_name, feature.name)) {
800 switch (op) {
801 '+' => set.addFeature(feat_index),
802 '-' => set.removeFeature(feat_index),
803 else => unreachable,
804 }
805 break;
806 }
807 } else {
808 diags.unknown_feature_name = feature_name;
809 return error.UnknownCpuFeature;
810 }
811 }
812 set.populateDependencies(all_features);
813 break :blk .{
814 .arch = arch,
815 .model = cpu_model,
816 .features = set,
817 };
818 };
819 var cross = Cross{
820 .cpu = cpu,
821 .os = os,
822 .abi = abi,
823 };
824 return Target{ .Cross = cross };
916825 }
917826
918827 pub fn oFileExt(self: Target) []const u8 {
......@@ -971,11 +880,15 @@ pub const Target = union(enum) {
971880 };
972881 }
973882
974 pub fn getArch(self: Target) Arch {
975 switch (self) {
976 .Native => return builtin.arch,
977 .Cross => |t| return t.arch,
978 }
883 pub fn getCpu(self: Target) Cpu {
884 return switch (self) {
885 .Native => builtin.cpu,
886 .Cross => |cross| cross.cpu,
887 };
888 }
889
890 pub fn getArch(self: Target) Cpu.Arch {
891 return self.getCpu().arch;
979892 }
980893
981894 pub fn getAbi(self: Target) Abi {
......@@ -1041,6 +954,20 @@ pub const Target = union(enum) {
1041954 };
1042955 }
1043956
957 pub fn isAndroid(self: Target) bool {
958 return switch (self.getAbi()) {
959 .android => true,
960 else => false,
961 };
962 }
963
964 pub fn isDragonFlyBSD(self: Target) bool {
965 return switch (self.getOs()) {
966 .dragonfly => true,
967 else => false,
968 };
969 }
970
1044971 pub fn isUefi(self: Target) bool {
1045972 return switch (self.getOs()) {
1046973 .uefi => true,
......@@ -1194,16 +1121,202 @@ pub const Target = union(enum) {
11941121
11951122 return .unavailable;
11961123 }
1124
1125 pub const FloatAbi = enum {
1126 hard,
1127 soft,
1128 soft_fp,
1129 };
1130
1131 pub fn getFloatAbi(self: Target) FloatAbi {
1132 return switch (self.getAbi()) {
1133 .gnueabihf,
1134 .eabihf,
1135 .musleabihf,
1136 => .hard,
1137 else => .soft,
1138 };
1139 }
1140
1141 pub fn hasDynamicLinker(self: Target) bool {
1142 switch (self.getArch()) {
1143 .wasm32,
1144 .wasm64,
1145 => return false,
1146 else => {},
1147 }
1148 switch (self.getOs()) {
1149 .freestanding,
1150 .ios,
1151 .tvos,
1152 .watchos,
1153 .macosx,
1154 .uefi,
1155 .windows,
1156 .emscripten,
1157 .other,
1158 => return false,
1159 else => return true,
1160 }
1161 }
1162
1163 /// Caller owns returned memory.
1164 pub fn getStandardDynamicLinkerPath(
1165 self: Target,
1166 allocator: *mem.Allocator,
1167 ) error{
1168 OutOfMemory,
1169 UnknownDynamicLinkerPath,
1170 TargetHasNoDynamicLinker,
1171 }![:0]u8 {
1172 const a = allocator;
1173 if (self.isAndroid()) {
1174 return mem.dupeZ(a, u8, if (self.getArchPtrBitWidth() == 64)
1175 "/system/bin/linker64"
1176 else
1177 "/system/bin/linker");
1178 }
1179
1180 if (self.isMusl()) {
1181 var result = try std.Buffer.init(allocator, "/lib/ld-musl-");
1182 defer result.deinit();
1183
1184 var is_arm = false;
1185 switch (self.getArch()) {
1186 .arm, .thumb => {
1187 try result.append("arm");
1188 is_arm = true;
1189 },
1190 .armeb, .thumbeb => {
1191 try result.append("armeb");
1192 is_arm = true;
1193 },
1194 else => |arch| try result.append(@tagName(arch)),
1195 }
1196 if (is_arm and self.getFloatAbi() == .hard) {
1197 try result.append("hf");
1198 }
1199 try result.append(".so.1");
1200 return result.toOwnedSlice();
1201 }
1202
1203 switch (self.getOs()) {
1204 .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"),
1205 .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"),
1206 .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"),
1207 .linux => switch (self.getArch()) {
1208 .i386,
1209 .sparc,
1210 .sparcel,
1211 => return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"),
1212
1213 .aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"),
1214 .aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"),
1215 .aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"),
1216
1217 .arm,
1218 .armeb,
1219 .thumb,
1220 .thumbeb,
1221 => return mem.dupeZ(a, u8, switch (self.getFloatAbi()) {
1222 .hard => "/lib/ld-linux-armhf.so.3",
1223 else => "/lib/ld-linux.so.3",
1224 }),
1225
1226 .mips,
1227 .mipsel,
1228 .mips64,
1229 .mips64el,
1230 => return error.UnknownDynamicLinkerPath,
1231
1232 .powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"),
1233 .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"),
1234 .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"),
1235 .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"),
1236 .x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) {
1237 .gnux32 => "/libx32/ld-linux-x32.so.2",
1238 else => "/lib64/ld-linux-x86-64.so.2",
1239 }),
1240
1241 .riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"),
1242 .riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"),
1243
1244 .wasm32,
1245 .wasm64,
1246 => return error.TargetHasNoDynamicLinker,
1247
1248 .arc,
1249 .avr,
1250 .bpfel,
1251 .bpfeb,
1252 .hexagon,
1253 .msp430,
1254 .r600,
1255 .amdgcn,
1256 .tce,
1257 .tcele,
1258 .xcore,
1259 .nvptx,
1260 .nvptx64,
1261 .le32,
1262 .le64,
1263 .amdil,
1264 .amdil64,
1265 .hsail,
1266 .hsail64,
1267 .spir,
1268 .spir64,
1269 .kalimba,
1270 .shave,
1271 .lanai,
1272 .renderscript32,
1273 .renderscript64,
1274 .ve,
1275 => return error.UnknownDynamicLinkerPath,
1276 },
1277
1278 .freestanding,
1279 .ios,
1280 .tvos,
1281 .watchos,
1282 .macosx,
1283 .uefi,
1284 .windows,
1285 .emscripten,
1286 .other,
1287 => return error.TargetHasNoDynamicLinker,
1288
1289 else => return error.UnknownDynamicLinkerPath,
1290 }
1291 }
11971292};
11981293
1199test "parseCpuFeatureSet" {
1200 const arch: Target.Arch = .x86_64;
1201 const baseline = arch.getBaselineCpuFeatures();
1202 const set = try arch.parseCpuFeatureSet(baseline.cpu, "-sse,-avx,-cx8");
1203 std.testing.expect(!Target.x86.featureSetHas(set, .sse));
1204 std.testing.expect(!Target.x86.featureSetHas(set, .avx));
1205 std.testing.expect(!Target.x86.featureSetHas(set, .cx8));
1206 // These are expected because they are part of the baseline
1207 std.testing.expect(Target.x86.featureSetHas(set, .cmov));
1208 std.testing.expect(Target.x86.featureSetHas(set, .fxsr));
1294test "Target.parse" {
1295 {
1296 const target = (try Target.parse(.{
1297 .arch_os_abi = "x86_64-linux-gnu",
1298 .cpu_features = "x86_64-sse-sse2-avx-cx8",
1299 })).Cross;
1300
1301 std.testing.expect(target.os == .linux);
1302 std.testing.expect(target.abi == .gnu);
1303 std.testing.expect(target.cpu.arch == .x86_64);
1304 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
1305 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
1306 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
1307 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
1308 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
1309 }
1310 {
1311 const target = (try Target.parse(.{
1312 .arch_os_abi = "arm-linux-musleabihf",
1313 .cpu_features = "generic+v8a",
1314 })).Cross;
1315
1316 std.testing.expect(target.os == .linux);
1317 std.testing.expect(target.abi == .musleabihf);
1318 std.testing.expect(target.cpu.arch == .arm);
1319 std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
1320 std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
1321 }
12091322}
lib/std/target/aarch64.zig+201-373
......@@ -1,15 +1,9 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
5 a35,
6 a53,
7 a55,
8 a57,
96 a65,
10 a72,
11 a73,
12 a75,
137 a76,
148 aes,
159 aggressive_fma,
......@@ -46,11 +40,7 @@ pub const Feature = enum {
4640 dotprod,
4741 ete,
4842 exynos_cheap_as_move,
49 exynosm1,
50 exynosm2,
51 exynosm3,
5243 exynosm4,
53 falkor,
5444 fmi,
5545 force_32bit_jump_tables,
5646 fp_armv8,
......@@ -64,7 +54,6 @@ pub const Feature = enum {
6454 fuse_csel,
6555 fuse_literals,
6656 jsconv,
67 kryo,
6857 lor,
6958 lse,
7059 lsl_fast,
......@@ -112,7 +101,6 @@ pub const Feature = enum {
112101 reserve_x6,
113102 reserve_x7,
114103 reserve_x9,
115 saphira,
116104 sb,
117105 sel2,
118106 sha2,
......@@ -132,11 +120,6 @@ pub const Feature = enum {
132120 sve2_sha3,
133121 sve2_sm4,
134122 tagged_globals,
135 thunderx,
136 thunderx2t99,
137 thunderxt81,
138 thunderxt83,
139 thunderxt88,
140123 tlb_rmi,
141124 tme,
142125 tpidr_el1,
......@@ -144,7 +127,6 @@ pub const Feature = enum {
144127 tpidr_el3,
145128 tracev8_4,
146129 trbe,
147 tsv110,
148130 uaops,
149131 use_aa,
150132 use_postra_scheduler,
......@@ -163,72 +145,13 @@ pub const Feature = enum {
163145 zcz_gp,
164146};
165147
166pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
148pub usingnamespace CpuFeature.feature_set_fns(Feature);
167149
168150pub const all_features = blk: {
169151 @setEvalBranchQuota(2000);
170152 const len = @typeInfo(Feature).Enum.fields.len;
171 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
172 var result: [len]Cpu.Feature = undefined;
173 result[@enumToInt(Feature.a35)] = .{
174 .llvm_name = "a35",
175 .description = "Cortex-A35 ARM processors",
176 .dependencies = featureSet(&[_]Feature{
177 .crc,
178 .crypto,
179 .fp_armv8,
180 .neon,
181 .perfmon,
182 }),
183 };
184 result[@enumToInt(Feature.a53)] = .{
185 .llvm_name = "a53",
186 .description = "Cortex-A53 ARM processors",
187 .dependencies = featureSet(&[_]Feature{
188 .balance_fp_ops,
189 .crc,
190 .crypto,
191 .custom_cheap_as_move,
192 .fp_armv8,
193 .fuse_aes,
194 .neon,
195 .perfmon,
196 .use_aa,
197 .use_postra_scheduler,
198 }),
199 };
200 result[@enumToInt(Feature.a55)] = .{
201 .llvm_name = "a55",
202 .description = "Cortex-A55 ARM processors",
203 .dependencies = featureSet(&[_]Feature{
204 .crypto,
205 .dotprod,
206 .fp_armv8,
207 .fullfp16,
208 .fuse_aes,
209 .neon,
210 .perfmon,
211 .rcpc,
212 .v8_2a,
213 }),
214 };
215 result[@enumToInt(Feature.a57)] = .{
216 .llvm_name = "a57",
217 .description = "Cortex-A57 ARM processors",
218 .dependencies = featureSet(&[_]Feature{
219 .balance_fp_ops,
220 .crc,
221 .crypto,
222 .custom_cheap_as_move,
223 .fp_armv8,
224 .fuse_aes,
225 .fuse_literals,
226 .neon,
227 .perfmon,
228 .predictable_select_expensive,
229 .use_postra_scheduler,
230 }),
231 };
153 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
154 var result: [len]CpuFeature = undefined;
232155 result[@enumToInt(Feature.a65)] = .{
233156 .llvm_name = "a65",
234157 .description = "Cortex-A65 ARM processors",
......@@ -244,54 +167,13 @@ pub const all_features = blk: {
244167 .v8_2a,
245168 }),
246169 };
247 result[@enumToInt(Feature.a72)] = .{
248 .llvm_name = "a72",
249 .description = "Cortex-A72 ARM processors",
250 .dependencies = featureSet(&[_]Feature{
251 .crc,
252 .crypto,
253 .fp_armv8,
254 .fuse_aes,
255 .neon,
256 .perfmon,
257 }),
258 };
259 result[@enumToInt(Feature.a73)] = .{
260 .llvm_name = "a73",
261 .description = "Cortex-A73 ARM processors",
262 .dependencies = featureSet(&[_]Feature{
263 .crc,
264 .crypto,
265 .fp_armv8,
266 .fuse_aes,
267 .neon,
268 .perfmon,
269 }),
270 };
271 result[@enumToInt(Feature.a75)] = .{
272 .llvm_name = "a75",
273 .description = "Cortex-A75 ARM processors",
274 .dependencies = featureSet(&[_]Feature{
275 .crypto,
276 .dotprod,
277 .fp_armv8,
278 .fullfp16,
279 .fuse_aes,
280 .neon,
281 .perfmon,
282 .rcpc,
283 .v8_2a,
284 }),
285 };
286170 result[@enumToInt(Feature.a76)] = .{
287171 .llvm_name = "a76",
288172 .description = "Cortex-A76 ARM processors",
289173 .dependencies = featureSet(&[_]Feature{
290174 .crypto,
291175 .dotprod,
292 .fp_armv8,
293176 .fullfp16,
294 .neon,
295177 .rcpc,
296178 .ssbs,
297179 .v8_2a,
......@@ -563,58 +445,6 @@ pub const all_features = blk: {
563445 .custom_cheap_as_move,
564446 }),
565447 };
566 result[@enumToInt(Feature.exynosm1)] = .{
567 .llvm_name = null,
568 .description = "Samsung Exynos-M1 processors",
569 .dependencies = featureSet(&[_]Feature{
570 .crc,
571 .crypto,
572 .exynos_cheap_as_move,
573 .force_32bit_jump_tables,
574 .fuse_aes,
575 .perfmon,
576 .slow_misaligned_128store,
577 .slow_paired_128,
578 .use_postra_scheduler,
579 .use_reciprocal_square_root,
580 .zcz_fp,
581 }),
582 };
583 result[@enumToInt(Feature.exynosm2)] = .{
584 .llvm_name = null,
585 .description = "Samsung Exynos-M2 processors",
586 .dependencies = featureSet(&[_]Feature{
587 .crc,
588 .crypto,
589 .exynos_cheap_as_move,
590 .force_32bit_jump_tables,
591 .fuse_aes,
592 .perfmon,
593 .slow_misaligned_128store,
594 .slow_paired_128,
595 .use_postra_scheduler,
596 .zcz_fp,
597 }),
598 };
599 result[@enumToInt(Feature.exynosm3)] = .{
600 .llvm_name = "exynosm3",
601 .description = "Samsung Exynos-M3 processors",
602 .dependencies = featureSet(&[_]Feature{
603 .crc,
604 .crypto,
605 .exynos_cheap_as_move,
606 .force_32bit_jump_tables,
607 .fuse_address,
608 .fuse_aes,
609 .fuse_csel,
610 .fuse_literals,
611 .lsl_fast,
612 .perfmon,
613 .predictable_select_expensive,
614 .use_postra_scheduler,
615 .zcz_fp,
616 }),
617 };
618448 result[@enumToInt(Feature.exynosm4)] = .{
619449 .llvm_name = "exynosm4",
620450 .description = "Samsung Exynos-M4 processors",
......@@ -638,24 +468,6 @@ pub const all_features = blk: {
638468 .zcz,
639469 }),
640470 };
641 result[@enumToInt(Feature.falkor)] = .{
642 .llvm_name = "falkor",
643 .description = "Qualcomm Falkor processors",
644 .dependencies = featureSet(&[_]Feature{
645 .crc,
646 .crypto,
647 .custom_cheap_as_move,
648 .fp_armv8,
649 .lsl_fast,
650 .neon,
651 .perfmon,
652 .predictable_select_expensive,
653 .rdm,
654 .slow_strqro_store,
655 .use_postra_scheduler,
656 .zcz,
657 }),
658 };
659471 result[@enumToInt(Feature.fmi)] = .{
660472 .llvm_name = "fmi",
661473 .description = "Enable v8.4-A Flag Manipulation Instructions",
......@@ -727,22 +539,6 @@ pub const all_features = blk: {
727539 .fp_armv8,
728540 }),
729541 };
730 result[@enumToInt(Feature.kryo)] = .{
731 .llvm_name = "kryo",
732 .description = "Qualcomm Kryo processors",
733 .dependencies = featureSet(&[_]Feature{
734 .crc,
735 .crypto,
736 .custom_cheap_as_move,
737 .fp_armv8,
738 .lsl_fast,
739 .neon,
740 .perfmon,
741 .predictable_select_expensive,
742 .use_postra_scheduler,
743 .zcz,
744 }),
745 };
746542 result[@enumToInt(Feature.lor)] = .{
747543 .llvm_name = "lor",
748544 .description = "Enables ARM v8.1 Limited Ordering Regions extension",
......@@ -1005,23 +801,6 @@ pub const all_features = blk: {
1005801 .description = "Reserve X9, making it unavailable as a GPR",
1006802 .dependencies = featureSet(&[_]Feature{}),
1007803 };
1008 result[@enumToInt(Feature.saphira)] = .{
1009 .llvm_name = "saphira",
1010 .description = "Qualcomm Saphira processors",
1011 .dependencies = featureSet(&[_]Feature{
1012 .crypto,
1013 .custom_cheap_as_move,
1014 .fp_armv8,
1015 .lsl_fast,
1016 .neon,
1017 .perfmon,
1018 .predictable_select_expensive,
1019 .spe,
1020 .use_postra_scheduler,
1021 .v8_4a,
1022 .zcz,
1023 }),
1024 };
1025804 result[@enumToInt(Feature.sb)] = .{
1026805 .llvm_name = "sb",
1027806 .description = "Enable v8.5 Speculation Barrier",
......@@ -1137,74 +916,6 @@ pub const all_features = blk: {
1137916 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
1138917 .dependencies = featureSet(&[_]Feature{}),
1139918 };
1140 result[@enumToInt(Feature.thunderx)] = .{
1141 .llvm_name = "thunderx",
1142 .description = "Cavium ThunderX processors",
1143 .dependencies = featureSet(&[_]Feature{
1144 .crc,
1145 .crypto,
1146 .fp_armv8,
1147 .neon,
1148 .perfmon,
1149 .predictable_select_expensive,
1150 .use_postra_scheduler,
1151 }),
1152 };
1153 result[@enumToInt(Feature.thunderx2t99)] = .{
1154 .llvm_name = "thunderx2t99",
1155 .description = "Cavium ThunderX2 processors",
1156 .dependencies = featureSet(&[_]Feature{
1157 .aggressive_fma,
1158 .arith_bcc_fusion,
1159 .crc,
1160 .crypto,
1161 .fp_armv8,
1162 .lse,
1163 .neon,
1164 .predictable_select_expensive,
1165 .use_postra_scheduler,
1166 .v8_1a,
1167 }),
1168 };
1169 result[@enumToInt(Feature.thunderxt81)] = .{
1170 .llvm_name = "thunderxt81",
1171 .description = "Cavium ThunderX processors",
1172 .dependencies = featureSet(&[_]Feature{
1173 .crc,
1174 .crypto,
1175 .fp_armv8,
1176 .neon,
1177 .perfmon,
1178 .predictable_select_expensive,
1179 .use_postra_scheduler,
1180 }),
1181 };
1182 result[@enumToInt(Feature.thunderxt83)] = .{
1183 .llvm_name = "thunderxt83",
1184 .description = "Cavium ThunderX processors",
1185 .dependencies = featureSet(&[_]Feature{
1186 .crc,
1187 .crypto,
1188 .fp_armv8,
1189 .neon,
1190 .perfmon,
1191 .predictable_select_expensive,
1192 .use_postra_scheduler,
1193 }),
1194 };
1195 result[@enumToInt(Feature.thunderxt88)] = .{
1196 .llvm_name = "thunderxt88",
1197 .description = "Cavium ThunderX processors",
1198 .dependencies = featureSet(&[_]Feature{
1199 .crc,
1200 .crypto,
1201 .fp_armv8,
1202 .neon,
1203 .perfmon,
1204 .predictable_select_expensive,
1205 .use_postra_scheduler,
1206 }),
1207 };
1208919 result[@enumToInt(Feature.tlb_rmi)] = .{
1209920 .llvm_name = "tlb-rmi",
1210921 .description = "Enable v8.4-A TLB Range and Maintenance Instructions",
......@@ -1240,24 +951,6 @@ pub const all_features = blk: {
1240951 .description = "Enable Trace Buffer Extension",
1241952 .dependencies = featureSet(&[_]Feature{}),
1242953 };
1243 result[@enumToInt(Feature.tsv110)] = .{
1244 .llvm_name = "tsv110",
1245 .description = "HiSilicon TS-V110 processors",
1246 .dependencies = featureSet(&[_]Feature{
1247 .crypto,
1248 .custom_cheap_as_move,
1249 .dotprod,
1250 .fp_armv8,
1251 .fp16fml,
1252 .fullfp16,
1253 .fuse_aes,
1254 .neon,
1255 .perfmon,
1256 .spe,
1257 .use_postra_scheduler,
1258 .v8_2a,
1259 }),
1260 };
1261954 result[@enumToInt(Feature.uaops)] = .{
1262955 .llvm_name = "uaops",
1263956 .description = "Enable v8.2 UAO PState",
......@@ -1398,282 +1091,417 @@ pub const all_features = blk: {
13981091};
13991092
14001093pub const cpu = struct {
1401 pub const apple_a10 = Cpu{
1094 pub const apple_a10 = CpuModel{
14021095 .name = "apple_a10",
14031096 .llvm_name = "apple-a10",
14041097 .features = featureSet(&[_]Feature{
14051098 .apple_a10,
14061099 }),
14071100 };
1408 pub const apple_a11 = Cpu{
1101 pub const apple_a11 = CpuModel{
14091102 .name = "apple_a11",
14101103 .llvm_name = "apple-a11",
14111104 .features = featureSet(&[_]Feature{
14121105 .apple_a11,
14131106 }),
14141107 };
1415 pub const apple_a12 = Cpu{
1108 pub const apple_a12 = CpuModel{
14161109 .name = "apple_a12",
14171110 .llvm_name = "apple-a12",
14181111 .features = featureSet(&[_]Feature{
14191112 .apple_a12,
14201113 }),
14211114 };
1422 pub const apple_a13 = Cpu{
1115 pub const apple_a13 = CpuModel{
14231116 .name = "apple_a13",
14241117 .llvm_name = "apple-a13",
14251118 .features = featureSet(&[_]Feature{
14261119 .apple_a13,
14271120 }),
14281121 };
1429 pub const apple_a7 = Cpu{
1122 pub const apple_a7 = CpuModel{
14301123 .name = "apple_a7",
14311124 .llvm_name = "apple-a7",
14321125 .features = featureSet(&[_]Feature{
14331126 .apple_a7,
14341127 }),
14351128 };
1436 pub const apple_a8 = Cpu{
1129 pub const apple_a8 = CpuModel{
14371130 .name = "apple_a8",
14381131 .llvm_name = "apple-a8",
14391132 .features = featureSet(&[_]Feature{
14401133 .apple_a7,
14411134 }),
14421135 };
1443 pub const apple_a9 = Cpu{
1136 pub const apple_a9 = CpuModel{
14441137 .name = "apple_a9",
14451138 .llvm_name = "apple-a9",
14461139 .features = featureSet(&[_]Feature{
14471140 .apple_a7,
14481141 }),
14491142 };
1450 pub const apple_latest = Cpu{
1143 pub const apple_latest = CpuModel{
14511144 .name = "apple_latest",
14521145 .llvm_name = "apple-latest",
14531146 .features = featureSet(&[_]Feature{
14541147 .apple_a13,
14551148 }),
14561149 };
1457 pub const apple_s4 = Cpu{
1150 pub const apple_s4 = CpuModel{
14581151 .name = "apple_s4",
14591152 .llvm_name = "apple-s4",
14601153 .features = featureSet(&[_]Feature{
14611154 .apple_a12,
14621155 }),
14631156 };
1464 pub const apple_s5 = Cpu{
1157 pub const apple_s5 = CpuModel{
14651158 .name = "apple_s5",
14661159 .llvm_name = "apple-s5",
14671160 .features = featureSet(&[_]Feature{
14681161 .apple_a12,
14691162 }),
14701163 };
1471 pub const cortex_a35 = Cpu{
1164 pub const cortex_a35 = CpuModel{
14721165 .name = "cortex_a35",
14731166 .llvm_name = "cortex-a35",
14741167 .features = featureSet(&[_]Feature{
1475 .a35,
1168 .crc,
1169 .crypto,
1170 .perfmon,
1171 .v8a,
14761172 }),
14771173 };
1478 pub const cortex_a53 = Cpu{
1174 pub const cortex_a53 = CpuModel{
14791175 .name = "cortex_a53",
14801176 .llvm_name = "cortex-a53",
14811177 .features = featureSet(&[_]Feature{
1482 .a53,
1178 .balance_fp_ops,
1179 .crc,
1180 .crypto,
1181 .custom_cheap_as_move,
1182 .fuse_aes,
1183 .perfmon,
1184 .use_aa,
1185 .use_postra_scheduler,
1186 .v8a,
14831187 }),
14841188 };
1485 pub const cortex_a55 = Cpu{
1189 pub const cortex_a55 = CpuModel{
14861190 .name = "cortex_a55",
14871191 .llvm_name = "cortex-a55",
14881192 .features = featureSet(&[_]Feature{
1489 .a55,
1193 .crypto,
1194 .dotprod,
1195 .fullfp16,
1196 .fuse_aes,
1197 .perfmon,
1198 .rcpc,
1199 .v8_2a,
14901200 }),
14911201 };
1492 pub const cortex_a57 = Cpu{
1202 pub const cortex_a57 = CpuModel{
14931203 .name = "cortex_a57",
14941204 .llvm_name = "cortex-a57",
14951205 .features = featureSet(&[_]Feature{
1496 .a57,
1206 .balance_fp_ops,
1207 .crc,
1208 .crypto,
1209 .custom_cheap_as_move,
1210 .fuse_aes,
1211 .fuse_literals,
1212 .perfmon,
1213 .predictable_select_expensive,
1214 .use_postra_scheduler,
1215 .v8a,
14971216 }),
14981217 };
1499 pub const cortex_a65 = Cpu{
1218 pub const cortex_a65 = CpuModel{
15001219 .name = "cortex_a65",
15011220 .llvm_name = "cortex-a65",
15021221 .features = featureSet(&[_]Feature{
15031222 .a65,
15041223 }),
15051224 };
1506 pub const cortex_a65ae = Cpu{
1225 pub const cortex_a65ae = CpuModel{
15071226 .name = "cortex_a65ae",
15081227 .llvm_name = "cortex-a65ae",
15091228 .features = featureSet(&[_]Feature{
15101229 .a65,
15111230 }),
15121231 };
1513 pub const cortex_a72 = Cpu{
1232 pub const cortex_a72 = CpuModel{
15141233 .name = "cortex_a72",
15151234 .llvm_name = "cortex-a72",
15161235 .features = featureSet(&[_]Feature{
1517 .a72,
1236 .crc,
1237 .crypto,
1238 .fuse_aes,
1239 .perfmon,
1240 .v8a,
15181241 }),
15191242 };
1520 pub const cortex_a73 = Cpu{
1243 pub const cortex_a73 = CpuModel{
15211244 .name = "cortex_a73",
15221245 .llvm_name = "cortex-a73",
15231246 .features = featureSet(&[_]Feature{
1524 .a73,
1247 .crc,
1248 .crypto,
1249 .fuse_aes,
1250 .perfmon,
1251 .v8a,
15251252 }),
15261253 };
1527 pub const cortex_a75 = Cpu{
1254 pub const cortex_a75 = CpuModel{
15281255 .name = "cortex_a75",
15291256 .llvm_name = "cortex-a75",
15301257 .features = featureSet(&[_]Feature{
1531 .a75,
1258 .crypto,
1259 .dotprod,
1260 .fullfp16,
1261 .fuse_aes,
1262 .perfmon,
1263 .rcpc,
1264 .v8_2a,
15321265 }),
15331266 };
1534 pub const cortex_a76 = Cpu{
1267 pub const cortex_a76 = CpuModel{
15351268 .name = "cortex_a76",
15361269 .llvm_name = "cortex-a76",
15371270 .features = featureSet(&[_]Feature{
15381271 .a76,
15391272 }),
15401273 };
1541 pub const cortex_a76ae = Cpu{
1274 pub const cortex_a76ae = CpuModel{
15421275 .name = "cortex_a76ae",
15431276 .llvm_name = "cortex-a76ae",
15441277 .features = featureSet(&[_]Feature{
15451278 .a76,
15461279 }),
15471280 };
1548 pub const cyclone = Cpu{
1281 pub const cyclone = CpuModel{
15491282 .name = "cyclone",
15501283 .llvm_name = "cyclone",
15511284 .features = featureSet(&[_]Feature{
15521285 .apple_a7,
15531286 }),
15541287 };
1555 pub const exynos_m1 = Cpu{
1288 pub const exynos_m1 = CpuModel{
15561289 .name = "exynos_m1",
15571290 .llvm_name = null,
15581291 .features = featureSet(&[_]Feature{
1559 .exynosm1,
1292 .crc,
1293 .crypto,
1294 .exynos_cheap_as_move,
1295 .force_32bit_jump_tables,
1296 .fuse_aes,
1297 .perfmon,
1298 .slow_misaligned_128store,
1299 .slow_paired_128,
1300 .use_postra_scheduler,
1301 .use_reciprocal_square_root,
1302 .v8a,
1303 .zcz_fp,
15601304 }),
15611305 };
1562 pub const exynos_m2 = Cpu{
1306 pub const exynos_m2 = CpuModel{
15631307 .name = "exynos_m2",
15641308 .llvm_name = null,
15651309 .features = featureSet(&[_]Feature{
1566 .exynosm2,
1310 .crc,
1311 .crypto,
1312 .exynos_cheap_as_move,
1313 .force_32bit_jump_tables,
1314 .fuse_aes,
1315 .perfmon,
1316 .slow_misaligned_128store,
1317 .slow_paired_128,
1318 .use_postra_scheduler,
1319 .v8a,
1320 .zcz_fp,
15671321 }),
15681322 };
1569 pub const exynos_m3 = Cpu{
1323 pub const exynos_m3 = CpuModel{
15701324 .name = "exynos_m3",
15711325 .llvm_name = "exynos-m3",
15721326 .features = featureSet(&[_]Feature{
1573 .exynosm3,
1327 .crc,
1328 .crypto,
1329 .exynos_cheap_as_move,
1330 .force_32bit_jump_tables,
1331 .fuse_address,
1332 .fuse_aes,
1333 .fuse_csel,
1334 .fuse_literals,
1335 .lsl_fast,
1336 .perfmon,
1337 .predictable_select_expensive,
1338 .use_postra_scheduler,
1339 .v8a,
1340 .zcz_fp,
15741341 }),
15751342 };
1576 pub const exynos_m4 = Cpu{
1343 pub const exynos_m4 = CpuModel{
15771344 .name = "exynos_m4",
15781345 .llvm_name = "exynos-m4",
15791346 .features = featureSet(&[_]Feature{
15801347 .exynosm4,
15811348 }),
15821349 };
1583 pub const exynos_m5 = Cpu{
1350 pub const exynos_m5 = CpuModel{
15841351 .name = "exynos_m5",
15851352 .llvm_name = "exynos-m5",
15861353 .features = featureSet(&[_]Feature{
15871354 .exynosm4,
15881355 }),
15891356 };
1590 pub const falkor = Cpu{
1357 pub const falkor = CpuModel{
15911358 .name = "falkor",
15921359 .llvm_name = "falkor",
15931360 .features = featureSet(&[_]Feature{
1594 .falkor,
1361 .crc,
1362 .crypto,
1363 .custom_cheap_as_move,
1364 .lsl_fast,
1365 .perfmon,
1366 .predictable_select_expensive,
1367 .rdm,
1368 .slow_strqro_store,
1369 .use_postra_scheduler,
1370 .v8a,
1371 .zcz,
15951372 }),
15961373 };
1597 pub const generic = Cpu{
1374 pub const generic = CpuModel{
15981375 .name = "generic",
15991376 .llvm_name = "generic",
16001377 .features = featureSet(&[_]Feature{
16011378 .ete,
1602 .fp_armv8,
16031379 .fuse_aes,
1604 .neon,
16051380 .perfmon,
16061381 .use_postra_scheduler,
1382 .v8a,
16071383 }),
16081384 };
1609 pub const kryo = Cpu{
1385 pub const kryo = CpuModel{
16101386 .name = "kryo",
16111387 .llvm_name = "kryo",
16121388 .features = featureSet(&[_]Feature{
1613 .kryo,
1389 .crc,
1390 .crypto,
1391 .custom_cheap_as_move,
1392 .lsl_fast,
1393 .perfmon,
1394 .predictable_select_expensive,
1395 .use_postra_scheduler,
1396 .zcz,
1397 .v8a,
16141398 }),
16151399 };
1616 pub const neoverse_e1 = Cpu{
1400 pub const neoverse_e1 = CpuModel{
16171401 .name = "neoverse_e1",
16181402 .llvm_name = "neoverse-e1",
16191403 .features = featureSet(&[_]Feature{
16201404 .neoversee1,
16211405 }),
16221406 };
1623 pub const neoverse_n1 = Cpu{
1407 pub const neoverse_n1 = CpuModel{
16241408 .name = "neoverse_n1",
16251409 .llvm_name = "neoverse-n1",
16261410 .features = featureSet(&[_]Feature{
16271411 .neoversen1,
16281412 }),
16291413 };
1630 pub const saphira = Cpu{
1414 pub const saphira = CpuModel{
16311415 .name = "saphira",
16321416 .llvm_name = "saphira",
16331417 .features = featureSet(&[_]Feature{
1634 .saphira,
1418 .crypto,
1419 .custom_cheap_as_move,
1420 .lsl_fast,
1421 .perfmon,
1422 .predictable_select_expensive,
1423 .spe,
1424 .use_postra_scheduler,
1425 .v8_4a,
1426 .zcz,
16351427 }),
16361428 };
1637 pub const thunderx = Cpu{
1429 pub const thunderx = CpuModel{
16381430 .name = "thunderx",
16391431 .llvm_name = "thunderx",
16401432 .features = featureSet(&[_]Feature{
1641 .thunderx,
1433 .crc,
1434 .crypto,
1435 .perfmon,
1436 .predictable_select_expensive,
1437 .use_postra_scheduler,
1438 .v8a,
16421439 }),
16431440 };
1644 pub const thunderx2t99 = Cpu{
1441 pub const thunderx2t99 = CpuModel{
16451442 .name = "thunderx2t99",
16461443 .llvm_name = "thunderx2t99",
16471444 .features = featureSet(&[_]Feature{
1648 .thunderx2t99,
1445 .aggressive_fma,
1446 .arith_bcc_fusion,
1447 .crc,
1448 .crypto,
1449 .lse,
1450 .predictable_select_expensive,
1451 .use_postra_scheduler,
1452 .v8_1a,
16491453 }),
16501454 };
1651 pub const thunderxt81 = Cpu{
1455 pub const thunderxt81 = CpuModel{
16521456 .name = "thunderxt81",
16531457 .llvm_name = "thunderxt81",
16541458 .features = featureSet(&[_]Feature{
1655 .thunderxt81,
1459 .crc,
1460 .crypto,
1461 .perfmon,
1462 .predictable_select_expensive,
1463 .use_postra_scheduler,
1464 .v8a,
16561465 }),
16571466 };
1658 pub const thunderxt83 = Cpu{
1467 pub const thunderxt83 = CpuModel{
16591468 .name = "thunderxt83",
16601469 .llvm_name = "thunderxt83",
16611470 .features = featureSet(&[_]Feature{
1662 .thunderxt83,
1471 .crc,
1472 .crypto,
1473 .perfmon,
1474 .predictable_select_expensive,
1475 .use_postra_scheduler,
1476 .v8a,
16631477 }),
16641478 };
1665 pub const thunderxt88 = Cpu{
1479 pub const thunderxt88 = CpuModel{
16661480 .name = "thunderxt88",
16671481 .llvm_name = "thunderxt88",
16681482 .features = featureSet(&[_]Feature{
1669 .thunderxt88,
1483 .crc,
1484 .crypto,
1485 .perfmon,
1486 .predictable_select_expensive,
1487 .use_postra_scheduler,
1488 .v8a,
16701489 }),
16711490 };
1672 pub const tsv110 = Cpu{
1491 pub const tsv110 = CpuModel{
16731492 .name = "tsv110",
16741493 .llvm_name = "tsv110",
16751494 .features = featureSet(&[_]Feature{
1676 .tsv110,
1495 .crypto,
1496 .custom_cheap_as_move,
1497 .dotprod,
1498 .fp16fml,
1499 .fullfp16,
1500 .fuse_aes,
1501 .perfmon,
1502 .spe,
1503 .use_postra_scheduler,
1504 .v8_2a,
16771505 }),
16781506 };
16791507};
......@@ -1681,7 +1509,7 @@ pub const cpu = struct {
16811509/// All aarch64 CPUs, sorted alphabetically by name.
16821510/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
16831511/// compiler has inefficient memory and CPU usage, affecting build times.
1684pub const all_cpus = &[_]*const Cpu{
1512pub const all_cpus = &[_]*const CpuModel{
16851513 &cpu.apple_a10,
16861514 &cpu.apple_a11,
16871515 &cpu.apple_a12,
lib/std/target/amdgpu.zig+45-44
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 @"16_bit_insts",
......@@ -112,12 +113,12 @@ pub const Feature = enum {
112113 xnack,
113114};
114115
115pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
116pub usingnamespace CpuFeature.feature_set_fns(Feature);
116117
117118pub const all_features = blk: {
118119 const len = @typeInfo(Feature).Enum.fields.len;
119 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
120 var result: [len]Cpu.Feature = undefined;
120 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
121 var result: [len]CpuFeature = undefined;
121122 result[@enumToInt(Feature.@"16_bit_insts")] = .{
122123 .llvm_name = "16-bit-insts",
123124 .description = "Has i16/f16 instructions",
......@@ -784,7 +785,7 @@ pub const all_features = blk: {
784785};
785786
786787pub const cpu = struct {
787 pub const bonaire = Cpu{
788 pub const bonaire = CpuModel{
788789 .name = "bonaire",
789790 .llvm_name = "bonaire",
790791 .features = featureSet(&[_]Feature{
......@@ -794,7 +795,7 @@ pub const cpu = struct {
794795 .sea_islands,
795796 }),
796797 };
797 pub const carrizo = Cpu{
798 pub const carrizo = CpuModel{
798799 .name = "carrizo",
799800 .llvm_name = "carrizo",
800801 .features = featureSet(&[_]Feature{
......@@ -807,7 +808,7 @@ pub const cpu = struct {
807808 .xnack,
808809 }),
809810 };
810 pub const fiji = Cpu{
811 pub const fiji = CpuModel{
811812 .name = "fiji",
812813 .llvm_name = "fiji",
813814 .features = featureSet(&[_]Feature{
......@@ -818,14 +819,14 @@ pub const cpu = struct {
818819 .volcanic_islands,
819820 }),
820821 };
821 pub const generic = Cpu{
822 pub const generic = CpuModel{
822823 .name = "generic",
823824 .llvm_name = "generic",
824825 .features = featureSet(&[_]Feature{
825826 .wavefrontsize64,
826827 }),
827828 };
828 pub const generic_hsa = Cpu{
829 pub const generic_hsa = CpuModel{
829830 .name = "generic_hsa",
830831 .llvm_name = "generic-hsa",
831832 .features = featureSet(&[_]Feature{
......@@ -833,7 +834,7 @@ pub const cpu = struct {
833834 .wavefrontsize64,
834835 }),
835836 };
836 pub const gfx1010 = Cpu{
837 pub const gfx1010 = CpuModel{
837838 .name = "gfx1010",
838839 .llvm_name = "gfx1010",
839840 .features = featureSet(&[_]Feature{
......@@ -859,7 +860,7 @@ pub const cpu = struct {
859860 .wavefrontsize32,
860861 }),
861862 };
862 pub const gfx1011 = Cpu{
863 pub const gfx1011 = CpuModel{
863864 .name = "gfx1011",
864865 .llvm_name = "gfx1011",
865866 .features = featureSet(&[_]Feature{
......@@ -888,7 +889,7 @@ pub const cpu = struct {
888889 .wavefrontsize32,
889890 }),
890891 };
891 pub const gfx1012 = Cpu{
892 pub const gfx1012 = CpuModel{
892893 .name = "gfx1012",
893894 .llvm_name = "gfx1012",
894895 .features = featureSet(&[_]Feature{
......@@ -918,7 +919,7 @@ pub const cpu = struct {
918919 .wavefrontsize32,
919920 }),
920921 };
921 pub const gfx600 = Cpu{
922 pub const gfx600 = CpuModel{
922923 .name = "gfx600",
923924 .llvm_name = "gfx600",
924925 .features = featureSet(&[_]Feature{
......@@ -930,7 +931,7 @@ pub const cpu = struct {
930931 .southern_islands,
931932 }),
932933 };
933 pub const gfx601 = Cpu{
934 pub const gfx601 = CpuModel{
934935 .name = "gfx601",
935936 .llvm_name = "gfx601",
936937 .features = featureSet(&[_]Feature{
......@@ -940,7 +941,7 @@ pub const cpu = struct {
940941 .southern_islands,
941942 }),
942943 };
943 pub const gfx700 = Cpu{
944 pub const gfx700 = CpuModel{
944945 .name = "gfx700",
945946 .llvm_name = "gfx700",
946947 .features = featureSet(&[_]Feature{
......@@ -950,7 +951,7 @@ pub const cpu = struct {
950951 .sea_islands,
951952 }),
952953 };
953 pub const gfx701 = Cpu{
954 pub const gfx701 = CpuModel{
954955 .name = "gfx701",
955956 .llvm_name = "gfx701",
956957 .features = featureSet(&[_]Feature{
......@@ -962,7 +963,7 @@ pub const cpu = struct {
962963 .sea_islands,
963964 }),
964965 };
965 pub const gfx702 = Cpu{
966 pub const gfx702 = CpuModel{
966967 .name = "gfx702",
967968 .llvm_name = "gfx702",
968969 .features = featureSet(&[_]Feature{
......@@ -973,7 +974,7 @@ pub const cpu = struct {
973974 .sea_islands,
974975 }),
975976 };
976 pub const gfx703 = Cpu{
977 pub const gfx703 = CpuModel{
977978 .name = "gfx703",
978979 .llvm_name = "gfx703",
979980 .features = featureSet(&[_]Feature{
......@@ -983,7 +984,7 @@ pub const cpu = struct {
983984 .sea_islands,
984985 }),
985986 };
986 pub const gfx704 = Cpu{
987 pub const gfx704 = CpuModel{
987988 .name = "gfx704",
988989 .llvm_name = "gfx704",
989990 .features = featureSet(&[_]Feature{
......@@ -993,7 +994,7 @@ pub const cpu = struct {
993994 .sea_islands,
994995 }),
995996 };
996 pub const gfx801 = Cpu{
997 pub const gfx801 = CpuModel{
997998 .name = "gfx801",
998999 .llvm_name = "gfx801",
9991000 .features = featureSet(&[_]Feature{
......@@ -1006,7 +1007,7 @@ pub const cpu = struct {
10061007 .xnack,
10071008 }),
10081009 };
1009 pub const gfx802 = Cpu{
1010 pub const gfx802 = CpuModel{
10101011 .name = "gfx802",
10111012 .llvm_name = "gfx802",
10121013 .features = featureSet(&[_]Feature{
......@@ -1018,7 +1019,7 @@ pub const cpu = struct {
10181019 .volcanic_islands,
10191020 }),
10201021 };
1021 pub const gfx803 = Cpu{
1022 pub const gfx803 = CpuModel{
10221023 .name = "gfx803",
10231024 .llvm_name = "gfx803",
10241025 .features = featureSet(&[_]Feature{
......@@ -1029,7 +1030,7 @@ pub const cpu = struct {
10291030 .volcanic_islands,
10301031 }),
10311032 };
1032 pub const gfx810 = Cpu{
1033 pub const gfx810 = CpuModel{
10331034 .name = "gfx810",
10341035 .llvm_name = "gfx810",
10351036 .features = featureSet(&[_]Feature{
......@@ -1039,7 +1040,7 @@ pub const cpu = struct {
10391040 .xnack,
10401041 }),
10411042 };
1042 pub const gfx900 = Cpu{
1043 pub const gfx900 = CpuModel{
10431044 .name = "gfx900",
10441045 .llvm_name = "gfx900",
10451046 .features = featureSet(&[_]Feature{
......@@ -1051,7 +1052,7 @@ pub const cpu = struct {
10511052 .no_xnack_support,
10521053 }),
10531054 };
1054 pub const gfx902 = Cpu{
1055 pub const gfx902 = CpuModel{
10551056 .name = "gfx902",
10561057 .llvm_name = "gfx902",
10571058 .features = featureSet(&[_]Feature{
......@@ -1063,7 +1064,7 @@ pub const cpu = struct {
10631064 .xnack,
10641065 }),
10651066 };
1066 pub const gfx904 = Cpu{
1067 pub const gfx904 = CpuModel{
10671068 .name = "gfx904",
10681069 .llvm_name = "gfx904",
10691070 .features = featureSet(&[_]Feature{
......@@ -1075,7 +1076,7 @@ pub const cpu = struct {
10751076 .no_xnack_support,
10761077 }),
10771078 };
1078 pub const gfx906 = Cpu{
1079 pub const gfx906 = CpuModel{
10791080 .name = "gfx906",
10801081 .llvm_name = "gfx906",
10811082 .features = featureSet(&[_]Feature{
......@@ -1090,7 +1091,7 @@ pub const cpu = struct {
10901091 .no_xnack_support,
10911092 }),
10921093 };
1093 pub const gfx908 = Cpu{
1094 pub const gfx908 = CpuModel{
10941095 .name = "gfx908",
10951096 .llvm_name = "gfx908",
10961097 .features = featureSet(&[_]Feature{
......@@ -1113,7 +1114,7 @@ pub const cpu = struct {
11131114 .sram_ecc,
11141115 }),
11151116 };
1116 pub const gfx909 = Cpu{
1117 pub const gfx909 = CpuModel{
11171118 .name = "gfx909",
11181119 .llvm_name = "gfx909",
11191120 .features = featureSet(&[_]Feature{
......@@ -1124,7 +1125,7 @@ pub const cpu = struct {
11241125 .xnack,
11251126 }),
11261127 };
1127 pub const hainan = Cpu{
1128 pub const hainan = CpuModel{
11281129 .name = "hainan",
11291130 .llvm_name = "hainan",
11301131 .features = featureSet(&[_]Feature{
......@@ -1134,7 +1135,7 @@ pub const cpu = struct {
11341135 .southern_islands,
11351136 }),
11361137 };
1137 pub const hawaii = Cpu{
1138 pub const hawaii = CpuModel{
11381139 .name = "hawaii",
11391140 .llvm_name = "hawaii",
11401141 .features = featureSet(&[_]Feature{
......@@ -1146,7 +1147,7 @@ pub const cpu = struct {
11461147 .sea_islands,
11471148 }),
11481149 };
1149 pub const iceland = Cpu{
1150 pub const iceland = CpuModel{
11501151 .name = "iceland",
11511152 .llvm_name = "iceland",
11521153 .features = featureSet(&[_]Feature{
......@@ -1158,7 +1159,7 @@ pub const cpu = struct {
11581159 .volcanic_islands,
11591160 }),
11601161 };
1161 pub const kabini = Cpu{
1162 pub const kabini = CpuModel{
11621163 .name = "kabini",
11631164 .llvm_name = "kabini",
11641165 .features = featureSet(&[_]Feature{
......@@ -1168,7 +1169,7 @@ pub const cpu = struct {
11681169 .sea_islands,
11691170 }),
11701171 };
1171 pub const kaveri = Cpu{
1172 pub const kaveri = CpuModel{
11721173 .name = "kaveri",
11731174 .llvm_name = "kaveri",
11741175 .features = featureSet(&[_]Feature{
......@@ -1178,7 +1179,7 @@ pub const cpu = struct {
11781179 .sea_islands,
11791180 }),
11801181 };
1181 pub const mullins = Cpu{
1182 pub const mullins = CpuModel{
11821183 .name = "mullins",
11831184 .llvm_name = "mullins",
11841185 .features = featureSet(&[_]Feature{
......@@ -1188,7 +1189,7 @@ pub const cpu = struct {
11881189 .sea_islands,
11891190 }),
11901191 };
1191 pub const oland = Cpu{
1192 pub const oland = CpuModel{
11921193 .name = "oland",
11931194 .llvm_name = "oland",
11941195 .features = featureSet(&[_]Feature{
......@@ -1198,7 +1199,7 @@ pub const cpu = struct {
11981199 .southern_islands,
11991200 }),
12001201 };
1201 pub const pitcairn = Cpu{
1202 pub const pitcairn = CpuModel{
12021203 .name = "pitcairn",
12031204 .llvm_name = "pitcairn",
12041205 .features = featureSet(&[_]Feature{
......@@ -1208,7 +1209,7 @@ pub const cpu = struct {
12081209 .southern_islands,
12091210 }),
12101211 };
1211 pub const polaris10 = Cpu{
1212 pub const polaris10 = CpuModel{
12121213 .name = "polaris10",
12131214 .llvm_name = "polaris10",
12141215 .features = featureSet(&[_]Feature{
......@@ -1219,7 +1220,7 @@ pub const cpu = struct {
12191220 .volcanic_islands,
12201221 }),
12211222 };
1222 pub const polaris11 = Cpu{
1223 pub const polaris11 = CpuModel{
12231224 .name = "polaris11",
12241225 .llvm_name = "polaris11",
12251226 .features = featureSet(&[_]Feature{
......@@ -1230,7 +1231,7 @@ pub const cpu = struct {
12301231 .volcanic_islands,
12311232 }),
12321233 };
1233 pub const stoney = Cpu{
1234 pub const stoney = CpuModel{
12341235 .name = "stoney",
12351236 .llvm_name = "stoney",
12361237 .features = featureSet(&[_]Feature{
......@@ -1240,7 +1241,7 @@ pub const cpu = struct {
12401241 .xnack,
12411242 }),
12421243 };
1243 pub const tahiti = Cpu{
1244 pub const tahiti = CpuModel{
12441245 .name = "tahiti",
12451246 .llvm_name = "tahiti",
12461247 .features = featureSet(&[_]Feature{
......@@ -1252,7 +1253,7 @@ pub const cpu = struct {
12521253 .southern_islands,
12531254 }),
12541255 };
1255 pub const tonga = Cpu{
1256 pub const tonga = CpuModel{
12561257 .name = "tonga",
12571258 .llvm_name = "tonga",
12581259 .features = featureSet(&[_]Feature{
......@@ -1264,7 +1265,7 @@ pub const cpu = struct {
12641265 .volcanic_islands,
12651266 }),
12661267 };
1267 pub const verde = Cpu{
1268 pub const verde = CpuModel{
12681269 .name = "verde",
12691270 .llvm_name = "verde",
12701271 .features = featureSet(&[_]Feature{
......@@ -1279,7 +1280,7 @@ pub const cpu = struct {
12791280/// All amdgpu CPUs, sorted alphabetically by name.
12801281/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
12811282/// compiler has inefficient memory and CPU usage, affecting build times.
1282pub const all_cpus = &[_]*const Cpu{
1283pub const all_cpus = &[_]*const CpuModel{
12831284 &cpu.bonaire,
12841285 &cpu.carrizo,
12851286 &cpu.fiji,
lib/std/target/arm.zig+698-829
......@@ -1,61 +1,14 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 @"32bit",
67 @"8msecext",
7 a12,
8 a15,
9 a17,
10 a32,
11 a35,
12 a5,
13 a53,
14 a55,
15 a57,
16 a7,
17 a72,
18 a73,
19 a75,
208 a76,
21 a8,
22 a9,
239 aclass,
2410 acquire_release,
2511 aes,
26 armv2,
27 armv2a,
28 armv3,
29 armv3m,
30 armv4,
31 armv4t,
32 armv5t,
33 armv5te,
34 armv5tej,
35 armv6,
36 armv6_m,
37 armv6j,
38 armv6k,
39 armv6kz,
40 armv6s_m,
41 armv6t2,
42 armv7_a,
43 armv7_m,
44 armv7_r,
45 armv7e_m,
46 armv7k,
47 armv7s,
48 armv7ve,
49 armv8_a,
50 armv8_m_base,
51 armv8_m_main,
52 armv8_r,
53 armv8_1_a,
54 armv8_1_m_main,
55 armv8_2_a,
56 armv8_3_a,
57 armv8_4_a,
58 armv8_5_a,
5912 avoid_movs_shop,
6013 avoid_partial_cpsr,
6114 cheap_predicable_cpsr,
......@@ -71,13 +24,13 @@ pub const Feature = enum {
7124 execute_only,
7225 expand_fp_mlx,
7326 exynos,
27 fp16,
28 fp16fml,
29 fp64,
7430 fp_armv8,
7531 fp_armv8d16,
7632 fp_armv8d16sp,
7733 fp_armv8sp,
78 fp16,
79 fp16fml,
80 fp64,
8134 fpao,
8235 fpregs,
8336 fpregs16,
......@@ -85,12 +38,28 @@ pub const Feature = enum {
8538 fullfp16,
8639 fuse_aes,
8740 fuse_literals,
41 has_v4t,
42 has_v5t,
43 has_v5te,
44 has_v6,
45 has_v6k,
46 has_v6m,
47 has_v6t2,
48 has_v7,
49 has_v7clrex,
50 has_v8_1a,
51 has_v8_1m_main,
52 has_v8_2a,
53 has_v8_3a,
54 has_v8_4a,
55 has_v8_5a,
56 has_v8,
57 has_v8m,
58 has_v8m_main,
8859 hwdiv,
8960 hwdiv_arm,
9061 iwmmxt,
9162 iwmmxt2,
92 krait,
93 kryo,
9463 lob,
9564 long_calls,
9665 loop_align,
......@@ -117,9 +86,6 @@ pub const Feature = enum {
11786 prefer_vmovsr,
11887 prof_unpr,
11988 r4,
120 r5,
121 r52,
122 r7,
12389 ras,
12490 rclass,
12591 read_tp_hard,
......@@ -138,28 +104,43 @@ pub const Feature = enum {
138104 splat_vfp_neon,
139105 strict_align,
140106 swift,
141 thumb_mode,
142107 thumb2,
108 thumb_mode,
143109 trustzone,
144110 use_misched,
111 v2,
112 v2a,
113 v3,
114 v3m,
115 v4,
145116 v4t,
146117 v5t,
147118 v5te,
119 v5tej,
148120 v6,
121 v6j,
149122 v6k,
123 v6kz,
150124 v6m,
125 v6sm,
151126 v6t2,
152 v7,
153 v7clrex,
154 v8,
127 v7a,
128 v7em,
129 v7k,
130 v7m,
131 v7r,
132 v7s,
133 v7ve,
134 v8a,
135 v8m,
136 v8m_main,
137 v8r,
155138 v8_1a,
156139 v8_1m_main,
157140 v8_2a,
158141 v8_3a,
159142 v8_4a,
160143 v8_5a,
161 v8m,
162 v8m_main,
163144 vfp2,
164145 vfp2sp,
165146 vfp3,
......@@ -179,13 +160,13 @@ pub const Feature = enum {
179160 zcz,
180161};
181162
182pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
163pub usingnamespace CpuFeature.feature_set_fns(Feature);
183164
184165pub const all_features = blk: {
185166 @setEvalBranchQuota(10000);
186167 const len = @typeInfo(Feature).Enum.fields.len;
187 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
188 var result: [len]Cpu.Feature = undefined;
168 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
169 var result: [len]CpuFeature = undefined;
189170 result[@enumToInt(Feature.@"32bit")] = .{
190171 .llvm_name = "32bit",
191172 .description = "Prefer 32-bit Thumb instrs",
......@@ -196,86 +177,11 @@ pub const all_features = blk: {
196177 .description = "Enable support for ARMv8-M Security Extensions",
197178 .dependencies = featureSet(&[_]Feature{}),
198179 };
199 result[@enumToInt(Feature.a12)] = .{
200 .llvm_name = "a12",
201 .description = "Cortex-A12 ARM processors",
202 .dependencies = featureSet(&[_]Feature{}),
203 };
204 result[@enumToInt(Feature.a15)] = .{
205 .llvm_name = "a15",
206 .description = "Cortex-A15 ARM processors",
207 .dependencies = featureSet(&[_]Feature{}),
208 };
209 result[@enumToInt(Feature.a17)] = .{
210 .llvm_name = "a17",
211 .description = "Cortex-A17 ARM processors",
212 .dependencies = featureSet(&[_]Feature{}),
213 };
214 result[@enumToInt(Feature.a32)] = .{
215 .llvm_name = "a32",
216 .description = "Cortex-A32 ARM processors",
217 .dependencies = featureSet(&[_]Feature{}),
218 };
219 result[@enumToInt(Feature.a35)] = .{
220 .llvm_name = "a35",
221 .description = "Cortex-A35 ARM processors",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@enumToInt(Feature.a5)] = .{
225 .llvm_name = "a5",
226 .description = "Cortex-A5 ARM processors",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@enumToInt(Feature.a53)] = .{
230 .llvm_name = "a53",
231 .description = "Cortex-A53 ARM processors",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@enumToInt(Feature.a55)] = .{
235 .llvm_name = "a55",
236 .description = "Cortex-A55 ARM processors",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@enumToInt(Feature.a57)] = .{
240 .llvm_name = "a57",
241 .description = "Cortex-A57 ARM processors",
242 .dependencies = featureSet(&[_]Feature{}),
243 };
244 result[@enumToInt(Feature.a7)] = .{
245 .llvm_name = "a7",
246 .description = "Cortex-A7 ARM processors",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@enumToInt(Feature.a72)] = .{
250 .llvm_name = "a72",
251 .description = "Cortex-A72 ARM processors",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@enumToInt(Feature.a73)] = .{
255 .llvm_name = "a73",
256 .description = "Cortex-A73 ARM processors",
257 .dependencies = featureSet(&[_]Feature{}),
258 };
259 result[@enumToInt(Feature.a75)] = .{
260 .llvm_name = "a75",
261 .description = "Cortex-A75 ARM processors",
262 .dependencies = featureSet(&[_]Feature{}),
263 };
264180 result[@enumToInt(Feature.a76)] = .{
265181 .llvm_name = "a76",
266182 .description = "Cortex-A76 ARM processors",
267183 .dependencies = featureSet(&[_]Feature{}),
268184 };
269 result[@enumToInt(Feature.a8)] = .{
270 .llvm_name = "a8",
271 .description = "Cortex-A8 ARM processors",
272 .dependencies = featureSet(&[_]Feature{}),
273 };
274 result[@enumToInt(Feature.a9)] = .{
275 .llvm_name = "a9",
276 .description = "Cortex-A9 ARM processors",
277 .dependencies = featureSet(&[_]Feature{}),
278 };
279185 result[@enumToInt(Feature.aclass)] = .{
280186 .llvm_name = "aclass",
281187 .description = "Is application profile ('A' series)",
......@@ -293,368 +199,6 @@ pub const all_features = blk: {
293199 .neon,
294200 }),
295201 };
296 result[@enumToInt(Feature.armv2)] = .{
297 .llvm_name = "armv2",
298 .description = "ARMv2 architecture",
299 .dependencies = featureSet(&[_]Feature{}),
300 };
301 result[@enumToInt(Feature.armv2a)] = .{
302 .llvm_name = "armv2a",
303 .description = "ARMv2a architecture",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@enumToInt(Feature.armv3)] = .{
307 .llvm_name = "armv3",
308 .description = "ARMv3 architecture",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@enumToInt(Feature.armv3m)] = .{
312 .llvm_name = "armv3m",
313 .description = "ARMv3m architecture",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@enumToInt(Feature.armv4)] = .{
317 .llvm_name = "armv4",
318 .description = "ARMv4 architecture",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@enumToInt(Feature.armv4t)] = .{
322 .llvm_name = "armv4t",
323 .description = "ARMv4t architecture",
324 .dependencies = featureSet(&[_]Feature{
325 .v4t,
326 }),
327 };
328 result[@enumToInt(Feature.armv5t)] = .{
329 .llvm_name = "armv5t",
330 .description = "ARMv5t architecture",
331 .dependencies = featureSet(&[_]Feature{
332 .v5t,
333 }),
334 };
335 result[@enumToInt(Feature.armv5te)] = .{
336 .llvm_name = "armv5te",
337 .description = "ARMv5te architecture",
338 .dependencies = featureSet(&[_]Feature{
339 .v5te,
340 }),
341 };
342 result[@enumToInt(Feature.armv5tej)] = .{
343 .llvm_name = "armv5tej",
344 .description = "ARMv5tej architecture",
345 .dependencies = featureSet(&[_]Feature{
346 .v5te,
347 }),
348 };
349 result[@enumToInt(Feature.armv6)] = .{
350 .llvm_name = "armv6",
351 .description = "ARMv6 architecture",
352 .dependencies = featureSet(&[_]Feature{
353 .dsp,
354 .v6,
355 }),
356 };
357 result[@enumToInt(Feature.armv6_m)] = .{
358 .llvm_name = "armv6-m",
359 .description = "ARMv6m architecture",
360 .dependencies = featureSet(&[_]Feature{
361 .db,
362 .mclass,
363 .noarm,
364 .strict_align,
365 .thumb_mode,
366 .v6m,
367 }),
368 };
369 result[@enumToInt(Feature.armv6j)] = .{
370 .llvm_name = "armv6j",
371 .description = "ARMv7a architecture",
372 .dependencies = featureSet(&[_]Feature{
373 .armv6,
374 }),
375 };
376 result[@enumToInt(Feature.armv6k)] = .{
377 .llvm_name = "armv6k",
378 .description = "ARMv6k architecture",
379 .dependencies = featureSet(&[_]Feature{
380 .v6k,
381 }),
382 };
383 result[@enumToInt(Feature.armv6kz)] = .{
384 .llvm_name = "armv6kz",
385 .description = "ARMv6kz architecture",
386 .dependencies = featureSet(&[_]Feature{
387 .trustzone,
388 .v6k,
389 }),
390 };
391 result[@enumToInt(Feature.armv6s_m)] = .{
392 .llvm_name = "armv6s-m",
393 .description = "ARMv6sm architecture",
394 .dependencies = featureSet(&[_]Feature{
395 .db,
396 .mclass,
397 .noarm,
398 .strict_align,
399 .thumb_mode,
400 .v6m,
401 }),
402 };
403 result[@enumToInt(Feature.armv6t2)] = .{
404 .llvm_name = "armv6t2",
405 .description = "ARMv6t2 architecture",
406 .dependencies = featureSet(&[_]Feature{
407 .dsp,
408 .v6t2,
409 }),
410 };
411 result[@enumToInt(Feature.armv7_a)] = .{
412 .llvm_name = "armv7-a",
413 .description = "ARMv7a architecture",
414 .dependencies = featureSet(&[_]Feature{
415 .aclass,
416 .db,
417 .dsp,
418 .neon,
419 .v7,
420 }),
421 };
422 result[@enumToInt(Feature.armv7_m)] = .{
423 .llvm_name = "armv7-m",
424 .description = "ARMv7m architecture",
425 .dependencies = featureSet(&[_]Feature{
426 .db,
427 .hwdiv,
428 .mclass,
429 .noarm,
430 .thumb_mode,
431 .thumb2,
432 .v7,
433 }),
434 };
435 result[@enumToInt(Feature.armv7_r)] = .{
436 .llvm_name = "armv7-r",
437 .description = "ARMv7r architecture",
438 .dependencies = featureSet(&[_]Feature{
439 .db,
440 .dsp,
441 .hwdiv,
442 .rclass,
443 .v7,
444 }),
445 };
446 result[@enumToInt(Feature.armv7e_m)] = .{
447 .llvm_name = "armv7e-m",
448 .description = "ARMv7em architecture",
449 .dependencies = featureSet(&[_]Feature{
450 .db,
451 .dsp,
452 .hwdiv,
453 .mclass,
454 .noarm,
455 .thumb_mode,
456 .thumb2,
457 .v7,
458 }),
459 };
460 result[@enumToInt(Feature.armv7k)] = .{
461 .llvm_name = "armv7k",
462 .description = "ARMv7a architecture",
463 .dependencies = featureSet(&[_]Feature{
464 .armv7_a,
465 }),
466 };
467 result[@enumToInt(Feature.armv7s)] = .{
468 .llvm_name = "armv7s",
469 .description = "ARMv7a architecture",
470 .dependencies = featureSet(&[_]Feature{
471 .armv7_a,
472 }),
473 };
474 result[@enumToInt(Feature.armv7ve)] = .{
475 .llvm_name = "armv7ve",
476 .description = "ARMv7ve architecture",
477 .dependencies = featureSet(&[_]Feature{
478 .aclass,
479 .db,
480 .dsp,
481 .mp,
482 .neon,
483 .trustzone,
484 .v7,
485 .virtualization,
486 }),
487 };
488 result[@enumToInt(Feature.armv8_a)] = .{
489 .llvm_name = "armv8-a",
490 .description = "ARMv8a architecture",
491 .dependencies = featureSet(&[_]Feature{
492 .aclass,
493 .crc,
494 .crypto,
495 .db,
496 .dsp,
497 .fp_armv8,
498 .mp,
499 .neon,
500 .trustzone,
501 .v8,
502 .virtualization,
503 }),
504 };
505 result[@enumToInt(Feature.armv8_m_base)] = .{
506 .llvm_name = "armv8-m.base",
507 .description = "ARMv8mBaseline architecture",
508 .dependencies = featureSet(&[_]Feature{
509 .@"8msecext",
510 .acquire_release,
511 .db,
512 .hwdiv,
513 .mclass,
514 .noarm,
515 .strict_align,
516 .thumb_mode,
517 .v7clrex,
518 .v8m,
519 }),
520 };
521 result[@enumToInt(Feature.armv8_m_main)] = .{
522 .llvm_name = "armv8-m.main",
523 .description = "ARMv8mMainline architecture",
524 .dependencies = featureSet(&[_]Feature{
525 .@"8msecext",
526 .acquire_release,
527 .db,
528 .hwdiv,
529 .mclass,
530 .noarm,
531 .thumb_mode,
532 .v8m_main,
533 }),
534 };
535 result[@enumToInt(Feature.armv8_r)] = .{
536 .llvm_name = "armv8-r",
537 .description = "ARMv8r architecture",
538 .dependencies = featureSet(&[_]Feature{
539 .crc,
540 .db,
541 .dfb,
542 .dsp,
543 .fp_armv8,
544 .mp,
545 .neon,
546 .rclass,
547 .v8,
548 .virtualization,
549 }),
550 };
551 result[@enumToInt(Feature.armv8_1_a)] = .{
552 .llvm_name = "armv8.1-a",
553 .description = "ARMv81a architecture",
554 .dependencies = featureSet(&[_]Feature{
555 .aclass,
556 .crc,
557 .crypto,
558 .db,
559 .dsp,
560 .fp_armv8,
561 .mp,
562 .neon,
563 .trustzone,
564 .v8_1a,
565 .virtualization,
566 }),
567 };
568 result[@enumToInt(Feature.armv8_1_m_main)] = .{
569 .llvm_name = "armv8.1-m.main",
570 .description = "ARMv81mMainline architecture",
571 .dependencies = featureSet(&[_]Feature{
572 .@"8msecext",
573 .acquire_release,
574 .db,
575 .hwdiv,
576 .lob,
577 .mclass,
578 .noarm,
579 .ras,
580 .thumb_mode,
581 .v8_1m_main,
582 }),
583 };
584 result[@enumToInt(Feature.armv8_2_a)] = .{
585 .llvm_name = "armv8.2-a",
586 .description = "ARMv82a architecture",
587 .dependencies = featureSet(&[_]Feature{
588 .aclass,
589 .crc,
590 .crypto,
591 .db,
592 .dsp,
593 .fp_armv8,
594 .mp,
595 .neon,
596 .ras,
597 .trustzone,
598 .v8_2a,
599 .virtualization,
600 }),
601 };
602 result[@enumToInt(Feature.armv8_3_a)] = .{
603 .llvm_name = "armv8.3-a",
604 .description = "ARMv83a architecture",
605 .dependencies = featureSet(&[_]Feature{
606 .aclass,
607 .crc,
608 .crypto,
609 .db,
610 .dsp,
611 .fp_armv8,
612 .mp,
613 .neon,
614 .ras,
615 .trustzone,
616 .v8_3a,
617 .virtualization,
618 }),
619 };
620 result[@enumToInt(Feature.armv8_4_a)] = .{
621 .llvm_name = "armv8.4-a",
622 .description = "ARMv84a architecture",
623 .dependencies = featureSet(&[_]Feature{
624 .aclass,
625 .crc,
626 .crypto,
627 .db,
628 .dotprod,
629 .dsp,
630 .fp_armv8,
631 .mp,
632 .neon,
633 .ras,
634 .trustzone,
635 .v8_4a,
636 .virtualization,
637 }),
638 };
639 result[@enumToInt(Feature.armv8_5_a)] = .{
640 .llvm_name = "armv8.5-a",
641 .description = "ARMv85a architecture",
642 .dependencies = featureSet(&[_]Feature{
643 .aclass,
644 .crc,
645 .crypto,
646 .db,
647 .dotprod,
648 .dsp,
649 .fp_armv8,
650 .mp,
651 .neon,
652 .ras,
653 .trustzone,
654 .v8_5a,
655 .virtualization,
656 }),
657 };
658202 result[@enumToInt(Feature.avoid_movs_shop)] = .{
659203 .llvm_name = "avoid-movs-shop",
660204 .description = "Avoid movs instructions with shifter operand",
......@@ -754,6 +298,25 @@ pub const all_features = blk: {
754298 .zcz,
755299 }),
756300 };
301 result[@enumToInt(Feature.fp16)] = .{
302 .llvm_name = "fp16",
303 .description = "Enable half-precision floating point",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@enumToInt(Feature.fp16fml)] = .{
307 .llvm_name = "fp16fml",
308 .description = "Enable full half-precision floating point fml instructions",
309 .dependencies = featureSet(&[_]Feature{
310 .fullfp16,
311 }),
312 };
313 result[@enumToInt(Feature.fp64)] = .{
314 .llvm_name = "fp64",
315 .description = "Floating point unit supports double precision",
316 .dependencies = featureSet(&[_]Feature{
317 .fpregs64,
318 }),
319 };
757320 result[@enumToInt(Feature.fp_armv8)] = .{
758321 .llvm_name = "fp-armv8",
759322 .description = "Enable ARMv8 FP",
......@@ -772,39 +335,20 @@ pub const all_features = blk: {
772335 .vfp4d16,
773336 }),
774337 };
775 result[@enumToInt(Feature.fp_armv8d16sp)] = .{
776 .llvm_name = "fp-armv8d16sp",
777 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",
778 .dependencies = featureSet(&[_]Feature{
779 .vfp4d16sp,
780 }),
781 };
782 result[@enumToInt(Feature.fp_armv8sp)] = .{
783 .llvm_name = "fp-armv8sp",
784 .description = "Enable ARMv8 FP with no double precision",
785 .dependencies = featureSet(&[_]Feature{
786 .d32,
787 .fp_armv8d16sp,
788 .vfp4sp,
789 }),
790 };
791 result[@enumToInt(Feature.fp16)] = .{
792 .llvm_name = "fp16",
793 .description = "Enable half-precision floating point",
794 .dependencies = featureSet(&[_]Feature{}),
795 };
796 result[@enumToInt(Feature.fp16fml)] = .{
797 .llvm_name = "fp16fml",
798 .description = "Enable full half-precision floating point fml instructions",
338 result[@enumToInt(Feature.fp_armv8d16sp)] = .{
339 .llvm_name = "fp-armv8d16sp",
340 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",
799341 .dependencies = featureSet(&[_]Feature{
800 .fullfp16,
342 .vfp4d16sp,
801343 }),
802344 };
803 result[@enumToInt(Feature.fp64)] = .{
804 .llvm_name = "fp64",
805 .description = "Floating point unit supports double precision",
345 result[@enumToInt(Feature.fp_armv8sp)] = .{
346 .llvm_name = "fp-armv8sp",
347 .description = "Enable ARMv8 FP with no double precision",
806348 .dependencies = featureSet(&[_]Feature{
807 .fpregs64,
349 .d32,
350 .fp_armv8d16sp,
351 .vfp4sp,
808352 }),
809353 };
810354 result[@enumToInt(Feature.fpao)] = .{
......@@ -849,6 +393,135 @@ pub const all_features = blk: {
849393 .description = "CPU fuses literal generation operations",
850394 .dependencies = featureSet(&[_]Feature{}),
851395 };
396 result[@enumToInt(Feature.has_v4t)] = .{
397 .llvm_name = "v4t",
398 .description = "Support ARM v4T instructions",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@enumToInt(Feature.has_v5t)] = .{
402 .llvm_name = "v5t",
403 .description = "Support ARM v5T instructions",
404 .dependencies = featureSet(&[_]Feature{
405 .has_v4t,
406 }),
407 };
408 result[@enumToInt(Feature.has_v5te)] = .{
409 .llvm_name = "v5te",
410 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",
411 .dependencies = featureSet(&[_]Feature{
412 .has_v5t,
413 }),
414 };
415 result[@enumToInt(Feature.has_v6)] = .{
416 .llvm_name = "v6",
417 .description = "Support ARM v6 instructions",
418 .dependencies = featureSet(&[_]Feature{
419 .has_v5te,
420 }),
421 };
422 result[@enumToInt(Feature.has_v6k)] = .{
423 .llvm_name = "v6k",
424 .description = "Support ARM v6k instructions",
425 .dependencies = featureSet(&[_]Feature{
426 .has_v6,
427 }),
428 };
429 result[@enumToInt(Feature.has_v6m)] = .{
430 .llvm_name = "v6m",
431 .description = "Support ARM v6M instructions",
432 .dependencies = featureSet(&[_]Feature{
433 .has_v6,
434 }),
435 };
436 result[@enumToInt(Feature.has_v6t2)] = .{
437 .llvm_name = "v6t2",
438 .description = "Support ARM v6t2 instructions",
439 .dependencies = featureSet(&[_]Feature{
440 .thumb2,
441 .has_v6k,
442 .has_v8m,
443 }),
444 };
445 result[@enumToInt(Feature.has_v7)] = .{
446 .llvm_name = "v7",
447 .description = "Support ARM v7 instructions",
448 .dependencies = featureSet(&[_]Feature{
449 .perfmon,
450 .has_v6t2,
451 .has_v7clrex,
452 }),
453 };
454 result[@enumToInt(Feature.has_v7clrex)] = .{
455 .llvm_name = "v7clrex",
456 .description = "Has v7 clrex instruction",
457 .dependencies = featureSet(&[_]Feature{}),
458 };
459 result[@enumToInt(Feature.has_v8)] = .{
460 .llvm_name = "v8",
461 .description = "Support ARM v8 instructions",
462 .dependencies = featureSet(&[_]Feature{
463 .acquire_release,
464 .has_v7,
465 }),
466 };
467 result[@enumToInt(Feature.has_v8_1a)] = .{
468 .llvm_name = "v8.1a",
469 .description = "Support ARM v8.1a instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .has_v8,
472 }),
473 };
474 result[@enumToInt(Feature.has_v8_1m_main)] = .{
475 .llvm_name = "v8.1m.main",
476 .description = "Support ARM v8-1M Mainline instructions",
477 .dependencies = featureSet(&[_]Feature{
478 .has_v8m_main,
479 }),
480 };
481 result[@enumToInt(Feature.has_v8_2a)] = .{
482 .llvm_name = "v8.2a",
483 .description = "Support ARM v8.2a instructions",
484 .dependencies = featureSet(&[_]Feature{
485 .has_v8_1a,
486 }),
487 };
488 result[@enumToInt(Feature.has_v8_3a)] = .{
489 .llvm_name = "v8.3a",
490 .description = "Support ARM v8.3a instructions",
491 .dependencies = featureSet(&[_]Feature{
492 .has_v8_2a,
493 }),
494 };
495 result[@enumToInt(Feature.has_v8_4a)] = .{
496 .llvm_name = "v8.4a",
497 .description = "Support ARM v8.4a instructions",
498 .dependencies = featureSet(&[_]Feature{
499 .dotprod,
500 .has_v8_3a,
501 }),
502 };
503 result[@enumToInt(Feature.has_v8_5a)] = .{
504 .llvm_name = "v8.5a",
505 .description = "Support ARM v8.5a instructions",
506 .dependencies = featureSet(&[_]Feature{
507 .sb,
508 .has_v8_4a,
509 }),
510 };
511 result[@enumToInt(Feature.has_v8m)] = .{
512 .llvm_name = "v8m",
513 .description = "Support ARM v8M Baseline instructions",
514 .dependencies = featureSet(&[_]Feature{
515 .has_v6m,
516 }),
517 };
518 result[@enumToInt(Feature.has_v8m_main)] = .{
519 .llvm_name = "v8m.main",
520 .description = "Support ARM v8M Mainline instructions",
521 .dependencies = featureSet(&[_]Feature{
522 .has_v7,
523 }),
524 };
852525 result[@enumToInt(Feature.hwdiv)] = .{
853526 .llvm_name = "hwdiv",
854527 .description = "Enable divide instructions in Thumb",
......@@ -863,26 +536,16 @@ pub const all_features = blk: {
863536 .llvm_name = "iwmmxt",
864537 .description = "ARMv5te architecture",
865538 .dependencies = featureSet(&[_]Feature{
866 .armv5te,
539 .has_v5te,
867540 }),
868541 };
869542 result[@enumToInt(Feature.iwmmxt2)] = .{
870543 .llvm_name = "iwmmxt2",
871544 .description = "ARMv5te architecture",
872545 .dependencies = featureSet(&[_]Feature{
873 .armv5te,
546 .has_v5te,
874547 }),
875548 };
876 result[@enumToInt(Feature.krait)] = .{
877 .llvm_name = "krait",
878 .description = "Qualcomm Krait processors",
879 .dependencies = featureSet(&[_]Feature{}),
880 };
881 result[@enumToInt(Feature.kryo)] = .{
882 .llvm_name = "kryo",
883 .description = "Qualcomm Kryo processors",
884 .dependencies = featureSet(&[_]Feature{}),
885 };
886549 result[@enumToInt(Feature.lob)] = .{
887550 .llvm_name = "lob",
888551 .description = "Enable Low Overhead Branch extensions",
......@@ -925,7 +588,7 @@ pub const all_features = blk: {
925588 .dsp,
926589 .fpregs16,
927590 .fpregs64,
928 .v8_1m_main,
591 .has_v8_1m_main,
929592 }),
930593 };
931594 result[@enumToInt(Feature.mve_fp)] = .{
......@@ -1024,21 +687,6 @@ pub const all_features = blk: {
1024687 .description = "Cortex-R4 ARM processors",
1025688 .dependencies = featureSet(&[_]Feature{}),
1026689 };
1027 result[@enumToInt(Feature.r5)] = .{
1028 .llvm_name = "r5",
1029 .description = "Cortex-R5 ARM processors",
1030 .dependencies = featureSet(&[_]Feature{}),
1031 };
1032 result[@enumToInt(Feature.r52)] = .{
1033 .llvm_name = "r52",
1034 .description = "Cortex-R52 ARM processors",
1035 .dependencies = featureSet(&[_]Feature{}),
1036 };
1037 result[@enumToInt(Feature.r7)] = .{
1038 .llvm_name = "r7",
1039 .description = "Cortex-R7 ARM processors",
1040 .dependencies = featureSet(&[_]Feature{}),
1041 };
1042690 result[@enumToInt(Feature.ras)] = .{
1043691 .llvm_name = "ras",
1044692 .description = "Enable Reliability, Availability and Serviceability extensions",
......@@ -1133,16 +781,16 @@ pub const all_features = blk: {
1133781 .description = "Swift ARM processors",
1134782 .dependencies = featureSet(&[_]Feature{}),
1135783 };
1136 result[@enumToInt(Feature.thumb_mode)] = .{
1137 .llvm_name = "thumb-mode",
1138 .description = "Thumb mode",
1139 .dependencies = featureSet(&[_]Feature{}),
1140 };
1141784 result[@enumToInt(Feature.thumb2)] = .{
1142785 .llvm_name = "thumb2",
1143786 .description = "Enable Thumb2 instructions",
1144787 .dependencies = featureSet(&[_]Feature{}),
1145788 };
789 result[@enumToInt(Feature.thumb_mode)] = .{
790 .llvm_name = "thumb-mode",
791 .description = "Thumb mode",
792 .dependencies = featureSet(&[_]Feature{}),
793 };
1146794 result[@enumToInt(Feature.trustzone)] = .{
1147795 .llvm_name = "trustzone",
1148796 .description = "Enable support for TrustZone security extensions",
......@@ -1153,133 +801,366 @@ pub const all_features = blk: {
1153801 .description = "Use the MachineScheduler",
1154802 .dependencies = featureSet(&[_]Feature{}),
1155803 };
1156 result[@enumToInt(Feature.v4t)] = .{
1157 .llvm_name = "v4t",
1158 .description = "Support ARM v4T instructions",
804 result[@enumToInt(Feature.v2)] = .{
805 .llvm_name = "armv2",
806 .description = "ARMv2 architecture",
807 .dependencies = featureSet(&[_]Feature{}),
808 };
809 result[@enumToInt(Feature.v2a)] = .{
810 .llvm_name = "armv2a",
811 .description = "ARMv2a architecture",
812 .dependencies = featureSet(&[_]Feature{}),
813 };
814 result[@enumToInt(Feature.v3)] = .{
815 .llvm_name = "armv3",
816 .description = "ARMv3 architecture",
817 .dependencies = featureSet(&[_]Feature{}),
818 };
819 result[@enumToInt(Feature.v3m)] = .{
820 .llvm_name = "armv3m",
821 .description = "ARMv3m architecture",
822 .dependencies = featureSet(&[_]Feature{}),
823 };
824 result[@enumToInt(Feature.v4)] = .{
825 .llvm_name = "armv4",
826 .description = "ARMv4 architecture",
1159827 .dependencies = featureSet(&[_]Feature{}),
1160828 };
1161 result[@enumToInt(Feature.v5t)] = .{
1162 .llvm_name = "v5t",
1163 .description = "Support ARM v5T instructions",
829 result[@enumToInt(Feature.v4t)] = .{
830 .llvm_name = "armv4t",
831 .description = "ARMv4t architecture",
832 .dependencies = featureSet(&[_]Feature{
833 .has_v4t,
834 }),
835 };
836 result[@enumToInt(Feature.v5t)] = .{
837 .llvm_name = "armv5t",
838 .description = "ARMv5t architecture",
839 .dependencies = featureSet(&[_]Feature{
840 .has_v5t,
841 }),
842 };
843 result[@enumToInt(Feature.v5te)] = .{
844 .llvm_name = "armv5te",
845 .description = "ARMv5te architecture",
846 .dependencies = featureSet(&[_]Feature{
847 .has_v5te,
848 }),
849 };
850 result[@enumToInt(Feature.v5tej)] = .{
851 .llvm_name = "armv5tej",
852 .description = "ARMv5tej architecture",
853 .dependencies = featureSet(&[_]Feature{
854 .has_v5te,
855 }),
856 };
857 result[@enumToInt(Feature.v6)] = .{
858 .llvm_name = "armv6",
859 .description = "ARMv6 architecture",
860 .dependencies = featureSet(&[_]Feature{
861 .dsp,
862 .has_v6,
863 }),
864 };
865 result[@enumToInt(Feature.v6m)] = .{
866 .llvm_name = "armv6-m",
867 .description = "ARMv6m architecture",
868 .dependencies = featureSet(&[_]Feature{
869 .db,
870 .mclass,
871 .noarm,
872 .strict_align,
873 .thumb_mode,
874 .has_v6m,
875 }),
876 };
877 result[@enumToInt(Feature.v6j)] = .{
878 .llvm_name = "armv6j",
879 .description = "ARMv7a architecture",
880 .dependencies = featureSet(&[_]Feature{
881 .v6,
882 }),
883 };
884 result[@enumToInt(Feature.v6k)] = .{
885 .llvm_name = "armv6k",
886 .description = "ARMv6k architecture",
887 .dependencies = featureSet(&[_]Feature{
888 .has_v6k,
889 }),
890 };
891 result[@enumToInt(Feature.v6kz)] = .{
892 .llvm_name = "armv6kz",
893 .description = "ARMv6kz architecture",
894 .dependencies = featureSet(&[_]Feature{
895 .trustzone,
896 .has_v6k,
897 }),
898 };
899 result[@enumToInt(Feature.v6sm)] = .{
900 .llvm_name = "armv6s-m",
901 .description = "ARMv6sm architecture",
902 .dependencies = featureSet(&[_]Feature{
903 .db,
904 .mclass,
905 .noarm,
906 .strict_align,
907 .thumb_mode,
908 .has_v6m,
909 }),
910 };
911 result[@enumToInt(Feature.v6t2)] = .{
912 .llvm_name = "armv6t2",
913 .description = "ARMv6t2 architecture",
914 .dependencies = featureSet(&[_]Feature{
915 .dsp,
916 .has_v6t2,
917 }),
918 };
919 result[@enumToInt(Feature.v7a)] = .{
920 .llvm_name = "armv7-a",
921 .description = "ARMv7a architecture",
922 .dependencies = featureSet(&[_]Feature{
923 .aclass,
924 .db,
925 .dsp,
926 .neon,
927 .has_v7,
928 }),
929 };
930 result[@enumToInt(Feature.v7m)] = .{
931 .llvm_name = "armv7-m",
932 .description = "ARMv7m architecture",
933 .dependencies = featureSet(&[_]Feature{
934 .db,
935 .hwdiv,
936 .mclass,
937 .noarm,
938 .thumb_mode,
939 .thumb2,
940 .has_v7,
941 }),
942 };
943 result[@enumToInt(Feature.v7r)] = .{
944 .llvm_name = "armv7-r",
945 .description = "ARMv7r architecture",
946 .dependencies = featureSet(&[_]Feature{
947 .db,
948 .dsp,
949 .hwdiv,
950 .rclass,
951 .has_v7,
952 }),
953 };
954 result[@enumToInt(Feature.v7em)] = .{
955 .llvm_name = "armv7e-m",
956 .description = "ARMv7em architecture",
1164957 .dependencies = featureSet(&[_]Feature{
1165 .v4t,
958 .db,
959 .dsp,
960 .hwdiv,
961 .mclass,
962 .noarm,
963 .thumb_mode,
964 .thumb2,
965 .has_v7,
1166966 }),
1167967 };
1168 result[@enumToInt(Feature.v5te)] = .{
1169 .llvm_name = "v5te",
1170 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",
968 result[@enumToInt(Feature.v7k)] = .{
969 .llvm_name = "armv7k",
970 .description = "ARMv7a architecture",
1171971 .dependencies = featureSet(&[_]Feature{
1172 .v5t,
972 .v7a,
1173973 }),
1174974 };
1175 result[@enumToInt(Feature.v6)] = .{
1176 .llvm_name = "v6",
1177 .description = "Support ARM v6 instructions",
975 result[@enumToInt(Feature.v7s)] = .{
976 .llvm_name = "armv7s",
977 .description = "ARMv7a architecture",
1178978 .dependencies = featureSet(&[_]Feature{
1179 .v5te,
979 .v7a,
1180980 }),
1181981 };
1182 result[@enumToInt(Feature.v6k)] = .{
1183 .llvm_name = "v6k",
1184 .description = "Support ARM v6k instructions",
982 result[@enumToInt(Feature.v7ve)] = .{
983 .llvm_name = "armv7ve",
984 .description = "ARMv7ve architecture",
1185985 .dependencies = featureSet(&[_]Feature{
1186 .v6,
986 .aclass,
987 .db,
988 .dsp,
989 .mp,
990 .neon,
991 .trustzone,
992 .has_v7,
993 .virtualization,
1187994 }),
1188995 };
1189 result[@enumToInt(Feature.v6m)] = .{
1190 .llvm_name = "v6m",
1191 .description = "Support ARM v6M instructions",
996 result[@enumToInt(Feature.v8a)] = .{
997 .llvm_name = "armv8-a",
998 .description = "ARMv8a architecture",
1192999 .dependencies = featureSet(&[_]Feature{
1193 .v6,
1000 .aclass,
1001 .crc,
1002 .crypto,
1003 .db,
1004 .dsp,
1005 .fp_armv8,
1006 .mp,
1007 .neon,
1008 .trustzone,
1009 .has_v8,
1010 .virtualization,
11941011 }),
11951012 };
1196 result[@enumToInt(Feature.v6t2)] = .{
1197 .llvm_name = "v6t2",
1198 .description = "Support ARM v6t2 instructions",
1013 result[@enumToInt(Feature.v8m)] = .{
1014 .llvm_name = "armv8-m.base",
1015 .description = "ARMv8mBaseline architecture",
11991016 .dependencies = featureSet(&[_]Feature{
1200 .thumb2,
1201 .v6k,
1202 .v8m,
1017 .@"8msecext",
1018 .acquire_release,
1019 .db,
1020 .hwdiv,
1021 .mclass,
1022 .noarm,
1023 .strict_align,
1024 .thumb_mode,
1025 .has_v7clrex,
1026 .has_v8m,
12031027 }),
12041028 };
1205 result[@enumToInt(Feature.v7)] = .{
1206 .llvm_name = "v7",
1207 .description = "Support ARM v7 instructions",
1029 result[@enumToInt(Feature.v8m_main)] = .{
1030 .llvm_name = "armv8-m.main",
1031 .description = "ARMv8mMainline architecture",
12081032 .dependencies = featureSet(&[_]Feature{
1209 .perfmon,
1210 .v6t2,
1211 .v7clrex,
1033 .@"8msecext",
1034 .acquire_release,
1035 .db,
1036 .hwdiv,
1037 .mclass,
1038 .noarm,
1039 .thumb_mode,
1040 .has_v8m_main,
12121041 }),
12131042 };
1214 result[@enumToInt(Feature.v7clrex)] = .{
1215 .llvm_name = "v7clrex",
1216 .description = "Has v7 clrex instruction",
1217 .dependencies = featureSet(&[_]Feature{}),
1218 };
1219 result[@enumToInt(Feature.v8)] = .{
1220 .llvm_name = "v8",
1221 .description = "Support ARM v8 instructions",
1043 result[@enumToInt(Feature.v8r)] = .{
1044 .llvm_name = "armv8-r",
1045 .description = "ARMv8r architecture",
12221046 .dependencies = featureSet(&[_]Feature{
1223 .acquire_release,
1224 .v7,
1047 .crc,
1048 .db,
1049 .dfb,
1050 .dsp,
1051 .fp_armv8,
1052 .mp,
1053 .neon,
1054 .rclass,
1055 .has_v8,
1056 .virtualization,
12251057 }),
12261058 };
12271059 result[@enumToInt(Feature.v8_1a)] = .{
1228 .llvm_name = "v8.1a",
1229 .description = "Support ARM v8.1a instructions",
1060 .llvm_name = "armv8.1-a",
1061 .description = "ARMv81a architecture",
12301062 .dependencies = featureSet(&[_]Feature{
1231 .v8,
1063 .aclass,
1064 .crc,
1065 .crypto,
1066 .db,
1067 .dsp,
1068 .fp_armv8,
1069 .mp,
1070 .neon,
1071 .trustzone,
1072 .has_v8_1a,
1073 .virtualization,
12321074 }),
12331075 };
12341076 result[@enumToInt(Feature.v8_1m_main)] = .{
1235 .llvm_name = "v8.1m.main",
1236 .description = "Support ARM v8-1M Mainline instructions",
1077 .llvm_name = "armv8.1-m.main",
1078 .description = "ARMv81mMainline architecture",
12371079 .dependencies = featureSet(&[_]Feature{
1238 .v8m_main,
1080 .@"8msecext",
1081 .acquire_release,
1082 .db,
1083 .hwdiv,
1084 .lob,
1085 .mclass,
1086 .noarm,
1087 .ras,
1088 .thumb_mode,
1089 .has_v8_1m_main,
12391090 }),
12401091 };
12411092 result[@enumToInt(Feature.v8_2a)] = .{
1242 .llvm_name = "v8.2a",
1243 .description = "Support ARM v8.2a instructions",
1093 .llvm_name = "armv8.2-a",
1094 .description = "ARMv82a architecture",
12441095 .dependencies = featureSet(&[_]Feature{
1245 .v8_1a,
1096 .aclass,
1097 .crc,
1098 .crypto,
1099 .db,
1100 .dsp,
1101 .fp_armv8,
1102 .mp,
1103 .neon,
1104 .ras,
1105 .trustzone,
1106 .has_v8_2a,
1107 .virtualization,
12461108 }),
12471109 };
12481110 result[@enumToInt(Feature.v8_3a)] = .{
1249 .llvm_name = "v8.3a",
1250 .description = "Support ARM v8.3a instructions",
1111 .llvm_name = "armv8.3-a",
1112 .description = "ARMv83a architecture",
12511113 .dependencies = featureSet(&[_]Feature{
1252 .v8_2a,
1114 .aclass,
1115 .crc,
1116 .crypto,
1117 .db,
1118 .dsp,
1119 .fp_armv8,
1120 .mp,
1121 .neon,
1122 .ras,
1123 .trustzone,
1124 .has_v8_3a,
1125 .virtualization,
12531126 }),
12541127 };
12551128 result[@enumToInt(Feature.v8_4a)] = .{
1256 .llvm_name = "v8.4a",
1257 .description = "Support ARM v8.4a instructions",
1129 .llvm_name = "armv8.4-a",
1130 .description = "ARMv84a architecture",
12581131 .dependencies = featureSet(&[_]Feature{
1132 .aclass,
1133 .crc,
1134 .crypto,
1135 .db,
12591136 .dotprod,
1260 .v8_3a,
1137 .dsp,
1138 .fp_armv8,
1139 .mp,
1140 .neon,
1141 .ras,
1142 .trustzone,
1143 .has_v8_4a,
1144 .virtualization,
12611145 }),
12621146 };
12631147 result[@enumToInt(Feature.v8_5a)] = .{
1264 .llvm_name = "v8.5a",
1265 .description = "Support ARM v8.5a instructions",
1266 .dependencies = featureSet(&[_]Feature{
1267 .sb,
1268 .v8_4a,
1269 }),
1270 };
1271 result[@enumToInt(Feature.v8m)] = .{
1272 .llvm_name = "v8m",
1273 .description = "Support ARM v8M Baseline instructions",
1274 .dependencies = featureSet(&[_]Feature{
1275 .v6m,
1276 }),
1277 };
1278 result[@enumToInt(Feature.v8m_main)] = .{
1279 .llvm_name = "v8m.main",
1280 .description = "Support ARM v8M Mainline instructions",
1148 .llvm_name = "armv8.5-a",
1149 .description = "ARMv85a architecture",
12811150 .dependencies = featureSet(&[_]Feature{
1282 .v7,
1151 .aclass,
1152 .crc,
1153 .crypto,
1154 .db,
1155 .dotprod,
1156 .dsp,
1157 .fp_armv8,
1158 .mp,
1159 .neon,
1160 .ras,
1161 .trustzone,
1162 .has_v8_5a,
1163 .virtualization,
12831164 }),
12841165 };
12851166 result[@enumToInt(Feature.vfp2)] = .{
......@@ -1399,7 +1280,7 @@ pub const all_features = blk: {
13991280 .llvm_name = "xscale",
14001281 .description = "ARMv5te architecture",
14011282 .dependencies = featureSet(&[_]Feature{
1402 .armv5te,
1283 .has_v5te,
14031284 }),
14041285 };
14051286 result[@enumToInt(Feature.zcz)] = .{
......@@ -1416,221 +1297,227 @@ pub const all_features = blk: {
14161297};
14171298
14181299pub const cpu = struct {
1419 pub const arm1020e = Cpu{
1300 pub const arm1020e = CpuModel{
14201301 .name = "arm1020e",
14211302 .llvm_name = "arm1020e",
14221303 .features = featureSet(&[_]Feature{
1423 .armv5te,
1304 .v5te,
14241305 }),
14251306 };
1426 pub const arm1020t = Cpu{
1307 pub const arm1020t = CpuModel{
14271308 .name = "arm1020t",
14281309 .llvm_name = "arm1020t",
14291310 .features = featureSet(&[_]Feature{
1430 .armv5t,
1311 .v5t,
14311312 }),
14321313 };
1433 pub const arm1022e = Cpu{
1314 pub const arm1022e = CpuModel{
14341315 .name = "arm1022e",
14351316 .llvm_name = "arm1022e",
14361317 .features = featureSet(&[_]Feature{
1437 .armv5te,
1318 .v5te,
14381319 }),
14391320 };
1440 pub const arm10e = Cpu{
1321 pub const arm10e = CpuModel{
14411322 .name = "arm10e",
14421323 .llvm_name = "arm10e",
14431324 .features = featureSet(&[_]Feature{
1444 .armv5te,
1325 .v5te,
14451326 }),
14461327 };
1447 pub const arm10tdmi = Cpu{
1328 pub const arm10tdmi = CpuModel{
14481329 .name = "arm10tdmi",
14491330 .llvm_name = "arm10tdmi",
14501331 .features = featureSet(&[_]Feature{
1451 .armv5t,
1332 .v5t,
14521333 }),
14531334 };
1454 pub const arm1136j_s = Cpu{
1335 pub const arm1136j_s = CpuModel{
14551336 .name = "arm1136j_s",
14561337 .llvm_name = "arm1136j-s",
14571338 .features = featureSet(&[_]Feature{
1458 .armv6,
1339 .v6,
14591340 }),
14601341 };
1461 pub const arm1136jf_s = Cpu{
1342 pub const arm1136jf_s = CpuModel{
14621343 .name = "arm1136jf_s",
14631344 .llvm_name = "arm1136jf-s",
14641345 .features = featureSet(&[_]Feature{
1465 .armv6,
1346 .v6,
14661347 .slowfpvmlx,
14671348 .vfp2,
14681349 }),
14691350 };
1470 pub const arm1156t2_s = Cpu{
1351 pub const arm1156t2_s = CpuModel{
14711352 .name = "arm1156t2_s",
14721353 .llvm_name = "arm1156t2-s",
14731354 .features = featureSet(&[_]Feature{
1474 .armv6t2,
1355 .v6t2,
14751356 }),
14761357 };
1477 pub const arm1156t2f_s = Cpu{
1358 pub const arm1156t2f_s = CpuModel{
14781359 .name = "arm1156t2f_s",
14791360 .llvm_name = "arm1156t2f-s",
14801361 .features = featureSet(&[_]Feature{
1481 .armv6t2,
1362 .v6t2,
14821363 .slowfpvmlx,
14831364 .vfp2,
14841365 }),
14851366 };
1486 pub const arm1176j_s = Cpu{
1367 pub const arm1176j_s = CpuModel{
14871368 .name = "arm1176j_s",
14881369 .llvm_name = "arm1176j-s",
14891370 .features = featureSet(&[_]Feature{
1490 .armv6kz,
1371 .v6kz,
14911372 }),
14921373 };
1493 pub const arm1176jz_s = Cpu{
1374 pub const arm1176jz_s = CpuModel{
14941375 .name = "arm1176jz_s",
14951376 .llvm_name = "arm1176jz-s",
14961377 .features = featureSet(&[_]Feature{
1497 .armv6kz,
1378 .v6kz,
14981379 }),
14991380 };
1500 pub const arm1176jzf_s = Cpu{
1381 pub const arm1176jzf_s = CpuModel{
15011382 .name = "arm1176jzf_s",
15021383 .llvm_name = "arm1176jzf-s",
15031384 .features = featureSet(&[_]Feature{
1504 .armv6kz,
1385 .v6kz,
15051386 .slowfpvmlx,
15061387 .vfp2,
15071388 }),
15081389 };
1509 pub const arm710t = Cpu{
1390 pub const arm710t = CpuModel{
15101391 .name = "arm710t",
15111392 .llvm_name = "arm710t",
15121393 .features = featureSet(&[_]Feature{
1513 .armv4t,
1394 .v4t,
15141395 }),
15151396 };
1516 pub const arm720t = Cpu{
1397 pub const arm720t = CpuModel{
15171398 .name = "arm720t",
15181399 .llvm_name = "arm720t",
15191400 .features = featureSet(&[_]Feature{
1520 .armv4t,
1401 .v4t,
15211402 }),
15221403 };
1523 pub const arm7tdmi = Cpu{
1404 pub const arm7tdmi = CpuModel{
15241405 .name = "arm7tdmi",
15251406 .llvm_name = "arm7tdmi",
15261407 .features = featureSet(&[_]Feature{
1527 .armv4t,
1408 .v4t,
15281409 }),
15291410 };
1530 pub const arm7tdmi_s = Cpu{
1411 pub const arm7tdmi_s = CpuModel{
15311412 .name = "arm7tdmi_s",
15321413 .llvm_name = "arm7tdmi-s",
15331414 .features = featureSet(&[_]Feature{
1534 .armv4t,
1415 .v4t,
15351416 }),
15361417 };
1537 pub const arm8 = Cpu{
1418 pub const arm8 = CpuModel{
15381419 .name = "arm8",
15391420 .llvm_name = "arm8",
15401421 .features = featureSet(&[_]Feature{
1541 .armv4,
1422 .v4,
15421423 }),
15431424 };
1544 pub const arm810 = Cpu{
1425 pub const arm810 = CpuModel{
15451426 .name = "arm810",
15461427 .llvm_name = "arm810",
15471428 .features = featureSet(&[_]Feature{
1548 .armv4,
1429 .v4,
15491430 }),
15501431 };
1551 pub const arm9 = Cpu{
1432 pub const arm9 = CpuModel{
15521433 .name = "arm9",
15531434 .llvm_name = "arm9",
15541435 .features = featureSet(&[_]Feature{
1555 .armv4t,
1436 .v4t,
15561437 }),
15571438 };
1558 pub const arm920 = Cpu{
1439 pub const arm920 = CpuModel{
15591440 .name = "arm920",
15601441 .llvm_name = "arm920",
15611442 .features = featureSet(&[_]Feature{
1562 .armv4t,
1443 .v4t,
15631444 }),
15641445 };
1565 pub const arm920t = Cpu{
1446 pub const arm920t = CpuModel{
15661447 .name = "arm920t",
15671448 .llvm_name = "arm920t",
15681449 .features = featureSet(&[_]Feature{
1569 .armv4t,
1450 .v4t,
15701451 }),
15711452 };
1572 pub const arm922t = Cpu{
1453 pub const arm922t = CpuModel{
15731454 .name = "arm922t",
15741455 .llvm_name = "arm922t",
15751456 .features = featureSet(&[_]Feature{
1576 .armv4t,
1457 .v4t,
15771458 }),
15781459 };
1579 pub const arm926ej_s = Cpu{
1460 pub const arm926ej_s = CpuModel{
15801461 .name = "arm926ej_s",
15811462 .llvm_name = "arm926ej-s",
15821463 .features = featureSet(&[_]Feature{
1583 .armv5te,
1464 .v5te,
15841465 }),
15851466 };
1586 pub const arm940t = Cpu{
1467 pub const arm940t = CpuModel{
15871468 .name = "arm940t",
15881469 .llvm_name = "arm940t",
15891470 .features = featureSet(&[_]Feature{
1590 .armv4t,
1471 .v4t,
15911472 }),
15921473 };
1593 pub const arm946e_s = Cpu{
1474 pub const arm946e_s = CpuModel{
15941475 .name = "arm946e_s",
15951476 .llvm_name = "arm946e-s",
15961477 .features = featureSet(&[_]Feature{
1597 .armv5te,
1478 .v5te,
15981479 }),
15991480 };
1600 pub const arm966e_s = Cpu{
1481 pub const arm966e_s = CpuModel{
16011482 .name = "arm966e_s",
16021483 .llvm_name = "arm966e-s",
16031484 .features = featureSet(&[_]Feature{
1604 .armv5te,
1485 .v5te,
16051486 }),
16061487 };
1607 pub const arm968e_s = Cpu{
1488 pub const arm968e_s = CpuModel{
16081489 .name = "arm968e_s",
16091490 .llvm_name = "arm968e-s",
16101491 .features = featureSet(&[_]Feature{
1611 .armv5te,
1492 .v5te,
16121493 }),
16131494 };
1614 pub const arm9e = Cpu{
1495 pub const arm9e = CpuModel{
16151496 .name = "arm9e",
16161497 .llvm_name = "arm9e",
16171498 .features = featureSet(&[_]Feature{
1618 .armv5te,
1499 .v5te,
16191500 }),
16201501 };
1621 pub const arm9tdmi = Cpu{
1502 pub const arm9tdmi = CpuModel{
16221503 .name = "arm9tdmi",
16231504 .llvm_name = "arm9tdmi",
16241505 .features = featureSet(&[_]Feature{
1625 .armv4t,
1506 .v4t,
1507 }),
1508 };
1509 pub const baseline = CpuModel{
1510 .name = "baseline",
1511 .llvm_name = "generic",
1512 .features = featureSet(&[_]Feature{
1513 .v6m,
16261514 }),
16271515 };
1628 pub const cortex_a12 = Cpu{
1516 pub const cortex_a12 = CpuModel{
16291517 .name = "cortex_a12",
16301518 .llvm_name = "cortex-a12",
16311519 .features = featureSet(&[_]Feature{
1632 .a12,
1633 .armv7_a,
1520 .v7a,
16341521 .avoid_partial_cpsr,
16351522 .mp,
16361523 .ret_addr_stack,
......@@ -1640,12 +1527,11 @@ pub const cpu = struct {
16401527 .vmlx_forwarding,
16411528 }),
16421529 };
1643 pub const cortex_a15 = Cpu{
1530 pub const cortex_a15 = CpuModel{
16441531 .name = "cortex_a15",
16451532 .llvm_name = "cortex-a15",
16461533 .features = featureSet(&[_]Feature{
1647 .a15,
1648 .armv7_a,
1534 .v7a,
16491535 .avoid_partial_cpsr,
16501536 .dont_widen_vmovs,
16511537 .mp,
......@@ -1658,12 +1544,11 @@ pub const cpu = struct {
16581544 .vldn_align,
16591545 }),
16601546 };
1661 pub const cortex_a17 = Cpu{
1547 pub const cortex_a17 = CpuModel{
16621548 .name = "cortex_a17",
16631549 .llvm_name = "cortex-a17",
16641550 .features = featureSet(&[_]Feature{
1665 .a17,
1666 .armv7_a,
1551 .v7a,
16671552 .avoid_partial_cpsr,
16681553 .mp,
16691554 .ret_addr_stack,
......@@ -1673,35 +1558,33 @@ pub const cpu = struct {
16731558 .vmlx_forwarding,
16741559 }),
16751560 };
1676 pub const cortex_a32 = Cpu{
1561 pub const cortex_a32 = CpuModel{
16771562 .name = "cortex_a32",
16781563 .llvm_name = "cortex-a32",
16791564 .features = featureSet(&[_]Feature{
1680 .armv8_a,
16811565 .crc,
16821566 .crypto,
16831567 .hwdiv,
16841568 .hwdiv_arm,
1569 .v8a,
16851570 }),
16861571 };
1687 pub const cortex_a35 = Cpu{
1572 pub const cortex_a35 = CpuModel{
16881573 .name = "cortex_a35",
16891574 .llvm_name = "cortex-a35",
16901575 .features = featureSet(&[_]Feature{
1691 .a35,
1692 .armv8_a,
16931576 .crc,
16941577 .crypto,
16951578 .hwdiv,
16961579 .hwdiv_arm,
1580 .v8a,
16971581 }),
16981582 };
1699 pub const cortex_a5 = Cpu{
1583 pub const cortex_a5 = CpuModel{
17001584 .name = "cortex_a5",
17011585 .llvm_name = "cortex-a5",
17021586 .features = featureSet(&[_]Feature{
1703 .a5,
1704 .armv7_a,
1587 .v7a,
17051588 .mp,
17061589 .ret_addr_stack,
17071590 .slow_fp_brcc,
......@@ -1712,12 +1595,11 @@ pub const cpu = struct {
17121595 .vmlx_forwarding,
17131596 }),
17141597 };
1715 pub const cortex_a53 = Cpu{
1598 pub const cortex_a53 = CpuModel{
17161599 .name = "cortex_a53",
17171600 .llvm_name = "cortex-a53",
17181601 .features = featureSet(&[_]Feature{
1719 .a53,
1720 .armv8_a,
1602 .v8a,
17211603 .crc,
17221604 .crypto,
17231605 .fpao,
......@@ -1725,23 +1607,21 @@ pub const cpu = struct {
17251607 .hwdiv_arm,
17261608 }),
17271609 };
1728 pub const cortex_a55 = Cpu{
1610 pub const cortex_a55 = CpuModel{
17291611 .name = "cortex_a55",
17301612 .llvm_name = "cortex-a55",
17311613 .features = featureSet(&[_]Feature{
1732 .a55,
1733 .armv8_2_a,
1614 .v8_2a,
17341615 .dotprod,
17351616 .hwdiv,
17361617 .hwdiv_arm,
17371618 }),
17381619 };
1739 pub const cortex_a57 = Cpu{
1620 pub const cortex_a57 = CpuModel{
17401621 .name = "cortex_a57",
17411622 .llvm_name = "cortex-a57",
17421623 .features = featureSet(&[_]Feature{
1743 .a57,
1744 .armv8_a,
1624 .v8a,
17451625 .avoid_partial_cpsr,
17461626 .cheap_predicable_cpsr,
17471627 .crc,
......@@ -1751,12 +1631,11 @@ pub const cpu = struct {
17511631 .hwdiv_arm,
17521632 }),
17531633 };
1754 pub const cortex_a7 = Cpu{
1634 pub const cortex_a7 = CpuModel{
17551635 .name = "cortex_a7",
17561636 .llvm_name = "cortex-a7",
17571637 .features = featureSet(&[_]Feature{
1758 .a7,
1759 .armv7_a,
1638 .v7a,
17601639 .mp,
17611640 .ret_addr_stack,
17621641 .slow_fp_brcc,
......@@ -1769,47 +1648,44 @@ pub const cpu = struct {
17691648 .vmlx_hazards,
17701649 }),
17711650 };
1772 pub const cortex_a72 = Cpu{
1651 pub const cortex_a72 = CpuModel{
17731652 .name = "cortex_a72",
17741653 .llvm_name = "cortex-a72",
17751654 .features = featureSet(&[_]Feature{
1776 .a72,
1777 .armv8_a,
1655 .v8a,
17781656 .crc,
17791657 .crypto,
17801658 .hwdiv,
17811659 .hwdiv_arm,
17821660 }),
17831661 };
1784 pub const cortex_a73 = Cpu{
1662 pub const cortex_a73 = CpuModel{
17851663 .name = "cortex_a73",
17861664 .llvm_name = "cortex-a73",
17871665 .features = featureSet(&[_]Feature{
1788 .a73,
1789 .armv8_a,
1666 .v8a,
17901667 .crc,
17911668 .crypto,
17921669 .hwdiv,
17931670 .hwdiv_arm,
17941671 }),
17951672 };
1796 pub const cortex_a75 = Cpu{
1673 pub const cortex_a75 = CpuModel{
17971674 .name = "cortex_a75",
17981675 .llvm_name = "cortex-a75",
17991676 .features = featureSet(&[_]Feature{
1800 .a75,
1801 .armv8_2_a,
1677 .v8_2a,
18021678 .dotprod,
18031679 .hwdiv,
18041680 .hwdiv_arm,
18051681 }),
18061682 };
1807 pub const cortex_a76 = Cpu{
1683 pub const cortex_a76 = CpuModel{
18081684 .name = "cortex_a76",
18091685 .llvm_name = "cortex-a76",
18101686 .features = featureSet(&[_]Feature{
18111687 .a76,
1812 .armv8_2_a,
1688 .v8_2a,
18131689 .crc,
18141690 .crypto,
18151691 .dotprod,
......@@ -1818,12 +1694,12 @@ pub const cpu = struct {
18181694 .hwdiv_arm,
18191695 }),
18201696 };
1821 pub const cortex_a76ae = Cpu{
1697 pub const cortex_a76ae = CpuModel{
18221698 .name = "cortex_a76ae",
18231699 .llvm_name = "cortex-a76ae",
18241700 .features = featureSet(&[_]Feature{
18251701 .a76,
1826 .armv8_2_a,
1702 .v8_2a,
18271703 .crc,
18281704 .crypto,
18291705 .dotprod,
......@@ -1832,12 +1708,11 @@ pub const cpu = struct {
18321708 .hwdiv_arm,
18331709 }),
18341710 };
1835 pub const cortex_a8 = Cpu{
1711 pub const cortex_a8 = CpuModel{
18361712 .name = "cortex_a8",
18371713 .llvm_name = "cortex-a8",
18381714 .features = featureSet(&[_]Feature{
1839 .a8,
1840 .armv7_a,
1715 .v7a,
18411716 .nonpipelined_vfp,
18421717 .ret_addr_stack,
18431718 .slow_fp_brcc,
......@@ -1848,12 +1723,11 @@ pub const cpu = struct {
18481723 .vmlx_hazards,
18491724 }),
18501725 };
1851 pub const cortex_a9 = Cpu{
1726 pub const cortex_a9 = CpuModel{
18521727 .name = "cortex_a9",
18531728 .llvm_name = "cortex-a9",
18541729 .features = featureSet(&[_]Feature{
1855 .a9,
1856 .armv7_a,
1730 .v7a,
18571731 .avoid_partial_cpsr,
18581732 .expand_fp_mlx,
18591733 .fp16,
......@@ -1868,51 +1742,51 @@ pub const cpu = struct {
18681742 .vmlx_hazards,
18691743 }),
18701744 };
1871 pub const cortex_m0 = Cpu{
1745 pub const cortex_m0 = CpuModel{
18721746 .name = "cortex_m0",
18731747 .llvm_name = "cortex-m0",
18741748 .features = featureSet(&[_]Feature{
1875 .armv6_m,
1749 .v6m,
18761750 }),
18771751 };
1878 pub const cortex_m0plus = Cpu{
1752 pub const cortex_m0plus = CpuModel{
18791753 .name = "cortex_m0plus",
18801754 .llvm_name = "cortex-m0plus",
18811755 .features = featureSet(&[_]Feature{
1882 .armv6_m,
1756 .v6m,
18831757 }),
18841758 };
1885 pub const cortex_m1 = Cpu{
1759 pub const cortex_m1 = CpuModel{
18861760 .name = "cortex_m1",
18871761 .llvm_name = "cortex-m1",
18881762 .features = featureSet(&[_]Feature{
1889 .armv6_m,
1763 .v6m,
18901764 }),
18911765 };
1892 pub const cortex_m23 = Cpu{
1766 pub const cortex_m23 = CpuModel{
18931767 .name = "cortex_m23",
18941768 .llvm_name = "cortex-m23",
18951769 .features = featureSet(&[_]Feature{
1896 .armv8_m_base,
1770 .v8m,
18971771 .no_movt,
18981772 }),
18991773 };
1900 pub const cortex_m3 = Cpu{
1774 pub const cortex_m3 = CpuModel{
19011775 .name = "cortex_m3",
19021776 .llvm_name = "cortex-m3",
19031777 .features = featureSet(&[_]Feature{
1904 .armv7_m,
1778 .v7m,
19051779 .loop_align,
19061780 .m3,
19071781 .no_branch_predictor,
19081782 .use_misched,
19091783 }),
19101784 };
1911 pub const cortex_m33 = Cpu{
1785 pub const cortex_m33 = CpuModel{
19121786 .name = "cortex_m33",
19131787 .llvm_name = "cortex-m33",
19141788 .features = featureSet(&[_]Feature{
1915 .armv8_m_main,
1789 .v8m_main,
19161790 .dsp,
19171791 .fp_armv8d16sp,
19181792 .loop_align,
......@@ -1922,11 +1796,11 @@ pub const cpu = struct {
19221796 .use_misched,
19231797 }),
19241798 };
1925 pub const cortex_m35p = Cpu{
1799 pub const cortex_m35p = CpuModel{
19261800 .name = "cortex_m35p",
19271801 .llvm_name = "cortex-m35p",
19281802 .features = featureSet(&[_]Feature{
1929 .armv8_m_main,
1803 .v8m_main,
19301804 .dsp,
19311805 .fp_armv8d16sp,
19321806 .loop_align,
......@@ -1936,11 +1810,11 @@ pub const cpu = struct {
19361810 .use_misched,
19371811 }),
19381812 };
1939 pub const cortex_m4 = Cpu{
1813 pub const cortex_m4 = CpuModel{
19401814 .name = "cortex_m4",
19411815 .llvm_name = "cortex-m4",
19421816 .features = featureSet(&[_]Feature{
1943 .armv7e_m,
1817 .v7em,
19441818 .loop_align,
19451819 .no_branch_predictor,
19461820 .slowfpvfmx,
......@@ -1949,29 +1823,29 @@ pub const cpu = struct {
19491823 .vfp4d16sp,
19501824 }),
19511825 };
1952 pub const cortex_m7 = Cpu{
1826 pub const cortex_m7 = CpuModel{
19531827 .name = "cortex_m7",
19541828 .llvm_name = "cortex-m7",
19551829 .features = featureSet(&[_]Feature{
1956 .armv7e_m,
1830 .v7em,
19571831 .fp_armv8d16,
19581832 }),
19591833 };
1960 pub const cortex_r4 = Cpu{
1834 pub const cortex_r4 = CpuModel{
19611835 .name = "cortex_r4",
19621836 .llvm_name = "cortex-r4",
19631837 .features = featureSet(&[_]Feature{
1964 .armv7_r,
1838 .v7r,
19651839 .avoid_partial_cpsr,
19661840 .r4,
19671841 .ret_addr_stack,
19681842 }),
19691843 };
1970 pub const cortex_r4f = Cpu{
1844 pub const cortex_r4f = CpuModel{
19711845 .name = "cortex_r4f",
19721846 .llvm_name = "cortex-r4f",
19731847 .features = featureSet(&[_]Feature{
1974 .armv7_r,
1848 .v7r,
19751849 .avoid_partial_cpsr,
19761850 .r4,
19771851 .ret_addr_stack,
......@@ -1981,14 +1855,13 @@ pub const cpu = struct {
19811855 .vfp3d16,
19821856 }),
19831857 };
1984 pub const cortex_r5 = Cpu{
1858 pub const cortex_r5 = CpuModel{
19851859 .name = "cortex_r5",
19861860 .llvm_name = "cortex-r5",
19871861 .features = featureSet(&[_]Feature{
1988 .armv7_r,
1862 .v7r,
19891863 .avoid_partial_cpsr,
19901864 .hwdiv_arm,
1991 .r5,
19921865 .ret_addr_stack,
19931866 .slow_fp_brcc,
19941867 .slowfpvfmx,
......@@ -1996,26 +1869,24 @@ pub const cpu = struct {
19961869 .vfp3d16,
19971870 }),
19981871 };
1999 pub const cortex_r52 = Cpu{
1872 pub const cortex_r52 = CpuModel{
20001873 .name = "cortex_r52",
20011874 .llvm_name = "cortex-r52",
20021875 .features = featureSet(&[_]Feature{
2003 .armv8_r,
1876 .v8r,
20041877 .fpao,
2005 .r52,
20061878 .use_misched,
20071879 }),
20081880 };
2009 pub const cortex_r7 = Cpu{
1881 pub const cortex_r7 = CpuModel{
20101882 .name = "cortex_r7",
20111883 .llvm_name = "cortex-r7",
20121884 .features = featureSet(&[_]Feature{
2013 .armv7_r,
1885 .v7r,
20141886 .avoid_partial_cpsr,
20151887 .fp16,
20161888 .hwdiv_arm,
20171889 .mp,
2018 .r7,
20191890 .ret_addr_stack,
20201891 .slow_fp_brcc,
20211892 .slowfpvfmx,
......@@ -2023,11 +1894,11 @@ pub const cpu = struct {
20231894 .vfp3d16,
20241895 }),
20251896 };
2026 pub const cortex_r8 = Cpu{
1897 pub const cortex_r8 = CpuModel{
20271898 .name = "cortex_r8",
20281899 .llvm_name = "cortex-r8",
20291900 .features = featureSet(&[_]Feature{
2030 .armv7_r,
1901 .v7r,
20311902 .avoid_partial_cpsr,
20321903 .fp16,
20331904 .hwdiv_arm,
......@@ -2039,11 +1910,11 @@ pub const cpu = struct {
20391910 .vfp3d16,
20401911 }),
20411912 };
2042 pub const cyclone = Cpu{
1913 pub const cyclone = CpuModel{
20431914 .name = "cyclone",
20441915 .llvm_name = "cyclone",
20451916 .features = featureSet(&[_]Feature{
2046 .armv8_a,
1917 .v8a,
20471918 .avoid_movs_shop,
20481919 .avoid_partial_cpsr,
20491920 .crypto,
......@@ -2061,119 +1932,117 @@ pub const cpu = struct {
20611932 .zcz,
20621933 }),
20631934 };
2064 pub const ep9312 = Cpu{
1935 pub const ep9312 = CpuModel{
20651936 .name = "ep9312",
20661937 .llvm_name = "ep9312",
20671938 .features = featureSet(&[_]Feature{
2068 .armv4t,
1939 .v4t,
20691940 }),
20701941 };
2071 pub const exynos_m1 = Cpu{
1942 pub const exynos_m1 = CpuModel{
20721943 .name = "exynos_m1",
20731944 .llvm_name = null,
20741945 .features = featureSet(&[_]Feature{
2075 .armv8_a,
1946 .v8a,
20761947 .exynos,
20771948 }),
20781949 };
2079 pub const exynos_m2 = Cpu{
1950 pub const exynos_m2 = CpuModel{
20801951 .name = "exynos_m2",
20811952 .llvm_name = null,
20821953 .features = featureSet(&[_]Feature{
2083 .armv8_a,
1954 .v8a,
20841955 .exynos,
20851956 }),
20861957 };
2087 pub const exynos_m3 = Cpu{
1958 pub const exynos_m3 = CpuModel{
20881959 .name = "exynos_m3",
20891960 .llvm_name = "exynos-m3",
20901961 .features = featureSet(&[_]Feature{
2091 .armv8_a,
1962 .v8_2a,
20921963 .exynos,
20931964 }),
20941965 };
2095 pub const exynos_m4 = Cpu{
1966 pub const exynos_m4 = CpuModel{
20961967 .name = "exynos_m4",
20971968 .llvm_name = "exynos-m4",
20981969 .features = featureSet(&[_]Feature{
2099 .armv8_2_a,
1970 .v8_2a,
21001971 .dotprod,
21011972 .exynos,
21021973 .fullfp16,
21031974 }),
21041975 };
2105 pub const exynos_m5 = Cpu{
1976 pub const exynos_m5 = CpuModel{
21061977 .name = "exynos_m5",
21071978 .llvm_name = "exynos-m5",
21081979 .features = featureSet(&[_]Feature{
2109 .armv8_2_a,
21101980 .dotprod,
21111981 .exynos,
21121982 .fullfp16,
1983 .v8_2a,
21131984 }),
21141985 };
2115 pub const generic = Cpu{
1986 pub const generic = CpuModel{
21161987 .name = "generic",
21171988 .llvm_name = "generic",
21181989 .features = featureSet(&[_]Feature{}),
21191990 };
2120 pub const iwmmxt = Cpu{
1991 pub const iwmmxt = CpuModel{
21211992 .name = "iwmmxt",
21221993 .llvm_name = "iwmmxt",
21231994 .features = featureSet(&[_]Feature{
2124 .armv5te,
1995 .v5te,
21251996 }),
21261997 };
2127 pub const krait = Cpu{
1998 pub const krait = CpuModel{
21281999 .name = "krait",
21292000 .llvm_name = "krait",
21302001 .features = featureSet(&[_]Feature{
2131 .armv7_a,
21322002 .avoid_partial_cpsr,
21332003 .fp16,
21342004 .hwdiv,
21352005 .hwdiv_arm,
2136 .krait,
21372006 .muxed_units,
21382007 .ret_addr_stack,
2008 .v7a,
21392009 .vfp4,
21402010 .vldn_align,
21412011 .vmlx_forwarding,
21422012 }),
21432013 };
2144 pub const kryo = Cpu{
2014 pub const kryo = CpuModel{
21452015 .name = "kryo",
21462016 .llvm_name = "kryo",
21472017 .features = featureSet(&[_]Feature{
2148 .armv8_a,
21492018 .crc,
21502019 .crypto,
21512020 .hwdiv,
21522021 .hwdiv_arm,
2153 .kryo,
2022 .v8a,
21542023 }),
21552024 };
2156 pub const mpcore = Cpu{
2025 pub const mpcore = CpuModel{
21572026 .name = "mpcore",
21582027 .llvm_name = "mpcore",
21592028 .features = featureSet(&[_]Feature{
2160 .armv6k,
2029 .v6k,
21612030 .slowfpvmlx,
21622031 .vfp2,
21632032 }),
21642033 };
2165 pub const mpcorenovfp = Cpu{
2034 pub const mpcorenovfp = CpuModel{
21662035 .name = "mpcorenovfp",
21672036 .llvm_name = "mpcorenovfp",
21682037 .features = featureSet(&[_]Feature{
2169 .armv6k,
2038 .v6k,
21702039 }),
21712040 };
2172 pub const neoverse_n1 = Cpu{
2041 pub const neoverse_n1 = CpuModel{
21732042 .name = "neoverse_n1",
21742043 .llvm_name = "neoverse-n1",
21752044 .features = featureSet(&[_]Feature{
2176 .armv8_2_a,
2045 .v8_2a,
21772046 .crc,
21782047 .crypto,
21792048 .dotprod,
......@@ -2181,56 +2050,56 @@ pub const cpu = struct {
21812050 .hwdiv_arm,
21822051 }),
21832052 };
2184 pub const sc000 = Cpu{
2053 pub const sc000 = CpuModel{
21852054 .name = "sc000",
21862055 .llvm_name = "sc000",
21872056 .features = featureSet(&[_]Feature{
2188 .armv6_m,
2057 .v6m,
21892058 }),
21902059 };
2191 pub const sc300 = Cpu{
2060 pub const sc300 = CpuModel{
21922061 .name = "sc300",
21932062 .llvm_name = "sc300",
21942063 .features = featureSet(&[_]Feature{
2195 .armv7_m,
2064 .v7m,
21962065 .m3,
21972066 .no_branch_predictor,
21982067 .use_misched,
21992068 }),
22002069 };
2201 pub const strongarm = Cpu{
2070 pub const strongarm = CpuModel{
22022071 .name = "strongarm",
22032072 .llvm_name = "strongarm",
22042073 .features = featureSet(&[_]Feature{
2205 .armv4,
2074 .v4,
22062075 }),
22072076 };
2208 pub const strongarm110 = Cpu{
2077 pub const strongarm110 = CpuModel{
22092078 .name = "strongarm110",
22102079 .llvm_name = "strongarm110",
22112080 .features = featureSet(&[_]Feature{
2212 .armv4,
2081 .v4,
22132082 }),
22142083 };
2215 pub const strongarm1100 = Cpu{
2084 pub const strongarm1100 = CpuModel{
22162085 .name = "strongarm1100",
22172086 .llvm_name = "strongarm1100",
22182087 .features = featureSet(&[_]Feature{
2219 .armv4,
2088 .v4,
22202089 }),
22212090 };
2222 pub const strongarm1110 = Cpu{
2091 pub const strongarm1110 = CpuModel{
22232092 .name = "strongarm1110",
22242093 .llvm_name = "strongarm1110",
22252094 .features = featureSet(&[_]Feature{
2226 .armv4,
2095 .v4,
22272096 }),
22282097 };
2229 pub const swift = Cpu{
2098 pub const swift = CpuModel{
22302099 .name = "swift",
22312100 .llvm_name = "swift",
22322101 .features = featureSet(&[_]Feature{
2233 .armv7_a,
2102 .v7a,
22342103 .avoid_movs_shop,
22352104 .avoid_partial_cpsr,
22362105 .disable_postra_scheduler,
......@@ -2254,11 +2123,11 @@ pub const cpu = struct {
22542123 .wide_stride_vfp,
22552124 }),
22562125 };
2257 pub const xscale = Cpu{
2126 pub const xscale = CpuModel{
22582127 .name = "xscale",
22592128 .llvm_name = "xscale",
22602129 .features = featureSet(&[_]Feature{
2261 .armv5te,
2130 .v5te,
22622131 }),
22632132 };
22642133};
......@@ -2266,7 +2135,7 @@ pub const cpu = struct {
22662135/// All arm CPUs, sorted alphabetically by name.
22672136/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
22682137/// compiler has inefficient memory and CPU usage, affecting build times.
2269pub const all_cpus = &[_]*const Cpu{
2138pub const all_cpus = &[_]*const CpuModel{
22702139 &cpu.arm1020e,
22712140 &cpu.arm1020t,
22722141 &cpu.arm1022e,
lib/std/target/avr.zig+263-262
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 addsubiw,
......@@ -37,12 +38,12 @@ pub const Feature = enum {
3738 xmegau,
3839};
3940
40pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
41pub usingnamespace CpuFeature.feature_set_fns(Feature);
4142
4243pub const all_features = blk: {
4344 const len = @typeInfo(Feature).Enum.fields.len;
44 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
45 var result: [len]Cpu.Feature = undefined;
45 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
46 var result: [len]CpuFeature = undefined;
4647 result[@enumToInt(Feature.addsubiw)] = .{
4748 .llvm_name = "addsubiw",
4849 .description = "Enable 16-bit register-immediate addition and subtraction instructions",
......@@ -293,28 +294,28 @@ pub const all_features = blk: {
293294};
294295
295296pub const cpu = struct {
296 pub const at43usb320 = Cpu{
297 pub const at43usb320 = CpuModel{
297298 .name = "at43usb320",
298299 .llvm_name = "at43usb320",
299300 .features = featureSet(&[_]Feature{
300301 .avr31,
301302 }),
302303 };
303 pub const at43usb355 = Cpu{
304 pub const at43usb355 = CpuModel{
304305 .name = "at43usb355",
305306 .llvm_name = "at43usb355",
306307 .features = featureSet(&[_]Feature{
307308 .avr3,
308309 }),
309310 };
310 pub const at76c711 = Cpu{
311 pub const at76c711 = CpuModel{
311312 .name = "at76c711",
312313 .llvm_name = "at76c711",
313314 .features = featureSet(&[_]Feature{
314315 .avr3,
315316 }),
316317 };
317 pub const at86rf401 = Cpu{
318 pub const at86rf401 = CpuModel{
318319 .name = "at86rf401",
319320 .llvm_name = "at86rf401",
320321 .features = featureSet(&[_]Feature{
......@@ -323,217 +324,217 @@ pub const cpu = struct {
323324 .movw,
324325 }),
325326 };
326 pub const at90c8534 = Cpu{
327 pub const at90c8534 = CpuModel{
327328 .name = "at90c8534",
328329 .llvm_name = "at90c8534",
329330 .features = featureSet(&[_]Feature{
330331 .avr2,
331332 }),
332333 };
333 pub const at90can128 = Cpu{
334 pub const at90can128 = CpuModel{
334335 .name = "at90can128",
335336 .llvm_name = "at90can128",
336337 .features = featureSet(&[_]Feature{
337338 .avr51,
338339 }),
339340 };
340 pub const at90can32 = Cpu{
341 pub const at90can32 = CpuModel{
341342 .name = "at90can32",
342343 .llvm_name = "at90can32",
343344 .features = featureSet(&[_]Feature{
344345 .avr5,
345346 }),
346347 };
347 pub const at90can64 = Cpu{
348 pub const at90can64 = CpuModel{
348349 .name = "at90can64",
349350 .llvm_name = "at90can64",
350351 .features = featureSet(&[_]Feature{
351352 .avr5,
352353 }),
353354 };
354 pub const at90pwm1 = Cpu{
355 pub const at90pwm1 = CpuModel{
355356 .name = "at90pwm1",
356357 .llvm_name = "at90pwm1",
357358 .features = featureSet(&[_]Feature{
358359 .avr4,
359360 }),
360361 };
361 pub const at90pwm161 = Cpu{
362 pub const at90pwm161 = CpuModel{
362363 .name = "at90pwm161",
363364 .llvm_name = "at90pwm161",
364365 .features = featureSet(&[_]Feature{
365366 .avr5,
366367 }),
367368 };
368 pub const at90pwm2 = Cpu{
369 pub const at90pwm2 = CpuModel{
369370 .name = "at90pwm2",
370371 .llvm_name = "at90pwm2",
371372 .features = featureSet(&[_]Feature{
372373 .avr4,
373374 }),
374375 };
375 pub const at90pwm216 = Cpu{
376 pub const at90pwm216 = CpuModel{
376377 .name = "at90pwm216",
377378 .llvm_name = "at90pwm216",
378379 .features = featureSet(&[_]Feature{
379380 .avr5,
380381 }),
381382 };
382 pub const at90pwm2b = Cpu{
383 pub const at90pwm2b = CpuModel{
383384 .name = "at90pwm2b",
384385 .llvm_name = "at90pwm2b",
385386 .features = featureSet(&[_]Feature{
386387 .avr4,
387388 }),
388389 };
389 pub const at90pwm3 = Cpu{
390 pub const at90pwm3 = CpuModel{
390391 .name = "at90pwm3",
391392 .llvm_name = "at90pwm3",
392393 .features = featureSet(&[_]Feature{
393394 .avr4,
394395 }),
395396 };
396 pub const at90pwm316 = Cpu{
397 pub const at90pwm316 = CpuModel{
397398 .name = "at90pwm316",
398399 .llvm_name = "at90pwm316",
399400 .features = featureSet(&[_]Feature{
400401 .avr5,
401402 }),
402403 };
403 pub const at90pwm3b = Cpu{
404 pub const at90pwm3b = CpuModel{
404405 .name = "at90pwm3b",
405406 .llvm_name = "at90pwm3b",
406407 .features = featureSet(&[_]Feature{
407408 .avr4,
408409 }),
409410 };
410 pub const at90pwm81 = Cpu{
411 pub const at90pwm81 = CpuModel{
411412 .name = "at90pwm81",
412413 .llvm_name = "at90pwm81",
413414 .features = featureSet(&[_]Feature{
414415 .avr4,
415416 }),
416417 };
417 pub const at90s1200 = Cpu{
418 pub const at90s1200 = CpuModel{
418419 .name = "at90s1200",
419420 .llvm_name = "at90s1200",
420421 .features = featureSet(&[_]Feature{
421422 .avr0,
422423 }),
423424 };
424 pub const at90s2313 = Cpu{
425 pub const at90s2313 = CpuModel{
425426 .name = "at90s2313",
426427 .llvm_name = "at90s2313",
427428 .features = featureSet(&[_]Feature{
428429 .avr2,
429430 }),
430431 };
431 pub const at90s2323 = Cpu{
432 pub const at90s2323 = CpuModel{
432433 .name = "at90s2323",
433434 .llvm_name = "at90s2323",
434435 .features = featureSet(&[_]Feature{
435436 .avr2,
436437 }),
437438 };
438 pub const at90s2333 = Cpu{
439 pub const at90s2333 = CpuModel{
439440 .name = "at90s2333",
440441 .llvm_name = "at90s2333",
441442 .features = featureSet(&[_]Feature{
442443 .avr2,
443444 }),
444445 };
445 pub const at90s2343 = Cpu{
446 pub const at90s2343 = CpuModel{
446447 .name = "at90s2343",
447448 .llvm_name = "at90s2343",
448449 .features = featureSet(&[_]Feature{
449450 .avr2,
450451 }),
451452 };
452 pub const at90s4414 = Cpu{
453 pub const at90s4414 = CpuModel{
453454 .name = "at90s4414",
454455 .llvm_name = "at90s4414",
455456 .features = featureSet(&[_]Feature{
456457 .avr2,
457458 }),
458459 };
459 pub const at90s4433 = Cpu{
460 pub const at90s4433 = CpuModel{
460461 .name = "at90s4433",
461462 .llvm_name = "at90s4433",
462463 .features = featureSet(&[_]Feature{
463464 .avr2,
464465 }),
465466 };
466 pub const at90s4434 = Cpu{
467 pub const at90s4434 = CpuModel{
467468 .name = "at90s4434",
468469 .llvm_name = "at90s4434",
469470 .features = featureSet(&[_]Feature{
470471 .avr2,
471472 }),
472473 };
473 pub const at90s8515 = Cpu{
474 pub const at90s8515 = CpuModel{
474475 .name = "at90s8515",
475476 .llvm_name = "at90s8515",
476477 .features = featureSet(&[_]Feature{
477478 .avr2,
478479 }),
479480 };
480 pub const at90s8535 = Cpu{
481 pub const at90s8535 = CpuModel{
481482 .name = "at90s8535",
482483 .llvm_name = "at90s8535",
483484 .features = featureSet(&[_]Feature{
484485 .avr2,
485486 }),
486487 };
487 pub const at90scr100 = Cpu{
488 pub const at90scr100 = CpuModel{
488489 .name = "at90scr100",
489490 .llvm_name = "at90scr100",
490491 .features = featureSet(&[_]Feature{
491492 .avr5,
492493 }),
493494 };
494 pub const at90usb1286 = Cpu{
495 pub const at90usb1286 = CpuModel{
495496 .name = "at90usb1286",
496497 .llvm_name = "at90usb1286",
497498 .features = featureSet(&[_]Feature{
498499 .avr51,
499500 }),
500501 };
501 pub const at90usb1287 = Cpu{
502 pub const at90usb1287 = CpuModel{
502503 .name = "at90usb1287",
503504 .llvm_name = "at90usb1287",
504505 .features = featureSet(&[_]Feature{
505506 .avr51,
506507 }),
507508 };
508 pub const at90usb162 = Cpu{
509 pub const at90usb162 = CpuModel{
509510 .name = "at90usb162",
510511 .llvm_name = "at90usb162",
511512 .features = featureSet(&[_]Feature{
512513 .avr35,
513514 }),
514515 };
515 pub const at90usb646 = Cpu{
516 pub const at90usb646 = CpuModel{
516517 .name = "at90usb646",
517518 .llvm_name = "at90usb646",
518519 .features = featureSet(&[_]Feature{
519520 .avr5,
520521 }),
521522 };
522 pub const at90usb647 = Cpu{
523 pub const at90usb647 = CpuModel{
523524 .name = "at90usb647",
524525 .llvm_name = "at90usb647",
525526 .features = featureSet(&[_]Feature{
526527 .avr5,
527528 }),
528529 };
529 pub const at90usb82 = Cpu{
530 pub const at90usb82 = CpuModel{
530531 .name = "at90usb82",
531532 .llvm_name = "at90usb82",
532533 .features = featureSet(&[_]Feature{
533534 .avr35,
534535 }),
535536 };
536 pub const at94k = Cpu{
537 pub const at94k = CpuModel{
537538 .name = "at94k",
538539 .llvm_name = "at94k",
539540 .features = featureSet(&[_]Feature{
......@@ -543,133 +544,133 @@ pub const cpu = struct {
543544 .mul,
544545 }),
545546 };
546 pub const ata5272 = Cpu{
547 pub const ata5272 = CpuModel{
547548 .name = "ata5272",
548549 .llvm_name = "ata5272",
549550 .features = featureSet(&[_]Feature{
550551 .avr25,
551552 }),
552553 };
553 pub const ata5505 = Cpu{
554 pub const ata5505 = CpuModel{
554555 .name = "ata5505",
555556 .llvm_name = "ata5505",
556557 .features = featureSet(&[_]Feature{
557558 .avr35,
558559 }),
559560 };
560 pub const ata5790 = Cpu{
561 pub const ata5790 = CpuModel{
561562 .name = "ata5790",
562563 .llvm_name = "ata5790",
563564 .features = featureSet(&[_]Feature{
564565 .avr5,
565566 }),
566567 };
567 pub const ata5795 = Cpu{
568 pub const ata5795 = CpuModel{
568569 .name = "ata5795",
569570 .llvm_name = "ata5795",
570571 .features = featureSet(&[_]Feature{
571572 .avr5,
572573 }),
573574 };
574 pub const ata6285 = Cpu{
575 pub const ata6285 = CpuModel{
575576 .name = "ata6285",
576577 .llvm_name = "ata6285",
577578 .features = featureSet(&[_]Feature{
578579 .avr4,
579580 }),
580581 };
581 pub const ata6286 = Cpu{
582 pub const ata6286 = CpuModel{
582583 .name = "ata6286",
583584 .llvm_name = "ata6286",
584585 .features = featureSet(&[_]Feature{
585586 .avr4,
586587 }),
587588 };
588 pub const ata6289 = Cpu{
589 pub const ata6289 = CpuModel{
589590 .name = "ata6289",
590591 .llvm_name = "ata6289",
591592 .features = featureSet(&[_]Feature{
592593 .avr4,
593594 }),
594595 };
595 pub const atmega103 = Cpu{
596 pub const atmega103 = CpuModel{
596597 .name = "atmega103",
597598 .llvm_name = "atmega103",
598599 .features = featureSet(&[_]Feature{
599600 .avr31,
600601 }),
601602 };
602 pub const atmega128 = Cpu{
603 pub const atmega128 = CpuModel{
603604 .name = "atmega128",
604605 .llvm_name = "atmega128",
605606 .features = featureSet(&[_]Feature{
606607 .avr51,
607608 }),
608609 };
609 pub const atmega1280 = Cpu{
610 pub const atmega1280 = CpuModel{
610611 .name = "atmega1280",
611612 .llvm_name = "atmega1280",
612613 .features = featureSet(&[_]Feature{
613614 .avr51,
614615 }),
615616 };
616 pub const atmega1281 = Cpu{
617 pub const atmega1281 = CpuModel{
617618 .name = "atmega1281",
618619 .llvm_name = "atmega1281",
619620 .features = featureSet(&[_]Feature{
620621 .avr51,
621622 }),
622623 };
623 pub const atmega1284 = Cpu{
624 pub const atmega1284 = CpuModel{
624625 .name = "atmega1284",
625626 .llvm_name = "atmega1284",
626627 .features = featureSet(&[_]Feature{
627628 .avr51,
628629 }),
629630 };
630 pub const atmega1284p = Cpu{
631 pub const atmega1284p = CpuModel{
631632 .name = "atmega1284p",
632633 .llvm_name = "atmega1284p",
633634 .features = featureSet(&[_]Feature{
634635 .avr51,
635636 }),
636637 };
637 pub const atmega1284rfr2 = Cpu{
638 pub const atmega1284rfr2 = CpuModel{
638639 .name = "atmega1284rfr2",
639640 .llvm_name = "atmega1284rfr2",
640641 .features = featureSet(&[_]Feature{
641642 .avr51,
642643 }),
643644 };
644 pub const atmega128a = Cpu{
645 pub const atmega128a = CpuModel{
645646 .name = "atmega128a",
646647 .llvm_name = "atmega128a",
647648 .features = featureSet(&[_]Feature{
648649 .avr51,
649650 }),
650651 };
651 pub const atmega128rfa1 = Cpu{
652 pub const atmega128rfa1 = CpuModel{
652653 .name = "atmega128rfa1",
653654 .llvm_name = "atmega128rfa1",
654655 .features = featureSet(&[_]Feature{
655656 .avr51,
656657 }),
657658 };
658 pub const atmega128rfr2 = Cpu{
659 pub const atmega128rfr2 = CpuModel{
659660 .name = "atmega128rfr2",
660661 .llvm_name = "atmega128rfr2",
661662 .features = featureSet(&[_]Feature{
662663 .avr51,
663664 }),
664665 };
665 pub const atmega16 = Cpu{
666 pub const atmega16 = CpuModel{
666667 .name = "atmega16",
667668 .llvm_name = "atmega16",
668669 .features = featureSet(&[_]Feature{
669670 .avr5,
670671 }),
671672 };
672 pub const atmega161 = Cpu{
673 pub const atmega161 = CpuModel{
673674 .name = "atmega161",
674675 .llvm_name = "atmega161",
675676 .features = featureSet(&[_]Feature{
......@@ -680,14 +681,14 @@ pub const cpu = struct {
680681 .spm,
681682 }),
682683 };
683 pub const atmega162 = Cpu{
684 pub const atmega162 = CpuModel{
684685 .name = "atmega162",
685686 .llvm_name = "atmega162",
686687 .features = featureSet(&[_]Feature{
687688 .avr5,
688689 }),
689690 };
690 pub const atmega163 = Cpu{
691 pub const atmega163 = CpuModel{
691692 .name = "atmega163",
692693 .llvm_name = "atmega163",
693694 .features = featureSet(&[_]Feature{
......@@ -698,623 +699,623 @@ pub const cpu = struct {
698699 .spm,
699700 }),
700701 };
701 pub const atmega164a = Cpu{
702 pub const atmega164a = CpuModel{
702703 .name = "atmega164a",
703704 .llvm_name = "atmega164a",
704705 .features = featureSet(&[_]Feature{
705706 .avr5,
706707 }),
707708 };
708 pub const atmega164p = Cpu{
709 pub const atmega164p = CpuModel{
709710 .name = "atmega164p",
710711 .llvm_name = "atmega164p",
711712 .features = featureSet(&[_]Feature{
712713 .avr5,
713714 }),
714715 };
715 pub const atmega164pa = Cpu{
716 pub const atmega164pa = CpuModel{
716717 .name = "atmega164pa",
717718 .llvm_name = "atmega164pa",
718719 .features = featureSet(&[_]Feature{
719720 .avr5,
720721 }),
721722 };
722 pub const atmega165 = Cpu{
723 pub const atmega165 = CpuModel{
723724 .name = "atmega165",
724725 .llvm_name = "atmega165",
725726 .features = featureSet(&[_]Feature{
726727 .avr5,
727728 }),
728729 };
729 pub const atmega165a = Cpu{
730 pub const atmega165a = CpuModel{
730731 .name = "atmega165a",
731732 .llvm_name = "atmega165a",
732733 .features = featureSet(&[_]Feature{
733734 .avr5,
734735 }),
735736 };
736 pub const atmega165p = Cpu{
737 pub const atmega165p = CpuModel{
737738 .name = "atmega165p",
738739 .llvm_name = "atmega165p",
739740 .features = featureSet(&[_]Feature{
740741 .avr5,
741742 }),
742743 };
743 pub const atmega165pa = Cpu{
744 pub const atmega165pa = CpuModel{
744745 .name = "atmega165pa",
745746 .llvm_name = "atmega165pa",
746747 .features = featureSet(&[_]Feature{
747748 .avr5,
748749 }),
749750 };
750 pub const atmega168 = Cpu{
751 pub const atmega168 = CpuModel{
751752 .name = "atmega168",
752753 .llvm_name = "atmega168",
753754 .features = featureSet(&[_]Feature{
754755 .avr5,
755756 }),
756757 };
757 pub const atmega168a = Cpu{
758 pub const atmega168a = CpuModel{
758759 .name = "atmega168a",
759760 .llvm_name = "atmega168a",
760761 .features = featureSet(&[_]Feature{
761762 .avr5,
762763 }),
763764 };
764 pub const atmega168p = Cpu{
765 pub const atmega168p = CpuModel{
765766 .name = "atmega168p",
766767 .llvm_name = "atmega168p",
767768 .features = featureSet(&[_]Feature{
768769 .avr5,
769770 }),
770771 };
771 pub const atmega168pa = Cpu{
772 pub const atmega168pa = CpuModel{
772773 .name = "atmega168pa",
773774 .llvm_name = "atmega168pa",
774775 .features = featureSet(&[_]Feature{
775776 .avr5,
776777 }),
777778 };
778 pub const atmega169 = Cpu{
779 pub const atmega169 = CpuModel{
779780 .name = "atmega169",
780781 .llvm_name = "atmega169",
781782 .features = featureSet(&[_]Feature{
782783 .avr5,
783784 }),
784785 };
785 pub const atmega169a = Cpu{
786 pub const atmega169a = CpuModel{
786787 .name = "atmega169a",
787788 .llvm_name = "atmega169a",
788789 .features = featureSet(&[_]Feature{
789790 .avr5,
790791 }),
791792 };
792 pub const atmega169p = Cpu{
793 pub const atmega169p = CpuModel{
793794 .name = "atmega169p",
794795 .llvm_name = "atmega169p",
795796 .features = featureSet(&[_]Feature{
796797 .avr5,
797798 }),
798799 };
799 pub const atmega169pa = Cpu{
800 pub const atmega169pa = CpuModel{
800801 .name = "atmega169pa",
801802 .llvm_name = "atmega169pa",
802803 .features = featureSet(&[_]Feature{
803804 .avr5,
804805 }),
805806 };
806 pub const atmega16a = Cpu{
807 pub const atmega16a = CpuModel{
807808 .name = "atmega16a",
808809 .llvm_name = "atmega16a",
809810 .features = featureSet(&[_]Feature{
810811 .avr5,
811812 }),
812813 };
813 pub const atmega16hva = Cpu{
814 pub const atmega16hva = CpuModel{
814815 .name = "atmega16hva",
815816 .llvm_name = "atmega16hva",
816817 .features = featureSet(&[_]Feature{
817818 .avr5,
818819 }),
819820 };
820 pub const atmega16hva2 = Cpu{
821 pub const atmega16hva2 = CpuModel{
821822 .name = "atmega16hva2",
822823 .llvm_name = "atmega16hva2",
823824 .features = featureSet(&[_]Feature{
824825 .avr5,
825826 }),
826827 };
827 pub const atmega16hvb = Cpu{
828 pub const atmega16hvb = CpuModel{
828829 .name = "atmega16hvb",
829830 .llvm_name = "atmega16hvb",
830831 .features = featureSet(&[_]Feature{
831832 .avr5,
832833 }),
833834 };
834 pub const atmega16hvbrevb = Cpu{
835 pub const atmega16hvbrevb = CpuModel{
835836 .name = "atmega16hvbrevb",
836837 .llvm_name = "atmega16hvbrevb",
837838 .features = featureSet(&[_]Feature{
838839 .avr5,
839840 }),
840841 };
841 pub const atmega16m1 = Cpu{
842 pub const atmega16m1 = CpuModel{
842843 .name = "atmega16m1",
843844 .llvm_name = "atmega16m1",
844845 .features = featureSet(&[_]Feature{
845846 .avr5,
846847 }),
847848 };
848 pub const atmega16u2 = Cpu{
849 pub const atmega16u2 = CpuModel{
849850 .name = "atmega16u2",
850851 .llvm_name = "atmega16u2",
851852 .features = featureSet(&[_]Feature{
852853 .avr35,
853854 }),
854855 };
855 pub const atmega16u4 = Cpu{
856 pub const atmega16u4 = CpuModel{
856857 .name = "atmega16u4",
857858 .llvm_name = "atmega16u4",
858859 .features = featureSet(&[_]Feature{
859860 .avr5,
860861 }),
861862 };
862 pub const atmega2560 = Cpu{
863 pub const atmega2560 = CpuModel{
863864 .name = "atmega2560",
864865 .llvm_name = "atmega2560",
865866 .features = featureSet(&[_]Feature{
866867 .avr6,
867868 }),
868869 };
869 pub const atmega2561 = Cpu{
870 pub const atmega2561 = CpuModel{
870871 .name = "atmega2561",
871872 .llvm_name = "atmega2561",
872873 .features = featureSet(&[_]Feature{
873874 .avr6,
874875 }),
875876 };
876 pub const atmega2564rfr2 = Cpu{
877 pub const atmega2564rfr2 = CpuModel{
877878 .name = "atmega2564rfr2",
878879 .llvm_name = "atmega2564rfr2",
879880 .features = featureSet(&[_]Feature{
880881 .avr6,
881882 }),
882883 };
883 pub const atmega256rfr2 = Cpu{
884 pub const atmega256rfr2 = CpuModel{
884885 .name = "atmega256rfr2",
885886 .llvm_name = "atmega256rfr2",
886887 .features = featureSet(&[_]Feature{
887888 .avr6,
888889 }),
889890 };
890 pub const atmega32 = Cpu{
891 pub const atmega32 = CpuModel{
891892 .name = "atmega32",
892893 .llvm_name = "atmega32",
893894 .features = featureSet(&[_]Feature{
894895 .avr5,
895896 }),
896897 };
897 pub const atmega323 = Cpu{
898 pub const atmega323 = CpuModel{
898899 .name = "atmega323",
899900 .llvm_name = "atmega323",
900901 .features = featureSet(&[_]Feature{
901902 .avr5,
902903 }),
903904 };
904 pub const atmega324a = Cpu{
905 pub const atmega324a = CpuModel{
905906 .name = "atmega324a",
906907 .llvm_name = "atmega324a",
907908 .features = featureSet(&[_]Feature{
908909 .avr5,
909910 }),
910911 };
911 pub const atmega324p = Cpu{
912 pub const atmega324p = CpuModel{
912913 .name = "atmega324p",
913914 .llvm_name = "atmega324p",
914915 .features = featureSet(&[_]Feature{
915916 .avr5,
916917 }),
917918 };
918 pub const atmega324pa = Cpu{
919 pub const atmega324pa = CpuModel{
919920 .name = "atmega324pa",
920921 .llvm_name = "atmega324pa",
921922 .features = featureSet(&[_]Feature{
922923 .avr5,
923924 }),
924925 };
925 pub const atmega325 = Cpu{
926 pub const atmega325 = CpuModel{
926927 .name = "atmega325",
927928 .llvm_name = "atmega325",
928929 .features = featureSet(&[_]Feature{
929930 .avr5,
930931 }),
931932 };
932 pub const atmega3250 = Cpu{
933 pub const atmega3250 = CpuModel{
933934 .name = "atmega3250",
934935 .llvm_name = "atmega3250",
935936 .features = featureSet(&[_]Feature{
936937 .avr5,
937938 }),
938939 };
939 pub const atmega3250a = Cpu{
940 pub const atmega3250a = CpuModel{
940941 .name = "atmega3250a",
941942 .llvm_name = "atmega3250a",
942943 .features = featureSet(&[_]Feature{
943944 .avr5,
944945 }),
945946 };
946 pub const atmega3250p = Cpu{
947 pub const atmega3250p = CpuModel{
947948 .name = "atmega3250p",
948949 .llvm_name = "atmega3250p",
949950 .features = featureSet(&[_]Feature{
950951 .avr5,
951952 }),
952953 };
953 pub const atmega3250pa = Cpu{
954 pub const atmega3250pa = CpuModel{
954955 .name = "atmega3250pa",
955956 .llvm_name = "atmega3250pa",
956957 .features = featureSet(&[_]Feature{
957958 .avr5,
958959 }),
959960 };
960 pub const atmega325a = Cpu{
961 pub const atmega325a = CpuModel{
961962 .name = "atmega325a",
962963 .llvm_name = "atmega325a",
963964 .features = featureSet(&[_]Feature{
964965 .avr5,
965966 }),
966967 };
967 pub const atmega325p = Cpu{
968 pub const atmega325p = CpuModel{
968969 .name = "atmega325p",
969970 .llvm_name = "atmega325p",
970971 .features = featureSet(&[_]Feature{
971972 .avr5,
972973 }),
973974 };
974 pub const atmega325pa = Cpu{
975 pub const atmega325pa = CpuModel{
975976 .name = "atmega325pa",
976977 .llvm_name = "atmega325pa",
977978 .features = featureSet(&[_]Feature{
978979 .avr5,
979980 }),
980981 };
981 pub const atmega328 = Cpu{
982 pub const atmega328 = CpuModel{
982983 .name = "atmega328",
983984 .llvm_name = "atmega328",
984985 .features = featureSet(&[_]Feature{
985986 .avr5,
986987 }),
987988 };
988 pub const atmega328p = Cpu{
989 pub const atmega328p = CpuModel{
989990 .name = "atmega328p",
990991 .llvm_name = "atmega328p",
991992 .features = featureSet(&[_]Feature{
992993 .avr5,
993994 }),
994995 };
995 pub const atmega329 = Cpu{
996 pub const atmega329 = CpuModel{
996997 .name = "atmega329",
997998 .llvm_name = "atmega329",
998999 .features = featureSet(&[_]Feature{
9991000 .avr5,
10001001 }),
10011002 };
1002 pub const atmega3290 = Cpu{
1003 pub const atmega3290 = CpuModel{
10031004 .name = "atmega3290",
10041005 .llvm_name = "atmega3290",
10051006 .features = featureSet(&[_]Feature{
10061007 .avr5,
10071008 }),
10081009 };
1009 pub const atmega3290a = Cpu{
1010 pub const atmega3290a = CpuModel{
10101011 .name = "atmega3290a",
10111012 .llvm_name = "atmega3290a",
10121013 .features = featureSet(&[_]Feature{
10131014 .avr5,
10141015 }),
10151016 };
1016 pub const atmega3290p = Cpu{
1017 pub const atmega3290p = CpuModel{
10171018 .name = "atmega3290p",
10181019 .llvm_name = "atmega3290p",
10191020 .features = featureSet(&[_]Feature{
10201021 .avr5,
10211022 }),
10221023 };
1023 pub const atmega3290pa = Cpu{
1024 pub const atmega3290pa = CpuModel{
10241025 .name = "atmega3290pa",
10251026 .llvm_name = "atmega3290pa",
10261027 .features = featureSet(&[_]Feature{
10271028 .avr5,
10281029 }),
10291030 };
1030 pub const atmega329a = Cpu{
1031 pub const atmega329a = CpuModel{
10311032 .name = "atmega329a",
10321033 .llvm_name = "atmega329a",
10331034 .features = featureSet(&[_]Feature{
10341035 .avr5,
10351036 }),
10361037 };
1037 pub const atmega329p = Cpu{
1038 pub const atmega329p = CpuModel{
10381039 .name = "atmega329p",
10391040 .llvm_name = "atmega329p",
10401041 .features = featureSet(&[_]Feature{
10411042 .avr5,
10421043 }),
10431044 };
1044 pub const atmega329pa = Cpu{
1045 pub const atmega329pa = CpuModel{
10451046 .name = "atmega329pa",
10461047 .llvm_name = "atmega329pa",
10471048 .features = featureSet(&[_]Feature{
10481049 .avr5,
10491050 }),
10501051 };
1051 pub const atmega32a = Cpu{
1052 pub const atmega32a = CpuModel{
10521053 .name = "atmega32a",
10531054 .llvm_name = "atmega32a",
10541055 .features = featureSet(&[_]Feature{
10551056 .avr5,
10561057 }),
10571058 };
1058 pub const atmega32c1 = Cpu{
1059 pub const atmega32c1 = CpuModel{
10591060 .name = "atmega32c1",
10601061 .llvm_name = "atmega32c1",
10611062 .features = featureSet(&[_]Feature{
10621063 .avr5,
10631064 }),
10641065 };
1065 pub const atmega32hvb = Cpu{
1066 pub const atmega32hvb = CpuModel{
10661067 .name = "atmega32hvb",
10671068 .llvm_name = "atmega32hvb",
10681069 .features = featureSet(&[_]Feature{
10691070 .avr5,
10701071 }),
10711072 };
1072 pub const atmega32hvbrevb = Cpu{
1073 pub const atmega32hvbrevb = CpuModel{
10731074 .name = "atmega32hvbrevb",
10741075 .llvm_name = "atmega32hvbrevb",
10751076 .features = featureSet(&[_]Feature{
10761077 .avr5,
10771078 }),
10781079 };
1079 pub const atmega32m1 = Cpu{
1080 pub const atmega32m1 = CpuModel{
10801081 .name = "atmega32m1",
10811082 .llvm_name = "atmega32m1",
10821083 .features = featureSet(&[_]Feature{
10831084 .avr5,
10841085 }),
10851086 };
1086 pub const atmega32u2 = Cpu{
1087 pub const atmega32u2 = CpuModel{
10871088 .name = "atmega32u2",
10881089 .llvm_name = "atmega32u2",
10891090 .features = featureSet(&[_]Feature{
10901091 .avr35,
10911092 }),
10921093 };
1093 pub const atmega32u4 = Cpu{
1094 pub const atmega32u4 = CpuModel{
10941095 .name = "atmega32u4",
10951096 .llvm_name = "atmega32u4",
10961097 .features = featureSet(&[_]Feature{
10971098 .avr5,
10981099 }),
10991100 };
1100 pub const atmega32u6 = Cpu{
1101 pub const atmega32u6 = CpuModel{
11011102 .name = "atmega32u6",
11021103 .llvm_name = "atmega32u6",
11031104 .features = featureSet(&[_]Feature{
11041105 .avr5,
11051106 }),
11061107 };
1107 pub const atmega406 = Cpu{
1108 pub const atmega406 = CpuModel{
11081109 .name = "atmega406",
11091110 .llvm_name = "atmega406",
11101111 .features = featureSet(&[_]Feature{
11111112 .avr5,
11121113 }),
11131114 };
1114 pub const atmega48 = Cpu{
1115 pub const atmega48 = CpuModel{
11151116 .name = "atmega48",
11161117 .llvm_name = "atmega48",
11171118 .features = featureSet(&[_]Feature{
11181119 .avr4,
11191120 }),
11201121 };
1121 pub const atmega48a = Cpu{
1122 pub const atmega48a = CpuModel{
11221123 .name = "atmega48a",
11231124 .llvm_name = "atmega48a",
11241125 .features = featureSet(&[_]Feature{
11251126 .avr4,
11261127 }),
11271128 };
1128 pub const atmega48p = Cpu{
1129 pub const atmega48p = CpuModel{
11291130 .name = "atmega48p",
11301131 .llvm_name = "atmega48p",
11311132 .features = featureSet(&[_]Feature{
11321133 .avr4,
11331134 }),
11341135 };
1135 pub const atmega48pa = Cpu{
1136 pub const atmega48pa = CpuModel{
11361137 .name = "atmega48pa",
11371138 .llvm_name = "atmega48pa",
11381139 .features = featureSet(&[_]Feature{
11391140 .avr4,
11401141 }),
11411142 };
1142 pub const atmega64 = Cpu{
1143 pub const atmega64 = CpuModel{
11431144 .name = "atmega64",
11441145 .llvm_name = "atmega64",
11451146 .features = featureSet(&[_]Feature{
11461147 .avr5,
11471148 }),
11481149 };
1149 pub const atmega640 = Cpu{
1150 pub const atmega640 = CpuModel{
11501151 .name = "atmega640",
11511152 .llvm_name = "atmega640",
11521153 .features = featureSet(&[_]Feature{
11531154 .avr5,
11541155 }),
11551156 };
1156 pub const atmega644 = Cpu{
1157 pub const atmega644 = CpuModel{
11571158 .name = "atmega644",
11581159 .llvm_name = "atmega644",
11591160 .features = featureSet(&[_]Feature{
11601161 .avr5,
11611162 }),
11621163 };
1163 pub const atmega644a = Cpu{
1164 pub const atmega644a = CpuModel{
11641165 .name = "atmega644a",
11651166 .llvm_name = "atmega644a",
11661167 .features = featureSet(&[_]Feature{
11671168 .avr5,
11681169 }),
11691170 };
1170 pub const atmega644p = Cpu{
1171 pub const atmega644p = CpuModel{
11711172 .name = "atmega644p",
11721173 .llvm_name = "atmega644p",
11731174 .features = featureSet(&[_]Feature{
11741175 .avr5,
11751176 }),
11761177 };
1177 pub const atmega644pa = Cpu{
1178 pub const atmega644pa = CpuModel{
11781179 .name = "atmega644pa",
11791180 .llvm_name = "atmega644pa",
11801181 .features = featureSet(&[_]Feature{
11811182 .avr5,
11821183 }),
11831184 };
1184 pub const atmega644rfr2 = Cpu{
1185 pub const atmega644rfr2 = CpuModel{
11851186 .name = "atmega644rfr2",
11861187 .llvm_name = "atmega644rfr2",
11871188 .features = featureSet(&[_]Feature{
11881189 .avr5,
11891190 }),
11901191 };
1191 pub const atmega645 = Cpu{
1192 pub const atmega645 = CpuModel{
11921193 .name = "atmega645",
11931194 .llvm_name = "atmega645",
11941195 .features = featureSet(&[_]Feature{
11951196 .avr5,
11961197 }),
11971198 };
1198 pub const atmega6450 = Cpu{
1199 pub const atmega6450 = CpuModel{
11991200 .name = "atmega6450",
12001201 .llvm_name = "atmega6450",
12011202 .features = featureSet(&[_]Feature{
12021203 .avr5,
12031204 }),
12041205 };
1205 pub const atmega6450a = Cpu{
1206 pub const atmega6450a = CpuModel{
12061207 .name = "atmega6450a",
12071208 .llvm_name = "atmega6450a",
12081209 .features = featureSet(&[_]Feature{
12091210 .avr5,
12101211 }),
12111212 };
1212 pub const atmega6450p = Cpu{
1213 pub const atmega6450p = CpuModel{
12131214 .name = "atmega6450p",
12141215 .llvm_name = "atmega6450p",
12151216 .features = featureSet(&[_]Feature{
12161217 .avr5,
12171218 }),
12181219 };
1219 pub const atmega645a = Cpu{
1220 pub const atmega645a = CpuModel{
12201221 .name = "atmega645a",
12211222 .llvm_name = "atmega645a",
12221223 .features = featureSet(&[_]Feature{
12231224 .avr5,
12241225 }),
12251226 };
1226 pub const atmega645p = Cpu{
1227 pub const atmega645p = CpuModel{
12271228 .name = "atmega645p",
12281229 .llvm_name = "atmega645p",
12291230 .features = featureSet(&[_]Feature{
12301231 .avr5,
12311232 }),
12321233 };
1233 pub const atmega649 = Cpu{
1234 pub const atmega649 = CpuModel{
12341235 .name = "atmega649",
12351236 .llvm_name = "atmega649",
12361237 .features = featureSet(&[_]Feature{
12371238 .avr5,
12381239 }),
12391240 };
1240 pub const atmega6490 = Cpu{
1241 pub const atmega6490 = CpuModel{
12411242 .name = "atmega6490",
12421243 .llvm_name = "atmega6490",
12431244 .features = featureSet(&[_]Feature{
12441245 .avr5,
12451246 }),
12461247 };
1247 pub const atmega6490a = Cpu{
1248 pub const atmega6490a = CpuModel{
12481249 .name = "atmega6490a",
12491250 .llvm_name = "atmega6490a",
12501251 .features = featureSet(&[_]Feature{
12511252 .avr5,
12521253 }),
12531254 };
1254 pub const atmega6490p = Cpu{
1255 pub const atmega6490p = CpuModel{
12551256 .name = "atmega6490p",
12561257 .llvm_name = "atmega6490p",
12571258 .features = featureSet(&[_]Feature{
12581259 .avr5,
12591260 }),
12601261 };
1261 pub const atmega649a = Cpu{
1262 pub const atmega649a = CpuModel{
12621263 .name = "atmega649a",
12631264 .llvm_name = "atmega649a",
12641265 .features = featureSet(&[_]Feature{
12651266 .avr5,
12661267 }),
12671268 };
1268 pub const atmega649p = Cpu{
1269 pub const atmega649p = CpuModel{
12691270 .name = "atmega649p",
12701271 .llvm_name = "atmega649p",
12711272 .features = featureSet(&[_]Feature{
12721273 .avr5,
12731274 }),
12741275 };
1275 pub const atmega64a = Cpu{
1276 pub const atmega64a = CpuModel{
12761277 .name = "atmega64a",
12771278 .llvm_name = "atmega64a",
12781279 .features = featureSet(&[_]Feature{
12791280 .avr5,
12801281 }),
12811282 };
1282 pub const atmega64c1 = Cpu{
1283 pub const atmega64c1 = CpuModel{
12831284 .name = "atmega64c1",
12841285 .llvm_name = "atmega64c1",
12851286 .features = featureSet(&[_]Feature{
12861287 .avr5,
12871288 }),
12881289 };
1289 pub const atmega64hve = Cpu{
1290 pub const atmega64hve = CpuModel{
12901291 .name = "atmega64hve",
12911292 .llvm_name = "atmega64hve",
12921293 .features = featureSet(&[_]Feature{
12931294 .avr5,
12941295 }),
12951296 };
1296 pub const atmega64m1 = Cpu{
1297 pub const atmega64m1 = CpuModel{
12971298 .name = "atmega64m1",
12981299 .llvm_name = "atmega64m1",
12991300 .features = featureSet(&[_]Feature{
13001301 .avr5,
13011302 }),
13021303 };
1303 pub const atmega64rfr2 = Cpu{
1304 pub const atmega64rfr2 = CpuModel{
13041305 .name = "atmega64rfr2",
13051306 .llvm_name = "atmega64rfr2",
13061307 .features = featureSet(&[_]Feature{
13071308 .avr5,
13081309 }),
13091310 };
1310 pub const atmega8 = Cpu{
1311 pub const atmega8 = CpuModel{
13111312 .name = "atmega8",
13121313 .llvm_name = "atmega8",
13131314 .features = featureSet(&[_]Feature{
13141315 .avr4,
13151316 }),
13161317 };
1317 pub const atmega8515 = Cpu{
1318 pub const atmega8515 = CpuModel{
13181319 .name = "atmega8515",
13191320 .llvm_name = "atmega8515",
13201321 .features = featureSet(&[_]Feature{
......@@ -1325,7 +1326,7 @@ pub const cpu = struct {
13251326 .spm,
13261327 }),
13271328 };
1328 pub const atmega8535 = Cpu{
1329 pub const atmega8535 = CpuModel{
13291330 .name = "atmega8535",
13301331 .llvm_name = "atmega8535",
13311332 .features = featureSet(&[_]Feature{
......@@ -1336,175 +1337,175 @@ pub const cpu = struct {
13361337 .spm,
13371338 }),
13381339 };
1339 pub const atmega88 = Cpu{
1340 pub const atmega88 = CpuModel{
13401341 .name = "atmega88",
13411342 .llvm_name = "atmega88",
13421343 .features = featureSet(&[_]Feature{
13431344 .avr4,
13441345 }),
13451346 };
1346 pub const atmega88a = Cpu{
1347 pub const atmega88a = CpuModel{
13471348 .name = "atmega88a",
13481349 .llvm_name = "atmega88a",
13491350 .features = featureSet(&[_]Feature{
13501351 .avr4,
13511352 }),
13521353 };
1353 pub const atmega88p = Cpu{
1354 pub const atmega88p = CpuModel{
13541355 .name = "atmega88p",
13551356 .llvm_name = "atmega88p",
13561357 .features = featureSet(&[_]Feature{
13571358 .avr4,
13581359 }),
13591360 };
1360 pub const atmega88pa = Cpu{
1361 pub const atmega88pa = CpuModel{
13611362 .name = "atmega88pa",
13621363 .llvm_name = "atmega88pa",
13631364 .features = featureSet(&[_]Feature{
13641365 .avr4,
13651366 }),
13661367 };
1367 pub const atmega8a = Cpu{
1368 pub const atmega8a = CpuModel{
13681369 .name = "atmega8a",
13691370 .llvm_name = "atmega8a",
13701371 .features = featureSet(&[_]Feature{
13711372 .avr4,
13721373 }),
13731374 };
1374 pub const atmega8hva = Cpu{
1375 pub const atmega8hva = CpuModel{
13751376 .name = "atmega8hva",
13761377 .llvm_name = "atmega8hva",
13771378 .features = featureSet(&[_]Feature{
13781379 .avr4,
13791380 }),
13801381 };
1381 pub const atmega8u2 = Cpu{
1382 pub const atmega8u2 = CpuModel{
13821383 .name = "atmega8u2",
13831384 .llvm_name = "atmega8u2",
13841385 .features = featureSet(&[_]Feature{
13851386 .avr35,
13861387 }),
13871388 };
1388 pub const attiny10 = Cpu{
1389 pub const attiny10 = CpuModel{
13891390 .name = "attiny10",
13901391 .llvm_name = "attiny10",
13911392 .features = featureSet(&[_]Feature{
13921393 .avrtiny,
13931394 }),
13941395 };
1395 pub const attiny102 = Cpu{
1396 pub const attiny102 = CpuModel{
13961397 .name = "attiny102",
13971398 .llvm_name = "attiny102",
13981399 .features = featureSet(&[_]Feature{
13991400 .avrtiny,
14001401 }),
14011402 };
1402 pub const attiny104 = Cpu{
1403 pub const attiny104 = CpuModel{
14031404 .name = "attiny104",
14041405 .llvm_name = "attiny104",
14051406 .features = featureSet(&[_]Feature{
14061407 .avrtiny,
14071408 }),
14081409 };
1409 pub const attiny11 = Cpu{
1410 pub const attiny11 = CpuModel{
14101411 .name = "attiny11",
14111412 .llvm_name = "attiny11",
14121413 .features = featureSet(&[_]Feature{
14131414 .avr1,
14141415 }),
14151416 };
1416 pub const attiny12 = Cpu{
1417 pub const attiny12 = CpuModel{
14171418 .name = "attiny12",
14181419 .llvm_name = "attiny12",
14191420 .features = featureSet(&[_]Feature{
14201421 .avr1,
14211422 }),
14221423 };
1423 pub const attiny13 = Cpu{
1424 pub const attiny13 = CpuModel{
14241425 .name = "attiny13",
14251426 .llvm_name = "attiny13",
14261427 .features = featureSet(&[_]Feature{
14271428 .avr25,
14281429 }),
14291430 };
1430 pub const attiny13a = Cpu{
1431 pub const attiny13a = CpuModel{
14311432 .name = "attiny13a",
14321433 .llvm_name = "attiny13a",
14331434 .features = featureSet(&[_]Feature{
14341435 .avr25,
14351436 }),
14361437 };
1437 pub const attiny15 = Cpu{
1438 pub const attiny15 = CpuModel{
14381439 .name = "attiny15",
14391440 .llvm_name = "attiny15",
14401441 .features = featureSet(&[_]Feature{
14411442 .avr1,
14421443 }),
14431444 };
1444 pub const attiny1634 = Cpu{
1445 pub const attiny1634 = CpuModel{
14451446 .name = "attiny1634",
14461447 .llvm_name = "attiny1634",
14471448 .features = featureSet(&[_]Feature{
14481449 .avr35,
14491450 }),
14501451 };
1451 pub const attiny167 = Cpu{
1452 pub const attiny167 = CpuModel{
14521453 .name = "attiny167",
14531454 .llvm_name = "attiny167",
14541455 .features = featureSet(&[_]Feature{
14551456 .avr35,
14561457 }),
14571458 };
1458 pub const attiny20 = Cpu{
1459 pub const attiny20 = CpuModel{
14591460 .name = "attiny20",
14601461 .llvm_name = "attiny20",
14611462 .features = featureSet(&[_]Feature{
14621463 .avrtiny,
14631464 }),
14641465 };
1465 pub const attiny22 = Cpu{
1466 pub const attiny22 = CpuModel{
14661467 .name = "attiny22",
14671468 .llvm_name = "attiny22",
14681469 .features = featureSet(&[_]Feature{
14691470 .avr2,
14701471 }),
14711472 };
1472 pub const attiny2313 = Cpu{
1473 pub const attiny2313 = CpuModel{
14731474 .name = "attiny2313",
14741475 .llvm_name = "attiny2313",
14751476 .features = featureSet(&[_]Feature{
14761477 .avr25,
14771478 }),
14781479 };
1479 pub const attiny2313a = Cpu{
1480 pub const attiny2313a = CpuModel{
14801481 .name = "attiny2313a",
14811482 .llvm_name = "attiny2313a",
14821483 .features = featureSet(&[_]Feature{
14831484 .avr25,
14841485 }),
14851486 };
1486 pub const attiny24 = Cpu{
1487 pub const attiny24 = CpuModel{
14871488 .name = "attiny24",
14881489 .llvm_name = "attiny24",
14891490 .features = featureSet(&[_]Feature{
14901491 .avr25,
14911492 }),
14921493 };
1493 pub const attiny24a = Cpu{
1494 pub const attiny24a = CpuModel{
14941495 .name = "attiny24a",
14951496 .llvm_name = "attiny24a",
14961497 .features = featureSet(&[_]Feature{
14971498 .avr25,
14981499 }),
14991500 };
1500 pub const attiny25 = Cpu{
1501 pub const attiny25 = CpuModel{
15011502 .name = "attiny25",
15021503 .llvm_name = "attiny25",
15031504 .features = featureSet(&[_]Feature{
15041505 .avr25,
15051506 }),
15061507 };
1507 pub const attiny26 = Cpu{
1508 pub const attiny26 = CpuModel{
15081509 .name = "attiny26",
15091510 .llvm_name = "attiny26",
15101511 .features = featureSet(&[_]Feature{
......@@ -1512,602 +1513,602 @@ pub const cpu = struct {
15121513 .lpmx,
15131514 }),
15141515 };
1515 pub const attiny261 = Cpu{
1516 pub const attiny261 = CpuModel{
15161517 .name = "attiny261",
15171518 .llvm_name = "attiny261",
15181519 .features = featureSet(&[_]Feature{
15191520 .avr25,
15201521 }),
15211522 };
1522 pub const attiny261a = Cpu{
1523 pub const attiny261a = CpuModel{
15231524 .name = "attiny261a",
15241525 .llvm_name = "attiny261a",
15251526 .features = featureSet(&[_]Feature{
15261527 .avr25,
15271528 }),
15281529 };
1529 pub const attiny28 = Cpu{
1530 pub const attiny28 = CpuModel{
15301531 .name = "attiny28",
15311532 .llvm_name = "attiny28",
15321533 .features = featureSet(&[_]Feature{
15331534 .avr1,
15341535 }),
15351536 };
1536 pub const attiny4 = Cpu{
1537 pub const attiny4 = CpuModel{
15371538 .name = "attiny4",
15381539 .llvm_name = "attiny4",
15391540 .features = featureSet(&[_]Feature{
15401541 .avrtiny,
15411542 }),
15421543 };
1543 pub const attiny40 = Cpu{
1544 pub const attiny40 = CpuModel{
15441545 .name = "attiny40",
15451546 .llvm_name = "attiny40",
15461547 .features = featureSet(&[_]Feature{
15471548 .avrtiny,
15481549 }),
15491550 };
1550 pub const attiny4313 = Cpu{
1551 pub const attiny4313 = CpuModel{
15511552 .name = "attiny4313",
15521553 .llvm_name = "attiny4313",
15531554 .features = featureSet(&[_]Feature{
15541555 .avr25,
15551556 }),
15561557 };
1557 pub const attiny43u = Cpu{
1558 pub const attiny43u = CpuModel{
15581559 .name = "attiny43u",
15591560 .llvm_name = "attiny43u",
15601561 .features = featureSet(&[_]Feature{
15611562 .avr25,
15621563 }),
15631564 };
1564 pub const attiny44 = Cpu{
1565 pub const attiny44 = CpuModel{
15651566 .name = "attiny44",
15661567 .llvm_name = "attiny44",
15671568 .features = featureSet(&[_]Feature{
15681569 .avr25,
15691570 }),
15701571 };
1571 pub const attiny44a = Cpu{
1572 pub const attiny44a = CpuModel{
15721573 .name = "attiny44a",
15731574 .llvm_name = "attiny44a",
15741575 .features = featureSet(&[_]Feature{
15751576 .avr25,
15761577 }),
15771578 };
1578 pub const attiny45 = Cpu{
1579 pub const attiny45 = CpuModel{
15791580 .name = "attiny45",
15801581 .llvm_name = "attiny45",
15811582 .features = featureSet(&[_]Feature{
15821583 .avr25,
15831584 }),
15841585 };
1585 pub const attiny461 = Cpu{
1586 pub const attiny461 = CpuModel{
15861587 .name = "attiny461",
15871588 .llvm_name = "attiny461",
15881589 .features = featureSet(&[_]Feature{
15891590 .avr25,
15901591 }),
15911592 };
1592 pub const attiny461a = Cpu{
1593 pub const attiny461a = CpuModel{
15931594 .name = "attiny461a",
15941595 .llvm_name = "attiny461a",
15951596 .features = featureSet(&[_]Feature{
15961597 .avr25,
15971598 }),
15981599 };
1599 pub const attiny48 = Cpu{
1600 pub const attiny48 = CpuModel{
16001601 .name = "attiny48",
16011602 .llvm_name = "attiny48",
16021603 .features = featureSet(&[_]Feature{
16031604 .avr25,
16041605 }),
16051606 };
1606 pub const attiny5 = Cpu{
1607 pub const attiny5 = CpuModel{
16071608 .name = "attiny5",
16081609 .llvm_name = "attiny5",
16091610 .features = featureSet(&[_]Feature{
16101611 .avrtiny,
16111612 }),
16121613 };
1613 pub const attiny828 = Cpu{
1614 pub const attiny828 = CpuModel{
16141615 .name = "attiny828",
16151616 .llvm_name = "attiny828",
16161617 .features = featureSet(&[_]Feature{
16171618 .avr25,
16181619 }),
16191620 };
1620 pub const attiny84 = Cpu{
1621 pub const attiny84 = CpuModel{
16211622 .name = "attiny84",
16221623 .llvm_name = "attiny84",
16231624 .features = featureSet(&[_]Feature{
16241625 .avr25,
16251626 }),
16261627 };
1627 pub const attiny84a = Cpu{
1628 pub const attiny84a = CpuModel{
16281629 .name = "attiny84a",
16291630 .llvm_name = "attiny84a",
16301631 .features = featureSet(&[_]Feature{
16311632 .avr25,
16321633 }),
16331634 };
1634 pub const attiny85 = Cpu{
1635 pub const attiny85 = CpuModel{
16351636 .name = "attiny85",
16361637 .llvm_name = "attiny85",
16371638 .features = featureSet(&[_]Feature{
16381639 .avr25,
16391640 }),
16401641 };
1641 pub const attiny861 = Cpu{
1642 pub const attiny861 = CpuModel{
16421643 .name = "attiny861",
16431644 .llvm_name = "attiny861",
16441645 .features = featureSet(&[_]Feature{
16451646 .avr25,
16461647 }),
16471648 };
1648 pub const attiny861a = Cpu{
1649 pub const attiny861a = CpuModel{
16491650 .name = "attiny861a",
16501651 .llvm_name = "attiny861a",
16511652 .features = featureSet(&[_]Feature{
16521653 .avr25,
16531654 }),
16541655 };
1655 pub const attiny87 = Cpu{
1656 pub const attiny87 = CpuModel{
16561657 .name = "attiny87",
16571658 .llvm_name = "attiny87",
16581659 .features = featureSet(&[_]Feature{
16591660 .avr25,
16601661 }),
16611662 };
1662 pub const attiny88 = Cpu{
1663 pub const attiny88 = CpuModel{
16631664 .name = "attiny88",
16641665 .llvm_name = "attiny88",
16651666 .features = featureSet(&[_]Feature{
16661667 .avr25,
16671668 }),
16681669 };
1669 pub const attiny9 = Cpu{
1670 pub const attiny9 = CpuModel{
16701671 .name = "attiny9",
16711672 .llvm_name = "attiny9",
16721673 .features = featureSet(&[_]Feature{
16731674 .avrtiny,
16741675 }),
16751676 };
1676 pub const atxmega128a1 = Cpu{
1677 pub const atxmega128a1 = CpuModel{
16771678 .name = "atxmega128a1",
16781679 .llvm_name = "atxmega128a1",
16791680 .features = featureSet(&[_]Feature{
16801681 .xmega,
16811682 }),
16821683 };
1683 pub const atxmega128a1u = Cpu{
1684 pub const atxmega128a1u = CpuModel{
16841685 .name = "atxmega128a1u",
16851686 .llvm_name = "atxmega128a1u",
16861687 .features = featureSet(&[_]Feature{
16871688 .xmegau,
16881689 }),
16891690 };
1690 pub const atxmega128a3 = Cpu{
1691 pub const atxmega128a3 = CpuModel{
16911692 .name = "atxmega128a3",
16921693 .llvm_name = "atxmega128a3",
16931694 .features = featureSet(&[_]Feature{
16941695 .xmega,
16951696 }),
16961697 };
1697 pub const atxmega128a3u = Cpu{
1698 pub const atxmega128a3u = CpuModel{
16981699 .name = "atxmega128a3u",
16991700 .llvm_name = "atxmega128a3u",
17001701 .features = featureSet(&[_]Feature{
17011702 .xmegau,
17021703 }),
17031704 };
1704 pub const atxmega128a4u = Cpu{
1705 pub const atxmega128a4u = CpuModel{
17051706 .name = "atxmega128a4u",
17061707 .llvm_name = "atxmega128a4u",
17071708 .features = featureSet(&[_]Feature{
17081709 .xmegau,
17091710 }),
17101711 };
1711 pub const atxmega128b1 = Cpu{
1712 pub const atxmega128b1 = CpuModel{
17121713 .name = "atxmega128b1",
17131714 .llvm_name = "atxmega128b1",
17141715 .features = featureSet(&[_]Feature{
17151716 .xmegau,
17161717 }),
17171718 };
1718 pub const atxmega128b3 = Cpu{
1719 pub const atxmega128b3 = CpuModel{
17191720 .name = "atxmega128b3",
17201721 .llvm_name = "atxmega128b3",
17211722 .features = featureSet(&[_]Feature{
17221723 .xmegau,
17231724 }),
17241725 };
1725 pub const atxmega128c3 = Cpu{
1726 pub const atxmega128c3 = CpuModel{
17261727 .name = "atxmega128c3",
17271728 .llvm_name = "atxmega128c3",
17281729 .features = featureSet(&[_]Feature{
17291730 .xmegau,
17301731 }),
17311732 };
1732 pub const atxmega128d3 = Cpu{
1733 pub const atxmega128d3 = CpuModel{
17331734 .name = "atxmega128d3",
17341735 .llvm_name = "atxmega128d3",
17351736 .features = featureSet(&[_]Feature{
17361737 .xmega,
17371738 }),
17381739 };
1739 pub const atxmega128d4 = Cpu{
1740 pub const atxmega128d4 = CpuModel{
17401741 .name = "atxmega128d4",
17411742 .llvm_name = "atxmega128d4",
17421743 .features = featureSet(&[_]Feature{
17431744 .xmega,
17441745 }),
17451746 };
1746 pub const atxmega16a4 = Cpu{
1747 pub const atxmega16a4 = CpuModel{
17471748 .name = "atxmega16a4",
17481749 .llvm_name = "atxmega16a4",
17491750 .features = featureSet(&[_]Feature{
17501751 .xmega,
17511752 }),
17521753 };
1753 pub const atxmega16a4u = Cpu{
1754 pub const atxmega16a4u = CpuModel{
17541755 .name = "atxmega16a4u",
17551756 .llvm_name = "atxmega16a4u",
17561757 .features = featureSet(&[_]Feature{
17571758 .xmegau,
17581759 }),
17591760 };
1760 pub const atxmega16c4 = Cpu{
1761 pub const atxmega16c4 = CpuModel{
17611762 .name = "atxmega16c4",
17621763 .llvm_name = "atxmega16c4",
17631764 .features = featureSet(&[_]Feature{
17641765 .xmegau,
17651766 }),
17661767 };
1767 pub const atxmega16d4 = Cpu{
1768 pub const atxmega16d4 = CpuModel{
17681769 .name = "atxmega16d4",
17691770 .llvm_name = "atxmega16d4",
17701771 .features = featureSet(&[_]Feature{
17711772 .xmega,
17721773 }),
17731774 };
1774 pub const atxmega16e5 = Cpu{
1775 pub const atxmega16e5 = CpuModel{
17751776 .name = "atxmega16e5",
17761777 .llvm_name = "atxmega16e5",
17771778 .features = featureSet(&[_]Feature{
17781779 .xmega,
17791780 }),
17801781 };
1781 pub const atxmega192a3 = Cpu{
1782 pub const atxmega192a3 = CpuModel{
17821783 .name = "atxmega192a3",
17831784 .llvm_name = "atxmega192a3",
17841785 .features = featureSet(&[_]Feature{
17851786 .xmega,
17861787 }),
17871788 };
1788 pub const atxmega192a3u = Cpu{
1789 pub const atxmega192a3u = CpuModel{
17891790 .name = "atxmega192a3u",
17901791 .llvm_name = "atxmega192a3u",
17911792 .features = featureSet(&[_]Feature{
17921793 .xmegau,
17931794 }),
17941795 };
1795 pub const atxmega192c3 = Cpu{
1796 pub const atxmega192c3 = CpuModel{
17961797 .name = "atxmega192c3",
17971798 .llvm_name = "atxmega192c3",
17981799 .features = featureSet(&[_]Feature{
17991800 .xmegau,
18001801 }),
18011802 };
1802 pub const atxmega192d3 = Cpu{
1803 pub const atxmega192d3 = CpuModel{
18031804 .name = "atxmega192d3",
18041805 .llvm_name = "atxmega192d3",
18051806 .features = featureSet(&[_]Feature{
18061807 .xmega,
18071808 }),
18081809 };
1809 pub const atxmega256a3 = Cpu{
1810 pub const atxmega256a3 = CpuModel{
18101811 .name = "atxmega256a3",
18111812 .llvm_name = "atxmega256a3",
18121813 .features = featureSet(&[_]Feature{
18131814 .xmega,
18141815 }),
18151816 };
1816 pub const atxmega256a3b = Cpu{
1817 pub const atxmega256a3b = CpuModel{
18171818 .name = "atxmega256a3b",
18181819 .llvm_name = "atxmega256a3b",
18191820 .features = featureSet(&[_]Feature{
18201821 .xmega,
18211822 }),
18221823 };
1823 pub const atxmega256a3bu = Cpu{
1824 pub const atxmega256a3bu = CpuModel{
18241825 .name = "atxmega256a3bu",
18251826 .llvm_name = "atxmega256a3bu",
18261827 .features = featureSet(&[_]Feature{
18271828 .xmegau,
18281829 }),
18291830 };
1830 pub const atxmega256a3u = Cpu{
1831 pub const atxmega256a3u = CpuModel{
18311832 .name = "atxmega256a3u",
18321833 .llvm_name = "atxmega256a3u",
18331834 .features = featureSet(&[_]Feature{
18341835 .xmegau,
18351836 }),
18361837 };
1837 pub const atxmega256c3 = Cpu{
1838 pub const atxmega256c3 = CpuModel{
18381839 .name = "atxmega256c3",
18391840 .llvm_name = "atxmega256c3",
18401841 .features = featureSet(&[_]Feature{
18411842 .xmegau,
18421843 }),
18431844 };
1844 pub const atxmega256d3 = Cpu{
1845 pub const atxmega256d3 = CpuModel{
18451846 .name = "atxmega256d3",
18461847 .llvm_name = "atxmega256d3",
18471848 .features = featureSet(&[_]Feature{
18481849 .xmega,
18491850 }),
18501851 };
1851 pub const atxmega32a4 = Cpu{
1852 pub const atxmega32a4 = CpuModel{
18521853 .name = "atxmega32a4",
18531854 .llvm_name = "atxmega32a4",
18541855 .features = featureSet(&[_]Feature{
18551856 .xmega,
18561857 }),
18571858 };
1858 pub const atxmega32a4u = Cpu{
1859 pub const atxmega32a4u = CpuModel{
18591860 .name = "atxmega32a4u",
18601861 .llvm_name = "atxmega32a4u",
18611862 .features = featureSet(&[_]Feature{
18621863 .xmegau,
18631864 }),
18641865 };
1865 pub const atxmega32c4 = Cpu{
1866 pub const atxmega32c4 = CpuModel{
18661867 .name = "atxmega32c4",
18671868 .llvm_name = "atxmega32c4",
18681869 .features = featureSet(&[_]Feature{
18691870 .xmegau,
18701871 }),
18711872 };
1872 pub const atxmega32d4 = Cpu{
1873 pub const atxmega32d4 = CpuModel{
18731874 .name = "atxmega32d4",
18741875 .llvm_name = "atxmega32d4",
18751876 .features = featureSet(&[_]Feature{
18761877 .xmega,
18771878 }),
18781879 };
1879 pub const atxmega32e5 = Cpu{
1880 pub const atxmega32e5 = CpuModel{
18801881 .name = "atxmega32e5",
18811882 .llvm_name = "atxmega32e5",
18821883 .features = featureSet(&[_]Feature{
18831884 .xmega,
18841885 }),
18851886 };
1886 pub const atxmega32x1 = Cpu{
1887 pub const atxmega32x1 = CpuModel{
18871888 .name = "atxmega32x1",
18881889 .llvm_name = "atxmega32x1",
18891890 .features = featureSet(&[_]Feature{
18901891 .xmega,
18911892 }),
18921893 };
1893 pub const atxmega384c3 = Cpu{
1894 pub const atxmega384c3 = CpuModel{
18941895 .name = "atxmega384c3",
18951896 .llvm_name = "atxmega384c3",
18961897 .features = featureSet(&[_]Feature{
18971898 .xmegau,
18981899 }),
18991900 };
1900 pub const atxmega384d3 = Cpu{
1901 pub const atxmega384d3 = CpuModel{
19011902 .name = "atxmega384d3",
19021903 .llvm_name = "atxmega384d3",
19031904 .features = featureSet(&[_]Feature{
19041905 .xmega,
19051906 }),
19061907 };
1907 pub const atxmega64a1 = Cpu{
1908 pub const atxmega64a1 = CpuModel{
19081909 .name = "atxmega64a1",
19091910 .llvm_name = "atxmega64a1",
19101911 .features = featureSet(&[_]Feature{
19111912 .xmega,
19121913 }),
19131914 };
1914 pub const atxmega64a1u = Cpu{
1915 pub const atxmega64a1u = CpuModel{
19151916 .name = "atxmega64a1u",
19161917 .llvm_name = "atxmega64a1u",
19171918 .features = featureSet(&[_]Feature{
19181919 .xmegau,
19191920 }),
19201921 };
1921 pub const atxmega64a3 = Cpu{
1922 pub const atxmega64a3 = CpuModel{
19221923 .name = "atxmega64a3",
19231924 .llvm_name = "atxmega64a3",
19241925 .features = featureSet(&[_]Feature{
19251926 .xmega,
19261927 }),
19271928 };
1928 pub const atxmega64a3u = Cpu{
1929 pub const atxmega64a3u = CpuModel{
19291930 .name = "atxmega64a3u",
19301931 .llvm_name = "atxmega64a3u",
19311932 .features = featureSet(&[_]Feature{
19321933 .xmegau,
19331934 }),
19341935 };
1935 pub const atxmega64a4u = Cpu{
1936 pub const atxmega64a4u = CpuModel{
19361937 .name = "atxmega64a4u",
19371938 .llvm_name = "atxmega64a4u",
19381939 .features = featureSet(&[_]Feature{
19391940 .xmegau,
19401941 }),
19411942 };
1942 pub const atxmega64b1 = Cpu{
1943 pub const atxmega64b1 = CpuModel{
19431944 .name = "atxmega64b1",
19441945 .llvm_name = "atxmega64b1",
19451946 .features = featureSet(&[_]Feature{
19461947 .xmegau,
19471948 }),
19481949 };
1949 pub const atxmega64b3 = Cpu{
1950 pub const atxmega64b3 = CpuModel{
19501951 .name = "atxmega64b3",
19511952 .llvm_name = "atxmega64b3",
19521953 .features = featureSet(&[_]Feature{
19531954 .xmegau,
19541955 }),
19551956 };
1956 pub const atxmega64c3 = Cpu{
1957 pub const atxmega64c3 = CpuModel{
19571958 .name = "atxmega64c3",
19581959 .llvm_name = "atxmega64c3",
19591960 .features = featureSet(&[_]Feature{
19601961 .xmegau,
19611962 }),
19621963 };
1963 pub const atxmega64d3 = Cpu{
1964 pub const atxmega64d3 = CpuModel{
19641965 .name = "atxmega64d3",
19651966 .llvm_name = "atxmega64d3",
19661967 .features = featureSet(&[_]Feature{
19671968 .xmega,
19681969 }),
19691970 };
1970 pub const atxmega64d4 = Cpu{
1971 pub const atxmega64d4 = CpuModel{
19711972 .name = "atxmega64d4",
19721973 .llvm_name = "atxmega64d4",
19731974 .features = featureSet(&[_]Feature{
19741975 .xmega,
19751976 }),
19761977 };
1977 pub const atxmega8e5 = Cpu{
1978 pub const atxmega8e5 = CpuModel{
19781979 .name = "atxmega8e5",
19791980 .llvm_name = "atxmega8e5",
19801981 .features = featureSet(&[_]Feature{
19811982 .xmega,
19821983 }),
19831984 };
1984 pub const avr1 = Cpu{
1985 pub const avr1 = CpuModel{
19851986 .name = "avr1",
19861987 .llvm_name = "avr1",
19871988 .features = featureSet(&[_]Feature{
19881989 .avr1,
19891990 }),
19901991 };
1991 pub const avr2 = Cpu{
1992 pub const avr2 = CpuModel{
19921993 .name = "avr2",
19931994 .llvm_name = "avr2",
19941995 .features = featureSet(&[_]Feature{
19951996 .avr2,
19961997 }),
19971998 };
1998 pub const avr25 = Cpu{
1999 pub const avr25 = CpuModel{
19992000 .name = "avr25",
20002001 .llvm_name = "avr25",
20012002 .features = featureSet(&[_]Feature{
20022003 .avr25,
20032004 }),
20042005 };
2005 pub const avr3 = Cpu{
2006 pub const avr3 = CpuModel{
20062007 .name = "avr3",
20072008 .llvm_name = "avr3",
20082009 .features = featureSet(&[_]Feature{
20092010 .avr3,
20102011 }),
20112012 };
2012 pub const avr31 = Cpu{
2013 pub const avr31 = CpuModel{
20132014 .name = "avr31",
20142015 .llvm_name = "avr31",
20152016 .features = featureSet(&[_]Feature{
20162017 .avr31,
20172018 }),
20182019 };
2019 pub const avr35 = Cpu{
2020 pub const avr35 = CpuModel{
20202021 .name = "avr35",
20212022 .llvm_name = "avr35",
20222023 .features = featureSet(&[_]Feature{
20232024 .avr35,
20242025 }),
20252026 };
2026 pub const avr4 = Cpu{
2027 pub const avr4 = CpuModel{
20272028 .name = "avr4",
20282029 .llvm_name = "avr4",
20292030 .features = featureSet(&[_]Feature{
20302031 .avr4,
20312032 }),
20322033 };
2033 pub const avr5 = Cpu{
2034 pub const avr5 = CpuModel{
20342035 .name = "avr5",
20352036 .llvm_name = "avr5",
20362037 .features = featureSet(&[_]Feature{
20372038 .avr5,
20382039 }),
20392040 };
2040 pub const avr51 = Cpu{
2041 pub const avr51 = CpuModel{
20412042 .name = "avr51",
20422043 .llvm_name = "avr51",
20432044 .features = featureSet(&[_]Feature{
20442045 .avr51,
20452046 }),
20462047 };
2047 pub const avr6 = Cpu{
2048 pub const avr6 = CpuModel{
20482049 .name = "avr6",
20492050 .llvm_name = "avr6",
20502051 .features = featureSet(&[_]Feature{
20512052 .avr6,
20522053 }),
20532054 };
2054 pub const avrtiny = Cpu{
2055 pub const avrtiny = CpuModel{
20552056 .name = "avrtiny",
20562057 .llvm_name = "avrtiny",
20572058 .features = featureSet(&[_]Feature{
20582059 .avrtiny,
20592060 }),
20602061 };
2061 pub const avrxmega1 = Cpu{
2062 pub const avrxmega1 = CpuModel{
20622063 .name = "avrxmega1",
20632064 .llvm_name = "avrxmega1",
20642065 .features = featureSet(&[_]Feature{
20652066 .xmega,
20662067 }),
20672068 };
2068 pub const avrxmega2 = Cpu{
2069 pub const avrxmega2 = CpuModel{
20692070 .name = "avrxmega2",
20702071 .llvm_name = "avrxmega2",
20712072 .features = featureSet(&[_]Feature{
20722073 .xmega,
20732074 }),
20742075 };
2075 pub const avrxmega3 = Cpu{
2076 pub const avrxmega3 = CpuModel{
20762077 .name = "avrxmega3",
20772078 .llvm_name = "avrxmega3",
20782079 .features = featureSet(&[_]Feature{
20792080 .xmega,
20802081 }),
20812082 };
2082 pub const avrxmega4 = Cpu{
2083 pub const avrxmega4 = CpuModel{
20832084 .name = "avrxmega4",
20842085 .llvm_name = "avrxmega4",
20852086 .features = featureSet(&[_]Feature{
20862087 .xmega,
20872088 }),
20882089 };
2089 pub const avrxmega5 = Cpu{
2090 pub const avrxmega5 = CpuModel{
20902091 .name = "avrxmega5",
20912092 .llvm_name = "avrxmega5",
20922093 .features = featureSet(&[_]Feature{
20932094 .xmega,
20942095 }),
20952096 };
2096 pub const avrxmega6 = Cpu{
2097 pub const avrxmega6 = CpuModel{
20972098 .name = "avrxmega6",
20982099 .llvm_name = "avrxmega6",
20992100 .features = featureSet(&[_]Feature{
21002101 .xmega,
21012102 }),
21022103 };
2103 pub const avrxmega7 = Cpu{
2104 pub const avrxmega7 = CpuModel{
21042105 .name = "avrxmega7",
21052106 .llvm_name = "avrxmega7",
21062107 .features = featureSet(&[_]Feature{
21072108 .xmega,
21082109 }),
21092110 };
2110 pub const m3000 = Cpu{
2111 pub const m3000 = CpuModel{
21112112 .name = "m3000",
21122113 .llvm_name = "m3000",
21132114 .features = featureSet(&[_]Feature{
......@@ -2119,7 +2120,7 @@ pub const cpu = struct {
21192120/// All avr CPUs, sorted alphabetically by name.
21202121/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
21212122/// compiler has inefficient memory and CPU usage, affecting build times.
2122pub const all_cpus = &[_]*const Cpu{
2123pub const all_cpus = &[_]*const CpuModel{
21232124 &cpu.at43usb320,
21242125 &cpu.at43usb355,
21252126 &cpu.at76c711,
lib/std/target/bpf.zig+11-10
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 alu32,
......@@ -7,12 +8,12 @@ pub const Feature = enum {
78 dwarfris,
89};
910
10pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
11pub usingnamespace CpuFeature.feature_set_fns(Feature);
1112
1213pub const all_features = blk: {
1314 const len = @typeInfo(Feature).Enum.fields.len;
14 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
15 var result: [len]Cpu.Feature = undefined;
15 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
16 var result: [len]CpuFeature = undefined;
1617 result[@enumToInt(Feature.alu32)] = .{
1718 .llvm_name = "alu32",
1819 .description = "Enable ALU32 instructions",
......@@ -37,27 +38,27 @@ pub const all_features = blk: {
3738};
3839
3940pub const cpu = struct {
40 pub const generic = Cpu{
41 pub const generic = CpuModel{
4142 .name = "generic",
4243 .llvm_name = "generic",
4344 .features = featureSet(&[_]Feature{}),
4445 };
45 pub const probe = Cpu{
46 pub const probe = CpuModel{
4647 .name = "probe",
4748 .llvm_name = "probe",
4849 .features = featureSet(&[_]Feature{}),
4950 };
50 pub const v1 = Cpu{
51 pub const v1 = CpuModel{
5152 .name = "v1",
5253 .llvm_name = "v1",
5354 .features = featureSet(&[_]Feature{}),
5455 };
55 pub const v2 = Cpu{
56 pub const v2 = CpuModel{
5657 .name = "v2",
5758 .llvm_name = "v2",
5859 .features = featureSet(&[_]Feature{}),
5960 };
60 pub const v3 = Cpu{
61 pub const v3 = CpuModel{
6162 .name = "v3",
6263 .llvm_name = "v3",
6364 .features = featureSet(&[_]Feature{}),
......@@ -67,7 +68,7 @@ pub const cpu = struct {
6768/// All bpf CPUs, sorted alphabetically by name.
6869/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
6970/// compiler has inefficient memory and CPU usage, affecting build times.
70pub const all_cpus = &[_]*const Cpu{
71pub const all_cpus = &[_]*const CpuModel{
7172 &cpu.generic,
7273 &cpu.probe,
7374 &cpu.v1,
lib/std/target/hexagon.zig+13-12
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 duplex,
......@@ -28,12 +29,12 @@ pub const Feature = enum {
2829 zreg,
2930};
3031
31pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
32pub usingnamespace CpuFeature.feature_set_fns(Feature);
3233
3334pub const all_features = blk: {
3435 const len = @typeInfo(Feature).Enum.fields.len;
35 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
36 var result: [len]Cpu.Feature = undefined;
36 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
37 var result: [len]CpuFeature = undefined;
3738 result[@enumToInt(Feature.duplex)] = .{
3839 .llvm_name = "duplex",
3940 .description = "Enable generation of duplex instruction",
......@@ -186,7 +187,7 @@ pub const all_features = blk: {
186187};
187188
188189pub const cpu = struct {
189 pub const generic = Cpu{
190 pub const generic = CpuModel{
190191 .name = "generic",
191192 .llvm_name = "generic",
192193 .features = featureSet(&[_]Feature{
......@@ -201,7 +202,7 @@ pub const cpu = struct {
201202 .v60,
202203 }),
203204 };
204 pub const hexagonv5 = Cpu{
205 pub const hexagonv5 = CpuModel{
205206 .name = "hexagonv5",
206207 .llvm_name = "hexagonv5",
207208 .features = featureSet(&[_]Feature{
......@@ -214,7 +215,7 @@ pub const cpu = struct {
214215 .v5,
215216 }),
216217 };
217 pub const hexagonv55 = Cpu{
218 pub const hexagonv55 = CpuModel{
218219 .name = "hexagonv55",
219220 .llvm_name = "hexagonv55",
220221 .features = featureSet(&[_]Feature{
......@@ -228,7 +229,7 @@ pub const cpu = struct {
228229 .v55,
229230 }),
230231 };
231 pub const hexagonv60 = Cpu{
232 pub const hexagonv60 = CpuModel{
232233 .name = "hexagonv60",
233234 .llvm_name = "hexagonv60",
234235 .features = featureSet(&[_]Feature{
......@@ -243,7 +244,7 @@ pub const cpu = struct {
243244 .v60,
244245 }),
245246 };
246 pub const hexagonv62 = Cpu{
247 pub const hexagonv62 = CpuModel{
247248 .name = "hexagonv62",
248249 .llvm_name = "hexagonv62",
249250 .features = featureSet(&[_]Feature{
......@@ -259,7 +260,7 @@ pub const cpu = struct {
259260 .v62,
260261 }),
261262 };
262 pub const hexagonv65 = Cpu{
263 pub const hexagonv65 = CpuModel{
263264 .name = "hexagonv65",
264265 .llvm_name = "hexagonv65",
265266 .features = featureSet(&[_]Feature{
......@@ -277,7 +278,7 @@ pub const cpu = struct {
277278 .v65,
278279 }),
279280 };
280 pub const hexagonv66 = Cpu{
281 pub const hexagonv66 = CpuModel{
281282 .name = "hexagonv66",
282283 .llvm_name = "hexagonv66",
283284 .features = featureSet(&[_]Feature{
......@@ -301,7 +302,7 @@ pub const cpu = struct {
301302/// All hexagon CPUs, sorted alphabetically by name.
302303/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
303304/// compiler has inefficient memory and CPU usage, affecting build times.
304pub const all_cpus = &[_]*const Cpu{
305pub const all_cpus = &[_]*const CpuModel{
305306 &cpu.generic,
306307 &cpu.hexagonv5,
307308 &cpu.hexagonv55,
lib/std/target/mips.zig+25-24
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 abs2008,
......@@ -55,12 +56,12 @@ pub const Feature = enum {
5556 xgot,
5657};
5758
58pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
59pub usingnamespace CpuFeature.feature_set_fns(Feature);
5960
6061pub const all_features = blk: {
6162 const len = @typeInfo(Feature).Enum.fields.len;
62 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
63 var result: [len]Cpu.Feature = undefined;
63 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
64 var result: [len]CpuFeature = undefined;
6465 result[@enumToInt(Feature.abs2008)] = .{
6566 .llvm_name = "abs2008",
6667 .description = "Disable IEEE 754-2008 abs.fmt mode",
......@@ -386,119 +387,119 @@ pub const all_features = blk: {
386387};
387388
388389pub const cpu = struct {
389 pub const generic = Cpu{
390 pub const generic = CpuModel{
390391 .name = "generic",
391392 .llvm_name = "generic",
392393 .features = featureSet(&[_]Feature{
393394 .mips32,
394395 }),
395396 };
396 pub const mips1 = Cpu{
397 pub const mips1 = CpuModel{
397398 .name = "mips1",
398399 .llvm_name = "mips1",
399400 .features = featureSet(&[_]Feature{
400401 .mips1,
401402 }),
402403 };
403 pub const mips2 = Cpu{
404 pub const mips2 = CpuModel{
404405 .name = "mips2",
405406 .llvm_name = "mips2",
406407 .features = featureSet(&[_]Feature{
407408 .mips2,
408409 }),
409410 };
410 pub const mips3 = Cpu{
411 pub const mips3 = CpuModel{
411412 .name = "mips3",
412413 .llvm_name = "mips3",
413414 .features = featureSet(&[_]Feature{
414415 .mips3,
415416 }),
416417 };
417 pub const mips32 = Cpu{
418 pub const mips32 = CpuModel{
418419 .name = "mips32",
419420 .llvm_name = "mips32",
420421 .features = featureSet(&[_]Feature{
421422 .mips32,
422423 }),
423424 };
424 pub const mips32r2 = Cpu{
425 pub const mips32r2 = CpuModel{
425426 .name = "mips32r2",
426427 .llvm_name = "mips32r2",
427428 .features = featureSet(&[_]Feature{
428429 .mips32r2,
429430 }),
430431 };
431 pub const mips32r3 = Cpu{
432 pub const mips32r3 = CpuModel{
432433 .name = "mips32r3",
433434 .llvm_name = "mips32r3",
434435 .features = featureSet(&[_]Feature{
435436 .mips32r3,
436437 }),
437438 };
438 pub const mips32r5 = Cpu{
439 pub const mips32r5 = CpuModel{
439440 .name = "mips32r5",
440441 .llvm_name = "mips32r5",
441442 .features = featureSet(&[_]Feature{
442443 .mips32r5,
443444 }),
444445 };
445 pub const mips32r6 = Cpu{
446 pub const mips32r6 = CpuModel{
446447 .name = "mips32r6",
447448 .llvm_name = "mips32r6",
448449 .features = featureSet(&[_]Feature{
449450 .mips32r6,
450451 }),
451452 };
452 pub const mips4 = Cpu{
453 pub const mips4 = CpuModel{
453454 .name = "mips4",
454455 .llvm_name = "mips4",
455456 .features = featureSet(&[_]Feature{
456457 .mips4,
457458 }),
458459 };
459 pub const mips5 = Cpu{
460 pub const mips5 = CpuModel{
460461 .name = "mips5",
461462 .llvm_name = "mips5",
462463 .features = featureSet(&[_]Feature{
463464 .mips5,
464465 }),
465466 };
466 pub const mips64 = Cpu{
467 pub const mips64 = CpuModel{
467468 .name = "mips64",
468469 .llvm_name = "mips64",
469470 .features = featureSet(&[_]Feature{
470471 .mips64,
471472 }),
472473 };
473 pub const mips64r2 = Cpu{
474 pub const mips64r2 = CpuModel{
474475 .name = "mips64r2",
475476 .llvm_name = "mips64r2",
476477 .features = featureSet(&[_]Feature{
477478 .mips64r2,
478479 }),
479480 };
480 pub const mips64r3 = Cpu{
481 pub const mips64r3 = CpuModel{
481482 .name = "mips64r3",
482483 .llvm_name = "mips64r3",
483484 .features = featureSet(&[_]Feature{
484485 .mips64r3,
485486 }),
486487 };
487 pub const mips64r5 = Cpu{
488 pub const mips64r5 = CpuModel{
488489 .name = "mips64r5",
489490 .llvm_name = "mips64r5",
490491 .features = featureSet(&[_]Feature{
491492 .mips64r5,
492493 }),
493494 };
494 pub const mips64r6 = Cpu{
495 pub const mips64r6 = CpuModel{
495496 .name = "mips64r6",
496497 .llvm_name = "mips64r6",
497498 .features = featureSet(&[_]Feature{
498499 .mips64r6,
499500 }),
500501 };
501 pub const octeon = Cpu{
502 pub const octeon = CpuModel{
502503 .name = "octeon",
503504 .llvm_name = "octeon",
504505 .features = featureSet(&[_]Feature{
......@@ -506,7 +507,7 @@ pub const cpu = struct {
506507 .mips64r2,
507508 }),
508509 };
509 pub const @"octeon+" = Cpu{
510 pub const @"octeon+" = CpuModel{
510511 .name = "octeon+",
511512 .llvm_name = "octeon+",
512513 .features = featureSet(&[_]Feature{
......@@ -515,7 +516,7 @@ pub const cpu = struct {
515516 .mips64r2,
516517 }),
517518 };
518 pub const p5600 = Cpu{
519 pub const p5600 = CpuModel{
519520 .name = "p5600",
520521 .llvm_name = "p5600",
521522 .features = featureSet(&[_]Feature{
......@@ -527,7 +528,7 @@ pub const cpu = struct {
527528/// All mips CPUs, sorted alphabetically by name.
528529/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
529530/// compiler has inefficient memory and CPU usage, affecting build times.
530pub const all_cpus = &[_]*const Cpu{
531pub const all_cpus = &[_]*const CpuModel{
531532 &cpu.generic,
532533 &cpu.mips1,
533534 &cpu.mips2,
lib/std/target/msp430.zig+9-8
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 ext,
......@@ -8,12 +9,12 @@ pub const Feature = enum {
89 hwmultf5,
910};
1011
11pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
12pub usingnamespace CpuFeature.feature_set_fns(Feature);
1213
1314pub const all_features = blk: {
1415 const len = @typeInfo(Feature).Enum.fields.len;
15 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
16 var result: [len]Cpu.Feature = undefined;
16 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
17 var result: [len]CpuFeature = undefined;
1718 result[@enumToInt(Feature.ext)] = .{
1819 .llvm_name = "ext",
1920 .description = "Enable MSP430-X extensions",
......@@ -43,17 +44,17 @@ pub const all_features = blk: {
4344};
4445
4546pub const cpu = struct {
46 pub const generic = Cpu{
47 pub const generic = CpuModel{
4748 .name = "generic",
4849 .llvm_name = "generic",
4950 .features = featureSet(&[_]Feature{}),
5051 };
51 pub const msp430 = Cpu{
52 pub const msp430 = CpuModel{
5253 .name = "msp430",
5354 .llvm_name = "msp430",
5455 .features = featureSet(&[_]Feature{}),
5556 };
56 pub const msp430x = Cpu{
57 pub const msp430x = CpuModel{
5758 .name = "msp430x",
5859 .llvm_name = "msp430x",
5960 .features = featureSet(&[_]Feature{
......@@ -65,7 +66,7 @@ pub const cpu = struct {
6566/// All msp430 CPUs, sorted alphabetically by name.
6667/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
6768/// compiler has inefficient memory and CPU usage, affecting build times.
68pub const all_cpus = &[_]*const Cpu{
69pub const all_cpus = &[_]*const CpuModel{
6970 &cpu.generic,
7071 &cpu.msp430,
7172 &cpu.msp430x,
lib/std/target/nvptx.zig+21-20
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 ptx32,
......@@ -29,12 +30,12 @@ pub const Feature = enum {
2930 sm_75,
3031};
3132
32pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
33pub usingnamespace CpuFeature.feature_set_fns(Feature);
3334
3435pub const all_features = blk: {
3536 const len = @typeInfo(Feature).Enum.fields.len;
36 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
37 var result: [len]Cpu.Feature = undefined;
37 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
38 var result: [len]CpuFeature = undefined;
3839 result[@enumToInt(Feature.ptx32)] = .{
3940 .llvm_name = "ptx32",
4041 .description = "Use PTX version 3.2",
......@@ -169,28 +170,28 @@ pub const all_features = blk: {
169170};
170171
171172pub const cpu = struct {
172 pub const sm_20 = Cpu{
173 pub const sm_20 = CpuModel{
173174 .name = "sm_20",
174175 .llvm_name = "sm_20",
175176 .features = featureSet(&[_]Feature{
176177 .sm_20,
177178 }),
178179 };
179 pub const sm_21 = Cpu{
180 pub const sm_21 = CpuModel{
180181 .name = "sm_21",
181182 .llvm_name = "sm_21",
182183 .features = featureSet(&[_]Feature{
183184 .sm_21,
184185 }),
185186 };
186 pub const sm_30 = Cpu{
187 pub const sm_30 = CpuModel{
187188 .name = "sm_30",
188189 .llvm_name = "sm_30",
189190 .features = featureSet(&[_]Feature{
190191 .sm_30,
191192 }),
192193 };
193 pub const sm_32 = Cpu{
194 pub const sm_32 = CpuModel{
194195 .name = "sm_32",
195196 .llvm_name = "sm_32",
196197 .features = featureSet(&[_]Feature{
......@@ -198,14 +199,14 @@ pub const cpu = struct {
198199 .sm_32,
199200 }),
200201 };
201 pub const sm_35 = Cpu{
202 pub const sm_35 = CpuModel{
202203 .name = "sm_35",
203204 .llvm_name = "sm_35",
204205 .features = featureSet(&[_]Feature{
205206 .sm_35,
206207 }),
207208 };
208 pub const sm_37 = Cpu{
209 pub const sm_37 = CpuModel{
209210 .name = "sm_37",
210211 .llvm_name = "sm_37",
211212 .features = featureSet(&[_]Feature{
......@@ -213,7 +214,7 @@ pub const cpu = struct {
213214 .sm_37,
214215 }),
215216 };
216 pub const sm_50 = Cpu{
217 pub const sm_50 = CpuModel{
217218 .name = "sm_50",
218219 .llvm_name = "sm_50",
219220 .features = featureSet(&[_]Feature{
......@@ -221,7 +222,7 @@ pub const cpu = struct {
221222 .sm_50,
222223 }),
223224 };
224 pub const sm_52 = Cpu{
225 pub const sm_52 = CpuModel{
225226 .name = "sm_52",
226227 .llvm_name = "sm_52",
227228 .features = featureSet(&[_]Feature{
......@@ -229,7 +230,7 @@ pub const cpu = struct {
229230 .sm_52,
230231 }),
231232 };
232 pub const sm_53 = Cpu{
233 pub const sm_53 = CpuModel{
233234 .name = "sm_53",
234235 .llvm_name = "sm_53",
235236 .features = featureSet(&[_]Feature{
......@@ -237,7 +238,7 @@ pub const cpu = struct {
237238 .sm_53,
238239 }),
239240 };
240 pub const sm_60 = Cpu{
241 pub const sm_60 = CpuModel{
241242 .name = "sm_60",
242243 .llvm_name = "sm_60",
243244 .features = featureSet(&[_]Feature{
......@@ -245,7 +246,7 @@ pub const cpu = struct {
245246 .sm_60,
246247 }),
247248 };
248 pub const sm_61 = Cpu{
249 pub const sm_61 = CpuModel{
249250 .name = "sm_61",
250251 .llvm_name = "sm_61",
251252 .features = featureSet(&[_]Feature{
......@@ -253,7 +254,7 @@ pub const cpu = struct {
253254 .sm_61,
254255 }),
255256 };
256 pub const sm_62 = Cpu{
257 pub const sm_62 = CpuModel{
257258 .name = "sm_62",
258259 .llvm_name = "sm_62",
259260 .features = featureSet(&[_]Feature{
......@@ -261,7 +262,7 @@ pub const cpu = struct {
261262 .sm_62,
262263 }),
263264 };
264 pub const sm_70 = Cpu{
265 pub const sm_70 = CpuModel{
265266 .name = "sm_70",
266267 .llvm_name = "sm_70",
267268 .features = featureSet(&[_]Feature{
......@@ -269,7 +270,7 @@ pub const cpu = struct {
269270 .sm_70,
270271 }),
271272 };
272 pub const sm_72 = Cpu{
273 pub const sm_72 = CpuModel{
273274 .name = "sm_72",
274275 .llvm_name = "sm_72",
275276 .features = featureSet(&[_]Feature{
......@@ -277,7 +278,7 @@ pub const cpu = struct {
277278 .sm_72,
278279 }),
279280 };
280 pub const sm_75 = Cpu{
281 pub const sm_75 = CpuModel{
281282 .name = "sm_75",
282283 .llvm_name = "sm_75",
283284 .features = featureSet(&[_]Feature{
......@@ -290,7 +291,7 @@ pub const cpu = struct {
290291/// All nvptx CPUs, sorted alphabetically by name.
291292/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
292293/// compiler has inefficient memory and CPU usage, affecting build times.
293pub const all_cpus = &[_]*const Cpu{
294pub const all_cpus = &[_]*const CpuModel{
294295 &cpu.sm_20,
295296 &cpu.sm_21,
296297 &cpu.sm_30,
lib/std/target/powerpc.zig+44-43
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 @"64bit",
......@@ -56,12 +57,12 @@ pub const Feature = enum {
5657 vsx,
5758};
5859
59pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
60pub usingnamespace CpuFeature.feature_set_fns(Feature);
6061
6162pub const all_features = blk: {
6263 const len = @typeInfo(Feature).Enum.fields.len;
63 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
64 var result: [len]Cpu.Feature = undefined;
64 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
65 var result: [len]CpuFeature = undefined;
6566 result[@enumToInt(Feature.@"64bit")] = .{
6667 .llvm_name = "64bit",
6768 .description = "Enable 64-bit instructions",
......@@ -383,7 +384,7 @@ pub const all_features = blk: {
383384};
384385
385386pub const cpu = struct {
386 pub const @"440" = Cpu{
387 pub const @"440" = CpuModel{
387388 .name = "440",
388389 .llvm_name = "440",
389390 .features = featureSet(&[_]Feature{
......@@ -395,7 +396,7 @@ pub const cpu = struct {
395396 .msync,
396397 }),
397398 };
398 pub const @"450" = Cpu{
399 pub const @"450" = CpuModel{
399400 .name = "450",
400401 .llvm_name = "450",
401402 .features = featureSet(&[_]Feature{
......@@ -407,21 +408,21 @@ pub const cpu = struct {
407408 .msync,
408409 }),
409410 };
410 pub const @"601" = Cpu{
411 pub const @"601" = CpuModel{
411412 .name = "601",
412413 .llvm_name = "601",
413414 .features = featureSet(&[_]Feature{
414415 .fpu,
415416 }),
416417 };
417 pub const @"602" = Cpu{
418 pub const @"602" = CpuModel{
418419 .name = "602",
419420 .llvm_name = "602",
420421 .features = featureSet(&[_]Feature{
421422 .fpu,
422423 }),
423424 };
424 pub const @"603" = Cpu{
425 pub const @"603" = CpuModel{
425426 .name = "603",
426427 .llvm_name = "603",
427428 .features = featureSet(&[_]Feature{
......@@ -429,7 +430,7 @@ pub const cpu = struct {
429430 .frsqrte,
430431 }),
431432 };
432 pub const @"603e" = Cpu{
433 pub const @"603e" = CpuModel{
433434 .name = "603e",
434435 .llvm_name = "603e",
435436 .features = featureSet(&[_]Feature{
......@@ -437,7 +438,7 @@ pub const cpu = struct {
437438 .frsqrte,
438439 }),
439440 };
440 pub const @"603ev" = Cpu{
441 pub const @"603ev" = CpuModel{
441442 .name = "603ev",
442443 .llvm_name = "603ev",
443444 .features = featureSet(&[_]Feature{
......@@ -445,7 +446,7 @@ pub const cpu = struct {
445446 .frsqrte,
446447 }),
447448 };
448 pub const @"604" = Cpu{
449 pub const @"604" = CpuModel{
449450 .name = "604",
450451 .llvm_name = "604",
451452 .features = featureSet(&[_]Feature{
......@@ -453,7 +454,7 @@ pub const cpu = struct {
453454 .frsqrte,
454455 }),
455456 };
456 pub const @"604e" = Cpu{
457 pub const @"604e" = CpuModel{
457458 .name = "604e",
458459 .llvm_name = "604e",
459460 .features = featureSet(&[_]Feature{
......@@ -461,7 +462,7 @@ pub const cpu = struct {
461462 .frsqrte,
462463 }),
463464 };
464 pub const @"620" = Cpu{
465 pub const @"620" = CpuModel{
465466 .name = "620",
466467 .llvm_name = "620",
467468 .features = featureSet(&[_]Feature{
......@@ -469,7 +470,7 @@ pub const cpu = struct {
469470 .frsqrte,
470471 }),
471472 };
472 pub const @"7400" = Cpu{
473 pub const @"7400" = CpuModel{
473474 .name = "7400",
474475 .llvm_name = "7400",
475476 .features = featureSet(&[_]Feature{
......@@ -478,7 +479,7 @@ pub const cpu = struct {
478479 .frsqrte,
479480 }),
480481 };
481 pub const @"7450" = Cpu{
482 pub const @"7450" = CpuModel{
482483 .name = "7450",
483484 .llvm_name = "7450",
484485 .features = featureSet(&[_]Feature{
......@@ -487,7 +488,7 @@ pub const cpu = struct {
487488 .frsqrte,
488489 }),
489490 };
490 pub const @"750" = Cpu{
491 pub const @"750" = CpuModel{
491492 .name = "750",
492493 .llvm_name = "750",
493494 .features = featureSet(&[_]Feature{
......@@ -495,7 +496,7 @@ pub const cpu = struct {
495496 .frsqrte,
496497 }),
497498 };
498 pub const @"970" = Cpu{
499 pub const @"970" = CpuModel{
499500 .name = "970",
500501 .llvm_name = "970",
501502 .features = featureSet(&[_]Feature{
......@@ -508,7 +509,7 @@ pub const cpu = struct {
508509 .stfiwx,
509510 }),
510511 };
511 pub const a2 = Cpu{
512 pub const a2 = CpuModel{
512513 .name = "a2",
513514 .llvm_name = "a2",
514515 .features = featureSet(&[_]Feature{
......@@ -533,7 +534,7 @@ pub const cpu = struct {
533534 .stfiwx,
534535 }),
535536 };
536 pub const a2q = Cpu{
537 pub const a2q = CpuModel{
537538 .name = "a2q",
538539 .llvm_name = "a2q",
539540 .features = featureSet(&[_]Feature{
......@@ -559,7 +560,7 @@ pub const cpu = struct {
559560 .stfiwx,
560561 }),
561562 };
562 pub const e500 = Cpu{
563 pub const e500 = CpuModel{
563564 .name = "e500",
564565 .llvm_name = "e500",
565566 .features = featureSet(&[_]Feature{
......@@ -569,7 +570,7 @@ pub const cpu = struct {
569570 .spe,
570571 }),
571572 };
572 pub const e500mc = Cpu{
573 pub const e500mc = CpuModel{
573574 .name = "e500mc",
574575 .llvm_name = "e500mc",
575576 .features = featureSet(&[_]Feature{
......@@ -579,7 +580,7 @@ pub const cpu = struct {
579580 .stfiwx,
580581 }),
581582 };
582 pub const e5500 = Cpu{
583 pub const e5500 = CpuModel{
583584 .name = "e5500",
584585 .llvm_name = "e5500",
585586 .features = featureSet(&[_]Feature{
......@@ -591,7 +592,7 @@ pub const cpu = struct {
591592 .stfiwx,
592593 }),
593594 };
594 pub const future = Cpu{
595 pub const future = CpuModel{
595596 .name = "future",
596597 .llvm_name = "future",
597598 .features = featureSet(&[_]Feature{
......@@ -630,7 +631,7 @@ pub const cpu = struct {
630631 .vsx,
631632 }),
632633 };
633 pub const g3 = Cpu{
634 pub const g3 = CpuModel{
634635 .name = "g3",
635636 .llvm_name = "g3",
636637 .features = featureSet(&[_]Feature{
......@@ -638,7 +639,7 @@ pub const cpu = struct {
638639 .frsqrte,
639640 }),
640641 };
641 pub const g4 = Cpu{
642 pub const g4 = CpuModel{
642643 .name = "g4",
643644 .llvm_name = "g4",
644645 .features = featureSet(&[_]Feature{
......@@ -647,7 +648,7 @@ pub const cpu = struct {
647648 .frsqrte,
648649 }),
649650 };
650 pub const @"g4+" = Cpu{
651 pub const @"g4+" = CpuModel{
651652 .name = "g4+",
652653 .llvm_name = "g4+",
653654 .features = featureSet(&[_]Feature{
......@@ -656,7 +657,7 @@ pub const cpu = struct {
656657 .frsqrte,
657658 }),
658659 };
659 pub const g5 = Cpu{
660 pub const g5 = CpuModel{
660661 .name = "g5",
661662 .llvm_name = "g5",
662663 .features = featureSet(&[_]Feature{
......@@ -669,28 +670,28 @@ pub const cpu = struct {
669670 .stfiwx,
670671 }),
671672 };
672 pub const generic = Cpu{
673 pub const generic = CpuModel{
673674 .name = "generic",
674675 .llvm_name = "generic",
675676 .features = featureSet(&[_]Feature{
676677 .hard_float,
677678 }),
678679 };
679 pub const ppc = Cpu{
680 pub const ppc = CpuModel{
680681 .name = "ppc",
681682 .llvm_name = "ppc",
682683 .features = featureSet(&[_]Feature{
683684 .hard_float,
684685 }),
685686 };
686 pub const ppc32 = Cpu{
687 pub const ppc32 = CpuModel{
687688 .name = "ppc32",
688689 .llvm_name = "ppc32",
689690 .features = featureSet(&[_]Feature{
690691 .hard_float,
691692 }),
692693 };
693 pub const ppc64 = Cpu{
694 pub const ppc64 = CpuModel{
694695 .name = "ppc64",
695696 .llvm_name = "ppc64",
696697 .features = featureSet(&[_]Feature{
......@@ -703,7 +704,7 @@ pub const cpu = struct {
703704 .stfiwx,
704705 }),
705706 };
706 pub const ppc64le = Cpu{
707 pub const ppc64le = CpuModel{
707708 .name = "ppc64le",
708709 .llvm_name = "ppc64le",
709710 .features = featureSet(&[_]Feature{
......@@ -739,7 +740,7 @@ pub const cpu = struct {
739740 .vsx,
740741 }),
741742 };
742 pub const pwr3 = Cpu{
743 pub const pwr3 = CpuModel{
743744 .name = "pwr3",
744745 .llvm_name = "pwr3",
745746 .features = featureSet(&[_]Feature{
......@@ -751,7 +752,7 @@ pub const cpu = struct {
751752 .stfiwx,
752753 }),
753754 };
754 pub const pwr4 = Cpu{
755 pub const pwr4 = CpuModel{
755756 .name = "pwr4",
756757 .llvm_name = "pwr4",
757758 .features = featureSet(&[_]Feature{
......@@ -764,7 +765,7 @@ pub const cpu = struct {
764765 .stfiwx,
765766 }),
766767 };
767 pub const pwr5 = Cpu{
768 pub const pwr5 = CpuModel{
768769 .name = "pwr5",
769770 .llvm_name = "pwr5",
770771 .features = featureSet(&[_]Feature{
......@@ -779,7 +780,7 @@ pub const cpu = struct {
779780 .stfiwx,
780781 }),
781782 };
782 pub const pwr5x = Cpu{
783 pub const pwr5x = CpuModel{
783784 .name = "pwr5x",
784785 .llvm_name = "pwr5x",
785786 .features = featureSet(&[_]Feature{
......@@ -795,7 +796,7 @@ pub const cpu = struct {
795796 .stfiwx,
796797 }),
797798 };
798 pub const pwr6 = Cpu{
799 pub const pwr6 = CpuModel{
799800 .name = "pwr6",
800801 .llvm_name = "pwr6",
801802 .features = featureSet(&[_]Feature{
......@@ -815,7 +816,7 @@ pub const cpu = struct {
815816 .stfiwx,
816817 }),
817818 };
818 pub const pwr6x = Cpu{
819 pub const pwr6x = CpuModel{
819820 .name = "pwr6x",
820821 .llvm_name = "pwr6x",
821822 .features = featureSet(&[_]Feature{
......@@ -835,7 +836,7 @@ pub const cpu = struct {
835836 .stfiwx,
836837 }),
837838 };
838 pub const pwr7 = Cpu{
839 pub const pwr7 = CpuModel{
839840 .name = "pwr7",
840841 .llvm_name = "pwr7",
841842 .features = featureSet(&[_]Feature{
......@@ -864,7 +865,7 @@ pub const cpu = struct {
864865 .vsx,
865866 }),
866867 };
867 pub const pwr8 = Cpu{
868 pub const pwr8 = CpuModel{
868869 .name = "pwr8",
869870 .llvm_name = "pwr8",
870871 .features = featureSet(&[_]Feature{
......@@ -900,7 +901,7 @@ pub const cpu = struct {
900901 .vsx,
901902 }),
902903 };
903 pub const pwr9 = Cpu{
904 pub const pwr9 = CpuModel{
904905 .name = "pwr9",
905906 .llvm_name = "pwr9",
906907 .features = featureSet(&[_]Feature{
......@@ -947,7 +948,7 @@ pub const cpu = struct {
947948/// All powerpc CPUs, sorted alphabetically by name.
948949/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
949950/// compiler has inefficient memory and CPU usage, affecting build times.
950pub const all_cpus = &[_]*const Cpu{
951pub const all_cpus = &[_]*const CpuModel{
951952 &cpu.@"440",
952953 &cpu.@"450",
953954 &cpu.@"601",
lib/std/target/riscv.zig+10-9
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 @"64bit",
......@@ -44,12 +45,12 @@ pub const Feature = enum {
4445 rvc_hints,
4546};
4647
47pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
48pub usingnamespace CpuFeature.feature_set_fns(Feature);
4849
4950pub const all_features = blk: {
5051 const len = @typeInfo(Feature).Enum.fields.len;
51 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
52 var result: [len]Cpu.Feature = undefined;
52 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
53 var result: [len]CpuFeature = undefined;
5354 result[@enumToInt(Feature.@"64bit")] = .{
5455 .llvm_name = "64bit",
5556 .description = "Implements RV64",
......@@ -261,7 +262,7 @@ pub const all_features = blk: {
261262};
262263
263264pub const cpu = struct {
264 pub const baseline_rv32 = Cpu{
265 pub const baseline_rv32 = CpuModel{
265266 .name = "baseline_rv32",
266267 .llvm_name = null,
267268 .features = featureSet(&[_]Feature{
......@@ -273,7 +274,7 @@ pub const cpu = struct {
273274 }),
274275 };
275276
276 pub const baseline_rv64 = Cpu{
277 pub const baseline_rv64 = CpuModel{
277278 .name = "baseline_rv64",
278279 .llvm_name = null,
279280 .features = featureSet(&[_]Feature{
......@@ -286,14 +287,14 @@ pub const cpu = struct {
286287 }),
287288 };
288289
289 pub const generic_rv32 = Cpu{
290 pub const generic_rv32 = CpuModel{
290291 .name = "generic_rv32",
291292 .llvm_name = null,
292293 .features = featureSet(&[_]Feature{
293294 .rvc_hints,
294295 }),
295296 };
296 pub const generic_rv64 = Cpu{
297 pub const generic_rv64 = CpuModel{
297298 .name = "generic_rv64",
298299 .llvm_name = null,
299300 .features = featureSet(&[_]Feature{
......@@ -306,7 +307,7 @@ pub const cpu = struct {
306307/// All riscv CPUs, sorted alphabetically by name.
307308/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
308309/// compiler has inefficient memory and CPU usage, affecting build times.
309pub const all_cpus = &[_]*const Cpu{
310pub const all_cpus = &[_]*const CpuModel{
310311 &cpu.baseline_rv32,
311312 &cpu.baseline_rv64,
312313 &cpu.generic_rv32,
lib/std/target/sparc.zig+46-45
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 deprecated_v8,
......@@ -23,12 +24,12 @@ pub const Feature = enum {
2324 vis3,
2425};
2526
26pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
27pub usingnamespace CpuFeature.feature_set_fns(Feature);
2728
2829pub const all_features = blk: {
2930 const len = @typeInfo(Feature).Enum.fields.len;
30 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
31 var result: [len]Cpu.Feature = undefined;
31 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
32 var result: [len]CpuFeature = undefined;
3233 result[@enumToInt(Feature.deprecated_v8)] = .{
3334 .llvm_name = "deprecated-v8",
3435 .description = "Enable deprecated V8 instructions in V9 mode",
......@@ -133,7 +134,7 @@ pub const all_features = blk: {
133134};
134135
135136pub const cpu = struct {
136 pub const at697e = Cpu{
137 pub const at697e = CpuModel{
137138 .name = "at697e",
138139 .llvm_name = "at697e",
139140 .features = featureSet(&[_]Feature{
......@@ -141,7 +142,7 @@ pub const cpu = struct {
141142 .leon,
142143 }),
143144 };
144 pub const at697f = Cpu{
145 pub const at697f = CpuModel{
145146 .name = "at697f",
146147 .llvm_name = "at697f",
147148 .features = featureSet(&[_]Feature{
......@@ -149,17 +150,17 @@ pub const cpu = struct {
149150 .leon,
150151 }),
151152 };
152 pub const f934 = Cpu{
153 pub const f934 = CpuModel{
153154 .name = "f934",
154155 .llvm_name = "f934",
155156 .features = featureSet(&[_]Feature{}),
156157 };
157 pub const generic = Cpu{
158 pub const generic = CpuModel{
158159 .name = "generic",
159160 .llvm_name = "generic",
160161 .features = featureSet(&[_]Feature{}),
161162 };
162 pub const gr712rc = Cpu{
163 pub const gr712rc = CpuModel{
163164 .name = "gr712rc",
164165 .llvm_name = "gr712rc",
165166 .features = featureSet(&[_]Feature{
......@@ -167,7 +168,7 @@ pub const cpu = struct {
167168 .leon,
168169 }),
169170 };
170 pub const gr740 = Cpu{
171 pub const gr740 = CpuModel{
171172 .name = "gr740",
172173 .llvm_name = "gr740",
173174 .features = featureSet(&[_]Feature{
......@@ -178,19 +179,19 @@ pub const cpu = struct {
178179 .leonpwrpsr,
179180 }),
180181 };
181 pub const hypersparc = Cpu{
182 pub const hypersparc = CpuModel{
182183 .name = "hypersparc",
183184 .llvm_name = "hypersparc",
184185 .features = featureSet(&[_]Feature{}),
185186 };
186 pub const leon2 = Cpu{
187 pub const leon2 = CpuModel{
187188 .name = "leon2",
188189 .llvm_name = "leon2",
189190 .features = featureSet(&[_]Feature{
190191 .leon,
191192 }),
192193 };
193 pub const leon3 = Cpu{
194 pub const leon3 = CpuModel{
194195 .name = "leon3",
195196 .llvm_name = "leon3",
196197 .features = featureSet(&[_]Feature{
......@@ -198,7 +199,7 @@ pub const cpu = struct {
198199 .leon,
199200 }),
200201 };
201 pub const leon4 = Cpu{
202 pub const leon4 = CpuModel{
202203 .name = "leon4",
203204 .llvm_name = "leon4",
204205 .features = featureSet(&[_]Feature{
......@@ -207,7 +208,7 @@ pub const cpu = struct {
207208 .leon,
208209 }),
209210 };
210 pub const ma2080 = Cpu{
211 pub const ma2080 = CpuModel{
211212 .name = "ma2080",
212213 .llvm_name = "ma2080",
213214 .features = featureSet(&[_]Feature{
......@@ -215,7 +216,7 @@ pub const cpu = struct {
215216 .leon,
216217 }),
217218 };
218 pub const ma2085 = Cpu{
219 pub const ma2085 = CpuModel{
219220 .name = "ma2085",
220221 .llvm_name = "ma2085",
221222 .features = featureSet(&[_]Feature{
......@@ -223,7 +224,7 @@ pub const cpu = struct {
223224 .leon,
224225 }),
225226 };
226 pub const ma2100 = Cpu{
227 pub const ma2100 = CpuModel{
227228 .name = "ma2100",
228229 .llvm_name = "ma2100",
229230 .features = featureSet(&[_]Feature{
......@@ -231,7 +232,7 @@ pub const cpu = struct {
231232 .leon,
232233 }),
233234 };
234 pub const ma2150 = Cpu{
235 pub const ma2150 = CpuModel{
235236 .name = "ma2150",
236237 .llvm_name = "ma2150",
237238 .features = featureSet(&[_]Feature{
......@@ -239,7 +240,7 @@ pub const cpu = struct {
239240 .leon,
240241 }),
241242 };
242 pub const ma2155 = Cpu{
243 pub const ma2155 = CpuModel{
243244 .name = "ma2155",
244245 .llvm_name = "ma2155",
245246 .features = featureSet(&[_]Feature{
......@@ -247,7 +248,7 @@ pub const cpu = struct {
247248 .leon,
248249 }),
249250 };
250 pub const ma2450 = Cpu{
251 pub const ma2450 = CpuModel{
251252 .name = "ma2450",
252253 .llvm_name = "ma2450",
253254 .features = featureSet(&[_]Feature{
......@@ -255,7 +256,7 @@ pub const cpu = struct {
255256 .leon,
256257 }),
257258 };
258 pub const ma2455 = Cpu{
259 pub const ma2455 = CpuModel{
259260 .name = "ma2455",
260261 .llvm_name = "ma2455",
261262 .features = featureSet(&[_]Feature{
......@@ -263,7 +264,7 @@ pub const cpu = struct {
263264 .leon,
264265 }),
265266 };
266 pub const ma2480 = Cpu{
267 pub const ma2480 = CpuModel{
267268 .name = "ma2480",
268269 .llvm_name = "ma2480",
269270 .features = featureSet(&[_]Feature{
......@@ -271,7 +272,7 @@ pub const cpu = struct {
271272 .leon,
272273 }),
273274 };
274 pub const ma2485 = Cpu{
275 pub const ma2485 = CpuModel{
275276 .name = "ma2485",
276277 .llvm_name = "ma2485",
277278 .features = featureSet(&[_]Feature{
......@@ -279,7 +280,7 @@ pub const cpu = struct {
279280 .leon,
280281 }),
281282 };
282 pub const ma2x5x = Cpu{
283 pub const ma2x5x = CpuModel{
283284 .name = "ma2x5x",
284285 .llvm_name = "ma2x5x",
285286 .features = featureSet(&[_]Feature{
......@@ -287,7 +288,7 @@ pub const cpu = struct {
287288 .leon,
288289 }),
289290 };
290 pub const ma2x8x = Cpu{
291 pub const ma2x8x = CpuModel{
291292 .name = "ma2x8x",
292293 .llvm_name = "ma2x8x",
293294 .features = featureSet(&[_]Feature{
......@@ -295,7 +296,7 @@ pub const cpu = struct {
295296 .leon,
296297 }),
297298 };
298 pub const myriad2 = Cpu{
299 pub const myriad2 = CpuModel{
299300 .name = "myriad2",
300301 .llvm_name = "myriad2",
301302 .features = featureSet(&[_]Feature{
......@@ -303,7 +304,7 @@ pub const cpu = struct {
303304 .leon,
304305 }),
305306 };
306 pub const myriad2_1 = Cpu{
307 pub const myriad2_1 = CpuModel{
307308 .name = "myriad2_1",
308309 .llvm_name = "myriad2.1",
309310 .features = featureSet(&[_]Feature{
......@@ -311,7 +312,7 @@ pub const cpu = struct {
311312 .leon,
312313 }),
313314 };
314 pub const myriad2_2 = Cpu{
315 pub const myriad2_2 = CpuModel{
315316 .name = "myriad2_2",
316317 .llvm_name = "myriad2.2",
317318 .features = featureSet(&[_]Feature{
......@@ -319,7 +320,7 @@ pub const cpu = struct {
319320 .leon,
320321 }),
321322 };
322 pub const myriad2_3 = Cpu{
323 pub const myriad2_3 = CpuModel{
323324 .name = "myriad2_3",
324325 .llvm_name = "myriad2.3",
325326 .features = featureSet(&[_]Feature{
......@@ -327,7 +328,7 @@ pub const cpu = struct {
327328 .leon,
328329 }),
329330 };
330 pub const niagara = Cpu{
331 pub const niagara = CpuModel{
331332 .name = "niagara",
332333 .llvm_name = "niagara",
333334 .features = featureSet(&[_]Feature{
......@@ -337,7 +338,7 @@ pub const cpu = struct {
337338 .vis2,
338339 }),
339340 };
340 pub const niagara2 = Cpu{
341 pub const niagara2 = CpuModel{
341342 .name = "niagara2",
342343 .llvm_name = "niagara2",
343344 .features = featureSet(&[_]Feature{
......@@ -348,7 +349,7 @@ pub const cpu = struct {
348349 .vis2,
349350 }),
350351 };
351 pub const niagara3 = Cpu{
352 pub const niagara3 = CpuModel{
352353 .name = "niagara3",
353354 .llvm_name = "niagara3",
354355 .features = featureSet(&[_]Feature{
......@@ -359,7 +360,7 @@ pub const cpu = struct {
359360 .vis2,
360361 }),
361362 };
362 pub const niagara4 = Cpu{
363 pub const niagara4 = CpuModel{
363364 .name = "niagara4",
364365 .llvm_name = "niagara4",
365366 .features = featureSet(&[_]Feature{
......@@ -371,32 +372,32 @@ pub const cpu = struct {
371372 .vis3,
372373 }),
373374 };
374 pub const sparclet = Cpu{
375 pub const sparclet = CpuModel{
375376 .name = "sparclet",
376377 .llvm_name = "sparclet",
377378 .features = featureSet(&[_]Feature{}),
378379 };
379 pub const sparclite = Cpu{
380 pub const sparclite = CpuModel{
380381 .name = "sparclite",
381382 .llvm_name = "sparclite",
382383 .features = featureSet(&[_]Feature{}),
383384 };
384 pub const sparclite86x = Cpu{
385 pub const sparclite86x = CpuModel{
385386 .name = "sparclite86x",
386387 .llvm_name = "sparclite86x",
387388 .features = featureSet(&[_]Feature{}),
388389 };
389 pub const supersparc = Cpu{
390 pub const supersparc = CpuModel{
390391 .name = "supersparc",
391392 .llvm_name = "supersparc",
392393 .features = featureSet(&[_]Feature{}),
393394 };
394 pub const tsc701 = Cpu{
395 pub const tsc701 = CpuModel{
395396 .name = "tsc701",
396397 .llvm_name = "tsc701",
397398 .features = featureSet(&[_]Feature{}),
398399 };
399 pub const ultrasparc = Cpu{
400 pub const ultrasparc = CpuModel{
400401 .name = "ultrasparc",
401402 .llvm_name = "ultrasparc",
402403 .features = featureSet(&[_]Feature{
......@@ -405,7 +406,7 @@ pub const cpu = struct {
405406 .vis,
406407 }),
407408 };
408 pub const ultrasparc3 = Cpu{
409 pub const ultrasparc3 = CpuModel{
409410 .name = "ultrasparc3",
410411 .llvm_name = "ultrasparc3",
411412 .features = featureSet(&[_]Feature{
......@@ -415,7 +416,7 @@ pub const cpu = struct {
415416 .vis2,
416417 }),
417418 };
418 pub const ut699 = Cpu{
419 pub const ut699 = CpuModel{
419420 .name = "ut699",
420421 .llvm_name = "ut699",
421422 .features = featureSet(&[_]Feature{
......@@ -426,7 +427,7 @@ pub const cpu = struct {
426427 .no_fsmuld,
427428 }),
428429 };
429 pub const v7 = Cpu{
430 pub const v7 = CpuModel{
430431 .name = "v7",
431432 .llvm_name = "v7",
432433 .features = featureSet(&[_]Feature{
......@@ -434,12 +435,12 @@ pub const cpu = struct {
434435 .soft_mul_div,
435436 }),
436437 };
437 pub const v8 = Cpu{
438 pub const v8 = CpuModel{
438439 .name = "v8",
439440 .llvm_name = "v8",
440441 .features = featureSet(&[_]Feature{}),
441442 };
442 pub const v9 = Cpu{
443 pub const v9 = CpuModel{
443444 .name = "v9",
444445 .llvm_name = "v9",
445446 .features = featureSet(&[_]Feature{
......@@ -451,7 +452,7 @@ pub const cpu = struct {
451452/// All sparc CPUs, sorted alphabetically by name.
452453/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
453454/// compiler has inefficient memory and CPU usage, affecting build times.
454pub const all_cpus = &[_]*const Cpu{
455pub const all_cpus = &[_]*const CpuModel{
455456 &cpu.at697e,
456457 &cpu.at697f,
457458 &cpu.f934,
lib/std/target/systemz.zig+19-18
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 deflate_conversion,
......@@ -39,12 +40,12 @@ pub const Feature = enum {
3940 vector_packed_decimal_enhancement,
4041};
4142
42pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
43pub usingnamespace CpuFeature.feature_set_fns(Feature);
4344
4445pub const all_features = blk: {
4546 const len = @typeInfo(Feature).Enum.fields.len;
46 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
47 var result: [len]Cpu.Feature = undefined;
47 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
48 var result: [len]CpuFeature = undefined;
4849 result[@enumToInt(Feature.deflate_conversion)] = .{
4950 .llvm_name = "deflate-conversion",
5051 .description = "Assume that the deflate-conversion facility is installed",
......@@ -229,7 +230,7 @@ pub const all_features = blk: {
229230};
230231
231232pub const cpu = struct {
232 pub const arch10 = Cpu{
233 pub const arch10 = CpuModel{
233234 .name = "arch10",
234235 .llvm_name = "arch10",
235236 .features = featureSet(&[_]Feature{
......@@ -252,7 +253,7 @@ pub const cpu = struct {
252253 .transactional_execution,
253254 }),
254255 };
255 pub const arch11 = Cpu{
256 pub const arch11 = CpuModel{
256257 .name = "arch11",
257258 .llvm_name = "arch11",
258259 .features = featureSet(&[_]Feature{
......@@ -280,7 +281,7 @@ pub const cpu = struct {
280281 .vector,
281282 }),
282283 };
283 pub const arch12 = Cpu{
284 pub const arch12 = CpuModel{
284285 .name = "arch12",
285286 .llvm_name = "arch12",
286287 .features = featureSet(&[_]Feature{
......@@ -315,7 +316,7 @@ pub const cpu = struct {
315316 .vector_packed_decimal,
316317 }),
317318 };
318 pub const arch13 = Cpu{
319 pub const arch13 = CpuModel{
319320 .name = "arch13",
320321 .llvm_name = "arch13",
321322 .features = featureSet(&[_]Feature{
......@@ -356,12 +357,12 @@ pub const cpu = struct {
356357 .vector_packed_decimal_enhancement,
357358 }),
358359 };
359 pub const arch8 = Cpu{
360 pub const arch8 = CpuModel{
360361 .name = "arch8",
361362 .llvm_name = "arch8",
362363 .features = featureSet(&[_]Feature{}),
363364 };
364 pub const arch9 = Cpu{
365 pub const arch9 = CpuModel{
365366 .name = "arch9",
366367 .llvm_name = "arch9",
367368 .features = featureSet(&[_]Feature{
......@@ -377,17 +378,17 @@ pub const cpu = struct {
377378 .reset_reference_bits_multiple,
378379 }),
379380 };
380 pub const generic = Cpu{
381 pub const generic = CpuModel{
381382 .name = "generic",
382383 .llvm_name = "generic",
383384 .features = featureSet(&[_]Feature{}),
384385 };
385 pub const z10 = Cpu{
386 pub const z10 = CpuModel{
386387 .name = "z10",
387388 .llvm_name = "z10",
388389 .features = featureSet(&[_]Feature{}),
389390 };
390 pub const z13 = Cpu{
391 pub const z13 = CpuModel{
391392 .name = "z13",
392393 .llvm_name = "z13",
393394 .features = featureSet(&[_]Feature{
......@@ -415,7 +416,7 @@ pub const cpu = struct {
415416 .vector,
416417 }),
417418 };
418 pub const z14 = Cpu{
419 pub const z14 = CpuModel{
419420 .name = "z14",
420421 .llvm_name = "z14",
421422 .features = featureSet(&[_]Feature{
......@@ -450,7 +451,7 @@ pub const cpu = struct {
450451 .vector_packed_decimal,
451452 }),
452453 };
453 pub const z15 = Cpu{
454 pub const z15 = CpuModel{
454455 .name = "z15",
455456 .llvm_name = "z15",
456457 .features = featureSet(&[_]Feature{
......@@ -491,7 +492,7 @@ pub const cpu = struct {
491492 .vector_packed_decimal_enhancement,
492493 }),
493494 };
494 pub const z196 = Cpu{
495 pub const z196 = CpuModel{
495496 .name = "z196",
496497 .llvm_name = "z196",
497498 .features = featureSet(&[_]Feature{
......@@ -507,7 +508,7 @@ pub const cpu = struct {
507508 .reset_reference_bits_multiple,
508509 }),
509510 };
510 pub const zEC12 = Cpu{
511 pub const zEC12 = CpuModel{
511512 .name = "zEC12",
512513 .llvm_name = "zEC12",
513514 .features = featureSet(&[_]Feature{
......@@ -535,7 +536,7 @@ pub const cpu = struct {
535536/// All systemz CPUs, sorted alphabetically by name.
536537/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
537538/// compiler has inefficient memory and CPU usage, affecting build times.
538pub const all_cpus = &[_]*const Cpu{
539pub const all_cpus = &[_]*const CpuModel{
539540 &cpu.arch10,
540541 &cpu.arch11,
541542 &cpu.arch12,
lib/std/target/wasm.zig+9-8
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 atomics,
......@@ -14,12 +15,12 @@ pub const Feature = enum {
1415 unimplemented_simd128,
1516};
1617
17pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
18pub usingnamespace CpuFeature.feature_set_fns(Feature);
1819
1920pub const all_features = blk: {
2021 const len = @typeInfo(Feature).Enum.fields.len;
21 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
22 var result: [len]Cpu.Feature = undefined;
22 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
23 var result: [len]CpuFeature = undefined;
2324 result[@enumToInt(Feature.atomics)] = .{
2425 .llvm_name = "atomics",
2526 .description = "Enable Atomics",
......@@ -81,7 +82,7 @@ pub const all_features = blk: {
8182};
8283
8384pub const cpu = struct {
84 pub const bleeding_edge = Cpu{
85 pub const bleeding_edge = CpuModel{
8586 .name = "bleeding_edge",
8687 .llvm_name = "bleeding-edge",
8788 .features = featureSet(&[_]Feature{
......@@ -92,12 +93,12 @@ pub const cpu = struct {
9293 .simd128,
9394 }),
9495 };
95 pub const generic = Cpu{
96 pub const generic = CpuModel{
9697 .name = "generic",
9798 .llvm_name = "generic",
9899 .features = featureSet(&[_]Feature{}),
99100 };
100 pub const mvp = Cpu{
101 pub const mvp = CpuModel{
101102 .name = "mvp",
102103 .llvm_name = "mvp",
103104 .features = featureSet(&[_]Feature{}),
......@@ -107,7 +108,7 @@ pub const cpu = struct {
107108/// All wasm CPUs, sorted alphabetically by name.
108109/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
109110/// compiler has inefficient memory and CPU usage, affecting build times.
110pub const all_cpus = &[_]*const Cpu{
111pub const all_cpus = &[_]*const CpuModel{
111112 &cpu.bleeding_edge,
112113 &cpu.generic,
113114 &cpu.mvp,
lib/std/target/x86.zig+85-84
......@@ -1,5 +1,6 @@
11const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;
2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
45pub const Feature = enum {
56 @"3dnow",
......@@ -129,12 +130,12 @@ pub const Feature = enum {
129130 xsaves,
130131};
131132
132pub usingnamespace Cpu.Feature.feature_set_fns(Feature);
133pub usingnamespace CpuFeature.feature_set_fns(Feature);
133134
134135pub const all_features = blk: {
135136 const len = @typeInfo(Feature).Enum.fields.len;
136 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);
137 var result: [len]Cpu.Feature = undefined;
137 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
138 var result: [len]CpuFeature = undefined;
138139 result[@enumToInt(Feature.@"3dnow")] = .{
139140 .llvm_name = "3dnow",
140141 .description = "Enable 3DNow! instructions",
......@@ -851,7 +852,7 @@ pub const all_features = blk: {
851852};
852853
853854pub const cpu = struct {
854 pub const amdfam10 = Cpu{
855 pub const amdfam10 = CpuModel{
855856 .name = "amdfam10",
856857 .llvm_name = "amdfam10",
857858 .features = featureSet(&[_]Feature{
......@@ -872,7 +873,7 @@ pub const cpu = struct {
872873 .x87,
873874 }),
874875 };
875 pub const athlon = Cpu{
876 pub const athlon = CpuModel{
876877 .name = "athlon",
877878 .llvm_name = "athlon",
878879 .features = featureSet(&[_]Feature{
......@@ -886,7 +887,7 @@ pub const cpu = struct {
886887 .x87,
887888 }),
888889 };
889 pub const athlon_4 = Cpu{
890 pub const athlon_4 = CpuModel{
890891 .name = "athlon_4",
891892 .llvm_name = "athlon-4",
892893 .features = featureSet(&[_]Feature{
......@@ -902,7 +903,7 @@ pub const cpu = struct {
902903 .x87,
903904 }),
904905 };
905 pub const athlon_fx = Cpu{
906 pub const athlon_fx = CpuModel{
906907 .name = "athlon_fx",
907908 .llvm_name = "athlon-fx",
908909 .features = featureSet(&[_]Feature{
......@@ -920,7 +921,7 @@ pub const cpu = struct {
920921 .x87,
921922 }),
922923 };
923 pub const athlon_mp = Cpu{
924 pub const athlon_mp = CpuModel{
924925 .name = "athlon_mp",
925926 .llvm_name = "athlon-mp",
926927 .features = featureSet(&[_]Feature{
......@@ -936,7 +937,7 @@ pub const cpu = struct {
936937 .x87,
937938 }),
938939 };
939 pub const athlon_tbird = Cpu{
940 pub const athlon_tbird = CpuModel{
940941 .name = "athlon_tbird",
941942 .llvm_name = "athlon-tbird",
942943 .features = featureSet(&[_]Feature{
......@@ -950,7 +951,7 @@ pub const cpu = struct {
950951 .x87,
951952 }),
952953 };
953 pub const athlon_xp = Cpu{
954 pub const athlon_xp = CpuModel{
954955 .name = "athlon_xp",
955956 .llvm_name = "athlon-xp",
956957 .features = featureSet(&[_]Feature{
......@@ -966,7 +967,7 @@ pub const cpu = struct {
966967 .x87,
967968 }),
968969 };
969 pub const athlon64 = Cpu{
970 pub const athlon64 = CpuModel{
970971 .name = "athlon64",
971972 .llvm_name = "athlon64",
972973 .features = featureSet(&[_]Feature{
......@@ -984,7 +985,7 @@ pub const cpu = struct {
984985 .x87,
985986 }),
986987 };
987 pub const athlon64_sse3 = Cpu{
988 pub const athlon64_sse3 = CpuModel{
988989 .name = "athlon64_sse3",
989990 .llvm_name = "athlon64-sse3",
990991 .features = featureSet(&[_]Feature{
......@@ -1003,7 +1004,7 @@ pub const cpu = struct {
10031004 .x87,
10041005 }),
10051006 };
1006 pub const atom = Cpu{
1007 pub const atom = CpuModel{
10071008 .name = "atom",
10081009 .llvm_name = "atom",
10091010 .features = featureSet(&[_]Feature{
......@@ -1028,7 +1029,7 @@ pub const cpu = struct {
10281029 .x87,
10291030 }),
10301031 };
1031 pub const barcelona = Cpu{
1032 pub const barcelona = CpuModel{
10321033 .name = "barcelona",
10331034 .llvm_name = "barcelona",
10341035 .features = featureSet(&[_]Feature{
......@@ -1049,7 +1050,7 @@ pub const cpu = struct {
10491050 .x87,
10501051 }),
10511052 };
1052 pub const bdver1 = Cpu{
1053 pub const bdver1 = CpuModel{
10531054 .name = "bdver1",
10541055 .llvm_name = "bdver1",
10551056 .features = featureSet(&[_]Feature{
......@@ -1077,7 +1078,7 @@ pub const cpu = struct {
10771078 .xsave,
10781079 }),
10791080 };
1080 pub const bdver2 = Cpu{
1081 pub const bdver2 = CpuModel{
10811082 .name = "bdver2",
10821083 .llvm_name = "bdver2",
10831084 .features = featureSet(&[_]Feature{
......@@ -1110,7 +1111,7 @@ pub const cpu = struct {
11101111 .xsave,
11111112 }),
11121113 };
1113 pub const bdver3 = Cpu{
1114 pub const bdver3 = CpuModel{
11141115 .name = "bdver3",
11151116 .llvm_name = "bdver3",
11161117 .features = featureSet(&[_]Feature{
......@@ -1145,7 +1146,7 @@ pub const cpu = struct {
11451146 .xsaveopt,
11461147 }),
11471148 };
1148 pub const bdver4 = Cpu{
1149 pub const bdver4 = CpuModel{
11491150 .name = "bdver4",
11501151 .llvm_name = "bdver4",
11511152 .features = featureSet(&[_]Feature{
......@@ -1183,7 +1184,7 @@ pub const cpu = struct {
11831184 .xsaveopt,
11841185 }),
11851186 };
1186 pub const bonnell = Cpu{
1187 pub const bonnell = CpuModel{
11871188 .name = "bonnell",
11881189 .llvm_name = "bonnell",
11891190 .features = featureSet(&[_]Feature{
......@@ -1208,7 +1209,7 @@ pub const cpu = struct {
12081209 .x87,
12091210 }),
12101211 };
1211 pub const broadwell = Cpu{
1212 pub const broadwell = CpuModel{
12121213 .name = "broadwell",
12131214 .llvm_name = "broadwell",
12141215 .features = featureSet(&[_]Feature{
......@@ -1253,7 +1254,7 @@ pub const cpu = struct {
12531254 .xsaveopt,
12541255 }),
12551256 };
1256 pub const btver1 = Cpu{
1257 pub const btver1 = CpuModel{
12571258 .name = "btver1",
12581259 .llvm_name = "btver1",
12591260 .features = featureSet(&[_]Feature{
......@@ -1278,7 +1279,7 @@ pub const cpu = struct {
12781279 .x87,
12791280 }),
12801281 };
1281 pub const btver2 = Cpu{
1282 pub const btver2 = CpuModel{
12821283 .name = "btver2",
12831284 .llvm_name = "btver2",
12841285 .features = featureSet(&[_]Feature{
......@@ -1313,7 +1314,7 @@ pub const cpu = struct {
13131314 .xsaveopt,
13141315 }),
13151316 };
1316 pub const c3 = Cpu{
1317 pub const c3 = CpuModel{
13171318 .name = "c3",
13181319 .llvm_name = "c3",
13191320 .features = featureSet(&[_]Feature{
......@@ -1323,7 +1324,7 @@ pub const cpu = struct {
13231324 .x87,
13241325 }),
13251326 };
1326 pub const c3_2 = Cpu{
1327 pub const c3_2 = CpuModel{
13271328 .name = "c3_2",
13281329 .llvm_name = "c3-2",
13291330 .features = featureSet(&[_]Feature{
......@@ -1337,7 +1338,7 @@ pub const cpu = struct {
13371338 .x87,
13381339 }),
13391340 };
1340 pub const cannonlake = Cpu{
1341 pub const cannonlake = CpuModel{
13411342 .name = "cannonlake",
13421343 .llvm_name = "cannonlake",
13431344 .features = featureSet(&[_]Feature{
......@@ -1397,7 +1398,7 @@ pub const cpu = struct {
13971398 .xsaves,
13981399 }),
13991400 };
1400 pub const cascadelake = Cpu{
1401 pub const cascadelake = CpuModel{
14011402 .name = "cascadelake",
14021403 .llvm_name = "cascadelake",
14031404 .features = featureSet(&[_]Feature{
......@@ -1456,7 +1457,7 @@ pub const cpu = struct {
14561457 .xsaves,
14571458 }),
14581459 };
1459 pub const cooperlake = Cpu{
1460 pub const cooperlake = CpuModel{
14601461 .name = "cooperlake",
14611462 .llvm_name = "cooperlake",
14621463 .features = featureSet(&[_]Feature{
......@@ -1516,7 +1517,7 @@ pub const cpu = struct {
15161517 .xsaves,
15171518 }),
15181519 };
1519 pub const core_avx_i = Cpu{
1520 pub const core_avx_i = CpuModel{
15201521 .name = "core_avx_i",
15211522 .llvm_name = "core-avx-i",
15221523 .features = featureSet(&[_]Feature{
......@@ -1549,7 +1550,7 @@ pub const cpu = struct {
15491550 .xsaveopt,
15501551 }),
15511552 };
1552 pub const core_avx2 = Cpu{
1553 pub const core_avx2 = CpuModel{
15531554 .name = "core_avx2",
15541555 .llvm_name = "core-avx2",
15551556 .features = featureSet(&[_]Feature{
......@@ -1591,7 +1592,7 @@ pub const cpu = struct {
15911592 .xsaveopt,
15921593 }),
15931594 };
1594 pub const core2 = Cpu{
1595 pub const core2 = CpuModel{
15951596 .name = "core2",
15961597 .llvm_name = "core2",
15971598 .features = featureSet(&[_]Feature{
......@@ -1610,7 +1611,7 @@ pub const cpu = struct {
16101611 .x87,
16111612 }),
16121613 };
1613 pub const corei7 = Cpu{
1614 pub const corei7 = CpuModel{
16141615 .name = "corei7",
16151616 .llvm_name = "corei7",
16161617 .features = featureSet(&[_]Feature{
......@@ -1629,7 +1630,7 @@ pub const cpu = struct {
16291630 .x87,
16301631 }),
16311632 };
1632 pub const corei7_avx = Cpu{
1633 pub const corei7_avx = CpuModel{
16331634 .name = "corei7_avx",
16341635 .llvm_name = "corei7-avx",
16351636 .features = featureSet(&[_]Feature{
......@@ -1659,7 +1660,7 @@ pub const cpu = struct {
16591660 .xsaveopt,
16601661 }),
16611662 };
1662 pub const generic = Cpu{
1663 pub const generic = CpuModel{
16631664 .name = "generic",
16641665 .llvm_name = "generic",
16651666 .features = featureSet(&[_]Feature{
......@@ -1669,7 +1670,7 @@ pub const cpu = struct {
16691670 .x87,
16701671 }),
16711672 };
1672 pub const geode = Cpu{
1673 pub const geode = CpuModel{
16731674 .name = "geode",
16741675 .llvm_name = "geode",
16751676 .features = featureSet(&[_]Feature{
......@@ -1680,7 +1681,7 @@ pub const cpu = struct {
16801681 .x87,
16811682 }),
16821683 };
1683 pub const goldmont = Cpu{
1684 pub const goldmont = CpuModel{
16841685 .name = "goldmont",
16851686 .llvm_name = "goldmont",
16861687 .features = featureSet(&[_]Feature{
......@@ -1717,7 +1718,7 @@ pub const cpu = struct {
17171718 .xsaves,
17181719 }),
17191720 };
1720 pub const goldmont_plus = Cpu{
1721 pub const goldmont_plus = CpuModel{
17211722 .name = "goldmont_plus",
17221723 .llvm_name = "goldmont-plus",
17231724 .features = featureSet(&[_]Feature{
......@@ -1756,7 +1757,7 @@ pub const cpu = struct {
17561757 .xsaves,
17571758 }),
17581759 };
1759 pub const haswell = Cpu{
1760 pub const haswell = CpuModel{
17601761 .name = "haswell",
17611762 .llvm_name = "haswell",
17621763 .features = featureSet(&[_]Feature{
......@@ -1798,7 +1799,7 @@ pub const cpu = struct {
17981799 .xsaveopt,
17991800 }),
18001801 };
1801 pub const _i386 = Cpu{
1802 pub const _i386 = CpuModel{
18021803 .name = "_i386",
18031804 .llvm_name = "i386",
18041805 .features = featureSet(&[_]Feature{
......@@ -1807,7 +1808,7 @@ pub const cpu = struct {
18071808 .x87,
18081809 }),
18091810 };
1810 pub const _i486 = Cpu{
1811 pub const _i486 = CpuModel{
18111812 .name = "_i486",
18121813 .llvm_name = "i486",
18131814 .features = featureSet(&[_]Feature{
......@@ -1816,7 +1817,7 @@ pub const cpu = struct {
18161817 .x87,
18171818 }),
18181819 };
1819 pub const _i586 = Cpu{
1820 pub const _i586 = CpuModel{
18201821 .name = "_i586",
18211822 .llvm_name = "i586",
18221823 .features = featureSet(&[_]Feature{
......@@ -1826,7 +1827,7 @@ pub const cpu = struct {
18261827 .x87,
18271828 }),
18281829 };
1829 pub const _i686 = Cpu{
1830 pub const _i686 = CpuModel{
18301831 .name = "_i686",
18311832 .llvm_name = "i686",
18321833 .features = featureSet(&[_]Feature{
......@@ -1837,7 +1838,7 @@ pub const cpu = struct {
18371838 .x87,
18381839 }),
18391840 };
1840 pub const icelake_client = Cpu{
1841 pub const icelake_client = CpuModel{
18411842 .name = "icelake_client",
18421843 .llvm_name = "icelake-client",
18431844 .features = featureSet(&[_]Feature{
......@@ -1906,7 +1907,7 @@ pub const cpu = struct {
19061907 .xsaves,
19071908 }),
19081909 };
1909 pub const icelake_server = Cpu{
1910 pub const icelake_server = CpuModel{
19101911 .name = "icelake_server",
19111912 .llvm_name = "icelake-server",
19121913 .features = featureSet(&[_]Feature{
......@@ -1977,7 +1978,7 @@ pub const cpu = struct {
19771978 .xsaves,
19781979 }),
19791980 };
1980 pub const ivybridge = Cpu{
1981 pub const ivybridge = CpuModel{
19811982 .name = "ivybridge",
19821983 .llvm_name = "ivybridge",
19831984 .features = featureSet(&[_]Feature{
......@@ -2010,7 +2011,7 @@ pub const cpu = struct {
20102011 .xsaveopt,
20112012 }),
20122013 };
2013 pub const k6 = Cpu{
2014 pub const k6 = CpuModel{
20142015 .name = "k6",
20152016 .llvm_name = "k6",
20162017 .features = featureSet(&[_]Feature{
......@@ -2021,7 +2022,7 @@ pub const cpu = struct {
20212022 .x87,
20222023 }),
20232024 };
2024 pub const k6_2 = Cpu{
2025 pub const k6_2 = CpuModel{
20252026 .name = "k6_2",
20262027 .llvm_name = "k6-2",
20272028 .features = featureSet(&[_]Feature{
......@@ -2032,7 +2033,7 @@ pub const cpu = struct {
20322033 .x87,
20332034 }),
20342035 };
2035 pub const k6_3 = Cpu{
2036 pub const k6_3 = CpuModel{
20362037 .name = "k6_3",
20372038 .llvm_name = "k6-3",
20382039 .features = featureSet(&[_]Feature{
......@@ -2043,7 +2044,7 @@ pub const cpu = struct {
20432044 .x87,
20442045 }),
20452046 };
2046 pub const k8 = Cpu{
2047 pub const k8 = CpuModel{
20472048 .name = "k8",
20482049 .llvm_name = "k8",
20492050 .features = featureSet(&[_]Feature{
......@@ -2061,7 +2062,7 @@ pub const cpu = struct {
20612062 .x87,
20622063 }),
20632064 };
2064 pub const k8_sse3 = Cpu{
2065 pub const k8_sse3 = CpuModel{
20652066 .name = "k8_sse3",
20662067 .llvm_name = "k8-sse3",
20672068 .features = featureSet(&[_]Feature{
......@@ -2080,7 +2081,7 @@ pub const cpu = struct {
20802081 .x87,
20812082 }),
20822083 };
2083 pub const knl = Cpu{
2084 pub const knl = CpuModel{
20842085 .name = "knl",
20852086 .llvm_name = "knl",
20862087 .features = featureSet(&[_]Feature{
......@@ -2123,7 +2124,7 @@ pub const cpu = struct {
21232124 .xsaveopt,
21242125 }),
21252126 };
2126 pub const knm = Cpu{
2127 pub const knm = CpuModel{
21272128 .name = "knm",
21282129 .llvm_name = "knm",
21292130 .features = featureSet(&[_]Feature{
......@@ -2167,14 +2168,14 @@ pub const cpu = struct {
21672168 .xsaveopt,
21682169 }),
21692170 };
2170 pub const lakemont = Cpu{
2171 pub const lakemont = CpuModel{
21712172 .name = "lakemont",
21722173 .llvm_name = "lakemont",
21732174 .features = featureSet(&[_]Feature{
21742175 .vzeroupper,
21752176 }),
21762177 };
2177 pub const nehalem = Cpu{
2178 pub const nehalem = CpuModel{
21782179 .name = "nehalem",
21792180 .llvm_name = "nehalem",
21802181 .features = featureSet(&[_]Feature{
......@@ -2193,7 +2194,7 @@ pub const cpu = struct {
21932194 .x87,
21942195 }),
21952196 };
2196 pub const nocona = Cpu{
2197 pub const nocona = CpuModel{
21972198 .name = "nocona",
21982199 .llvm_name = "nocona",
21992200 .features = featureSet(&[_]Feature{
......@@ -2210,7 +2211,7 @@ pub const cpu = struct {
22102211 .x87,
22112212 }),
22122213 };
2213 pub const opteron = Cpu{
2214 pub const opteron = CpuModel{
22142215 .name = "opteron",
22152216 .llvm_name = "opteron",
22162217 .features = featureSet(&[_]Feature{
......@@ -2228,7 +2229,7 @@ pub const cpu = struct {
22282229 .x87,
22292230 }),
22302231 };
2231 pub const opteron_sse3 = Cpu{
2232 pub const opteron_sse3 = CpuModel{
22322233 .name = "opteron_sse3",
22332234 .llvm_name = "opteron-sse3",
22342235 .features = featureSet(&[_]Feature{
......@@ -2247,7 +2248,7 @@ pub const cpu = struct {
22472248 .x87,
22482249 }),
22492250 };
2250 pub const penryn = Cpu{
2251 pub const penryn = CpuModel{
22512252 .name = "penryn",
22522253 .llvm_name = "penryn",
22532254 .features = featureSet(&[_]Feature{
......@@ -2266,7 +2267,7 @@ pub const cpu = struct {
22662267 .x87,
22672268 }),
22682269 };
2269 pub const pentium = Cpu{
2270 pub const pentium = CpuModel{
22702271 .name = "pentium",
22712272 .llvm_name = "pentium",
22722273 .features = featureSet(&[_]Feature{
......@@ -2276,7 +2277,7 @@ pub const cpu = struct {
22762277 .x87,
22772278 }),
22782279 };
2279 pub const pentium_m = Cpu{
2280 pub const pentium_m = CpuModel{
22802281 .name = "pentium_m",
22812282 .llvm_name = "pentium-m",
22822283 .features = featureSet(&[_]Feature{
......@@ -2291,7 +2292,7 @@ pub const cpu = struct {
22912292 .x87,
22922293 }),
22932294 };
2294 pub const pentium_mmx = Cpu{
2295 pub const pentium_mmx = CpuModel{
22952296 .name = "pentium_mmx",
22962297 .llvm_name = "pentium-mmx",
22972298 .features = featureSet(&[_]Feature{
......@@ -2302,7 +2303,7 @@ pub const cpu = struct {
23022303 .x87,
23032304 }),
23042305 };
2305 pub const pentium2 = Cpu{
2306 pub const pentium2 = CpuModel{
23062307 .name = "pentium2",
23072308 .llvm_name = "pentium2",
23082309 .features = featureSet(&[_]Feature{
......@@ -2316,7 +2317,7 @@ pub const cpu = struct {
23162317 .x87,
23172318 }),
23182319 };
2319 pub const pentium3 = Cpu{
2320 pub const pentium3 = CpuModel{
23202321 .name = "pentium3",
23212322 .llvm_name = "pentium3",
23222323 .features = featureSet(&[_]Feature{
......@@ -2331,7 +2332,7 @@ pub const cpu = struct {
23312332 .x87,
23322333 }),
23332334 };
2334 pub const pentium3m = Cpu{
2335 pub const pentium3m = CpuModel{
23352336 .name = "pentium3m",
23362337 .llvm_name = "pentium3m",
23372338 .features = featureSet(&[_]Feature{
......@@ -2346,7 +2347,7 @@ pub const cpu = struct {
23462347 .x87,
23472348 }),
23482349 };
2349 pub const pentium4 = Cpu{
2350 pub const pentium4 = CpuModel{
23502351 .name = "pentium4",
23512352 .llvm_name = "pentium4",
23522353 .features = featureSet(&[_]Feature{
......@@ -2361,7 +2362,7 @@ pub const cpu = struct {
23612362 .x87,
23622363 }),
23632364 };
2364 pub const pentium4m = Cpu{
2365 pub const pentium4m = CpuModel{
23652366 .name = "pentium4m",
23662367 .llvm_name = "pentium4m",
23672368 .features = featureSet(&[_]Feature{
......@@ -2376,7 +2377,7 @@ pub const cpu = struct {
23762377 .x87,
23772378 }),
23782379 };
2379 pub const pentiumpro = Cpu{
2380 pub const pentiumpro = CpuModel{
23802381 .name = "pentiumpro",
23812382 .llvm_name = "pentiumpro",
23822383 .features = featureSet(&[_]Feature{
......@@ -2388,7 +2389,7 @@ pub const cpu = struct {
23882389 .x87,
23892390 }),
23902391 };
2391 pub const prescott = Cpu{
2392 pub const prescott = CpuModel{
23922393 .name = "prescott",
23932394 .llvm_name = "prescott",
23942395 .features = featureSet(&[_]Feature{
......@@ -2403,7 +2404,7 @@ pub const cpu = struct {
24032404 .x87,
24042405 }),
24052406 };
2406 pub const sandybridge = Cpu{
2407 pub const sandybridge = CpuModel{
24072408 .name = "sandybridge",
24082409 .llvm_name = "sandybridge",
24092410 .features = featureSet(&[_]Feature{
......@@ -2433,7 +2434,7 @@ pub const cpu = struct {
24332434 .xsaveopt,
24342435 }),
24352436 };
2436 pub const silvermont = Cpu{
2437 pub const silvermont = CpuModel{
24372438 .name = "silvermont",
24382439 .llvm_name = "silvermont",
24392440 .features = featureSet(&[_]Feature{
......@@ -2462,7 +2463,7 @@ pub const cpu = struct {
24622463 .x87,
24632464 }),
24642465 };
2465 pub const skx = Cpu{
2466 pub const skx = CpuModel{
24662467 .name = "skx",
24672468 .llvm_name = "skx",
24682469 .features = featureSet(&[_]Feature{
......@@ -2520,7 +2521,7 @@ pub const cpu = struct {
25202521 .xsaves,
25212522 }),
25222523 };
2523 pub const skylake = Cpu{
2524 pub const skylake = CpuModel{
25242525 .name = "skylake",
25252526 .llvm_name = "skylake",
25262527 .features = featureSet(&[_]Feature{
......@@ -2571,7 +2572,7 @@ pub const cpu = struct {
25712572 .xsaves,
25722573 }),
25732574 };
2574 pub const skylake_avx512 = Cpu{
2575 pub const skylake_avx512 = CpuModel{
25752576 .name = "skylake_avx512",
25762577 .llvm_name = "skylake-avx512",
25772578 .features = featureSet(&[_]Feature{
......@@ -2629,7 +2630,7 @@ pub const cpu = struct {
26292630 .xsaves,
26302631 }),
26312632 };
2632 pub const slm = Cpu{
2633 pub const slm = CpuModel{
26332634 .name = "slm",
26342635 .llvm_name = "slm",
26352636 .features = featureSet(&[_]Feature{
......@@ -2658,7 +2659,7 @@ pub const cpu = struct {
26582659 .x87,
26592660 }),
26602661 };
2661 pub const tigerlake = Cpu{
2662 pub const tigerlake = CpuModel{
26622663 .name = "tigerlake",
26632664 .llvm_name = "tigerlake",
26642665 .features = featureSet(&[_]Feature{
......@@ -2731,7 +2732,7 @@ pub const cpu = struct {
27312732 .xsaves,
27322733 }),
27332734 };
2734 pub const tremont = Cpu{
2735 pub const tremont = CpuModel{
27352736 .name = "tremont",
27362737 .llvm_name = "tremont",
27372738 .features = featureSet(&[_]Feature{
......@@ -2775,7 +2776,7 @@ pub const cpu = struct {
27752776 .xsaves,
27762777 }),
27772778 };
2778 pub const westmere = Cpu{
2779 pub const westmere = CpuModel{
27792780 .name = "westmere",
27802781 .llvm_name = "westmere",
27812782 .features = featureSet(&[_]Feature{
......@@ -2795,7 +2796,7 @@ pub const cpu = struct {
27952796 .x87,
27962797 }),
27972798 };
2798 pub const winchip_c6 = Cpu{
2799 pub const winchip_c6 = CpuModel{
27992800 .name = "winchip_c6",
28002801 .llvm_name = "winchip-c6",
28012802 .features = featureSet(&[_]Feature{
......@@ -2805,7 +2806,7 @@ pub const cpu = struct {
28052806 .x87,
28062807 }),
28072808 };
2808 pub const winchip2 = Cpu{
2809 pub const winchip2 = CpuModel{
28092810 .name = "winchip2",
28102811 .llvm_name = "winchip2",
28112812 .features = featureSet(&[_]Feature{
......@@ -2815,7 +2816,7 @@ pub const cpu = struct {
28152816 .x87,
28162817 }),
28172818 };
2818 pub const x86_64 = Cpu{
2819 pub const x86_64 = CpuModel{
28192820 .name = "x86_64",
28202821 .llvm_name = "x86-64",
28212822 .features = featureSet(&[_]Feature{
......@@ -2833,7 +2834,7 @@ pub const cpu = struct {
28332834 .x87,
28342835 }),
28352836 };
2836 pub const yonah = Cpu{
2837 pub const yonah = CpuModel{
28372838 .name = "yonah",
28382839 .llvm_name = "yonah",
28392840 .features = featureSet(&[_]Feature{
......@@ -2848,7 +2849,7 @@ pub const cpu = struct {
28482849 .x87,
28492850 }),
28502851 };
2851 pub const znver1 = Cpu{
2852 pub const znver1 = CpuModel{
28522853 .name = "znver1",
28532854 .llvm_name = "znver1",
28542855 .features = featureSet(&[_]Feature{
......@@ -2893,7 +2894,7 @@ pub const cpu = struct {
28932894 .xsaves,
28942895 }),
28952896 };
2896 pub const znver2 = Cpu{
2897 pub const znver2 = CpuModel{
28972898 .name = "znver2",
28982899 .llvm_name = "znver2",
28992900 .features = featureSet(&[_]Feature{
......@@ -2946,7 +2947,7 @@ pub const cpu = struct {
29462947/// All x86 CPUs, sorted alphabetically by name.
29472948/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
29482949/// compiler has inefficient memory and CPU usage, affecting build times.
2949pub const all_cpus = &[_]*const Cpu{
2950pub const all_cpus = &[_]*const CpuModel{
29502951 &cpu.amdfam10,
29512952 &cpu.athlon,
29522953 &cpu.athlon_4,
lib/std/thread.zig+3-3
......@@ -148,7 +148,7 @@ pub const Thread = struct {
148148 const default_stack_size = 16 * 1024 * 1024;
149149
150150 const Context = @TypeOf(context);
151 comptime assert(@ArgType(@TypeOf(startFn), 0) == Context);
151 comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context);
152152
153153 if (builtin.os == builtin.Os.windows) {
154154 const WinThread = struct {
......@@ -158,7 +158,7 @@ pub const Thread = struct {
158158 };
159159 fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD {
160160 const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*;
161 switch (@typeId(@TypeOf(startFn).ReturnType)) {
161 switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
162162 .Int => {
163163 return startFn(arg);
164164 },
......@@ -201,7 +201,7 @@ pub const Thread = struct {
201201 fn linuxThreadMain(ctx_addr: usize) callconv(.C) u8 {
202202 const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*;
203203
204 switch (@typeId(@TypeOf(startFn).ReturnType)) {
204 switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
205205 .Int => {
206206 return startFn(arg);
207207 },
lib/std/time.zig+14-9
......@@ -8,6 +8,7 @@ const math = std.math;
88pub const epoch = @import("time/epoch.zig");
99
1010/// Spurious wakeups are possible and no precision of timing is guaranteed.
11/// TODO integrate with evented I/O
1112pub fn sleep(nanoseconds: u64) void {
1213 if (builtin.os == .windows) {
1314 const ns_per_ms = ns_per_s / ms_per_s;
......@@ -152,15 +153,9 @@ pub const Timer = struct {
152153 }
153154
154155 /// Reads the timer value since start or the last reset in nanoseconds
155 pub fn read(self: *Timer) u64 {
156 pub fn read(self: Timer) u64 {
156157 var clock = clockNative() - self.start_time;
157 if (builtin.os == .windows) {
158 return @divFloor(clock * ns_per_s, self.frequency);
159 }
160 if (comptime std.Target.current.isDarwin()) {
161 return @divFloor(clock * self.frequency.numer, self.frequency.denom);
162 }
163 return clock;
158 return self.nativeDurationToNanos(clock);
164159 }
165160
166161 /// Resets the timer value to 0/now.
......@@ -171,7 +166,7 @@ pub const Timer = struct {
171166 /// Returns the current value of the timer in nanoseconds, then resets it
172167 pub fn lap(self: *Timer) u64 {
173168 var now = clockNative();
174 var lap_time = self.read();
169 var lap_time = self.nativeDurationToNanos(now - self.start_time);
175170 self.start_time = now;
176171 return lap_time;
177172 }
......@@ -187,6 +182,16 @@ pub const Timer = struct {
187182 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
188183 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
189184 }
185
186 fn nativeDurationToNanos(self: Timer, duration: u64) u64 {
187 if (builtin.os == .windows) {
188 return @divFloor(duration * ns_per_s, self.frequency);
189 }
190 if (comptime std.Target.current.isDarwin()) {
191 return @divFloor(duration * self.frequency.numer, self.frequency.denom);
192 }
193 return duration;
194 }
190195};
191196
192197test "sleep" {
lib/std/unicode.zig+6-6
......@@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct {
243243
244244 pub fn init(s: []const u16) Utf16LeIterator {
245245 return Utf16LeIterator{
246 .bytes = @sliceToBytes(s),
246 .bytes = mem.sliceAsBytes(s),
247247 .i = 0,
248248 };
249249 }
......@@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize {
496496
497497test "utf16leToUtf8" {
498498 var utf16le: [2]u16 = undefined;
499 const utf16le_as_bytes = @sliceToBytes(utf16le[0..]);
499 const utf16le_as_bytes = mem.sliceAsBytes(utf16le[0..]);
500500
501501 {
502502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
......@@ -606,12 +606,12 @@ test "utf8ToUtf16Le" {
606606 {
607607 const length = try utf8ToUtf16Le(utf16le[0..], "𐐷");
608608 testing.expectEqual(@as(usize, 2), length);
609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16le[0..]));
609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16le[0..]));
610610 }
611611 {
612612 const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}");
613613 testing.expectEqual(@as(usize, 2), length);
614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16le[0..]));
614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16le[0..]));
615615 }
616616}
617617
......@@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" {
619619 {
620620 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");
621621 defer testing.allocator.free(utf16);
622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..]));
622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16[0..]));
623623 testing.expect(utf16[2] == 0);
624624 }
625625 {
626626 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");
627627 defer testing.allocator.free(utf16);
628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..]));
628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16[0..]));
629629 testing.expect(utf16[2] == 0);
630630 }
631631}
lib/std/zig.zig+1
......@@ -5,6 +5,7 @@ pub const parse = @import("zig/parse.zig").parse;
55pub const parseStringLiteral = @import("zig/parse_string_literal.zig").parseStringLiteral;
66pub const render = @import("zig/render.zig").render;
77pub const ast = @import("zig/ast.zig");
8pub const system = @import("zig/system.zig");
89
910test "std.zig tests" {
1011 _ = @import("zig/ast.zig");
lib/std/zig/ast.zig+17-19
......@@ -460,10 +460,9 @@ pub const Node = struct {
460460 }
461461
462462 pub fn iterate(base: *Node, index: usize) ?*Node {
463 comptime var i = 0;
464 inline while (i < @memberCount(Id)) : (i += 1) {
465 if (base.id == @field(Id, @memberName(Id, i))) {
466 const T = @field(Node, @memberName(Id, i));
463 inline for (@typeInfo(Id).Enum.fields) |f| {
464 if (base.id == @field(Id, f.name)) {
465 const T = @field(Node, f.name);
467466 return @fieldParentPtr(T, "base", base).iterate(index);
468467 }
469468 }
......@@ -471,10 +470,9 @@ pub const Node = struct {
471470 }
472471
473472 pub fn firstToken(base: *const Node) TokenIndex {
474 comptime var i = 0;
475 inline while (i < @memberCount(Id)) : (i += 1) {
476 if (base.id == @field(Id, @memberName(Id, i))) {
477 const T = @field(Node, @memberName(Id, i));
473 inline for (@typeInfo(Id).Enum.fields) |f| {
474 if (base.id == @field(Id, f.name)) {
475 const T = @field(Node, f.name);
478476 return @fieldParentPtr(T, "base", base).firstToken();
479477 }
480478 }
......@@ -482,10 +480,9 @@ pub const Node = struct {
482480 }
483481
484482 pub fn lastToken(base: *const Node) TokenIndex {
485 comptime var i = 0;
486 inline while (i < @memberCount(Id)) : (i += 1) {
487 if (base.id == @field(Id, @memberName(Id, i))) {
488 const T = @field(Node, @memberName(Id, i));
483 inline for (@typeInfo(Id).Enum.fields) |f| {
484 if (base.id == @field(Id, f.name)) {
485 const T = @field(Node, f.name);
489486 return @fieldParentPtr(T, "base", base).lastToken();
490487 }
491488 }
......@@ -493,10 +490,9 @@ pub const Node = struct {
493490 }
494491
495492 pub fn typeToId(comptime T: type) Id {
496 comptime var i = 0;
497 inline while (i < @memberCount(Id)) : (i += 1) {
498 if (T == @field(Node, @memberName(Id, i))) {
499 return @field(Id, @memberName(Id, i));
493 inline for (@typeInfo(Id).Enum.fields) |f| {
494 if (T == @field(Node, f.name)) {
495 return @field(Id, f.name);
500496 }
501497 }
502498 unreachable;
......@@ -1567,7 +1563,9 @@ pub const Node = struct {
15671563 pub const Op = union(enum) {
15681564 AddressOf,
15691565 ArrayType: ArrayInfo,
1570 Await,
1566 Await: struct {
1567 noasync_token: ?TokenIndex = null,
1568 },
15711569 BitNot,
15721570 BoolNot,
15731571 Cancel,
......@@ -2184,10 +2182,10 @@ pub const Node = struct {
21842182 pub fn iterate(self: *Asm, index: usize) ?*Node {
21852183 var i = index;
21862184
2187 if (i < self.outputs.len) return &self.outputs.at(index).*.base;
2185 if (i < self.outputs.len) return &self.outputs.at(i).*.base;
21882186 i -= self.outputs.len;
21892187
2190 if (i < self.inputs.len) return &self.inputs.at(index).*.base;
2188 if (i < self.inputs.len) return &self.inputs.at(i).*.base;
21912189 i -= self.inputs.len;
21922190
21932191 return null;
lib/std/zig/parse.zig+14-2
......@@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
11291129/// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments
11301130/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
11311131fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1132 var maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync);
1132 const maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync);
11331133 if (maybe_async) |async_token| {
11341134 const token_fn = eatToken(it, .Keyword_fn);
11351135 if (async_token.ptr.id == .Keyword_async and token_fn != null) {
......@@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
21792179 .MinusPercent => ops{ .NegationWrap = {} },
21802180 .Ampersand => ops{ .AddressOf = {} },
21812181 .Keyword_try => ops{ .Try = {} },
2182 .Keyword_await => ops{ .Await = {} },
2182 .Keyword_await => ops{ .Await = .{} },
2183 .Keyword_noasync => if (eatToken(it, .Keyword_await)) |await_tok| {
2184 const node = try arena.create(Node.PrefixOp);
2185 node.* = Node.PrefixOp{
2186 .op_token = await_tok,
2187 .op = .{ .Await = .{ .noasync_token = token.index } },
2188 .rhs = undefined, // set by caller
2189 };
2190 return &node.base;
2191 } else {
2192 putBackToken(it, token.index);
2193 return null;
2194 },
21832195 else => {
21842196 putBackToken(it, token.index);
21852197 return null;
lib/std/zig/parser_test.zig+12-1
......@@ -1,3 +1,12 @@
1test "zig fmt: noasync await" {
2 try testCanonical(
3 \\fn foo() void {
4 \\ x = noasync await y;
5 \\}
6 \\
7 );
8}
9
110test "zig fmt: trailing comma in container declaration" {
211 try testCanonical(
312 \\const X = struct { foo: i32 };
......@@ -83,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
8392 \\nakedcc fn foo1() void {}
8493 \\stdcallcc fn foo2() void {}
8594 \\extern fn foo3() void {}
95 \\extern "mylib" fn foo4() void {}
8696 ,
8797 \\fn foo1() callconv(.Naked) void {}
8898 \\fn foo2() callconv(.Stdcall) void {}
8999 \\fn foo3() callconv(.C) void {}
100 \\fn foo4() callconv(.C) void {}
90101 \\
91102 );
92103}
......@@ -1399,7 +1410,7 @@ test "zig fmt: same-line comment after non-block if expression" {
13991410test "zig fmt: same-line comment on comptime expression" {
14001411 try testCanonical(
14011412 \\test "" {
1402 \\ comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
1413 \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
14031414 \\}
14041415 \\
14051416 );
lib/std/zig/render.zig+9-3
......@@ -1,5 +1,4 @@
11const std = @import("../std.zig");
2const builtin = @import("builtin");
32const assert = std.debug.assert;
43const mem = std.mem;
54const ast = std.zig.ast;
......@@ -14,7 +13,7 @@ pub const Error = error{
1413
1514/// Returns whether anything changed
1615pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Child.Error || Error)!bool {
17 comptime assert(@typeId(@TypeOf(stream)) == builtin.TypeId.Pointer);
16 comptime assert(@typeInfo(@TypeOf(stream)) == .Pointer);
1817
1918 var anything_changed: bool = false;
2019
......@@ -584,12 +583,18 @@ fn renderExpression(
584583 },
585584
586585 .Try,
587 .Await,
588586 .Cancel,
589587 .Resume,
590588 => {
591589 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
592590 },
591
592 .Await => |await_info| {
593 if (await_info.noasync_token) |tok| {
594 try renderToken(tree, stream, tok, indent, start_col, Space.Space);
595 }
596 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
597 },
593598 }
594599
595600 return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space);
......@@ -1390,6 +1395,7 @@ fn renderExpression(
13901395 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
13911396 } else {
13921397 cc_rewrite_str = ".C";
1398 fn_proto.lib_name = null;
13931399 }
13941400 }
13951401
lib/std/zig/system.zig created+163
......@@ -0,0 +1,163 @@
1const std = @import("../std.zig");
2const mem = std.mem;
3const Allocator = std.mem.Allocator;
4const ArrayList = std.ArrayList;
5const assert = std.debug.assert;
6const process = std.process;
7
8const is_windows = std.Target.current.isWindows();
9
10pub const NativePaths = struct {
11 include_dirs: ArrayList([:0]u8),
12 lib_dirs: ArrayList([:0]u8),
13 rpaths: ArrayList([:0]u8),
14 warnings: ArrayList([:0]u8),
15
16 pub fn detect(allocator: *Allocator) !NativePaths {
17 var self: NativePaths = .{
18 .include_dirs = ArrayList([:0]u8).init(allocator),
19 .lib_dirs = ArrayList([:0]u8).init(allocator),
20 .rpaths = ArrayList([:0]u8).init(allocator),
21 .warnings = ArrayList([:0]u8).init(allocator),
22 };
23 errdefer self.deinit();
24
25 var is_nix = false;
26 if (process.getEnvVarOwned(allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
27 defer allocator.free(nix_cflags_compile);
28
29 is_nix = true;
30 var it = mem.tokenize(nix_cflags_compile, " ");
31 while (true) {
32 const word = it.next() orelse break;
33 if (mem.eql(u8, word, "-isystem")) {
34 const include_path = it.next() orelse {
35 try self.addWarning("Expected argument after -isystem in NIX_CFLAGS_COMPILE");
36 break;
37 };
38 try self.addIncludeDir(include_path);
39 } else {
40 try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}", .{word});
41 break;
42 }
43 }
44 } else |err| switch (err) {
45 error.InvalidUtf8 => {},
46 error.EnvironmentVariableNotFound => {},
47 error.OutOfMemory => |e| return e,
48 }
49 if (process.getEnvVarOwned(allocator, "NIX_LDFLAGS")) |nix_ldflags| {
50 defer allocator.free(nix_ldflags);
51
52 is_nix = true;
53 var it = mem.tokenize(nix_ldflags, " ");
54 while (true) {
55 const word = it.next() orelse break;
56 if (mem.eql(u8, word, "-rpath")) {
57 const rpath = it.next() orelse {
58 try self.addWarning("Expected argument after -rpath in NIX_LDFLAGS");
59 break;
60 };
61 try self.addRPath(rpath);
62 } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
63 const lib_path = word[2..];
64 try self.addLibDir(lib_path);
65 } else {
66 try self.addWarningFmt("Unrecognized C flag from NIX_LDFLAGS: {}", .{word});
67 break;
68 }
69 }
70 } else |err| switch (err) {
71 error.InvalidUtf8 => {},
72 error.EnvironmentVariableNotFound => {},
73 error.OutOfMemory => |e| return e,
74 }
75 if (is_nix) {
76 return self;
77 }
78
79 if (!is_windows) {
80 const triple = try std.Target.current.linuxTriple(allocator);
81
82 // TODO: $ ld --verbose | grep SEARCH_DIR
83 // the output contains some paths that end with lib64, maybe include them too?
84 // TODO: what is the best possible order of things?
85 // TODO: some of these are suspect and should only be added on some systems. audit needed.
86
87 try self.addIncludeDir("/usr/local/include");
88 try self.addLibDir("/usr/local/lib");
89 try self.addLibDir("/usr/local/lib64");
90
91 try self.addIncludeDirFmt("/usr/include/{}", .{triple});
92 try self.addLibDirFmt("/usr/lib/{}", .{triple});
93
94 try self.addIncludeDir("/usr/include");
95 try self.addLibDir("/lib");
96 try self.addLibDir("/lib64");
97 try self.addLibDir("/usr/lib");
98 try self.addLibDir("/usr/lib64");
99
100 // example: on a 64-bit debian-based linux distro, with zlib installed from apt:
101 // zlib.h is in /usr/include (added above)
102 // libz.so.1 is in /lib/x86_64-linux-gnu (added here)
103 try self.addLibDirFmt("/lib/{}", .{triple});
104 }
105
106 return self;
107 }
108
109 pub fn deinit(self: *NativePaths) void {
110 deinitArray(&self.include_dirs);
111 deinitArray(&self.lib_dirs);
112 deinitArray(&self.rpaths);
113 deinitArray(&self.warnings);
114 self.* = undefined;
115 }
116
117 fn deinitArray(array: *ArrayList([:0]u8)) void {
118 for (array.toSlice()) |item| {
119 array.allocator.free(item);
120 }
121 array.deinit();
122 }
123
124 pub fn addIncludeDir(self: *NativePaths, s: []const u8) !void {
125 return self.appendArray(&self.include_dirs, s);
126 }
127
128 pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
129 const item = try std.fmt.allocPrint0(self.include_dirs.allocator, fmt, args);
130 errdefer self.include_dirs.allocator.free(item);
131 try self.include_dirs.append(item);
132 }
133
134 pub fn addLibDir(self: *NativePaths, s: []const u8) !void {
135 return self.appendArray(&self.lib_dirs, s);
136 }
137
138 pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
139 const item = try std.fmt.allocPrint0(self.lib_dirs.allocator, fmt, args);
140 errdefer self.lib_dirs.allocator.free(item);
141 try self.lib_dirs.append(item);
142 }
143
144 pub fn addWarning(self: *NativePaths, s: []const u8) !void {
145 return self.appendArray(&self.warnings, s);
146 }
147
148 pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
149 const item = try std.fmt.allocPrint0(self.warnings.allocator, fmt, args);
150 errdefer self.warnings.allocator.free(item);
151 try self.warnings.append(item);
152 }
153
154 pub fn addRPath(self: *NativePaths, s: []const u8) !void {
155 return self.appendArray(&self.rpaths, s);
156 }
157
158 fn appendArray(self: *NativePaths, array: *ArrayList([:0]u8), s: []const u8) !void {
159 const item = try std.mem.dupeZ(array.allocator, u8, s);
160 errdefer array.allocator.free(item);
161 try array.append(item);
162 }
163};
lib/std/zig/tokenizer.zig+2-6
......@@ -414,10 +414,8 @@ pub const Tokenizer = struct {
414414
415415 pub fn next(self: *Tokenizer) Token {
416416 if (self.pending_invalid_token) |token| {
417 // TODO: Audit this pattern once #2915 is closed
418 const copy = token;
419417 self.pending_invalid_token = null;
420 return copy;
418 return token;
421419 }
422420 const start_index = self.index;
423421 var state = State.Start;
......@@ -1270,10 +1268,8 @@ pub const Tokenizer = struct {
12701268
12711269 if (result.id == Token.Id.Eof) {
12721270 if (self.pending_invalid_token) |token| {
1273 // TODO: Audit this pattern once #2915 is closed
1274 const copy = token;
12751271 self.pending_invalid_token = null;
1276 return copy;
1272 return token;
12771273 }
12781274 }
12791275
src-self-hosted/c.zig-1
......@@ -4,5 +4,4 @@ pub usingnamespace @cImport({
44 @cInclude("inttypes.h");
55 @cInclude("config.h");
66 @cInclude("zig_llvm.h");
7 @cInclude("windows_sdk.h");
87});
src-self-hosted/introspect.zig+8
......@@ -6,6 +6,14 @@ const fs = std.fs;
66
77const warn = std.debug.warn;
88
9pub fn detectDynamicLinker(allocator: *mem.Allocator, target: std.Target) ![:0]u8 {
10 if (target == .Native) {
11 return @import("libc_installation.zig").detectNativeDynamicLinker(allocator);
12 } else {
13 return target.getStandardDynamicLinkerPath(allocator);
14 }
15}
16
917/// Caller must free result
1018pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
1119 const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" });
src-self-hosted/ir.zig+17-22
......@@ -76,20 +76,18 @@ pub const Inst = struct {
7676 }
7777
7878 pub fn typeToId(comptime T: type) Id {
79 comptime var i = 0;
80 inline while (i < @memberCount(Id)) : (i += 1) {
81 if (T == @field(Inst, @memberName(Id, i))) {
82 return @field(Id, @memberName(Id, i));
79 inline for (@typeInfo(Id).Enum.fields) |f| {
80 if (T == @field(Inst, f.name)) {
81 return @field(Id, f.name);
8382 }
8483 }
8584 unreachable;
8685 }
8786
8887 pub fn dump(base: *const Inst) void {
89 comptime var i = 0;
90 inline while (i < @memberCount(Id)) : (i += 1) {
91 if (base.id == @field(Id, @memberName(Id, i))) {
92 const T = @field(Inst, @memberName(Id, i));
88 inline for (@typeInfo(Id).Enum.fields) |f| {
89 if (base.id == @field(Id, f.name)) {
90 const T = @field(Inst, f.name);
9391 std.debug.warn("#{} = {}(", .{ base.debug_id, @tagName(base.id) });
9492 @fieldParentPtr(T, "base", base).dump();
9593 std.debug.warn(")", .{});
......@@ -100,10 +98,9 @@ pub const Inst = struct {
10098 }
10199
102100 pub fn hasSideEffects(base: *const Inst) bool {
103 comptime var i = 0;
104 inline while (i < @memberCount(Id)) : (i += 1) {
105 if (base.id == @field(Id, @memberName(Id, i))) {
106 const T = @field(Inst, @memberName(Id, i));
101 inline for (@typeInfo(Id).Enum.fields) |f| {
102 if (base.id == @field(Id, f.name)) {
103 const T = @field(Inst, f.name);
107104 return @fieldParentPtr(T, "base", base).hasSideEffects();
108105 }
109106 }
......@@ -1805,21 +1802,19 @@ pub const Builder = struct {
18051802 };
18061803
18071804 // Look at the params and ref() other instructions
1808 comptime var i = 0;
1809 inline while (i < @memberCount(I.Params)) : (i += 1) {
1810 const FieldType = comptime @TypeOf(@field(@as(I.Params, undefined), @memberName(I.Params, i)));
1811 switch (FieldType) {
1812 *Inst => @field(inst.params, @memberName(I.Params, i)).ref(self),
1813 *BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self),
1814 ?*Inst => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref(self),
1805 inline for (@typeInfo(I.Params).Struct.fields) |f| {
1806 switch (f.fiedl_type) {
1807 *Inst => @field(inst.params, f.name).ref(self),
1808 *BasicBlock => @field(inst.params, f.name).ref(self),
1809 ?*Inst => if (@field(inst.params, f.name)) |other| other.ref(self),
18151810 []*Inst => {
18161811 // TODO https://github.com/ziglang/zig/issues/1269
1817 for (@field(inst.params, @memberName(I.Params, i))) |other|
1812 for (@field(inst.params, f.name)) |other|
18181813 other.ref(self);
18191814 },
18201815 []*BasicBlock => {
18211816 // TODO https://github.com/ziglang/zig/issues/1269
1822 for (@field(inst.params, @memberName(I.Params, i))) |other|
1817 for (@field(inst.params, f.name)) |other|
18231818 other.ref(self);
18241819 },
18251820 Type.Pointer.Mut,
......@@ -1831,7 +1826,7 @@ pub const Builder = struct {
18311826 => {},
18321827 // it's ok to add more types here, just make sure that
18331828 // any instructions and basic blocks are ref'd appropriately
1834 else => @compileError("unrecognized type in Params: " ++ @typeName(FieldType)),
1829 else => @compileError("unrecognized type in Params: " ++ @typeName(f.field_type)),
18351830 }
18361831 }
18371832
src-self-hosted/libc_installation.zig+533-259
......@@ -1,20 +1,29 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const event = std.event;
43const util = @import("util.zig");
54const Target = std.Target;
6const c = @import("c.zig");
75const fs = std.fs;
86const Allocator = std.mem.Allocator;
7const Batch = std.event.Batch;
8
9const is_darwin = Target.current.isDarwin();
10const is_windows = Target.current.isWindows();
11const is_freebsd = Target.current.isFreeBSD();
12const is_netbsd = Target.current.isNetBSD();
13const is_linux = Target.current.isLinux();
14const is_dragonfly = Target.current.isDragonFlyBSD();
15const is_gnu = Target.current.isGnu();
16
17usingnamespace @import("windows_sdk.zig");
918
1019/// See the render function implementation for documentation of the fields.
1120pub const LibCInstallation = struct {
12 include_dir: []const u8,
13 lib_dir: ?[]const u8,
14 static_lib_dir: ?[]const u8,
15 msvc_lib_dir: ?[]const u8,
16 kernel32_lib_dir: ?[]const u8,
17 dynamic_linker_path: ?[]const u8,
21 include_dir: ?[:0]const u8 = null,
22 sys_include_dir: ?[:0]const u8 = null,
23 crt_dir: ?[:0]const u8 = null,
24 static_crt_dir: ?[:0]const u8 = null,
25 msvc_lib_dir: ?[:0]const u8 = null,
26 kernel32_lib_dir: ?[:0]const u8 = null,
1827
1928 pub const FindError = error{
2029 OutOfMemory,
......@@ -27,31 +36,24 @@ pub const LibCInstallation = struct {
2736 LibCStdLibHeaderNotFound,
2837 LibCKernel32LibNotFound,
2938 UnsupportedArchitecture,
39 WindowsSdkNotFound,
3040 };
3141
3242 pub fn parse(
33 self: *LibCInstallation,
3443 allocator: *Allocator,
3544 libc_file: []const u8,
3645 stderr: *std.io.OutStream(fs.File.WriteError),
37 ) !void {
38 self.initEmpty();
39
40 const keys = [_][]const u8{
41 "include_dir",
42 "lib_dir",
43 "static_lib_dir",
44 "msvc_lib_dir",
45 "kernel32_lib_dir",
46 "dynamic_linker_path",
47 };
46 ) !LibCInstallation {
47 var self: LibCInstallation = .{};
48
49 const fields = std.meta.fields(LibCInstallation);
4850 const FoundKey = struct {
4951 found: bool,
50 allocated: ?[]u8,
52 allocated: ?[:0]u8,
5153 };
52 var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** keys.len;
54 var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** fields.len;
5355 errdefer {
54 self.initEmpty();
56 self = .{};
5557 for (found_keys) |found_key| {
5658 if (found_key.allocated) |s| allocator.free(s);
5759 }
......@@ -69,152 +71,216 @@ pub const LibCInstallation = struct {
6971 return error.ParseError;
7072 };
7173 const value = line_it.rest();
72 inline for (keys) |key, i| {
73 if (std.mem.eql(u8, name, key)) {
74 inline for (fields) |field, i| {
75 if (std.mem.eql(u8, name, field.name)) {
7476 found_keys[i].found = true;
75 switch (@typeInfo(@TypeOf(@field(self, key)))) {
76 .Optional => {
77 if (value.len == 0) {
78 @field(self, key) = null;
79 } else {
80 found_keys[i].allocated = try std.mem.dupe(allocator, u8, value);
81 @field(self, key) = found_keys[i].allocated;
82 }
83 },
84 else => {
85 if (value.len == 0) {
86 try stderr.print("field cannot be empty: {}\n", .{key});
87 return error.ParseError;
88 }
89 const dupe = try std.mem.dupe(allocator, u8, value);
90 found_keys[i].allocated = dupe;
91 @field(self, key) = dupe;
92 },
77 if (value.len == 0) {
78 @field(self, field.name) = null;
79 } else {
80 found_keys[i].allocated = try std.mem.dupeZ(allocator, u8, value);
81 @field(self, field.name) = found_keys[i].allocated;
9382 }
9483 break;
9584 }
9685 }
9786 }
98 for (found_keys) |found_key, i| {
99 if (!found_key.found) {
100 try stderr.print("missing field: {}\n", .{keys[i]});
87 inline for (fields) |field, i| {
88 if (!found_keys[i].found) {
89 try stderr.print("missing field: {}\n", .{field.name});
10190 return error.ParseError;
10291 }
10392 }
93 if (self.include_dir == null) {
94 try stderr.print("include_dir may not be empty\n", .{});
95 return error.ParseError;
96 }
97 if (self.sys_include_dir == null) {
98 try stderr.print("sys_include_dir may not be empty\n", .{});
99 return error.ParseError;
100 }
101 if (self.crt_dir == null and !is_darwin) {
102 try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.getOs())});
103 return error.ParseError;
104 }
105 if (self.static_crt_dir == null and is_windows and is_gnu) {
106 try stderr.print("static_crt_dir may not be empty for {}-{}\n", .{
107 @tagName(Target.current.getOs()),
108 @tagName(Target.current.getAbi()),
109 });
110 return error.ParseError;
111 }
112 if (self.msvc_lib_dir == null and is_windows and !is_gnu) {
113 try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{
114 @tagName(Target.current.getOs()),
115 @tagName(Target.current.getAbi()),
116 });
117 return error.ParseError;
118 }
119 if (self.kernel32_lib_dir == null and is_windows and !is_gnu) {
120 try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{
121 @tagName(Target.current.getOs()),
122 @tagName(Target.current.getAbi()),
123 });
124 return error.ParseError;
125 }
126
127 return self;
104128 }
105129
106 pub fn render(self: *const LibCInstallation, out: *std.io.OutStream(fs.File.WriteError)) !void {
130 pub fn render(self: LibCInstallation, out: *std.io.OutStream(fs.File.WriteError)) !void {
107131 @setEvalBranchQuota(4000);
108 const lib_dir = self.lib_dir orelse "";
109 const static_lib_dir = self.static_lib_dir orelse "";
132 const include_dir = self.include_dir orelse "";
133 const sys_include_dir = self.sys_include_dir orelse "";
134 const crt_dir = self.crt_dir orelse "";
135 const static_crt_dir = self.static_crt_dir orelse "";
110136 const msvc_lib_dir = self.msvc_lib_dir orelse "";
111137 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";
112 const dynamic_linker_path = self.dynamic_linker_path orelse util.getDynamicLinkerPath(Target{ .Native = {} });
138
113139 try out.print(
114140 \\# The directory that contains `stdlib.h`.
115 \\# On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`
141 \\# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
116142 \\include_dir={}
117143 \\
118 \\# The directory that contains `crt1.o`.
119 \\# On Linux, can be found with `cc -print-file-name=crt1.o`.
144 \\# The system-specific include directory. May be the same as `include_dir`.
145 \\# On Windows it's the directory that includes `vcruntime.h`.
146 \\# On POSIX it's the directory that includes `sys/errno.h`.
147 \\sys_include_dir={}
148 \\
149 \\# The directory that contains `crt1.o` or `crt2.o`.
150 \\# On POSIX, can be found with `cc -print-file-name=crt1.o`.
120151 \\# Not needed when targeting MacOS.
121 \\lib_dir={}
152 \\crt_dir={}
122153 \\
123154 \\# The directory that contains `crtbegin.o`.
124 \\# On Linux, can be found with `cc -print-file-name=crtbegin.o`.
125 \\# Not needed when targeting MacOS or Windows.
126 \\static_lib_dir={}
155 \\# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.
156 \\# Only needed when targeting MinGW-w64 on Windows.
157 \\static_crt_dir={}
127158 \\
128159 \\# The directory that contains `vcruntime.lib`.
129 \\# Only needed when targeting Windows.
160 \\# Only needed when targeting MSVC on Windows.
130161 \\msvc_lib_dir={}
131162 \\
132163 \\# The directory that contains `kernel32.lib`.
133 \\# Only needed when targeting Windows.
164 \\# Only needed when targeting MSVC on Windows.
134165 \\kernel32_lib_dir={}
135166 \\
136 \\# The full path to the dynamic linker, on the target system.
137 \\# Only needed when targeting Linux.
138 \\dynamic_linker_path={}
139 \\
140 , .{ self.include_dir, lib_dir, static_lib_dir, msvc_lib_dir, kernel32_lib_dir, dynamic_linker_path });
167 , .{
168 include_dir,
169 sys_include_dir,
170 crt_dir,
171 static_crt_dir,
172 msvc_lib_dir,
173 kernel32_lib_dir,
174 });
141175 }
142176
177 pub const FindNativeOptions = struct {
178 allocator: *Allocator,
179
180 /// If enabled, will print human-friendly errors to stderr.
181 verbose: bool = false,
182 };
183
143184 /// Finds the default, native libc.
144 pub fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {
145 self.initEmpty();
146 var group = event.Group(FindError!void).init(allocator);
147 errdefer group.wait() catch {};
148 var windows_sdk: ?*c.ZigWindowsSDK = null;
149 errdefer if (windows_sdk) |sdk| c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));
150
151 switch (builtin.os) {
152 .windows => {
153 var sdk: *c.ZigWindowsSDK = undefined;
154 switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) {
155 c.ZigFindWindowsSdkError.None => {
156 windows_sdk = sdk;
157
158 if (sdk.msvc_lib_dir_ptr != 0) {
159 self.msvc_lib_dir = try std.mem.dupe(allocator, u8, sdk.msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
160 }
161 try group.call(findNativeKernel32LibDir, .{ allocator, self, sdk });
162 try group.call(findNativeIncludeDirWindows, .{ self, allocator, sdk });
163 try group.call(findNativeLibDirWindows, .{ self, allocator, sdk });
185 pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
186 var self: LibCInstallation = .{};
187
188 if (is_windows) {
189 if (is_gnu) {
190 var batch = Batch(FindError!void, 3, .auto_async).init();
191 batch.add(&async self.findNativeIncludeDirPosix(args));
192 batch.add(&async self.findNativeCrtDirPosix(args));
193 batch.add(&async self.findNativeStaticCrtDirPosix(args));
194 try batch.wait();
195 } else {
196 var sdk: *ZigWindowsSDK = undefined;
197 switch (zig_find_windows_sdk(&sdk)) {
198 .None => {
199 defer zig_free_windows_sdk(sdk);
200
201 var batch = Batch(FindError!void, 5, .auto_async).init();
202 batch.add(&async self.findNativeMsvcIncludeDir(args, sdk));
203 batch.add(&async self.findNativeMsvcLibDir(args, sdk));
204 batch.add(&async self.findNativeKernel32LibDir(args, sdk));
205 batch.add(&async self.findNativeIncludeDirWindows(args, sdk));
206 batch.add(&async self.findNativeCrtDirWindows(args, sdk));
207 try batch.wait();
164208 },
165 c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory,
166 c.ZigFindWindowsSdkError.NotFound => return error.NotFound,
167 c.ZigFindWindowsSdkError.PathTooLong => return error.NotFound,
209 .OutOfMemory => return error.OutOfMemory,
210 .NotFound => return error.WindowsSdkNotFound,
211 .PathTooLong => return error.WindowsSdkNotFound,
168212 }
169 },
170 .linux => {
171 try group.call(findNativeIncludeDirLinux, .{ self, allocator });
172 try group.call(findNativeLibDirLinux, .{ self, allocator });
173 try group.call(findNativeStaticLibDir, .{ self, allocator });
174 try group.call(findNativeDynamicLinker, .{ self, allocator });
175 },
176 .macosx, .freebsd, .netbsd => {
177 self.include_dir = try std.mem.dupe(allocator, u8, "/usr/include");
178 },
179 else => @compileError("unimplemented: find libc for this OS"),
213 }
214 } else {
215 try blk: {
216 var batch = Batch(FindError!void, 2, .auto_async).init();
217 errdefer batch.wait() catch {};
218 batch.add(&async self.findNativeIncludeDirPosix(args));
219 if (is_freebsd or is_netbsd) {
220 self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib");
221 } else if (is_linux or is_dragonfly) {
222 batch.add(&async self.findNativeCrtDirPosix(args));
223 }
224 break :blk batch.wait();
225 };
226 }
227 return self;
228 }
229
230 /// Must be the same allocator passed to `parse` or `findNative`.
231 pub fn deinit(self: *LibCInstallation, allocator: *Allocator) void {
232 const fields = std.meta.fields(LibCInstallation);
233 inline for (fields) |field| {
234 if (@field(self, field.name)) |payload| {
235 allocator.free(payload);
236 }
180237 }
181 return group.wait();
238 self.* = undefined;
182239 }
183240
184 async fn findNativeIncludeDirLinux(self: *LibCInstallation, allocator: *Allocator) FindError!void {
185 const cc_exe = std.os.getenv("CC") orelse "cc";
241 fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
242 const allocator = args.allocator;
243 const dev_null = if (is_windows) "nul" else "/dev/null";
244 const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe;
186245 const argv = [_][]const u8{
187246 cc_exe,
188247 "-E",
189248 "-Wp,-v",
190249 "-xc",
191 "/dev/null",
250 dev_null,
192251 };
193 // TODO make this use event loop
194 const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024);
195 const exec_result = if (std.debug.runtime_safety) blk: {
196 break :blk errorable_result catch unreachable;
197 } else blk: {
198 break :blk errorable_result catch |err| switch (err) {
199 error.OutOfMemory => return error.OutOfMemory,
200 else => return error.UnableToSpawnCCompiler,
201 };
252 const exec_res = std.ChildProcess.exec2(.{
253 .allocator = allocator,
254 .argv = &argv,
255 .max_output_bytes = 1024 * 1024,
256 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
257 // to their own executable, without even bothering to resolve PATH. This results in the message:
258 // error: unable to execute command: Executable "" doesn't exist!
259 // So we use the expandArg0 variant of ChildProcess to give them a helping hand.
260 .expand_arg0 = .expand,
261 }) catch |err| switch (err) {
262 error.OutOfMemory => return error.OutOfMemory,
263 else => {
264 printVerboseInvocation(&argv, null, args.verbose, null);
265 return error.UnableToSpawnCCompiler;
266 },
202267 };
203268 defer {
204 allocator.free(exec_result.stdout);
205 allocator.free(exec_result.stderr);
269 allocator.free(exec_res.stdout);
270 allocator.free(exec_res.stderr);
206271 }
207
208 switch (exec_result.term) {
209 .Exited => |code| {
210 if (code != 0) return error.CCompilerExitCode;
272 switch (exec_res.term) {
273 .Exited => |code| if (code != 0) {
274 printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr);
275 return error.CCompilerExitCode;
211276 },
212277 else => {
278 printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr);
213279 return error.CCompilerCrashed;
214280 },
215281 }
216282
217 var it = std.mem.tokenize(exec_result.stderr, "\n\r");
283 var it = std.mem.tokenize(exec_res.stderr, "\n\r");
218284 var search_paths = std.ArrayList([]const u8).init(allocator);
219285 defer search_paths.deinit();
220286 while (it.next()) |line| {
......@@ -226,16 +292,44 @@ pub const LibCInstallation = struct {
226292 return error.CCompilerCannotFindHeaders;
227293 }
228294
229 // search in reverse order
295 const include_dir_example_file = "stdlib.h";
296 const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h";
297
230298 var path_i: usize = 0;
231299 while (path_i < search_paths.len) : (path_i += 1) {
300 // search in reverse order
232301 const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1);
233302 const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");
234 const stdlib_path = try fs.path.join(allocator, &[_][]const u8{ search_path, "stdlib.h" });
235 defer allocator.free(stdlib_path);
303 var search_dir = fs.cwd().openDirList(search_path) catch |err| switch (err) {
304 error.FileNotFound,
305 error.NotDir,
306 error.NoDevice,
307 => continue,
308
309 else => return error.FileSystem,
310 };
311 defer search_dir.close();
312
313 if (self.include_dir == null) {
314 if (search_dir.accessZ(include_dir_example_file, .{})) |_| {
315 self.include_dir = try std.mem.dupeZ(allocator, u8, search_path);
316 } else |err| switch (err) {
317 error.FileNotFound => {},
318 else => return error.FileSystem,
319 }
320 }
321
322 if (self.sys_include_dir == null) {
323 if (search_dir.accessZ(sys_include_dir_example_file, .{})) |_| {
324 self.sys_include_dir = try std.mem.dupeZ(allocator, u8, search_path);
325 } else |err| switch (err) {
326 error.FileNotFound => {},
327 else => return error.FileSystem,
328 }
329 }
236330
237 if (try fileExists(stdlib_path)) {
238 self.include_dir = try std.mem.dupe(allocator, u8, search_path);
331 if (self.include_dir != null and self.sys_include_dir != null) {
332 // Success.
239333 return;
240334 }
241335 }
......@@ -243,7 +337,13 @@ pub const LibCInstallation = struct {
243337 return error.LibCStdLibHeaderNotFound;
244338 }
245339
246 async fn findNativeIncludeDirWindows(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) !void {
340 fn findNativeIncludeDirWindows(
341 self: *LibCInstallation,
342 args: FindNativeOptions,
343 sdk: *ZigWindowsSDK,
344 ) FindError!void {
345 const allocator = args.allocator;
346
247347 var search_buf: [2]Search = undefined;
248348 const searches = fillSearch(&search_buf, sdk);
249349
......@@ -255,180 +355,363 @@ pub const LibCInstallation = struct {
255355 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
256356 try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
257357
258 const stdlib_path = try fs.path.join(
259 allocator,
260 [_][]const u8{ result_buf.toSliceConst(), "stdlib.h" },
261 );
262 defer allocator.free(stdlib_path);
358 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
359 error.FileNotFound,
360 error.NotDir,
361 error.NoDevice,
362 => continue,
263363
264 if (try fileExists(stdlib_path)) {
265 self.include_dir = result_buf.toOwnedSlice();
266 return;
267 }
364 else => return error.FileSystem,
365 };
366 defer dir.close();
367
368 dir.accessZ("stdlib.h", .{}) catch |err| switch (err) {
369 error.FileNotFound => continue,
370 else => return error.FileSystem,
371 };
372
373 self.include_dir = result_buf.toOwnedSlice();
374 return;
268375 }
269376
270377 return error.LibCStdLibHeaderNotFound;
271378 }
272379
273 async fn findNativeLibDirWindows(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) FindError!void {
380 fn findNativeCrtDirWindows(
381 self: *LibCInstallation,
382 args: FindNativeOptions,
383 sdk: *ZigWindowsSDK,
384 ) FindError!void {
385 const allocator = args.allocator;
386
274387 var search_buf: [2]Search = undefined;
275388 const searches = fillSearch(&search_buf, sdk);
276389
277390 var result_buf = try std.Buffer.initSize(allocator, 0);
278391 defer result_buf.deinit();
279392
393 const arch_sub_dir = switch (builtin.arch) {
394 .i386 => "x86",
395 .x86_64 => "x64",
396 .arm, .armeb => "arm",
397 else => return error.UnsupportedArchitecture,
398 };
399
280400 for (searches) |search| {
281401 result_buf.shrink(0);
282402 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
283 try stream.print("{}\\Lib\\{}\\ucrt\\", .{ search.path, search.version });
284 switch (builtin.arch) {
285 .i386 => try stream.write("x86"),
286 .x86_64 => try stream.write("x64"),
287 .aarch64 => try stream.write("arm"),
288 else => return error.UnsupportedArchitecture,
289 }
290 const ucrt_lib_path = try fs.path.join(
291 allocator,
292 [_][]const u8{ result_buf.toSliceConst(), "ucrt.lib" },
293 );
294 defer allocator.free(ucrt_lib_path);
295 if (try fileExists(ucrt_lib_path)) {
296 self.lib_dir = result_buf.toOwnedSlice();
297 return;
298 }
299 }
300 return error.LibCRuntimeNotFound;
301 }
403 try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
302404
303 async fn findNativeLibDirLinux(self: *LibCInstallation, allocator: *Allocator) FindError!void {
304 self.lib_dir = try ccPrintFileName(allocator, "crt1.o", true);
305 }
405 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
406 error.FileNotFound,
407 error.NotDir,
408 error.NoDevice,
409 => continue,
306410
307 async fn findNativeStaticLibDir(self: *LibCInstallation, allocator: *Allocator) FindError!void {
308 self.static_lib_dir = try ccPrintFileName(allocator, "crtbegin.o", true);
309 }
411 else => return error.FileSystem,
412 };
413 defer dir.close();
310414
311 async fn findNativeDynamicLinker(self: *LibCInstallation, allocator: *Allocator) FindError!void {
312 var dyn_tests = [_]DynTest{
313 DynTest{
314 .name = "ld-linux-x86-64.so.2",
315 .result = null,
316 },
317 DynTest{
318 .name = "ld-musl-x86_64.so.1",
319 .result = null,
320 },
321 };
322 var group = event.Group(FindError!void).init(allocator);
323 errdefer group.wait() catch {};
324 for (dyn_tests) |*dyn_test| {
325 try group.call(testNativeDynamicLinker, .{ self, allocator, dyn_test });
326 }
327 try group.wait();
328 for (dyn_tests) |*dyn_test| {
329 if (dyn_test.result) |result| {
330 self.dynamic_linker_path = result;
331 return;
332 }
415 dir.accessZ("ucrt.lib", .{}) catch |err| switch (err) {
416 error.FileNotFound => continue,
417 else => return error.FileSystem,
418 };
419
420 self.crt_dir = result_buf.toOwnedSlice();
421 return;
333422 }
423 return error.LibCRuntimeNotFound;
334424 }
335425
336 const DynTest = struct {
337 name: []const u8,
338 result: ?[]const u8,
339 };
426 fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
427 self.crt_dir = try ccPrintFileName(.{
428 .allocator = args.allocator,
429 .search_basename = "crt1.o",
430 .want_dirname = .only_dir,
431 .verbose = args.verbose,
432 });
433 }
340434
341 async fn testNativeDynamicLinker(self: *LibCInstallation, allocator: *Allocator, dyn_test: *DynTest) FindError!void {
342 if (ccPrintFileName(allocator, dyn_test.name, false)) |result| {
343 dyn_test.result = result;
344 return;
345 } else |err| switch (err) {
346 error.LibCRuntimeNotFound => return,
347 else => return err,
348 }
435 fn findNativeStaticCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
436 self.static_crt_dir = try ccPrintFileName(.{
437 .allocator = args.allocator,
438 .search_basename = "crtbegin.o",
439 .want_dirname = .only_dir,
440 .verbose = args.verbose,
441 });
349442 }
350443
351 async fn findNativeKernel32LibDir(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) FindError!void {
444 fn findNativeKernel32LibDir(
445 self: *LibCInstallation,
446 args: FindNativeOptions,
447 sdk: *ZigWindowsSDK,
448 ) FindError!void {
449 const allocator = args.allocator;
450
352451 var search_buf: [2]Search = undefined;
353452 const searches = fillSearch(&search_buf, sdk);
354453
355454 var result_buf = try std.Buffer.initSize(allocator, 0);
356455 defer result_buf.deinit();
357456
457 const arch_sub_dir = switch (builtin.arch) {
458 .i386 => "x86",
459 .x86_64 => "x64",
460 .arm, .armeb => "arm",
461 else => return error.UnsupportedArchitecture,
462 };
463
358464 for (searches) |search| {
359465 result_buf.shrink(0);
360466 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
361 try stream.print("{}\\Lib\\{}\\um\\", .{ search.path, search.version });
362 switch (builtin.arch) {
363 .i386 => try stream.write("x86\\"),
364 .x86_64 => try stream.write("x64\\"),
365 .aarch64 => try stream.write("arm\\"),
366 else => return error.UnsupportedArchitecture,
367 }
368 const kernel32_path = try fs.path.join(
369 allocator,
370 [_][]const u8{ result_buf.toSliceConst(), "kernel32.lib" },
371 );
372 defer allocator.free(kernel32_path);
373 if (try fileExists(kernel32_path)) {
374 self.kernel32_lib_dir = result_buf.toOwnedSlice();
375 return;
376 }
467 try stream.print("{}\\Lib\\{}\\um\\{}", .{ search.path, search.version, arch_sub_dir });
468
469 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
470 error.FileNotFound,
471 error.NotDir,
472 error.NoDevice,
473 => continue,
474
475 else => return error.FileSystem,
476 };
477 defer dir.close();
478
479 dir.accessZ("kernel32.lib", .{}) catch |err| switch (err) {
480 error.FileNotFound => continue,
481 else => return error.FileSystem,
482 };
483
484 self.kernel32_lib_dir = result_buf.toOwnedSlice();
485 return;
377486 }
378487 return error.LibCKernel32LibNotFound;
379488 }
380489
381 fn initEmpty(self: *LibCInstallation) void {
382 self.* = LibCInstallation{
383 .include_dir = @as([*]const u8, undefined)[0..0],
384 .lib_dir = null,
385 .static_lib_dir = null,
386 .msvc_lib_dir = null,
387 .kernel32_lib_dir = null,
388 .dynamic_linker_path = null,
490 fn findNativeMsvcIncludeDir(
491 self: *LibCInstallation,
492 args: FindNativeOptions,
493 sdk: *ZigWindowsSDK,
494 ) FindError!void {
495 const allocator = args.allocator;
496
497 const msvc_lib_dir_ptr = sdk.msvc_lib_dir_ptr orelse return error.LibCStdLibHeaderNotFound;
498 const msvc_lib_dir = msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len];
499 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
500 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
501
502 var result_buf = try std.Buffer.init(allocator, up2);
503 defer result_buf.deinit();
504
505 try result_buf.append("\\include");
506
507 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
508 error.FileNotFound,
509 error.NotDir,
510 error.NoDevice,
511 => return error.LibCStdLibHeaderNotFound,
512
513 else => return error.FileSystem,
514 };
515 defer dir.close();
516
517 dir.accessZ("vcruntime.h", .{}) catch |err| switch (err) {
518 error.FileNotFound => return error.LibCStdLibHeaderNotFound,
519 else => return error.FileSystem,
389520 };
521
522 self.sys_include_dir = result_buf.toOwnedSlice();
523 }
524
525 fn findNativeMsvcLibDir(
526 self: *LibCInstallation,
527 args: FindNativeOptions,
528 sdk: *ZigWindowsSDK,
529 ) FindError!void {
530 const allocator = args.allocator;
531 const msvc_lib_dir_ptr = sdk.msvc_lib_dir_ptr orelse return error.LibCRuntimeNotFound;
532 self.msvc_lib_dir = try std.mem.dupeZ(allocator, u8, msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
390533 }
391534};
392535
536const default_cc_exe = if (is_windows) "cc.exe" else "cc";
537
538pub const CCPrintFileNameOptions = struct {
539 allocator: *Allocator,
540 search_basename: []const u8,
541 want_dirname: enum { full_path, only_dir },
542 verbose: bool = false,
543};
544
393545/// caller owns returned memory
394fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {
395 const cc_exe = std.os.getenv("CC") orelse "cc";
396 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", .{o_file});
546fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
547 const allocator = args.allocator;
548
549 const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe;
550 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", .{args.search_basename});
397551 defer allocator.free(arg1);
398552 const argv = [_][]const u8{ cc_exe, arg1 };
399553
400 // TODO This simulates evented I/O for the child process exec
401 event.Loop.startCpuBoundOperation();
402 const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024);
403 const exec_result = if (std.debug.runtime_safety) blk: {
404 break :blk errorable_result catch unreachable;
405 } else blk: {
406 break :blk errorable_result catch |err| switch (err) {
407 error.OutOfMemory => return error.OutOfMemory,
408 else => return error.UnableToSpawnCCompiler,
409 };
554 const exec_res = std.ChildProcess.exec2(.{
555 .allocator = allocator,
556 .argv = &argv,
557 .max_output_bytes = 1024 * 1024,
558 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
559 // to their own executable, without even bothering to resolve PATH. This results in the message:
560 // error: unable to execute command: Executable "" doesn't exist!
561 // So we use the expandArg0 variant of ChildProcess to give them a helping hand.
562 .expand_arg0 = .expand,
563 }) catch |err| switch (err) {
564 error.OutOfMemory => return error.OutOfMemory,
565 else => return error.UnableToSpawnCCompiler,
410566 };
411567 defer {
412 allocator.free(exec_result.stdout);
413 allocator.free(exec_result.stderr);
568 allocator.free(exec_res.stdout);
569 allocator.free(exec_res.stderr);
414570 }
415 switch (exec_result.term) {
416 .Exited => |code| {
417 if (code != 0) return error.CCompilerExitCode;
571 switch (exec_res.term) {
572 .Exited => |code| if (code != 0) {
573 printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr);
574 return error.CCompilerExitCode;
418575 },
419576 else => {
577 printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr);
420578 return error.CCompilerCrashed;
421579 },
422580 }
423 var it = std.mem.tokenize(exec_result.stdout, "\n\r");
581
582 var it = std.mem.tokenize(exec_res.stdout, "\n\r");
424583 const line = it.next() orelse return error.LibCRuntimeNotFound;
425 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
584 // When this command fails, it returns exit code 0 and duplicates the input file name.
585 // So we detect failure by checking if the output matches exactly the input.
586 if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
587 switch (args.want_dirname) {
588 .full_path => return std.mem.dupeZ(allocator, u8, line),
589 .only_dir => {
590 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
591 return std.mem.dupeZ(allocator, u8, dirname);
592 },
593 }
594}
595
596fn printVerboseInvocation(
597 argv: []const []const u8,
598 search_basename: ?[]const u8,
599 verbose: bool,
600 stderr: ?[]const u8,
601) void {
602 if (!verbose) return;
426603
427 if (want_dirname) {
428 return std.mem.dupe(allocator, u8, dirname);
604 if (search_basename) |s| {
605 std.debug.warn("Zig attempted to find the file '{}' by executing this command:\n", .{s});
429606 } else {
430 return std.mem.dupe(allocator, u8, line);
607 std.debug.warn("Zig attempted to find the path to native system libc headers by executing this command:\n", .{});
608 }
609 for (argv) |arg, i| {
610 if (i != 0) std.debug.warn(" ", .{});
611 std.debug.warn("{}", .{arg});
612 }
613 std.debug.warn("\n", .{});
614 if (stderr) |s| {
615 std.debug.warn("Output:\n==========\n{}\n==========\n", .{s});
616 }
617}
618
619/// Caller owns returned memory.
620pub fn detectNativeDynamicLinker(allocator: *Allocator) error{
621 OutOfMemory,
622 TargetHasNoDynamicLinker,
623 UnknownDynamicLinkerPath,
624}![:0]u8 {
625 if (!comptime Target.current.hasDynamicLinker()) {
626 return error.TargetHasNoDynamicLinker;
627 }
628
629 // The current target's ABI cannot be relied on for this. For example, we may build the zig
630 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
631 // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined
632 // and supported by Zig. But that means that we must detect the system ABI here rather than
633 // relying on `std.Target.current`.
634
635 const LdInfo = struct {
636 ld_path: []u8,
637 abi: Target.Abi,
638 };
639 var ld_info_list = std.ArrayList(LdInfo).init(allocator);
640 defer {
641 for (ld_info_list.toSlice()) |ld_info| allocator.free(ld_info.ld_path);
642 ld_info_list.deinit();
643 }
644
645 const all_abis = comptime blk: {
646 const fields = std.meta.fields(Target.Abi);
647 var array: [fields.len]Target.Abi = undefined;
648 inline for (fields) |field, i| {
649 array[i] = @field(Target.Abi, field.name);
650 }
651 break :blk array;
652 };
653 for (all_abis) |abi| {
654 // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
655 // skip adding it to `ld_info_list`.
656 const target: Target = .{
657 .Cross = .{
658 .cpu = Target.Cpu.baseline(Target.current.getArch()),
659 .os = Target.current.getOs(),
660 .abi = abi,
661 },
662 };
663 const standard_ld_path = target.getStandardDynamicLinkerPath(allocator) catch |err| switch (err) {
664 error.OutOfMemory => return error.OutOfMemory,
665 error.UnknownDynamicLinkerPath, error.TargetHasNoDynamicLinker => continue,
666 };
667 errdefer allocator.free(standard_ld_path);
668 try ld_info_list.append(.{
669 .ld_path = standard_ld_path,
670 .abi = abi,
671 });
672 }
673
674 // Best case scenario: the zig compiler is dynamically linked, and we can iterate
675 // over our own shared objects and find a dynamic linker.
676 {
677 const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator);
678 defer allocator.free(lib_paths);
679
680 // This is O(N^M) but typical case here is N=2 and M=10.
681 for (lib_paths) |lib_path| {
682 for (ld_info_list.toSlice()) |ld_info| {
683 const standard_ld_basename = fs.path.basename(ld_info.ld_path);
684 if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) {
685 return std.mem.dupeZ(allocator, u8, lib_path);
686 }
687 }
688 }
689 }
690
691 // If Zig is statically linked, such as via distributed binary static builds, the above
692 // trick won't work. What are we left with? Try to run the system C compiler and get
693 // it to tell us the dynamic linker path.
694 // TODO: instead of this, look at the shared libs of /usr/bin/env.
695 for (ld_info_list.toSlice()) |ld_info| {
696 const standard_ld_basename = fs.path.basename(ld_info.ld_path);
697
698 const full_ld_path = ccPrintFileName(.{
699 .allocator = allocator,
700 .search_basename = standard_ld_basename,
701 .want_dirname = .full_path,
702 }) catch |err| switch (err) {
703 error.OutOfMemory => return error.OutOfMemory,
704 error.LibCRuntimeNotFound,
705 error.CCompilerExitCode,
706 error.CCompilerCrashed,
707 error.UnableToSpawnCCompiler,
708 => continue,
709 };
710 return full_ld_path;
431711 }
712
713 // Finally, we fall back on the standard path.
714 return Target.current.getStandardDynamicLinkerPath(allocator);
432715}
433716
434717const Search = struct {
......@@ -436,34 +719,25 @@ const Search = struct {
436719 version: []const u8,
437720};
438721
439fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search {
722fn fillSearch(search_buf: *[2]Search, sdk: *ZigWindowsSDK) []Search {
440723 var search_end: usize = 0;
441 if (sdk.path10_ptr != 0) {
442 if (sdk.version10_ptr != 0) {
724 if (sdk.path10_ptr) |path10_ptr| {
725 if (sdk.version10_ptr) |version10_ptr| {
443726 search_buf[search_end] = Search{
444 .path = sdk.path10_ptr[0..sdk.path10_len],
445 .version = sdk.version10_ptr[0..sdk.version10_len],
727 .path = path10_ptr[0..sdk.path10_len],
728 .version = version10_ptr[0..sdk.version10_len],
446729 };
447730 search_end += 1;
448731 }
449732 }
450 if (sdk.path81_ptr != 0) {
451 if (sdk.version81_ptr != 0) {
733 if (sdk.path81_ptr) |path81_ptr| {
734 if (sdk.version81_ptr) |version81_ptr| {
452735 search_buf[search_end] = Search{
453 .path = sdk.path81_ptr[0..sdk.path81_len],
454 .version = sdk.version81_ptr[0..sdk.version81_len],
736 .path = path81_ptr[0..sdk.path81_len],
737 .version = version81_ptr[0..sdk.version81_len],
455738 };
456739 search_end += 1;
457740 }
458741 }
459742 return search_buf[0..search_end];
460743}
461
462fn fileExists(path: []const u8) !bool {
463 if (fs.File.access(path)) |_| {
464 return true;
465 } else |err| switch (err) {
466 error.FileNotFound => return false,
467 else => return error.FileSystem,
468 }
469}
src-self-hosted/print_targets.zig+34-50
......@@ -113,37 +113,14 @@ pub fn cmdTargets(
113113 try jws.beginObject();
114114
115115 try jws.objectField("arch");
116 try jws.beginObject();
116 try jws.beginArray();
117117 {
118 inline for (@typeInfo(Target.Arch).Union.fields) |field| {
119 try jws.objectField(field.name);
120 if (field.field_type == void) {
121 try jws.emitNull();
122 } else {
123 try jws.emitString(@typeName(field.field_type));
124 }
125 }
126 }
127 try jws.endObject();
128
129 try jws.objectField("subArch");
130 try jws.beginObject();
131 const sub_arch_list = [_]type{
132 Target.Arch.Arm32,
133 Target.Arch.Arm64,
134 Target.Arch.Kalimba,
135 Target.Arch.Mips,
136 };
137 inline for (sub_arch_list) |SubArch| {
138 try jws.objectField(@typeName(SubArch));
139 try jws.beginArray();
140 inline for (@typeInfo(SubArch).Enum.fields) |field| {
118 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
141119 try jws.arrayElem();
142120 try jws.emitString(field.name);
143121 }
144 try jws.endArray();
145122 }
146 try jws.endObject();
123 try jws.endArray();
147124
148125 try jws.objectField("os");
149126 try jws.beginArray();
......@@ -179,15 +156,15 @@ pub fn cmdTargets(
179156
180157 try jws.objectField("cpus");
181158 try jws.beginObject();
182 inline for (@typeInfo(Target.Arch).Union.fields) |field| {
159 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
183160 try jws.objectField(field.name);
184161 try jws.beginObject();
185 const arch = @unionInit(Target.Arch, field.name, undefined);
186 for (arch.allCpus()) |cpu| {
187 try jws.objectField(cpu.name);
162 const arch = @field(Target.Cpu.Arch, field.name);
163 for (arch.allCpuModels()) |model| {
164 try jws.objectField(model.name);
188165 try jws.beginArray();
189166 for (arch.allFeaturesList()) |feature, i| {
190 if (cpu.features.isEnabled(@intCast(u8, i))) {
167 if (model.features.isEnabled(@intCast(u8, i))) {
191168 try jws.arrayElem();
192169 try jws.emitString(feature.name);
193170 }
......@@ -200,10 +177,10 @@ pub fn cmdTargets(
200177
201178 try jws.objectField("cpuFeatures");
202179 try jws.beginObject();
203 inline for (@typeInfo(Target.Arch).Union.fields) |field| {
180 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
204181 try jws.objectField(field.name);
205182 try jws.beginArray();
206 const arch = @unionInit(Target.Arch, field.name, undefined);
183 const arch = @field(Target.Cpu.Arch, field.name);
207184 for (arch.allFeaturesList()) |feature| {
208185 try jws.arrayElem();
209186 try jws.emitString(feature.name);
......@@ -220,27 +197,34 @@ pub fn cmdTargets(
220197 try jws.objectField("triple");
221198 try jws.emitString(triple);
222199 }
223 try jws.objectField("arch");
224 try jws.emitString(@tagName(native_target.getArch()));
225 try jws.objectField("os");
226 try jws.emitString(@tagName(native_target.getOs()));
227 try jws.objectField("abi");
228 try jws.emitString(@tagName(native_target.getAbi()));
229 try jws.objectField("cpuName");
230 const cpu_features = native_target.getCpuFeatures();
231 try jws.emitString(cpu_features.cpu.name);
232200 {
233 try jws.objectField("cpuFeatures");
234 try jws.beginArray();
235 for (native_target.getArch().allFeaturesList()) |feature, i_usize| {
236 const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
237 if (cpu_features.features.isEnabled(index)) {
238 try jws.arrayElem();
239 try jws.emitString(feature.name);
201 try jws.objectField("cpu");
202 try jws.beginObject();
203 try jws.objectField("arch");
204 try jws.emitString(@tagName(native_target.getArch()));
205
206 try jws.objectField("name");
207 const cpu = native_target.getCpu();
208 try jws.emitString(cpu.model.name);
209
210 {
211 try jws.objectField("features");
212 try jws.beginArray();
213 for (native_target.getArch().allFeaturesList()) |feature, i_usize| {
214 const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
215 if (cpu.features.isEnabled(index)) {
216 try jws.arrayElem();
217 try jws.emitString(feature.name);
218 }
240219 }
220 try jws.endArray();
241221 }
242 try jws.endArray();
222 try jws.endObject();
243223 }
224 try jws.objectField("os");
225 try jws.emitString(@tagName(native_target.getOs()));
226 try jws.objectField("abi");
227 try jws.emitString(@tagName(native_target.getAbi()));
244228 // TODO implement native glibc version detection in self-hosted
245229 try jws.endObject();
246230
src-self-hosted/stage1.zig deleted-832
......@@ -1,832 +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
4const std = @import("std");
5const io = std.io;
6const mem = std.mem;
7const fs = std.fs;
8const process = std.process;
9const Allocator = mem.Allocator;
10const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;
12const Target = std.Target;
13const self_hosted_main = @import("main.zig");
14const errmsg = @import("errmsg.zig");
15const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
16const assert = std.debug.assert;
17
18var stderr_file: fs.File = undefined;
19var stderr: *io.OutStream(fs.File.WriteError) = undefined;
20var stdout: *io.OutStream(fs.File.WriteError) = undefined;
21
22comptime {
23 _ = @import("dep_tokenizer.zig");
24}
25
26// ABI warning
27export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
28 const info_zen = @import("main.zig").info_zen;
29 ptr.* = info_zen;
30 len.* = info_zen.len;
31}
32
33// ABI warning
34export fn stage2_panic(ptr: [*]const u8, len: usize) void {
35 @panic(ptr[0..len]);
36}
37
38// ABI warning
39const Error = extern enum {
40 None,
41 OutOfMemory,
42 InvalidFormat,
43 SemanticAnalyzeFail,
44 AccessDenied,
45 Interrupted,
46 SystemResources,
47 FileNotFound,
48 FileSystem,
49 FileTooBig,
50 DivByZero,
51 Overflow,
52 PathAlreadyExists,
53 Unexpected,
54 ExactDivRemainder,
55 NegativeDenominator,
56 ShiftedOutOneBits,
57 CCompileErrors,
58 EndOfFile,
59 IsDir,
60 NotDir,
61 UnsupportedOperatingSystem,
62 SharingViolation,
63 PipeBusy,
64 PrimitiveTypeNotFound,
65 CacheUnavailable,
66 PathTooLong,
67 CCompilerCannotFindFile,
68 NoCCompilerInstalled,
69 ReadingDepFile,
70 InvalidDepFile,
71 MissingArchitecture,
72 MissingOperatingSystem,
73 UnknownArchitecture,
74 UnknownOperatingSystem,
75 UnknownABI,
76 InvalidFilename,
77 DiskQuota,
78 DiskSpace,
79 UnexpectedWriteFailure,
80 UnexpectedSeekFailure,
81 UnexpectedFileTruncationFailure,
82 Unimplemented,
83 OperationAborted,
84 BrokenPipe,
85 NoSpaceLeft,
86 NotLazy,
87 IsAsync,
88 ImportOutsidePkgPath,
89 UnknownCpu,
90 UnknownSubArchitecture,
91 UnknownCpuFeature,
92 InvalidCpuFeatures,
93 InvalidLlvmCpuFeaturesFormat,
94 UnknownApplicationBinaryInterface,
95};
96
97const FILE = std.c.FILE;
98const ast = std.zig.ast;
99const translate_c = @import("translate_c.zig");
100
101/// Args should have a null terminating last arg.
102export fn stage2_translate_c(
103 out_ast: **ast.Tree,
104 out_errors_ptr: *[*]translate_c.ClangErrMsg,
105 out_errors_len: *usize,
106 args_begin: [*]?[*]const u8,
107 args_end: [*]?[*]const u8,
108 resources_path: [*:0]const u8,
109) Error {
110 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
111 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
112 error.SemanticAnalyzeFail => {
113 out_errors_ptr.* = errors.ptr;
114 out_errors_len.* = errors.len;
115 return Error.CCompileErrors;
116 },
117 error.OutOfMemory => return Error.OutOfMemory,
118 };
119 return Error.None;
120}
121
122export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
123 translate_c.freeErrors(errors_ptr[0..errors_len]);
124}
125
126export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
127 const c_out_stream = &std.io.COutStream.init(output_file).stream;
128 _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
129 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
130 error.SystemResources => return Error.SystemResources,
131 error.OperationAborted => return Error.OperationAborted,
132 error.BrokenPipe => return Error.BrokenPipe,
133 error.DiskQuota => return Error.DiskQuota,
134 error.FileTooBig => return Error.FileTooBig,
135 error.NoSpaceLeft => return Error.NoSpaceLeft,
136 error.AccessDenied => return Error.AccessDenied,
137 error.OutOfMemory => return Error.OutOfMemory,
138 error.Unexpected => return Error.Unexpected,
139 error.InputOutput => return Error.FileSystem,
140 };
141 return Error.None;
142}
143
144// TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377,
145// we use a blocking implementation.
146export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
147 if (std.debug.runtime_safety) {
148 fmtMain(argc, argv) catch unreachable;
149 } else {
150 fmtMain(argc, argv) catch |e| {
151 std.debug.warn("{}\n", .{@errorName(e)});
152 return -1;
153 };
154 }
155 return 0;
156}
157
158fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
159 const allocator = std.heap.c_allocator;
160 var args_list = std.ArrayList([]const u8).init(allocator);
161 const argc_usize = @intCast(usize, argc);
162 var arg_i: usize = 0;
163 while (arg_i < argc_usize) : (arg_i += 1) {
164 try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
165 }
166
167 stdout = &std.io.getStdOut().outStream().stream;
168 stderr_file = std.io.getStdErr();
169 stderr = &stderr_file.outStream().stream;
170
171 const args = args_list.toSliceConst()[2..];
172
173 var color: errmsg.Color = .Auto;
174 var stdin_flag: bool = false;
175 var check_flag: bool = false;
176 var input_files = ArrayList([]const u8).init(allocator);
177
178 {
179 var i: usize = 0;
180 while (i < args.len) : (i += 1) {
181 const arg = args[i];
182 if (mem.startsWith(u8, arg, "-")) {
183 if (mem.eql(u8, arg, "--help")) {
184 try stdout.write(self_hosted_main.usage_fmt);
185 process.exit(0);
186 } else if (mem.eql(u8, arg, "--color")) {
187 if (i + 1 >= args.len) {
188 try stderr.write("expected [auto|on|off] after --color\n");
189 process.exit(1);
190 }
191 i += 1;
192 const next_arg = args[i];
193 if (mem.eql(u8, next_arg, "auto")) {
194 color = .Auto;
195 } else if (mem.eql(u8, next_arg, "on")) {
196 color = .On;
197 } else if (mem.eql(u8, next_arg, "off")) {
198 color = .Off;
199 } else {
200 try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg});
201 process.exit(1);
202 }
203 } else if (mem.eql(u8, arg, "--stdin")) {
204 stdin_flag = true;
205 } else if (mem.eql(u8, arg, "--check")) {
206 check_flag = true;
207 } else {
208 try stderr.print("unrecognized parameter: '{}'", .{arg});
209 process.exit(1);
210 }
211 } else {
212 try input_files.append(arg);
213 }
214 }
215 }
216
217 if (stdin_flag) {
218 if (input_files.len != 0) {
219 try stderr.write("cannot use --stdin with positional arguments\n");
220 process.exit(1);
221 }
222
223 const stdin_file = io.getStdIn();
224 var stdin = stdin_file.inStream();
225
226 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
227 defer allocator.free(source_code);
228
229 const tree = std.zig.parse(allocator, source_code) catch |err| {
230 try stderr.print("error parsing stdin: {}\n", .{err});
231 process.exit(1);
232 };
233 defer tree.deinit();
234
235 var error_it = tree.errors.iterator(0);
236 while (error_it.next()) |parse_error| {
237 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
238 }
239 if (tree.errors.len != 0) {
240 process.exit(1);
241 }
242 if (check_flag) {
243 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
244 const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
245 process.exit(code);
246 }
247
248 _ = try std.zig.render(allocator, stdout, tree);
249 return;
250 }
251
252 if (input_files.len == 0) {
253 try stderr.write("expected at least one source file argument\n");
254 process.exit(1);
255 }
256
257 var fmt = Fmt{
258 .seen = Fmt.SeenMap.init(allocator),
259 .any_error = false,
260 .color = color,
261 .allocator = allocator,
262 };
263
264 for (input_files.toSliceConst()) |file_path| {
265 try fmtPath(&fmt, file_path, check_flag);
266 }
267 if (fmt.any_error) {
268 process.exit(1);
269 }
270}
271
272const FmtError = error{
273 SystemResources,
274 OperationAborted,
275 IoPending,
276 BrokenPipe,
277 Unexpected,
278 WouldBlock,
279 FileClosed,
280 DestinationAddressRequired,
281 DiskQuota,
282 FileTooBig,
283 InputOutput,
284 NoSpaceLeft,
285 AccessDenied,
286 OutOfMemory,
287 RenameAcrossMountPoints,
288 ReadOnlyFileSystem,
289 LinkQuotaExceeded,
290 FileBusy,
291} || fs.File.OpenError;
292
293fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
294 if (fmt.seen.exists(file_path)) return;
295 try fmt.seen.put(file_path);
296
297 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
298 error.IsDir, error.AccessDenied => {
299 // TODO make event based (and dir.next())
300 var dir = try fs.cwd().openDirList(file_path);
301 defer dir.close();
302
303 var dir_it = dir.iterate();
304
305 while (try dir_it.next()) |entry| {
306 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
307 const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name });
308 try fmtPath(fmt, full_path, check_mode);
309 }
310 }
311 return;
312 },
313 else => {
314 // TODO lock stderr printing
315 try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
316 fmt.any_error = true;
317 return;
318 },
319 };
320 defer fmt.allocator.free(source_code);
321
322 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
323 try stderr.print("error parsing file '{}': {}\n", .{ file_path, err });
324 fmt.any_error = true;
325 return;
326 };
327 defer tree.deinit();
328
329 var error_it = tree.errors.iterator(0);
330 while (error_it.next()) |parse_error| {
331 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
332 }
333 if (tree.errors.len != 0) {
334 fmt.any_error = true;
335 return;
336 }
337
338 if (check_mode) {
339 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
340 if (anything_changed) {
341 try stderr.print("{}\n", .{file_path});
342 fmt.any_error = true;
343 }
344 } else {
345 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
346 defer baf.destroy();
347
348 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
349 if (anything_changed) {
350 try stderr.print("{}\n", .{file_path});
351 try baf.finish();
352 }
353 }
354}
355
356const Fmt = struct {
357 seen: SeenMap,
358 any_error: bool,
359 color: errmsg.Color,
360 allocator: *mem.Allocator,
361
362 const SeenMap = std.BufSet;
363};
364
365fn printErrMsgToFile(
366 allocator: *mem.Allocator,
367 parse_error: *const ast.Error,
368 tree: *ast.Tree,
369 path: []const u8,
370 file: fs.File,
371 color: errmsg.Color,
372) !void {
373 const color_on = switch (color) {
374 .Auto => file.isTty(),
375 .On => true,
376 .Off => false,
377 };
378 const lok_token = parse_error.loc();
379 const span = errmsg.Span{
380 .first = lok_token,
381 .last = lok_token,
382 };
383
384 const first_token = tree.tokens.at(span.first);
385 const last_token = tree.tokens.at(span.last);
386 const start_loc = tree.tokenLocationPtr(0, first_token);
387 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
388
389 var text_buf = try std.Buffer.initSize(allocator, 0);
390 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
391 try parse_error.render(&tree.tokens, out_stream);
392 const text = text_buf.toOwnedSlice();
393
394 const stream = &file.outStream().stream;
395 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
396
397 if (!color_on) return;
398
399 // Print \r and \t as one space each so that column counts line up
400 for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| {
401 try stream.writeByte(switch (byte) {
402 '\r', '\t' => ' ',
403 else => byte,
404 });
405 }
406 try stream.writeByte('\n');
407 try stream.writeByteNTimes(' ', start_loc.column);
408 try stream.writeByteNTimes('~', last_token.end - first_token.start);
409 try stream.writeByte('\n');
410}
411
412export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
413 const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
414 t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
415 return stage2_DepTokenizer{
416 .handle = t,
417 };
418}
419
420export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
421 self.handle.deinit();
422}
423
424export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
425 const otoken = self.handle.next() catch {
426 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
427 return stage2_DepNextResult{
428 .type_id = .error_,
429 .textz = textz.toSlice().ptr,
430 };
431 };
432 const token = otoken orelse {
433 return stage2_DepNextResult{
434 .type_id = .null_,
435 .textz = undefined,
436 };
437 };
438 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
439 return stage2_DepNextResult{
440 .type_id = switch (token.id) {
441 .target => .target,
442 .prereq => .prereq,
443 },
444 .textz = textz.toSlice().ptr,
445 };
446}
447
448const stage2_DepTokenizer = extern struct {
449 handle: *DepTokenizer,
450};
451
452const stage2_DepNextResult = extern struct {
453 type_id: TypeId,
454
455 // when type_id == error --> error text
456 // when type_id == null --> undefined
457 // when type_id == target --> target pathname
458 // when type_id == prereq --> prereq pathname
459 textz: [*]const u8,
460
461 const TypeId = extern enum {
462 error_,
463 null_,
464 target,
465 prereq,
466 };
467};
468
469// ABI warning
470export fn stage2_attach_segfault_handler() void {
471 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
472 std.debug.attachSegfaultHandler();
473 }
474}
475
476// ABI warning
477export fn stage2_progress_create() *std.Progress {
478 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
479 ptr.* = std.Progress{};
480 return ptr;
481}
482
483// ABI warning
484export fn stage2_progress_destroy(progress: *std.Progress) void {
485 std.heap.c_allocator.destroy(progress);
486}
487
488// ABI warning
489export fn stage2_progress_start_root(
490 progress: *std.Progress,
491 name_ptr: [*]const u8,
492 name_len: usize,
493 estimated_total_items: usize,
494) *std.Progress.Node {
495 return progress.start(
496 name_ptr[0..name_len],
497 if (estimated_total_items == 0) null else estimated_total_items,
498 ) catch @panic("timer unsupported");
499}
500
501// ABI warning
502export fn stage2_progress_disable_tty(progress: *std.Progress) void {
503 progress.terminal = null;
504}
505
506// ABI warning
507export fn stage2_progress_start(
508 node: *std.Progress.Node,
509 name_ptr: [*]const u8,
510 name_len: usize,
511 estimated_total_items: usize,
512) *std.Progress.Node {
513 const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory");
514 child_node.* = node.start(
515 name_ptr[0..name_len],
516 if (estimated_total_items == 0) null else estimated_total_items,
517 );
518 child_node.activate();
519 return child_node;
520}
521
522// ABI warning
523export fn stage2_progress_end(node: *std.Progress.Node) void {
524 node.end();
525 if (&node.context.root != node) {
526 std.heap.c_allocator.destroy(node);
527 }
528}
529
530// ABI warning
531export fn stage2_progress_complete_one(node: *std.Progress.Node) void {
532 node.completeOne();
533}
534
535// ABI warning
536export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void {
537 node.completed_items = done_count;
538 node.estimated_total_items = total_count;
539 node.activate();
540 node.context.maybeRefresh();
541}
542
543fn cpuFeaturesFromLLVM(
544 arch: Target.Arch,
545 llvm_cpu_name_z: ?[*:0]const u8,
546 llvm_cpu_features_opt: ?[*:0]const u8,
547) !Target.CpuFeatures {
548 var result = arch.getBaselineCpuFeatures();
549
550 if (llvm_cpu_name_z) |cpu_name_z| {
551 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
552
553 for (arch.allCpus()) |cpu| {
554 const this_llvm_name = cpu.llvm_name orelse continue;
555 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
556 // Here we use the non-dependencies-populated set,
557 // so that subtracting features later in this function
558 // affect the prepopulated set.
559 result = Target.CpuFeatures{
560 .cpu = cpu,
561 .features = cpu.features,
562 };
563 break;
564 }
565 }
566 }
567
568 const all_features = arch.allFeaturesList();
569
570 if (llvm_cpu_features_opt) |llvm_cpu_features| {
571 var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
572 while (it.next()) |decorated_llvm_feat| {
573 var op: enum {
574 add,
575 sub,
576 } = undefined;
577 var llvm_feat: []const u8 = undefined;
578 if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
579 op = .add;
580 llvm_feat = decorated_llvm_feat[1..];
581 } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
582 op = .sub;
583 llvm_feat = decorated_llvm_feat[1..];
584 } else {
585 return error.InvalidLlvmCpuFeaturesFormat;
586 }
587 for (all_features) |feature, index_usize| {
588 const this_llvm_name = feature.llvm_name orelse continue;
589 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
590 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
591 switch (op) {
592 .add => result.features.addFeature(index),
593 .sub => result.features.removeFeature(index),
594 }
595 break;
596 }
597 }
598 }
599 }
600
601 result.features.populateDependencies(all_features);
602 return result;
603}
604
605// ABI warning
606export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int {
607 cmdTargets(zig_triple) catch |err| {
608 std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
609 return -1;
610 };
611 return 0;
612}
613
614fn cmdTargets(zig_triple: [*:0]const u8) !void {
615 var target = try Target.parse(mem.toSliceConst(u8, zig_triple));
616 target.Cross.cpu_features = blk: {
617 const llvm = @import("llvm.zig");
618 const llvm_cpu_name = llvm.GetHostCPUName();
619 const llvm_cpu_features = llvm.GetNativeFeatures();
620 break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features);
621 };
622 return @import("print_targets.zig").cmdTargets(
623 std.heap.c_allocator,
624 &[0][]u8{},
625 &std.io.getStdOut().outStream().stream,
626 target,
627 );
628}
629
630const Stage2CpuFeatures = struct {
631 allocator: *mem.Allocator,
632 cpu_features: Target.CpuFeatures,
633
634 llvm_features_str: ?[*:0]const u8,
635
636 builtin_str: [:0]const u8,
637 cache_hash: [:0]const u8,
638
639 const Self = @This();
640
641 fn createFromNative(allocator: *mem.Allocator) !*Self {
642 const arch = Target.current.getArch();
643 const llvm = @import("llvm.zig");
644 const llvm_cpu_name = llvm.GetHostCPUName();
645 const llvm_cpu_features = llvm.GetNativeFeatures();
646 const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name, llvm_cpu_features);
647 return createFromCpuFeatures(allocator, arch, cpu_features);
648 }
649
650 fn createFromCpuFeatures(
651 allocator: *mem.Allocator,
652 arch: Target.Arch,
653 cpu_features: Target.CpuFeatures,
654 ) !*Self {
655 const self = try allocator.create(Self);
656 errdefer allocator.destroy(self);
657
658 const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{
659 cpu_features.cpu.name,
660 cpu_features.features.asBytes(),
661 });
662 errdefer allocator.free(cache_hash);
663
664 const generic_arch_name = arch.genericName();
665 var builtin_str_buffer = try std.Buffer.allocPrint(allocator,
666 \\CpuFeatures{{
667 \\ .cpu = &Target.{}.cpu.{},
668 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
669 \\
670 , .{
671 generic_arch_name,
672 cpu_features.cpu.name,
673 generic_arch_name,
674 generic_arch_name,
675 });
676 defer builtin_str_buffer.deinit();
677
678 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
679 defer llvm_features_buffer.deinit();
680
681 for (arch.allFeaturesList()) |feature, index_usize| {
682 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
683 const is_enabled = cpu_features.features.isEnabled(index);
684
685 if (feature.llvm_name) |llvm_name| {
686 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
687 try llvm_features_buffer.appendByte(plus_or_minus);
688 try llvm_features_buffer.append(llvm_name);
689 try llvm_features_buffer.append(",");
690 }
691
692 if (is_enabled) {
693 // TODO some kind of "zig identifier escape" function rather than
694 // unconditionally using @"" syntax
695 try builtin_str_buffer.append(" .@\"");
696 try builtin_str_buffer.append(feature.name);
697 try builtin_str_buffer.append("\",\n");
698 }
699 }
700
701 try builtin_str_buffer.append(
702 \\ }),
703 \\};
704 \\
705 );
706
707 assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
708 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
709
710 self.* = Self{
711 .allocator = allocator,
712 .cpu_features = cpu_features,
713 .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr,
714 .builtin_str = builtin_str_buffer.toOwnedSlice(),
715 .cache_hash = cache_hash,
716 };
717 return self;
718 }
719
720 fn destroy(self: *Self) void {
721 self.allocator.free(self.cache_hash);
722 self.allocator.free(self.builtin_str);
723 // TODO if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str);
724 self.allocator.destroy(self);
725 }
726};
727
728// ABI warning
729export fn stage2_cpu_features_parse(
730 result: **Stage2CpuFeatures,
731 zig_triple: ?[*:0]const u8,
732 cpu_name: ?[*:0]const u8,
733 cpu_features: ?[*:0]const u8,
734) Error {
735 result.* = stage2ParseCpuFeatures(zig_triple, cpu_name, cpu_features) catch |err| switch (err) {
736 error.OutOfMemory => return .OutOfMemory,
737 error.UnknownArchitecture => return .UnknownArchitecture,
738 error.UnknownSubArchitecture => return .UnknownSubArchitecture,
739 error.UnknownOperatingSystem => return .UnknownOperatingSystem,
740 error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
741 error.MissingOperatingSystem => return .MissingOperatingSystem,
742 error.MissingArchitecture => return .MissingArchitecture,
743 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
744 error.InvalidCpuFeatures => return .InvalidCpuFeatures,
745 };
746 return .None;
747}
748
749fn stage2ParseCpuFeatures(
750 zig_triple_oz: ?[*:0]const u8,
751 cpu_name_oz: ?[*:0]const u8,
752 cpu_features_oz: ?[*:0]const u8,
753) !*Stage2CpuFeatures {
754 const zig_triple_z = zig_triple_oz orelse return Stage2CpuFeatures.createFromNative(std.heap.c_allocator);
755 const target = try Target.parse(mem.toSliceConst(u8, zig_triple_z));
756 const arch = target.Cross.arch;
757
758 const cpu = if (cpu_name_oz) |cpu_name_z| blk: {
759 const cpu_name = mem.toSliceConst(u8, cpu_name_z);
760 break :blk arch.parseCpu(cpu_name) catch |err| switch (err) {
761 error.UnknownCpu => {
762 std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
763 cpu_name,
764 @tagName(arch),
765 });
766 for (arch.allCpus()) |cpu| {
767 std.debug.warn(" {}\n", .{cpu.name});
768 }
769 process.exit(1);
770 },
771 else => |e| return e,
772 };
773 } else target.Cross.cpu_features.cpu;
774
775 var set = if (cpu_features_oz) |cpu_features_z| blk: {
776 const cpu_features = mem.toSliceConst(u8, cpu_features_z);
777 break :blk arch.parseCpuFeatureSet(cpu, cpu_features) catch |err| switch (err) {
778 error.UnknownCpuFeature => {
779 std.debug.warn(
780 \\Unknown CPU features specified.
781 \\Available CPU features for architecture '{}':
782 \\
783 , .{@tagName(arch)});
784 for (arch.allFeaturesList()) |feature| {
785 std.debug.warn(" {}\n", .{feature.name});
786 }
787 process.exit(1);
788 },
789 else => |e| return e,
790 };
791 } else cpu.features;
792
793 if (arch.subArchFeature()) |index| {
794 set.addFeature(index);
795 }
796 set.populateDependencies(arch.allFeaturesList());
797
798 return Stage2CpuFeatures.createFromCpuFeatures(std.heap.c_allocator, arch, .{
799 .cpu = cpu,
800 .features = set,
801 });
802}
803
804// ABI warning
805export fn stage2_cpu_features_get_cache_hash(
806 cpu_features: *const Stage2CpuFeatures,
807 ptr: *[*:0]const u8,
808 len: *usize,
809) void {
810 ptr.* = cpu_features.cache_hash.ptr;
811 len.* = cpu_features.cache_hash.len;
812}
813
814// ABI warning
815export fn stage2_cpu_features_get_builtin_str(
816 cpu_features: *const Stage2CpuFeatures,
817 ptr: *[*:0]const u8,
818 len: *usize,
819) void {
820 ptr.* = cpu_features.builtin_str.ptr;
821 len.* = cpu_features.builtin_str.len;
822}
823
824// ABI warning
825export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
826 return if (cpu_features.cpu_features.cpu.llvm_name) |s| s.ptr else null;
827}
828
829// ABI warning
830export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
831 return cpu_features.llvm_features_str;
832}
src-self-hosted/stage2.zig created+1064
......@@ -0,0 +1,1064 @@
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
4const std = @import("std");
5const io = std.io;
6const mem = std.mem;
7const fs = std.fs;
8const process = std.process;
9const Allocator = mem.Allocator;
10const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;
12const Target = std.Target;
13const self_hosted_main = @import("main.zig");
14const errmsg = @import("errmsg.zig");
15const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
16const assert = std.debug.assert;
17const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
18
19var stderr_file: fs.File = undefined;
20var stderr: *io.OutStream(fs.File.WriteError) = undefined;
21var stdout: *io.OutStream(fs.File.WriteError) = undefined;
22
23comptime {
24 _ = @import("dep_tokenizer.zig");
25}
26
27// ABI warning
28export 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
35export fn stage2_panic(ptr: [*]const u8, len: usize) void {
36 @panic(ptr[0..len]);
37}
38
39// ABI warning
40const 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 UnknownCpuFeature,
92 InvalidCpuFeatures,
93 InvalidLlvmCpuFeaturesFormat,
94 UnknownApplicationBinaryInterface,
95 ASTUnitFailure,
96 BadPathName,
97 SymLinkLoop,
98 ProcessFdQuotaExceeded,
99 SystemFdQuotaExceeded,
100 NoDevice,
101 DeviceBusy,
102 UnableToSpawnCCompiler,
103 CCompilerExitCode,
104 CCompilerCrashed,
105 CCompilerCannotFindHeaders,
106 LibCRuntimeNotFound,
107 LibCStdLibHeaderNotFound,
108 LibCKernel32LibNotFound,
109 UnsupportedArchitecture,
110 WindowsSdkNotFound,
111 UnknownDynamicLinkerPath,
112 TargetHasNoDynamicLinker,
113};
114
115const FILE = std.c.FILE;
116const ast = std.zig.ast;
117const translate_c = @import("translate_c.zig");
118
119/// Args should have a null terminating last arg.
120export fn stage2_translate_c(
121 out_ast: **ast.Tree,
122 out_errors_ptr: *[*]translate_c.ClangErrMsg,
123 out_errors_len: *usize,
124 args_begin: [*]?[*]const u8,
125 args_end: [*]?[*]const u8,
126 resources_path: [*:0]const u8,
127) Error {
128 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
129 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
130 error.SemanticAnalyzeFail => {
131 out_errors_ptr.* = errors.ptr;
132 out_errors_len.* = errors.len;
133 return .CCompileErrors;
134 },
135 error.ASTUnitFailure => return .ASTUnitFailure,
136 error.OutOfMemory => return .OutOfMemory,
137 };
138 return .None;
139}
140
141export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
142 translate_c.freeErrors(errors_ptr[0..errors_len]);
143}
144
145export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
146 const c_out_stream = &std.io.COutStream.init(output_file).stream;
147 _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
148 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
149 error.SystemResources => return .SystemResources,
150 error.OperationAborted => return .OperationAborted,
151 error.BrokenPipe => return .BrokenPipe,
152 error.DiskQuota => return .DiskQuota,
153 error.FileTooBig => return .FileTooBig,
154 error.NoSpaceLeft => return .NoSpaceLeft,
155 error.AccessDenied => return .AccessDenied,
156 error.OutOfMemory => return .OutOfMemory,
157 error.Unexpected => return .Unexpected,
158 error.InputOutput => return .FileSystem,
159 };
160 return .None;
161}
162
163// TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377,
164// we use a blocking implementation.
165export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
166 if (std.debug.runtime_safety) {
167 fmtMain(argc, argv) catch unreachable;
168 } else {
169 fmtMain(argc, argv) catch |e| {
170 std.debug.warn("{}\n", .{@errorName(e)});
171 return -1;
172 };
173 }
174 return 0;
175}
176
177fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
178 const allocator = std.heap.c_allocator;
179 var args_list = std.ArrayList([]const u8).init(allocator);
180 const argc_usize = @intCast(usize, argc);
181 var arg_i: usize = 0;
182 while (arg_i < argc_usize) : (arg_i += 1) {
183 try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
184 }
185
186 stdout = &std.io.getStdOut().outStream().stream;
187 stderr_file = std.io.getStdErr();
188 stderr = &stderr_file.outStream().stream;
189
190 const args = args_list.toSliceConst()[2..];
191
192 var color: errmsg.Color = .Auto;
193 var stdin_flag: bool = false;
194 var check_flag: bool = false;
195 var input_files = ArrayList([]const u8).init(allocator);
196
197 {
198 var i: usize = 0;
199 while (i < args.len) : (i += 1) {
200 const arg = args[i];
201 if (mem.startsWith(u8, arg, "-")) {
202 if (mem.eql(u8, arg, "--help")) {
203 try stdout.write(self_hosted_main.usage_fmt);
204 process.exit(0);
205 } else if (mem.eql(u8, arg, "--color")) {
206 if (i + 1 >= args.len) {
207 try stderr.write("expected [auto|on|off] after --color\n");
208 process.exit(1);
209 }
210 i += 1;
211 const next_arg = args[i];
212 if (mem.eql(u8, next_arg, "auto")) {
213 color = .Auto;
214 } else if (mem.eql(u8, next_arg, "on")) {
215 color = .On;
216 } else if (mem.eql(u8, next_arg, "off")) {
217 color = .Off;
218 } else {
219 try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg});
220 process.exit(1);
221 }
222 } else if (mem.eql(u8, arg, "--stdin")) {
223 stdin_flag = true;
224 } else if (mem.eql(u8, arg, "--check")) {
225 check_flag = true;
226 } else {
227 try stderr.print("unrecognized parameter: '{}'", .{arg});
228 process.exit(1);
229 }
230 } else {
231 try input_files.append(arg);
232 }
233 }
234 }
235
236 if (stdin_flag) {
237 if (input_files.len != 0) {
238 try stderr.write("cannot use --stdin with positional arguments\n");
239 process.exit(1);
240 }
241
242 const stdin_file = io.getStdIn();
243 var stdin = stdin_file.inStream();
244
245 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
246 defer allocator.free(source_code);
247
248 const tree = std.zig.parse(allocator, source_code) catch |err| {
249 try stderr.print("error parsing stdin: {}\n", .{err});
250 process.exit(1);
251 };
252 defer tree.deinit();
253
254 var error_it = tree.errors.iterator(0);
255 while (error_it.next()) |parse_error| {
256 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
257 }
258 if (tree.errors.len != 0) {
259 process.exit(1);
260 }
261 if (check_flag) {
262 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
263 const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
264 process.exit(code);
265 }
266
267 _ = try std.zig.render(allocator, stdout, tree);
268 return;
269 }
270
271 if (input_files.len == 0) {
272 try stderr.write("expected at least one source file argument\n");
273 process.exit(1);
274 }
275
276 var fmt = Fmt{
277 .seen = Fmt.SeenMap.init(allocator),
278 .any_error = false,
279 .color = color,
280 .allocator = allocator,
281 };
282
283 for (input_files.toSliceConst()) |file_path| {
284 try fmtPath(&fmt, file_path, check_flag);
285 }
286 if (fmt.any_error) {
287 process.exit(1);
288 }
289}
290
291const FmtError = error{
292 SystemResources,
293 OperationAborted,
294 IoPending,
295 BrokenPipe,
296 Unexpected,
297 WouldBlock,
298 FileClosed,
299 DestinationAddressRequired,
300 DiskQuota,
301 FileTooBig,
302 InputOutput,
303 NoSpaceLeft,
304 AccessDenied,
305 OutOfMemory,
306 RenameAcrossMountPoints,
307 ReadOnlyFileSystem,
308 LinkQuotaExceeded,
309 FileBusy,
310} || fs.File.OpenError;
311
312fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
313 if (fmt.seen.exists(file_path)) return;
314 try fmt.seen.put(file_path);
315
316 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
317 error.IsDir, error.AccessDenied => {
318 // TODO make event based (and dir.next())
319 var dir = try fs.cwd().openDirList(file_path);
320 defer dir.close();
321
322 var dir_it = dir.iterate();
323
324 while (try dir_it.next()) |entry| {
325 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
326 const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name });
327 try fmtPath(fmt, full_path, check_mode);
328 }
329 }
330 return;
331 },
332 else => {
333 // TODO lock stderr printing
334 try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
335 fmt.any_error = true;
336 return;
337 },
338 };
339 defer fmt.allocator.free(source_code);
340
341 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
342 try stderr.print("error parsing file '{}': {}\n", .{ file_path, err });
343 fmt.any_error = true;
344 return;
345 };
346 defer tree.deinit();
347
348 var error_it = tree.errors.iterator(0);
349 while (error_it.next()) |parse_error| {
350 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
351 }
352 if (tree.errors.len != 0) {
353 fmt.any_error = true;
354 return;
355 }
356
357 if (check_mode) {
358 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
359 if (anything_changed) {
360 try stderr.print("{}\n", .{file_path});
361 fmt.any_error = true;
362 }
363 } else {
364 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
365 defer baf.destroy();
366
367 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
368 if (anything_changed) {
369 try stderr.print("{}\n", .{file_path});
370 try baf.finish();
371 }
372 }
373}
374
375const Fmt = struct {
376 seen: SeenMap,
377 any_error: bool,
378 color: errmsg.Color,
379 allocator: *mem.Allocator,
380
381 const SeenMap = std.BufSet;
382};
383
384fn printErrMsgToFile(
385 allocator: *mem.Allocator,
386 parse_error: *const ast.Error,
387 tree: *ast.Tree,
388 path: []const u8,
389 file: fs.File,
390 color: errmsg.Color,
391) !void {
392 const color_on = switch (color) {
393 .Auto => file.isTty(),
394 .On => true,
395 .Off => false,
396 };
397 const lok_token = parse_error.loc();
398 const span = errmsg.Span{
399 .first = lok_token,
400 .last = lok_token,
401 };
402
403 const first_token = tree.tokens.at(span.first);
404 const last_token = tree.tokens.at(span.last);
405 const start_loc = tree.tokenLocationPtr(0, first_token);
406 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
407
408 var text_buf = try std.Buffer.initSize(allocator, 0);
409 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
410 try parse_error.render(&tree.tokens, out_stream);
411 const text = text_buf.toOwnedSlice();
412
413 const stream = &file.outStream().stream;
414 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
415
416 if (!color_on) return;
417
418 // Print \r and \t as one space each so that column counts line up
419 for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| {
420 try stream.writeByte(switch (byte) {
421 '\r', '\t' => ' ',
422 else => byte,
423 });
424 }
425 try stream.writeByte('\n');
426 try stream.writeByteNTimes(' ', start_loc.column);
427 try stream.writeByteNTimes('~', last_token.end - first_token.start);
428 try stream.writeByte('\n');
429}
430
431export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
432 const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
433 t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
434 return stage2_DepTokenizer{
435 .handle = t,
436 };
437}
438
439export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
440 self.handle.deinit();
441}
442
443export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
444 const otoken = self.handle.next() catch {
445 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
446 return stage2_DepNextResult{
447 .type_id = .error_,
448 .textz = textz.toSlice().ptr,
449 };
450 };
451 const token = otoken orelse {
452 return stage2_DepNextResult{
453 .type_id = .null_,
454 .textz = undefined,
455 };
456 };
457 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
458 return stage2_DepNextResult{
459 .type_id = switch (token.id) {
460 .target => .target,
461 .prereq => .prereq,
462 },
463 .textz = textz.toSlice().ptr,
464 };
465}
466
467const stage2_DepTokenizer = extern struct {
468 handle: *DepTokenizer,
469};
470
471const stage2_DepNextResult = extern struct {
472 type_id: TypeId,
473
474 // when type_id == error --> error text
475 // when type_id == null --> undefined
476 // when type_id == target --> target pathname
477 // when type_id == prereq --> prereq pathname
478 textz: [*]const u8,
479
480 const TypeId = extern enum {
481 error_,
482 null_,
483 target,
484 prereq,
485 };
486};
487
488// ABI warning
489export fn stage2_attach_segfault_handler() void {
490 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
491 std.debug.attachSegfaultHandler();
492 }
493}
494
495// ABI warning
496export fn stage2_progress_create() *std.Progress {
497 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
498 ptr.* = std.Progress{};
499 return ptr;
500}
501
502// ABI warning
503export fn stage2_progress_destroy(progress: *std.Progress) void {
504 std.heap.c_allocator.destroy(progress);
505}
506
507// ABI warning
508export fn stage2_progress_start_root(
509 progress: *std.Progress,
510 name_ptr: [*]const u8,
511 name_len: usize,
512 estimated_total_items: usize,
513) *std.Progress.Node {
514 return progress.start(
515 name_ptr[0..name_len],
516 if (estimated_total_items == 0) null else estimated_total_items,
517 ) catch @panic("timer unsupported");
518}
519
520// ABI warning
521export fn stage2_progress_disable_tty(progress: *std.Progress) void {
522 progress.terminal = null;
523}
524
525// ABI warning
526export fn stage2_progress_start(
527 node: *std.Progress.Node,
528 name_ptr: [*]const u8,
529 name_len: usize,
530 estimated_total_items: usize,
531) *std.Progress.Node {
532 const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory");
533 child_node.* = node.start(
534 name_ptr[0..name_len],
535 if (estimated_total_items == 0) null else estimated_total_items,
536 );
537 child_node.activate();
538 return child_node;
539}
540
541// ABI warning
542export fn stage2_progress_end(node: *std.Progress.Node) void {
543 node.end();
544 if (&node.context.root != node) {
545 std.heap.c_allocator.destroy(node);
546 }
547}
548
549// ABI warning
550export fn stage2_progress_complete_one(node: *std.Progress.Node) void {
551 node.completeOne();
552}
553
554// ABI warning
555export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void {
556 node.completed_items = done_count;
557 node.estimated_total_items = total_count;
558 node.activate();
559 node.context.maybeRefresh();
560}
561
562fn detectNativeCpuWithLLVM(
563 arch: Target.Cpu.Arch,
564 llvm_cpu_name_z: ?[*:0]const u8,
565 llvm_cpu_features_opt: ?[*:0]const u8,
566) !Target.Cpu {
567 var result = Target.Cpu.baseline(arch);
568
569 if (llvm_cpu_name_z) |cpu_name_z| {
570 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
571
572 for (arch.allCpuModels()) |model| {
573 const this_llvm_name = model.llvm_name orelse continue;
574 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
575 // Here we use the non-dependencies-populated set,
576 // so that subtracting features later in this function
577 // affect the prepopulated set.
578 result = Target.Cpu{
579 .arch = arch,
580 .model = model,
581 .features = model.features,
582 };
583 break;
584 }
585 }
586 }
587
588 const all_features = arch.allFeaturesList();
589
590 if (llvm_cpu_features_opt) |llvm_cpu_features| {
591 var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
592 while (it.next()) |decorated_llvm_feat| {
593 var op: enum {
594 add,
595 sub,
596 } = undefined;
597 var llvm_feat: []const u8 = undefined;
598 if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
599 op = .add;
600 llvm_feat = decorated_llvm_feat[1..];
601 } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
602 op = .sub;
603 llvm_feat = decorated_llvm_feat[1..];
604 } else {
605 return error.InvalidLlvmCpuFeaturesFormat;
606 }
607 for (all_features) |feature, index_usize| {
608 const this_llvm_name = feature.llvm_name orelse continue;
609 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
610 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
611 switch (op) {
612 .add => result.features.addFeature(index),
613 .sub => result.features.removeFeature(index),
614 }
615 break;
616 }
617 }
618 }
619 }
620
621 result.features.populateDependencies(all_features);
622 return result;
623}
624
625// ABI warning
626export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int {
627 cmdTargets(zig_triple) catch |err| {
628 std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
629 return -1;
630 };
631 return 0;
632}
633
634fn cmdTargets(zig_triple: [*:0]const u8) !void {
635 var target = try Target.parse(.{ .arch_os_abi = mem.toSliceConst(u8, zig_triple) });
636 target.Cross.cpu = blk: {
637 const llvm = @import("llvm.zig");
638 const llvm_cpu_name = llvm.GetHostCPUName();
639 const llvm_cpu_features = llvm.GetNativeFeatures();
640 break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features);
641 };
642 return @import("print_targets.zig").cmdTargets(
643 std.heap.c_allocator,
644 &[0][]u8{},
645 &std.io.getStdOut().outStream().stream,
646 target,
647 );
648}
649
650// ABI warning
651export fn stage2_target_parse(
652 target: *Stage2Target,
653 zig_triple: ?[*:0]const u8,
654 mcpu: ?[*:0]const u8,
655) Error {
656 stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) {
657 error.OutOfMemory => return .OutOfMemory,
658 error.UnknownArchitecture => return .UnknownArchitecture,
659 error.UnknownOperatingSystem => return .UnknownOperatingSystem,
660 error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
661 error.MissingOperatingSystem => return .MissingOperatingSystem,
662 error.MissingArchitecture => return .MissingArchitecture,
663 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
664 error.UnexpectedExtraField => return .SemanticAnalyzeFail,
665 };
666 return .None;
667}
668
669fn stage2TargetParse(
670 stage1_target: *Stage2Target,
671 zig_triple_oz: ?[*:0]const u8,
672 mcpu_oz: ?[*:0]const u8,
673) !void {
674 const target: Target = if (zig_triple_oz) |zig_triple_z| blk: {
675 const zig_triple = mem.toSliceConst(u8, zig_triple_z);
676 const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline";
677 var diags: std.Target.ParseOptions.Diagnostics = .{};
678 break :blk Target.parse(.{
679 .arch_os_abi = zig_triple,
680 .cpu_features = mcpu,
681 .diagnostics = &diags,
682 }) catch |err| switch (err) {
683 error.UnknownCpu => {
684 std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
685 diags.cpu_name.?,
686 @tagName(diags.arch.?),
687 });
688 for (diags.arch.?.allCpuModels()) |cpu| {
689 std.debug.warn(" {}\n", .{cpu.name});
690 }
691 process.exit(1);
692 },
693 error.UnknownCpuFeature => {
694 std.debug.warn(
695 \\Unknown CPU feature: '{}'
696 \\Available CPU features for architecture '{}':
697 \\
698 , .{
699 diags.unknown_feature_name,
700 @tagName(diags.arch.?),
701 });
702 for (diags.arch.?.allFeaturesList()) |feature| {
703 std.debug.warn(" {}: {}\n", .{ feature.name, feature.description });
704 }
705 process.exit(1);
706 },
707 else => |e| return e,
708 };
709 } else Target.Native;
710
711 try stage1_target.fromTarget(target);
712}
713
714fn initStage1TargetCpuFeatures(stage1_target: *Stage2Target, cpu: Target.Cpu) !void {
715 const allocator = std.heap.c_allocator;
716 const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{
717 cpu.model.name,
718 cpu.features.asBytes(),
719 });
720 errdefer allocator.free(cache_hash);
721
722 const generic_arch_name = cpu.arch.genericName();
723 var builtin_str_buffer = try std.Buffer.allocPrint(allocator,
724 \\Cpu{{
725 \\ .arch = .{},
726 \\ .model = &Target.{}.cpu.{},
727 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
728 \\
729 , .{
730 @tagName(cpu.arch),
731 generic_arch_name,
732 cpu.model.name,
733 generic_arch_name,
734 generic_arch_name,
735 });
736 defer builtin_str_buffer.deinit();
737
738 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
739 defer llvm_features_buffer.deinit();
740
741 for (cpu.arch.allFeaturesList()) |feature, index_usize| {
742 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
743 const is_enabled = cpu.features.isEnabled(index);
744
745 if (feature.llvm_name) |llvm_name| {
746 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
747 try llvm_features_buffer.appendByte(plus_or_minus);
748 try llvm_features_buffer.append(llvm_name);
749 try llvm_features_buffer.append(",");
750 }
751
752 if (is_enabled) {
753 // TODO some kind of "zig identifier escape" function rather than
754 // unconditionally using @"" syntax
755 try builtin_str_buffer.append(" .@\"");
756 try builtin_str_buffer.append(feature.name);
757 try builtin_str_buffer.append("\",\n");
758 }
759 }
760
761 try builtin_str_buffer.append(
762 \\ }),
763 \\};
764 \\
765 );
766
767 assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
768 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
769
770 stage1_target.llvm_cpu_name = if (cpu.model.llvm_name) |s| s.ptr else null;
771 stage1_target.llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr;
772 stage1_target.builtin_str = builtin_str_buffer.toOwnedSlice().ptr;
773 stage1_target.cache_hash = cache_hash.ptr;
774}
775
776// ABI warning
777const Stage2LibCInstallation = extern struct {
778 include_dir: [*:0]const u8,
779 include_dir_len: usize,
780 sys_include_dir: [*:0]const u8,
781 sys_include_dir_len: usize,
782 crt_dir: [*:0]const u8,
783 crt_dir_len: usize,
784 static_crt_dir: [*:0]const u8,
785 static_crt_dir_len: usize,
786 msvc_lib_dir: [*:0]const u8,
787 msvc_lib_dir_len: usize,
788 kernel32_lib_dir: [*:0]const u8,
789 kernel32_lib_dir_len: usize,
790
791 fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
792 if (libc.include_dir) |s| {
793 self.include_dir = s.ptr;
794 self.include_dir_len = s.len;
795 } else {
796 self.include_dir = "";
797 self.include_dir_len = 0;
798 }
799 if (libc.sys_include_dir) |s| {
800 self.sys_include_dir = s.ptr;
801 self.sys_include_dir_len = s.len;
802 } else {
803 self.sys_include_dir = "";
804 self.sys_include_dir_len = 0;
805 }
806 if (libc.crt_dir) |s| {
807 self.crt_dir = s.ptr;
808 self.crt_dir_len = s.len;
809 } else {
810 self.crt_dir = "";
811 self.crt_dir_len = 0;
812 }
813 if (libc.static_crt_dir) |s| {
814 self.static_crt_dir = s.ptr;
815 self.static_crt_dir_len = s.len;
816 } else {
817 self.static_crt_dir = "";
818 self.static_crt_dir_len = 0;
819 }
820 if (libc.msvc_lib_dir) |s| {
821 self.msvc_lib_dir = s.ptr;
822 self.msvc_lib_dir_len = s.len;
823 } else {
824 self.msvc_lib_dir = "";
825 self.msvc_lib_dir_len = 0;
826 }
827 if (libc.kernel32_lib_dir) |s| {
828 self.kernel32_lib_dir = s.ptr;
829 self.kernel32_lib_dir_len = s.len;
830 } else {
831 self.kernel32_lib_dir = "";
832 self.kernel32_lib_dir_len = 0;
833 }
834 }
835
836 fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
837 var libc: LibCInstallation = .{};
838 if (self.include_dir_len != 0) {
839 libc.include_dir = self.include_dir[0..self.include_dir_len :0];
840 }
841 if (self.sys_include_dir_len != 0) {
842 libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
843 }
844 if (self.crt_dir_len != 0) {
845 libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
846 }
847 if (self.static_crt_dir_len != 0) {
848 libc.static_crt_dir = self.static_crt_dir[0..self.static_crt_dir_len :0];
849 }
850 if (self.msvc_lib_dir_len != 0) {
851 libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
852 }
853 if (self.kernel32_lib_dir_len != 0) {
854 libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
855 }
856 return libc;
857 }
858};
859
860// ABI warning
861export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {
862 stderr_file = std.io.getStdErr();
863 stderr = &stderr_file.outStream().stream;
864 const libc_file = mem.toSliceConst(u8, libc_file_z);
865 var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) {
866 error.ParseError => return .SemanticAnalyzeFail,
867 error.DiskQuota => return .DiskQuota,
868 error.FileTooBig => return .FileTooBig,
869 error.InputOutput => return .FileSystem,
870 error.NoSpaceLeft => return .NoSpaceLeft,
871 error.AccessDenied => return .AccessDenied,
872 error.BrokenPipe => return .BrokenPipe,
873 error.SystemResources => return .SystemResources,
874 error.OperationAborted => return .OperationAborted,
875 error.WouldBlock => unreachable,
876 error.Unexpected => return .Unexpected,
877 error.EndOfStream => return .EndOfFile,
878 error.IsDir => return .IsDir,
879 error.ConnectionResetByPeer => unreachable,
880 error.OutOfMemory => return .OutOfMemory,
881 error.Unseekable => unreachable,
882 error.SharingViolation => return .SharingViolation,
883 error.PathAlreadyExists => unreachable,
884 error.FileNotFound => return .FileNotFound,
885 error.PipeBusy => return .PipeBusy,
886 error.NameTooLong => return .PathTooLong,
887 error.InvalidUtf8 => return .BadPathName,
888 error.BadPathName => return .BadPathName,
889 error.SymLinkLoop => return .SymLinkLoop,
890 error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded,
891 error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded,
892 error.NoDevice => return .NoDevice,
893 error.NotDir => return .NotDir,
894 error.DeviceBusy => return .DeviceBusy,
895 };
896 stage1_libc.initFromStage2(libc);
897 return .None;
898}
899
900// ABI warning
901export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error {
902 var libc = LibCInstallation.findNative(.{
903 .allocator = std.heap.c_allocator,
904 .verbose = true,
905 }) catch |err| switch (err) {
906 error.OutOfMemory => return .OutOfMemory,
907 error.FileSystem => return .FileSystem,
908 error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler,
909 error.CCompilerExitCode => return .CCompilerExitCode,
910 error.CCompilerCrashed => return .CCompilerCrashed,
911 error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders,
912 error.LibCRuntimeNotFound => return .LibCRuntimeNotFound,
913 error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound,
914 error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound,
915 error.UnsupportedArchitecture => return .UnsupportedArchitecture,
916 error.WindowsSdkNotFound => return .WindowsSdkNotFound,
917 };
918 stage1_libc.initFromStage2(libc);
919 return .None;
920}
921
922// ABI warning
923export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error {
924 var libc = stage1_libc.toStage2();
925 const c_out_stream = &std.io.COutStream.init(output_file).stream;
926 libc.render(c_out_stream) catch |err| switch (err) {
927 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
928 error.SystemResources => return .SystemResources,
929 error.OperationAborted => return .OperationAborted,
930 error.BrokenPipe => return .BrokenPipe,
931 error.DiskQuota => return .DiskQuota,
932 error.FileTooBig => return .FileTooBig,
933 error.NoSpaceLeft => return .NoSpaceLeft,
934 error.AccessDenied => return .AccessDenied,
935 error.Unexpected => return .Unexpected,
936 error.InputOutput => return .FileSystem,
937 };
938 return .None;
939}
940
941// ABI warning
942const Stage2Target = extern struct {
943 arch: c_int,
944 vendor: c_int,
945
946 abi: c_int,
947 os: c_int,
948
949 is_native: bool,
950
951 glibc_version: ?*Stage2GLibCVersion, // null means default
952
953 llvm_cpu_name: ?[*:0]const u8,
954 llvm_cpu_features: ?[*:0]const u8,
955 builtin_str: ?[*:0]const u8,
956 cache_hash: ?[*:0]const u8,
957
958 fn toTarget(in_target: Stage2Target) Target {
959 if (in_target.is_native) return .Native;
960
961 const in_arch = in_target.arch - 1; // skip over ZigLLVM_UnknownArch
962 const in_os = in_target.os;
963 const in_abi = in_target.abi;
964
965 return .{
966 .Cross = .{
967 .cpu = Target.Cpu.baseline(enumInt(Target.Cpu.Arch, in_arch)),
968 .os = enumInt(Target.Os, in_os),
969 .abi = enumInt(Target.Abi, in_abi),
970 },
971 };
972 }
973
974 fn fromTarget(self: *Stage2Target, target: Target) !void {
975 const cpu = switch (target) {
976 .Native => blk: {
977 // TODO self-host CPU model and feature detection instead of relying on LLVM
978 const llvm = @import("llvm.zig");
979 const llvm_cpu_name = llvm.GetHostCPUName();
980 const llvm_cpu_features = llvm.GetNativeFeatures();
981 break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features);
982 },
983 .Cross => target.getCpu(),
984 };
985 self.* = .{
986 .arch = @enumToInt(target.getArch()) + 1, // skip over ZigLLVM_UnknownArch
987 .vendor = 0,
988 .os = @enumToInt(target.getOs()),
989 .abi = @enumToInt(target.getAbi()),
990 .llvm_cpu_name = null,
991 .llvm_cpu_features = null,
992 .builtin_str = null,
993 .cache_hash = null,
994 .is_native = target == .Native,
995 .glibc_version = null,
996 };
997 try initStage1TargetCpuFeatures(self, cpu);
998 }
999};
1000
1001// ABI warning
1002const Stage2GLibCVersion = extern struct {
1003 major: u32,
1004 minor: u32,
1005 patch: u32,
1006};
1007
1008// ABI warning
1009export fn stage2_detect_dynamic_linker(in_target: *const Stage2Target, out_ptr: *[*:0]u8, out_len: *usize) Error {
1010 const target = in_target.toTarget();
1011 const result = @import("introspect.zig").detectDynamicLinker(
1012 std.heap.c_allocator,
1013 target,
1014 ) catch |err| switch (err) {
1015 error.OutOfMemory => return .OutOfMemory,
1016 error.UnknownDynamicLinkerPath => return .UnknownDynamicLinkerPath,
1017 error.TargetHasNoDynamicLinker => return .TargetHasNoDynamicLinker,
1018 };
1019 out_ptr.* = result.ptr;
1020 out_len.* = result.len;
1021 return .None;
1022}
1023
1024fn enumInt(comptime Enum: type, int: c_int) Enum {
1025 return @intToEnum(Enum, @intCast(@TagType(Enum), int));
1026}
1027
1028// ABI warning
1029const Stage2NativePaths = extern struct {
1030 include_dirs_ptr: [*][*:0]u8,
1031 include_dirs_len: usize,
1032 lib_dirs_ptr: [*][*:0]u8,
1033 lib_dirs_len: usize,
1034 rpaths_ptr: [*][*:0]u8,
1035 rpaths_len: usize,
1036 warnings_ptr: [*][*:0]u8,
1037 warnings_len: usize,
1038};
1039// ABI warning
1040export fn stage2_detect_native_paths(stage1_paths: *Stage2NativePaths) Error {
1041 stage2DetectNativePaths(stage1_paths) catch |err| switch (err) {
1042 error.OutOfMemory => return .OutOfMemory,
1043 };
1044 return .None;
1045}
1046
1047fn stage2DetectNativePaths(stage1_paths: *Stage2NativePaths) !void {
1048 var paths = try std.zig.system.NativePaths.detect(std.heap.c_allocator);
1049 errdefer paths.deinit();
1050
1051 try convertSlice(paths.include_dirs.toSlice(), &stage1_paths.include_dirs_ptr, &stage1_paths.include_dirs_len);
1052 try convertSlice(paths.lib_dirs.toSlice(), &stage1_paths.lib_dirs_ptr, &stage1_paths.lib_dirs_len);
1053 try convertSlice(paths.rpaths.toSlice(), &stage1_paths.rpaths_ptr, &stage1_paths.rpaths_len);
1054 try convertSlice(paths.warnings.toSlice(), &stage1_paths.warnings_ptr, &stage1_paths.warnings_len);
1055}
1056
1057fn convertSlice(slice: [][:0]u8, ptr: *[*][*:0]u8, len: *usize) !void {
1058 len.* = slice.len;
1059 const new_slice = try std.heap.c_allocator.alloc([*:0]u8, slice.len);
1060 for (slice) |item, i| {
1061 new_slice[i] = item.ptr;
1062 }
1063 ptr.* = new_slice.ptr;
1064}
src-self-hosted/translate_c.zig+5-5
......@@ -264,7 +264,7 @@ pub fn translate(
264264 &errors.len,
265265 resources_path,
266266 ) orelse {
267 if (errors.len == 0) return error.OutOfMemory;
267 if (errors.len == 0) return error.ASTUnitFailure;
268268 return error.SemanticAnalyzeFail;
269269 };
270270 defer ZigClangASTUnit_delete(ast_unit);
......@@ -5382,15 +5382,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
53825382 return error.ParseError;
53835383 }
53845384
5385 //if (@typeId(@TypeOf(x)) == .Pointer)
5385 //if (@typeInfo(@TypeOf(x)) == .Pointer)
53865386 // @ptrCast(dest, x)
5387 //else if (@typeId(@TypeOf(x)) == .Integer)
5387 //else if (@typeInfo(@TypeOf(x)) == .Integer)
53885388 // @intToPtr(dest, x)
53895389 //else
53905390 // @as(dest, x)
53915391
53925392 const if_1 = try transCreateNodeIf(c);
5393 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeId");
5393 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
53945394 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
53955395 try type_id_1.params.push(&type_of_1.base);
53965396 try type_of_1.params.push(node_to_cast);
......@@ -5417,7 +5417,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
54175417 if_1.@"else" = else_1;
54185418
54195419 const if_2 = try transCreateNodeIf(c);
5420 const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeId");
5420 const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
54215421 const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
54225422 try type_id_2.params.push(&type_of_2.base);
54235423 try type_of_2.params.push(node_to_cast);
src-self-hosted/type.zig+1-1
......@@ -1042,7 +1042,7 @@ fn hashAny(x: var, comptime seed: u64) u32 {
10421042 switch (@typeInfo(@TypeOf(x))) {
10431043 .Int => |info| {
10441044 comptime var rng = comptime std.rand.DefaultPrng.init(seed);
1045 const unsigned_x = @bitCast(@IntType(false, info.bits), x);
1045 const unsigned_x = @bitCast(std.meta.IntType(false, info.bits), x);
10461046 if (info.bits <= 32) {
10471047 return @as(u32, unsigned_x) *% comptime rng.random.scalar(u32);
10481048 } else {
src-self-hosted/util.zig-138
......@@ -2,144 +2,6 @@ const std = @import("std");
22const Target = std.Target;
33const llvm = @import("llvm.zig");
44
5pub const FloatAbi = enum {
6 Hard,
7 Soft,
8 SoftFp,
9};
10
11/// TODO expose the arch and subarch separately
12pub fn isArmOrThumb(self: Target) bool {
13 return switch (self.getArch()) {
14 .arm,
15 .armeb,
16 .aarch64,
17 .aarch64_be,
18 .thumb,
19 .thumbeb,
20 => true,
21 else => false,
22 };
23}
24
25pub fn getFloatAbi(self: Target) FloatAbi {
26 return switch (self.getAbi()) {
27 .gnueabihf,
28 .eabihf,
29 .musleabihf,
30 => .Hard,
31 else => .Soft,
32 };
33}
34
35pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
36 const env = self.getAbi();
37 const arch = self.getArch();
38 const os = self.getOs();
39 switch (os) {
40 .freebsd => {
41 return "/libexec/ld-elf.so.1";
42 },
43 .linux => {
44 switch (env) {
45 .android => {
46 if (self.getArchPtrBitWidth() == 64) {
47 return "/system/bin/linker64";
48 } else {
49 return "/system/bin/linker";
50 }
51 },
52 .gnux32 => {
53 if (arch == .x86_64) {
54 return "/libx32/ld-linux-x32.so.2";
55 }
56 },
57 .musl,
58 .musleabi,
59 .musleabihf,
60 => {
61 if (arch == .x86_64) {
62 return "/lib/ld-musl-x86_64.so.1";
63 }
64 },
65 else => {},
66 }
67 switch (arch) {
68 .i386,
69 .sparc,
70 .sparcel,
71 => return "/lib/ld-linux.so.2",
72
73 .aarch64 => return "/lib/ld-linux-aarch64.so.1",
74
75 .aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
76
77 .arm,
78 .thumb,
79 => return switch (getFloatAbi(self)) {
80 .Hard => return "/lib/ld-linux-armhf.so.3",
81 else => return "/lib/ld-linux.so.3",
82 },
83
84 .armeb,
85 .thumbeb,
86 => return switch (getFloatAbi(self)) {
87 .Hard => return "/lib/ld-linux-armhf.so.3",
88 else => return "/lib/ld-linux.so.3",
89 },
90
91 .mips,
92 .mipsel,
93 .mips64,
94 .mips64el,
95 => return null,
96
97 .powerpc => return "/lib/ld.so.1",
98 .powerpc64 => return "/lib64/ld64.so.2",
99 .powerpc64le => return "/lib64/ld64.so.2",
100 .s390x => return "/lib64/ld64.so.1",
101 .sparcv9 => return "/lib64/ld-linux.so.2",
102 .x86_64 => return "/lib64/ld-linux-x86-64.so.2",
103
104 .arc,
105 .avr,
106 .bpfel,
107 .bpfeb,
108 .hexagon,
109 .msp430,
110 .r600,
111 .amdgcn,
112 .riscv32,
113 .riscv64,
114 .tce,
115 .tcele,
116 .xcore,
117 .nvptx,
118 .nvptx64,
119 .le32,
120 .le64,
121 .amdil,
122 .amdil64,
123 .hsail,
124 .hsail64,
125 .spir,
126 .spir64,
127 .kalimba,
128 .shave,
129 .lanai,
130 .wasm32,
131 .wasm64,
132 .renderscript32,
133 .renderscript64,
134 .aarch64_32,
135 .ve,
136 => return null,
137 }
138 },
139 else => return null,
140 }
141}
142
1435pub fn getDarwinArchString(self: Target) [:0]const u8 {
1446 const arch = self.getArch();
1457 switch (arch) {
src-self-hosted/windows_sdk.zig created+22
......@@ -0,0 +1,22 @@
1// C API bindings for src/windows_sdk.h
2
3pub const ZigWindowsSDK = extern struct {
4 path10_ptr: ?[*]const u8,
5 path10_len: usize,
6 version10_ptr: ?[*]const u8,
7 version10_len: usize,
8 path81_ptr: ?[*]const u8,
9 path81_len: usize,
10 version81_ptr: ?[*]const u8,
11 version81_len: usize,
12 msvc_lib_dir_ptr: ?[*]const u8,
13 msvc_lib_dir_len: usize,
14};
15pub const ZigFindWindowsSdkError = extern enum {
16 None,
17 OutOfMemory,
18 NotFound,
19 PathTooLong,
20};
21pub extern fn zig_find_windows_sdk(out_sdk: **ZigWindowsSDK) ZigFindWindowsSdkError;
22pub extern fn zig_free_windows_sdk(sdk: *ZigWindowsSDK) void;
src/all_types.hpp+21-84
......@@ -18,7 +18,6 @@
1818#include "bigfloat.hpp"
1919#include "target.hpp"
2020#include "tokenizer.hpp"
21#include "libc_installation.hpp"
2221
2322struct AstNode;
2423struct ZigFn;
......@@ -370,12 +369,22 @@ enum LazyValueId {
370369 LazyValueIdFnType,
371370 LazyValueIdErrUnionType,
372371 LazyValueIdArrayType,
372 LazyValueIdTypeInfoDecls,
373373};
374374
375375struct LazyValue {
376376 LazyValueId id;
377377};
378378
379struct LazyValueTypeInfoDecls {
380 LazyValue base;
381
382 IrAnalyze *ira;
383
384 ScopeDecls *decls_scope;
385 IrInst *source_instr;
386};
387
379388struct LazyValueAlignOf {
380389 LazyValue base;
381390
......@@ -1139,6 +1148,7 @@ struct AstNodeErrorType {
11391148};
11401149
11411150struct AstNodeAwaitExpr {
1151 Token *noasync_token;
11421152 AstNode *expr;
11431153};
11441154
......@@ -1685,9 +1695,6 @@ enum BuiltinFnId {
16851695 BuiltinFnIdMemset,
16861696 BuiltinFnIdSizeof,
16871697 BuiltinFnIdAlignOf,
1688 BuiltinFnIdMemberCount,
1689 BuiltinFnIdMemberType,
1690 BuiltinFnIdMemberName,
16911698 BuiltinFnIdField,
16921699 BuiltinFnIdTypeInfo,
16931700 BuiltinFnIdType,
......@@ -1740,8 +1747,6 @@ enum BuiltinFnId {
17401747 BuiltinFnIdIntCast,
17411748 BuiltinFnIdFloatCast,
17421749 BuiltinFnIdErrSetCast,
1743 BuiltinFnIdToBytes,
1744 BuiltinFnIdFromBytes,
17451750 BuiltinFnIdIntToFloat,
17461751 BuiltinFnIdFloatToInt,
17471752 BuiltinFnIdBoolToInt,
......@@ -1749,7 +1754,6 @@ enum BuiltinFnId {
17491754 BuiltinFnIdIntToErr,
17501755 BuiltinFnIdEnumToInt,
17511756 BuiltinFnIdIntToEnum,
1752 BuiltinFnIdIntType,
17531757 BuiltinFnIdVectorType,
17541758 BuiltinFnIdShuffle,
17551759 BuiltinFnIdSplat,
......@@ -1768,7 +1772,6 @@ enum BuiltinFnId {
17681772 BuiltinFnIdByteOffsetOf,
17691773 BuiltinFnIdBitOffsetOf,
17701774 BuiltinFnIdAsyncCall,
1771 BuiltinFnIdTypeId,
17721775 BuiltinFnIdShlExact,
17731776 BuiltinFnIdShrExact,
17741777 BuiltinFnIdSetEvalBranchQuota,
......@@ -1776,7 +1779,6 @@ enum BuiltinFnId {
17761779 BuiltinFnIdOpaqueType,
17771780 BuiltinFnIdThis,
17781781 BuiltinFnIdSetAlignStack,
1779 BuiltinFnIdArgType,
17801782 BuiltinFnIdExport,
17811783 BuiltinFnIdErrorReturnTrace,
17821784 BuiltinFnIdAtomicRmw,
......@@ -1810,7 +1812,6 @@ enum PanicMsgId {
18101812 PanicMsgIdDivisionByZero,
18111813 PanicMsgIdRemainderDivisionByZero,
18121814 PanicMsgIdExactDivisionRemainder,
1813 PanicMsgIdSliceWidenRemainder,
18141815 PanicMsgIdUnwrapOptionalFail,
18151816 PanicMsgIdInvalidErrorCode,
18161817 PanicMsgIdIncorrectAlignment,
......@@ -1955,12 +1956,6 @@ enum CodeModel {
19551956 CodeModelLarge,
19561957};
19571958
1958enum EmitFileType {
1959 EmitFileTypeBinary,
1960 EmitFileTypeAssembly,
1961 EmitFileTypeLLVMIr,
1962};
1963
19641959struct LinkLib {
19651960 Buf *name;
19661961 Buf *path;
......@@ -2131,13 +2126,15 @@ struct CodeGen {
21312126
21322127 Buf llvm_triple_str;
21332128 Buf global_asm;
2134 Buf output_file_path;
21352129 Buf o_file_output_path;
2130 Buf bin_file_output_path;
2131 Buf asm_file_output_path;
2132 Buf llvm_ir_file_output_path;
21362133 Buf *cache_dir;
21372134 // As an input parameter, mutually exclusive with enable_cache. But it gets
21382135 // populated in codegen_build_and_link.
21392136 Buf *output_dir;
2140 Buf **libc_include_dir_list;
2137 const char **libc_include_dir_list;
21412138 size_t libc_include_dir_len;
21422139
21432140 Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir.
......@@ -2218,14 +2215,13 @@ struct CodeGen {
22182215 ZigList<const char *> lib_dirs;
22192216 ZigList<const char *> framework_dirs;
22202217
2221 ZigLibCInstallation *libc;
2218 Stage2LibCInstallation *libc;
22222219
22232220 size_t version_major;
22242221 size_t version_minor;
22252222 size_t version_patch;
22262223 const char *linker_script;
22272224
2228 EmitFileType emit_file_type;
22292225 BuildMode build_mode;
22302226 OutType out_type;
22312227 const ZigTarget *zig_target;
......@@ -2247,7 +2243,9 @@ struct CodeGen {
22472243 bool function_sections;
22482244 bool enable_dump_analysis;
22492245 bool enable_doc_generation;
2250 bool disable_bin_generation;
2246 bool emit_bin;
2247 bool emit_asm;
2248 bool emit_llvm_ir;
22512249 bool test_is_evented;
22522250 CodeModel code_model;
22532251
......@@ -2625,7 +2623,6 @@ enum IrInstSrcId {
26252623 IrInstSrcIdIntToFloat,
26262624 IrInstSrcIdFloatToInt,
26272625 IrInstSrcIdBoolToInt,
2628 IrInstSrcIdIntType,
26292626 IrInstSrcIdVectorType,
26302627 IrInstSrcIdShuffleVector,
26312628 IrInstSrcIdSplat,
......@@ -2633,9 +2630,6 @@ enum IrInstSrcId {
26332630 IrInstSrcIdMemset,
26342631 IrInstSrcIdMemcpy,
26352632 IrInstSrcIdSlice,
2636 IrInstSrcIdMemberCount,
2637 IrInstSrcIdMemberType,
2638 IrInstSrcIdMemberName,
26392633 IrInstSrcIdBreakpoint,
26402634 IrInstSrcIdReturnAddress,
26412635 IrInstSrcIdFrameAddress,
......@@ -2672,7 +2666,6 @@ enum IrInstSrcId {
26722666 IrInstSrcIdTypeInfo,
26732667 IrInstSrcIdType,
26742668 IrInstSrcIdHasField,
2675 IrInstSrcIdTypeId,
26762669 IrInstSrcIdSetEvalBranchQuota,
26772670 IrInstSrcIdPtrType,
26782671 IrInstSrcIdAlignCast,
......@@ -2691,8 +2684,6 @@ enum IrInstSrcId {
26912684 IrInstSrcIdSaveErrRetAddr,
26922685 IrInstSrcIdAddImplicitReturnType,
26932686 IrInstSrcIdErrSetCast,
2694 IrInstSrcIdToBytes,
2695 IrInstSrcIdFromBytes,
26962687 IrInstSrcIdCheckRuntimeScope,
26972688 IrInstSrcIdHasDecl,
26982689 IrInstSrcIdUndeclaredIdent,
......@@ -2731,7 +2722,6 @@ enum IrInstGenId {
27312722 IrInstGenIdCall,
27322723 IrInstGenIdReturn,
27332724 IrInstGenIdCast,
2734 IrInstGenIdResizeSlice,
27352725 IrInstGenIdUnreachable,
27362726 IrInstGenIdAsm,
27372727 IrInstGenIdTestNonNull,
......@@ -3263,13 +3253,6 @@ struct IrInstGenCast {
32633253 CastOp cast_op;
32643254};
32653255
3266struct IrInstGenResizeSlice {
3267 IrInstGen base;
3268
3269 IrInstGen *operand;
3270 IrInstGen *result_loc;
3271};
3272
32733256struct IrInstSrcContainerInitList {
32743257 IrInstSrc base;
32753258
......@@ -3621,21 +3604,6 @@ struct IrInstSrcErrSetCast {
36213604 IrInstSrc *target;
36223605};
36233606
3624struct IrInstSrcToBytes {
3625 IrInstSrc base;
3626
3627 IrInstSrc *target;
3628 ResultLoc *result_loc;
3629};
3630
3631struct IrInstSrcFromBytes {
3632 IrInstSrc base;
3633
3634 IrInstSrc *dest_child_type;
3635 IrInstSrc *target;
3636 ResultLoc *result_loc;
3637};
3638
36393607struct IrInstSrcIntToFloat {
36403608 IrInstSrc base;
36413609
......@@ -3656,13 +3624,6 @@ struct IrInstSrcBoolToInt {
36563624 IrInstSrc *target;
36573625};
36583626
3659struct IrInstSrcIntType {
3660 IrInstSrc base;
3661
3662 IrInstSrc *is_signed;
3663 IrInstSrc *bit_count;
3664};
3665
36663627struct IrInstSrcVectorType {
36673628 IrInstSrc base;
36683629
......@@ -3735,26 +3696,6 @@ struct IrInstGenSlice {
37353696 bool safety_check_on;
37363697};
37373698
3738struct IrInstSrcMemberCount {
3739 IrInstSrc base;
3740
3741 IrInstSrc *container;
3742};
3743
3744struct IrInstSrcMemberType {
3745 IrInstSrc base;
3746
3747 IrInstSrc *container_type;
3748 IrInstSrc *member_index;
3749};
3750
3751struct IrInstSrcMemberName {
3752 IrInstSrc base;
3753
3754 IrInstSrc *container_type;
3755 IrInstSrc *member_index;
3756};
3757
37583699struct IrInstSrcBreakpoint {
37593700 IrInstSrc base;
37603701};
......@@ -4162,12 +4103,6 @@ struct IrInstSrcHasField {
41624103 IrInstSrc *field_name;
41634104};
41644105
4165struct IrInstSrcTypeId {
4166 IrInstSrc base;
4167
4168 IrInstSrc *type_value;
4169};
4170
41714106struct IrInstSrcSetEvalBranchQuota {
41724107 IrInstSrc base;
41734108
......@@ -4499,6 +4434,7 @@ struct IrInstSrcAwait {
44994434
45004435 IrInstSrc *frame;
45014436 ResultLoc *result_loc;
4437 bool is_noasync;
45024438};
45034439
45044440struct IrInstGenAwait {
......@@ -4507,6 +4443,7 @@ struct IrInstGenAwait {
45074443 IrInstGen *frame;
45084444 IrInstGen *result_loc;
45094445 ZigFn *target_fn;
4446 bool is_noasync;
45104447};
45114448
45124449struct IrInstSrcResume {
src/analyze.cpp+10-4
......@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
11501150 case LazyValueIdInvalid:
11511151 case LazyValueIdAlignOf:
11521152 case LazyValueIdSizeOf:
1153 case LazyValueIdTypeInfoDecls:
11531154 zig_unreachable();
11541155 case LazyValueIdPtrType: {
11551156 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
......@@ -1209,6 +1210,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o
12091210 case LazyValueIdInvalid:
12101211 case LazyValueIdAlignOf:
12111212 case LazyValueIdSizeOf:
1213 case LazyValueIdTypeInfoDecls:
12121214 zig_unreachable();
12131215 case LazyValueIdSliceType:
12141216 case LazyValueIdPtrType:
......@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
12301232 case LazyValueIdInvalid:
12311233 case LazyValueIdAlignOf:
12321234 case LazyValueIdSizeOf:
1235 case LazyValueIdTypeInfoDecls:
12331236 zig_unreachable();
12341237 case LazyValueIdSliceType: {
12351238 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
......@@ -1303,6 +1306,7 @@ start_over:
13031306 case LazyValueIdInvalid:
13041307 case LazyValueIdAlignOf:
13051308 case LazyValueIdSizeOf:
1309 case LazyValueIdTypeInfoDecls:
13061310 zig_unreachable();
13071311 case LazyValueIdSliceType: {
13081312 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
......@@ -1370,6 +1374,7 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
13701374 case LazyValueIdInvalid:
13711375 case LazyValueIdAlignOf:
13721376 case LazyValueIdSizeOf:
1377 case LazyValueIdTypeInfoDecls:
13731378 zig_unreachable();
13741379 case LazyValueIdSliceType:
13751380 case LazyValueIdPtrType:
......@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
14121417 case LazyValueIdInvalid:
14131418 case LazyValueIdAlignOf:
14141419 case LazyValueIdSizeOf:
1420 case LazyValueIdTypeInfoDecls:
14151421 zig_unreachable();
14161422 case LazyValueIdSliceType: // it has the len field
14171423 case LazyValueIdOptType: // it has the optional bit
......@@ -4710,8 +4716,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
47104716 }
47114717 for (size_t i = 0; i < fn->await_list.length; i += 1) {
47124718 IrInstGenAwait *await = fn->await_list.at(i);
4713 // TODO If this is a noasync await, it doesn't count
4714 // https://github.com/ziglang/zig/issues/3157
4719 if (await->is_noasync) continue;
47154720 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
47164721 CallModifierNone))
47174722 {
......@@ -6315,8 +6320,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
63156320 // The funtion call result of foo() must be spilled.
63166321 for (size_t i = 0; i < fn->await_list.length; i += 1) {
63176322 IrInstGenAwait *await = fn->await_list.at(i);
6318 // TODO If this is a noasync await, it doesn't suspend
6319 // https://github.com/ziglang/zig/issues/3157
6323 if (await->is_noasync) {
6324 continue;
6325 }
63206326 if (await->base.value->special != ConstValSpecialRuntime) {
63216327 // Known at comptime. No spill, no suspend.
63226328 continue;
src/cache_hash.cpp+1-1
......@@ -5,7 +5,7 @@
55 * See http://opensource.org/licenses/MIT
66 */
77
8#include "userland.h"
8#include "stage2.h"
99#include "cache_hash.hpp"
1010#include "all_types.hpp"
1111#include "buffer.hpp"
src/codegen.cpp+161-293
......@@ -18,7 +18,7 @@
1818#include "target.hpp"
1919#include "util.hpp"
2020#include "zig_llvm.h"
21#include "userland.h"
21#include "stage2.h"
2222#include "dump_analysis.hpp"
2323#include "softfloat.hpp"
2424#include "mem_profile.hpp"
......@@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
121121 g->version_patch = patch;
122122}
123123
124void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) {
125 g->emit_file_type = emit_file_type;
126}
127
128124void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
129125 g->each_lib_rpath = each_lib_rpath;
130126}
......@@ -975,8 +971,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
975971 return buf_create_from_str("remainder division by zero or negative value");
976972 case PanicMsgIdExactDivisionRemainder:
977973 return buf_create_from_str("exact division produced remainder");
978 case PanicMsgIdSliceWidenRemainder:
979 return buf_create_from_str("slice widening size mismatch");
980974 case PanicMsgIdUnwrapOptionalFail:
981975 return buf_create_from_str("attempt to unwrap null");
982976 case PanicMsgIdUnreachable:
......@@ -3085,74 +3079,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
30853079 }
30863080}
30873081
3088static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable,
3089 IrInstGenResizeSlice *instruction)
3090{
3091 ZigType *actual_type = instruction->operand->value->type;
3092 ZigType *wanted_type = instruction->base.value->type;
3093 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3094 assert(expr_val);
3095
3096 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3097 assert(wanted_type->id == ZigTypeIdStruct);
3098 assert(wanted_type->data.structure.special == StructSpecialSlice);
3099 assert(actual_type->id == ZigTypeIdStruct);
3100 assert(actual_type->data.structure.special == StructSpecialSlice);
3101
3102 ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry;
3103 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
3104 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry;
3105 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
3106
3107
3108 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index;
3109 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index;
3110 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index;
3111 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index;
3112
3113 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
3114 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
3115 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
3116 get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), "");
3117 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
3118 (unsigned)wanted_ptr_index, "");
3119 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
3120
3121 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
3122 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
3123 uint64_t src_size = type_size(g, actual_child_type);
3124 uint64_t dest_size = type_size(g, wanted_child_type);
3125
3126 LLVMValueRef new_len;
3127 if (dest_size == 1) {
3128 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false);
3129 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
3130 } else if (src_size == 1) {
3131 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false);
3132 if (ir_want_runtime_safety(g, &instruction->base)) {
3133 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
3134 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
3135 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
3136 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
3137 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
3138 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
3139
3140 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3141 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
3142
3143 LLVMPositionBuilderAtEnd(g->builder, ok_block);
3144 }
3145 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
3146 } else {
3147 zig_unreachable();
3148 }
3149
3150 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, "");
3151 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
3152
3153 return result_loc;
3154}
3155
31563082static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
31573083 IrInstGenCast *cast_instruction)
31583084{
......@@ -5014,6 +4940,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
50144940 if (!type_has_bits(instruction->base.value->type)) {
50154941 return nullptr;
50164942 }
4943 if (instruction->operand->id == IrInstGenIdCall) {
4944 IrInstGenCall *call = reinterpret_cast<IrInstGenCall *>(instruction->operand);
4945 if (call->result_loc != nullptr) {
4946 return ir_llvm_value(g, call->result_loc);
4947 }
4948 }
50174949 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
50184950 if (handle_is_ptr(instruction->operand->value->type)) {
50194951 return value;
......@@ -6177,7 +6109,9 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
61776109 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
61786110 nullptr : ir_llvm_value(g, instruction->result_loc);
61796111
6180 if (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)) {
6112 if (instruction->is_noasync ||
6113 (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
6114 {
61816115 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
61826116 ptr_result_type, result_loc, true);
61836117 }
......@@ -6476,8 +6410,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
64766410 return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);
64776411 case IrInstGenIdAssertNonNull:
64786412 return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);
6479 case IrInstGenIdResizeSlice:
6480 return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction);
64816413 case IrInstGenIdPtrOfArrayToSlice:
64826414 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);
64836415 case IrInstGenIdSuspendBegin:
......@@ -6528,7 +6460,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
65286460 set_debug_location(g, instruction);
65296461 }
65306462 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
6531 if (instruction->spill != nullptr) {
6463 if (instruction->spill != nullptr && instruction->llvm_value != nullptr) {
65326464 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);
65336465 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);
65346466 instruction->llvm_value = nullptr;
......@@ -7912,50 +7844,44 @@ static void zig_llvm_emit_output(CodeGen *g) {
79127844
79137845 bool is_small = g->build_mode == BuildModeSmallRelease;
79147846
7915 Buf *output_path = &g->o_file_output_path;
79167847 char *err_msg = nullptr;
7917 switch (g->emit_file_type) {
7918 case EmitFileTypeBinary:
7919 if (g->disable_bin_generation)
7920 return;
7921 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
7922 ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small,
7923 g->enable_time_report))
7924 {
7925 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);
7926 }
7927 validate_inline_fns(g);
7928 g->link_objects.append(output_path);
7929 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||
7930 (g->out_type == OutTypeLib && !g->is_dynamic)))
7931 {
7932 zig_link_add_compiler_rt(g, g->sub_progress_node);
7933 }
7934 break;
7848 const char *asm_filename = nullptr;
7849 const char *bin_filename = nullptr;
7850 const char *llvm_ir_filename = nullptr;
7851
7852 if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path);
7853 if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path);
7854 if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
7855
7856 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
7857 // pipeline multiple times if this is requested.
7858 if (asm_filename != nullptr && bin_filename != nullptr) {
7859 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7860 is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename))
7861 {
7862 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7863 exit(1);
7864 }
7865 bin_filename = nullptr;
7866 llvm_ir_filename = nullptr;
7867 }
79357868
7936 case EmitFileTypeAssembly:
7937 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
7938 ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small,
7939 g->enable_time_report))
7940 {
7941 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);
7942 }
7943 validate_inline_fns(g);
7944 break;
7869 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7870 is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename))
7871 {
7872 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7873 exit(1);
7874 }
79457875
7946 case EmitFileTypeLLVMIr:
7947 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
7948 ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small,
7949 g->enable_time_report))
7950 {
7951 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);
7952 }
7953 validate_inline_fns(g);
7954 break;
7876 validate_inline_fns(g);
79557877
7956 default:
7957 zig_unreachable();
7878 if (g->emit_bin) {
7879 g->link_objects.append(&g->o_file_output_path);
7880 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) {
7881 zig_link_add_compiler_rt(g, g->sub_progress_node);
7882 }
79587883 }
7884
79597885 LLVMDisposeModule(g->module);
79607886 g->module = nullptr;
79617887 LLVMDisposeTargetData(g->target_data_ref);
......@@ -8221,9 +8147,6 @@ static void define_builtin_fns(CodeGen *g) {
82218147 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
82228148 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
82238149 create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1);
8224 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
8225 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
8226 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
82278150 create_builtin_fn(g, BuiltinFnIdField, "field", 2);
82288151 create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1);
82298152 create_builtin_fn(g, BuiltinFnIdType, "Type", 1);
......@@ -8261,7 +8184,6 @@ static void define_builtin_fns(CodeGen *g) {
82618184 create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2);
82628185 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
82638186 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
8264 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
82658187 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2);
82668188 create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4);
82678189 create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2);
......@@ -8299,22 +8221,18 @@ static void define_builtin_fns(CodeGen *g) {
82998221 create_builtin_fn(g, BuiltinFnIdRound, "round", 1);
83008222 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);
83018223 create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX);
8302 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
83038224 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);
83048225 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);
83058226 create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1);
83068227 create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2);
83078228 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);
83088229 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);
8309 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2);
83108230 create_builtin_fn(g, BuiltinFnIdExport, "export", 2);
83118231 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
83128232 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
83138233 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
83148234 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);
83158235 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
8316 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
8317 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
83188236 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
83198237 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2);
83208238 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3);
......@@ -8361,9 +8279,11 @@ static bool detect_dynamic_link(CodeGen *g) {
83618279 return true;
83628280 if (g->zig_target->os == OsFreestanding)
83638281 return false;
8364 if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr))
8282 if (target_os_requires_libc(g->zig_target->os))
83658283 return true;
8366 // If there are no dynamic libraries then we can disable PIC
8284 if (g->libc_link_lib != nullptr && target_is_glibc(g->zig_target))
8285 return true;
8286 // If there are no dynamic libraries then we can disable dynamic linking.
83678287 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
83688288 LinkLib *link_lib = g->link_libs_list.at(i);
83698289 if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name)))
......@@ -8498,25 +8418,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
84988418 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {
84998419 ZigLLVM_ArchType arch = target_arch_enum(arch_i);
85008420 const char *arch_name = target_arch_name(arch);
8501 SubArchList sub_arch_list = target_subarch_list(arch);
8502 if (sub_arch_list == SubArchListNone) {
8503 if (arch == g->zig_target->arch) {
8504 g->target_arch_index = arch_i;
8505 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name));
8506 }
8507 } else {
8508 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list);
8509 if (arch == g->zig_target->arch) {
8510 size_t sub_count = target_subarch_count(sub_arch_list);
8511 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
8512 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
8513 if (sub == g->zig_target->sub_arch) {
8514 g->target_sub_arch_index = sub_i;
8515 cur_arch = buf_ptr(buf_sprintf("Arch{ .%s = Arch.%s.%s }",
8516 arch_name, sub_arch_list_name, target_subarch_name(sub)));
8517 }
8518 }
8519 }
8421 if (arch == g->zig_target->arch) {
8422 g->target_arch_index = arch_i;
8423 cur_arch = arch_name;
85208424 }
85218425 }
85228426 }
......@@ -8610,22 +8514,19 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
86108514 break;
86118515 }
86128516 buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type);
8613 const char *link_type = g->is_dynamic ? "Dynamic" : "Static";
8517 const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static";
86148518 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type);
86158519 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
86168520 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
86178521 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
8618 buf_appendf(contents, "pub const arch = %s;\n", cur_arch);
8522 buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
86198523 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
86208524 {
8621 buf_append_str(contents, "pub const cpu_features: CpuFeatures = ");
8622 if (g->zig_target->cpu_features != nullptr) {
8623 const char *ptr;
8624 size_t len;
8625 stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len);
8626 buf_append_mem(contents, ptr, len);
8525 buf_append_str(contents, "pub const cpu: Cpu = ");
8526 if (g->zig_target->builtin_str != nullptr) {
8527 buf_append_str(contents, g->zig_target->builtin_str);
86278528 } else {
8628 buf_append_str(contents, "arch.getBaselineCpuFeatures();\n");
8529 buf_append_str(contents, "Target.Cpu.baseline(arch);\n");
86298530 }
86308531 }
86318532 if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {
......@@ -8717,22 +8618,18 @@ static Error define_builtin_compile_vars(CodeGen *g) {
87178618 cache_int(&cache_hash, g->build_mode);
87188619 cache_bool(&cache_hash, g->strip_debug_symbols);
87198620 cache_int(&cache_hash, g->out_type);
8720 cache_bool(&cache_hash, g->is_dynamic);
8621 cache_bool(&cache_hash, detect_dynamic_link(g));
87218622 cache_bool(&cache_hash, g->is_test_build);
87228623 cache_bool(&cache_hash, g->is_single_threaded);
87238624 cache_bool(&cache_hash, g->test_is_evented);
87248625 cache_int(&cache_hash, g->code_model);
87258626 cache_int(&cache_hash, g->zig_target->is_native);
87268627 cache_int(&cache_hash, g->zig_target->arch);
8727 cache_int(&cache_hash, g->zig_target->sub_arch);
87288628 cache_int(&cache_hash, g->zig_target->vendor);
87298629 cache_int(&cache_hash, g->zig_target->os);
87308630 cache_int(&cache_hash, g->zig_target->abi);
8731 if (g->zig_target->cpu_features != nullptr) {
8732 const char *ptr;
8733 size_t len;
8734 stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
8735 cache_str(&cache_hash, ptr);
8631 if (g->zig_target->cache_hash != nullptr) {
8632 cache_str(&cache_hash, g->zig_target->cache_hash);
87368633 }
87378634 if (g->zig_target->glibc_version != nullptr) {
87388635 cache_int(&cache_hash, g->zig_target->glibc_version->major);
......@@ -8867,9 +8764,11 @@ static void init(CodeGen *g) {
88678764 }
88688765
88698766 // Override CPU and features if defined by user.
8870 if (g->zig_target->cpu_features != nullptr) {
8871 target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
8872 target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
8767 if (g->zig_target->llvm_cpu_name != nullptr) {
8768 target_specific_cpu_args = g->zig_target->llvm_cpu_name;
8769 }
8770 if (g->zig_target->llvm_cpu_features != nullptr) {
8771 target_specific_features = g->zig_target->llvm_cpu_features;
88738772 }
88748773 if (g->verbose_llvm_cpu_features) {
88758774 fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str));
......@@ -8943,6 +8842,8 @@ static void init(CodeGen *g) {
89438842}
89448843
89458844static void detect_dynamic_linker(CodeGen *g) {
8845 Error err;
8846
89468847 if (g->dynamic_linker_path != nullptr)
89478848 return;
89488849 if (!g->have_dynamic_link)
......@@ -8950,42 +8851,16 @@ static void detect_dynamic_linker(CodeGen *g) {
89508851 if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))
89518852 return;
89528853
8953 const char *standard_ld_path = target_dynamic_linker(g->zig_target);
8954 if (standard_ld_path == nullptr)
8955 return;
8956
8957 if (g->zig_target->is_native) {
8958 // target_dynamic_linker is usually correct. However on some systems, such as NixOS
8959 // it will be incorrect. See if we can do better by looking at what zig's own
8960 // dynamic linker path is.
8961 g->dynamic_linker_path = get_self_dynamic_linker_path();
8962 if (g->dynamic_linker_path != nullptr)
8963 return;
8964
8965 // If Zig is statically linked, such as via distributed binary static builds, the above
8966 // trick won't work. What are we left with? Try to run the system C compiler and get
8967 // it to tell us the dynamic linker path
8968#if defined(ZIG_OS_LINUX)
8969 {
8970 Error err;
8971 Buf *result = buf_alloc();
8972 for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
8973 const char *lib_name = possible_ld_names[i];
8974 if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) {
8975 if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) {
8976 fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err));
8977 exit(1);
8978 }
8979 continue;
8980 }
8981 g->dynamic_linker_path = result;
8982 return;
8983 }
8984 }
8985#endif
8854 char *dynamic_linker_ptr;
8855 size_t dynamic_linker_len;
8856 if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) {
8857 if (err == ErrorTargetHasNoDynamicLinker) return;
8858 fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err));
8859 exit(1);
89868860 }
8987
8988 g->dynamic_linker_path = buf_create_from_str(standard_ld_path);
8861 g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len);
8862 // Skips heap::c_allocator because the memory is allocated by stage2 library.
8863 free(dynamic_linker_ptr);
89898864}
89908865
89918866static void detect_libc(CodeGen *g) {
......@@ -9014,16 +8889,16 @@ static void detect_libc(CodeGen *g) {
90148889 buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os));
90158890
90168891 g->libc_include_dir_len = 4;
9017 g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(g->libc_include_dir_len);
9018 g->libc_include_dir_list[0] = arch_include_dir;
9019 g->libc_include_dir_list[1] = generic_include_dir;
9020 g->libc_include_dir_list[2] = arch_os_include_dir;
9021 g->libc_include_dir_list[3] = generic_os_include_dir;
8892 g->libc_include_dir_list = heap::c_allocator.allocate<const char*>(g->libc_include_dir_len);
8893 g->libc_include_dir_list[0] = buf_ptr(arch_include_dir);
8894 g->libc_include_dir_list[1] = buf_ptr(generic_include_dir);
8895 g->libc_include_dir_list[2] = buf_ptr(arch_os_include_dir);
8896 g->libc_include_dir_list[3] = buf_ptr(generic_os_include_dir);
90228897 return;
90238898 }
90248899
90258900 if (g->zig_target->is_native) {
9026 g->libc = heap::c_allocator.create<ZigLibCInstallation>();
8901 g->libc = heap::c_allocator.create<Stage2LibCInstallation>();
90278902
90288903 // search for native_libc.txt in following dirs:
90298904 // - LOCAL_CACHE_DIR
......@@ -9068,8 +8943,8 @@ static void detect_libc(CodeGen *g) {
90688943 if (libc_txt == nullptr)
90698944 libc_txt = &global_libc_txt;
90708945
9071 if ((err = zig_libc_parse(g->libc, libc_txt, g->zig_target, false))) {
9072 if ((err = zig_libc_find_native(g->libc, true))) {
8946 if ((err = stage2_libc_parse(g->libc, buf_ptr(libc_txt)))) {
8947 if ((err = stage2_libc_find_native(g->libc))) {
90738948 fprintf(stderr,
90748949 "Unable to link against libc: Unable to find libc installation: %s\n"
90758950 "See `zig libc --help` for more details.\n", err_str(err));
......@@ -9089,7 +8964,7 @@ static void detect_libc(CodeGen *g) {
90898964 fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
90908965 exit(1);
90918966 }
9092 zig_libc_render(g->libc, file);
8967 stage2_libc_render(g->libc, file);
90938968 if (fclose(file) != 0) {
90948969 fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
90958970 exit(1);
......@@ -9099,27 +8974,28 @@ static void detect_libc(CodeGen *g) {
90998974 exit(1);
91008975 }
91018976 }
9102 bool want_sys_dir = !buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir);
8977 bool want_sys_dir = !mem_eql_mem(g->libc->include_dir, g->libc->include_dir_len,
8978 g->libc->sys_include_dir, g->libc->sys_include_dir_len);
91038979 size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0;
91048980 size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs;
91058981 g->libc_include_dir_len = 0;
9106 g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(dir_count);
8982 g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
91078983
9108 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir;
8984 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
91098985 g->libc_include_dir_len += 1;
91108986
91118987 if (want_sys_dir) {
9112 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->sys_include_dir;
8988 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
91138989 g->libc_include_dir_len += 1;
91148990 }
91158991
91168992 if (want_um_and_shared_dirs != 0) {
9117 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "um",
9118 buf_ptr(&g->libc->include_dir));
8993 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
8994 "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
91198995 g->libc_include_dir_len += 1;
91208996
9121 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "shared",
9122 buf_ptr(&g->libc->include_dir));
8997 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
8998 "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
91238999 g->libc_include_dir_len += 1;
91249000 }
91259001 assert(g->libc_include_dir_len == dir_count);
......@@ -9194,9 +9070,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
91949070 args.append(buf_ptr(g->zig_c_headers_dir));
91959071
91969072 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
9197 Buf *include_dir = g->libc_include_dir_list[i];
9073 const char *include_dir = g->libc_include_dir_list[i];
91989074 args.append("-isystem");
9199 args.append(buf_ptr(include_dir));
9075 args.append(include_dir);
92009076 }
92019077
92029078 if (g->zig_target->is_native) {
......@@ -9207,19 +9083,17 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92079083 args.append("-target");
92089084 args.append(buf_ptr(&g->llvm_triple_str));
92099085
9210 const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
9211 if (llvm_cpu != nullptr) {
9086 if (g->zig_target->llvm_cpu_name != nullptr) {
92129087 args.append("-Xclang");
92139088 args.append("-target-cpu");
92149089 args.append("-Xclang");
9215 args.append(llvm_cpu);
9090 args.append(g->zig_target->llvm_cpu_name);
92169091 }
9217 const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
9218 if (llvm_target_features != nullptr) {
9092 if (g->zig_target->llvm_cpu_features != nullptr) {
92199093 args.append("-Xclang");
92209094 args.append("-target-feature");
92219095 args.append("-Xclang");
9222 args.append(llvm_target_features);
9096 args.append(g->zig_target->llvm_cpu_features);
92239097 }
92249098 }
92259099
......@@ -9652,10 +9526,9 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
96529526 cache_buf(cache_hash, compiler_id);
96539527 cache_int(cache_hash, g->err_color);
96549528 cache_buf(cache_hash, g->zig_c_headers_dir);
9655 cache_list_of_buf(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
9529 cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
96569530 cache_int(cache_hash, g->zig_target->is_native);
96579531 cache_int(cache_hash, g->zig_target->arch);
9658 cache_int(cache_hash, g->zig_target->sub_arch);
96599532 cache_int(cache_hash, g->zig_target->vendor);
96609533 cache_int(cache_hash, g->zig_target->os);
96619534 cache_int(cache_hash, g->zig_target->abi);
......@@ -10419,15 +10292,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1041910292 cache_int(ch, g->out_type);
1042010293 cache_bool(ch, g->zig_target->is_native);
1042110294 cache_int(ch, g->zig_target->arch);
10422 cache_int(ch, g->zig_target->sub_arch);
1042310295 cache_int(ch, g->zig_target->vendor);
1042410296 cache_int(ch, g->zig_target->os);
1042510297 cache_int(ch, g->zig_target->abi);
10426 if (g->zig_target->cpu_features != nullptr) {
10427 const char *ptr;
10428 size_t len;
10429 stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
10430 cache_str(ch, ptr);
10298 if (g->zig_target->cache_hash != nullptr) {
10299 cache_str(ch, g->zig_target->cache_hash);
1043110300 }
1043210301 if (g->zig_target->glibc_version != nullptr) {
1043310302 cache_int(ch, g->zig_target->glibc_version->major);
......@@ -10457,7 +10326,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1045710326 cache_bool(ch, g->function_sections);
1045810327 cache_bool(ch, g->enable_dump_analysis);
1045910328 cache_bool(ch, g->enable_doc_generation);
10460 cache_bool(ch, g->disable_bin_generation);
10329 cache_bool(ch, g->emit_bin);
10330 cache_bool(ch, g->emit_llvm_ir);
10331 cache_bool(ch, g->emit_asm);
1046110332 cache_buf_opt(ch, g->mmacosx_version_min);
1046210333 cache_buf_opt(ch, g->mios_version_min);
1046310334 cache_usize(ch, g->version_major);
......@@ -10468,11 +10339,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
1046810339 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
1046910340 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
1047010341 if (g->libc) {
10471 cache_buf(ch, &g->libc->include_dir);
10472 cache_buf(ch, &g->libc->sys_include_dir);
10473 cache_buf(ch, &g->libc->crt_dir);
10474 cache_buf(ch, &g->libc->msvc_lib_dir);
10475 cache_buf(ch, &g->libc->kernel32_lib_dir);
10342 cache_str(ch, g->libc->include_dir);
10343 cache_str(ch, g->libc->sys_include_dir);
10344 cache_str(ch, g->libc->crt_dir);
10345 cache_str(ch, g->libc->msvc_lib_dir);
10346 cache_str(ch, g->libc->kernel32_lib_dir);
1047610347 }
1047710348 cache_buf_opt(ch, g->dynamic_linker_path);
1047810349 cache_buf_opt(ch, g->version_script_path);
......@@ -10502,58 +10373,54 @@ static void resolve_out_paths(CodeGen *g) {
1050210373 assert(g->output_dir != nullptr);
1050310374 assert(g->root_out_name != nullptr);
1050410375
10505 Buf *out_basename = buf_create_from_buf(g->root_out_name);
10506 Buf *o_basename = buf_create_from_buf(g->root_out_name);
10507 switch (g->emit_file_type) {
10508 case EmitFileTypeBinary: {
10509 switch (g->out_type) {
10510 case OutTypeUnknown:
10511 zig_unreachable();
10512 case OutTypeObj:
10513 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {
10514 buf_init_from_buf(&g->output_file_path, g->link_objects.at(0));
10515 return;
10516 }
10517 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
10518 buf_eql_buf(o_basename, out_basename))
10519 {
10520 // make it not collide with main output object
10521 buf_append_str(o_basename, ".root");
10522 }
10523 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10524 buf_append_str(out_basename, target_o_file_ext(g->zig_target));
10525 break;
10526 case OutTypeExe:
10527 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10528 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));
10529 break;
10530 case OutTypeLib:
10531 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10532 buf_resize(out_basename, 0);
10533 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
10534 buf_append_buf(out_basename, g->root_out_name);
10535 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
10536 g->version_major, g->version_minor, g->version_patch));
10537 break;
10538 }
10539 break;
10540 }
10541 case EmitFileTypeAssembly: {
10542 const char *asm_ext = target_asm_file_ext(g->zig_target);
10543 buf_append_str(o_basename, asm_ext);
10544 buf_append_str(out_basename, asm_ext);
10545 break;
10546 }
10547 case EmitFileTypeLLVMIr: {
10548 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10549 buf_append_str(o_basename, llvm_ir_ext);
10550 buf_append_str(out_basename, llvm_ir_ext);
10551 break;
10376 if (g->emit_bin) {
10377 Buf *out_basename = buf_create_from_buf(g->root_out_name);
10378 Buf *o_basename = buf_create_from_buf(g->root_out_name);
10379 switch (g->out_type) {
10380 case OutTypeUnknown:
10381 zig_unreachable();
10382 case OutTypeObj:
10383 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {
10384 buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0));
10385 return;
10386 }
10387 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
10388 buf_eql_buf(o_basename, out_basename))
10389 {
10390 // make it not collide with main output object
10391 buf_append_str(o_basename, ".root");
10392 }
10393 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10394 buf_append_str(out_basename, target_o_file_ext(g->zig_target));
10395 break;
10396 case OutTypeExe:
10397 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10398 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));
10399 break;
10400 case OutTypeLib:
10401 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10402 buf_resize(out_basename, 0);
10403 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
10404 buf_append_buf(out_basename, g->root_out_name);
10405 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
10406 g->version_major, g->version_minor, g->version_patch));
10407 break;
1055210408 }
10409 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10410 os_path_join(g->output_dir, out_basename, &g->bin_file_output_path);
10411 }
10412 if (g->emit_asm) {
10413 Buf *asm_basename = buf_create_from_buf(g->root_out_name);
10414 const char *asm_ext = target_asm_file_ext(g->zig_target);
10415 buf_append_str(asm_basename, asm_ext);
10416 os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path);
10417 }
10418 if (g->emit_llvm_ir) {
10419 Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name);
10420 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10421 buf_append_str(llvm_ir_basename, llvm_ir_ext);
10422 os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path);
1055310423 }
10554
10555 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10556 os_path_join(g->output_dir, out_basename, &g->output_file_path);
1055710424}
1055810425
1055910426void codegen_build_and_link(CodeGen *g) {
......@@ -10715,7 +10582,7 @@ void codegen_build_and_link(CodeGen *g) {
1071510582 // If there is more than one object, we have to link them (with -r).
1071610583 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,
1071710584 // then we have an object from C source that we must copy to the output dir which we do with a -r link.
10718 if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary &&
10585 if (g->emit_bin &&
1071910586 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||
1072010587 (!need_llvm_module(g) && !g->enable_cache)))
1072110588 {
......@@ -10751,7 +10618,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
1075110618}
1075210619
1075310620CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
10754 ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)
10621 Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)
1075510622{
1075610623 Stage2ProgressNode *child_progress_node = stage2_progress_start(
1075710624 parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node,
......@@ -10790,9 +10657,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
1079010657
1079110658CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
1079210659 OutType out_type, BuildMode build_mode, Buf *override_lib_dir,
10793 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
10660 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
1079410661{
1079510662 CodeGen *g = heap::c_allocator.create<CodeGen>();
10663 g->emit_bin = true;
1079610664 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
1079710665 g->main_progress_node = progress_node;
1079810666
src/codegen.hpp+3-5
......@@ -11,23 +11,21 @@
1111#include "parser.hpp"
1212#include "errmsg.hpp"
1313#include "target.hpp"
14#include "libc_installation.hpp"
15#include "userland.h"
14#include "stage2.h"
1615
1716#include <stdio.h>
1817
1918CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
2019 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir,
21 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node);
20 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node);
2221
2322CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
24 ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node);
23 Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node);
2524
2625void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
2726void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
2827void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2928
30void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type);
3129void codegen_set_strip(CodeGen *codegen, bool strip);
3230void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
3331void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
src/compiler.cpp-34
......@@ -4,20 +4,6 @@
44
55#include <stdio.h>
66
7static Buf saved_dynamic_linker_path = BUF_INIT;
8static bool searched_for_dyn_linker = false;
9
10static void detect_dynamic_linker(Buf *lib_path) {
11#if defined(ZIG_OS_LINUX)
12 for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
13 if (buf_ends_with_str(lib_path, possible_ld_names[i])) {
14 buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
15 break;
16 }
17 }
18#endif
19}
20
217Buf *get_self_libc_path(void) {
228 static Buf saved_libc_path = BUF_INIT;
239 static bool searched_for_libc = false;
......@@ -43,25 +29,6 @@ Buf *get_self_libc_path(void) {
4329 }
4430}
4531
46Buf *get_self_dynamic_linker_path(void) {
47 for (;;) {
48 if (saved_dynamic_linker_path.list.length != 0) {
49 return &saved_dynamic_linker_path;
50 }
51 if (searched_for_dyn_linker)
52 return nullptr;
53 ZigList<Buf *> lib_paths = {};
54 Error err;
55 if ((err = os_self_exe_shared_libs(lib_paths)))
56 return nullptr;
57 for (size_t i = 0; i < lib_paths.length; i += 1) {
58 Buf *lib_path = lib_paths.at(i);
59 detect_dynamic_linker(lib_path);
60 }
61 searched_for_dyn_linker = true;
62 }
63}
64
6532Error get_compiler_id(Buf **result) {
6633 static Buf saved_compiler_id = BUF_INIT;
6734
......@@ -98,7 +65,6 @@ Error get_compiler_id(Buf **result) {
9865 return err;
9966 for (size_t i = 0; i < lib_paths.length; i += 1) {
10067 Buf *lib_path = lib_paths.at(i);
101 detect_dynamic_linker(lib_path);
10268 if ((err = cache_add_file(ch, lib_path)))
10369 return err;
10470 }
src/compiler.hpp-1
......@@ -12,7 +12,6 @@
1212#include "error.hpp"
1313
1414Error get_compiler_id(Buf **result);
15Buf *get_self_dynamic_linker_path(void);
1615Buf *get_self_libc_path(void);
1716
1817Buf *get_zig_lib_dir(void);
src/error.cpp+18-1
......@@ -59,11 +59,28 @@ const char *err_str(Error err) {
5959 case ErrorIsAsync: return "is async";
6060 case ErrorImportOutsidePkgPath: return "import of file outside package path";
6161 case ErrorUnknownCpu: return "unknown CPU";
62 case ErrorUnknownSubArchitecture: return "unknown sub-architecture";
6362 case ErrorUnknownCpuFeature: return "unknown CPU feature";
6463 case ErrorInvalidCpuFeatures: return "invalid CPU features";
6564 case ErrorInvalidLlvmCpuFeaturesFormat: return "invalid LLVM CPU features format";
6665 case ErrorUnknownApplicationBinaryInterface: return "unknown application binary interface";
66 case ErrorASTUnitFailure: return "compiler bug: clang encountered a compile error, but the libclang API does not expose the error. See https://github.com/ziglang/zig/issues/4455 for more details";
67 case ErrorBadPathName: return "bad path name";
68 case ErrorSymLinkLoop: return "sym link loop";
69 case ErrorProcessFdQuotaExceeded: return "process fd quota exceeded";
70 case ErrorSystemFdQuotaExceeded: return "system fd quota exceeded";
71 case ErrorNoDevice: return "no device";
72 case ErrorDeviceBusy: return "device busy";
73 case ErrorUnableToSpawnCCompiler: return "unable to spawn system C compiler";
74 case ErrorCCompilerExitCode: return "system C compiler exited with failure code";
75 case ErrorCCompilerCrashed: return "system C compiler crashed";
76 case ErrorCCompilerCannotFindHeaders: return "system C compiler cannot find libc headers";
77 case ErrorLibCRuntimeNotFound: return "libc runtime not found";
78 case ErrorLibCStdLibHeaderNotFound: return "libc std lib headers not found";
79 case ErrorLibCKernel32LibNotFound: return "kernel32 library not found";
80 case ErrorUnsupportedArchitecture: return "unsupported architecture";
81 case ErrorWindowsSdkNotFound: return "Windows SDK not found";
82 case ErrorUnknownDynamicLinkerPath: return "unknown dynamic linker path";
83 case ErrorTargetHasNoDynamicLinker: return "target has no dynamic linker";
6784 }
6885 return "(invalid error)";
6986}
src/error.hpp+1-1
......@@ -8,7 +8,7 @@
88#ifndef ERROR_HPP
99#define ERROR_HPP
1010
11#include "userland.h"
11#include "stage2.h"
1212
1313const char *err_str(Error err);
1414
src/glibc.cpp+2-4
......@@ -116,10 +116,8 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
116116 assert(opt_abi.is_some);
117117
118118
119 err = target_parse_archsub(&target->arch, &target->sub_arch,
120 (char*)opt_arch.value.ptr, opt_arch.value.len);
121 // there's no sub arch so we might get an error, but the arch is still populated
122 assert(err == ErrorNone || err == ErrorUnknownArchitecture);
119 err = target_parse_arch(&target->arch, (char*)opt_arch.value.ptr, opt_arch.value.len);
120 assert(err == ErrorNone);
123121
124122 target->os = OsLinux;
125123
src/ir.cpp+166-666
......@@ -14,6 +14,7 @@
1414#include "range_set.hpp"
1515#include "softfloat.hpp"
1616#include "util.hpp"
17#include "mem_list.hpp"
1718
1819#include <errno.h>
1920
......@@ -28,6 +29,9 @@ struct IrBuilderGen {
2829 CodeGen *codegen;
2930 IrExecutableGen *exec;
3031 IrBasicBlockGen *current_basic_block;
32
33 // track for immediate post-analysis destruction
34 mem::List<IrInstGenConst *> constants;
3135};
3236
3337struct IrAnalyze {
......@@ -383,18 +387,12 @@ static void destroy_instruction_src(IrInstSrc *inst) {
383387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
384388 case IrInstSrcIdErrSetCast:
385389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
386 case IrInstSrcIdFromBytes:
387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst));
388 case IrInstSrcIdToBytes:
389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcToBytes *>(inst));
390390 case IrInstSrcIdIntToFloat:
391391 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
392392 case IrInstSrcIdFloatToInt:
393393 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));
394394 case IrInstSrcIdBoolToInt:
395395 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));
396 case IrInstSrcIdIntType:
397 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntType *>(inst));
398396 case IrInstSrcIdVectorType:
399397 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));
400398 case IrInstSrcIdShuffleVector:
......@@ -409,12 +407,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
409407 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));
410408 case IrInstSrcIdSlice:
411409 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));
412 case IrInstSrcIdMemberCount:
413 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberCount *>(inst));
414 case IrInstSrcIdMemberType:
415 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberType *>(inst));
416 case IrInstSrcIdMemberName:
417 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberName *>(inst));
418410 case IrInstSrcIdBreakpoint:
419411 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));
420412 case IrInstSrcIdReturnAddress:
......@@ -481,8 +473,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
481473 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));
482474 case IrInstSrcIdHasField:
483475 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));
484 case IrInstSrcIdTypeId:
485 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeId *>(inst));
486476 case IrInstSrcIdSetEvalBranchQuota:
487477 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));
488478 case IrInstSrcIdAlignCast:
......@@ -707,8 +697,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
707697 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));
708698 case IrInstGenIdAssertNonNull:
709699 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));
710 case IrInstGenIdResizeSlice:
711 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst));
712700 case IrInstGenIdAlloca:
713701 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));
714702 case IrInstGenIdSuspendBegin:
......@@ -741,6 +729,10 @@ static void ira_ref(IrAnalyze *ira) {
741729static void ira_deref(IrAnalyze *ira) {
742730 if (ira->ref_count > 1) {
743731 ira->ref_count -= 1;
732
733 // immediate destruction of dangling IrInstGenConst is not possible
734 // free tracking memory because it will never be used
735 ira->new_irb.constants.deinit(&heap::c_allocator);
744736 return;
745737 }
746738 assert(ira->ref_count != 0);
......@@ -758,6 +750,15 @@ static void ira_deref(IrAnalyze *ira) {
758750 heap::c_allocator.destroy(ira->old_irb.exec);
759751 ira->src_implicit_return_type_list.deinit();
760752 ira->resume_stack.deinit();
753
754 // destroy dangling IrInstGenConst
755 for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) {
756 auto constant = ira->new_irb.constants.items[i];
757 if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base))
758 destroy_instruction_gen(&constant->base);
759 }
760 ira->new_irb.constants.deinit(&heap::c_allocator);
761
761762 heap::c_allocator.destroy(ira);
762763}
763764
......@@ -1299,10 +1300,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {
12991300 return IrInstSrcIdBoolToInt;
13001301}
13011302
1302static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntType *) {
1303 return IrInstSrcIdIntType;
1304}
1305
13061303static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {
13071304 return IrInstSrcIdVectorType;
13081305}
......@@ -1331,18 +1328,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {
13311328 return IrInstSrcIdSlice;
13321329}
13331330
1334static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberCount *) {
1335 return IrInstSrcIdMemberCount;
1336}
1337
1338static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberType *) {
1339 return IrInstSrcIdMemberType;
1340}
1341
1342static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberName *) {
1343 return IrInstSrcIdMemberName;
1344}
1345
13461331static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {
13471332 return IrInstSrcIdBreakpoint;
13481333}
......@@ -1487,10 +1472,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {
14871472 return IrInstSrcIdHasField;
14881473}
14891474
1490static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeId *) {
1491 return IrInstSrcIdTypeId;
1492}
1493
14941475static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {
14951476 return IrInstSrcIdSetEvalBranchQuota;
14961477}
......@@ -1563,14 +1544,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {
15631544 return IrInstSrcIdErrSetCast;
15641545}
15651546
1566static constexpr IrInstSrcId ir_inst_id(IrInstSrcToBytes *) {
1567 return IrInstSrcIdToBytes;
1568}
1569
1570static constexpr IrInstSrcId ir_inst_id(IrInstSrcFromBytes *) {
1571 return IrInstSrcIdFromBytes;
1572}
1573
15741547static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {
15751548 return IrInstSrcIdCheckRuntimeScope;
15761549}
......@@ -1700,10 +1673,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
17001673 return IrInstGenIdCast;
17011674}
17021675
1703static constexpr IrInstGenId ir_inst_id(IrInstGenResizeSlice *) {
1704 return IrInstGenIdResizeSlice;
1705}
1706
17071676static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
17081677 return IrInstGenIdUnreachable;
17091678}
......@@ -2759,21 +2728,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi
27592728 return &inst->base;
27602729}
27612730
2762static IrInstGen *ir_build_resize_slice(IrAnalyze *ira, IrInst *source_instruction,
2763 IrInstGen *operand, ZigType *ty, IrInstGen *result_loc)
2764{
2765 IrInstGenResizeSlice *instruction = ir_build_inst_gen<IrInstGenResizeSlice>(&ira->new_irb,
2766 source_instruction->scope, source_instruction->source_node);
2767 instruction->base.value->type = ty;
2768 instruction->operand = operand;
2769 instruction->result_loc = result_loc;
2770
2771 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);
2772 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
2773
2774 return &instruction->base;
2775}
2776
27772731static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
27782732 IrInstSrc *target, IrInstSrc *options)
27792733{
......@@ -3540,32 +3494,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode
35403494 return &instruction->base;
35413495}
35423496
3543static IrInstSrc *ir_build_to_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target,
3544 ResultLoc *result_loc)
3545{
3546 IrInstSrcToBytes *instruction = ir_build_instruction<IrInstSrcToBytes>(irb, scope, source_node);
3547 instruction->target = target;
3548 instruction->result_loc = result_loc;
3549
3550 ir_ref_instruction(target, irb->current_basic_block);
3551
3552 return &instruction->base;
3553}
3554
3555static IrInstSrc *ir_build_from_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3556 IrInstSrc *dest_child_type, IrInstSrc *target, ResultLoc *result_loc)
3557{
3558 IrInstSrcFromBytes *instruction = ir_build_instruction<IrInstSrcFromBytes>(irb, scope, source_node);
3559 instruction->dest_child_type = dest_child_type;
3560 instruction->target = target;
3561 instruction->result_loc = result_loc;
3562
3563 ir_ref_instruction(dest_child_type, irb->current_basic_block);
3564 ir_ref_instruction(target, irb->current_basic_block);
3565
3566 return &instruction->base;
3567}
3568
35693497static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
35703498 IrInstSrc *dest_type, IrInstSrc *target)
35713499{
......@@ -3601,19 +3529,6 @@ static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode
36013529 return &instruction->base;
36023530}
36033531
3604static IrInstSrc *ir_build_int_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_signed,
3605 IrInstSrc *bit_count)
3606{
3607 IrInstSrcIntType *instruction = ir_build_instruction<IrInstSrcIntType>(irb, scope, source_node);
3608 instruction->is_signed = is_signed;
3609 instruction->bit_count = bit_count;
3610
3611 ir_ref_instruction(is_signed, irb->current_basic_block);
3612 ir_ref_instruction(bit_count, irb->current_basic_block);
3613
3614 return &instruction->base;
3615}
3616
36173532static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len,
36183533 IrInstSrc *elem_type)
36193534{
......@@ -3808,41 +3723,6 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,
38083723 return &instruction->base;
38093724}
38103725
3811static IrInstSrc *ir_build_member_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *container) {
3812 IrInstSrcMemberCount *instruction = ir_build_instruction<IrInstSrcMemberCount>(irb, scope, source_node);
3813 instruction->container = container;
3814
3815 ir_ref_instruction(container, irb->current_basic_block);
3816
3817 return &instruction->base;
3818}
3819
3820static IrInstSrc *ir_build_member_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3821 IrInstSrc *container_type, IrInstSrc *member_index)
3822{
3823 IrInstSrcMemberType *instruction = ir_build_instruction<IrInstSrcMemberType>(irb, scope, source_node);
3824 instruction->container_type = container_type;
3825 instruction->member_index = member_index;
3826
3827 ir_ref_instruction(container_type, irb->current_basic_block);
3828 ir_ref_instruction(member_index, irb->current_basic_block);
3829
3830 return &instruction->base;
3831}
3832
3833static IrInstSrc *ir_build_member_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3834 IrInstSrc *container_type, IrInstSrc *member_index)
3835{
3836 IrInstSrcMemberName *instruction = ir_build_instruction<IrInstSrcMemberName>(irb, scope, source_node);
3837 instruction->container_type = container_type;
3838 instruction->member_index = member_index;
3839
3840 ir_ref_instruction(container_type, irb->current_basic_block);
3841 ir_ref_instruction(member_index, irb->current_basic_block);
3842
3843 return &instruction->base;
3844}
3845
38463726static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
38473727 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node);
38483728 return &instruction->base;
......@@ -4517,15 +4397,6 @@ static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source
45174397 return &instruction->base;
45184398}
45194399
4520static IrInstSrc *ir_build_type_id(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
4521 IrInstSrcTypeId *instruction = ir_build_instruction<IrInstSrcTypeId>(irb, scope, source_node);
4522 instruction->type_value = type_value;
4523
4524 ir_ref_instruction(type_value, irb->current_basic_block);
4525
4526 return &instruction->base;
4527}
4528
45294400static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
45304401 IrInstSrc *new_quota)
45314402{
......@@ -4956,11 +4827,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins
49564827}
49574828
49584829static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4959 IrInstSrc *frame, ResultLoc *result_loc)
4830 IrInstSrc *frame, ResultLoc *result_loc, bool is_noasync)
49604831{
49614832 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
49624833 instruction->frame = frame;
49634834 instruction->result_loc = result_loc;
4835 instruction->is_noasync = is_noasync;
49644836
49654837 ir_ref_instruction(frame, irb->current_basic_block);
49664838
......@@ -4968,13 +4840,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s
49684840}
49694841
49704842static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
4971 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc)
4843 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_noasync)
49724844{
49734845 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
49744846 source_instruction->scope, source_instruction->source_node);
49754847 instruction->base.value->type = result_type;
49764848 instruction->frame = frame;
49774849 instruction->result_loc = result_loc;
4850 instruction->is_noasync = is_noasync;
49784851
49794852 ir_ref_inst_gen(frame, ira->new_irb.current_basic_block);
49804853 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
......@@ -6595,31 +6468,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
65956468 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
65966469 return ir_lval_wrap(irb, scope, result, lval, result_loc);
65976470 }
6598 case BuiltinFnIdFromBytes:
6599 {
6600 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6601 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6602 if (arg0_value == irb->codegen->invalid_inst_src)
6603 return arg0_value;
6604
6605 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6606 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6607 if (arg1_value == irb->codegen->invalid_inst_src)
6608 return arg1_value;
6609
6610 IrInstSrc *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc);
6611 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6612 }
6613 case BuiltinFnIdToBytes:
6614 {
6615 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6616 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6617 if (arg0_value == irb->codegen->invalid_inst_src)
6618 return arg0_value;
6619
6620 IrInstSrc *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc);
6621 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6622 }
66236471 case BuiltinFnIdIntToFloat:
66246472 {
66256473 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -6680,21 +6528,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
66806528 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
66816529 return ir_lval_wrap(irb, scope, result, lval, result_loc);
66826530 }
6683 case BuiltinFnIdIntType:
6684 {
6685 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6686 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6687 if (arg0_value == irb->codegen->invalid_inst_src)
6688 return arg0_value;
6689
6690 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6691 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6692 if (arg1_value == irb->codegen->invalid_inst_src)
6693 return arg1_value;
6694
6695 IrInstSrc *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
6696 return ir_lval_wrap(irb, scope, int_type, lval, result_loc);
6697 }
66986531 case BuiltinFnIdVectorType:
66996532 {
67006533 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -6792,48 +6625,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
67926625 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value);
67936626 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);
67946627 }
6795 case BuiltinFnIdMemberCount:
6796 {
6797 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6798 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6799 if (arg0_value == irb->codegen->invalid_inst_src)
6800 return arg0_value;
6801
6802 IrInstSrc *member_count = ir_build_member_count(irb, scope, node, arg0_value);
6803 return ir_lval_wrap(irb, scope, member_count, lval, result_loc);
6804 }
6805 case BuiltinFnIdMemberType:
6806 {
6807 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6808 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6809 if (arg0_value == irb->codegen->invalid_inst_src)
6810 return arg0_value;
6811
6812 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6813 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6814 if (arg1_value == irb->codegen->invalid_inst_src)
6815 return arg1_value;
6816
6817
6818 IrInstSrc *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
6819 return ir_lval_wrap(irb, scope, member_type, lval, result_loc);
6820 }
6821 case BuiltinFnIdMemberName:
6822 {
6823 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6824 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6825 if (arg0_value == irb->codegen->invalid_inst_src)
6826 return arg0_value;
6827
6828 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6829 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6830 if (arg1_value == irb->codegen->invalid_inst_src)
6831 return arg1_value;
6832
6833
6834 IrInstSrc *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
6835 return ir_lval_wrap(irb, scope, member_name, lval, result_loc);
6836 }
68376628 case BuiltinFnIdField:
68386629 {
68396630 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -7158,16 +6949,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
71586949 }
71596950 case BuiltinFnIdAsyncCall:
71606951 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc);
7161 case BuiltinFnIdTypeId:
7162 {
7163 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7164 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7165 if (arg0_value == irb->codegen->invalid_inst_src)
7166 return arg0_value;
7167
7168 IrInstSrc *type_id = ir_build_type_id(irb, scope, node, arg0_value);
7169 return ir_lval_wrap(irb, scope, type_id, lval, result_loc);
7170 }
71716952 case BuiltinFnIdShlExact:
71726953 {
71736954 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -7243,21 +7024,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
72437024 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
72447025 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);
72457026 }
7246 case BuiltinFnIdArgType:
7247 {
7248 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7249 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7250 if (arg0_value == irb->codegen->invalid_inst_src)
7251 return arg0_value;
7252
7253 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7254 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7255 if (arg1_value == irb->codegen->invalid_inst_src)
7256 return arg1_value;
7257
7258 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false);
7259 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
7260 }
72617027 case BuiltinFnIdExport:
72627028 {
72637029 // Cast the options parameter to the options type
......@@ -8073,9 +7839,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
80737839 if (var_symbol) {
80747840 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node,
80757841 err_val_ptr, false, false);
8076 IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ?
8077 ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr;
8078 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr);
7842 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
7843 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
7844 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
80797845 }
80807846
80817847 ZigList<IrInstSrc *> incoming_values = {0};
......@@ -8123,7 +7889,8 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
81237889 true, false, false, is_comptime);
81247890 Scope *err_scope = err_var->child_scope;
81257891 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr);
8126 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr);
7892 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr);
7893 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime);
81277894
81287895 if (peer_parent->peers.length != 0) {
81297896 peer_parent->peers.last()->next_bb = else_block;
......@@ -8184,9 +7951,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
81847951
81857952 ir_set_cursor_at_end_and_append_block(irb, body_block);
81867953 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false, false);
8187 IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ?
8188 ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr;
8189 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr);
7954 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
7955 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
7956 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
81907957
81917958 ZigList<IrInstSrc *> incoming_values = {0};
81927959 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
......@@ -8425,9 +8192,9 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod
84258192 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
84268193 Scope *child_scope = elem_var->child_scope;
84278194
8428 IrInstSrc *var_ptr = node->data.for_expr.elem_is_ptr ?
8429 ir_build_ref_src(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr;
8430 ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr);
8195 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ?
8196 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
8197 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
84318198
84328199 ZigList<IrInstSrc *> incoming_values = {0};
84338200 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
......@@ -8847,8 +8614,9 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo
88478614 var_symbol, is_const, is_const, is_shadowable, is_comptime);
88488615
88498616 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);
8850 IrInstSrc *var_ptr = var_is_ptr ? ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
8851 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
8617 IrInstSrc *var_value = var_is_ptr ?
8618 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr);
8619 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime);
88528620 var_scope = var->child_scope;
88538621 } else {
88548622 var_scope = subexpr_scope;
......@@ -8929,9 +8697,9 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
89298697 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
89308698
89318699 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false);
8932 IrInstSrc *var_ptr = var_is_ptr ?
8933 ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;
8934 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);
8700 IrInstSrc *var_value = var_is_ptr ?
8701 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr);
8702 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime);
89358703 var_scope = var->child_scope;
89368704 } else {
89378705 var_scope = subexpr_scope;
......@@ -8956,7 +8724,8 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
89568724 err_symbol, is_const, is_const, is_shadowable, is_comptime);
89578725
89588726 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr);
8959 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr);
8727 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr);
8728 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime);
89608729 err_var_scope = var->child_scope;
89618730 } else {
89628731 err_var_scope = subexpr_scope;
......@@ -9006,22 +8775,24 @@ static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *s
90068775 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,
90078776 var_name, is_const, is_const, is_shadowable, var_is_comptime);
90088777 child_scope = var->child_scope;
9009 IrInstSrc *var_ptr;
8778 IrInstSrc *var_value;
90108779 if (out_switch_else_var != nullptr) {
90118780 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,
90128781 target_value_ptr);
90138782 *out_switch_else_var = switch_else_var;
90148783 IrInstSrc *payload_ptr = &switch_else_var->base;
9015 var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;
8784 var_value = var_is_ptr ?
8785 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
90168786 } else if (prong_values != nullptr) {
90178787 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,
90188788 prong_values, prong_values_len);
9019 var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;
8789 var_value = var_is_ptr ?
8790 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
90208791 } else {
9021 var_ptr = var_is_ptr ?
9022 ir_build_ref_src(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr;
8792 var_value = var_is_ptr ?
8793 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr);
90238794 }
9024 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr);
8795 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime);
90258796 } else {
90268797 child_scope = scope;
90278798 }
......@@ -9594,7 +9365,8 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
95949365 is_const, is_const, is_shadowable, is_comptime);
95959366 err_scope = var->child_scope;
95969367 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr);
9597 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr);
9368 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr);
9369 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime);
95989370 } else {
95999371 err_scope = subexpr_scope;
96009372 }
......@@ -9914,6 +9686,8 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
99149686{
99159687 assert(node->type == NodeTypeAwaitExpr);
99169688
9689 bool is_noasync = node->data.await_expr.noasync_token != nullptr;
9690
99179691 AstNode *expr_node = node->data.await_expr.expr;
99189692 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
99199693 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;
......@@ -9946,7 +9720,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
99469720 if (target_inst == irb->codegen->invalid_inst_src)
99479721 return irb->codegen->invalid_inst_src;
99489722
9949 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc);
9723 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_noasync);
99509724 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
99519725}
99529726
......@@ -12703,12 +12477,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) {
1270312477 IrInstGen *new_instruction = &const_instruction->base;
1270412478 new_instruction->value->type = ty;
1270512479 new_instruction->value->special = ConstValSpecialStatic;
12480 ira->new_irb.constants.append(&heap::c_allocator, const_instruction);
1270612481 return new_instruction;
1270712482}
1270812483
1270912484static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) {
1271012485 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb,
1271112486 old_instruction->scope, old_instruction->source_node);
12487 ira->new_irb.constants.append(&heap::c_allocator, const_instruction);
1271212488 return &const_instruction->base;
1271312489}
1271412490
......@@ -20599,12 +20375,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2059920375 if (type_is_invalid(array_ptr->value->type))
2060020376 return ira->codegen->invalid_inst_gen;
2060120377
20602 ZigValue *orig_array_ptr_val = array_ptr->value;
20603
2060420378 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;
2060520379 if (type_is_invalid(elem_index->value->type))
2060620380 return ira->codegen->invalid_inst_gen;
2060720381
20382 ZigValue *orig_array_ptr_val = array_ptr->value;
20383
2060820384 ZigType *ptr_type = orig_array_ptr_val->type;
2060920385 assert(ptr_type->id == ZigTypeIdPointer);
2061020386
......@@ -20614,23 +20390,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2061420390 // We will adjust return_type's alignment before returning it.
2061520391 ZigType *return_type;
2061620392
20617 if (type_is_invalid(array_type)) {
20393 if (type_is_invalid(array_type))
2061820394 return ira->codegen->invalid_inst_gen;
20619 } else if (array_type->id == ZigTypeIdArray ||
20620 (array_type->id == ZigTypeIdPointer &&
20621 array_type->data.pointer.ptr_len == PtrLenSingle &&
20622 array_type->data.pointer.child_type->id == ZigTypeIdArray))
20395
20396 if (array_type->id == ZigTypeIdPointer &&
20397 array_type->data.pointer.ptr_len == PtrLenSingle &&
20398 array_type->data.pointer.child_type->id == ZigTypeIdArray)
2062320399 {
20624 if (array_type->id == ZigTypeIdPointer) {
20625 array_type = array_type->data.pointer.child_type;
20626 ptr_type = ptr_type->data.pointer.child_type;
20627 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {
20628 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20629 elem_ptr_instruction->base.base.source_node);
20630 if (orig_array_ptr_val == nullptr)
20631 return ira->codegen->invalid_inst_gen;
20632 }
20633 }
20400 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base,
20401 array_ptr, nullptr);
20402 if (type_is_invalid(ptr_value->value->type))
20403 return ira->codegen->invalid_inst_gen;
20404
20405 array_type = array_type->data.pointer.child_type;
20406 ptr_type = ptr_type->data.pointer.child_type;
20407
20408 orig_array_ptr_val = ptr_value->value;
20409 }
20410
20411 if (array_type->id == ZigTypeIdArray) {
2063420412 if (array_type->data.array.len == 0) {
2063520413 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,
2063620414 buf_sprintf("index 0 outside array of size 0"));
......@@ -20768,8 +20546,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2076820546 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
2076920547 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))
2077020548 {
20549 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20550 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad)))
20551 {
20552 return ira->codegen->invalid_inst_gen;
20553 }
20554
2077120555 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20772 elem_ptr_instruction->base.base.source_node);
20556 elem_ptr_instruction->base.base.source_node);
2077320557 if (array_ptr_val == nullptr)
2077420558 return ira->codegen->invalid_inst_gen;
2077520559
......@@ -21178,6 +20962,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
2117820962 return ira->codegen->invalid_inst_gen;
2117920963 if (type_is_invalid(struct_val->type))
2118020964 return ira->codegen->invalid_inst_gen;
20965
20966 // This to allow lazy values to be resolved.
20967 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20968 source_instr->source_node, struct_val, UndefOk)))
20969 {
20970 return ira->codegen->invalid_inst_gen;
20971 }
2118120972 if (initializing && struct_val->special == ConstValSpecialUndef) {
2118220973 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
2118320974 struct_val->special = ConstValSpecialStatic;
......@@ -23583,7 +23374,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
2358323374}
2358423375
2358523376static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,
23586 ScopeDecls *decls_scope)
23377 ScopeDecls *decls_scope, bool resolve_types)
2358723378{
2358823379 Error err;
2358923380 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
......@@ -23594,6 +23385,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
2359423385 ensure_field_index(type_info_declaration_type, "is_pub", 1);
2359523386 ensure_field_index(type_info_declaration_type, "data", 2);
2359623387
23388 if (!resolve_types) {
23389 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type,
23390 false, false, PtrLenUnknown, 0, 0, 0, false);
23391
23392 out_val->special = ConstValSpecialLazy;
23393 out_val->type = get_slice_type(ira->codegen, ptr_type);
23394
23395 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>();
23396 lazy_type_info_decls->ira = ira; ira_ref(ira);
23397 out_val->data.x_lazy = &lazy_type_info_decls->base;
23398 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls;
23399
23400 lazy_type_info_decls->source_instr = source_instr;
23401 lazy_type_info_decls->decls_scope = decls_scope;
23402
23403 return ErrorNone;
23404 }
23405
2359723406 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
2359823407 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
2359923408 return err;
......@@ -23606,14 +23415,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
2360623415 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))
2360723416 return err;
2360823417
23609 // Loop through our declarations once to figure out how many declarations we will generate info for.
23418 // The unresolved declarations are collected in a separate queue to avoid
23419 // modifying decl_table while iterating over it
23420 ZigList<Tld*> resolve_decl_queue{};
23421
2361023422 auto decl_it = decls_scope->decl_table.entry_iterator();
2361123423 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
23612 int declaration_count = 0;
23613
2361423424 while ((curr_entry = decl_it.next()) != nullptr) {
23615 // If the declaration is unresolved, force it to be resolved again.
23616 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false);
2361723425 if (curr_entry->value->resolution == TldResolutionInvalid) {
2361823426 return ErrorSemanticAnalyzeFail;
2361923427 }
......@@ -23623,16 +23431,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
2362323431 return ErrorSemanticAnalyzeFail;
2362423432 }
2362523433
23434 // If the declaration is unresolved, force it to be resolved again.
23435 if (curr_entry->value->resolution == TldResolutionUnresolved)
23436 resolve_decl_queue.append(curr_entry->value);
23437 }
23438
23439 for (size_t i = 0; i < resolve_decl_queue.length; i++) {
23440 Tld *decl = resolve_decl_queue.at(i);
23441 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false);
23442 if (decl->resolution == TldResolutionInvalid) {
23443 return ErrorSemanticAnalyzeFail;
23444 }
23445 }
23446
23447 resolve_decl_queue.deinit();
23448
23449 // Loop through our declarations once to figure out how many declarations we will generate info for.
23450 int declaration_count = 0;
23451 decl_it = decls_scope->decl_table.entry_iterator();
23452 while ((curr_entry = decl_it.next()) != nullptr) {
2362623453 // Skip comptime blocks and test functions.
23627 if (curr_entry->value->id != TldIdCompTime) {
23628 if (curr_entry->value->id == TldIdFn) {
23629 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23630 if (fn_entry->is_test)
23631 continue;
23632 }
23454 if (curr_entry->value->id == TldIdCompTime)
23455 continue;
2363323456
23634 declaration_count += 1;
23457 if (curr_entry->value->id == TldIdFn) {
23458 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23459 if (fn_entry->is_test)
23460 continue;
2363523461 }
23462
23463 declaration_count += 1;
2363623464 }
2363723465
2363823466 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();
......@@ -24146,7 +23974,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2414623974 // decls: []TypeInfo.Declaration
2414723975 ensure_field_index(result->type, "decls", 3);
2414823976 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24149 type_entry->data.enumeration.decls_scope)))
23977 type_entry->data.enumeration.decls_scope, false)))
2415023978 {
2415123979 return err;
2415223980 }
......@@ -24318,7 +24146,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2431824146 // decls: []TypeInfo.Declaration
2431924147 ensure_field_index(result->type, "decls", 3);
2432024148 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24321 type_entry->data.unionation.decls_scope)))
24149 type_entry->data.unionation.decls_scope, false)))
2432224150 {
2432324151 return err;
2432424152 }
......@@ -24410,7 +24238,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2441024238 // decls: []TypeInfo.Declaration
2441124239 ensure_field_index(result->type, "decls", 2);
2441224240 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
24413 type_entry->data.structure.decls_scope)))
24241 type_entry->data.structure.decls_scope, false)))
2441424242 {
2441524243 return err;
2441624244 }
......@@ -24784,19 +24612,6 @@ static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *ins
2478424612 return ir_const_type(ira, &instruction->base.base, type);
2478524613}
2478624614
24787static IrInstGen *ir_analyze_instruction_type_id(IrAnalyze *ira, IrInstSrcTypeId *instruction) {
24788 IrInstGen *type_value = instruction->type_value->child;
24789 ZigType *type_entry = ir_resolve_type(ira, type_value);
24790 if (type_is_invalid(type_entry))
24791 return ira->codegen->invalid_inst_gen;
24792
24793 ZigType *result_type = get_builtin_type(ira->codegen, "TypeId");
24794
24795 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type);
24796 bigint_init_unsigned(&result->value->data.x_enum_tag, type_id_index(type_entry));
24797 return result;
24798}
24799
2480024615static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
2480124616 IrInstSrcSetEvalBranchQuota *instruction)
2480224617{
......@@ -25394,171 +25209,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE
2539425209 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type);
2539525210}
2539625211
25397static IrInstGen *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstSrcFromBytes *instruction) {
25398 Error err;
25399
25400 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child);
25401 if (type_is_invalid(dest_child_type))
25402 return ira->codegen->invalid_inst_gen;
25403
25404 IrInstGen *target = instruction->target->child;
25405 if (type_is_invalid(target->value->type))
25406 return ira->codegen->invalid_inst_gen;
25407
25408 bool src_ptr_const;
25409 bool src_ptr_volatile;
25410 uint32_t src_ptr_align;
25411 if (target->value->type->id == ZigTypeIdPointer) {
25412 src_ptr_const = target->value->type->data.pointer.is_const;
25413 src_ptr_volatile = target->value->type->data.pointer.is_volatile;
25414
25415 if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align)))
25416 return ira->codegen->invalid_inst_gen;
25417 } else if (is_slice(target->value->type)) {
25418 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25419 src_ptr_const = src_ptr_type->data.pointer.is_const;
25420 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
25421
25422 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align)))
25423 return ira->codegen->invalid_inst_gen;
25424 } else {
25425 src_ptr_const = true;
25426 src_ptr_volatile = false;
25427
25428 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown)))
25429 return ira->codegen->invalid_inst_gen;
25430
25431 src_ptr_align = get_abi_alignment(ira->codegen, target->value->type);
25432 }
25433
25434 if (src_ptr_align != 0) {
25435 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown)))
25436 return ira->codegen->invalid_inst_gen;
25437 }
25438
25439 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type,
25440 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25441 src_ptr_align, 0, 0, false);
25442 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25443
25444 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25445 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25446 src_ptr_align, 0, 0, false);
25447 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
25448
25449 IrInstGen *casted_value = ir_implicit_cast2(ira, &instruction->target->base, target, u8_slice);
25450 if (type_is_invalid(casted_value->value->type))
25451 return ira->codegen->invalid_inst_gen;
25452
25453 bool have_known_len = false;
25454 uint64_t known_len;
25455
25456 if (instr_is_comptime(casted_value)) {
25457 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad);
25458 if (!val)
25459 return ira->codegen->invalid_inst_gen;
25460
25461 ZigValue *len_val = val->data.x_struct.fields[slice_len_index];
25462 if (value_is_comptime(len_val)) {
25463 known_len = bigint_as_u64(&len_val->data.x_bigint);
25464 have_known_len = true;
25465 }
25466 }
25467
25468 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25469 dest_slice_type, nullptr, true, true);
25470 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) {
25471 return result_loc;
25472 }
25473
25474 if (target->value->type->id == ZigTypeIdPointer &&
25475 target->value->type->data.pointer.ptr_len == PtrLenSingle &&
25476 target->value->type->data.pointer.child_type->id == ZigTypeIdArray)
25477 {
25478 known_len = target->value->type->data.pointer.child_type->data.array.len;
25479 have_known_len = true;
25480 } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) {
25481 known_len = casted_value->value->data.rh_slice.len;
25482 have_known_len = true;
25483 }
25484
25485 if (have_known_len) {
25486 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown)))
25487 return ira->codegen->invalid_inst_gen;
25488 uint64_t child_type_size = type_size(ira->codegen, dest_child_type);
25489 uint64_t remainder = known_len % child_type_size;
25490 if (remainder != 0) {
25491 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
25492 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch",
25493 known_len, buf_ptr(&dest_slice_type->name)));
25494 add_error_note(ira->codegen, msg, instruction->dest_child_type->base.source_node,
25495 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64,
25496 buf_ptr(&dest_child_type->name), child_type_size, remainder));
25497 return ira->codegen->invalid_inst_gen;
25498 }
25499 }
25500
25501 return ir_build_resize_slice(ira, &instruction->base.base, casted_value, dest_slice_type, result_loc);
25502}
25503
25504static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToBytes *instruction) {
25505 Error err;
25506
25507 IrInstGen *target = instruction->target->child;
25508 if (type_is_invalid(target->value->type))
25509 return ira->codegen->invalid_inst_gen;
25510
25511 if (!is_slice(target->value->type)) {
25512 ir_add_error(ira, &instruction->target->base,
25513 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name)));
25514 return ira->codegen->invalid_inst_gen;
25515 }
25516
25517 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25518
25519 uint32_t alignment;
25520 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
25521 return ira->codegen->invalid_inst_gen;
25522
25523 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25524 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown,
25525 alignment, 0, 0, false);
25526 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25527
25528 if (instr_is_comptime(target)) {
25529 ZigValue *target_val = ir_resolve_const(ira, target, UndefBad);
25530 if (target_val == nullptr)
25531 return ira->codegen->invalid_inst_gen;
25532
25533 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type);
25534 result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
25535
25536 ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index];
25537 ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
25538 copy_const_val(ira->codegen, ptr_val, target_ptr_val);
25539 ptr_val->type = dest_ptr_type;
25540
25541 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index];
25542 len_val->special = ConstValSpecialStatic;
25543 len_val->type = ira->codegen->builtin_types.entry_usize;
25544 ZigValue *target_len_val = target_val->data.x_struct.fields[slice_len_index];
25545 ZigType *elem_type = src_ptr_type->data.pointer.child_type;
25546 BigInt elem_size_bigint;
25547 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
25548 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint);
25549
25550 return result;
25551 }
25552
25553 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25554 dest_slice_type, nullptr, true, true);
25555 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
25556 return result_loc;
25557 }
25558
25559 return ir_build_resize_slice(ira, &instruction->base.base, target, dest_slice_type, result_loc);
25560}
25561
2556225212static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
2556325213 Error err;
2556425214
......@@ -25672,20 +25322,6 @@ static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBo
2567225322 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt);
2567325323}
2567425324
25675static IrInstGen *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstSrcIntType *instruction) {
25676 IrInstGen *is_signed_value = instruction->is_signed->child;
25677 bool is_signed;
25678 if (!ir_resolve_bool(ira, is_signed_value, &is_signed))
25679 return ira->codegen->invalid_inst_gen;
25680
25681 IrInstGen *bit_count_value = instruction->bit_count->child;
25682 uint64_t bit_count;
25683 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count))
25684 return ira->codegen->invalid_inst_gen;
25685
25686 return ir_const_type(ira, &instruction->base.base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count));
25687}
25688
2568925325static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) {
2569025326 uint64_t len;
2569125327 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len))
......@@ -26582,148 +26218,21 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2658226218
2658326219 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
2658426220 return_type, nullptr, true, true);
26585 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26586 return result_loc;
26587 }
26588 return ir_build_slice_gen(ira, &instruction->base.base, return_type,
26589 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
26590}
26591
26592static IrInstGen *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstSrcMemberCount *instruction) {
26593 Error err;
26594 IrInstGen *container = instruction->container->child;
26595 if (type_is_invalid(container->value->type))
26596 return ira->codegen->invalid_inst_gen;
26597 ZigType *container_type = ir_resolve_type(ira, container);
26598
26599 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
26600 return ira->codegen->invalid_inst_gen;
26601
26602 uint64_t result;
26603 if (type_is_invalid(container_type)) {
26604 return ira->codegen->invalid_inst_gen;
26605 } else if (container_type->id == ZigTypeIdEnum) {
26606 result = container_type->data.enumeration.src_field_count;
26607 } else if (container_type->id == ZigTypeIdStruct) {
26608 result = container_type->data.structure.src_field_count;
26609 } else if (container_type->id == ZigTypeIdUnion) {
26610 result = container_type->data.unionation.src_field_count;
26611 } else if (container_type->id == ZigTypeIdErrorSet) {
26612 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.base.source_node)) {
26613 return ira->codegen->invalid_inst_gen;
26614 }
26615 if (type_is_global_error_set(container_type)) {
26616 ir_add_error(ira, &instruction->base.base, buf_sprintf("global error set member count not available at comptime"));
26617 return ira->codegen->invalid_inst_gen;
26618 }
26619 result = container_type->data.error_set.err_count;
26620 } else {
26621 ir_add_error(ira, &instruction->base.base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name)));
26622 return ira->codegen->invalid_inst_gen;
26623 }
26624
26625 return ir_const_unsigned(ira, &instruction->base.base, result);
26626}
26627
26628static IrInstGen *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstSrcMemberType *instruction) {
26629 Error err;
26630 IrInstGen *container_type_value = instruction->container_type->child;
26631 ZigType *container_type = ir_resolve_type(ira, container_type_value);
26632 if (type_is_invalid(container_type))
26633 return ira->codegen->invalid_inst_gen;
26634
26635 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
26636 return ira->codegen->invalid_inst_gen;
26637
26638
26639 uint64_t member_index;
26640 IrInstGen *index_value = instruction->member_index->child;
26641 if (!ir_resolve_usize(ira, index_value, &member_index))
26642 return ira->codegen->invalid_inst_gen;
2664326221
26644 if (container_type->id == ZigTypeIdStruct) {
26645 if (member_index >= container_type->data.structure.src_field_count) {
26646 ir_add_error(ira, &index_value->base,
26647 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26648 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
26649 return ira->codegen->invalid_inst_gen;
26222 if (result_loc != nullptr) {
26223 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26224 return result_loc;
2665026225 }
26651 TypeStructField *field = container_type->data.structure.fields[member_index];
26652
26653 return ir_const_type(ira, &instruction->base.base, field->type_entry);
26654 } else if (container_type->id == ZigTypeIdUnion) {
26655 if (member_index >= container_type->data.unionation.src_field_count) {
26656 ir_add_error(ira, &index_value->base,
26657 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26658 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
26226 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
26227 dummy_value->value->special = ConstValSpecialRuntime;
26228 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
26229 dummy_value, result_loc->value->type->data.pointer.child_type);
26230 if (type_is_invalid(dummy_result->value->type))
2665926231 return ira->codegen->invalid_inst_gen;
26660 }
26661 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
26662
26663 return ir_const_type(ira, &instruction->base.base, field->type_entry);
26664 } else {
26665 ir_add_error(ira, &container_type_value->base,
26666 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name)));
26667 return ira->codegen->invalid_inst_gen;
2666826232 }
26669}
26670
26671static IrInstGen *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstSrcMemberName *instruction) {
26672 Error err;
26673 IrInstGen *container_type_value = instruction->container_type->child;
26674 ZigType *container_type = ir_resolve_type(ira, container_type_value);
26675 if (type_is_invalid(container_type))
26676 return ira->codegen->invalid_inst_gen;
2667726233
26678 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
26679 return ira->codegen->invalid_inst_gen;
26680
26681 uint64_t member_index;
26682 IrInstGen *index_value = instruction->member_index->child;
26683 if (!ir_resolve_usize(ira, index_value, &member_index))
26684 return ira->codegen->invalid_inst_gen;
26685
26686 if (container_type->id == ZigTypeIdStruct) {
26687 if (member_index >= container_type->data.structure.src_field_count) {
26688 ir_add_error(ira, &index_value->base,
26689 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26690 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
26691 return ira->codegen->invalid_inst_gen;
26692 }
26693 TypeStructField *field = container_type->data.structure.fields[member_index];
26694
26695 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26696 init_const_str_lit(ira->codegen, result->value, field->name);
26697 return result;
26698 } else if (container_type->id == ZigTypeIdEnum) {
26699 if (member_index >= container_type->data.enumeration.src_field_count) {
26700 ir_add_error(ira, &index_value->base,
26701 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26702 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count));
26703 return ira->codegen->invalid_inst_gen;
26704 }
26705 TypeEnumField *field = &container_type->data.enumeration.fields[member_index];
26706
26707 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26708 init_const_str_lit(ira->codegen, result->value, field->name);
26709 return result;
26710 } else if (container_type->id == ZigTypeIdUnion) {
26711 if (member_index >= container_type->data.unionation.src_field_count) {
26712 ir_add_error(ira, &index_value->base,
26713 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26714 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
26715 return ira->codegen->invalid_inst_gen;
26716 }
26717 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
26718
26719 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26720 init_const_str_lit(ira->codegen, result->value, field->name);
26721 return result;
26722 } else {
26723 ir_add_error(ira, &container_type_value->base,
26724 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name)));
26725 return ira->codegen->invalid_inst_gen;
26726 }
26234 return ir_build_slice_gen(ira, &instruction->base.base, return_type,
26235 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
2672726236}
2672826237
2672926238static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) {
......@@ -29466,7 +28975,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
2946628975 ir_assert(fn_entry != nullptr, &instruction->base.base);
2946728976
2946828977 // If it's not @Frame(func) then it's definitely a suspend point
29469 if (target_fn == nullptr) {
28978 if (target_fn == nullptr && !instruction->is_noasync) {
2947028979 if (fn_entry->inferred_async_node == nullptr) {
2947128980 fn_entry->inferred_async_node = instruction->base.base.source_node;
2947228981 }
......@@ -29489,7 +28998,8 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
2948928998 result_loc = nullptr;
2949028999 }
2949129000
29492 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc);
29001 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,
29002 instruction->is_noasync);
2949329003 result->target_fn = target_fn;
2949429004 fn_entry->await_list.append(result);
2949529005 return ir_finish_anal(ira, &result->base);
......@@ -29677,18 +29187,12 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
2967729187 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction);
2967829188 case IrInstSrcIdErrSetCast:
2967929189 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction);
29680 case IrInstSrcIdFromBytes:
29681 return ir_analyze_instruction_from_bytes(ira, (IrInstSrcFromBytes *)instruction);
29682 case IrInstSrcIdToBytes:
29683 return ir_analyze_instruction_to_bytes(ira, (IrInstSrcToBytes *)instruction);
2968429190 case IrInstSrcIdIntToFloat:
2968529191 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction);
2968629192 case IrInstSrcIdFloatToInt:
2968729193 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction);
2968829194 case IrInstSrcIdBoolToInt:
2968929195 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction);
29690 case IrInstSrcIdIntType:
29691 return ir_analyze_instruction_int_type(ira, (IrInstSrcIntType *)instruction);
2969229196 case IrInstSrcIdVectorType:
2969329197 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction);
2969429198 case IrInstSrcIdShuffleVector:
......@@ -29703,12 +29207,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
2970329207 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction);
2970429208 case IrInstSrcIdSlice:
2970529209 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction);
29706 case IrInstSrcIdMemberCount:
29707 return ir_analyze_instruction_member_count(ira, (IrInstSrcMemberCount *)instruction);
29708 case IrInstSrcIdMemberType:
29709 return ir_analyze_instruction_member_type(ira, (IrInstSrcMemberType *)instruction);
29710 case IrInstSrcIdMemberName:
29711 return ir_analyze_instruction_member_name(ira, (IrInstSrcMemberName *)instruction);
2971229210 case IrInstSrcIdBreakpoint:
2971329211 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction);
2971429212 case IrInstSrcIdReturnAddress:
......@@ -29763,8 +29261,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
2976329261 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction);
2976429262 case IrInstSrcIdHasField:
2976529263 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction);
29766 case IrInstSrcIdTypeId:
29767 return ir_analyze_instruction_type_id(ira, (IrInstSrcTypeId *)instruction);
2976829264 case IrInstSrcIdSetEvalBranchQuota:
2976929265 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction);
2977029266 case IrInstSrcIdPtrType:
......@@ -30007,7 +29503,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {
3000729503 case IrInstGenIdCmpxchg:
3000829504 case IrInstGenIdAssertZero:
3000929505 case IrInstGenIdAssertNonNull:
30010 case IrInstGenIdResizeSlice:
3001129506 case IrInstGenIdPtrOfArrayToSlice:
3001229507 case IrInstGenIdSlice:
3001329508 case IrInstGenIdOptionalWrap:
......@@ -30180,15 +29675,11 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
3018029675 case IrInstSrcIdRef:
3018129676 case IrInstSrcIdEmbedFile:
3018229677 case IrInstSrcIdTruncate:
30183 case IrInstSrcIdIntType:
3018429678 case IrInstSrcIdVectorType:
3018529679 case IrInstSrcIdShuffleVector:
3018629680 case IrInstSrcIdSplat:
3018729681 case IrInstSrcIdBoolNot:
3018829682 case IrInstSrcIdSlice:
30189 case IrInstSrcIdMemberCount:
30190 case IrInstSrcIdMemberType:
30191 case IrInstSrcIdMemberName:
3019229683 case IrInstSrcIdAlignOf:
3019329684 case IrInstSrcIdReturnAddress:
3019429685 case IrInstSrcIdFrameAddress:
......@@ -30215,7 +29706,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
3021529706 case IrInstSrcIdTypeInfo:
3021629707 case IrInstSrcIdType:
3021729708 case IrInstSrcIdHasField:
30218 case IrInstSrcIdTypeId:
3021929709 case IrInstSrcIdAlignCast:
3022029710 case IrInstSrcIdImplicitCast:
3022129711 case IrInstSrcIdResolveResult:
......@@ -30233,8 +29723,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
3023329723 case IrInstSrcIdIntToFloat:
3023429724 case IrInstSrcIdFloatToInt:
3023529725 case IrInstSrcIdBoolToInt:
30236 case IrInstSrcIdFromBytes:
30237 case IrInstSrcIdToBytes:
3023829726 case IrInstSrcIdEnumToInt:
3023929727 case IrInstSrcIdHasDecl:
3024029728 case IrInstSrcIdAlloca:
......@@ -30347,6 +29835,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
3034729835 switch (val->data.x_lazy->id) {
3034829836 case LazyValueIdInvalid:
3034929837 zig_unreachable();
29838 case LazyValueIdTypeInfoDecls: {
29839 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy);
29840 IrAnalyze *ira = type_info_decls->ira;
29841
29842 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true)))
29843 {
29844 return err;
29845 };
29846
29847 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
29848 return ErrorNone;
29849 }
3035029850 case LazyValueIdAlignOf: {
3035129851 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
3035229852 IrAnalyze *ira = lazy_align_of->ira;
src/ir_print.cpp-102
......@@ -179,8 +179,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
179179 return "SrcFloatToInt";
180180 case IrInstSrcIdBoolToInt:
181181 return "SrcBoolToInt";
182 case IrInstSrcIdIntType:
183 return "SrcIntType";
184182 case IrInstSrcIdVectorType:
185183 return "SrcVectorType";
186184 case IrInstSrcIdBoolNot:
......@@ -191,12 +189,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
191189 return "SrcMemcpy";
192190 case IrInstSrcIdSlice:
193191 return "SrcSlice";
194 case IrInstSrcIdMemberCount:
195 return "SrcMemberCount";
196 case IrInstSrcIdMemberType:
197 return "SrcMemberType";
198 case IrInstSrcIdMemberName:
199 return "SrcMemberName";
200192 case IrInstSrcIdBreakpoint:
201193 return "SrcBreakpoint";
202194 case IrInstSrcIdReturnAddress:
......@@ -269,8 +261,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
269261 return "SrcType";
270262 case IrInstSrcIdHasField:
271263 return "SrcHasField";
272 case IrInstSrcIdTypeId:
273 return "SrcTypeId";
274264 case IrInstSrcIdSetEvalBranchQuota:
275265 return "SrcSetEvalBranchQuota";
276266 case IrInstSrcIdPtrType:
......@@ -307,10 +297,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
307297 return "SrcAddImplicitReturnType";
308298 case IrInstSrcIdErrSetCast:
309299 return "SrcErrSetCast";
310 case IrInstSrcIdToBytes:
311 return "SrcToBytes";
312 case IrInstSrcIdFromBytes:
313 return "SrcFromBytes";
314300 case IrInstSrcIdCheckRuntimeScope:
315301 return "SrcCheckRuntimeScope";
316302 case IrInstSrcIdHasDecl:
......@@ -383,8 +369,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
383369 return "GenReturn";
384370 case IrInstGenIdCast:
385371 return "GenCast";
386 case IrInstGenIdResizeSlice:
387 return "GenResizeSlice";
388372 case IrInstGenIdUnreachable:
389373 return "GenUnreachable";
390374 case IrInstGenIdAsm:
......@@ -590,11 +574,6 @@ static void ir_print_const_value(CodeGen *g, FILE *f, ZigValue *const_val) {
590574static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {
591575 if (inst == nullptr) {
592576 fprintf(irp->f, "(null)");
593 return;
594 }
595
596 if (inst->value->special != ConstValSpecialRuntime) {
597 ir_print_const_value(irp->codegen, irp->f, inst->value);
598577 } else {
599578 ir_print_var_gen(irp, inst);
600579 }
......@@ -1649,20 +1628,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct
16491628 fprintf(irp->f, ")");
16501629}
16511630
1652static void ir_print_from_bytes(IrPrintSrc *irp, IrInstSrcFromBytes *instruction) {
1653 fprintf(irp->f, "@bytesToSlice(");
1654 ir_print_other_inst_src(irp, instruction->dest_child_type);
1655 fprintf(irp->f, ", ");
1656 ir_print_other_inst_src(irp, instruction->target);
1657 fprintf(irp->f, ")");
1658}
1659
1660static void ir_print_to_bytes(IrPrintSrc *irp, IrInstSrcToBytes *instruction) {
1661 fprintf(irp->f, "@sliceToBytes(");
1662 ir_print_other_inst_src(irp, instruction->target);
1663 fprintf(irp->f, ")");
1664}
1665
16661631static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) {
16671632 fprintf(irp->f, "@intToFloat(");
16681633 ir_print_other_inst_src(irp, instruction->dest_type);
......@@ -1685,14 +1650,6 @@ static void ir_print_bool_to_int(IrPrintSrc *irp, IrInstSrcBoolToInt *instructio
16851650 fprintf(irp->f, ")");
16861651}
16871652
1688static void ir_print_int_type(IrPrintSrc *irp, IrInstSrcIntType *instruction) {
1689 fprintf(irp->f, "@IntType(");
1690 ir_print_other_inst_src(irp, instruction->is_signed);
1691 fprintf(irp->f, ", ");
1692 ir_print_other_inst_src(irp, instruction->bit_count);
1693 fprintf(irp->f, ")");
1694}
1695
16961653static void ir_print_vector_type(IrPrintSrc *irp, IrInstSrcVectorType *instruction) {
16971654 fprintf(irp->f, "@Vector(");
16981655 ir_print_other_inst_src(irp, instruction->len);
......@@ -1809,28 +1766,6 @@ static void ir_print_slice_gen(IrPrintGen *irp, IrInstGenSlice *instruction) {
18091766 ir_print_other_inst_gen(irp, instruction->result_loc);
18101767}
18111768
1812static void ir_print_member_count(IrPrintSrc *irp, IrInstSrcMemberCount *instruction) {
1813 fprintf(irp->f, "@memberCount(");
1814 ir_print_other_inst_src(irp, instruction->container);
1815 fprintf(irp->f, ")");
1816}
1817
1818static void ir_print_member_type(IrPrintSrc *irp, IrInstSrcMemberType *instruction) {
1819 fprintf(irp->f, "@memberType(");
1820 ir_print_other_inst_src(irp, instruction->container_type);
1821 fprintf(irp->f, ", ");
1822 ir_print_other_inst_src(irp, instruction->member_index);
1823 fprintf(irp->f, ")");
1824}
1825
1826static void ir_print_member_name(IrPrintSrc *irp, IrInstSrcMemberName *instruction) {
1827 fprintf(irp->f, "@memberName(");
1828 ir_print_other_inst_src(irp, instruction->container_type);
1829 fprintf(irp->f, ", ");
1830 ir_print_other_inst_src(irp, instruction->member_index);
1831 fprintf(irp->f, ")");
1832}
1833
18341769static void ir_print_breakpoint(IrPrintSrc *irp, IrInstSrcBreakpoint *instruction) {
18351770 fprintf(irp->f, "@breakpoint()");
18361771}
......@@ -2147,13 +2082,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in
21472082 fprintf(irp->f, ")");
21482083}
21492084
2150static void ir_print_resize_slice(IrPrintGen *irp, IrInstGenResizeSlice *instruction) {
2151 fprintf(irp->f, "@resizeSlice(");
2152 ir_print_other_inst_gen(irp, instruction->operand);
2153 fprintf(irp->f, ")result=");
2154 ir_print_other_inst_gen(irp, instruction->result_loc);
2155}
2156
21572085static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) {
21582086 fprintf(irp->f, "Alloca(align=");
21592087 ir_print_other_inst_src(irp, instruction->align);
......@@ -2311,12 +2239,6 @@ static void ir_print_has_field(IrPrintSrc *irp, IrInstSrcHasField *instruction)
23112239 fprintf(irp->f, ")");
23122240}
23132241
2314static void ir_print_type_id(IrPrintSrc *irp, IrInstSrcTypeId *instruction) {
2315 fprintf(irp->f, "@typeId(");
2316 ir_print_other_inst_src(irp, instruction->type_value);
2317 fprintf(irp->f, ")");
2318}
2319
23202242static void ir_print_set_eval_branch_quota(IrPrintSrc *irp, IrInstSrcSetEvalBranchQuota *instruction) {
23212243 fprintf(irp->f, "@setEvalBranchQuota(");
23222244 ir_print_other_inst_src(irp, instruction->new_quota);
......@@ -2798,12 +2720,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
27982720 case IrInstSrcIdErrSetCast:
27992721 ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction);
28002722 break;
2801 case IrInstSrcIdFromBytes:
2802 ir_print_from_bytes(irp, (IrInstSrcFromBytes *)instruction);
2803 break;
2804 case IrInstSrcIdToBytes:
2805 ir_print_to_bytes(irp, (IrInstSrcToBytes *)instruction);
2806 break;
28072723 case IrInstSrcIdIntToFloat:
28082724 ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction);
28092725 break;
......@@ -2813,9 +2729,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
28132729 case IrInstSrcIdBoolToInt:
28142730 ir_print_bool_to_int(irp, (IrInstSrcBoolToInt *)instruction);
28152731 break;
2816 case IrInstSrcIdIntType:
2817 ir_print_int_type(irp, (IrInstSrcIntType *)instruction);
2818 break;
28192732 case IrInstSrcIdVectorType:
28202733 ir_print_vector_type(irp, (IrInstSrcVectorType *)instruction);
28212734 break;
......@@ -2837,15 +2750,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
28372750 case IrInstSrcIdSlice:
28382751 ir_print_slice_src(irp, (IrInstSrcSlice *)instruction);
28392752 break;
2840 case IrInstSrcIdMemberCount:
2841 ir_print_member_count(irp, (IrInstSrcMemberCount *)instruction);
2842 break;
2843 case IrInstSrcIdMemberType:
2844 ir_print_member_type(irp, (IrInstSrcMemberType *)instruction);
2845 break;
2846 case IrInstSrcIdMemberName:
2847 ir_print_member_name(irp, (IrInstSrcMemberName *)instruction);
2848 break;
28492753 case IrInstSrcIdBreakpoint:
28502754 ir_print_breakpoint(irp, (IrInstSrcBreakpoint *)instruction);
28512755 break;
......@@ -2945,9 +2849,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
29452849 case IrInstSrcIdHasField:
29462850 ir_print_has_field(irp, (IrInstSrcHasField *)instruction);
29472851 break;
2948 case IrInstSrcIdTypeId:
2949 ir_print_type_id(irp, (IrInstSrcTypeId *)instruction);
2950 break;
29512852 case IrInstSrcIdSetEvalBranchQuota:
29522853 ir_print_set_eval_branch_quota(irp, (IrInstSrcSetEvalBranchQuota *)instruction);
29532854 break;
......@@ -3278,9 +3179,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
32783179 case IrInstGenIdAssertNonNull:
32793180 ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction);
32803181 break;
3281 case IrInstGenIdResizeSlice:
3282 ir_print_resize_slice(irp, (IrInstGenResizeSlice *)instruction);
3283 break;
32843182 case IrInstGenIdAlloca:
32853183 ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction);
32863184 break;
src/libc_installation.cpp deleted-498
......@@ -1,498 +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#include "libc_installation.hpp"
9#include "os.hpp"
10#include "windows_sdk.h"
11#include "target.hpp"
12
13static const char *zig_libc_keys[] = {
14 "include_dir",
15 "sys_include_dir",
16 "crt_dir",
17 "static_crt_dir",
18 "msvc_lib_dir",
19 "kernel32_lib_dir",
20};
21
22static const size_t zig_libc_keys_len = array_length(zig_libc_keys);
23
24static bool zig_libc_match_key(Slice<uint8_t> name, Slice<uint8_t> value, bool *found_keys,
25 size_t index, Buf *field_ptr)
26{
27 if (!memEql(name, str(zig_libc_keys[index]))) return false;
28 buf_init_from_mem(field_ptr, (const char*)value.ptr, value.len);
29 found_keys[index] = true;
30 return true;
31}
32
33static void zig_libc_init_empty(ZigLibCInstallation *libc) {
34 *libc = {};
35 buf_init_from_str(&libc->include_dir, "");
36 buf_init_from_str(&libc->sys_include_dir, "");
37 buf_init_from_str(&libc->crt_dir, "");
38 buf_init_from_str(&libc->static_crt_dir, "");
39 buf_init_from_str(&libc->msvc_lib_dir, "");
40 buf_init_from_str(&libc->kernel32_lib_dir, "");
41}
42
43Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget *target, bool verbose) {
44 Error err;
45 zig_libc_init_empty(libc);
46
47 bool found_keys[array_length(zig_libc_keys)] = {};
48
49 Buf *contents = buf_alloc();
50 if ((err = os_fetch_file_path(libc_file, contents))) {
51 if (err != ErrorFileNotFound && verbose) {
52 fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err));
53 }
54 return err;
55 }
56
57 SplitIterator it = memSplit(buf_to_slice(contents), str("\n"));
58 for (;;) {
59 Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);
60 if (!opt_line.is_some)
61 break;
62
63 if (opt_line.value.len == 0 || opt_line.value.ptr[0] == '#')
64 continue;
65
66 SplitIterator line_it = memSplit(opt_line.value, str("="));
67 Slice<uint8_t> name;
68 if (!SplitIterator_next(&line_it).unwrap(&name)) {
69 if (verbose) {
70 fprintf(stderr, "missing equal sign after field name\n");
71 }
72 return ErrorSemanticAnalyzeFail;
73 }
74 Slice<uint8_t> value = SplitIterator_rest(&line_it);
75 bool match = false;
76 match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
77 match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->sys_include_dir);
78 match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir);
79 match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->static_crt_dir);
80 match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->msvc_lib_dir);
81 match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->kernel32_lib_dir);
82 }
83
84 for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
85 if (!found_keys[i]) {
86 if (verbose) {
87 fprintf(stderr, "missing field: %s\n", zig_libc_keys[i]);
88 }
89 return ErrorSemanticAnalyzeFail;
90 }
91 }
92
93 if (buf_len(&libc->include_dir) == 0) {
94 if (verbose) {
95 fprintf(stderr, "include_dir may not be empty\n");
96 }
97 return ErrorSemanticAnalyzeFail;
98 }
99
100 if (buf_len(&libc->sys_include_dir) == 0) {
101 if (verbose) {
102 fprintf(stderr, "sys_include_dir may not be empty\n");
103 }
104 return ErrorSemanticAnalyzeFail;
105 }
106
107 if (buf_len(&libc->crt_dir) == 0) {
108 if (!target_os_is_darwin(target->os)) {
109 if (verbose) {
110 fprintf(stderr, "crt_dir may not be empty for %s\n", target_os_name(target->os));
111 }
112 return ErrorSemanticAnalyzeFail;
113 }
114 }
115
116 if (buf_len(&libc->static_crt_dir) == 0) {
117 if (target->os == OsWindows && target_abi_is_gnu(target->abi)) {
118 if (verbose) {
119 fprintf(stderr, "static_crt_dir may not be empty for %s\n", target_os_name(target->os));
120 }
121 return ErrorSemanticAnalyzeFail;
122 }
123 }
124
125 if (buf_len(&libc->msvc_lib_dir) == 0) {
126 if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
127 if (verbose) {
128 fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", target_os_name(target->os));
129 }
130 return ErrorSemanticAnalyzeFail;
131 }
132 }
133
134 if (buf_len(&libc->kernel32_lib_dir) == 0) {
135 if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
136 if (verbose) {
137 fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", target_os_name(target->os));
138 }
139 return ErrorSemanticAnalyzeFail;
140 }
141 }
142
143 return ErrorNone;
144}
145
146#if defined(ZIG_OS_WINDOWS)
147#define CC_EXE "cc.exe"
148#else
149#define CC_EXE "cc"
150#endif
151
152static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, bool verbose) {
153 const char *cc_exe = getenv("CC");
154 cc_exe = (cc_exe == nullptr) ? CC_EXE : cc_exe;
155 ZigList<const char *> args = {};
156 args.append(cc_exe);
157 args.append("-E");
158 args.append("-Wp,-v");
159 args.append("-xc");
160 #if defined(ZIG_OS_WINDOWS)
161 args.append("nul");
162 #else
163 args.append("/dev/null");
164 #endif
165
166 Termination term;
167 Buf *out_stderr = buf_alloc();
168 Buf *out_stdout = buf_alloc();
169 Error err;
170 if ((err = os_exec_process(args, &term, out_stderr, out_stdout))) {
171 if (verbose) {
172 fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
173 }
174 return err;
175 }
176 if (term.how != TerminationIdClean || term.code != 0) {
177 if (verbose) {
178 fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
179 }
180 return ErrorCCompileErrors;
181 }
182 char *prev_newline = buf_ptr(out_stderr);
183 ZigList<const char *> search_paths = {};
184 for (;;) {
185 char *newline = strchr(prev_newline, '\n');
186 if (newline == nullptr) {
187 break;
188 }
189
190 #if defined(ZIG_OS_WINDOWS)
191 *(newline - 1) = 0;
192 #endif
193 *newline = 0;
194
195 if (prev_newline[0] == ' ') {
196 search_paths.append(prev_newline);
197 }
198 prev_newline = newline + 1;
199 }
200 if (search_paths.length == 0) {
201 if (verbose) {
202 fprintf(stderr, "unable to determine libc include path: '%s' cannot find libc headers\n", cc_exe);
203 }
204 return ErrorCCompileErrors;
205 }
206 for (size_t i = 0; i < search_paths.length; i += 1) {
207 // search in reverse order
208 const char *search_path = search_paths.items[search_paths.length - i - 1];
209 // cut off spaces
210 while (*search_path == ' ') {
211 search_path += 1;
212 }
213
214 #if defined(ZIG_OS_WINDOWS)
215 if (buf_len(&self->include_dir) == 0) {
216 Buf *stdlib_path = buf_sprintf("%s\\stdlib.h", search_path);
217 bool exists;
218 if ((err = os_file_exists(stdlib_path, &exists))) {
219 exists = false;
220 }
221 if (exists) {
222 buf_init_from_str(&self->include_dir, search_path);
223 }
224 }
225 if (buf_len(&self->sys_include_dir) == 0) {
226 Buf *stdlib_path = buf_sprintf("%s\\sys\\types.h", search_path);
227 bool exists;
228 if ((err = os_file_exists(stdlib_path, &exists))) {
229 exists = false;
230 }
231 if (exists) {
232 buf_init_from_str(&self->sys_include_dir, search_path);
233 }
234 }
235 #else
236 if (buf_len(&self->include_dir) == 0) {
237 Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
238 bool exists;
239 if ((err = os_file_exists(stdlib_path, &exists))) {
240 exists = false;
241 }
242 if (exists) {
243 buf_init_from_str(&self->include_dir, search_path);
244 }
245 }
246 if (buf_len(&self->sys_include_dir) == 0) {
247 Buf *stdlib_path = buf_sprintf("%s/sys/errno.h", search_path);
248 bool exists;
249 if ((err = os_file_exists(stdlib_path, &exists))) {
250 exists = false;
251 }
252 if (exists) {
253 buf_init_from_str(&self->sys_include_dir, search_path);
254 }
255 }
256 #endif
257
258 if (buf_len(&self->include_dir) != 0 && buf_len(&self->sys_include_dir) != 0) {
259 return ErrorNone;
260 }
261 }
262 if (verbose) {
263 if (buf_len(&self->include_dir) == 0) {
264 fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe);
265 }
266 if (buf_len(&self->sys_include_dir) == 0) {
267 #if defined(ZIG_OS_WINDOWS)
268 fprintf(stderr, "unable to determine libc include path: sys/types.h not found in '%s' search paths\n", cc_exe);
269 #else
270 fprintf(stderr, "unable to determine libc include path: sys/errno.h not found in '%s' search paths\n", cc_exe);
271 #endif
272 }
273 }
274 return ErrorFileNotFound;
275}
276
277Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
278 const char *cc_exe = getenv("CC");
279 cc_exe = (cc_exe == nullptr) ? CC_EXE : cc_exe;
280 ZigList<const char *> args = {};
281 args.append(cc_exe);
282 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
283 Termination term;
284 Buf *out_stderr = buf_alloc();
285 Buf *out_stdout = buf_alloc();
286 Error err;
287 if ((err = os_exec_process(args, &term, out_stderr, out_stdout))) {
288 if (err == ErrorFileNotFound)
289 return ErrorNoCCompilerInstalled;
290 if (verbose) {
291 fprintf(stderr, "unable to determine libc library path: executing '%s': %s\n", cc_exe, err_str(err));
292 }
293 return err;
294 }
295 if (term.how != TerminationIdClean || term.code != 0) {
296 if (verbose) {
297 fprintf(stderr, "unable to determine libc library path: executing '%s' failed\n", cc_exe);
298 }
299 return ErrorCCompileErrors;
300 }
301 #if defined(ZIG_OS_WINDOWS)
302 if (buf_ends_with_str(out_stdout, "\r\n")) {
303 buf_resize(out_stdout, buf_len(out_stdout) - 2);
304 }
305 #else
306 if (buf_ends_with_str(out_stdout, "\n")) {
307 buf_resize(out_stdout, buf_len(out_stdout) - 1);
308 }
309 #endif
310 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
311 return ErrorCCompilerCannotFindFile;
312 }
313 if (want_dirname) {
314 os_path_dirname(out_stdout, out);
315 } else {
316 buf_init_from_buf(out, out_stdout);
317 }
318 return ErrorNone;
319}
320
321#undef CC_EXE
322
323#if defined(ZIG_OS_WINDOWS) || defined(ZIG_OS_LINUX) || defined(ZIG_OS_DRAGONFLY)
324static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
325 return zig_libc_cc_print_file_name("crt1.o", &self->crt_dir, true, verbose);
326}
327#endif
328
329#if defined(ZIG_OS_WINDOWS)
330static Error zig_libc_find_native_static_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
331 return zig_libc_cc_print_file_name("crtbegin.o", &self->static_crt_dir, true, verbose);
332}
333
334static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
335 Error err;
336 if ((err = os_get_win32_ucrt_include_path(sdk, &self->include_dir))) {
337 if (verbose) {
338 fprintf(stderr, "Unable to determine libc include path: %s\n", err_str(err));
339 }
340 return err;
341 }
342 return ErrorNone;
343}
344
345static Error zig_libc_find_native_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
346 bool verbose)
347{
348 Error err;
349 if ((err = os_get_win32_ucrt_lib_path(sdk, &self->crt_dir, target->arch))) {
350 if (verbose) {
351 fprintf(stderr, "Unable to determine ucrt path: %s\n", err_str(err));
352 }
353 return err;
354 }
355 return ErrorNone;
356}
357
358static Error zig_libc_find_kernel32_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
359 bool verbose)
360{
361 Error err;
362 if ((err = os_get_win32_kern32_path(sdk, &self->kernel32_lib_dir, target->arch))) {
363 if (verbose) {
364 fprintf(stderr, "Unable to determine kernel32 path: %s\n", err_str(err));
365 }
366 return err;
367 }
368 return ErrorNone;
369}
370
371static Error zig_libc_find_native_msvc_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
372 if (sdk->msvc_lib_dir_ptr == nullptr) {
373 if (verbose) {
374 fprintf(stderr, "Unable to determine vcruntime.lib path\n");
375 }
376 return ErrorFileNotFound;
377 }
378 buf_init_from_mem(&self->msvc_lib_dir, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
379 return ErrorNone;
380}
381
382static Error zig_libc_find_native_msvc_include_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
383 Error err;
384 if (sdk->msvc_lib_dir_ptr == nullptr) {
385 if (verbose) {
386 fprintf(stderr, "Unable to determine vcruntime.h path\n");
387 }
388 return ErrorFileNotFound;
389 }
390 Buf search_path = BUF_INIT;
391 buf_init_from_mem(&search_path, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
392 buf_append_str(&search_path, "..\\..\\include");
393
394 Buf *vcruntime_path = buf_sprintf("%s\\vcruntime.h", buf_ptr(&search_path));
395 bool exists;
396 if ((err = os_file_exists(vcruntime_path, &exists))) {
397 exists = false;
398 }
399 if (exists) {
400 self->sys_include_dir = search_path;
401 return ErrorNone;
402 }
403
404 if (verbose) {
405 fprintf(stderr, "Unable to determine vcruntime.h path\n");
406 }
407 return ErrorFileNotFound;
408}
409#endif
410
411void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
412 fprintf(file,
413 "# The directory that contains `stdlib.h`.\n"
414 "# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`\n"
415 "include_dir=%s\n"
416 "\n"
417 "# The system-specific include directory. May be the same as `include_dir`.\n"
418 "# On Windows it's the directory that includes `vcruntime.h`.\n"
419 "# On POSIX it's the directory that includes `sys/errno.h`.\n"
420 "sys_include_dir=%s\n"
421 "\n"
422 "# The directory that contains `crt1.o` or `crt2.o`.\n"
423 "# On POSIX, can be found with `cc -print-file-name=crt1.o`.\n"
424 "# Not needed when targeting MacOS.\n"
425 "crt_dir=%s\n"
426 "\n"
427 "# The directory that contains `crtbegin.o`.\n"
428 "# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.\n"
429 "# Not needed when targeting MacOS.\n"
430 "static_crt_dir=%s\n"
431 "\n"
432 "# The directory that contains `vcruntime.lib`.\n"
433 "# Only needed when targeting MSVC on Windows.\n"
434 "msvc_lib_dir=%s\n"
435 "\n"
436 "# The directory that contains `kernel32.lib`.\n"
437 "# Only needed when targeting MSVC on Windows.\n"
438 "kernel32_lib_dir=%s\n"
439 "\n",
440 buf_ptr(&self->include_dir),
441 buf_ptr(&self->sys_include_dir),
442 buf_ptr(&self->crt_dir),
443 buf_ptr(&self->static_crt_dir),
444 buf_ptr(&self->msvc_lib_dir),
445 buf_ptr(&self->kernel32_lib_dir)
446 );
447}
448
449Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
450 Error err;
451 zig_libc_init_empty(self);
452#if defined(ZIG_OS_WINDOWS)
453 ZigTarget native_target;
454 get_native_target(&native_target);
455 if (target_abi_is_gnu(native_target.abi)) {
456 if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
457 return err;
458 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
459 return err;
460 if ((err = zig_libc_find_native_static_crt_dir_posix(self, verbose)))
461 return err;
462 return ErrorNone;
463 } else {
464 ZigWindowsSDK *sdk;
465 switch (zig_find_windows_sdk(&sdk)) {
466 case ZigFindWindowsSdkErrorNone:
467 if ((err = zig_libc_find_native_msvc_include_dir(self, sdk, verbose)))
468 return err;
469 if ((err = zig_libc_find_native_msvc_lib_dir(self, sdk, verbose)))
470 return err;
471 if ((err = zig_libc_find_kernel32_lib_dir(self, sdk, &native_target, verbose)))
472 return err;
473 if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
474 return err;
475 if ((err = zig_libc_find_native_crt_dir_windows(self, sdk, &native_target, verbose)))
476 return err;
477 return ErrorNone;
478 case ZigFindWindowsSdkErrorOutOfMemory:
479 return ErrorNoMem;
480 case ZigFindWindowsSdkErrorNotFound:
481 return ErrorFileNotFound;
482 case ZigFindWindowsSdkErrorPathTooLong:
483 return ErrorPathTooLong;
484 }
485 }
486 zig_unreachable();
487#else
488 if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
489 return err;
490#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD)
491 buf_init_from_str(&self->crt_dir, "/usr/lib");
492#elif defined(ZIG_OS_LINUX) || defined(ZIG_OS_DRAGONFLY)
493 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
494 return err;
495#endif
496 return ErrorNone;
497#endif
498}
src/libc_installation.hpp deleted-35
......@@ -1,35 +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_LIBC_INSTALLATION_HPP
9#define ZIG_LIBC_INSTALLATION_HPP
10
11#include <stdio.h>
12
13#include "buffer.hpp"
14#include "error.hpp"
15#include "target.hpp"
16
17// Must be synchronized with zig_libc_keys
18struct ZigLibCInstallation {
19 Buf include_dir;
20 Buf sys_include_dir;
21 Buf crt_dir;
22 Buf static_crt_dir;
23 Buf msvc_lib_dir;
24 Buf kernel32_lib_dir;
25};
26
27Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file,
28 const ZigTarget *target, bool verbose);
29void zig_libc_render(ZigLibCInstallation *self, FILE *file);
30
31Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
32
33Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose);
34
35#endif
src/link.cpp+26-26
......@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil
605605 c_source_files.append(c_file);
606606 child_gen->c_source_files = c_source_files;
607607 codegen_build_and_link(child_gen);
608 return buf_ptr(&child_gen->output_file_path);
608 return buf_ptr(&child_gen->bin_file_output_path);
609609}
610610
611611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
......@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
682682 }
683683 child_gen->c_source_files = c_source_files;
684684 codegen_build_and_link(child_gen);
685 return buf_ptr(&child_gen->output_file_path);
685 return buf_ptr(&child_gen->bin_file_output_path);
686686}
687687
688688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
......@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
11231123
11241124 child_gen->c_source_files = c_source_files;
11251125 codegen_build_and_link(child_gen);
1126 return buf_ptr(&child_gen->output_file_path);
1126 return buf_ptr(&child_gen->bin_file_output_path);
11271127}
11281128
11291129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
......@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
12531253 child_gen->c_source_files.append(c_file);
12541254 }
12551255 codegen_build_and_link(child_gen);
1256 return buf_ptr(&child_gen->output_file_path);
1256 return buf_ptr(&child_gen->bin_file_output_path);
12571257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {
12581258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);
12591259
......@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
12701270 }
12711271 }
12721272 codegen_build_and_link(child_gen);
1273 return buf_ptr(&child_gen->output_file_path);
1273 return buf_ptr(&child_gen->bin_file_output_path);
12741274 } else if (strcmp(file, "mingwex.lib") == 0) {
12751275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);
12761276
......@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
12951295 zig_unreachable();
12961296 }
12971297 codegen_build_and_link(child_gen);
1298 return buf_ptr(&child_gen->output_file_path);
1298 return buf_ptr(&child_gen->bin_file_output_path);
12991299 } else {
13001300 zig_unreachable();
13011301 }
......@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
13651365 codegen_add_object(child_gen, buf_create_from_str(start_os));
13661366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
13671367 codegen_build_and_link(child_gen);
1368 return buf_ptr(&child_gen->output_file_path);
1368 return buf_ptr(&child_gen->bin_file_output_path);
13691369 } else if (strcmp(file, "libc_nonshared.a") == 0) {
13701370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
13711371 {
......@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
14451445 build_libc_object(parent, deps[i].name, c_file, progress_node)));
14461446 }
14471447 codegen_build_and_link(child_gen);
1448 return buf_ptr(&child_gen->output_file_path);
1448 return buf_ptr(&child_gen->bin_file_output_path);
14491449 } else {
14501450 zig_unreachable();
14511451 }
......@@ -1483,7 +1483,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
14831483 } else {
14841484 assert(parent->libc != nullptr);
14851485 Buf *out_buf = buf_alloc();
1486 os_path_join(&parent->libc->crt_dir, buf_create_from_str(file), out_buf);
1486 os_path_join(buf_create_from_str(parent->libc->crt_dir), buf_create_from_str(file), out_buf);
14871487 return buf_ptr(out_buf);
14881488 }
14891489}
......@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
15191519 child_gen->want_stack_check = WantStackCheckDisabled;
15201520
15211521 codegen_build_and_link(child_gen);
1522 return &child_gen->output_file_path;
1522 return &child_gen->bin_file_output_path;
15231523}
15241524
15251525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
......@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
16811681 } else if (is_dyn_lib) {
16821682 lj->args.append("-shared");
16831683
1684 assert(buf_len(&g->output_file_path) != 0);
1684 assert(buf_len(&g->bin_file_output_path) != 0);
16851685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
16861686 }
16871687
......@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
16901690 }
16911691
16921692 lj->args.append("-o");
1693 lj->args.append(buf_ptr(&g->output_file_path));
1693 lj->args.append(buf_ptr(&g->bin_file_output_path));
16941694
16951695 if (lj->link_in_crt) {
16961696 const char *crt1o;
......@@ -1747,7 +1747,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
17471747 if (g->libc_link_lib != nullptr) {
17481748 if (g->libc != nullptr) {
17491749 lj->args.append("-L");
1750 lj->args.append(buf_ptr(&g->libc->crt_dir));
1750 lj->args.append(g->libc->crt_dir);
17511751 }
17521752
17531753 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
......@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
18721872 }
18731873 lj->args.append("--allow-undefined");
18741874 lj->args.append("-o");
1875 lj->args.append(buf_ptr(&g->output_file_path));
1875 lj->args.append(buf_ptr(&g->bin_file_output_path));
18761876
18771877 // .o files
18781878 for (size_t i = 0; i < g->link_objects.length; i += 1) {
......@@ -2253,17 +2253,17 @@ static void construct_linker_job_coff(LinkJob *lj) {
22532253 lj->args.append("-DLL");
22542254 }
22552255
2256 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
2256 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
22572257
22582258 if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2259 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
2259 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
22602260
22612261 if (target_abi_is_gnu(g->zig_target->abi)) {
2262 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));
2263 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));
2262 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
2263 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
22642264 } else {
2265 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
2266 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
2265 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
2266 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
22672267 }
22682268 }
22692269
......@@ -2506,7 +2506,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
25062506 //lj->args.append("-install_name");
25072507 //lj->args.append(buf_ptr(dylib_install_name));
25082508
2509 assert(buf_len(&g->output_file_path) != 0);
2509 assert(buf_len(&g->bin_file_output_path) != 0);
25102510 }
25112511
25122512 lj->args.append("-arch");
......@@ -2537,14 +2537,14 @@ static void construct_linker_job_macho(LinkJob *lj) {
25372537 }
25382538
25392539 lj->args.append("-o");
2540 lj->args.append(buf_ptr(&g->output_file_path));
2540 lj->args.append(buf_ptr(&g->bin_file_output_path));
25412541
25422542 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
25432543 Buf *rpath = g->rpath_list.at(i);
25442544 add_rpath(lj, rpath);
25452545 }
25462546 if (is_dyn_lib) {
2547 add_rpath(lj, &g->output_file_path);
2547 add_rpath(lj, &g->bin_file_output_path);
25482548 }
25492549
25502550 if (is_dyn_lib) {
......@@ -2664,14 +2664,14 @@ void codegen_link(CodeGen *g) {
26642664 progress_name, strlen(progress_name), 0));
26652665 }
26662666 if (g->verbose_link) {
2667 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
2667 fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path));
26682668 for (size_t i = 0; i < file_names.length; i += 1) {
26692669 fprintf(stderr, " %s", file_names.at(i));
26702670 }
26712671 fprintf(stderr, "\n");
26722672 }
2673 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {
2674 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));
2673 if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) {
2674 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path));
26752675 exit(1);
26762676 }
26772677 return;
src/main.cpp+151-88
......@@ -14,8 +14,7 @@
1414#include "heap.hpp"
1515#include "os.hpp"
1616#include "target.hpp"
17#include "libc_installation.hpp"
18#include "userland.h"
17#include "stage2.h"
1918#include "glibc.hpp"
2019#include "dump_analysis.hpp"
2120#include "mem_profile.hpp"
......@@ -63,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
6362 " -fno-stack-check disable stack probing in safe builds\n"
6463 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"
6564 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"
66 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
65 " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n"
6766 " -fPIC enable Position Independent Code\n"
6867 " -fno-PIC disable Position Independent Code\n"
6968 " -ftime-report print timing diagnostics\n"
7069 " -fstack-report print stack size diagnostics\n"
71#ifdef ZIG_ENABLE_MEM_PROFILE
7270 " -fmem-report print memory usage diagnostics\n"
73#endif
7471 " -fdump-analysis write analysis.json file with type information\n"
7572 " -femit-docs create a docs/ dir with html documentation\n"
76 " -fno-emit-bin skip emitting machine code\n"
73 " -fno-emit-docs do not produce docs/ dir with html documentation\n"
74 " -femit-bin (default) output machine code\n"
75 " -fno-emit-bin do not output machine code\n"
76 " -femit-asm output .s (assembly code)\n"
77 " -fno-emit-asm (default) do not output .s (assembly code)\n"
78 " -femit-llvm-ir produce a .ll file with LLVM IR\n"
79 " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
7780 " --libc [file] Provide a file which specifies libc paths\n"
7881 " --name [name] override output name\n"
7982 " --output-dir [dir] override output directory (defaults to cwd)\n"
......@@ -103,8 +106,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
103106 " --override-lib-dir [arg] override path to Zig lib directory\n"
104107 " -ffunction-sections places each function in a separate section\n"
105108 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
106 " -target-cpu [cpu] target one specific CPU by name\n"
107 " -target-feature [features] specify the set of CPU features to target\n"
109 " -mcpu [cpu] specify target CPU and feature set\n"
108110 " -code-model [default|tiny| set target code model\n"
109111 " small|kernel|\n"
110112 " medium|large]\n"
......@@ -235,6 +237,14 @@ static int zig_error_no_build_file(void) {
235237 return EXIT_FAILURE;
236238}
237239
240static bool str_starts_with(const char *s1, const char *s2) {
241 size_t s2_len = strlen(s2);
242 if (strlen(s1) < s2_len) {
243 return false;
244 }
245 return memcmp(s1, s2, s2_len) == 0;
246}
247
238248extern "C" int ZigClang_main(int argc, char **argv);
239249
240250#ifdef ZIG_ENABLE_MEM_PROFILE
......@@ -378,7 +388,6 @@ static int main0(int argc, char **argv) {
378388 }
379389
380390 Cmd cmd = CmdNone;
381 EmitFileType emit_file_type = EmitFileTypeBinary;
382391 const char *in_file = nullptr;
383392 Buf *output_dir = nullptr;
384393 bool strip = false;
......@@ -426,7 +435,9 @@ static int main0(int argc, char **argv) {
426435 bool stack_report = false;
427436 bool enable_dump_analysis = false;
428437 bool enable_doc_generation = false;
429 bool disable_bin_generation = false;
438 bool emit_bin = true;
439 bool emit_asm = false;
440 bool emit_llvm_ir = false;
430441 const char *cache_dir = nullptr;
431442 CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();
432443 BuildMode build_mode = BuildModeDebug;
......@@ -444,8 +455,7 @@ static int main0(int argc, char **argv) {
444455 WantStackCheck want_stack_check = WantStackCheckAuto;
445456 WantCSanitize want_sanitize_c = WantCSanitizeAuto;
446457 bool function_sections = false;
447 const char *cpu = nullptr;
448 const char *features = nullptr;
458 const char *mcpu = nullptr;
449459 CodeModel code_model = CodeModelDefault;
450460
451461 ZigList<const char *> llvm_argv = {0};
......@@ -554,7 +564,7 @@ static int main0(int argc, char **argv) {
554564 }
555565
556566 Termination term;
557 args.items[0] = buf_ptr(&g->output_file_path);
567 args.items[0] = buf_ptr(&g->bin_file_output_path);
558568 os_spawn_process(args, &term);
559569 if (term.how != TerminationIdClean || term.code != 0) {
560570 fprintf(stderr, "\nBuild failed. The following command failed:\n");
......@@ -633,8 +643,6 @@ static int main0(int argc, char **argv) {
633643 enable_dump_analysis = true;
634644 } else if (strcmp(arg, "-femit-docs") == 0) {
635645 enable_doc_generation = true;
636 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
637 disable_bin_generation = true;
638646 } else if (strcmp(arg, "--enable-valgrind") == 0) {
639647 valgrind_support = ValgrindSupportEnabled;
640648 } else if (strcmp(arg, "--disable-valgrind") == 0) {
......@@ -703,6 +711,20 @@ static int main0(int argc, char **argv) {
703711 function_sections = true;
704712 } else if (strcmp(arg, "--test-evented-io") == 0) {
705713 test_evented_io = true;
714 } else if (strcmp(arg, "-femit-bin") == 0) {
715 emit_bin = true;
716 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
717 emit_bin = false;
718 } else if (strcmp(arg, "-femit-asm") == 0) {
719 emit_asm = true;
720 } else if (strcmp(arg, "-fno-emit-asm") == 0) {
721 emit_asm = false;
722 } else if (strcmp(arg, "-femit-llvm-ir") == 0) {
723 emit_llvm_ir = true;
724 } else if (strcmp(arg, "-fno-emit-llvm-ir") == 0) {
725 emit_llvm_ir = false;
726 } else if (str_starts_with(arg, "-mcpu=")) {
727 mcpu = arg + strlen("-mcpu=");
706728 } else if (i + 1 >= argc) {
707729 fprintf(stderr, "Expected another argument after %s\n", arg);
708730 return print_error_usage(arg0);
......@@ -734,11 +756,13 @@ static int main0(int argc, char **argv) {
734756 }
735757 } else if (strcmp(arg, "--emit") == 0) {
736758 if (strcmp(argv[i], "asm") == 0) {
737 emit_file_type = EmitFileTypeAssembly;
759 emit_asm = true;
760 emit_bin = false;
738761 } else if (strcmp(argv[i], "bin") == 0) {
739 emit_file_type = EmitFileTypeBinary;
762 emit_bin = true;
740763 } else if (strcmp(argv[i], "llvm-ir") == 0) {
741 emit_file_type = EmitFileTypeLLVMIr;
764 emit_llvm_ir = true;
765 emit_bin = false;
742766 } else {
743767 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
744768 return print_error_usage(arg0);
......@@ -877,10 +901,8 @@ static int main0(int argc, char **argv) {
877901 , argv[i]);
878902 return EXIT_FAILURE;
879903 }
880 } else if (strcmp(arg, "-target-cpu") == 0) {
881 cpu = argv[i];
882 } else if (strcmp(arg, "-target-feature") == 0) {
883 features = argv[i];
904 } else if (strcmp(arg, "-mcpu") == 0) {
905 mcpu = argv[i];
884906 } else {
885907 fprintf(stderr, "Invalid argument: %s\n", arg);
886908 return print_error_usage(arg0);
......@@ -956,58 +978,54 @@ static int main0(int argc, char **argv) {
956978 init_all_targets();
957979
958980 ZigTarget target;
959 if (target_string == nullptr) {
960 get_native_target(&target);
981 if ((err = target_parse_triple(&target, target_string, mcpu))) {
982 fprintf(stderr, "invalid target: %s\n"
983 "See `%s targets` to display valid targets.\n", err_str(err), arg0);
984 return print_error_usage(arg0);
985 }
986 if (target_is_glibc(&target)) {
987 target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
988
961989 if (target_glibc != nullptr) {
962 fprintf(stderr, "-target-glibc provided but no -target parameter\n");
963 return print_error_usage(arg0);
964 }
965 } else {
966 if ((err = target_parse_triple(&target, target_string))) {
967 if (err == ErrorUnknownArchitecture && target.arch != ZigLLVM_UnknownArch) {
968 fprintf(stderr, "'%s' requires a sub-architecture. Try one of these:\n",
969 target_arch_name(target.arch));
970 SubArchList sub_arch_list = target_subarch_list(target.arch);
971 size_t subarch_count = target_subarch_count(sub_arch_list);
972 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
973 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
974 fprintf(stderr, " %s%s\n", target_arch_name(target.arch), target_subarch_name(sub));
975 }
976 return print_error_usage(arg0);
977 } else {
978 fprintf(stderr, "invalid target: %s\n", err_str(err));
990 if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {
991 fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err));
979992 return print_error_usage(arg0);
980993 }
981 }
982 if (target_is_glibc(&target)) {
983 target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
984
985 if (target_glibc != nullptr) {
986 if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {
987 fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err));
988 return print_error_usage(arg0);
994 } else {
995 target_init_default_glibc_version(&target);
996#if defined(ZIG_OS_LINUX)
997 if (target.is_native) {
998 // TODO self-host glibc version detection, and then this logic can go away
999 if ((err = glibc_detect_native_version(target.glibc_version))) {
1000 // Fall back to the default version.
9891001 }
990 } else {
991 target_init_default_glibc_version(&target);
9921002 }
993 } else if (target_glibc != nullptr) {
994 fprintf(stderr, "'%s' is not a glibc-compatible target", target_string);
995 return print_error_usage(arg0);
1003#endif
9961004 }
1005 } else if (target_glibc != nullptr) {
1006 fprintf(stderr, "'%s' is not a glibc-compatible target", target_string);
1007 return print_error_usage(arg0);
9971008 }
9981009
9991010 Buf zig_triple_buf = BUF_INIT;
10001011 target_triple_zig(&zig_triple_buf, &target);
10011012
1002 const char *stage2_triple_arg = target.is_native ? nullptr : buf_ptr(&zig_triple_buf);
1003 if ((err = stage2_cpu_features_parse(&target.cpu_features, stage2_triple_arg, cpu, features))) {
1004 fprintf(stderr, "unable to initialize CPU features: %s\n", err_str(err));
1005 return main_exit(root_progress_node, EXIT_FAILURE);
1006 }
1007
1013 // If both output_dir and enable_cache are provided, and doing build-lib, we
1014 // will just do a file copy at the end. This helps when bootstrapping zig from zig0
1015 // because we want to pass something like this:
1016 // zig0 build-lib --cache on --output-dir ${CMAKE_BINARY_DIR}
1017 // And we don't have access to `zig0 build` because that would require detecting native libc
1018 // on systems where we are not able to build a libc from source for them.
1019 // But that's the only reason this works, so otherwise we give an error here.
1020 Buf *final_output_dir_step = nullptr;
10081021 if (output_dir != nullptr && enable_cache == CacheOptOn) {
1009 fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");
1010 return print_error_usage(arg0);
1022 if (cmd == CmdBuild && out_type == OutTypeLib) {
1023 final_output_dir_step = output_dir;
1024 output_dir = nullptr;
1025 } else {
1026 fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");
1027 return print_error_usage(arg0);
1028 }
10111029 }
10121030
10131031 if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) {
......@@ -1015,8 +1033,8 @@ static int main0(int argc, char **argv) {
10151033 return print_error_usage(arg0);
10161034 }
10171035
1018 if (emit_file_type != EmitFileTypeBinary && in_file == nullptr) {
1019 fprintf(stderr, "A root source file is required when using `--emit asm` or `--emit llvm-ir`\n");
1036 if ((emit_asm || emit_llvm_ir) && in_file == nullptr) {
1037 fprintf(stderr, "A root source file is required when using `-femit-asm` or `-femit-llvm-ir`\n");
10201038 return print_error_usage(arg0);
10211039 }
10221040
......@@ -1028,15 +1046,22 @@ static int main0(int argc, char **argv) {
10281046 switch (cmd) {
10291047 case CmdLibC: {
10301048 if (in_file) {
1031 ZigLibCInstallation libc;
1032 if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))
1049 Stage2LibCInstallation libc;
1050 if ((err = stage2_libc_parse(&libc, in_file))) {
1051 fprintf(stderr, "unable to parse libc file: %s\n", err_str(err));
10331052 return main_exit(root_progress_node, EXIT_FAILURE);
1053 }
10341054 return main_exit(root_progress_node, EXIT_SUCCESS);
10351055 }
1036 ZigLibCInstallation libc;
1037 if ((err = zig_libc_find_native(&libc, true)))
1056 Stage2LibCInstallation libc;
1057 if ((err = stage2_libc_find_native(&libc))) {
1058 fprintf(stderr, "unable to find native libc file: %s\n", err_str(err));
10381059 return main_exit(root_progress_node, EXIT_FAILURE);
1039 zig_libc_render(&libc, stdout);
1060 }
1061 if ((err = stage2_libc_render(&libc, stdout))) {
1062 fprintf(stderr, "unable to print libc file: %s\n", err_str(err));
1063 return main_exit(root_progress_node, EXIT_FAILURE);
1064 }
10401065 return main_exit(root_progress_node, EXIT_SUCCESS);
10411066 }
10421067 case CmdBuiltin: {
......@@ -1080,11 +1105,38 @@ static int main0(int argc, char **argv) {
10801105 {
10811106 fprintf(stderr, "Expected source file argument.\n");
10821107 return print_error_usage(arg0);
1083 } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) {
1084 fprintf(stderr, "Cannot run non-executable file.\n");
1108 } else if (cmd == CmdRun && !emit_bin) {
1109 fprintf(stderr, "Cannot run without emitting a binary file.\n");
10851110 return print_error_usage(arg0);
10861111 }
10871112
1113 if (target.is_native && link_libs.length != 0) {
1114 Error err;
1115 Stage2NativePaths paths;
1116 if ((err = stage2_detect_native_paths(&paths))) {
1117 fprintf(stderr, "unable to detect native system paths: %s\n", err_str(err));
1118 exit(1);
1119 }
1120 for (size_t i = 0; i < paths.warnings_len; i += 1) {
1121 const char *warning = paths.warnings_ptr[i];
1122 fprintf(stderr, "warning: %s\n", warning);
1123 }
1124 for (size_t i = 0; i < paths.include_dirs_len; i += 1) {
1125 const char *include_dir = paths.include_dirs_ptr[i];
1126 clang_argv.append("-I");
1127 clang_argv.append(include_dir);
1128 }
1129 for (size_t i = 0; i < paths.lib_dirs_len; i += 1) {
1130 const char *lib_dir = paths.lib_dirs_ptr[i];
1131 lib_dirs.append(lib_dir);
1132 }
1133 for (size_t i = 0; i < paths.rpaths_len; i += 1) {
1134 const char *rpath = paths.rpaths_ptr[i];
1135 rpath_list.append(rpath);
1136 }
1137 }
1138
1139
10881140 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
10891141
10901142 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
......@@ -1126,10 +1178,10 @@ static int main0(int argc, char **argv) {
11261178 if (cmd == CmdRun && buf_out_name == nullptr) {
11271179 buf_out_name = buf_create_from_str("run");
11281180 }
1129 ZigLibCInstallation *libc = nullptr;
1181 Stage2LibCInstallation *libc = nullptr;
11301182 if (libc_txt != nullptr) {
1131 libc = heap::c_allocator.create<ZigLibCInstallation>();
1132 if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {
1183 libc = heap::c_allocator.create<Stage2LibCInstallation>();
1184 if ((err = stage2_libc_parse(libc, libc_txt))) {
11331185 fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
11341186 return main_exit(root_progress_node, EXIT_FAILURE);
11351187 }
......@@ -1158,7 +1210,10 @@ static int main0(int argc, char **argv) {
11581210 g->enable_stack_report = stack_report;
11591211 g->enable_dump_analysis = enable_dump_analysis;
11601212 g->enable_doc_generation = enable_doc_generation;
1161 g->disable_bin_generation = disable_bin_generation;
1213 g->emit_bin = emit_bin;
1214 g->emit_asm = emit_asm;
1215 g->emit_llvm_ir = emit_llvm_ir;
1216
11621217 codegen_set_out_name(g, buf_out_name);
11631218 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
11641219 g->want_single_threaded = want_single_threaded;
......@@ -1188,7 +1243,6 @@ static int main0(int argc, char **argv) {
11881243 g->function_sections = function_sections;
11891244 g->code_model = code_model;
11901245
1191
11921246 for (size_t i = 0; i < lib_dirs.length; i += 1) {
11931247 codegen_add_lib_dir(g, lib_dirs.at(i));
11941248 }
......@@ -1244,8 +1298,6 @@ static int main0(int argc, char **argv) {
12441298
12451299
12461300 if (cmd == CmdBuild || cmd == CmdRun) {
1247 codegen_set_emit_file_type(g, emit_file_type);
1248
12491301 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
12501302 codegen_build_and_link(g);
12511303 if (root_progress_node != nullptr) {
......@@ -1263,7 +1315,7 @@ static int main0(int argc, char **argv) {
12631315 mem::print_report();
12641316#endif
12651317
1266 const char *exec_path = buf_ptr(&g->output_file_path);
1318 const char *exec_path = buf_ptr(&g->bin_file_output_path);
12671319 ZigList<const char*> args = {0};
12681320
12691321 args.append(exec_path);
......@@ -1283,10 +1335,23 @@ static int main0(int argc, char **argv) {
12831335 } else if (cmd == CmdBuild) {
12841336 if (g->enable_cache) {
12851337#if defined(ZIG_OS_WINDOWS)
1286 buf_replace(&g->output_file_path, '/', '\\');
1338 buf_replace(&g->bin_file_output_path, '/', '\\');
12871339#endif
1288 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)
1289 return main_exit(root_progress_node, EXIT_FAILURE);
1340 if (final_output_dir_step != nullptr) {
1341 Buf *dest_basename = buf_alloc();
1342 os_path_split(&g->bin_file_output_path, nullptr, dest_basename);
1343 Buf *dest_path = buf_alloc();
1344 os_path_join(final_output_dir_step, dest_basename, dest_path);
1345
1346 if ((err = os_update_file(&g->bin_file_output_path, dest_path))) {
1347 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path),
1348 buf_ptr(dest_path), err_str(err));
1349 return main_exit(root_progress_node, EXIT_FAILURE);
1350 }
1351 } else {
1352 if (printf("%s\n", buf_ptr(&g->bin_file_output_path)) < 0)
1353 return main_exit(root_progress_node, EXIT_FAILURE);
1354 }
12901355 }
12911356 return main_exit(root_progress_node, EXIT_SUCCESS);
12921357 } else {
......@@ -1299,8 +1364,6 @@ static int main0(int argc, char **argv) {
12991364 codegen_print_timing_report(g, stderr);
13001365 return main_exit(root_progress_node, EXIT_SUCCESS);
13011366 } else if (cmd == CmdTest) {
1302 codegen_set_emit_file_type(g, emit_file_type);
1303
13041367 ZigTarget native;
13051368 get_native_target(&native);
13061369
......@@ -1319,17 +1382,17 @@ static int main0(int argc, char **argv) {
13191382 zig_print_stack_report(g, stdout);
13201383 }
13211384
1322 if (g->disable_bin_generation) {
1385 if (!g->emit_bin) {
13231386 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");
13241387 return main_exit(root_progress_node, EXIT_SUCCESS);
13251388 }
13261389
1327 Buf *test_exe_path_unresolved = &g->output_file_path;
1390 Buf *test_exe_path_unresolved = &g->bin_file_output_path;
13281391 Buf *test_exe_path = buf_alloc();
13291392 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
13301393
1331 if (emit_file_type != EmitFileTypeBinary) {
1332 fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",
1394 if (!g->emit_bin) {
1395 fprintf(stderr, "Created %s but skipping execution because no binary generated.\n",
13331396 buf_ptr(test_exe_path));
13341397 return main_exit(root_progress_node, EXIT_SUCCESS);
13351398 }
src/mem_list.hpp+9-6
......@@ -14,11 +14,14 @@ namespace mem {
1414
1515template<typename T>
1616struct List {
17 void deinit(Allocator& allocator) {
18 allocator.deallocate<T>(items, capacity);
17 void deinit(Allocator *allocator) {
18 allocator->deallocate<T>(items, capacity);
19 items = nullptr;
20 length = 0;
21 capacity = 0;
1922 }
2023
21 void append(Allocator& allocator, const T& item) {
24 void append(Allocator *allocator, const T& item) {
2225 ensure_capacity(allocator, length + 1);
2326 items[length++] = item;
2427 }
......@@ -57,7 +60,7 @@ struct List {
5760 return items[length - 1];
5861 }
5962
60 void resize(Allocator& allocator, size_t new_length) {
63 void resize(Allocator *allocator, size_t new_length) {
6164 assert(new_length != SIZE_MAX);
6265 ensure_capacity(allocator, new_length);
6366 length = new_length;
......@@ -67,7 +70,7 @@ struct List {
6770 length = 0;
6871 }
6972
70 void ensure_capacity(Allocator& allocator, size_t new_capacity) {
73 void ensure_capacity(Allocator *allocator, size_t new_capacity) {
7174 if (capacity >= new_capacity)
7275 return;
7376
......@@ -76,7 +79,7 @@ struct List {
7679 better_capacity = better_capacity * 5 / 2 + 8;
7780 } while (better_capacity < new_capacity);
7881
79 items = allocator.reallocate_nonzero<T>(items, capacity, better_capacity);
82 items = allocator->reallocate_nonzero<T>(items, capacity, better_capacity);
8083 capacity = better_capacity;
8184 }
8285
src/mem_profile.cpp+2-2
......@@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) {
9292 auto entry = it.next();
9393 if (!entry)
9494 break;
95 list.append(heap::bootstrap_allocator, &entry->value);
95 list.append(&heap::bootstrap_allocator, &entry->value);
9696 }
9797
9898 qsort(list.items, list.length, sizeof(const Entry *), entry_compare);
......@@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) {
143143 fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n",
144144 total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc));
145145
146 list.deinit(heap::bootstrap_allocator);
146 list.deinit(&heap::bootstrap_allocator);
147147}
148148
149149uint32_t Profile::usage_hash(UsageKey key) {
src/os.cpp+155-162
......@@ -81,11 +81,7 @@ static clock_serv_t macos_monotonic_clock;
8181#include <errno.h>
8282#include <time.h>
8383
84// Apple doesn't provide the environ global variable
85#if defined(__APPLE__) && !defined(environ)
86#include <crt_externs.h>
87#define environ (*_NSGetEnviron())
88#elif defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY)
84#if !defined(environ)
8985extern char **environ;
9086#endif
9187
......@@ -826,7 +822,9 @@ static Error os_exec_process_posix(ZigList<const char *> &args,
826822 if (errno == ENOENT) {
827823 report_err = ErrorFileNotFound;
828824 }
829 write(err_pipe[1], &report_err, sizeof(Error));
825 if (write(err_pipe[1], &report_err, sizeof(Error)) == -1) {
826 zig_panic("write failed");
827 }
830828 exit(1);
831829 } else {
832830 // parent
......@@ -851,9 +849,13 @@ static Error os_exec_process_posix(ZigList<const char *> &args,
851849 if (err2) return err2;
852850
853851 Error child_err = ErrorNone;
854 write(err_pipe[1], &child_err, sizeof(Error));
852 if (write(err_pipe[1], &child_err, sizeof(Error)) == -1) {
853 zig_panic("write failed");
854 }
855855 close(err_pipe[1]);
856 read(err_pipe[0], &child_err, sizeof(Error));
856 if (read(err_pipe[0], &child_err, sizeof(Error)) == -1) {
857 zig_panic("write failed");
858 }
857859 close(err_pipe[0]);
858860 return child_err;
859861 }
......@@ -1029,6 +1031,124 @@ Error os_write_file(Buf *full_path, Buf *contents) {
10291031 return ErrorNone;
10301032}
10311033
1034static Error copy_open_files(FILE *src_f, FILE *dest_f) {
1035 static const size_t buf_size = 2048;
1036 char buf[buf_size];
1037 for (;;) {
1038 size_t amt_read = fread(buf, 1, buf_size, src_f);
1039 if (amt_read != buf_size) {
1040 if (ferror(src_f)) {
1041 return ErrorFileSystem;
1042 }
1043 }
1044 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1045 if (amt_written != amt_read) {
1046 return ErrorFileSystem;
1047 }
1048 if (feof(src_f)) {
1049 return ErrorNone;
1050 }
1051 }
1052}
1053
1054#if defined(ZIG_OS_WINDOWS)
1055static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1056 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1057 mtime->nsec = 0;
1058}
1059static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
1060 FILETIME result;
1061 result.dwHighDateTime = mtime.sec >> 32;
1062 result.dwLowDateTime = mtime.sec;
1063 return result;
1064}
1065#endif
1066
1067static Error set_file_times(OsFile file, OsTimeStamp ts) {
1068#if defined(ZIG_OS_WINDOWS)
1069 FILETIME ft = windows_os_timestamp_to_filetime(ts);
1070 if (SetFileTime(file, nullptr, &ft, &ft) == 0) {
1071 return ErrorUnexpected;
1072 }
1073 return ErrorNone;
1074#else
1075 struct timespec times[2] = {
1076 { ts.sec, ts.nsec },
1077 { ts.sec, ts.nsec },
1078 };
1079 if (futimens(file, times) == -1) {
1080 switch (errno) {
1081 case EBADF:
1082 zig_panic("futimens EBADF");
1083 default:
1084 return ErrorUnexpected;
1085 }
1086 }
1087 return ErrorNone;
1088#endif
1089}
1090
1091Error os_update_file(Buf *src_path, Buf *dst_path) {
1092 Error err;
1093
1094 OsFile src_file;
1095 OsFileAttr src_attr;
1096 if ((err = os_file_open_r(src_path, &src_file, &src_attr))) {
1097 return err;
1098 }
1099
1100 OsFile dst_file;
1101 OsFileAttr dst_attr;
1102 if ((err = os_file_open_w(dst_path, &dst_file, &dst_attr, src_attr.mode))) {
1103 os_file_close(&src_file);
1104 return err;
1105 }
1106
1107 if (src_attr.size == dst_attr.size &&
1108 src_attr.mode == dst_attr.mode &&
1109 src_attr.mtime.sec == dst_attr.mtime.sec &&
1110 src_attr.mtime.nsec == dst_attr.mtime.nsec)
1111 {
1112 os_file_close(&src_file);
1113 os_file_close(&dst_file);
1114 return ErrorNone;
1115 }
1116#if defined(ZIG_OS_WINDOWS)
1117 if (SetEndOfFile(dst_file) == 0) {
1118 return ErrorUnexpected;
1119 }
1120#else
1121 if (ftruncate(dst_file, 0) == -1) {
1122 return ErrorUnexpected;
1123 }
1124#endif
1125#if defined(ZIG_OS_WINDOWS)
1126 FILE *src_libc_file = _fdopen(_open_osfhandle((intptr_t)src_file, _O_RDONLY), "rb");
1127 FILE *dst_libc_file = _fdopen(_open_osfhandle((intptr_t)dst_file, 0), "wb");
1128#else
1129 FILE *src_libc_file = fdopen(src_file, "rb");
1130 FILE *dst_libc_file = fdopen(dst_file, "wb");
1131#endif
1132 assert(src_libc_file);
1133 assert(dst_libc_file);
1134
1135 if ((err = copy_open_files(src_libc_file, dst_libc_file))) {
1136 fclose(src_libc_file);
1137 fclose(dst_libc_file);
1138 return err;
1139 }
1140 if (fflush(src_libc_file) == -1) {
1141 return ErrorUnexpected;
1142 }
1143 if (fflush(dst_libc_file) == -1) {
1144 return ErrorUnexpected;
1145 }
1146 err = set_file_times(dst_file, src_attr.mtime);
1147 fclose(src_libc_file);
1148 fclose(dst_libc_file);
1149 return err;
1150}
1151
10321152Error os_copy_file(Buf *src_path, Buf *dest_path) {
10331153 FILE *src_f = fopen(buf_ptr(src_path), "rb");
10341154 if (!src_f) {
......@@ -1055,30 +1175,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
10551175 return ErrorFileSystem;
10561176 }
10571177 }
1058
1059 static const size_t buf_size = 2048;
1060 char buf[buf_size];
1061 for (;;) {
1062 size_t amt_read = fread(buf, 1, buf_size, src_f);
1063 if (amt_read != buf_size) {
1064 if (ferror(src_f)) {
1065 fclose(src_f);
1066 fclose(dest_f);
1067 return ErrorFileSystem;
1068 }
1069 }
1070 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1071 if (amt_written != amt_read) {
1072 fclose(src_f);
1073 fclose(dest_f);
1074 return ErrorFileSystem;
1075 }
1076 if (feof(src_f)) {
1077 fclose(src_f);
1078 fclose(dest_f);
1079 return ErrorNone;
1080 }
1081 }
1178 Error err = copy_open_files(src_f, dest_f);
1179 fclose(src_f);
1180 fclose(dest_f);
1181 return err;
10821182}
10831183
10841184Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
......@@ -1218,13 +1318,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {
12181318 return ErrorNone;
12191319}
12201320
1221#if defined(ZIG_OS_WINDOWS)
1222static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1223 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1224 mtime->nsec = 0;
1225}
1226#endif
1227
12281321OsTimeStamp os_timestamp_calendar(void) {
12291322 OsTimeStamp result;
12301323#if defined(ZIG_OS_WINDOWS)
......@@ -1551,108 +1644,6 @@ void os_stderr_set_color(TermColor color) {
15511644#endif
15521645}
15531646
1554Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1555#if defined(ZIG_OS_WINDOWS)
1556 buf_resize(output_buf, 0);
1557 buf_appendf(output_buf, "%sLib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
1558 switch (platform_type) {
1559 case ZigLLVM_x86:
1560 buf_append_str(output_buf, "x86\\");
1561 break;
1562 case ZigLLVM_x86_64:
1563 buf_append_str(output_buf, "x64\\");
1564 break;
1565 case ZigLLVM_arm:
1566 buf_append_str(output_buf, "arm\\");
1567 break;
1568 default:
1569 zig_panic("Attempted to use vcruntime for non-supported platform.");
1570 }
1571 Buf* tmp_buf = buf_alloc();
1572 buf_init_from_buf(tmp_buf, output_buf);
1573 buf_append_str(tmp_buf, "ucrt.lib");
1574 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1575 return ErrorNone;
1576 }
1577 else {
1578 buf_resize(output_buf, 0);
1579 return ErrorFileNotFound;
1580 }
1581#else
1582 return ErrorFileNotFound;
1583#endif
1584}
1585
1586Error os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
1587#if defined(ZIG_OS_WINDOWS)
1588 buf_resize(output_buf, 0);
1589 buf_appendf(output_buf, "%sInclude\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
1590 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
1591 return ErrorNone;
1592 }
1593 else {
1594 buf_resize(output_buf, 0);
1595 return ErrorFileNotFound;
1596 }
1597#else
1598 return ErrorFileNotFound;
1599#endif
1600}
1601
1602Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1603#if defined(ZIG_OS_WINDOWS)
1604 {
1605 buf_resize(output_buf, 0);
1606 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr);
1607 switch (platform_type) {
1608 case ZigLLVM_x86:
1609 buf_append_str(output_buf, "x86\\");
1610 break;
1611 case ZigLLVM_x86_64:
1612 buf_append_str(output_buf, "x64\\");
1613 break;
1614 case ZigLLVM_arm:
1615 buf_append_str(output_buf, "arm\\");
1616 break;
1617 default:
1618 zig_panic("Attempted to use vcruntime for non-supported platform.");
1619 }
1620 Buf* tmp_buf = buf_alloc();
1621 buf_init_from_buf(tmp_buf, output_buf);
1622 buf_append_str(tmp_buf, "kernel32.lib");
1623 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1624 return ErrorNone;
1625 }
1626 }
1627 {
1628 buf_resize(output_buf, 0);
1629 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr);
1630 switch (platform_type) {
1631 case ZigLLVM_x86:
1632 buf_append_str(output_buf, "x86\\");
1633 break;
1634 case ZigLLVM_x86_64:
1635 buf_append_str(output_buf, "x64\\");
1636 break;
1637 case ZigLLVM_arm:
1638 buf_append_str(output_buf, "arm\\");
1639 break;
1640 default:
1641 zig_panic("Attempted to use vcruntime for non-supported platform.");
1642 }
1643 Buf* tmp_buf = buf_alloc();
1644 buf_init_from_buf(tmp_buf, output_buf);
1645 buf_append_str(tmp_buf, "kernel32.lib");
1646 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1647 return ErrorNone;
1648 }
1649 }
1650 return ErrorFileNotFound;
1651#else
1652 return ErrorFileNotFound;
1653#endif
1654}
1655
16561647#if defined(ZIG_OS_WINDOWS)
16571648// Ported from std/unicode.zig
16581649struct Utf16LeIterator {
......@@ -1835,10 +1826,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
18351826#endif
18361827}
18371828
1838Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1829Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) {
18391830#if defined(ZIG_OS_WINDOWS)
18401831 // TODO use CreateFileW
1841 HANDLE result = CreateFileA(buf_ptr(full_path), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
1832 HANDLE result = CreateFileA(buf_ptr(full_path),
1833 need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
1834 need_write ? 0 : FILE_SHARE_READ,
1835 nullptr,
1836 need_write ? OPEN_ALWAYS : OPEN_EXISTING,
1837 FILE_ATTRIBUTE_NORMAL, nullptr);
18421838
18431839 if (result == INVALID_HANDLE_VALUE) {
18441840 DWORD err = GetLastError();
......@@ -1871,12 +1867,15 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
18711867 }
18721868 windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);
18731869 attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
1870 attr->mode = 0;
1871 attr->size = (((uint64_t)file_info.nFileSizeHigh) << 32) | file_info.nFileSizeLow;
18741872 }
18751873
18761874 return ErrorNone;
18771875#else
18781876 for (;;) {
1879 int fd = open(buf_ptr(full_path), O_RDONLY|O_CLOEXEC);
1877 int fd = open(buf_ptr(full_path),
1878 need_write ? (O_RDWR|O_CLOEXEC|O_CREAT) : (O_RDONLY|O_CLOEXEC), mode);
18801879 if (fd == -1) {
18811880 switch (errno) {
18821881 case EINTR:
......@@ -1886,6 +1885,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
18861885 case EFAULT:
18871886 zig_unreachable();
18881887 case EACCES:
1888 case EPERM:
18891889 return ErrorAccess;
18901890 case EISDIR:
18911891 return ErrorIsDir;
......@@ -1915,12 +1915,22 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
19151915 attr->mtime.sec = statbuf.st_mtim.tv_sec;
19161916 attr->mtime.nsec = statbuf.st_mtim.tv_nsec;
19171917#endif
1918 attr->mode = statbuf.st_mode;
1919 attr->size = statbuf.st_size;
19181920 }
19191921 return ErrorNone;
19201922 }
19211923#endif
19221924}
19231925
1926Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1927 return os_file_open_rw(full_path, out_file, attr, false, 0);
1928}
1929
1930Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode) {
1931 return os_file_open_rw(full_path, out_file, attr, true, mode);
1932}
1933
19241934Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
19251935#if defined(ZIG_OS_WINDOWS)
19261936 for (;;) {
......@@ -1966,6 +1976,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
19661976 case EFAULT:
19671977 zig_unreachable();
19681978 case EACCES:
1979 case EPERM:
19691980 return ErrorAccess;
19701981 case EISDIR:
19711982 return ErrorIsDir;
......@@ -2114,21 +2125,3 @@ void os_file_close(OsFile *file) {
21142125 *file = -1;
21152126#endif
21162127}
2117
2118#ifdef ZIG_OS_LINUX
2119const char *possible_ld_names[] = {
2120#if defined(ZIG_ARCH_X86_64)
2121 "ld-linux-x86-64.so.2",
2122 "ld-musl-x86_64.so.1",
2123#elif defined(ZIG_ARCH_ARM64)
2124 "ld-linux-aarch64.so.1",
2125 "ld-musl-aarch64.so.1",
2126#elif defined(ZIG_ARCH_ARM)
2127 "ld-linux-armhf.so.3",
2128 "ld-musl-armhf.so.1",
2129 "ld-linux.so.3",
2130 "ld-musl-arm.so.1",
2131#endif
2132 NULL,
2133};
2134#endif
src/os.hpp+6-10
......@@ -43,10 +43,6 @@
4343#define ZIG_ARCH_UNKNOWN
4444#endif
4545
46#ifdef ZIG_OS_LINUX
47extern const char *possible_ld_names[];
48#endif
49
5046#if defined(ZIG_OS_WINDOWS)
5147#define ZIG_PRI_usize "I64u"
5248#define ZIG_PRI_i64 "I64d"
......@@ -93,13 +89,15 @@ struct Termination {
9389#endif
9490
9591struct OsTimeStamp {
96 uint64_t sec;
97 uint64_t nsec;
92 int64_t sec;
93 int64_t nsec;
9894};
9995
10096struct OsFileAttr {
10197 OsTimeStamp mtime;
98 uint64_t size;
10299 uint64_t inode;
100 uint32_t mode;
103101};
104102
105103int os_init(void);
......@@ -121,6 +119,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
121119Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
122120
123121Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);
122Error ATTRIBUTE_MUST_USE os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode);
124123Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
125124Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
126125Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
......@@ -129,6 +128,7 @@ void os_file_close(OsFile *file);
129128
130129Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
131130Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
131Error ATTRIBUTE_MUST_USE os_update_file(Buf *src_path, Buf *dest_path);
132132
133133Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
134134Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);
......@@ -152,10 +152,6 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);
152152
153153Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);
154154
155Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
156Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
157Error ATTRIBUTE_MUST_USE os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
158
159155Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);
160156
161157#endif
src/parser.cpp+7
......@@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
689689
690690 AstNode *res = fn_proto;
691691 if (body != nullptr) {
692 if (fn_proto->data.fn_proto.is_extern) {
693 ast_error(pc, first, "extern functions have no body");
694 }
692695 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);
693696 res->data.fn_def.fn_proto = fn_proto;
694697 res->data.fn_def.body = body;
......@@ -2596,10 +2599,14 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
25962599 return res;
25972600 }
25982601
2602 Token *noasync_token = eat_token_if(pc, TokenIdKeywordNoAsync);
25992603 Token *await = eat_token_if(pc, TokenIdKeywordAwait);
26002604 if (await != nullptr) {
26012605 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
2606 res->data.await_expr.noasync_token = noasync_token;
26022607 return res;
2608 } else if (noasync_token != nullptr) {
2609 put_back_token(pc);
26032610 }
26042611
26052612 return nullptr;
src/stage2.cpp created+208
......@@ -0,0 +1,208 @@
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 "target.hpp"
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12Error stage2_translate_c(struct Stage2Ast **out_ast,
13 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
14 const char **args_begin, const char **args_end, const char *resources_path)
15{
16 const char *msg = "stage0 called stage2_translate_c";
17 stage2_panic(msg, strlen(msg));
18}
19
20void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) {
21 const char *msg = "stage0 called stage2_free_clang_errors";
22 stage2_panic(msg, strlen(msg));
23}
24
25void stage2_zen(const char **ptr, size_t *len) {
26 const char *msg = "stage0 called stage2_zen";
27 stage2_panic(msg, strlen(msg));
28}
29
30void stage2_attach_segfault_handler(void) { }
31
32void stage2_panic(const char *ptr, size_t len) {
33 fwrite(ptr, 1, len, stderr);
34 fprintf(stderr, "\n");
35 fflush(stderr);
36 abort();
37}
38
39void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) {
40 const char *msg = "stage0 called stage2_render_ast";
41 stage2_panic(msg, strlen(msg));
42}
43
44int stage2_fmt(int argc, char **argv) {
45 const char *msg = "stage0 called stage2_fmt";
46 stage2_panic(msg, strlen(msg));
47}
48
49stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) {
50 const char *msg = "stage0 called stage2_DepTokenizer_init";
51 stage2_panic(msg, strlen(msg));
52}
53
54void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) {
55 const char *msg = "stage0 called stage2_DepTokenizer_deinit";
56 stage2_panic(msg, strlen(msg));
57}
58
59stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {
60 const char *msg = "stage0 called stage2_DepTokenizer_next";
61 stage2_panic(msg, strlen(msg));
62}
63
64
65struct Stage2Progress {
66 int trash;
67};
68
69struct Stage2ProgressNode {
70 int trash;
71};
72
73Stage2Progress *stage2_progress_create(void) {
74 return nullptr;
75}
76
77void stage2_progress_destroy(Stage2Progress *progress) {}
78
79Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
80 const char *name_ptr, size_t name_len, size_t estimated_total_items)
81{
82 return nullptr;
83}
84Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
85 const char *name_ptr, size_t name_len, size_t estimated_total_items)
86{
87 return nullptr;
88}
89void stage2_progress_end(Stage2ProgressNode *node) {}
90void stage2_progress_complete_one(Stage2ProgressNode *node) {}
91void stage2_progress_disable_tty(Stage2Progress *progress) {}
92void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
93
94Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) {
95 Error err;
96
97 if (zig_triple == nullptr) {
98 get_native_target(target);
99
100 if (mcpu == nullptr) {
101 target->llvm_cpu_name = ZigLLVMGetHostCPUName();
102 target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
103 target->builtin_str = "Target.Cpu.baseline(arch);\n";
104 target->cache_hash = "native\n\n";
105 } else if (strcmp(mcpu, "baseline") == 0) {
106 target->is_native = false;
107 target->llvm_cpu_name = "";
108 target->llvm_cpu_features = "";
109 target->builtin_str = "Target.Cpu.baseline(arch);\n";
110 target->cache_hash = "baseline\n\n";
111 } else {
112 const char *msg = "stage0 can't handle CPU/features in the target";
113 stage2_panic(msg, strlen(msg));
114 }
115 } else {
116 // first initialize all to zero
117 *target = {};
118
119 SplitIterator it = memSplit(str(zig_triple), str("-"));
120
121 Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
122 Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
123 Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
124
125 if (!opt_archsub.is_some)
126 return ErrorMissingArchitecture;
127
128 if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) {
129 return err;
130 }
131
132 if (!opt_os.is_some)
133 return ErrorMissingOperatingSystem;
134
135 if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
136 return err;
137 }
138
139 if (opt_abi.is_some) {
140 if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
141 return err;
142 }
143 } else {
144 target->abi = target_default_abi(target->arch, target->os);
145 }
146
147 if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) {
148 const char *msg = "stage0 can't handle CPU/features in the target";
149 stage2_panic(msg, strlen(msg));
150 }
151 target->builtin_str = "Target.Cpu.baseline(arch);\n";
152 target->cache_hash = "\n\n";
153 }
154
155 return ErrorNone;
156}
157
158int stage2_cmd_targets(const char *zig_triple) {
159 const char *msg = "stage0 called stage2_cmd_targets";
160 stage2_panic(msg, strlen(msg));
161}
162
163enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) {
164 libc->include_dir = "/dummy/include";
165 libc->include_dir_len = strlen(libc->include_dir);
166 libc->sys_include_dir = "/dummy/sys/include";
167 libc->sys_include_dir_len = strlen(libc->sys_include_dir);
168 libc->crt_dir = "";
169 libc->crt_dir_len = strlen(libc->crt_dir);
170 libc->static_crt_dir = "";
171 libc->static_crt_dir_len = strlen(libc->static_crt_dir);
172 libc->msvc_lib_dir = "";
173 libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir);
174 libc->kernel32_lib_dir = "";
175 libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir);
176 return ErrorNone;
177}
178
179enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) {
180 const char *msg = "stage0 called stage2_libc_render";
181 stage2_panic(msg, strlen(msg));
182}
183
184enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) {
185 const char *msg = "stage0 called stage2_libc_find_native";
186 stage2_panic(msg, strlen(msg));
187}
188
189enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) {
190 const char *msg = "stage0 called stage2_detect_dynamic_linker";
191 stage2_panic(msg, strlen(msg));
192}
193
194enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) {
195 native_paths->include_dirs_ptr = nullptr;
196 native_paths->include_dirs_len = 0;
197
198 native_paths->lib_dirs_ptr = nullptr;
199 native_paths->lib_dirs_len = 0;
200
201 native_paths->rpaths_ptr = nullptr;
202 native_paths->rpaths_len = 0;
203
204 native_paths->warnings_ptr = nullptr;
205 native_paths->warnings_len = 0;
206
207 return ErrorNone;
208}
src/stage2.h created+319
......@@ -0,0 +1,319 @@
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#include "zig_llvm.h"
16
17#ifdef __cplusplus
18#define ZIG_EXTERN_C extern "C"
19#else
20#define ZIG_EXTERN_C
21#endif
22
23#if defined(_MSC_VER)
24#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn)
25#else
26#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn))
27#endif
28
29// ABI warning: the types and declarations in this file must match both those in
30// stage2.cpp and src-self-hosted/stage2.zig.
31
32// ABI warning
33enum Error {
34 ErrorNone,
35 ErrorNoMem,
36 ErrorInvalidFormat,
37 ErrorSemanticAnalyzeFail,
38 ErrorAccess,
39 ErrorInterrupted,
40 ErrorSystemResources,
41 ErrorFileNotFound,
42 ErrorFileSystem,
43 ErrorFileTooBig,
44 ErrorDivByZero,
45 ErrorOverflow,
46 ErrorPathAlreadyExists,
47 ErrorUnexpected,
48 ErrorExactDivRemainder,
49 ErrorNegativeDenominator,
50 ErrorShiftedOutOneBits,
51 ErrorCCompileErrors,
52 ErrorEndOfFile,
53 ErrorIsDir,
54 ErrorNotDir,
55 ErrorUnsupportedOperatingSystem,
56 ErrorSharingViolation,
57 ErrorPipeBusy,
58 ErrorPrimitiveTypeNotFound,
59 ErrorCacheUnavailable,
60 ErrorPathTooLong,
61 ErrorCCompilerCannotFindFile,
62 ErrorNoCCompilerInstalled,
63 ErrorReadingDepFile,
64 ErrorInvalidDepFile,
65 ErrorMissingArchitecture,
66 ErrorMissingOperatingSystem,
67 ErrorUnknownArchitecture,
68 ErrorUnknownOperatingSystem,
69 ErrorUnknownABI,
70 ErrorInvalidFilename,
71 ErrorDiskQuota,
72 ErrorDiskSpace,
73 ErrorUnexpectedWriteFailure,
74 ErrorUnexpectedSeekFailure,
75 ErrorUnexpectedFileTruncationFailure,
76 ErrorUnimplemented,
77 ErrorOperationAborted,
78 ErrorBrokenPipe,
79 ErrorNoSpaceLeft,
80 ErrorNotLazy,
81 ErrorIsAsync,
82 ErrorImportOutsidePkgPath,
83 ErrorUnknownCpu,
84 ErrorUnknownCpuFeature,
85 ErrorInvalidCpuFeatures,
86 ErrorInvalidLlvmCpuFeaturesFormat,
87 ErrorUnknownApplicationBinaryInterface,
88 ErrorASTUnitFailure,
89 ErrorBadPathName,
90 ErrorSymLinkLoop,
91 ErrorProcessFdQuotaExceeded,
92 ErrorSystemFdQuotaExceeded,
93 ErrorNoDevice,
94 ErrorDeviceBusy,
95 ErrorUnableToSpawnCCompiler,
96 ErrorCCompilerExitCode,
97 ErrorCCompilerCrashed,
98 ErrorCCompilerCannotFindHeaders,
99 ErrorLibCRuntimeNotFound,
100 ErrorLibCStdLibHeaderNotFound,
101 ErrorLibCKernel32LibNotFound,
102 ErrorUnsupportedArchitecture,
103 ErrorWindowsSdkNotFound,
104 ErrorUnknownDynamicLinkerPath,
105 ErrorTargetHasNoDynamicLinker,
106};
107
108// ABI warning
109struct Stage2ErrorMsg {
110 const char *filename_ptr; // can be null
111 size_t filename_len;
112 const char *msg_ptr;
113 size_t msg_len;
114 const char *source; // valid until the ASTUnit is freed. can be null
115 unsigned line; // 0 based
116 unsigned column; // 0 based
117 unsigned offset; // byte offset into source
118};
119
120// ABI warning
121struct Stage2Ast;
122
123// ABI warning
124ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
125 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
126 const char **args_begin, const char **args_end, const char *resources_path);
127
128// ABI warning
129ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
130
131// ABI warning
132ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
133
134// ABI warning
135ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
136
137// ABI warning
138ZIG_EXTERN_C void stage2_attach_segfault_handler(void);
139
140// ABI warning
141ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
142
143// ABI warning
144ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
145
146// ABI warning
147struct stage2_DepTokenizer {
148 void *handle;
149};
150
151// ABI warning
152struct stage2_DepNextResult {
153 enum TypeId {
154 error,
155 null,
156 target,
157 prereq,
158 };
159
160 TypeId type_id;
161
162 // when ent == error --> error text
163 // when ent == null --> undefined
164 // when ent == target --> target pathname
165 // when ent == prereq --> prereq pathname
166 const char *textz;
167};
168
169// ABI warning
170ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len);
171
172// ABI warning
173ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
174
175// ABI warning
176ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
177
178// ABI warning
179struct Stage2Progress;
180// ABI warning
181struct Stage2ProgressNode;
182// ABI warning
183ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
184// ABI warning
185ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
186// ABI warning
187ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
188// ABI warning
189ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
190 const char *name_ptr, size_t name_len, size_t estimated_total_items);
191// ABI warning
192ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
193 const char *name_ptr, size_t name_len, size_t estimated_total_items);
194// ABI warning
195ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
196// ABI warning
197ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
198// ABI warning
199ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
200 size_t completed_count, size_t estimated_total_items);
201
202// ABI warning
203ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
204
205// ABI warning
206struct Stage2LibCInstallation {
207 const char *include_dir;
208 size_t include_dir_len;
209 const char *sys_include_dir;
210 size_t sys_include_dir_len;
211 const char *crt_dir;
212 size_t crt_dir_len;
213 const char *static_crt_dir;
214 size_t static_crt_dir_len;
215 const char *msvc_lib_dir;
216 size_t msvc_lib_dir_len;
217 const char *kernel32_lib_dir;
218 size_t kernel32_lib_dir_len;
219};
220
221// ABI warning
222ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file);
223// ABI warning
224ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file);
225// ABI warning
226ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc);
227
228// ABI warning
229// Synchronize with target.cpp::os_list
230enum Os {
231 OsFreestanding,
232 OsAnanas,
233 OsCloudABI,
234 OsDragonFly,
235 OsFreeBSD,
236 OsFuchsia,
237 OsIOS,
238 OsKFreeBSD,
239 OsLinux,
240 OsLv2, // PS3
241 OsMacOSX,
242 OsNetBSD,
243 OsOpenBSD,
244 OsSolaris,
245 OsWindows,
246 OsHaiku,
247 OsMinix,
248 OsRTEMS,
249 OsNaCl, // Native Client
250 OsCNK, // BG/P Compute-Node Kernel
251 OsAIX,
252 OsCUDA, // NVIDIA CUDA
253 OsNVCL, // NVIDIA OpenCL
254 OsAMDHSA, // AMD HSA Runtime
255 OsPS4,
256 OsELFIAMCU,
257 OsTvOS, // Apple tvOS
258 OsWatchOS, // Apple watchOS
259 OsMesa3D,
260 OsContiki,
261 OsAMDPAL,
262 OsHermitCore,
263 OsHurd,
264 OsWASI,
265 OsEmscripten,
266 OsUefi,
267 OsOther,
268};
269
270// ABI warning
271struct ZigGLibCVersion {
272 uint32_t major; // always 2
273 uint32_t minor;
274 uint32_t patch;
275};
276
277struct Stage2TargetData;
278
279// ABI warning
280struct ZigTarget {
281 enum ZigLLVM_ArchType arch;
282 enum ZigLLVM_VendorType vendor;
283
284 enum ZigLLVM_EnvironmentType abi;
285 Os os;
286
287 bool is_native;
288
289 struct ZigGLibCVersion *glibc_version; // null means default
290
291 const char *llvm_cpu_name;
292 const char *llvm_cpu_features;
293 const char *builtin_str;
294 const char *cache_hash;
295};
296
297// ABI warning
298ZIG_EXTERN_C enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target,
299 char **out_ptr, size_t *out_len);
300
301// ABI warning
302ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu);
303
304
305// ABI warning
306struct Stage2NativePaths {
307 const char **include_dirs_ptr;
308 size_t include_dirs_len;
309 const char **lib_dirs_ptr;
310 size_t lib_dirs_len;
311 const char **rpaths_ptr;
312 size_t rpaths_len;
313 const char **warnings_ptr;
314 size_t warnings_len;
315};
316// ABI warning
317ZIG_EXTERN_C enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths);
318
319#endif
src/target.cpp+9-533
......@@ -15,65 +15,6 @@
1515
1616#include <stdio.h>
1717
18static const SubArchList subarch_list_list[] = {
19 SubArchListNone,
20 SubArchListArm32,
21 SubArchListArm64,
22 SubArchListKalimba,
23 SubArchListMips,
24 SubArchListPPC,
25};
26
27static const ZigLLVM_SubArchType subarch_list_arm32[] = {
28 ZigLLVM_ARMSubArch_v8_5a,
29 ZigLLVM_ARMSubArch_v8_4a,
30 ZigLLVM_ARMSubArch_v8_3a,
31 ZigLLVM_ARMSubArch_v8_2a,
32 ZigLLVM_ARMSubArch_v8_1a,
33 ZigLLVM_ARMSubArch_v8,
34 ZigLLVM_ARMSubArch_v8r,
35 ZigLLVM_ARMSubArch_v8m_baseline,
36 ZigLLVM_ARMSubArch_v8m_mainline,
37 ZigLLVM_ARMSubArch_v8_1m_mainline,
38 ZigLLVM_ARMSubArch_v7,
39 ZigLLVM_ARMSubArch_v7em,
40 ZigLLVM_ARMSubArch_v7m,
41 ZigLLVM_ARMSubArch_v7s,
42 ZigLLVM_ARMSubArch_v7k,
43 ZigLLVM_ARMSubArch_v7ve,
44 ZigLLVM_ARMSubArch_v6,
45 ZigLLVM_ARMSubArch_v6m,
46 ZigLLVM_ARMSubArch_v6k,
47 ZigLLVM_ARMSubArch_v6t2,
48 ZigLLVM_ARMSubArch_v5,
49 ZigLLVM_ARMSubArch_v5te,
50 ZigLLVM_ARMSubArch_v4t,
51
52};
53
54static const ZigLLVM_SubArchType subarch_list_arm64[] = {
55 ZigLLVM_ARMSubArch_v8_5a,
56 ZigLLVM_ARMSubArch_v8_4a,
57 ZigLLVM_ARMSubArch_v8_3a,
58 ZigLLVM_ARMSubArch_v8_2a,
59 ZigLLVM_ARMSubArch_v8_1a,
60 ZigLLVM_ARMSubArch_v8,
61};
62
63static const ZigLLVM_SubArchType subarch_list_kalimba[] = {
64 ZigLLVM_KalimbaSubArch_v5,
65 ZigLLVM_KalimbaSubArch_v4,
66 ZigLLVM_KalimbaSubArch_v3,
67};
68
69static const ZigLLVM_SubArchType subarch_list_mips[] = {
70 ZigLLVM_MipsSubArch_r6,
71};
72
73static const ZigLLVM_SubArchType subarch_list_ppc[] = {
74 ZigLLVM_PPCSubArch_spe,
75};
76
7718static const ZigLLVM_ArchType arch_list[] = {
7819 ZigLLVM_arm, // ARM (little endian): arm, armv.*, xscale
7920 ZigLLVM_armeb, // ARM (big endian): armeb
......@@ -513,7 +454,6 @@ void get_native_target(ZigTarget *target) {
513454 ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
514455 ZigLLVMGetNativeTarget(
515456 &target->arch,
516 &target->sub_arch,
517457 &target->vendor,
518458 &os_type,
519459 &target->abi,
......@@ -526,12 +466,6 @@ void get_native_target(ZigTarget *target) {
526466 if (target_is_glibc(target)) {
527467 target->glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
528468 target_init_default_glibc_version(target);
529#ifdef ZIG_OS_LINUX
530 Error err;
531 if ((err = glibc_detect_native_version(target->glibc_version))) {
532 // Fall back to the default version.
533 }
534#endif
535469 }
536470}
537471
......@@ -539,233 +473,18 @@ void target_init_default_glibc_version(ZigTarget *target) {
539473 *target->glibc_version = {2, 17, 0};
540474}
541475
542Error target_parse_archsub(ZigLLVM_ArchType *out_arch, ZigLLVM_SubArchType *out_sub,
543 const char *archsub_ptr, size_t archsub_len)
544{
476Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) {
545477 *out_arch = ZigLLVM_UnknownArch;
546 *out_sub = ZigLLVM_NoSubArch;
547478 for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) {
548479 ZigLLVM_ArchType arch = arch_list[arch_i];
549 SubArchList sub_arch_list = target_subarch_list(arch);
550 size_t subarch_count = target_subarch_count(sub_arch_list);
551 if (mem_eql_str(archsub_ptr, archsub_len, target_arch_name(arch))) {
480 if (mem_eql_str(arch_ptr, arch_len, target_arch_name(arch))) {
552481 *out_arch = arch;
553 if (subarch_count == 0) {
554 return ErrorNone;
555 }
556 }
557 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
558 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
559 char arch_name[64];
560 int n = sprintf(arch_name, "%s%s", target_arch_name(arch), target_subarch_name(sub));
561 if (mem_eql_mem(arch_name, n, archsub_ptr, archsub_len)) {
562 *out_arch = arch;
563 *out_sub = sub;
564 return ErrorNone;
565 }
482 return ErrorNone;
566483 }
567484 }
568485 return ErrorUnknownArchitecture;
569486}
570487
571SubArchList target_subarch_list(ZigLLVM_ArchType arch) {
572 switch (arch) {
573 case ZigLLVM_UnknownArch:
574 zig_unreachable();
575 case ZigLLVM_arm:
576 case ZigLLVM_armeb:
577 case ZigLLVM_thumb:
578 case ZigLLVM_thumbeb:
579 return SubArchListArm32;
580
581 case ZigLLVM_aarch64:
582 case ZigLLVM_aarch64_be:
583 case ZigLLVM_aarch64_32:
584 return SubArchListArm64;
585
586 case ZigLLVM_kalimba:
587 return SubArchListKalimba;
588
589 case ZigLLVM_arc:
590 case ZigLLVM_avr:
591 case ZigLLVM_bpfel:
592 case ZigLLVM_bpfeb:
593 case ZigLLVM_hexagon:
594 case ZigLLVM_mips:
595 case ZigLLVM_mipsel:
596 case ZigLLVM_mips64:
597 case ZigLLVM_mips64el:
598 case ZigLLVM_msp430:
599 case ZigLLVM_ppc:
600 case ZigLLVM_ppc64:
601 case ZigLLVM_ppc64le:
602 case ZigLLVM_r600:
603 case ZigLLVM_amdgcn:
604 case ZigLLVM_riscv32:
605 case ZigLLVM_riscv64:
606 case ZigLLVM_sparc:
607 case ZigLLVM_sparcv9:
608 case ZigLLVM_sparcel:
609 case ZigLLVM_systemz:
610 case ZigLLVM_tce:
611 case ZigLLVM_tcele:
612 case ZigLLVM_x86:
613 case ZigLLVM_x86_64:
614 case ZigLLVM_xcore:
615 case ZigLLVM_nvptx:
616 case ZigLLVM_nvptx64:
617 case ZigLLVM_le32:
618 case ZigLLVM_le64:
619 case ZigLLVM_amdil:
620 case ZigLLVM_amdil64:
621 case ZigLLVM_hsail:
622 case ZigLLVM_hsail64:
623 case ZigLLVM_spir:
624 case ZigLLVM_spir64:
625 case ZigLLVM_shave:
626 case ZigLLVM_lanai:
627 case ZigLLVM_wasm32:
628 case ZigLLVM_wasm64:
629 case ZigLLVM_renderscript32:
630 case ZigLLVM_renderscript64:
631 case ZigLLVM_ve:
632 return SubArchListNone;
633 }
634 zig_unreachable();
635}
636
637size_t target_subarch_count(SubArchList sub_arch_list) {
638 switch (sub_arch_list) {
639 case SubArchListNone:
640 return 0;
641 case SubArchListArm32:
642 return array_length(subarch_list_arm32);
643 case SubArchListArm64:
644 return array_length(subarch_list_arm64);
645 case SubArchListKalimba:
646 return array_length(subarch_list_kalimba);
647 case SubArchListMips:
648 return array_length(subarch_list_mips);
649 case SubArchListPPC:
650 return array_length(subarch_list_ppc);
651 }
652 zig_unreachable();
653}
654
655ZigLLVM_SubArchType target_subarch_enum(SubArchList sub_arch_list, size_t i) {
656 switch (sub_arch_list) {
657 case SubArchListNone:
658 zig_unreachable();
659 case SubArchListArm32:
660 assert(i < array_length(subarch_list_arm32));
661 return subarch_list_arm32[i];
662 case SubArchListArm64:
663 assert(i < array_length(subarch_list_arm64));
664 return subarch_list_arm64[i];
665 case SubArchListKalimba:
666 assert(i < array_length(subarch_list_kalimba));
667 return subarch_list_kalimba[i];
668 case SubArchListMips:
669 assert(i < array_length(subarch_list_mips));
670 return subarch_list_mips[i];
671 case SubArchListPPC:
672 assert(i < array_length(subarch_list_ppc));
673 return subarch_list_ppc[i];
674 }
675 zig_unreachable();
676}
677
678const char *target_subarch_name(ZigLLVM_SubArchType subarch) {
679 switch (subarch) {
680 case ZigLLVM_NoSubArch:
681 return "";
682 case ZigLLVM_ARMSubArch_v8_5a:
683 return "v8_5a";
684 case ZigLLVM_ARMSubArch_v8_4a:
685 return "v8_4a";
686 case ZigLLVM_ARMSubArch_v8_3a:
687 return "v8_3a";
688 case ZigLLVM_ARMSubArch_v8_2a:
689 return "v8_2a";
690 case ZigLLVM_ARMSubArch_v8_1a:
691 return "v8_1a";
692 case ZigLLVM_ARMSubArch_v8:
693 return "v8a";
694 case ZigLLVM_ARMSubArch_v8r:
695 return "v8r";
696 case ZigLLVM_ARMSubArch_v8m_baseline:
697 return "v8m_baseline";
698 case ZigLLVM_ARMSubArch_v8m_mainline:
699 return "v8m_mainline";
700 case ZigLLVM_ARMSubArch_v8_1m_mainline:
701 return "v8_1m_mainline";
702 case ZigLLVM_ARMSubArch_v7:
703 return "v7a";
704 case ZigLLVM_ARMSubArch_v7em:
705 return "v7em";
706 case ZigLLVM_ARMSubArch_v7m:
707 return "v7m";
708 case ZigLLVM_ARMSubArch_v7s:
709 return "v7s";
710 case ZigLLVM_ARMSubArch_v7k:
711 return "v7k";
712 case ZigLLVM_ARMSubArch_v7ve:
713 return "v7ve";
714 case ZigLLVM_ARMSubArch_v6:
715 return "v6";
716 case ZigLLVM_ARMSubArch_v6m:
717 return "v6m";
718 case ZigLLVM_ARMSubArch_v6k:
719 return "v6k";
720 case ZigLLVM_ARMSubArch_v6t2:
721 return "v6t2";
722 case ZigLLVM_ARMSubArch_v5:
723 return "v5";
724 case ZigLLVM_ARMSubArch_v5te:
725 return "v5te";
726 case ZigLLVM_ARMSubArch_v4t:
727 return "v4t";
728 case ZigLLVM_KalimbaSubArch_v3:
729 return "v3";
730 case ZigLLVM_KalimbaSubArch_v4:
731 return "v4";
732 case ZigLLVM_KalimbaSubArch_v5:
733 return "v5";
734 case ZigLLVM_MipsSubArch_r6:
735 return "r6";
736 case ZigLLVM_PPCSubArch_spe:
737 return "spe";
738 }
739 zig_unreachable();
740}
741
742size_t target_subarch_list_count(void) {
743 return array_length(subarch_list_list);
744}
745
746SubArchList target_subarch_list_enum(size_t index) {
747 assert(index < array_length(subarch_list_list));
748 return subarch_list_list[index];
749}
750
751const char *target_subarch_list_name(SubArchList sub_arch_list) {
752 switch (sub_arch_list) {
753 case SubArchListNone:
754 return "None";
755 case SubArchListArm32:
756 return "Arm32";
757 case SubArchListArm64:
758 return "Arm64";
759 case SubArchListKalimba:
760 return "Kalimba";
761 case SubArchListMips:
762 return "Mips";
763 case SubArchListPPC:
764 return "PPC";
765 }
766 zig_unreachable();
767}
768
769488Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
770489 for (size_t i = 0; i < array_length(os_list); i += 1) {
771490 Os os = os_list[i];
......@@ -790,42 +509,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si
790509 return ErrorUnknownABI;
791510}
792511
793Error target_parse_triple(ZigTarget *target, const char *triple) {
794 Error err;
795
796 // first initialize all to zero
797 *target = {};
798
799 SplitIterator it = memSplit(str(triple), str("-"));
800
801 Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
802 Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
803 Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
804
805 if (!opt_archsub.is_some)
806 return ErrorMissingArchitecture;
807
808 if ((err = target_parse_archsub(&target->arch, &target->sub_arch,
809 (char*)opt_archsub.value.ptr, opt_archsub.value.len)))
810 {
811 return err;
812 }
813
814 if (!opt_os.is_some)
815 return ErrorMissingOperatingSystem;
816
817 if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
818 return err;
819 }
820
821 if (opt_abi.is_some) {
822 if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
823 return err;
824 }
825 } else {
826 target->abi = target_default_abi(target->arch, target->os);
827 }
828 return ErrorNone;
512Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) {
513 return stage2_target_parse(target, triple, mcpu);
829514}
830515
831516const char *target_arch_name(ZigLLVM_ArchType arch) {
......@@ -842,18 +527,16 @@ void init_all_targets(void) {
842527
843528void target_triple_zig(Buf *triple, const ZigTarget *target) {
844529 buf_resize(triple, 0);
845 buf_appendf(triple, "%s%s-%s-%s",
530 buf_appendf(triple, "%s-%s-%s",
846531 target_arch_name(target->arch),
847 target_subarch_name(target->sub_arch),
848532 target_os_name(target->os),
849533 target_abi_name(target->abi));
850534}
851535
852536void target_triple_llvm(Buf *triple, const ZigTarget *target) {
853537 buf_resize(triple, 0);
854 buf_appendf(triple, "%s%s-%s-%s-%s",
538 buf_appendf(triple, "%s-%s-%s-%s",
855539 ZigLLVMGetArchTypeName(target->arch),
856 ZigLLVMGetSubArchTypeName(target->sub_arch),
857540 ZigLLVMGetVendorTypeName(target->vendor),
858541 ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
859542 ZigLLVMGetEnvironmentTypeName(target->abi));
......@@ -1220,214 +903,10 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
1220903 }
1221904}
1222905
1223enum FloatAbi {
1224 FloatAbiHard,
1225 FloatAbiSoft,
1226 FloatAbiSoftFp,
1227};
1228
1229static FloatAbi get_float_abi(const ZigTarget *target) {
1230 const ZigLLVM_EnvironmentType env = target->abi;
1231 if (env == ZigLLVM_GNUEABIHF ||
1232 env == ZigLLVM_EABIHF ||
1233 env == ZigLLVM_MuslEABIHF)
1234 {
1235 return FloatAbiHard;
1236 } else {
1237 return FloatAbiSoft;
1238 }
1239}
1240
1241static bool is_64_bit(ZigLLVM_ArchType arch) {
1242 return target_arch_pointer_bit_width(arch) == 64;
1243}
1244
1245906bool target_is_android(const ZigTarget *target) {
1246907 return target->abi == ZigLLVM_Android;
1247908}
1248909
1249const char *target_dynamic_linker(const ZigTarget *target) {
1250 if (target_is_android(target)) {
1251 return is_64_bit(target->arch) ? "/system/bin/linker64" : "/system/bin/linker";
1252 }
1253
1254 if (target_is_musl(target)) {
1255 Buf buf = BUF_INIT;
1256 buf_init_from_str(&buf, "/lib/ld-musl-");
1257 bool is_arm = false;
1258 switch (target->arch) {
1259 case ZigLLVM_arm:
1260 case ZigLLVM_thumb:
1261 buf_append_str(&buf, "arm");
1262 is_arm = true;
1263 break;
1264 case ZigLLVM_armeb:
1265 case ZigLLVM_thumbeb:
1266 buf_append_str(&buf, "armeb");
1267 is_arm = true;
1268 break;
1269 default:
1270 buf_append_str(&buf, target_arch_name(target->arch));
1271 }
1272 if (is_arm && get_float_abi(target) == FloatAbiHard) {
1273 buf_append_str(&buf, "hf");
1274 }
1275 buf_append_str(&buf, ".so.1");
1276 return buf_ptr(&buf);
1277 }
1278
1279 switch (target->os) {
1280 case OsFreeBSD:
1281 return "/libexec/ld-elf.so.1";
1282 case OsNetBSD:
1283 return "/libexec/ld.elf_so";
1284 case OsDragonFly:
1285 return "/libexec/ld-elf.so.2";
1286 case OsLinux: {
1287 const ZigLLVM_EnvironmentType abi = target->abi;
1288 switch (target->arch) {
1289 case ZigLLVM_UnknownArch:
1290 zig_unreachable();
1291 case ZigLLVM_x86:
1292 case ZigLLVM_sparc:
1293 case ZigLLVM_sparcel:
1294 return "/lib/ld-linux.so.2";
1295
1296 case ZigLLVM_aarch64:
1297 return "/lib/ld-linux-aarch64.so.1";
1298
1299 case ZigLLVM_aarch64_be:
1300 return "/lib/ld-linux-aarch64_be.so.1";
1301
1302 case ZigLLVM_aarch64_32:
1303 return "/lib/ld-linux-aarch64_32.so.1";
1304
1305 case ZigLLVM_arm:
1306 case ZigLLVM_thumb:
1307 if (get_float_abi(target) == FloatAbiHard) {
1308 return "/lib/ld-linux-armhf.so.3";
1309 } else {
1310 return "/lib/ld-linux.so.3";
1311 }
1312
1313 case ZigLLVM_armeb:
1314 case ZigLLVM_thumbeb:
1315 if (get_float_abi(target) == FloatAbiHard) {
1316 return "/lib/ld-linux-armhf.so.3";
1317 } else {
1318 return "/lib/ld-linux.so.3";
1319 }
1320
1321 case ZigLLVM_mips:
1322 case ZigLLVM_mipsel:
1323 case ZigLLVM_mips64:
1324 case ZigLLVM_mips64el:
1325 zig_panic("TODO implement target_dynamic_linker for mips");
1326
1327 case ZigLLVM_ppc:
1328 return "/lib/ld.so.1";
1329
1330 case ZigLLVM_ppc64:
1331 return "/lib64/ld64.so.2";
1332
1333 case ZigLLVM_ppc64le:
1334 return "/lib64/ld64.so.2";
1335
1336 case ZigLLVM_systemz:
1337 return "/lib64/ld64.so.1";
1338
1339 case ZigLLVM_sparcv9:
1340 return "/lib64/ld-linux.so.2";
1341
1342 case ZigLLVM_x86_64:
1343 if (abi == ZigLLVM_GNUX32) {
1344 return "/libx32/ld-linux-x32.so.2";
1345 }
1346 if (abi == ZigLLVM_Musl || abi == ZigLLVM_MuslEABI || abi == ZigLLVM_MuslEABIHF) {
1347 return "/lib/ld-musl-x86_64.so.1";
1348 }
1349 return "/lib64/ld-linux-x86-64.so.2";
1350
1351 case ZigLLVM_wasm32:
1352 case ZigLLVM_wasm64:
1353 return nullptr;
1354
1355 case ZigLLVM_riscv32:
1356 return "/lib/ld-linux-riscv32-ilp32.so.1";
1357 case ZigLLVM_riscv64:
1358 return "/lib/ld-linux-riscv64-lp64.so.1";
1359
1360 case ZigLLVM_arc:
1361 case ZigLLVM_avr:
1362 case ZigLLVM_bpfel:
1363 case ZigLLVM_bpfeb:
1364 case ZigLLVM_hexagon:
1365 case ZigLLVM_msp430:
1366 case ZigLLVM_r600:
1367 case ZigLLVM_amdgcn:
1368 case ZigLLVM_tce:
1369 case ZigLLVM_tcele:
1370 case ZigLLVM_xcore:
1371 case ZigLLVM_nvptx:
1372 case ZigLLVM_nvptx64:
1373 case ZigLLVM_le32:
1374 case ZigLLVM_le64:
1375 case ZigLLVM_amdil:
1376 case ZigLLVM_amdil64:
1377 case ZigLLVM_hsail:
1378 case ZigLLVM_hsail64:
1379 case ZigLLVM_spir:
1380 case ZigLLVM_spir64:
1381 case ZigLLVM_kalimba:
1382 case ZigLLVM_shave:
1383 case ZigLLVM_lanai:
1384 case ZigLLVM_renderscript32:
1385 case ZigLLVM_renderscript64:
1386 case ZigLLVM_ve:
1387 zig_panic("TODO implement target_dynamic_linker for this arch");
1388 }
1389 zig_unreachable();
1390 }
1391 case OsFreestanding:
1392 case OsIOS:
1393 case OsTvOS:
1394 case OsWatchOS:
1395 case OsMacOSX:
1396 case OsUefi:
1397 case OsWindows:
1398 case OsEmscripten:
1399 case OsOther:
1400 return nullptr;
1401
1402 case OsAnanas:
1403 case OsCloudABI:
1404 case OsFuchsia:
1405 case OsKFreeBSD:
1406 case OsLv2:
1407 case OsOpenBSD:
1408 case OsSolaris:
1409 case OsHaiku:
1410 case OsMinix:
1411 case OsRTEMS:
1412 case OsNaCl:
1413 case OsCNK:
1414 case OsAIX:
1415 case OsCUDA:
1416 case OsNVCL:
1417 case OsAMDHSA:
1418 case OsPS4:
1419 case OsELFIAMCU:
1420 case OsMesa3D:
1421 case OsContiki:
1422 case OsAMDPAL:
1423 case OsHermitCore:
1424 case OsHurd:
1425 case OsWASI:
1426 zig_panic("TODO implement target_dynamic_linker for this OS");
1427 }
1428 zig_unreachable();
1429}
1430
1431910bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {
1432911 assert(host_target != nullptr);
1433912
......@@ -1436,10 +915,8 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
1436915 return true;
1437916 }
1438917
1439 if (guest_target->os == host_target->os && guest_target->arch == host_target->arch &&
1440 guest_target->sub_arch == host_target->sub_arch)
1441 {
1442 // OS, arch, and sub-arch match
918 if (guest_target->os == host_target->os && guest_target->arch == host_target->arch) {
919 // OS and arch match
1443920 return true;
1444921 }
1445922
......@@ -1861,7 +1338,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
18611338 out_target->arch = libcs_available[index].arch;
18621339 out_target->os = libcs_available[index].os;
18631340 out_target->abi = libcs_available[index].abi;
1864 out_target->sub_arch = ZigLLVM_NoSubArch;
18651341 out_target->vendor = ZigLLVM_UnknownVendor;
18661342 out_target->is_native = false;
18671343}
src/target.hpp+3-83
......@@ -8,61 +8,10 @@
88#ifndef ZIG_TARGET_HPP
99#define ZIG_TARGET_HPP
1010
11#include <zig_llvm.h>
11#include "stage2.h"
1212
1313struct Buf;
1414
15// Synchronize with target.cpp::os_list
16enum Os {
17 OsFreestanding,
18 OsAnanas,
19 OsCloudABI,
20 OsDragonFly,
21 OsFreeBSD,
22 OsFuchsia,
23 OsIOS,
24 OsKFreeBSD,
25 OsLinux,
26 OsLv2, // PS3
27 OsMacOSX,
28 OsNetBSD,
29 OsOpenBSD,
30 OsSolaris,
31 OsWindows,
32 OsHaiku,
33 OsMinix,
34 OsRTEMS,
35 OsNaCl, // Native Client
36 OsCNK, // BG/P Compute-Node Kernel
37 OsAIX,
38 OsCUDA, // NVIDIA CUDA
39 OsNVCL, // NVIDIA OpenCL
40 OsAMDHSA, // AMD HSA Runtime
41 OsPS4,
42 OsELFIAMCU,
43 OsTvOS, // Apple tvOS
44 OsWatchOS, // Apple watchOS
45 OsMesa3D,
46 OsContiki,
47 OsAMDPAL,
48 OsHermitCore,
49 OsHurd,
50 OsWASI,
51 OsEmscripten,
52 OsUefi,
53 OsOther,
54};
55
56// Synchronize with target.cpp::subarch_list_list
57enum SubArchList {
58 SubArchListNone,
59 SubArchListArm32,
60 SubArchListArm64,
61 SubArchListKalimba,
62 SubArchListMips,
63 SubArchListPPC,
64};
65
6615enum TargetSubsystem {
6716 TargetSubsystemConsole,
6817 TargetSubsystemWindows,
......@@ -79,23 +28,6 @@ enum TargetSubsystem {
7928 TargetSubsystemAuto
8029};
8130
82struct ZigGLibCVersion {
83 uint32_t major; // always 2
84 uint32_t minor;
85 uint32_t patch;
86};
87
88struct ZigTarget {
89 ZigLLVM_ArchType arch;
90 ZigLLVM_SubArchType sub_arch;
91 ZigLLVM_VendorType vendor;
92 Os os;
93 ZigLLVM_EnvironmentType abi;
94 ZigGLibCVersion *glibc_version; // null means default
95 Stage2CpuFeatures *cpu_features;
96 bool is_native;
97};
98
9931enum CIntType {
10032 CIntTypeShort,
10133 CIntTypeUShort,
......@@ -109,9 +41,8 @@ enum CIntType {
10941 CIntTypeCount,
11042};
11143
112Error target_parse_triple(ZigTarget *target, const char *triple);
113Error target_parse_archsub(ZigLLVM_ArchType *arch, ZigLLVM_SubArchType *sub,
114 const char *archsub_ptr, size_t archsub_len);
44Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu);
45Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len);
11546Error target_parse_os(Os *os, const char *os_ptr, size_t os_len);
11647Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len);
11748
......@@ -122,15 +53,6 @@ size_t target_arch_count(void);
12253ZigLLVM_ArchType target_arch_enum(size_t index);
12354const char *target_arch_name(ZigLLVM_ArchType arch);
12455
125SubArchList target_subarch_list(ZigLLVM_ArchType arch);
126size_t target_subarch_count(SubArchList sub_arch_list);
127ZigLLVM_SubArchType target_subarch_enum(SubArchList subarch_list, size_t index);
128const char *target_subarch_name(ZigLLVM_SubArchType subarch);
129
130size_t target_subarch_list_count(void);
131SubArchList target_subarch_list_enum(size_t index);
132const char *target_subarch_list_name(SubArchList sub_arch_list);
133
13456const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch);
13557
13658size_t target_vendor_count(void);
......@@ -169,8 +91,6 @@ const char *target_lib_file_prefix(const ZigTarget *target);
16991const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
17092 size_t version_major, size_t version_minor, size_t version_patch);
17193
172const char *target_dynamic_linker(const ZigTarget *target);
173
17494bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
17595ZigLLVM_OSType get_llvm_os_type(Os os_type);
17696
src/userland.cpp deleted-146
......@@ -1,146 +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
11Error 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
19void 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
24void stage2_zen(const char **ptr, size_t *len) {
25 const char *msg = "stage0 called stage2_zen";
26 stage2_panic(msg, strlen(msg));
27}
28
29void stage2_attach_segfault_handler(void) { }
30
31void 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
38void 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
43int stage2_fmt(int argc, char **argv) {
44 const char *msg = "stage0 called stage2_fmt";
45 stage2_panic(msg, strlen(msg));
46}
47
48stage2_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
53void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) {
54 const char *msg = "stage0 called stage2_DepTokenizer_deinit";
55 stage2_panic(msg, strlen(msg));
56}
57
58stage2_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
64struct Stage2Progress {
65 int trash;
66};
67
68struct Stage2ProgressNode {
69 int trash;
70};
71
72Stage2Progress *stage2_progress_create(void) {
73 return nullptr;
74}
75
76void stage2_progress_destroy(Stage2Progress *progress) {}
77
78Stage2ProgressNode *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}
83Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
84 const char *name_ptr, size_t name_len, size_t estimated_total_items)
85{
86 return nullptr;
87}
88void stage2_progress_end(Stage2ProgressNode *node) {}
89void stage2_progress_complete_one(Stage2ProgressNode *node) {}
90void stage2_progress_disable_tty(Stage2Progress *progress) {}
91void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
92
93struct 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
100Error 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
124void 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}
130const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) {
131 return cpu_features->llvm_cpu_name;
132}
133const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) {
134 return cpu_features->llvm_cpu_features;
135}
136void 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
143int stage2_cmd_targets(const char *zig_triple) {
144 const char *msg = "stage0 called stage2_cmd_targets";
145 stage2_panic(msg, strlen(msg));
146}
src/userland.h deleted-208
......@@ -1,208 +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
31enum 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};
88
89// ABI warning
90struct Stage2ErrorMsg {
91 const char *filename_ptr; // can be null
92 size_t filename_len;
93 const char *msg_ptr;
94 size_t msg_len;
95 const char *source; // valid until the ASTUnit is freed. can be null
96 unsigned line; // 0 based
97 unsigned column; // 0 based
98 unsigned offset; // byte offset into source
99};
100
101// ABI warning
102struct Stage2Ast;
103
104// ABI warning
105ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
106 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
107 const char **args_begin, const char **args_end, const char *resources_path);
108
109// ABI warning
110ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
111
112// ABI warning
113ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
114
115// ABI warning
116ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
117
118// ABI warning
119ZIG_EXTERN_C void stage2_attach_segfault_handler(void);
120
121// ABI warning
122ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
123
124// ABI warning
125ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
126
127// ABI warning
128struct stage2_DepTokenizer {
129 void *handle;
130};
131
132// ABI warning
133struct stage2_DepNextResult {
134 enum TypeId {
135 error,
136 null,
137 target,
138 prereq,
139 };
140
141 TypeId type_id;
142
143 // when ent == error --> error text
144 // when ent == null --> undefined
145 // when ent == target --> target pathname
146 // when ent == prereq --> prereq pathname
147 const char *textz;
148};
149
150// ABI warning
151ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len);
152
153// ABI warning
154ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
155
156// ABI warning
157ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
158
159// ABI warning
160struct Stage2Progress;
161// ABI warning
162struct Stage2ProgressNode;
163// ABI warning
164ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
165// ABI warning
166ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
167// ABI warning
168ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
169// ABI warning
170ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
171 const char *name_ptr, size_t name_len, size_t estimated_total_items);
172// ABI warning
173ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
174 const char *name_ptr, size_t name_len, size_t estimated_total_items);
175// ABI warning
176ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
177// ABI warning
178ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
179// ABI warning
180ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
181 size_t completed_count, size_t estimated_total_items);
182
183// ABI warning
184struct Stage2CpuFeatures;
185
186// ABI warning
187ZIG_EXTERN_C Error stage2_cpu_features_parse(struct Stage2CpuFeatures **result,
188 const char *zig_triple, const char *cpu_name, const char *cpu_features);
189
190// ABI warning
191ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const struct Stage2CpuFeatures *cpu_features);
192
193// ABI warning
194ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const struct Stage2CpuFeatures *cpu_features);
195
196// ABI warning
197ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const struct Stage2CpuFeatures *cpu_features,
198 const char **ptr, size_t *len);
199
200// ABI warning
201ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatures *cpu_features,
202 const char **ptr, size_t *len);
203
204// ABI warning
205ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
206
207
208#endif
src/util.cpp+1-1
......@@ -6,7 +6,7 @@
66 */
77
88#include "util.hpp"
9#include "userland.h"
9#include "stage2.h"
1010
1111#include <stdio.h>
1212#include <stdarg.h>
src/windows_sdk.h+4
......@@ -16,6 +16,7 @@
1616
1717#include <stddef.h>
1818
19// ABI warning - src-self-hosted/windows_sdk.zig
1920struct ZigWindowsSDK {
2021 const char *path10_ptr;
2122 size_t path10_len;
......@@ -33,6 +34,7 @@ struct ZigWindowsSDK {
3334 size_t msvc_lib_dir_len;
3435};
3536
37// ABI warning - src-self-hosted/windows_sdk.zig
3638enum ZigFindWindowsSdkError {
3739 ZigFindWindowsSdkErrorNone,
3840 ZigFindWindowsSdkErrorOutOfMemory,
......@@ -40,8 +42,10 @@ enum ZigFindWindowsSdkError {
4042 ZigFindWindowsSdkErrorPathTooLong,
4143};
4244
45// ABI warning - src-self-hosted/windows_sdk.zig
4346ZIG_EXTERN_C enum ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk);
4447
48// ABI warning - src-self-hosted/windows_sdk.zig
4549ZIG_EXTERN_C void zig_free_windows_sdk(struct ZigWindowsSDK *sdk);
4650
4751#endif
src/zig_clang.h+1-1
......@@ -8,7 +8,7 @@
88#ifndef ZIG_ZIG_CLANG_H
99#define ZIG_ZIG_CLANG_H
1010
11#include "userland.h"
11#include "stage2.h"
1212#include <inttypes.h>
1313#include <stdbool.h>
1414
src/zig_llvm.cpp+60-138
......@@ -162,17 +162,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
162162}
163163
164164bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
165 const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,
166 bool is_small, bool time_report)
165 char **error_message, bool is_debug,
166 bool is_small, bool time_report,
167 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)
167168{
168169 TimePassesIsEnabled = time_report;
169170
170 std::error_code EC;
171 raw_fd_ostream dest(filename, EC, sys::fs::F_None);
172 if (EC) {
173 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
174 return true;
171 raw_fd_ostream *dest_asm = nullptr;
172 raw_fd_ostream *dest_bin = nullptr;
173
174 if (asm_filename) {
175 std::error_code EC;
176 dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None);
177 if (EC) {
178 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
179 return true;
180 }
175181 }
182 if (bin_filename) {
183 std::error_code EC;
184 dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None);
185 if (EC) {
186 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
187 return true;
188 }
189 }
190
176191 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
177192 target_machine->setO0WantsFastISel(true);
178193
......@@ -223,49 +238,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
223238 }
224239 PMBuilder->populateFunctionPassManager(FPM);
225240
226 // Set up the per-module pass manager.
227 legacy::PassManager MPM;
228 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
229 PMBuilder->populateModulePassManager(MPM);
230
231 // Set output pass.
232 CodeGenFileType ft;
233 if (output_type != ZigLLVM_EmitLLVMIr) {
234 switch (output_type) {
235 case ZigLLVM_EmitAssembly:
236 ft = CGFT_AssemblyFile;
237 break;
238 case ZigLLVM_EmitBinary:
239 ft = CGFT_ObjectFile;
240 break;
241 default:
242 abort();
241 {
242 // Set up the per-module pass manager.
243 legacy::PassManager MPM;
244 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
245 PMBuilder->populateModulePassManager(MPM);
246
247 // Set output passes.
248 if (dest_bin) {
249 if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, CGFT_ObjectFile)) {
250 *error_message = strdup("TargetMachine can't emit an object file");
251 return true;
252 }
243253 }
244
245 if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) {
246 *error_message = strdup("TargetMachine can't emit a file of this type");
247 return true;
254 if (dest_asm) {
255 if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, CGFT_AssemblyFile)) {
256 *error_message = strdup("TargetMachine can't emit an assembly file");
257 return true;
258 }
248259 }
249 }
250260
251 // run per function optimization passes
252 FPM.doInitialization();
253 for (Function &F : *module)
254 if (!F.isDeclaration())
255 FPM.run(F);
256 FPM.doFinalization();
261 // run per function optimization passes
262 FPM.doInitialization();
263 for (Function &F : *module)
264 if (!F.isDeclaration())
265 FPM.run(F);
266 FPM.doFinalization();
257267
258 MPM.run(*module);
268 MPM.run(*module);
259269
260 if (output_type == ZigLLVM_EmitLLVMIr) {
261 if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {
262 return true;
270 if (llvm_ir_filename) {
271 if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) {
272 return true;
273 }
274 }
275
276 if (time_report) {
277 TimerGroup::printAll(errs());
263278 }
264 }
265279
266 if (time_report) {
267 TimerGroup::printAll(errs());
280 // MPM goes out of scope and writes to the out streams
268281 }
282
283 delete dest_asm;
284 delete dest_bin;
285
269286 return false;
270287}
271288
......@@ -792,7 +809,7 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
792809 return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();
793810}
794811
795void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
812void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type,
796813 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
797814 ZigLLVM_ObjectFormatType *oformat)
798815{
......@@ -800,7 +817,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
800817 Triple triple(Triple::normalize(native_triple));
801818
802819 *arch_type = (ZigLLVM_ArchType)triple.getArch();
803 *sub_arch_type = (ZigLLVM_SubArchType)triple.getSubArch();
804820 *vendor_type = (ZigLLVM_VendorType)triple.getVendor();
805821 *os_type = (ZigLLVM_OSType)triple.getOS();
806822 *environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();
......@@ -809,70 +825,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
809825 free(native_triple);
810826}
811827
812const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
813 switch (sub_arch) {
814 case ZigLLVM_NoSubArch:
815 return "";
816 case ZigLLVM_ARMSubArch_v8_5a:
817 return "v8.5a";
818 case ZigLLVM_ARMSubArch_v8_4a:
819 return "v8.4a";
820 case ZigLLVM_ARMSubArch_v8_3a:
821 return "v8.3a";
822 case ZigLLVM_ARMSubArch_v8_2a:
823 return "v8.2a";
824 case ZigLLVM_ARMSubArch_v8_1a:
825 return "v8.1a";
826 case ZigLLVM_ARMSubArch_v8:
827 return "v8a";
828 case ZigLLVM_ARMSubArch_v8r:
829 return "v8r";
830 case ZigLLVM_ARMSubArch_v8m_baseline:
831 return "v8m.base";
832 case ZigLLVM_ARMSubArch_v8m_mainline:
833 return "v8m.main";
834 case ZigLLVM_ARMSubArch_v8_1m_mainline:
835 return "v8.1m.main";
836 case ZigLLVM_ARMSubArch_v7:
837 return "v7a";
838 case ZigLLVM_ARMSubArch_v7em:
839 return "v7em";
840 case ZigLLVM_ARMSubArch_v7m:
841 return "v7m";
842 case ZigLLVM_ARMSubArch_v7s:
843 return "v7s";
844 case ZigLLVM_ARMSubArch_v7k:
845 return "v7k";
846 case ZigLLVM_ARMSubArch_v7ve:
847 return "v7ve";
848 case ZigLLVM_ARMSubArch_v6:
849 return "v6";
850 case ZigLLVM_ARMSubArch_v6m:
851 return "v6m";
852 case ZigLLVM_ARMSubArch_v6k:
853 return "v6k";
854 case ZigLLVM_ARMSubArch_v6t2:
855 return "v6t2";
856 case ZigLLVM_ARMSubArch_v5:
857 return "v5";
858 case ZigLLVM_ARMSubArch_v5te:
859 return "v5te";
860 case ZigLLVM_ARMSubArch_v4t:
861 return "v4t";
862 case ZigLLVM_KalimbaSubArch_v3:
863 return "v3";
864 case ZigLLVM_KalimbaSubArch_v4:
865 return "v4";
866 case ZigLLVM_KalimbaSubArch_v5:
867 return "v5";
868 case ZigLLVM_MipsSubArch_r6:
869 return "r6";
870 case ZigLLVM_PPCSubArch_spe:
871 return "spe";
872 }
873 abort();
874}
875
876828void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
877829 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
878830 unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4);
......@@ -1210,36 +1162,6 @@ static_assert((Triple::ArchType)ZigLLVM_renderscript64 == Triple::renderscript64
12101162static_assert((Triple::ArchType)ZigLLVM_ve == Triple::ve, "");
12111163static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
12121164
1213static_assert((Triple::SubArchType)ZigLLVM_NoSubArch == Triple::NoSubArch, "");
1214static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_4a == Triple::ARMSubArch_v8_4a, "");
1215static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_3a == Triple::ARMSubArch_v8_3a, "");
1216static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_2a == Triple::ARMSubArch_v8_2a, "");
1217static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1a == Triple::ARMSubArch_v8_1a, "");
1218static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8 == Triple::ARMSubArch_v8, "");
1219static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8r == Triple::ARMSubArch_v8r, "");
1220static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_baseline == Triple::ARMSubArch_v8m_baseline, "");
1221static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_mainline == Triple::ARMSubArch_v8m_mainline, "");
1222static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1m_mainline == Triple::ARMSubArch_v8_1m_mainline, "");
1223static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7 == Triple::ARMSubArch_v7, "");
1224static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7em == Triple::ARMSubArch_v7em, "");
1225static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7m == Triple::ARMSubArch_v7m, "");
1226static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7s == Triple::ARMSubArch_v7s, "");
1227static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7k == Triple::ARMSubArch_v7k, "");
1228static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7ve == Triple::ARMSubArch_v7ve, "");
1229static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6 == Triple::ARMSubArch_v6, "");
1230static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6m == Triple::ARMSubArch_v6m, "");
1231static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6k == Triple::ARMSubArch_v6k, "");
1232static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6t2 == Triple::ARMSubArch_v6t2, "");
1233static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5 == Triple::ARMSubArch_v5, "");
1234static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5te == Triple::ARMSubArch_v5te, "");
1235static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v4t == Triple::ARMSubArch_v4t, "");
1236static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v3 == Triple::KalimbaSubArch_v3, "");
1237static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v4 == Triple::KalimbaSubArch_v4, "");
1238static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
1239static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
1240static_assert((Triple::SubArchType)ZigLLVM_MipsSubArch_r6 == Triple::MipsSubArch_r6, "");
1241static_assert((Triple::SubArchType)ZigLLVM_PPCSubArch_spe == Triple::PPCSubArch_spe, "");
1242
12431165static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor, "");
12441166static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, "");
12451167static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, "");
src/zig_llvm.h+4-49
......@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
4646ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
4747ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
4848
49// We use a custom enum here since LLVM does not expose LLVMIr as an emit
50// output through the same mechanism as assembly/binary.
51enum ZigLLVM_EmitOutputType {
52 ZigLLVM_EmitAssembly,
53 ZigLLVM_EmitBinary,
54 ZigLLVM_EmitLLVMIr,
55};
56
5749ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
58 const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,
59 bool is_small, bool time_report);
50 char **error_message, bool is_debug,
51 bool is_small, bool time_report,
52 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename);
6053
6154ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
6255 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
......@@ -332,43 +325,6 @@ enum ZigLLVM_ArchType {
332325 ZigLLVM_LastArchType = ZigLLVM_ve
333326};
334327
335// synchronize with lists in target.cpp
336enum ZigLLVM_SubArchType {
337 ZigLLVM_NoSubArch,
338
339 ZigLLVM_ARMSubArch_v8_5a,
340 ZigLLVM_ARMSubArch_v8_4a,
341 ZigLLVM_ARMSubArch_v8_3a,
342 ZigLLVM_ARMSubArch_v8_2a,
343 ZigLLVM_ARMSubArch_v8_1a,
344 ZigLLVM_ARMSubArch_v8,
345 ZigLLVM_ARMSubArch_v8r,
346 ZigLLVM_ARMSubArch_v8m_baseline,
347 ZigLLVM_ARMSubArch_v8m_mainline,
348 ZigLLVM_ARMSubArch_v8_1m_mainline,
349 ZigLLVM_ARMSubArch_v7,
350 ZigLLVM_ARMSubArch_v7em,
351 ZigLLVM_ARMSubArch_v7m,
352 ZigLLVM_ARMSubArch_v7s,
353 ZigLLVM_ARMSubArch_v7k,
354 ZigLLVM_ARMSubArch_v7ve,
355 ZigLLVM_ARMSubArch_v6,
356 ZigLLVM_ARMSubArch_v6m,
357 ZigLLVM_ARMSubArch_v6k,
358 ZigLLVM_ARMSubArch_v6t2,
359 ZigLLVM_ARMSubArch_v5,
360 ZigLLVM_ARMSubArch_v5te,
361 ZigLLVM_ARMSubArch_v4t,
362
363 ZigLLVM_KalimbaSubArch_v3,
364 ZigLLVM_KalimbaSubArch_v4,
365 ZigLLVM_KalimbaSubArch_v5,
366
367 ZigLLVM_MipsSubArch_r6,
368
369 ZigLLVM_PPCSubArch_spe,
370};
371
372328enum ZigLLVM_VendorType {
373329 ZigLLVM_UnknownVendor,
374330
......@@ -526,7 +482,6 @@ LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp
526482#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29)
527483
528484ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
529ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
530485ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
531486ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);
532487ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi);
......@@ -541,7 +496,7 @@ ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **fil
541496bool ZigLLVMWriteImportLibrary(const char *def_path, const enum ZigLLVM_ArchType arch,
542497 const char *output_lib_path, const bool kill_at);
543498
544ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,
499ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type,
545500 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
546501 enum ZigLLVM_ObjectFormatType *oformat);
547502
test/compile_errors.zig+37-142
......@@ -3,6 +3,35 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("slice to pointer conversion mismatch",
7 \\pub fn bytesAsSlice(bytes: var) [*]align(1) const u16 {
8 \\ return @ptrCast([*]align(1) const u16, bytes.ptr)[0..1];
9 \\}
10 \\test "bytesAsSlice" {
11 \\ const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
12 \\ const slice = bytesAsSlice(bytes[0..]);
13 \\}
14 , &[_][]const u8{
15 "tmp.zig:2:54: error: expected type '[*]align(1) const u16', found '[]align(1) const u16'",
16 });
17
18 cases.addTest("access invalid @typeInfo decl",
19 \\const A = B;
20 \\test "Crash" {
21 \\ _ = @typeInfo(@This()).Struct.decls[0];
22 \\}
23 , &[_][]const u8{
24 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
25 });
26
27 cases.addTest("reject extern function definitions with body",
28 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {
29 \\ return a + b;
30 \\}
31 , &[_][]const u8{
32 "tmp.zig:1:1: error: extern functions have no body",
33 });
34
635 cases.addTest("duplicate field in anonymous struct literal",
736 \\export fn entry() void {
837 \\ const anon = .{
......@@ -30,10 +59,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3059 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
3160 });
3261
33 cases.addTest("dependency loop in top-level decl with @TypeInfo",
34 \\export const foo = @typeInfo(@This());
62 cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls",
63 \\export const foo = @typeInfo(@This()).Struct.decls;
3564 , &[_][]const u8{
3665 "tmp.zig:1:20: error: dependency loop detected",
66 "tmp.zig:1:45: note: referenced here",
3767 });
3868
3969 cases.add("function call assigned to incorrect type",
......@@ -332,8 +362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
332362 });
333363 tc.target = Target{
334364 .Cross = .{
335 .arch = .wasm32,
336 .cpu_features = Target.Arch.wasm32.getBaselineCpuFeatures(),
365 .cpu = Target.Cpu.baseline(.wasm32),
337366 .os = .wasi,
338367 .abi = .none,
339368 },
......@@ -734,8 +763,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
734763 });
735764 tc.target = Target{
736765 .Cross = .{
737 .arch = .x86_64,
738 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
766 .cpu = Target.Cpu.baseline(.x86_64),
739767 .os = .linux,
740768 .abi = .gnu,
741769 },
......@@ -1346,24 +1374,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
13461374 "tmp.zig:8:28: note: referenced here",
13471375 });
13481376
1349 cases.add("@typeInfo causing depend on itself compile error",
1350 \\const start = struct {
1351 \\ fn crash() bug() {
1352 \\ return bug;
1353 \\ }
1354 \\};
1355 \\fn bug() void {
1356 \\ _ = @typeInfo(start).Struct;
1357 \\}
1358 \\export fn entry() void {
1359 \\ var boom = start.crash();
1360 \\}
1361 , &[_][]const u8{
1362 "tmp.zig:7:9: error: dependency loop detected",
1363 "tmp.zig:2:19: note: referenced here",
1364 "tmp.zig:10:21: note: referenced here",
1365 });
1366
13671377 cases.add("enum field value references enum",
13681378 \\pub const Foo = extern enum {
13691379 \\ A = Foo.B,
......@@ -1647,7 +1657,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
16471657 \\ var ptr: [*c]u8 = (1 << 64) + 1;
16481658 \\}
16491659 \\export fn b() void {
1650 \\ var x: @IntType(false, 65) = 0x1234;
1660 \\ var x: u65 = 0x1234;
16511661 \\ var ptr: [*c]u8 = x;
16521662 \\}
16531663 , &[_][]const u8{
......@@ -1886,13 +1896,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18861896
18871897 cases.add("exceeded maximum bit width of integer",
18881898 \\export fn entry1() void {
1889 \\ const T = @IntType(false, 65536);
1899 \\ const T = u65536;
18901900 \\}
18911901 \\export fn entry2() void {
18921902 \\ var x: i65536 = 1;
18931903 \\}
18941904 , &[_][]const u8{
1895 "tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'",
18961905 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
18971906 });
18981907
......@@ -2932,14 +2941,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29322941 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",
29332942 });
29342943
2935 cases.add("@memberCount of error",
2936 \\comptime {
2937 \\ _ = @memberCount(anyerror);
2938 \\}
2939 , &[_][]const u8{
2940 "tmp.zig:2:9: error: global error set member count not available at comptime",
2941 });
2942
29432944 cases.add("duplicate error value in error set",
29442945 \\const Foo = error {
29452946 \\ Bar,
......@@ -4735,16 +4736,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
47354736 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
47364737 });
47374738
4738 cases.add("convert fixed size array to slice with invalid size",
4739 \\export fn f() void {
4740 \\ var array: [5]u8 = undefined;
4741 \\ var foo = @bytesToSlice(u32, &array)[0];
4742 \\}
4743 , &[_][]const u8{
4744 "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) u32: size mismatch",
4745 "tmp.zig:3:29: note: u32 has size 4; remaining bytes: 1",
4746 });
4747
47484739 cases.add("non-pure function returns type",
47494740 \\var a: u32 = 0;
47504741 \\pub fn List(comptime T: type) type {
......@@ -5606,7 +5597,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
56065597 });
56075598
56085599 cases.add("globally shadowing a primitive type",
5609 \\const u16 = @intType(false, 8);
5600 \\const u16 = u8;
56105601 \\export fn entry() void {
56115602 \\ const a: u16 = 300;
56125603 \\}
......@@ -5947,93 +5938,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
59475938 "tmp.zig:2:1: error: invalid character: '\\t'",
59485939 });
59495940
5950 cases.add("@ArgType given non function parameter",
5951 \\comptime {
5952 \\ _ = @ArgType(i32, 3);
5953 \\}
5954 , &[_][]const u8{
5955 "tmp.zig:2:18: error: expected function, found 'i32'",
5956 });
5957
5958 cases.add("@ArgType arg index out of bounds",
5959 \\comptime {
5960 \\ _ = @ArgType(@TypeOf(add), 2);
5961 \\}
5962 \\fn add(a: i32, b: i32) i32 { return a + b; }
5963 , &[_][]const u8{
5964 "tmp.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments",
5965 });
5966
5967 cases.add("@memberType on unsupported type",
5968 \\comptime {
5969 \\ _ = @memberType(i32, 0);
5970 \\}
5971 , &[_][]const u8{
5972 "tmp.zig:2:21: error: type 'i32' does not support @memberType",
5973 });
5974
5975 cases.add("@memberType on enum",
5976 \\comptime {
5977 \\ _ = @memberType(Foo, 0);
5978 \\}
5979 \\const Foo = enum {A,};
5980 , &[_][]const u8{
5981 "tmp.zig:2:21: error: type 'Foo' does not support @memberType",
5982 });
5983
5984 cases.add("@memberType struct out of bounds",
5985 \\comptime {
5986 \\ _ = @memberType(Foo, 0);
5987 \\}
5988 \\const Foo = struct {};
5989 , &[_][]const u8{
5990 "tmp.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
5991 });
5992
5993 cases.add("@memberType union out of bounds",
5994 \\comptime {
5995 \\ _ = @memberType(Foo, 1);
5996 \\}
5997 \\const Foo = union {A: void,};
5998 , &[_][]const u8{
5999 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6000 });
6001
6002 cases.add("@memberName on unsupported type",
6003 \\comptime {
6004 \\ _ = @memberName(i32, 0);
6005 \\}
6006 , &[_][]const u8{
6007 "tmp.zig:2:21: error: type 'i32' does not support @memberName",
6008 });
6009
6010 cases.add("@memberName struct out of bounds",
6011 \\comptime {
6012 \\ _ = @memberName(Foo, 0);
6013 \\}
6014 \\const Foo = struct {};
6015 , &[_][]const u8{
6016 "tmp.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
6017 });
6018
6019 cases.add("@memberName enum out of bounds",
6020 \\comptime {
6021 \\ _ = @memberName(Foo, 1);
6022 \\}
6023 \\const Foo = enum {A,};
6024 , &[_][]const u8{
6025 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6026 });
6027
6028 cases.add("@memberName union out of bounds",
6029 \\comptime {
6030 \\ _ = @memberName(Foo, 1);
6031 \\}
6032 \\const Foo = union {A:i32,};
6033 , &[_][]const u8{
6034 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6035 });
6036
60375941 cases.add("calling var args extern function, passing array instead of pointer",
60385942 \\export fn entry() void {
60395943 \\ foo("hello".*,);
......@@ -6457,15 +6361,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
64576361 "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic",
64586362 });
64596363
6460 cases.add("getting @ArgType of generic function",
6461 \\fn generic(a: var) void {}
6462 \\comptime {
6463 \\ _ = @ArgType(@TypeOf(generic), 0);
6464 \\}
6465 , &[_][]const u8{
6466 "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var) var' is generic",
6467 });
6468
64696364 cases.add("unsupported modifier at start of asm output constraint",
64706365 \\export fn foo() void {
64716366 \\ var bar: u32 = 3;
test/runtime_safety.zig+9-7
......@@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
553553 );
554554
555555 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
556 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
557 \\ @import("std").os.exit(126);
556 \\const std = @import("std");
557 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
558 \\ std.os.exit(126);
558559 \\}
559560 \\pub fn main() !void {
560561 \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});
561562 \\ if (x.len == 0) return error.Whatever;
562563 \\}
563564 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
564 \\ return @bytesToSlice(i32, slice);
565 \\ return std.mem.bytesAsSlice(i32, slice);
565566 \\}
566567 );
567568
......@@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
656657 );
657658
658659 cases.addRuntimeSafety("@alignCast misaligned",
659 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
660 \\ @import("std").os.exit(126);
660 \\const std = @import("std");
661 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
662 \\ std.os.exit(126);
661663 \\}
662664 \\pub fn main() !void {
663665 \\ var array align(4) = [_]u32{0x11111111, 0x11111111};
664 \\ const bytes = @sliceToBytes(array[0..]);
666 \\ const bytes = std.mem.sliceAsBytes(array[0..]);
665667 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
666668 \\}
667669 \\fn foo(bytes: []u8) u32 {
668670 \\ const slice4 = bytes[1..5];
669 \\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
671 \\ const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
670672 \\ return int_slice[0];
671673 \\}
672674 );
test/stage1/behavior.zig+1-1
......@@ -38,6 +38,7 @@ comptime {
3838 _ = @import("behavior/bugs/3112.zig");
3939 _ = @import("behavior/bugs/3367.zig");
4040 _ = @import("behavior/bugs/3384.zig");
41 _ = @import("behavior/bugs/3586.zig");
4142 _ = @import("behavior/bugs/3742.zig");
4243 _ = @import("behavior/bugs/394.zig");
4344 _ = @import("behavior/bugs/421.zig");
......@@ -91,7 +92,6 @@ comptime {
9192 _ = @import("behavior/shuffle.zig");
9293 _ = @import("behavior/sizeof_and_typeof.zig");
9394 _ = @import("behavior/slice.zig");
94 _ = @import("behavior/slicetobytes.zig");
9595 _ = @import("behavior/struct.zig");
9696 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
9797 _ = @import("behavior/struct_contains_slice_of_itself.zig");
test/stage1/behavior/align.zig-14
......@@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void {
8181 expect(ptr.* == 0x33333333);
8282}
8383
84test "specifying alignment allows slice cast" {
85 testBytesAlignSlice(0x33);
86}
87fn testBytesAlignSlice(b: u8) void {
88 var bytes align(4) = [_]u8{
89 b,
90 b,
91 b,
92 b,
93 };
94 const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
95 expect(slice[0] == 0x33333333);
96}
97
9884test "@alignCast pointers" {
9985 var x: u32 align(4) = 1;
10086 expectsOnly1(&x);
test/stage1/behavior/async_fn.zig+52-2
......@@ -334,7 +334,7 @@ test "async fn with inferred error set" {
334334 var frame: [1]@Frame(middle) = undefined;
335335 var fn_ptr = middle;
336336 var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;
337 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, fn_ptr);
337 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr);
338338 resume global_frame;
339339 std.testing.expectError(error.Fail, result);
340340 }
......@@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
954954 fn doTheTest() void {
955955 var frame: [1]@Frame(middle) = undefined;
956956 var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;
957 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, middle);
957 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle);
958958 resume global_frame;
959959 std.testing.expectError(error.Fail, result);
960960 }
......@@ -1481,3 +1481,53 @@ test "handle defer interfering with return value spill" {
14811481 };
14821482 S.doTheTest();
14831483}
1484
1485test "take address of temporary async frame" {
1486 const S = struct {
1487 var global_frame: anyframe = undefined;
1488 var finished = false;
1489
1490 fn doTheTest() void {
1491 _ = async asyncDoTheTest();
1492 resume global_frame;
1493 expect(finished);
1494 }
1495
1496 fn asyncDoTheTest() void {
1497 expect(finishIt(&async foo(10)) == 1245);
1498 finished = true;
1499 }
1500
1501 fn foo(arg: i32) i32 {
1502 global_frame = @frame();
1503 suspend;
1504 return arg + 1234;
1505 }
1506
1507 fn finishIt(frame: anyframe->i32) i32 {
1508 return (await frame) + 1;
1509 }
1510 };
1511 S.doTheTest();
1512}
1513
1514test "noasync await" {
1515 const S = struct {
1516 var finished = false;
1517
1518 fn doTheTest() void {
1519 var frame = async foo(false);
1520 expect(noasync await frame == 42);
1521 finished = true;
1522 }
1523
1524 fn foo(want_suspend: bool) i32 {
1525 if (want_suspend) {
1526 suspend;
1527 }
1528 return 42;
1529 }
1530 };
1531 S.doTheTest();
1532 expect(S.finished);
1533}
test/stage1/behavior/bit_shifting.zig+2-2
......@@ -2,9 +2,9 @@ const std = @import("std");
22const expect = std.testing.expect;
33
44fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type {
5 expect(Key == @IntType(false, Key.bit_count));
5 expect(Key == std.meta.IntType(false, Key.bit_count));
66 expect(Key.bit_count >= mask_bit_count);
7 const ShardKey = @IntType(false, mask_bit_count);
7 const ShardKey = std.meta.IntType(false, mask_bit_count);
88 const shift_amount = Key.bit_count - ShardKey.bit_count;
99 return struct {
1010 const Self = @This();
test/stage1/behavior/bugs/1851.zig+1-1
......@@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" {
1313 x[0] = 0xFFFFFF;
1414 x[1] = 0xFFFFFF;
1515
16 const bytes = @sliceToBytes(x);
16 const bytes = std.mem.sliceAsBytes(x);
1717 expect(@TypeOf(bytes) == []align(4) u8);
1818 expect(bytes.len == 8);
1919
test/stage1/behavior/bugs/3586.zig created+11
......@@ -0,0 +1,11 @@
1const NoteParams = struct {};
2
3const Container = struct {
4 params: ?NoteParams,
5};
6
7test "fixed" {
8 var ctr = Container{
9 .params = NoteParams{},
10 };
11}
test/stage1/behavior/bugs/3742.zig+1-1
......@@ -17,7 +17,7 @@ pub const GET = struct {
1717};
1818
1919pub fn isCommand(comptime T: type) bool {
20 const tid = @typeId(T);
20 const tid = @typeInfo(T);
2121 return (tid == .Struct or tid == .Enum or tid == .Union) and
2222 @hasDecl(T, "Redis") and @hasDecl(T.Redis, "Command");
2323}
test/stage1/behavior/cast.zig-20
......@@ -300,20 +300,6 @@ fn cast128Float(x: u128) f128 {
300300 return @bitCast(f128, x);
301301}
302302
303test "const slice widen cast" {
304 const bytes align(4) = [_]u8{
305 0x12,
306 0x12,
307 0x12,
308 0x12,
309 };
310
311 const u32_value = @bytesToSlice(u32, bytes[0..])[0];
312 expect(u32_value == 0x12121212);
313
314 expect(@bitCast(u32, bytes) == 0x12121212);
315}
316
317303test "single-item pointer of array to slice and to unknown length pointer" {
318304 testCastPtrOfArrayToSliceAndPtr();
319305 comptime testCastPtrOfArrayToSliceAndPtr();
......@@ -388,12 +374,6 @@ test "comptime_int @intToFloat" {
388374 }
389375}
390376
391test "@bytesToSlice keeps pointer alignment" {
392 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
393 const numbers = @bytesToSlice(u32, bytes[0..]);
394 comptime expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
395}
396
397377test "@intCast i32 to u7" {
398378 var x: u128 = maxInt(u128);
399379 var y: i32 = 120;
test/stage1/behavior/enum.zig+2-2
......@@ -96,8 +96,8 @@ test "enum type" {
9696 const bar = Bar.B;
9797
9898 expect(bar == Bar.B);
99 expect(@memberCount(Foo) == 3);
100 expect(@memberCount(Bar) == 4);
99 expect(@typeInfo(Foo).Union.fields.len == 3);
100 expect(@typeInfo(Bar).Enum.fields.len == 4);
101101 expect(@sizeOf(Foo) == @sizeOf(FooNoVoid));
102102 expect(@sizeOf(Bar) == 1);
103103}
test/stage1/behavior/error.zig+3-4
......@@ -3,7 +3,6 @@ const expect = std.testing.expect;
33const expectError = std.testing.expectError;
44const expectEqual = std.testing.expectEqual;
55const mem = std.mem;
6const builtin = @import("builtin");
76
87pub fn foo() anyerror!i32 {
98 const x = try bar();
......@@ -84,8 +83,8 @@ test "error union type " {
8483fn testErrorUnionType() void {
8584 const x: anyerror!i32 = 1234;
8685 if (x) |value| expect(value == 1234) else |_| unreachable;
87 expect(@typeId(@TypeOf(x)) == builtin.TypeId.ErrorUnion);
88 expect(@typeId(@TypeOf(x).ErrorSet) == builtin.TypeId.ErrorSet);
86 expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
87 expect(@typeInfo(@TypeOf(x).ErrorSet) == .ErrorSet);
8988 expect(@TypeOf(x).ErrorSet == anyerror);
9089}
9190
......@@ -100,7 +99,7 @@ const MyErrSet = error{
10099};
101100
102101fn testErrorSetType() void {
103 expect(@memberCount(MyErrSet) == 2);
102 expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
104103
105104 const a: MyErrSet!i32 = 5678;
106105 const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
test/stage1/behavior/eval.zig+2-12
......@@ -654,8 +654,8 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
654654 expect(b == 2);
655655}
656656
657test "@tagName of @typeId" {
658 const str = @tagName(@typeId(u8));
657test "@tagName of @typeInfo" {
658 const str = @tagName(@typeInfo(u8));
659659 expect(std.mem.eql(u8, str, "Int"));
660660}
661661
......@@ -711,16 +711,6 @@ test "bit shift a u1" {
711711 expect(y == 1);
712712}
713713
714test "@bytesToslice on a packed struct" {
715 const F = packed struct {
716 a: u8,
717 };
718
719 var b = [1]u8{9};
720 var f = @bytesToSlice(F, &b);
721 expect(f[0].a == 9);
722}
723
724714test "comptime pointer cast array and then slice" {
725715 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
726716
test/stage1/behavior/for.zig+28
......@@ -1,5 +1,6 @@
11const std = @import("std");
22const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
34const mem = std.mem;
45
56test "continue in for loop" {
......@@ -142,3 +143,30 @@ test "for with null and T peer types and inferred result location type" {
142143 S.doTheTest(&[_]u8{ 1, 2 });
143144 comptime S.doTheTest(&[_]u8{ 1, 2 });
144145}
146
147test "for copies its payload" {
148 const S = struct {
149 fn doTheTest() void {
150 var x = [_]usize{ 1, 2, 3 };
151 for (x) |value, i| {
152 // Modify the original array
153 x[i] += 99;
154 expectEqual(value, i + 1);
155 }
156 }
157 };
158 S.doTheTest();
159 comptime S.doTheTest();
160}
161
162test "for on slice with allowzero ptr" {
163 const S = struct {
164 fn doTheTest(slice: []u8) void {
165 var ptr = @ptrCast([*]allowzero u8, slice.ptr)[0..slice.len];
166 for (ptr) |x, i| expect(x == i + 1);
167 for (ptr) |*x, i| expect(x.* == i + 1);
168 }
169 };
170 S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
171 comptime S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
172}
test/stage1/behavior/if.zig+18-1
......@@ -1,4 +1,6 @@
1const expect = @import("std").testing.expect;
1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
24
35test "if statements" {
46 shouldBeEqual(1, 1);
......@@ -90,3 +92,18 @@ test "if prongs cast to expected type instead of peer type resolution" {
9092 S.doTheTest(false);
9193 comptime S.doTheTest(false);
9294}
95
96test "while copies its payload" {
97 const S = struct {
98 fn doTheTest() void {
99 var tmp: ?i32 = 10;
100 if (tmp) |value| {
101 // Modify the original variable
102 tmp = null;
103 expectEqual(@as(i32, 10), value);
104 } else unreachable;
105 }
106 };
107 S.doTheTest();
108 comptime S.doTheTest();
109}
test/stage1/behavior/math.zig+1-1
......@@ -266,7 +266,7 @@ fn testBinaryNot(x: u16) void {
266266}
267267
268268test "small int addition" {
269 var x: @IntType(false, 2) = 0;
269 var x: u2 = 0;
270270 expect(x == 0);
271271
272272 x += 1;
test/stage1/behavior/misc.zig-85
......@@ -3,7 +3,6 @@ const expect = std.testing.expect;
33const expectEqualSlices = std.testing.expectEqualSlices;
44const mem = std.mem;
55const builtin = @import("builtin");
6const maxInt = std.math.maxInt;
76
87// normal comment
98
......@@ -25,35 +24,6 @@ test "call disabled extern fn" {
2524 disabledExternFn();
2625}
2726
28test "@IntType builtin" {
29 expect(@IntType(true, 8) == i8);
30 expect(@IntType(true, 16) == i16);
31 expect(@IntType(true, 32) == i32);
32 expect(@IntType(true, 64) == i64);
33
34 expect(@IntType(false, 8) == u8);
35 expect(@IntType(false, 16) == u16);
36 expect(@IntType(false, 32) == u32);
37 expect(@IntType(false, 64) == u64);
38
39 expect(i8.bit_count == 8);
40 expect(i16.bit_count == 16);
41 expect(i32.bit_count == 32);
42 expect(i64.bit_count == 64);
43
44 expect(i8.is_signed);
45 expect(i16.is_signed);
46 expect(i32.is_signed);
47 expect(i64.is_signed);
48 expect(isize.is_signed);
49
50 expect(!u8.is_signed);
51 expect(!u16.is_signed);
52 expect(!u32.is_signed);
53 expect(!u64.is_signed);
54 expect(!usize.is_signed);
55}
56
5727test "floating point primitive bit counts" {
5828 expect(f16.bit_count == 16);
5929 expect(f32.bit_count == 32);
......@@ -377,26 +347,6 @@ test "string concatenation" {
377347 expect(b[len] == 0);
378348}
379349
380test "cast slice to u8 slice" {
381 expect(@sizeOf(i32) == 4);
382 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
383 const big_thing_slice: []i32 = big_thing_array[0..];
384 const bytes = @sliceToBytes(big_thing_slice);
385 expect(bytes.len == 4 * 4);
386 bytes[4] = 0;
387 bytes[5] = 0;
388 bytes[6] = 0;
389 bytes[7] = 0;
390 expect(big_thing_slice[1] == 0);
391 const big_thing_again = @bytesToSlice(i32, bytes);
392 expect(big_thing_again[2] == 3);
393 big_thing_again[2] = -1;
394 expect(bytes[8] == maxInt(u8));
395 expect(bytes[9] == maxInt(u8));
396 expect(bytes[10] == maxInt(u8));
397 expect(bytes[11] == maxInt(u8));
398}
399
400350test "pointer to void return type" {
401351 testPointerToVoidReturnType() catch unreachable;
402352}
......@@ -428,7 +378,6 @@ fn testArray2DConstDoublePtr(ptr: *const f32) void {
428378 expect(ptr2[1] == 2.0);
429379}
430380
431const Tid = builtin.TypeId;
432381const AStruct = struct {
433382 x: i32,
434383};
......@@ -445,40 +394,6 @@ const AUnion = union {
445394 Two: void,
446395};
447396
448test "@typeId" {
449 comptime {
450 expect(@typeId(type) == Tid.Type);
451 expect(@typeId(void) == Tid.Void);
452 expect(@typeId(bool) == Tid.Bool);
453 expect(@typeId(noreturn) == Tid.NoReturn);
454 expect(@typeId(i8) == Tid.Int);
455 expect(@typeId(u8) == Tid.Int);
456 expect(@typeId(i64) == Tid.Int);
457 expect(@typeId(u64) == Tid.Int);
458 expect(@typeId(f32) == Tid.Float);
459 expect(@typeId(f64) == Tid.Float);
460 expect(@typeId(*f32) == Tid.Pointer);
461 expect(@typeId([2]u8) == Tid.Array);
462 expect(@typeId(AStruct) == Tid.Struct);
463 expect(@typeId(@TypeOf(1)) == Tid.ComptimeInt);
464 expect(@typeId(@TypeOf(1.0)) == Tid.ComptimeFloat);
465 expect(@typeId(@TypeOf(undefined)) == Tid.Undefined);
466 expect(@typeId(@TypeOf(null)) == Tid.Null);
467 expect(@typeId(?i32) == Tid.Optional);
468 expect(@typeId(anyerror!i32) == Tid.ErrorUnion);
469 expect(@typeId(anyerror) == Tid.ErrorSet);
470 expect(@typeId(AnEnum) == Tid.Enum);
471 expect(@typeId(@TypeOf(AUnionEnum.One)) == Tid.Enum);
472 expect(@typeId(AUnionEnum) == Tid.Union);
473 expect(@typeId(AUnion) == Tid.Union);
474 expect(@typeId(fn () void) == Tid.Fn);
475 expect(@typeId(@TypeOf(builtin)) == Tid.Type);
476 // TODO bound fn
477 // TODO arg tuple
478 // TODO opaque
479 }
480}
481
482397test "@typeName" {
483398 const Struct = struct {};
484399 const Union = union {
test/stage1/behavior/reflection.zig+3-33
......@@ -16,9 +16,9 @@ test "reflection: function return type, var args, and param types" {
1616 expect(@TypeOf(dummy).ReturnType == i32);
1717 expect(!@TypeOf(dummy).is_var_args);
1818 expect(@TypeOf(dummy).arg_count == 3);
19 expect(@ArgType(@TypeOf(dummy), 0) == bool);
20 expect(@ArgType(@TypeOf(dummy), 1) == i32);
21 expect(@ArgType(@TypeOf(dummy), 2) == f32);
19 expect(@typeInfo(@TypeOf(dummy)).Fn.args[0].arg_type.? == bool);
20 expect(@typeInfo(@TypeOf(dummy)).Fn.args[1].arg_type.? == i32);
21 expect(@typeInfo(@TypeOf(dummy)).Fn.args[2].arg_type.? == f32);
2222 }
2323}
2424
......@@ -26,36 +26,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 {
2626 return 1234;
2727}
2828
29test "reflection: struct member types and names" {
30 comptime {
31 expect(@memberCount(Foo) == 3);
32
33 expect(@memberType(Foo, 0) == i32);
34 expect(@memberType(Foo, 1) == bool);
35 expect(@memberType(Foo, 2) == void);
36
37 expect(mem.eql(u8, @memberName(Foo, 0), "one"));
38 expect(mem.eql(u8, @memberName(Foo, 1), "two"));
39 expect(mem.eql(u8, @memberName(Foo, 2), "three"));
40 }
41}
42
43test "reflection: enum member types and names" {
44 comptime {
45 expect(@memberCount(Bar) == 4);
46
47 expect(@memberType(Bar, 0) == void);
48 expect(@memberType(Bar, 1) == i32);
49 expect(@memberType(Bar, 2) == bool);
50 expect(@memberType(Bar, 3) == f64);
51
52 expect(mem.eql(u8, @memberName(Bar, 0), "One"));
53 expect(mem.eql(u8, @memberName(Bar, 1), "Two"));
54 expect(mem.eql(u8, @memberName(Bar, 2), "Three"));
55 expect(mem.eql(u8, @memberName(Bar, 3), "Four"));
56 }
57}
58
5929test "reflection: @field" {
6030 var f = Foo{
6131 .one = 42,
test/stage1/behavior/slicetobytes.zig deleted-29
......@@ -1,29 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5test "@sliceToBytes packed struct at runtime and comptime" {
6 const Foo = packed struct {
7 a: u4,
8 b: u4,
9 };
10 const S = struct {
11 fn doTheTest() void {
12 var foo: Foo = undefined;
13 var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]);
14 slice[0] = 0x13;
15 switch (builtin.endian) {
16 builtin.Endian.Big => {
17 expect(foo.a == 0x1);
18 expect(foo.b == 0x3);
19 },
20 builtin.Endian.Little => {
21 expect(foo.a == 0x3);
22 expect(foo.b == 0x1);
23 },
24 }
25 }
26 };
27 S.doTheTest();
28 comptime S.doTheTest();
29}
test/stage1/behavior/struct.zig+2-2
......@@ -315,7 +315,7 @@ test "packed array 24bits" {
315315
316316 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
317317 bytes[bytes.len - 1] = 0xaa;
318 const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
318 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
319319 expect(ptr.a == 0);
320320 expect(ptr.b[0].field == 0);
321321 expect(ptr.b[1].field == 0);
......@@ -364,7 +364,7 @@ test "aligned array of packed struct" {
364364 }
365365
366366 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
367 const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];
367 const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
368368
369369 expect(ptr.a[0].a == 0xbb);
370370 expect(ptr.a[0].b == 0xbb);
test/stage1/behavior/switch.zig+22
......@@ -1,6 +1,7 @@
11const std = @import("std");
22const expect = std.testing.expect;
33const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;
45
56test "switch with numbers" {
67 testSwitchWithNumbers(13);
......@@ -493,3 +494,24 @@ test "switch on error set with single else" {
493494 S.doTheTest();
494495 comptime S.doTheTest();
495496}
497
498test "while copies its payload" {
499 const S = struct {
500 fn doTheTest() void {
501 var tmp: union(enum) {
502 A: u8,
503 B: u32,
504 } = .{ .A = 42 };
505 switch (tmp) {
506 .A => |value| {
507 // Modify the original union
508 tmp = .{ .B = 0x10101010 };
509 expectEqual(@as(u8, 42), value);
510 },
511 else => unreachable,
512 }
513 }
514 };
515 S.doTheTest();
516 comptime S.doTheTest();
517}
test/stage1/behavior/type_info.zig+11
......@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {
375375 const c_void_info = @typeInfo(*c_void);
376376 expect(c_void_info.Pointer.sentinel == null);
377377}
378
379test "@typeInfo does not force declarations into existence" {
380 const S = struct {
381 x: i32,
382
383 fn doNotReferenceMe() void {
384 @compileError("test failed");
385 }
386 };
387 comptime expect(@typeInfo(S).Struct.fields.len == 1);
388}
test/stage1/behavior/union.zig+1-1
......@@ -531,7 +531,7 @@ var glbl: Foo1 = undefined;
531531
532532test "global union with single field is correctly initialized" {
533533 glbl = Foo1{
534 .f = @memberType(Foo1, 0){ .x = 123 },
534 .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 },
535535 };
536536 expect(glbl.f.x == 123);
537537}
test/stage1/behavior/while.zig+17-1
......@@ -1,4 +1,5 @@
1const expect = @import("std").testing.expect;
1const std = @import("std");
2const expect = std.testing.expect;
23
34test "while loop" {
45 var i: i32 = 0;
......@@ -271,3 +272,18 @@ test "while error 2 break statements and an else" {
271272 S.entry(true, false);
272273 comptime S.entry(true, false);
273274}
275
276test "while copies its payload" {
277 const S = struct {
278 fn doTheTest() void {
279 var tmp: ?i32 = 10;
280 while (tmp) |value| {
281 // Modify the original variable
282 tmp = null;
283 expect(value == 10);
284 }
285 }
286 };
287 S.doTheTest();
288 comptime S.doTheTest();
289}
test/standalone/guess_number/main.zig+7-7
......@@ -5,6 +5,7 @@ const fmt = std.fmt;
55
66pub fn main() !void {
77 const stdout = &io.getStdOut().outStream().stream;
8 const stdin = io.getStdIn();
89
910 try stdout.print("Welcome to the Guess Number Game in Zig.\n", .{});
1011
......@@ -22,13 +23,12 @@ pub fn main() !void {
2223 try stdout.print("\nGuess a number between 1 and 100: ", .{});
2324 var line_buf: [20]u8 = undefined;
2425
25 const line = io.readLineSlice(line_buf[0..]) catch |err| switch (err) {
26 error.OutOfMemory => {
27 try stdout.print("Input too long.\n", .{});
28 continue;
29 },
30 else => return err,
31 };
26 const amt = try stdin.read(&line_buf);
27 if (amt == line_buf.len) {
28 try stdout.print("Input too long.\n", .{});
29 continue;
30 }
31 const line = std.mem.trimRight(u8, line_buf[0..amt], "\r\n");
3232
3333 const guess = fmt.parseUnsigned(u8, line, 10) catch {
3434 try stdout.print("Invalid number.\n", .{});
test/tests.zig+32-57
......@@ -55,20 +55,18 @@ const test_targets = blk: {
5555 TestTarget{
5656 .target = Target{
5757 .Cross = CrossTarget{
58 .cpu = Target.Cpu.baseline(.x86_64),
5859 .os = .linux,
59 .arch = .x86_64,
6060 .abi = .none,
61 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
6261 },
6362 },
6463 },
6564 TestTarget{
6665 .target = Target{
6766 .Cross = CrossTarget{
67 .cpu = Target.Cpu.baseline(.x86_64),
6868 .os = .linux,
69 .arch = .x86_64,
7069 .abi = .gnu,
71 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
7270 },
7371 },
7472 .link_libc = true,
......@@ -76,9 +74,8 @@ const test_targets = blk: {
7674 TestTarget{
7775 .target = Target{
7876 .Cross = CrossTarget{
77 .cpu = Target.Cpu.baseline(.x86_64),
7978 .os = .linux,
80 .arch = .x86_64,
81 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
8279 .abi = .musl,
8380 },
8481 },
......@@ -88,9 +85,8 @@ const test_targets = blk: {
8885 TestTarget{
8986 .target = Target{
9087 .Cross = CrossTarget{
88 .cpu = Target.Cpu.baseline(.i386),
9189 .os = .linux,
92 .arch = .i386,
93 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
9490 .abi = .none,
9591 },
9692 },
......@@ -98,9 +94,8 @@ const test_targets = blk: {
9894 TestTarget{
9995 .target = Target{
10096 .Cross = CrossTarget{
97 .cpu = Target.Cpu.baseline(.i386),
10198 .os = .linux,
102 .arch = .i386,
103 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
10499 .abi = .musl,
105100 },
106101 },
......@@ -110,9 +105,8 @@ const test_targets = blk: {
110105 TestTarget{
111106 .target = Target{
112107 .Cross = CrossTarget{
108 .cpu = Target.Cpu.baseline(.aarch64),
113109 .os = .linux,
114 .arch = Target.Arch{ .aarch64 = .v8a },
115 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
116110 .abi = .none,
117111 },
118112 },
......@@ -120,9 +114,8 @@ const test_targets = blk: {
120114 TestTarget{
121115 .target = Target{
122116 .Cross = CrossTarget{
117 .cpu = Target.Cpu.baseline(.aarch64),
123118 .os = .linux,
124 .arch = Target.Arch{ .aarch64 = .v8a },
125 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
126119 .abi = .musl,
127120 },
128121 },
......@@ -131,9 +124,8 @@ const test_targets = blk: {
131124 TestTarget{
132125 .target = Target{
133126 .Cross = CrossTarget{
127 .cpu = Target.Cpu.baseline(.aarch64),
134128 .os = .linux,
135 .arch = Target.Arch{ .aarch64 = .v8a },
136 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
137129 .abi = .gnu,
138130 },
139131 },
......@@ -141,45 +133,32 @@ const test_targets = blk: {
141133 },
142134
143135 TestTarget{
144 .target = Target{
145 .Cross = CrossTarget{
146 .os = .linux,
147 .arch = Target.Arch{ .arm = .v8a },
148 .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
149 .abi = .none,
150 },
151 },
136 .target = Target.parse(.{
137 .arch_os_abi = "arm-linux-none",
138 .cpu_features = "generic+v8a",
139 }) catch unreachable,
152140 },
153141 TestTarget{
154 .target = Target{
155 .Cross = CrossTarget{
156 .os = .linux,
157 .arch = Target.Arch{ .arm = .v8a },
158 .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
159 .abi = .musleabihf,
160 },
161 },
142 .target = Target.parse(.{
143 .arch_os_abi = "arm-linux-musleabihf",
144 .cpu_features = "generic+v8a",
145 }) catch unreachable,
162146 .link_libc = true,
163147 },
164148 // TODO https://github.com/ziglang/zig/issues/3287
165149 //TestTarget{
166 // .target = Target{
167 // .Cross = CrossTarget{
168 // .os = .linux,
169 // .arch = Target.Arch{ .arm = .v8a },
170 // .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
171 // .abi = .gnueabihf,
172 // },
173 // },
150 // .target = Target.parse(.{
151 // .arch_os_abi = "arm-linux-gnueabihf",
152 // .cpu_features = "generic+v8a",
153 // }) catch unreachable,
174154 // .link_libc = true,
175155 //},
176156
177157 TestTarget{
178158 .target = Target{
179159 .Cross = CrossTarget{
160 .cpu = Target.Cpu.baseline(.mipsel),
180161 .os = .linux,
181 .arch = .mipsel,
182 .cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
183162 .abi = .none,
184163 },
185164 },
......@@ -187,9 +166,8 @@ const test_targets = blk: {
187166 TestTarget{
188167 .target = Target{
189168 .Cross = CrossTarget{
169 .cpu = Target.Cpu.baseline(.mipsel),
190170 .os = .linux,
191 .arch = .mipsel,
192 .cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
193171 .abi = .musl,
194172 },
195173 },
......@@ -236,9 +214,8 @@ const test_targets = blk: {
236214 TestTarget{
237215 .target = Target{
238216 .Cross = CrossTarget{
217 .cpu = Target.Cpu.baseline(.x86_64),
239218 .os = .macosx,
240 .arch = .x86_64,
241 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
242219 .abi = .gnu,
243220 },
244221 },
......@@ -249,9 +226,8 @@ const test_targets = blk: {
249226 TestTarget{
250227 .target = Target{
251228 .Cross = CrossTarget{
229 .cpu = Target.Cpu.baseline(.i386),
252230 .os = .windows,
253 .arch = .i386,
254 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
255231 .abi = .msvc,
256232 },
257233 },
......@@ -260,9 +236,8 @@ const test_targets = blk: {
260236 TestTarget{
261237 .target = Target{
262238 .Cross = CrossTarget{
239 .cpu = Target.Cpu.baseline(.x86_64),
263240 .os = .windows,
264 .arch = .x86_64,
265 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
266241 .abi = .msvc,
267242 },
268243 },
......@@ -271,9 +246,8 @@ const test_targets = blk: {
271246 TestTarget{
272247 .target = Target{
273248 .Cross = CrossTarget{
249 .cpu = Target.Cpu.baseline(.i386),
274250 .os = .windows,
275 .arch = .i386,
276 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
277251 .abi = .gnu,
278252 },
279253 },
......@@ -283,9 +257,8 @@ const test_targets = blk: {
283257 TestTarget{
284258 .target = Target{
285259 .Cross = CrossTarget{
260 .cpu = Target.Cpu.baseline(.x86_64),
286261 .os = .windows,
287 .arch = .x86_64,
288 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
289262 .abi = .gnu,
290263 },
291264 },
......@@ -513,7 +486,7 @@ pub fn addPkgTests(
513486 const ArchTag = @TagType(builtin.Arch);
514487 if (test_target.disable_native and
515488 test_target.target.getOs() == builtin.os and
516 @as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch))
489 test_target.target.getArch() == builtin.arch)
517490 {
518491 continue;
519492 }
......@@ -714,8 +687,10 @@ pub const StackTracesContext = struct {
714687 const got: []const u8 = got_result: {
715688 var buf = try Buffer.initSize(b.allocator, 0);
716689 defer buf.deinit();
717 var bytes = stderr.toSliceConst();
718 if (bytes.len != 0 and bytes[bytes.len - 1] == '\n') bytes = bytes[0 .. bytes.len - 1];
690 const bytes = if (stderr.endsWith("\n"))
691 stderr.toSliceConst()[0 .. stderr.len() - 1]
692 else
693 stderr.toSliceConst()[0..stderr.len()];
719694 var it = mem.separate(bytes, "\n");
720695 process_lines: while (it.next()) |line| {
721696 if (line.len == 0) continue;
test/translate_c.zig+20-22
......@@ -3,6 +3,13 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("macro line continuation",
7 \\#define FOO -\
8 \\BAR
9 , &[_][]const u8{
10 \\pub const FOO = -BAR;
11 });
12
613 cases.add("function prototype translated as optional",
714 \\typedef void (*fnptr_ty)(void);
815 \\typedef __attribute__((cdecl)) void (*fnptr_attr_ty)(void);
......@@ -1088,10 +1095,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10881095
10891096 cases.addWithTarget("Calling convention", tests.Target{
10901097 .Cross = .{
1098 .cpu = Target.Cpu.baseline(.i386),
10911099 .os = .linux,
1092 .arch = .i386,
10931100 .abi = .none,
1094 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
10951101 },
10961102 },
10971103 \\void __attribute__((fastcall)) foo1(float *a);
......@@ -1107,14 +1113,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11071113 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;
11081114 });
11091115
1110 cases.addWithTarget("Calling convention", tests.Target{
1111 .Cross = .{
1112 .os = .linux,
1113 .arch = .{ .arm = .v8_5a },
1114 .abi = .none,
1115 .cpu_features = (Target.Arch{ .arm = .v8_5a }).getBaselineCpuFeatures(),
1116 },
1117 },
1116 cases.addWithTarget("Calling convention", Target.parse(.{
1117 .arch_os_abi = "arm-linux-none",
1118 .cpu_features = "generic+v8_5a",
1119 }) catch unreachable,
11181120 \\void __attribute__((pcs("aapcs"))) foo1(float *a);
11191121 \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a);
11201122 , &[_][]const u8{
......@@ -1122,14 +1124,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11221124 \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;
11231125 });
11241126
1125 cases.addWithTarget("Calling convention", tests.Target{
1126 .Cross = .{
1127 .os = .linux,
1128 .arch = .{ .aarch64 = .v8_5a },
1129 .abi = .none,
1130 .cpu_features = (Target.Arch{ .aarch64 = .v8_5a }).getBaselineCpuFeatures(),
1131 },
1132 },
1127 cases.addWithTarget("Calling convention", Target.parse(.{
1128 .arch_os_abi = "aarch64-linux-none",
1129 .cpu_features = "generic+v8_5a",
1130 }) catch unreachable,
11331131 \\void __attribute__((aarch64_vector_pcs)) foo1(float *a);
11341132 , &[_][]const u8{
11351133 \\pub fn foo1(a: [*c]f32) callconv(.Vectorcall) void;
......@@ -1356,7 +1354,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13561354 cases.add("macro pointer cast",
13571355 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
13581356 , &[_][]const u8{
1359 \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
1357 \\pub const NRF_GPIO = if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
13601358 });
13611359
13621360 cases.add("basic macro function",
......@@ -2540,11 +2538,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
25402538 \\#define FOO(bar) baz((void *)(baz))
25412539 \\#define BAR (void*) a
25422540 , &[_][]const u8{
2543 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {
2544 \\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));
2541 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {
2542 \\ return baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));
25452543 \\}
25462544 ,
2547 \\pub const BAR = if (@typeId(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeId(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);
2545 \\pub const BAR = if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);
25482546 });
25492547
25502548 cases.add("macro conditional operator",