authorgravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-05-12 02:00:49-07:00
committergravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-05-12 02:00:49-07:00
log3787f3428625e830fd852a8f5a40c7d8a2d429f6
tree23fb493b9d2f07c7abe57955874682959936319a
parent16aee1f58a80295f7599a8290d764a5c7040c373
parentedcc7c72d1a684a8a16ca23ad26689f2cce4e803
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'master' into rebased


222 files changed, 18469 insertions(+), 7246 deletions(-)

CMakeLists.txt+87-24
......@@ -15,7 +15,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
1515
1616
1717set(ZIG_VERSION_MAJOR 0)
18set(ZIG_VERSION_MINOR 3)
18set(ZIG_VERSION_MINOR 4)
1919set(ZIG_VERSION_PATCH 0)
2020set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}")
2121
......@@ -50,10 +50,6 @@ option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead
5050find_package(llvm)
5151find_package(clang)
5252
53if(MINGW)
54 find_package(z3)
55endif()
56
5753if(APPLE AND ZIG_STATIC)
5854 list(REMOVE_ITEM LLVM_LIBRARIES "-lz")
5955 find_library(ZLIB NAMES z zlib libz)
......@@ -62,6 +58,16 @@ endif()
6258
6359set(ZIG_CPP_LIB_DIR "${CMAKE_BINARY_DIR}/zig_cpp")
6460
61# Handle multi-config builds and place each into a common lib. The VS generator
62# for example will append a Debug folder by default if not explicitly specified.
63set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ZIG_CPP_LIB_DIR})
64set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ZIG_CPP_LIB_DIR})
65foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
66 string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE)
67 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})
68 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIG_CPP_LIB_DIR})
69endforeach(CONFIG_TYPE CMAKE_CONFIGURATION_TYPES)
70
6571if(ZIG_FORCE_EXTERNAL_LLD)
6672 find_package(lld)
6773 include_directories(${LLVM_INCLUDE_DIRS})
......@@ -196,7 +202,7 @@ else()
196202 if(MSVC)
197203 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -D_CRT_SECURE_NO_WARNINGS /w")
198204 else()
199 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment")
205 set(ZIG_LLD_COMPILE_FLAGS "-std=c++11 -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -Wno-comment")
200206 if(MINGW)
201207 set(ZIG_LLD_COMPILE_FLAGS "${ZIG_LLD_COMPILE_FLAGS} -D__STDC_FORMAT_MACROS -D__USE_MINGW_ANSI_STDIO -Wno-pedantic-ms-format")
202208 endif()
......@@ -257,7 +263,6 @@ else()
257263 embedded_lld_wasm
258264 embedded_lld_lib
259265 )
260 install(TARGETS embedded_lld_elf embedded_lld_coff embedded_lld_mingw embedded_lld_wasm embedded_lld_lib DESTINATION "${ZIG_CPP_LIB_DIR}")
261266endif()
262267
263268# No patches have been applied to SoftFloat-3e
......@@ -407,6 +412,12 @@ set(SOFTFLOAT_LIBRARIES embedded_softfloat)
407412
408413find_package(Threads)
409414
415# CMake doesn't let us create an empty executable, so we hang on to this one separately.
416set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
417
418# This is our shim which will be replaced by libuserland written in Zig.
419set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
420
410421set(ZIG_SOURCES
411422 "${CMAKE_SOURCE_DIR}/src/analyze.cpp"
412423 "${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
......@@ -423,7 +434,6 @@ set(ZIG_SOURCES
423434 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
424435 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
425436 "${CMAKE_SOURCE_DIR}/src/link.cpp"
426 "${CMAKE_SOURCE_DIR}/src/main.cpp"
427437 "${CMAKE_SOURCE_DIR}/src/os.cpp"
428438 "${CMAKE_SOURCE_DIR}/src/parser.cpp"
429439 "${CMAKE_SOURCE_DIR}/src/range_set.cpp"
......@@ -477,6 +487,7 @@ set(ZIG_STD_FILES
477487 "crypto/x25519.zig"
478488 "cstr.zig"
479489 "debug.zig"
490 "debug/leb128.zig"
480491 "debug/failing_allocator.zig"
481492 "dwarf.zig"
482493 "dynamic_library.zig"
......@@ -507,6 +518,7 @@ set(ZIG_STD_FILES
507518 "heap.zig"
508519 "io.zig"
509520 "io/seekable_stream.zig"
521 "io/c_out_stream.zig"
510522 "json.zig"
511523 "lazy_init.zig"
512524 "linked_list.zig"
......@@ -521,6 +533,7 @@ set(ZIG_STD_FILES
521533 "math/atanh.zig"
522534 "math/big.zig"
523535 "math/big/int.zig"
536 "math/big/rational.zig"
524537 "math/cbrt.zig"
525538 "math/ceil.zig"
526539 "math/complex.zig"
......@@ -599,6 +612,7 @@ set(ZIG_STD_FILES
599612 "os/linux.zig"
600613 "os/linux/arm64.zig"
601614 "os/linux/errno.zig"
615 "os/linux/tls.zig"
602616 "os/linux/vdso.zig"
603617 "os/linux/x86_64.zig"
604618 "os/netbsd.zig"
......@@ -606,6 +620,8 @@ set(ZIG_STD_FILES
606620 "os/path.zig"
607621 "os/time.zig"
608622 "os/uefi.zig"
623 "os/wasi.zig"
624 "os/wasi/core.zig"
609625 "os/windows.zig"
610626 "os/windows/advapi32.zig"
611627 "os/windows/error.zig"
......@@ -615,6 +631,7 @@ set(ZIG_STD_FILES
615631 "os/windows/shell32.zig"
616632 "os/windows/util.zig"
617633 "os/zen.zig"
634 "packed_int_array.zig"
618635 "pdb.zig"
619636 "priority_queue.zig"
620637 "rand.zig"
......@@ -628,10 +645,15 @@ set(ZIG_STD_FILES
628645 "special/build_runner.zig"
629646 "special/builtin.zig"
630647 "special/compiler_rt.zig"
648 "special/compiler_rt/stack_probe.zig"
649 "special/compiler_rt/arm/aeabi_fcmp.zig"
650 "special/compiler_rt/arm/aeabi_dcmp.zig"
631651 "special/compiler_rt/addXf3.zig"
632652 "special/compiler_rt/aulldiv.zig"
633653 "special/compiler_rt/aullrem.zig"
634654 "special/compiler_rt/comparetf2.zig"
655 "special/compiler_rt/comparedf2.zig"
656 "special/compiler_rt/comparesf2.zig"
635657 "special/compiler_rt/divsf3.zig"
636658 "special/compiler_rt/divdf3.zig"
637659 "special/compiler_rt/divti3.zig"
......@@ -656,9 +678,13 @@ set(ZIG_STD_FILES
656678 "special/compiler_rt/fixunstfdi.zig"
657679 "special/compiler_rt/fixunstfsi.zig"
658680 "special/compiler_rt/fixunstfti.zig"
681 "special/compiler_rt/floatdidf.zig"
682 "special/compiler_rt/floatsiXf.zig"
683 "special/compiler_rt/floatunsidf.zig"
659684 "special/compiler_rt/floattidf.zig"
660685 "special/compiler_rt/floattisf.zig"
661686 "special/compiler_rt/floattitf.zig"
687 "special/compiler_rt/floatundidf.zig"
662688 "special/compiler_rt/floatunditf.zig"
663689 "special/compiler_rt/floatunsitf.zig"
664690 "special/compiler_rt/floatuntidf.zig"
......@@ -667,7 +693,11 @@ set(ZIG_STD_FILES
667693 "special/compiler_rt/modti3.zig"
668694 "special/compiler_rt/mulXf3.zig"
669695 "special/compiler_rt/muloti4.zig"
696 "special/compiler_rt/mulodi4.zig"
670697 "special/compiler_rt/multi3.zig"
698 "special/compiler_rt/ashlti3.zig"
699 "special/compiler_rt/ashrti3.zig"
700 "special/compiler_rt/lshrti3.zig"
671701 "special/compiler_rt/negXf2.zig"
672702 "special/compiler_rt/popcountdi2.zig"
673703 "special/compiler_rt/truncXfYf2.zig"
......@@ -676,7 +706,6 @@ set(ZIG_STD_FILES
676706 "special/compiler_rt/udivmodti4.zig"
677707 "special/compiler_rt/udivti3.zig"
678708 "special/compiler_rt/umodti3.zig"
679 "special/fmt_runner.zig"
680709 "special/init-exe/build.zig"
681710 "special/init-exe/src/main.zig"
682711 "special/init-lib/build.zig"
......@@ -6604,7 +6633,7 @@ endif()
66046633if(MSVC)
66056634 set(EXE_CFLAGS "${EXE_CFLAGS}")
66066635else()
6607 set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces")
6636 set(EXE_CFLAGS "${EXE_CFLAGS} -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D_GNU_SOURCE -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -Werror=strict-prototypes -Werror=old-style-definition -Werror=type-limits -Wno-missing-braces")
66086637 if(MINGW)
66096638 set(EXE_CFLAGS "${EXE_CFLAGS} -D__USE_MINGW_ANSI_STDIO -Wno-pedantic-ms-format")
66106639 endif()
......@@ -6639,13 +6668,12 @@ set_target_properties(opt_c_util PROPERTIES
66396668 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
66406669)
66416670
6642add_executable(zig ${ZIG_SOURCES})
6643set_target_properties(zig PROPERTIES
6671add_library(compiler STATIC ${ZIG_SOURCES})
6672set_target_properties(compiler PROPERTIES
66446673 COMPILE_FLAGS ${EXE_CFLAGS}
66456674 LINK_FLAGS ${EXE_LDFLAGS}
66466675)
6647
6648target_link_libraries(zig LINK_PUBLIC
6676target_link_libraries(compiler LINK_PUBLIC
66496677 zig_cpp
66506678 opt_c_util
66516679 ${SOFTFLOAT_LIBRARIES}
......@@ -6654,24 +6682,63 @@ target_link_libraries(zig LINK_PUBLIC
66546682 ${LLVM_LIBRARIES}
66556683 ${CMAKE_THREAD_LIBS_INIT}
66566684)
6657
66586685if(NOT MSVC)
6659 target_link_libraries(zig LINK_PUBLIC ${LIBXML2})
6686 target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})
66606687endif()
66616688
66626689if(MINGW)
6663 target_link_libraries(zig LINK_PUBLIC ${Z3_LIBRARIES})
6690 find_library(Z3_LIBRARIES NAMES z3 z3.dll)
6691 target_link_libraries(compiler LINK_PUBLIC ${Z3_LIBRARIES})
66646692endif()
66656693
66666694if(ZIG_DIA_GUIDS_LIB)
6667 target_link_libraries(zig LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
6695 target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
66686696endif()
66696697
66706698if(MSVC OR MINGW)
6671 target_link_libraries(zig LINK_PUBLIC version)
6699 target_link_libraries(compiler LINK_PUBLIC version)
66726700endif()
6701
6702add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
6703set_target_properties(zig0 PROPERTIES
6704 COMPILE_FLAGS ${EXE_CFLAGS}
6705 LINK_FLAGS ${EXE_LDFLAGS}
6706)
6707target_link_libraries(zig0 compiler)
6708
6709if(WIN32)
6710 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib")
6711elseif(APPLE)
6712 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.o")
6713else()
6714 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a")
6715endif()
6716add_custom_command(
6717 OUTPUT "${LIBUSERLAND}"
6718 COMMAND zig0 ARGS build
6719 --override-std-dir std
6720 --override-lib-dir "${CMAKE_SOURCE_DIR}"
6721 libuserland
6722 "-Doutput-dir=${CMAKE_BINARY_DIR}"
6723 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
6724 DEPENDS
6725 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
6726 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
6727 "${CMAKE_SOURCE_DIR}/build.zig"
6728)
6729add_custom_target(userland_target DEPENDS "${LIBUSERLAND}")
6730add_executable(zig "${ZIG_MAIN_SRC}")
6731if(MINGW)
6732 set(EXE_LDFLAGS "${EXE_LDFLAGS} -fstack-protector")
6733endif()
6734set_target_properties(zig PROPERTIES
6735 COMPILE_FLAGS ${EXE_CFLAGS}
6736 LINK_FLAGS ${EXE_LDFLAGS}
6737)
6738target_link_libraries(zig compiler "${LIBUSERLAND}")
6739add_dependencies(zig userland_target)
66736740install(TARGETS zig DESTINATION bin)
6674install(TARGETS zig_cpp DESTINATION "${ZIG_CPP_LIB_DIR}")
6741
66756742
66766743foreach(file ${ZIG_C_HEADER_FILES})
66776744 get_filename_component(file_dir "${C_HEADERS_DEST}/${file}" DIRECTORY)
......@@ -6697,7 +6764,3 @@ foreach(file ${ZIG_LIBCXX_FILES})
66976764 get_filename_component(file_dir "${LIBCXX_FILES_DEST}/${file}" DIRECTORY)
66986765 install(FILES "${CMAKE_SOURCE_DIR}/libcxx/${file}" DESTINATION "${file_dir}")
66996766endforeach()
6700
6701install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/arg.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
6702install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/main.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
6703install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/errmsg.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
README.md+104-138
......@@ -1,140 +1,15 @@
11![ZIG](https://ziglang.org/zig-logo.svg)
22
3A programming language designed for robustness, optimality, and
4clarity.
5
6[Download & Documentation](https://ziglang.org/download/)
7
8## Feature Highlights
9
10 * Small, simple language. Focus on debugging your application rather than
11 debugging knowledge of your programming language.
12 * Ships with a build system that obviates the need for a configure script
13 or a makefile. In fact, existing C and C++ projects may choose to depend on
14 Zig instead of e.g. cmake.
15 * A fresh take on error handling which makes writing correct code easier than
16 writing buggy code.
17 * Debug mode optimizes for fast compilation time and crashing with a stack trace
18 when undefined behavior *would* happen.
19 * ReleaseFast mode produces heavily optimized code. What other projects call
20 "Link Time Optimization" Zig does automatically.
21 * Compatible with C libraries with no wrapper necessary. Directly include
22 C .h files and get access to the functions and symbols therein.
23 * Provides standard library which competes with the C standard library and is
24 always compiled against statically in source form. Zig binaries do not
25 depend on libc unless explicitly linked.
26 * Optional type instead of null pointers.
27 * Safe unions, tagged unions, and C ABI compatible unions.
28 * Generics so that one can write efficient data structures that work for any
29 data type.
30 * No header files required. Top level declarations are entirely
31 order-independent.
32 * Compile-time code execution. Compile-time reflection.
33 * Partial compile-time function evaluation which eliminates the need for
34 a preprocessor or macros.
35 * The binaries produced by Zig have complete debugging information so you can,
36 for example, use GDB, MSVC, or LLDB to debug your software.
37 * Built-in unit tests with `zig test`.
38 * Friendly toward package maintainers. Reproducible build, bootstrapping
39 process carefully documented. Issues filed by package maintainers are
40 considered especially important.
41 * Cross-compiling is a primary use case.
42 * In addition to creating executables, creating a C library is a primary use
43 case. You can export an auto-generated .h file.
44
45### Supported Targets
46
47#### Tier 1 Support
48
49 * Not only can Zig generate machine code for these targets, but the standard
50 library cross-platform abstractions have implementations for these targets.
51 Thus it is practical to write a pure Zig application with no dependency on
52 libc.
53 * The CI server automatically tests these targets on every commit to master
54 branch, and updates ziglang.org/download with links to pre-built binaries.
55 * These targets have debug info capabilities and therefore produce stack
56 traces on failed assertions.
57 * ([coming soon](https://github.com/ziglang/zig/issues/514)) libc is available
58 for this target even when cross compiling.
59
60#### Tier 2 Support
61
62 * There may be some standard library implementations, but many abstractions
63 will give an "Unsupported OS" compile error. One can link with libc or other
64 libraries to fill in the gaps in the standard library.
65 * These targets are known to work, but are not automatically tested, so there
66 are occasional regressions.
67 * Some tests may be disabled for these targets as we work toward Tier 1
68 support.
69
70#### Tier 3 Support
71
72 * The standard library has little to no knowledge of the existence of this
73 target.
74 * Because Zig is based on LLVM, it has the capability to build for these
75 targets, and LLVM has the target enabled by default.
76 * These targets are not frequently tested; one will likely need to contribute
77 to Zig in order to build for these targets.
78 * The Zig compiler might need to be updated with a few things such as
79 - what sizes are the C integer types
80 - C ABI calling convention for this target
81 - bootstrap code and default panic handler
82 * `zig targets` is guaranteed to include this target.
83
84#### Tier 4 Support
85
86 * Support for these targets is entirely experimental.
87 * LLVM may have the target as an experimental target, which means that you
88 need to use Zig-provided binaries for the target to be available, or
89 build LLVM from source with special configure flags. `zig targets` will
90 display the target if it is available.
91 * This target may be considered deprecated by an official party,
92 [such as macosx/i386](https://support.apple.com/en-us/HT208436) in which
93 case this target will remain forever stuck in Tier 4.
94 * This target may only support `--emit asm` and cannot emit object files.
95
96#### Support Table
97
98| | freestanding | linux | macosx | windows | freebsd | netbsd | UEFI | other |
99|-------------|--------------|--------|--------|---------|---------|------- | -------|--------|
100|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 2 | Tier 3 |
101|i386 | Tier 2 | Tier 2 | Tier 4 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
102|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
103|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
104|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
105|hexagon | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
106|mips | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
107|powerpc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
108|amdgcn | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
109|sparc | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
110|s390x | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
111|lanai | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | N/A | Tier 3 |
112|wasm32 | Tier 3 | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
113|wasm64 | Tier 3 | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
114|avr | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
115|riscv32 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 |
116|riscv64 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | Tier 4 | Tier 4 |
117|xcore | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
118|nvptx | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
119|msp430 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
120|r600 | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
121|arc | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
122|tce | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
123|le | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
124|amdil | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
125|hsail | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
126|spir | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
127|kalimba | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
128|shave | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
129|renderscript | Tier 4 | Tier 4 | N/A | N/A | Tier 4 | Tier 4 | N/A | Tier 4 |
130
131## Community
132
133 * IRC: `#zig` on Freenode ([Channel Logs](https://irclog.whitequark.org/zig/)).
134 * Reddit: [/r/zig](https://www.reddit.com/r/zig)
135 * Email list: [~andrewrk/ziglang@lists.sr.ht](https://lists.sr.ht/%7Eandrewrk/ziglang)
136
137## Building
3Zig is an open-source programming language designed for **robustness**,
4**optimality**, and **maintainability**.
5
6## Resources
7
8 * [Introduction](https://ziglang.org/#Introduction)
9 * [Download & Documentation](https://ziglang.org/download)
10 * [Community](https://github.com/ziglang/zig/wiki/Community)
11
12## Building from Source
13813
13914[![Build Status](https://dev.azure.com/ziglang/zig/_apis/build/status/ziglang.zig?branchName=master)](https://dev.azure.com/ziglang/zig/_build/latest?definitionId=1&branchName=master)
14015
......@@ -150,12 +25,14 @@ Note that you can
15025 * cmake >= 2.8.5
15126 * gcc >= 5.0.0 or clang >= 3.6.0
15227 * LLVM, Clang, LLD development libraries == 8.x, compiled with the same gcc or clang version above
28 - Use the system package manager, or [build from source](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#posix).
15329
15430##### Windows
15531
15632 * cmake >= 2.8.5
15733 * Microsoft Visual Studio 2017 (version 15.8)
15834 * LLVM, Clang, LLD development libraries == 8.x, compiled with the same MSVC version above
35 - Use the [pre-built binaries](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#pre-built-binaries) or [build from source](https://github.com/ziglang/zig/wiki/How-to-build-LLVM,-libclang,-and-liblld-from-source#windows).
15936
16037#### Instructions
16138
......@@ -165,9 +42,7 @@ Note that you can
16542mkdir build
16643cd build
16744cmake ..
168make
16945make install
170bin/zig build --build-file ../build.zig test
17146```
17247
17348##### MacOS
......@@ -179,7 +54,6 @@ mkdir build
17954cd build
18055cmake .. -DCMAKE_PREFIX_PATH=/usr/local/Cellar/llvm/8.0.0
18156make install
182bin/zig build --build-file ../build.zig test
18357```
18458
18559##### Windows
......@@ -222,3 +96,95 @@ use stage 1.
22296```
22397./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
22498```
99
100## Contributing
101
102### Start a Project Using Zig
103
104One of the best ways you can contribute to Zig is to start using it for a
105personal project. Here are some great examples:
106
107 * [Oxid](https://github.com/dbandstra/oxid) - arcade style game
108 * [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games
109 * [trOS](https://github.com/sjdh02/trOS) - tiny aarch64 baremetal OS thingy
110
111Without fail, these projects lead to discovering bugs and helping flesh out use
112cases, which lead to further design iterations of Zig. Importantly, each issue
113found this way comes with real world motivations, so it is easy to explain
114your reasoning behind proposals and feature requests.
115
116Ideally, such a project will help you to learn new skills and add something
117to your personal portfolio at the same time.
118
119### Spread the Word
120
121Another way to contribute is to write about Zig, or speak about Zig at a
122conference, or do either of those things for your project which uses Zig.
123Here are some examples:
124
125 * [Iterative Replacement of C with Zig](http://tiehuis.github.io/blog/zig1.html)
126 * [The Right Tool for the Right Job: Redis Modules & Zig](https://www.youtube.com/watch?v=eCHM8-_poZY)
127
128Zig is a brand new language, with no advertising budget. Word of mouth is the
129only way people find out about the project, and the more people hear about it,
130the more people will use it, and the better chance we have to take over the
131world.
132
133### Finding Contributor Friendly Issues
134
135Please note that issues labeled
136[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal)
137but do not also have the
138[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted)
139label are still under consideration, and efforts to implement such a proposal
140have a high risk of being wasted. If you are interested in a proposal which is
141still under consideration, please express your interest in the issue tracker,
142providing extra insights and considerations that others have not yet expressed.
143The most highly regarded argument in such a discussion is a real world use case.
144
145The issue label
146[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22)
147exists to help contributors find issues that are "limited in scope and/or
148knowledge of Zig internals."
149
150### Editing Source Code
151
152First, build the Stage 1 compiler as described in [the Building section](#building).
153
154When making changes to the standard library, be sure to edit the files in the
155`std` directory and not the installed copy in the build directory. If you add a
156new file to the standard library, you must also add the file path in
157CMakeLists.txt.
158
159To test changes, do the following from the build directory:
160
1611. Run `make install` (on POSIX) or
162 `msbuild -p:Configuration=Release INSTALL.vcxproj` (on Windows).
1632. `bin/zig build --build-file ../build.zig test` (on POSIX) or
164 `bin\zig.exe build --build-file ..\build.zig test` (on Windows).
165
166That runs the whole test suite, which does a lot of extra testing that you
167likely won't always need, and can take upwards of 2 hours. This is what the
168CI server runs when you make a pull request.
169
170To save time, you can add the `--help` option to the `zig build` command and
171see what options are available. One of the most helpful ones is
172`-Dskip-release`. Adding this option to the command in step 2 above will take
173the time down from around 2 hours to about 6 minutes, and this is a good
174enough amount of testing before making a pull request.
175
176Another example is choosing a different set of things to test. For example,
177`test-std` instead of `test` will only run the standard library tests, and
178not the other ones. Combining this suggestion with the previous one, you could
179do this:
180
181`bin/zig build --build-file ../build.zig test-std -Dskip-release` (on POSIX) or
182`bin\zig.exe build --build-file ..\build.zig test-std -Dskip-release` (on Windows).
183
184This will run only the standard library tests, in debug mode only, for all
185targets (it will cross-compile the tests for non-native targets but not run
186them).
187
188When making changes to the compiler source code, the most helpful test step to
189run is `test-behavior`. When editing documentation it is `docs`. You can find
190this information and more in the `--help` menu.
build.zig+27
......@@ -65,6 +65,8 @@ pub fn build(b: *Builder) !void {
6565
6666 b.default_step.dependOn(&exe.step);
6767
68 addLibUserlandStep(b);
69
6870 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
6971 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
7072 const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;
......@@ -380,3 +382,28 @@ const Context = struct {
380382 dia_guids_lib: []const u8,
381383 llvm: LibraryDep,
382384};
385
386fn addLibUserlandStep(b: *Builder) void {
387 // Sadly macOS requires hacks to work around the buggy MACH-O linker code.
388 const artifact = if (builtin.os == .macosx)
389 b.addObject("userland", "src-self-hosted/stage1.zig")
390 else
391 b.addStaticLibrary("userland", "src-self-hosted/stage1.zig");
392 artifact.disable_gen_h = true;
393 if (builtin.os == .macosx) {
394 artifact.disable_stack_probing = true;
395 } else {
396 artifact.bundle_compiler_rt = true;
397 }
398 artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
399 artifact.linkSystemLibrary("c");
400 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");
401 libuserland_step.dependOn(&artifact.step);
402
403 const output_dir = b.option(
404 []const u8,
405 "output-dir",
406 "For libuserland step, where to put the output",
407 ) orelse return;
408 artifact.setOutputDir(output_dir);
409}
ci/azure/windows_upload+1-1
......@@ -6,7 +6,7 @@ set -e
66if [ "${BUILD_REASON}" != "PullRequest" ]; then
77 cd "$ZIGBUILDDIR"
88
9 rm release/*.lib
9 rm release/*.exe
1010 mv ../LICENSE release/
1111 mv ../zig-cache/langref.html release/
1212 mv release/bin/zig.exe release/
cmake/Findclang.cmake+1-1
......@@ -44,7 +44,7 @@ else()
4444 /usr/local/llvm80/include
4545 /mingw64/include)
4646
47 macro(FIND_AND_ADD_CLANG_LIB _libname_)
47 macro(FIND_AND_ADD_CLANG_LIB _libname_)
4848 string(TOUPPER ${_libname_} _prettylibname_)
4949 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}
5050 PATHS
deps/lld/wasm/OutputSections.cpp+6-6
......@@ -111,8 +111,8 @@ void CodeSection::writeTo(uint8_t *Buf) {
111111 memcpy(Buf, CodeSectionHeader.data(), CodeSectionHeader.size());
112112
113113 // Write code section bodies
114 parallelForEach(Functions,
115 [&](const InputChunk *Chunk) { Chunk->writeTo(Buf); });
114 for (const InputChunk *Chunk : Functions)
115 Chunk->writeTo(Buf);
116116}
117117
118118uint32_t CodeSection::numRelocations() const {
......@@ -176,7 +176,7 @@ void DataSection::writeTo(uint8_t *Buf) {
176176 // Write data section headers
177177 memcpy(Buf, DataSectionHeader.data(), DataSectionHeader.size());
178178
179 parallelForEach(Segments, [&](const OutputSegment *Segment) {
179 for (const OutputSegment *Segment : Segments) {
180180 // Write data segment header
181181 uint8_t *SegStart = Buf + Segment->SectionOffset;
182182 memcpy(SegStart, Segment->Header.data(), Segment->Header.size());
......@@ -184,7 +184,7 @@ void DataSection::writeTo(uint8_t *Buf) {
184184 // Write segment data payload
185185 for (const InputChunk *Chunk : Segment->InputSegments)
186186 Chunk->writeTo(Buf);
187 });
187 }
188188}
189189
190190uint32_t DataSection::numRelocations() const {
......@@ -232,8 +232,8 @@ void CustomSection::writeTo(uint8_t *Buf) {
232232 Buf += NameData.size();
233233
234234 // Write custom sections payload
235 parallelForEach(InputSections,
236 [&](const InputSection *Section) { Section->writeTo(Buf); });
235 for (const InputSection *Section : InputSections)
236 Section->writeTo(Buf);
237237}
238238
239239uint32_t CustomSection::numRelocations() const {
doc/docgen.zig+54-1
......@@ -265,6 +265,7 @@ const SeeAlsoItem = struct {
265265const ExpectedOutcome = enum {
266266 Succeed,
267267 Fail,
268 BuildFail,
268269};
269270
270271const Code = struct {
......@@ -468,6 +469,8 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
468469 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Succeed };
469470 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
470471 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.Fail };
472 } else if (mem.eql(u8, code_kind_str, "exe_build_err")) {
473 code_kind_id = Code.Id{ .Exe = ExpectedOutcome.BuildFail };
471474 } else if (mem.eql(u8, code_kind_str, "test")) {
472475 code_kind_id = Code.Id.Test;
473476 } else if (mem.eql(u8, code_kind_str, "test_err")) {
......@@ -509,6 +512,10 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
509512 target_str = "x86_64-windows";
510513 } else if (mem.eql(u8, end_tag_name, "target_linux_x86_64")) {
511514 target_str = "x86_64-linux";
515 } else if (mem.eql(u8, end_tag_name, "target_wasm")) {
516 target_str = "wasm32-freestanding";
517 } else if (mem.eql(u8, end_tag_name, "target_wasi")) {
518 target_str = "wasm32-wasi";
512519 } else if (mem.eql(u8, end_tag_name, "link_libc")) {
513520 link_libc = true;
514521 } else if (mem.eql(u8, end_tag_name, "code_end")) {
......@@ -1025,6 +1032,8 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
10251032 tmp_dir_name,
10261033 "--name",
10271034 code.name,
1035 "--color",
1036 "on",
10281037 });
10291038 try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);
10301039 switch (code.mode) {
......@@ -1059,14 +1068,52 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
10591068 }
10601069 if (code.target_str) |triple| {
10611070 try build_args.appendSlice([][]const u8{ "-target", triple });
1071 if (!code.is_inline) {
1072 try out.print(" -target {}", triple);
1073 }
1074 }
1075 if (expected_outcome == .BuildFail) {
1076 const result = try os.ChildProcess.exec(
1077 allocator,
1078 build_args.toSliceConst(),
1079 null,
1080 &env_map,
1081 max_doc_file_size,
1082 );
1083 switch (result.term) {
1084 os.ChildProcess.Term.Exited => |exit_code| {
1085 if (exit_code == 0) {
1086 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
1087 for (build_args.toSliceConst()) |arg|
1088 warn("{} ", arg)
1089 else
1090 warn("\n");
1091 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
1092 }
1093 },
1094 else => {
1095 warn("{}\nThe following command crashed:\n", result.stderr);
1096 for (build_args.toSliceConst()) |arg|
1097 warn("{} ", arg)
1098 else
1099 warn("\n");
1100 return parseError(tokenizer, code.source_token, "example compile crashed");
1101 },
1102 }
1103 const escaped_stderr = try escapeHtml(allocator, result.stderr);
1104 const colored_stderr = try termColor(allocator, escaped_stderr);
1105 try out.print("\n{}</code></pre>\n", colored_stderr);
1106 break :code_block;
10621107 }
10631108 _ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
10641109
10651110 if (code.target_str) |triple| {
1066 if (mem.startsWith(u8, triple, "x86_64-linux") and
1111 if (mem.startsWith(u8, triple, "wasm32") or
1112 mem.startsWith(u8, triple, "x86_64-linux") and
10671113 (builtin.os != builtin.Os.linux or builtin.arch != builtin.Arch.x86_64))
10681114 {
10691115 // skip execution
1116 try out.print("</code></pre>\n");
10701117 break :code_block;
10711118 }
10721119 }
......@@ -1130,6 +1177,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
11301177 }
11311178 if (code.target_str) |triple| {
11321179 try test_args.appendSlice([][]const u8{ "-target", triple });
1180 try out.print(" -target {}", triple);
11331181 }
11341182 const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
11351183 const escaped_stderr = try escapeHtml(allocator, result.stderr);
......@@ -1310,6 +1358,11 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
13101358 },
13111359 }
13121360
1361 if (code.target_str) |triple| {
1362 try build_args.appendSlice([][]const u8{ "-target", triple });
1363 try out.print(" -target {}", triple);
1364 }
1365
13131366 if (maybe_error_match) |error_match| {
13141367 const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, &env_map, max_doc_file_size);
13151368 switch (result.term) {
doc/langref.html.in+74-35
......@@ -4,11 +4,12 @@
44 <meta charset="utf-8">
55 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
66 <title>Documentation - The Zig Programming Language</title>
7 <link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNSAxMCIgZmlsbD0iI2Y3YTQxZCI+PHBhdGggZD0iTTAsMSBIMy41IFYzIEgyIFY3IEgzLjY4MiBMMS44ODEsOSBIMCBaIE0xNSw5IEgxMS41IFY3IEgxMyBWMyBIMTEuMzE4IEwxMy4xMTksMSBIMTUgWiBNNCwxIEg5LjkxMiBMMTMuMzI4LDAuMDIxIEw3LjA0NSw3IEgxMSBWOSBINS4wODggTDEuNjcyLDkuOTc5IEw3Ljk1NSwzIEg0IFoiLz48L3N2Zz4="/>
78 <style type="text/css">
89 body{
910 font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
1011 }
11 a {
12 a:not(:hover) {
1213 text-decoration: none;
1314 }
1415 table, th, td {
......@@ -158,13 +159,15 @@
158159 <div id="contents">
159160 {#header_open|Introduction#}
160161 <p>
161 Zig is an open-source programming language designed for <strong>robustness</strong>,
162 <strong>optimality</strong>, and <strong>clarity</strong>.
162 Zig is a general-purpose programming language designed for <strong>robustness</strong>,
163 <strong>optimality</strong>, and <strong>maintainability</strong>.
163164 </p>
164165 <ul>
165166 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>
166167 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>
167 <li><strong>Clear</strong> - precisely communicate your intent to the compiler and other programmers. The language imposes a low overhead to reading code.</li>
168 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and other programmers.
169 The language imposes a low overhead to reading code and is resilient to changing requirements
170 and environments.</li>
168171 </ul>
169172 <p>
170173 Often the most efficient way to learn something new is to see examples, so
......@@ -3125,7 +3128,7 @@ test "while null capture" {
31253128 while (eventuallyNullSequence()) |value| {
31263129 sum2 += value;
31273130 } else {
3128 assert(sum1 == 3);
3131 assert(sum2 == 3);
31293132 }
31303133}
31313134
......@@ -7180,14 +7183,6 @@ pub const FloatMode = enum {
71807183 {#see_also|Floating Point Operations#}
71817184 {#header_close#}
71827185
7183 {#header_open|@setGlobalLinkage#}
7184 <pre>{#syntax#}@setGlobalLinkage(global_variable_name, comptime linkage: GlobalLinkage){#endsyntax#}</pre>
7185 <p>
7186 {#syntax#}GlobalLinkage{#endsyntax#} can be found with {#syntax#}@import("builtin").GlobalLinkage{#endsyntax#}.
7187 </p>
7188 {#see_also|Compile Variables#}
7189 {#header_close#}
7190
71917186 {#header_open|@setRuntimeSafety#}
71927187 <pre>{#syntax#}@setRuntimeSafety(safety_on: bool){#endsyntax#}</pre>
71937188 <p>
......@@ -7217,6 +7212,8 @@ test "@setRuntimeSafety" {
72177212 }
72187213}
72197214 {#code_end#}
7215 <p>Note: it is <a href="https://github.com/ziglang/zig/issues/978">planned</a> to replace
7216 {#syntax#}@setRuntimeSafety{#endsyntax#} with <code>@optimizeFor</code></p>
72207217
72217218 {#header_close#}
72227219
......@@ -7272,6 +7269,10 @@ test "@setRuntimeSafety" {
72727269 consider whether you want to use {#syntax#}@sizeOf(T){#endsyntax#} or
72737270 {#syntax#}@typeInfo(T).Int.bits{#endsyntax#}.
72747271 </p>
7272 <p>
7273 This function measures the size at runtime. For types that are disallowed at runtime, such as
7274 {#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
7275 </p>
72757276 {#see_also|@typeInfo#}
72767277 {#header_close#}
72777278
......@@ -7360,20 +7361,30 @@ fn List(comptime T: type) type {
73607361 <pre>{#syntax#}@truncate(comptime T: type, integer: var) T{#endsyntax#}</pre>
73617362 <p>
73627363 This function truncates bits from an integer type, resulting in a smaller
7363 integer type.
7364 or same-sized integer type.
73647365 </p>
73657366 <p>
7366 The following produces a crash in {#link|Debug#} mode and {#link|Undefined Behavior#} in
7367 {#link|ReleaseFast#} mode:
7367 The following produces safety-checked {#link|Undefined Behavior#}:
73687368 </p>
7369 <pre>{#syntax#}const a: u16 = 0xabcd;
7370const b: u8 = u8(a);{#endsyntax#}</pre>
7369 {#code_begin|test_err|cast truncated bits#}
7370test "integer cast panic" {
7371 var a: u16 = 0xabcd;
7372 var b: u8 = @intCast(u8, a);
7373}
7374 {#code_end#}
73717375 <p>
73727376 However this is well defined and working code:
73737377 </p>
7374 <pre>{#syntax#}const a: u16 = 0xabcd;
7375const b: u8 = @truncate(u8, a);
7376// b is now 0xcd{#endsyntax#}</pre>
7378 {#code_begin|test|truncate#}
7379const std = @import("std");
7380const assert = std.debug.assert;
7381
7382test "integer truncation" {
7383 var a: u16 = 0xabcd;
7384 var b: u8 = @truncate(u8, a);
7385 assert(b == 0xcd);
7386}
7387 {#code_end#}
73777388 <p>
73787389 This function always truncates the significant bits of the integer, regardless
73797390 of endianness on the target platform.
......@@ -8840,20 +8851,21 @@ export fn add(a: i32, b: i32) i32 {
88408851 return a + b;
88418852}
88428853 {#code_end#}
8843 <p>To make a shared library:</p>
8854 <p>To make a static library:</p>
88448855 <pre><code class="shell">$ zig build-lib mathtest.zig
88458856</code></pre>
8846 <p>To make a static library:</p>
8847 <pre><code class="shell">$ zig build-lib mathtest.zig --static
8857 <p>To make a shared library:</p>
8858 <pre><code class="shell">$ zig build-lib mathtest.zig -dynamic
88488859</code></pre>
88498860 <p>Here is an example with the {#link|Zig Build System#}:</p>
88508861 <p class="file">test.c</p>
88518862 <pre><code class="cpp">// This header is generated by zig from mathtest.zig
88528863#include "mathtest.h"
8853#include &lt;assert.h&gt;
8864#include &lt;stdio.h&gt;
88548865
88558866int main(int argc, char **argv) {
8856 assert(add(42, 1337) == 1379);
8867 int32_t result = add(42, 1337);
8868 printf("%d\n", result);
88578869 return 0;
88588870}</code></pre>
88598871 <p class="file">build.zig</p>
......@@ -8863,10 +8875,10 @@ const Builder = @import("std").build.Builder;
88638875pub fn build(b: *Builder) void {
88648876 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
88658877
8866 const exe = b.addCExecutable("test");
8867 exe.addCompileFlags([][]const u8{"-std=c99"});
8868 exe.addSourceFile("test.c");
8878 const exe = b.addExecutable("test", null);
8879 exe.addCSourceFile("test.c", [][]const u8{"-std=c99"});
88698880 exe.linkLibrary(lib);
8881 exe.linkSystemLibrary("c");
88708882
88718883 b.default_step.dependOn(&exe.step);
88728884
......@@ -8877,10 +8889,9 @@ pub fn build(b: *Builder) void {
88778889}
88788890 {#code_end#}
88798891 <p class="file">terminal</p>
8880 <pre><code class="shell">$ zig build
8881$ ./test
8882$ echo $?
88830</code></pre>
8892 <pre><code class="shell">$ zig build test
88931379
8894</code></pre>
88848895 {#see_also|export#}
88858896 {#header_close#}
88868897 {#header_open|Mixing Object Files#}
......@@ -8947,6 +8958,33 @@ all your base are belong to us</code></pre>
89478958 {#see_also|Targets|Zig Build System#}
89488959 {#header_close#}
89498960 {#header_close#}
8961 {#header_open|WebAssembly#}
8962 {#header_open|Freestanding#}
8963 {#code_begin|exe|wasm#}
8964 {#target_wasm#}
8965extern fn print(i32) void;
8966
8967export fn add(a: i32, b: i32) void {
8968 print(a + b);
8969}
8970 {#code_end#}
8971 {#header_close#}
8972 {#header_open|WASI#}
8973 {#code_begin|exe|wasi#}
8974 {#target_wasi#}
8975const std = @import("std");
8976
8977pub fn main() !void {
8978 const args = try std.os.argsAlloc(std.heap.wasm_allocator);
8979 defer std.os.argsFree(std.heap.wasm_allocator, args);
8980
8981 for (args) |arg, i| {
8982 std.debug.warn("{}: {}\n", i, arg);
8983 }
8984}
8985 {#code_end#}
8986 {#header_close#}
8987 {#header_close#}
89508988 {#header_open|Targets#}
89518989 <p>
89528990 Zig supports generating code for all targets that LLVM supports. Here is
......@@ -9430,8 +9468,6 @@ PrimaryExpr
94309468
94319469IfExpr &lt;- IfPrefix Expr (KEYWORD_else Payload? Expr)?
94329470
9433LabeledExpr &lt;- BlockLabel? (Block / LoopExpr)
9434
94359471Block &lt;- LBRACE Statement* RBRACE
94369472
94379473LoopExpr &lt;- KEYWORD_inline? (ForExpr / WhileExpr)
......@@ -9440,6 +9476,8 @@ ForExpr &lt;- ForPrefix Expr (KEYWORD_else Expr)?
94409476
94419477WhileExpr &lt;- WhilePrefix Expr (KEYWORD_else Payload? Expr)?
94429478
9479CurlySuffixExpr &lt;- TypeExpr InitList?
9480
94439481InitList
94449482 &lt;- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
94459483 / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
......@@ -9457,6 +9495,7 @@ PrimaryTypeExpr
94579495 &lt;- BUILTINIDENTIFIER FnCallArguments
94589496 / CHAR_LITERAL
94599497 / ContainerDecl
9498 / DOT IDENTIFIER
94609499 / ErrorSetDecl
94619500 / FLOAT
94629501 / FnProto
src-self-hosted/clang.zig created+866
......@@ -0,0 +1,866 @@
1pub const struct_ZigClangAPValue = @OpaqueType();
2pub const struct_ZigClangAPSInt = @OpaqueType();
3pub const struct_ZigClangASTContext = @OpaqueType();
4pub const struct_ZigClangASTUnit = @OpaqueType();
5pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();
6pub const struct_ZigClangArrayType = @OpaqueType();
7pub const struct_ZigClangAttributedType = @OpaqueType();
8pub const struct_ZigClangBinaryOperator = @OpaqueType();
9pub const struct_ZigClangBreakStmt = @OpaqueType();
10pub const struct_ZigClangBuiltinType = @OpaqueType();
11pub const struct_ZigClangCStyleCastExpr = @OpaqueType();
12pub const struct_ZigClangCallExpr = @OpaqueType();
13pub const struct_ZigClangCaseStmt = @OpaqueType();
14pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
15pub const ZigClangCompoundStmt = @OpaqueType();
16pub const struct_ZigClangConditionalOperator = @OpaqueType();
17pub const struct_ZigClangConstantArrayType = @OpaqueType();
18pub const struct_ZigClangContinueStmt = @OpaqueType();
19pub const struct_ZigClangDecayedType = @OpaqueType();
20pub const struct_ZigClangDecl = @OpaqueType();
21pub const struct_ZigClangDeclRefExpr = @OpaqueType();
22pub const struct_ZigClangDeclStmt = @OpaqueType();
23pub const struct_ZigClangDefaultStmt = @OpaqueType();
24pub const struct_ZigClangDiagnosticOptions = @OpaqueType();
25pub const struct_ZigClangDiagnosticsEngine = @OpaqueType();
26pub const struct_ZigClangDoStmt = @OpaqueType();
27pub const struct_ZigClangElaboratedType = @OpaqueType();
28pub const struct_ZigClangEnumConstantDecl = @OpaqueType();
29pub const struct_ZigClangEnumDecl = @OpaqueType();
30pub const struct_ZigClangEnumType = @OpaqueType();
31pub const struct_ZigClangExpr = @OpaqueType();
32pub const struct_ZigClangFieldDecl = @OpaqueType();
33pub const struct_ZigClangFileID = @OpaqueType();
34pub const struct_ZigClangForStmt = @OpaqueType();
35pub const struct_ZigClangFullSourceLoc = @OpaqueType();
36pub const ZigClangFunctionDecl = @OpaqueType();
37pub const struct_ZigClangFunctionProtoType = @OpaqueType();
38pub const struct_ZigClangIfStmt = @OpaqueType();
39pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
40pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
41pub const struct_ZigClangIntegerLiteral = @OpaqueType();
42pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
43pub const struct_ZigClangMemberExpr = @OpaqueType();
44pub const struct_ZigClangNamedDecl = @OpaqueType();
45pub const struct_ZigClangNone = @OpaqueType();
46pub const struct_ZigClangPCHContainerOperations = @OpaqueType();
47pub const struct_ZigClangParenExpr = @OpaqueType();
48pub const struct_ZigClangParenType = @OpaqueType();
49pub const struct_ZigClangParmVarDecl = @OpaqueType();
50pub const struct_ZigClangPointerType = @OpaqueType();
51pub const struct_ZigClangPreprocessedEntity = @OpaqueType();
52pub const struct_ZigClangRecordDecl = @OpaqueType();
53pub const struct_ZigClangRecordType = @OpaqueType();
54pub const struct_ZigClangReturnStmt = @OpaqueType();
55pub const struct_ZigClangSkipFunctionBodiesScope = @OpaqueType();
56pub const struct_ZigClangSourceManager = @OpaqueType();
57pub const struct_ZigClangSourceRange = @OpaqueType();
58pub const struct_ZigClangStmt = @OpaqueType();
59pub const struct_ZigClangStringLiteral = @OpaqueType();
60pub const struct_ZigClangStringRef = @OpaqueType();
61pub const struct_ZigClangSwitchStmt = @OpaqueType();
62pub const struct_ZigClangTagDecl = @OpaqueType();
63pub const struct_ZigClangType = @OpaqueType();
64pub const struct_ZigClangTypedefNameDecl = @OpaqueType();
65pub const struct_ZigClangTypedefType = @OpaqueType();
66pub const struct_ZigClangUnaryExprOrTypeTraitExpr = @OpaqueType();
67pub const struct_ZigClangUnaryOperator = @OpaqueType();
68pub const struct_ZigClangValueDecl = @OpaqueType();
69pub const struct_ZigClangVarDecl = @OpaqueType();
70pub const struct_ZigClangWhileStmt = @OpaqueType();
71pub const ZigClangFunctionType = @OpaqueType();
72
73pub const ZigClangBO = extern enum {
74 PtrMemD,
75 PtrMemI,
76 Mul,
77 Div,
78 Rem,
79 Add,
80 Sub,
81 Shl,
82 Shr,
83 Cmp,
84 LT,
85 GT,
86 LE,
87 GE,
88 EQ,
89 NE,
90 And,
91 Xor,
92 Or,
93 LAnd,
94 LOr,
95 Assign,
96 MulAssign,
97 DivAssign,
98 RemAssign,
99 AddAssign,
100 SubAssign,
101 ShlAssign,
102 ShrAssign,
103 AndAssign,
104 XorAssign,
105 OrAssign,
106 Comma,
107};
108
109pub const ZigClangUO = extern enum {
110 PostInc,
111 PostDec,
112 PreInc,
113 PreDec,
114 AddrOf,
115 Deref,
116 Plus,
117 Minus,
118 Not,
119 LNot,
120 Real,
121 Imag,
122 Extension,
123 Coawait,
124};
125
126pub const ZigClangTypeClass = extern enum {
127 Builtin,
128 Complex,
129 Pointer,
130 BlockPointer,
131 LValueReference,
132 RValueReference,
133 MemberPointer,
134 ConstantArray,
135 IncompleteArray,
136 VariableArray,
137 DependentSizedArray,
138 DependentSizedExtVector,
139 DependentAddressSpace,
140 Vector,
141 DependentVector,
142 ExtVector,
143 FunctionProto,
144 FunctionNoProto,
145 UnresolvedUsing,
146 Paren,
147 Typedef,
148 Adjusted,
149 Decayed,
150 TypeOfExpr,
151 TypeOf,
152 Decltype,
153 UnaryTransform,
154 Record,
155 Enum,
156 Elaborated,
157 Attributed,
158 TemplateTypeParm,
159 SubstTemplateTypeParm,
160 SubstTemplateTypeParmPack,
161 TemplateSpecialization,
162 Auto,
163 DeducedTemplateSpecialization,
164 InjectedClassName,
165 DependentName,
166 DependentTemplateSpecialization,
167 PackExpansion,
168 ObjCTypeParam,
169 ObjCObject,
170 ObjCInterface,
171 ObjCObjectPointer,
172 Pipe,
173 Atomic,
174};
175
176pub const ZigClangStmtClass = extern enum {
177 NoStmtClass = 0,
178 GCCAsmStmtClass = 1,
179 MSAsmStmtClass = 2,
180 AttributedStmtClass = 3,
181 BreakStmtClass = 4,
182 CXXCatchStmtClass = 5,
183 CXXForRangeStmtClass = 6,
184 CXXTryStmtClass = 7,
185 CapturedStmtClass = 8,
186 CompoundStmtClass = 9,
187 ContinueStmtClass = 10,
188 CoreturnStmtClass = 11,
189 CoroutineBodyStmtClass = 12,
190 DeclStmtClass = 13,
191 DoStmtClass = 14,
192 BinaryConditionalOperatorClass = 15,
193 ConditionalOperatorClass = 16,
194 AddrLabelExprClass = 17,
195 ArrayInitIndexExprClass = 18,
196 ArrayInitLoopExprClass = 19,
197 ArraySubscriptExprClass = 20,
198 ArrayTypeTraitExprClass = 21,
199 AsTypeExprClass = 22,
200 AtomicExprClass = 23,
201 BinaryOperatorClass = 24,
202 CompoundAssignOperatorClass = 25,
203 BlockExprClass = 26,
204 CXXBindTemporaryExprClass = 27,
205 CXXBoolLiteralExprClass = 28,
206 CXXConstructExprClass = 29,
207 CXXTemporaryObjectExprClass = 30,
208 CXXDefaultArgExprClass = 31,
209 CXXDefaultInitExprClass = 32,
210 CXXDeleteExprClass = 33,
211 CXXDependentScopeMemberExprClass = 34,
212 CXXFoldExprClass = 35,
213 CXXInheritedCtorInitExprClass = 36,
214 CXXNewExprClass = 37,
215 CXXNoexceptExprClass = 38,
216 CXXNullPtrLiteralExprClass = 39,
217 CXXPseudoDestructorExprClass = 40,
218 CXXScalarValueInitExprClass = 41,
219 CXXStdInitializerListExprClass = 42,
220 CXXThisExprClass = 43,
221 CXXThrowExprClass = 44,
222 CXXTypeidExprClass = 45,
223 CXXUnresolvedConstructExprClass = 46,
224 CXXUuidofExprClass = 47,
225 CallExprClass = 48,
226 CUDAKernelCallExprClass = 49,
227 CXXMemberCallExprClass = 50,
228 CXXOperatorCallExprClass = 51,
229 UserDefinedLiteralClass = 52,
230 CStyleCastExprClass = 53,
231 CXXFunctionalCastExprClass = 54,
232 CXXConstCastExprClass = 55,
233 CXXDynamicCastExprClass = 56,
234 CXXReinterpretCastExprClass = 57,
235 CXXStaticCastExprClass = 58,
236 ObjCBridgedCastExprClass = 59,
237 ImplicitCastExprClass = 60,
238 CharacterLiteralClass = 61,
239 ChooseExprClass = 62,
240 CompoundLiteralExprClass = 63,
241 ConvertVectorExprClass = 64,
242 CoawaitExprClass = 65,
243 CoyieldExprClass = 66,
244 DeclRefExprClass = 67,
245 DependentCoawaitExprClass = 68,
246 DependentScopeDeclRefExprClass = 69,
247 DesignatedInitExprClass = 70,
248 DesignatedInitUpdateExprClass = 71,
249 ExpressionTraitExprClass = 72,
250 ExtVectorElementExprClass = 73,
251 FixedPointLiteralClass = 74,
252 FloatingLiteralClass = 75,
253 ConstantExprClass = 76,
254 ExprWithCleanupsClass = 77,
255 FunctionParmPackExprClass = 78,
256 GNUNullExprClass = 79,
257 GenericSelectionExprClass = 80,
258 ImaginaryLiteralClass = 81,
259 ImplicitValueInitExprClass = 82,
260 InitListExprClass = 83,
261 IntegerLiteralClass = 84,
262 LambdaExprClass = 85,
263 MSPropertyRefExprClass = 86,
264 MSPropertySubscriptExprClass = 87,
265 MaterializeTemporaryExprClass = 88,
266 MemberExprClass = 89,
267 NoInitExprClass = 90,
268 OMPArraySectionExprClass = 91,
269 ObjCArrayLiteralClass = 92,
270 ObjCAvailabilityCheckExprClass = 93,
271 ObjCBoolLiteralExprClass = 94,
272 ObjCBoxedExprClass = 95,
273 ObjCDictionaryLiteralClass = 96,
274 ObjCEncodeExprClass = 97,
275 ObjCIndirectCopyRestoreExprClass = 98,
276 ObjCIsaExprClass = 99,
277 ObjCIvarRefExprClass = 100,
278 ObjCMessageExprClass = 101,
279 ObjCPropertyRefExprClass = 102,
280 ObjCProtocolExprClass = 103,
281 ObjCSelectorExprClass = 104,
282 ObjCStringLiteralClass = 105,
283 ObjCSubscriptRefExprClass = 106,
284 OffsetOfExprClass = 107,
285 OpaqueValueExprClass = 108,
286 UnresolvedLookupExprClass = 109,
287 UnresolvedMemberExprClass = 110,
288 PackExpansionExprClass = 111,
289 ParenExprClass = 112,
290 ParenListExprClass = 113,
291 PredefinedExprClass = 114,
292 PseudoObjectExprClass = 115,
293 ShuffleVectorExprClass = 116,
294 SizeOfPackExprClass = 117,
295 StmtExprClass = 118,
296 StringLiteralClass = 119,
297 SubstNonTypeTemplateParmExprClass = 120,
298 SubstNonTypeTemplateParmPackExprClass = 121,
299 TypeTraitExprClass = 122,
300 TypoExprClass = 123,
301 UnaryExprOrTypeTraitExprClass = 124,
302 UnaryOperatorClass = 125,
303 VAArgExprClass = 126,
304 ForStmtClass = 127,
305 GotoStmtClass = 128,
306 IfStmtClass = 129,
307 IndirectGotoStmtClass = 130,
308 LabelStmtClass = 131,
309 MSDependentExistsStmtClass = 132,
310 NullStmtClass = 133,
311 OMPAtomicDirectiveClass = 134,
312 OMPBarrierDirectiveClass = 135,
313 OMPCancelDirectiveClass = 136,
314 OMPCancellationPointDirectiveClass = 137,
315 OMPCriticalDirectiveClass = 138,
316 OMPFlushDirectiveClass = 139,
317 OMPDistributeDirectiveClass = 140,
318 OMPDistributeParallelForDirectiveClass = 141,
319 OMPDistributeParallelForSimdDirectiveClass = 142,
320 OMPDistributeSimdDirectiveClass = 143,
321 OMPForDirectiveClass = 144,
322 OMPForSimdDirectiveClass = 145,
323 OMPParallelForDirectiveClass = 146,
324 OMPParallelForSimdDirectiveClass = 147,
325 OMPSimdDirectiveClass = 148,
326 OMPTargetParallelForSimdDirectiveClass = 149,
327 OMPTargetSimdDirectiveClass = 150,
328 OMPTargetTeamsDistributeDirectiveClass = 151,
329 OMPTargetTeamsDistributeParallelForDirectiveClass = 152,
330 OMPTargetTeamsDistributeParallelForSimdDirectiveClass = 153,
331 OMPTargetTeamsDistributeSimdDirectiveClass = 154,
332 OMPTaskLoopDirectiveClass = 155,
333 OMPTaskLoopSimdDirectiveClass = 156,
334 OMPTeamsDistributeDirectiveClass = 157,
335 OMPTeamsDistributeParallelForDirectiveClass = 158,
336 OMPTeamsDistributeParallelForSimdDirectiveClass = 159,
337 OMPTeamsDistributeSimdDirectiveClass = 160,
338 OMPMasterDirectiveClass = 161,
339 OMPOrderedDirectiveClass = 162,
340 OMPParallelDirectiveClass = 163,
341 OMPParallelSectionsDirectiveClass = 164,
342 OMPSectionDirectiveClass = 165,
343 OMPSectionsDirectiveClass = 166,
344 OMPSingleDirectiveClass = 167,
345 OMPTargetDataDirectiveClass = 168,
346 OMPTargetDirectiveClass = 169,
347 OMPTargetEnterDataDirectiveClass = 170,
348 OMPTargetExitDataDirectiveClass = 171,
349 OMPTargetParallelDirectiveClass = 172,
350 OMPTargetParallelForDirectiveClass = 173,
351 OMPTargetTeamsDirectiveClass = 174,
352 OMPTargetUpdateDirectiveClass = 175,
353 OMPTaskDirectiveClass = 176,
354 OMPTaskgroupDirectiveClass = 177,
355 OMPTaskwaitDirectiveClass = 178,
356 OMPTaskyieldDirectiveClass = 179,
357 OMPTeamsDirectiveClass = 180,
358 ObjCAtCatchStmtClass = 181,
359 ObjCAtFinallyStmtClass = 182,
360 ObjCAtSynchronizedStmtClass = 183,
361 ObjCAtThrowStmtClass = 184,
362 ObjCAtTryStmtClass = 185,
363 ObjCAutoreleasePoolStmtClass = 186,
364 ObjCForCollectionStmtClass = 187,
365 ReturnStmtClass = 188,
366 SEHExceptStmtClass = 189,
367 SEHFinallyStmtClass = 190,
368 SEHLeaveStmtClass = 191,
369 SEHTryStmtClass = 192,
370 CaseStmtClass = 193,
371 DefaultStmtClass = 194,
372 SwitchStmtClass = 195,
373 WhileStmtClass = 196,
374};
375
376pub const ZigClangCK = extern enum {
377 Dependent,
378 BitCast,
379 LValueBitCast,
380 LValueToRValue,
381 NoOp,
382 BaseToDerived,
383 DerivedToBase,
384 UncheckedDerivedToBase,
385 Dynamic,
386 ToUnion,
387 ArrayToPointerDecay,
388 FunctionToPointerDecay,
389 NullToPointer,
390 NullToMemberPointer,
391 BaseToDerivedMemberPointer,
392 DerivedToBaseMemberPointer,
393 MemberPointerToBoolean,
394 ReinterpretMemberPointer,
395 UserDefinedConversion,
396 ConstructorConversion,
397 IntegralToPointer,
398 PointerToIntegral,
399 PointerToBoolean,
400 ToVoid,
401 VectorSplat,
402 IntegralCast,
403 IntegralToBoolean,
404 IntegralToFloating,
405 FixedPointCast,
406 FixedPointToBoolean,
407 FloatingToIntegral,
408 FloatingToBoolean,
409 BooleanToSignedIntegral,
410 FloatingCast,
411 CPointerToObjCPointerCast,
412 BlockPointerToObjCPointerCast,
413 AnyPointerToBlockPointerCast,
414 ObjCObjectLValueCast,
415 FloatingRealToComplex,
416 FloatingComplexToReal,
417 FloatingComplexToBoolean,
418 FloatingComplexCast,
419 FloatingComplexToIntegralComplex,
420 IntegralRealToComplex,
421 IntegralComplexToReal,
422 IntegralComplexToBoolean,
423 IntegralComplexCast,
424 IntegralComplexToFloatingComplex,
425 ARCProduceObject,
426 ARCConsumeObject,
427 ARCReclaimReturnedObject,
428 ARCExtendBlockObject,
429 AtomicToNonAtomic,
430 NonAtomicToAtomic,
431 CopyAndAutoreleaseBlockObject,
432 BuiltinFnToFnPtr,
433 ZeroToOCLOpaqueType,
434 AddressSpaceConversion,
435 IntToOCLSampler,
436};
437
438pub const ZigClangAPValueKind = extern enum {
439 Uninitialized,
440 Int,
441 Float,
442 ComplexInt,
443 ComplexFloat,
444 LValue,
445 Vector,
446 Array,
447 Struct,
448 Union,
449 MemberPointer,
450 AddrLabelDiff,
451};
452
453pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation;
454pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8;
455pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
456pub extern fn ZigClangSourceManager_getSpellingColumnNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
457pub extern fn ZigClangSourceManager_getCharacterData(arg0: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8;
458pub extern fn ZigClangASTContext_getPointerType(arg0: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
459pub extern fn ZigClangASTUnit_getASTContext(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
460pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
461pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
462pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl;
463pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl;
464pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
465pub extern fn ZigClangEnumDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
466pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
467pub extern fn ZigClangRecordDecl_getDefinition(arg0: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
468pub extern fn ZigClangEnumDecl_getDefinition(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
469pub extern fn ZigClangRecordDecl_getLocation(arg0: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
470pub extern fn ZigClangEnumDecl_getLocation(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation;
471pub extern fn ZigClangTypedefNameDecl_getLocation(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation;
472pub extern fn ZigClangDecl_getLocation(self: *const ZigClangDecl) ZigClangSourceLocation;
473pub extern fn ZigClangRecordDecl_isUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
474pub extern fn ZigClangRecordDecl_isStruct(record_decl: ?*const struct_ZigClangRecordDecl) bool;
475pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
476pub extern fn ZigClangEnumDecl_getIntegerType(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
477pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
478pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
479pub extern fn ZigClangTypedefType_getDecl(arg0: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
480pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
481pub extern fn ZigClangQualType_getCanonicalType(arg0: struct_ZigClangQualType) struct_ZigClangQualType;
482pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;
483pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void;
484pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
485pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) bool;
486pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool;
487pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool;
488pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
489pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
490pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
491pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
492pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
493pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
494pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
495pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
496pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
497pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
498pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
499pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
500pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
501pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
502pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
503pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
504pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
505pub extern fn ZigClangAPSInt_isNegative(self: ?*const struct_ZigClangAPSInt) bool;
506pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const struct_ZigClangAPSInt;
507pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
508pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
509pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
510pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
511pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void;
512
513pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType;
514pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation;
515pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
516pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
517pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
518pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
519
520pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
521
522pub extern fn ZigClangFunctionType_getNoReturnAttr(self: *const ZigClangFunctionType) bool;
523pub extern fn ZigClangFunctionType_getCallConv(self: *const ZigClangFunctionType) ZigClangCallingConv;
524pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionType) ZigClangQualType;
525
526pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
527pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
528pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
529
530pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
531pub const ZigClangQualType = struct_ZigClangQualType;
532pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
533pub const ZigClangAPValue = struct_ZigClangAPValue;
534pub const ZigClangAPSInt = struct_ZigClangAPSInt;
535pub const ZigClangASTContext = struct_ZigClangASTContext;
536pub const ZigClangASTUnit = struct_ZigClangASTUnit;
537pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr;
538pub const ZigClangArrayType = struct_ZigClangArrayType;
539pub const ZigClangAttributedType = struct_ZigClangAttributedType;
540pub const ZigClangBinaryOperator = struct_ZigClangBinaryOperator;
541pub const ZigClangBreakStmt = struct_ZigClangBreakStmt;
542pub const ZigClangBuiltinType = struct_ZigClangBuiltinType;
543pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr;
544pub const ZigClangCallExpr = struct_ZigClangCallExpr;
545pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
546pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
547pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
548pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
549pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
550pub const ZigClangDecayedType = struct_ZigClangDecayedType;
551pub const ZigClangDecl = struct_ZigClangDecl;
552pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr;
553pub const ZigClangDeclStmt = struct_ZigClangDeclStmt;
554pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt;
555pub const ZigClangDiagnosticOptions = struct_ZigClangDiagnosticOptions;
556pub const ZigClangDiagnosticsEngine = struct_ZigClangDiagnosticsEngine;
557pub const ZigClangDoStmt = struct_ZigClangDoStmt;
558pub const ZigClangElaboratedType = struct_ZigClangElaboratedType;
559pub const ZigClangEnumConstantDecl = struct_ZigClangEnumConstantDecl;
560pub const ZigClangEnumDecl = struct_ZigClangEnumDecl;
561pub const ZigClangEnumType = struct_ZigClangEnumType;
562pub const ZigClangExpr = struct_ZigClangExpr;
563pub const ZigClangFieldDecl = struct_ZigClangFieldDecl;
564pub const ZigClangFileID = struct_ZigClangFileID;
565pub const ZigClangForStmt = struct_ZigClangForStmt;
566pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc;
567pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType;
568pub const ZigClangIfStmt = struct_ZigClangIfStmt;
569pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
570pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
571pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
572pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
573pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
574pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
575pub const ZigClangNone = struct_ZigClangNone;
576pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
577pub const ZigClangParenExpr = struct_ZigClangParenExpr;
578pub const ZigClangParenType = struct_ZigClangParenType;
579pub const ZigClangParmVarDecl = struct_ZigClangParmVarDecl;
580pub const ZigClangPointerType = struct_ZigClangPointerType;
581pub const ZigClangPreprocessedEntity = struct_ZigClangPreprocessedEntity;
582pub const ZigClangRecordDecl = struct_ZigClangRecordDecl;
583pub const ZigClangRecordType = struct_ZigClangRecordType;
584pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
585pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
586pub const ZigClangSourceManager = struct_ZigClangSourceManager;
587pub const ZigClangSourceRange = struct_ZigClangSourceRange;
588pub const ZigClangStmt = struct_ZigClangStmt;
589pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
590pub const ZigClangStringRef = struct_ZigClangStringRef;
591pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
592pub const ZigClangTagDecl = struct_ZigClangTagDecl;
593pub const ZigClangType = struct_ZigClangType;
594pub const ZigClangTypedefNameDecl = struct_ZigClangTypedefNameDecl;
595pub const ZigClangTypedefType = struct_ZigClangTypedefType;
596pub const ZigClangUnaryExprOrTypeTraitExpr = struct_ZigClangUnaryExprOrTypeTraitExpr;
597pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator;
598pub const ZigClangValueDecl = struct_ZigClangValueDecl;
599pub const ZigClangVarDecl = struct_ZigClangVarDecl;
600pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
601
602pub const struct_ZigClangSourceLocation = extern struct {
603 ID: c_uint,
604};
605
606pub const Stage2ErrorMsg = extern struct {
607 filename_ptr: ?[*]const u8,
608 filename_len: usize,
609 msg_ptr: [*]const u8,
610 msg_len: usize,
611 // valid until the ASTUnit is freed
612 source: ?[*]const u8,
613 // 0 based
614 line: c_uint,
615 // 0 based
616 column: c_uint,
617 // byte offset into source
618 offset: c_uint,
619};
620pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void;
621
622pub extern fn ZigClangLoadFromCommandLine(
623 args_begin: [*]?[*]const u8,
624 args_end: [*]?[*]const u8,
625 errors_ptr: *[*]Stage2ErrorMsg,
626 errors_len: *usize,
627 resources_path: [*c]const u8,
628) ?*ZigClangASTUnit;
629
630pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
631pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*]const u8;
632
633pub const ZigClangDeclKind = extern enum {
634 AccessSpec,
635 Block,
636 Captured,
637 ClassScopeFunctionSpecialization,
638 Empty,
639 Export,
640 ExternCContext,
641 FileScopeAsm,
642 Friend,
643 FriendTemplate,
644 Import,
645 LinkageSpec,
646 Label,
647 Namespace,
648 NamespaceAlias,
649 ObjCCompatibleAlias,
650 ObjCCategory,
651 ObjCCategoryImpl,
652 ObjCImplementation,
653 ObjCInterface,
654 ObjCProtocol,
655 ObjCMethod,
656 ObjCProperty,
657 BuiltinTemplate,
658 ClassTemplate,
659 FunctionTemplate,
660 TypeAliasTemplate,
661 VarTemplate,
662 TemplateTemplateParm,
663 Enum,
664 Record,
665 CXXRecord,
666 ClassTemplateSpecialization,
667 ClassTemplatePartialSpecialization,
668 TemplateTypeParm,
669 ObjCTypeParam,
670 TypeAlias,
671 Typedef,
672 UnresolvedUsingTypename,
673 Using,
674 UsingDirective,
675 UsingPack,
676 UsingShadow,
677 ConstructorUsingShadow,
678 Binding,
679 Field,
680 ObjCAtDefsField,
681 ObjCIvar,
682 Function,
683 CXXDeductionGuide,
684 CXXMethod,
685 CXXConstructor,
686 CXXConversion,
687 CXXDestructor,
688 MSProperty,
689 NonTypeTemplateParm,
690 Var,
691 Decomposition,
692 ImplicitParam,
693 OMPCapturedExpr,
694 ParmVar,
695 VarTemplateSpecialization,
696 VarTemplatePartialSpecialization,
697 EnumConstant,
698 IndirectField,
699 OMPDeclareReduction,
700 UnresolvedUsingValue,
701 OMPRequires,
702 OMPThreadPrivate,
703 ObjCPropertyImpl,
704 PragmaComment,
705 PragmaDetectMismatch,
706 StaticAssert,
707 TranslationUnit,
708};
709
710pub const struct_ZigClangQualType = extern struct {
711 ptr: ?*c_void,
712};
713
714pub const ZigClangBuiltinTypeKind = extern enum {
715 OCLImage1dRO,
716 OCLImage1dArrayRO,
717 OCLImage1dBufferRO,
718 OCLImage2dRO,
719 OCLImage2dArrayRO,
720 OCLImage2dDepthRO,
721 OCLImage2dArrayDepthRO,
722 OCLImage2dMSAARO,
723 OCLImage2dArrayMSAARO,
724 OCLImage2dMSAADepthRO,
725 OCLImage2dArrayMSAADepthRO,
726 OCLImage3dRO,
727 OCLImage1dWO,
728 OCLImage1dArrayWO,
729 OCLImage1dBufferWO,
730 OCLImage2dWO,
731 OCLImage2dArrayWO,
732 OCLImage2dDepthWO,
733 OCLImage2dArrayDepthWO,
734 OCLImage2dMSAAWO,
735 OCLImage2dArrayMSAAWO,
736 OCLImage2dMSAADepthWO,
737 OCLImage2dArrayMSAADepthWO,
738 OCLImage3dWO,
739 OCLImage1dRW,
740 OCLImage1dArrayRW,
741 OCLImage1dBufferRW,
742 OCLImage2dRW,
743 OCLImage2dArrayRW,
744 OCLImage2dDepthRW,
745 OCLImage2dArrayDepthRW,
746 OCLImage2dMSAARW,
747 OCLImage2dArrayMSAARW,
748 OCLImage2dMSAADepthRW,
749 OCLImage2dArrayMSAADepthRW,
750 OCLImage3dRW,
751 OCLIntelSubgroupAVCMcePayload,
752 OCLIntelSubgroupAVCImePayload,
753 OCLIntelSubgroupAVCRefPayload,
754 OCLIntelSubgroupAVCSicPayload,
755 OCLIntelSubgroupAVCMceResult,
756 OCLIntelSubgroupAVCImeResult,
757 OCLIntelSubgroupAVCRefResult,
758 OCLIntelSubgroupAVCSicResult,
759 OCLIntelSubgroupAVCImeResultSingleRefStreamout,
760 OCLIntelSubgroupAVCImeResultDualRefStreamout,
761 OCLIntelSubgroupAVCImeSingleRefStreamin,
762 OCLIntelSubgroupAVCImeDualRefStreamin,
763 Void,
764 Bool,
765 Char_U,
766 UChar,
767 WChar_U,
768 Char8,
769 Char16,
770 Char32,
771 UShort,
772 UInt,
773 ULong,
774 ULongLong,
775 UInt128,
776 Char_S,
777 SChar,
778 WChar_S,
779 Short,
780 Int,
781 Long,
782 LongLong,
783 Int128,
784 ShortAccum,
785 Accum,
786 LongAccum,
787 UShortAccum,
788 UAccum,
789 ULongAccum,
790 ShortFract,
791 Fract,
792 LongFract,
793 UShortFract,
794 UFract,
795 ULongFract,
796 SatShortAccum,
797 SatAccum,
798 SatLongAccum,
799 SatUShortAccum,
800 SatUAccum,
801 SatULongAccum,
802 SatShortFract,
803 SatFract,
804 SatLongFract,
805 SatUShortFract,
806 SatUFract,
807 SatULongFract,
808 Half,
809 Float,
810 Double,
811 LongDouble,
812 Float16,
813 Float128,
814 NullPtr,
815 ObjCId,
816 ObjCClass,
817 ObjCSel,
818 OCLSampler,
819 OCLEvent,
820 OCLClkEvent,
821 OCLQueue,
822 OCLReserveID,
823 Dependent,
824 Overload,
825 BoundMember,
826 PseudoObject,
827 UnknownAny,
828 BuiltinFn,
829 ARCUnbridgedCast,
830 OMPArraySection,
831};
832
833pub const ZigClangCallingConv = extern enum {
834 C,
835 X86StdCall,
836 X86FastCall,
837 X86ThisCall,
838 X86VectorCall,
839 X86Pascal,
840 Win64,
841 X86_64SysV,
842 X86RegCall,
843 AAPCS,
844 AAPCS_VFP,
845 IntelOclBicc,
846 SpirFunction,
847 OpenCLKernel,
848 Swift,
849 PreserveMost,
850 PreserveAll,
851 AArch64VectorCall,
852};
853
854pub const ZigClangStorageClass = extern enum {
855 None,
856 Extern,
857 Static,
858 PrivateExtern,
859 Auto,
860 Register,
861};
862
863pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt;
864
865pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
866pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
src-self-hosted/compilation.zig+4-6
......@@ -569,9 +569,9 @@ pub const Compilation = struct {
569569 'i', 'u' => blk: {
570570 for (name[1..]) |byte|
571571 switch (byte) {
572 '0'...'9' => {},
573 else => break :blk,
574 };
572 '0'...'9' => {},
573 else => break :blk,
574 };
575575 const is_signed = name[0] == 'i';
576576 const bit_count = std.fmt.parseUnsigned(u32, name[1..], 10) catch |err| switch (err) {
577577 error.Overflow => return error.Overflow,
......@@ -841,11 +841,9 @@ pub const Compilation = struct {
841841 };
842842 errdefer self.gpa().free(source_code);
843843
844 const tree = try self.gpa().create(ast.Tree);
845 tree.* = try std.zig.parse(self.gpa(), source_code);
844 const tree = try std.zig.parse(self.gpa(), source_code);
846845 errdefer {
847846 tree.deinit();
848 self.gpa().destroy(tree);
849847 }
850848
851849 break :blk try Scope.AstTree.create(self, tree, root_scope);
src-self-hosted/main.zig+9-9
......@@ -625,7 +625,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
625625 const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);
626626 defer allocator.free(source_code);
627627
628 var tree = std.zig.parse(allocator, source_code) catch |err| {
628 const tree = std.zig.parse(allocator, source_code) catch |err| {
629629 try stderr.print("error parsing stdin: {}\n", err);
630630 os.exit(1);
631631 };
......@@ -633,7 +633,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
633633
634634 var error_it = tree.errors.iterator(0);
635635 while (error_it.next()) |parse_error| {
636 const msg = try errmsg.Msg.createFromParseError(allocator, parse_error, &tree, "<stdin>");
636 const msg = try errmsg.Msg.createFromParseError(allocator, parse_error, tree, "<stdin>");
637637 defer msg.destroy();
638638
639639 try msg.printToFile(stderr_file, color);
......@@ -642,12 +642,12 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
642642 os.exit(1);
643643 }
644644 if (flags.present("check")) {
645 const anything_changed = try std.zig.render(allocator, io.null_out_stream, &tree);
645 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
646646 const code = if (anything_changed) u8(1) else u8(0);
647647 os.exit(code);
648648 }
649649
650 _ = try std.zig.render(allocator, stdout, &tree);
650 _ = try std.zig.render(allocator, stdout, tree);
651651 return;
652652 }
653653
......@@ -768,7 +768,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
768768 };
769769 defer fmt.loop.allocator.free(source_code);
770770
771 var tree = std.zig.parse(fmt.loop.allocator, source_code) catch |err| {
771 const tree = std.zig.parse(fmt.loop.allocator, source_code) catch |err| {
772772 try stderr.print("error parsing file '{}': {}\n", file_path, err);
773773 fmt.any_error = true;
774774 return;
......@@ -777,7 +777,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
777777
778778 var error_it = tree.errors.iterator(0);
779779 while (error_it.next()) |parse_error| {
780 const msg = try errmsg.Msg.createFromParseError(fmt.loop.allocator, parse_error, &tree, file_path);
780 const msg = try errmsg.Msg.createFromParseError(fmt.loop.allocator, parse_error, tree, file_path);
781781 defer fmt.loop.allocator.destroy(msg);
782782
783783 try msg.printToFile(stderr_file, fmt.color);
......@@ -788,7 +788,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
788788 }
789789
790790 if (check_mode) {
791 const anything_changed = try std.zig.render(fmt.loop.allocator, io.null_out_stream, &tree);
791 const anything_changed = try std.zig.render(fmt.loop.allocator, io.null_out_stream, tree);
792792 if (anything_changed) {
793793 try stderr.print("{}\n", file_path);
794794 fmt.any_error = true;
......@@ -798,7 +798,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
798798 const baf = try io.BufferedAtomicFile.create(fmt.loop.allocator, file_path);
799799 defer baf.destroy();
800800
801 const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), &tree);
801 const anything_changed = try std.zig.render(fmt.loop.allocator, baf.stream(), tree);
802802 if (anything_changed) {
803803 try stderr.print("{}\n", file_path);
804804 try baf.finish();
......@@ -858,7 +858,7 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {
858858 try stdout.write(usage);
859859}
860860
861const info_zen =
861pub const info_zen =
862862 \\
863863 \\ * Communicate intent precisely.
864864 \\ * Edge cases matter.
src-self-hosted/scope.zig-1
......@@ -163,7 +163,6 @@ pub const Scope = struct {
163163 pub fn destroy(self: *AstTree, comp: *Compilation) void {
164164 comp.gpa().free(self.tree.source);
165165 self.tree.deinit();
166 comp.gpa().destroy(self.tree);
167166 comp.gpa().destroy(self);
168167 }
169168
src-self-hosted/stage1.zig created+397
......@@ -0,0 +1,397 @@
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 builtin = @import("builtin");
6
7// ABI warning
8export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
9 const info_zen = @import("main.zig").info_zen;
10 ptr.* = &info_zen;
11 len.* = info_zen.len;
12}
13
14// ABI warning
15export fn stage2_panic(ptr: [*]const u8, len: usize) void {
16 @panic(ptr[0..len]);
17}
18
19// ABI warning
20const TranslateMode = extern enum {
21 import,
22 translate,
23};
24
25// ABI warning
26const Error = extern enum {
27 None,
28 OutOfMemory,
29 InvalidFormat,
30 SemanticAnalyzeFail,
31 AccessDenied,
32 Interrupted,
33 SystemResources,
34 FileNotFound,
35 FileSystem,
36 FileTooBig,
37 DivByZero,
38 Overflow,
39 PathAlreadyExists,
40 Unexpected,
41 ExactDivRemainder,
42 NegativeDenominator,
43 ShiftedOutOneBits,
44 CCompileErrors,
45 EndOfFile,
46 IsDir,
47 NotDir,
48 UnsupportedOperatingSystem,
49 SharingViolation,
50 PipeBusy,
51 PrimitiveTypeNotFound,
52 CacheUnavailable,
53 PathTooLong,
54 CCompilerCannotFindFile,
55 ReadingDepFile,
56 InvalidDepFile,
57 MissingArchitecture,
58 MissingOperatingSystem,
59 UnknownArchitecture,
60 UnknownOperatingSystem,
61 UnknownABI,
62 InvalidFilename,
63 DiskQuota,
64 DiskSpace,
65 UnexpectedWriteFailure,
66 UnexpectedSeekFailure,
67 UnexpectedFileTruncationFailure,
68 Unimplemented,
69 OperationAborted,
70 BrokenPipe,
71 NoSpaceLeft,
72};
73
74const FILE = std.c.FILE;
75const ast = std.zig.ast;
76const translate_c = @import("translate_c.zig");
77
78/// Args should have a null terminating last arg.
79export fn stage2_translate_c(
80 out_ast: **ast.Tree,
81 out_errors_ptr: *[*]translate_c.ClangErrMsg,
82 out_errors_len: *usize,
83 args_begin: [*]?[*]const u8,
84 args_end: [*]?[*]const u8,
85 mode: TranslateMode,
86 resources_path: [*]const u8,
87) Error {
88 var errors: []translate_c.ClangErrMsg = undefined;
89 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, switch (mode) {
90 .import => translate_c.Mode.import,
91 .translate => translate_c.Mode.translate,
92 }, &errors, resources_path) catch |err| switch (err) {
93 // TODO after https://github.com/ziglang/zig/issues/769 we can remove error.UnsupportedType
94 error.SemanticAnalyzeFail, error.UnsupportedType => {
95 out_errors_ptr.* = errors.ptr;
96 out_errors_len.* = errors.len;
97 return Error.CCompileErrors;
98 },
99 error.OutOfMemory => return Error.OutOfMemory,
100 };
101 return Error.None;
102}
103
104export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
105 translate_c.freeErrors(errors_ptr[0..errors_len]);
106}
107
108export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
109 const c_out_stream = &std.io.COutStream.init(output_file).stream;
110 _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
111 error.SystemResources => return Error.SystemResources,
112 error.OperationAborted => return Error.OperationAborted,
113 error.BrokenPipe => return Error.BrokenPipe,
114 error.DiskQuota => return Error.DiskQuota,
115 error.FileTooBig => return Error.FileTooBig,
116 error.NoSpaceLeft => return Error.NoSpaceLeft,
117 error.AccessDenied => return Error.AccessDenied,
118 error.OutOfMemory => return Error.OutOfMemory,
119 error.Unexpected => return Error.Unexpected,
120 error.InputOutput => return Error.FileSystem,
121 };
122 return Error.None;
123}
124
125// TODO: just use the actual self-hosted zig fmt. Until the coroutine rewrite, we use a blocking implementation.
126export fn stage2_fmt(argc: c_int, argv: [*]const [*]const u8) c_int {
127 if (std.debug.runtime_safety) {
128 fmtMain(argc, argv) catch unreachable;
129 } else {
130 fmtMain(argc, argv) catch |e| {
131 std.debug.warn("{}\n", @errorName(e));
132 return -1;
133 };
134 }
135 return 0;
136}
137
138fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
139 const allocator = std.heap.c_allocator;
140 var args_list = std.ArrayList([]const u8).init(allocator);
141 const argc_usize = @intCast(usize, argc);
142 var arg_i: usize = 0;
143 while (arg_i < argc_usize) : (arg_i += 1) {
144 try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));
145 }
146
147 var stdout_file = try std.io.getStdOut();
148 var stdout_out_stream = stdout_file.outStream();
149 stdout = &stdout_out_stream.stream;
150
151 stderr_file = try std.io.getStdErr();
152 var stderr_out_stream = stderr_file.outStream();
153 stderr = &stderr_out_stream.stream;
154
155 const args = args_list.toSliceConst();
156 var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[2..]);
157 defer flags.deinit();
158
159 if (flags.present("help")) {
160 try stdout.write(self_hosted_main.usage_fmt);
161 os.exit(0);
162 }
163
164 const color = blk: {
165 if (flags.single("color")) |color_flag| {
166 if (mem.eql(u8, color_flag, "auto")) {
167 break :blk errmsg.Color.Auto;
168 } else if (mem.eql(u8, color_flag, "on")) {
169 break :blk errmsg.Color.On;
170 } else if (mem.eql(u8, color_flag, "off")) {
171 break :blk errmsg.Color.Off;
172 } else unreachable;
173 } else {
174 break :blk errmsg.Color.Auto;
175 }
176 };
177
178 if (flags.present("stdin")) {
179 if (flags.positionals.len != 0) {
180 try stderr.write("cannot use --stdin with positional arguments\n");
181 os.exit(1);
182 }
183
184 var stdin_file = try io.getStdIn();
185 var stdin = stdin_file.inStream();
186
187 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
188 defer allocator.free(source_code);
189
190 const tree = std.zig.parse(allocator, source_code) catch |err| {
191 try stderr.print("error parsing stdin: {}\n", err);
192 os.exit(1);
193 };
194 defer tree.deinit();
195
196 var error_it = tree.errors.iterator(0);
197 while (error_it.next()) |parse_error| {
198 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
199 }
200 if (tree.errors.len != 0) {
201 os.exit(1);
202 }
203 if (flags.present("check")) {
204 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
205 const code = if (anything_changed) u8(1) else u8(0);
206 os.exit(code);
207 }
208
209 _ = try std.zig.render(allocator, stdout, tree);
210 return;
211 }
212
213 if (flags.positionals.len == 0) {
214 try stderr.write("expected at least one source file argument\n");
215 os.exit(1);
216 }
217
218 var fmt = Fmt{
219 .seen = Fmt.SeenMap.init(allocator),
220 .any_error = false,
221 .color = color,
222 .allocator = allocator,
223 };
224
225 const check_mode = flags.present("check");
226
227 for (flags.positionals.toSliceConst()) |file_path| {
228 try fmtPath(&fmt, file_path, check_mode);
229 }
230 if (fmt.any_error) {
231 os.exit(1);
232 }
233}
234
235const FmtError = error{
236 SystemResources,
237 OperationAborted,
238 IoPending,
239 BrokenPipe,
240 Unexpected,
241 WouldBlock,
242 FileClosed,
243 DestinationAddressRequired,
244 DiskQuota,
245 FileTooBig,
246 InputOutput,
247 NoSpaceLeft,
248 AccessDenied,
249 OutOfMemory,
250 RenameAcrossMountPoints,
251 ReadOnlyFileSystem,
252 LinkQuotaExceeded,
253 FileBusy,
254} || os.File.OpenError;
255
256fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
257 const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
258 defer fmt.allocator.free(file_path);
259
260 if (try fmt.seen.put(file_path, {})) |_| return;
261
262 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
263 error.IsDir, error.AccessDenied => {
264 // TODO make event based (and dir.next())
265 var dir = try std.os.Dir.open(fmt.allocator, file_path);
266 defer dir.close();
267
268 while (try dir.next()) |entry| {
269 if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
270 const full_path = try os.path.join(fmt.allocator, [][]const u8{ file_path, entry.name });
271 try fmtPath(fmt, full_path, check_mode);
272 }
273 }
274 return;
275 },
276 else => {
277 // TODO lock stderr printing
278 try stderr.print("unable to open '{}': {}\n", file_path, err);
279 fmt.any_error = true;
280 return;
281 },
282 };
283 defer fmt.allocator.free(source_code);
284
285 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
286 try stderr.print("error parsing file '{}': {}\n", file_path, err);
287 fmt.any_error = true;
288 return;
289 };
290 defer tree.deinit();
291
292 var error_it = tree.errors.iterator(0);
293 while (error_it.next()) |parse_error| {
294 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
295 }
296 if (tree.errors.len != 0) {
297 fmt.any_error = true;
298 return;
299 }
300
301 if (check_mode) {
302 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
303 if (anything_changed) {
304 try stderr.print("{}\n", file_path);
305 fmt.any_error = true;
306 }
307 } else {
308 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
309 defer baf.destroy();
310
311 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
312 if (anything_changed) {
313 try stderr.print("{}\n", file_path);
314 try baf.finish();
315 }
316 }
317}
318
319const Fmt = struct {
320 seen: SeenMap,
321 any_error: bool,
322 color: errmsg.Color,
323 allocator: *mem.Allocator,
324
325 const SeenMap = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
326};
327
328fn printErrMsgToFile(
329 allocator: *mem.Allocator,
330 parse_error: *const ast.Error,
331 tree: *ast.Tree,
332 path: []const u8,
333 file: os.File,
334 color: errmsg.Color,
335) !void {
336 const color_on = switch (color) {
337 errmsg.Color.Auto => file.isTty(),
338 errmsg.Color.On => true,
339 errmsg.Color.Off => false,
340 };
341 const lok_token = parse_error.loc();
342 const span = errmsg.Span{
343 .first = lok_token,
344 .last = lok_token,
345 };
346
347 const first_token = tree.tokens.at(span.first);
348 const last_token = tree.tokens.at(span.last);
349 const start_loc = tree.tokenLocationPtr(0, first_token);
350 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
351
352 var text_buf = try std.Buffer.initSize(allocator, 0);
353 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
354 try parse_error.render(&tree.tokens, out_stream);
355 const text = text_buf.toOwnedSlice();
356
357 const stream = &file.outStream().stream;
358 if (!color_on) {
359 try stream.print(
360 "{}:{}:{}: error: {}\n",
361 path,
362 start_loc.line + 1,
363 start_loc.column + 1,
364 text,
365 );
366 return;
367 }
368
369 try stream.print(
370 "{}:{}:{}: error: {}\n{}\n",
371 path,
372 start_loc.line + 1,
373 start_loc.column + 1,
374 text,
375 tree.source[start_loc.line_start..start_loc.line_end],
376 );
377 try stream.writeByteNTimes(' ', start_loc.column);
378 try stream.writeByteNTimes('~', last_token.end - first_token.start);
379 try stream.write("\n");
380}
381
382const os = std.os;
383const io = std.io;
384const mem = std.mem;
385const Allocator = mem.Allocator;
386const ArrayList = std.ArrayList;
387const Buffer = std.Buffer;
388
389const arg = @import("arg.zig");
390const self_hosted_main = @import("main.zig");
391const Args = arg.Args;
392const Flag = arg.Flag;
393const errmsg = @import("errmsg.zig");
394
395var stderr_file: os.File = undefined;
396var stderr: *io.OutStream(os.File.WriteError) = undefined;
397var stdout: *io.OutStream(os.File.WriteError) = undefined;
src-self-hosted/translate_c.zig created+682
......@@ -0,0 +1,682 @@
1// This is the userland implementation of translate-c which will be used by both stage1
2// and stage2. Currently the only way it is used is with `zig translate-c-2`.
3
4const std = @import("std");
5const builtin = @import("builtin");
6const assert = std.debug.assert;
7const ast = std.zig.ast;
8const Token = std.zig.Token;
9use @import("clang.zig");
10
11pub const Mode = enum {
12 import,
13 translate,
14};
15
16// TODO merge with Type.Fn.CallingConvention
17const CallingConvention = builtin.TypeInfo.CallingConvention;
18
19pub const ClangErrMsg = Stage2ErrorMsg;
20
21pub const Error = error{
22 OutOfMemory,
23 UnsupportedType,
24};
25pub const TransError = error{
26 OutOfMemory,
27 UnsupportedTranslation,
28};
29
30const DeclTable = std.HashMap(usize, void, addrHash, addrEql);
31
32fn addrHash(x: usize) u32 {
33 switch (@typeInfo(usize).Int.bits) {
34 32 => return x,
35 // pointers are usually aligned so we ignore the bits that are probably all 0 anyway
36 // usually the larger bits of addr space are unused so we just chop em off
37 64 => return @truncate(u32, x >> 4),
38 else => @compileError("unreachable"),
39 }
40}
41
42fn addrEql(a: usize, b: usize) bool {
43 return a == b;
44}
45
46const Scope = struct {
47 id: Id,
48 parent: ?*Scope,
49
50 const Id = enum {
51 Switch,
52 Var,
53 Block,
54 Root,
55 While,
56 };
57 const Switch = struct {
58 base: Scope,
59 };
60
61 const Var = struct {
62 base: Scope,
63 c_name: []const u8,
64 zig_name: []const u8,
65 };
66
67 const Block = struct {
68 base: Scope,
69 block_node: *ast.Node.Block,
70
71 /// Don't forget to set rbrace token later
72 fn create(c: *Context, parent: *Scope, lbrace_tok: ast.TokenIndex) !*Block {
73 const block = try c.a().create(Block);
74 block.* = Block{
75 .base = Scope{
76 .id = Id.Block,
77 .parent = parent,
78 },
79 .block_node = try c.a().create(ast.Node.Block),
80 };
81 block.block_node.* = ast.Node.Block{
82 .base = ast.Node{ .id = ast.Node.Id.Block },
83 .label = null,
84 .lbrace = lbrace_tok,
85 .statements = ast.Node.Block.StatementList.init(c.a()),
86 .rbrace = undefined,
87 };
88 return block;
89 }
90 };
91
92 const Root = struct {
93 base: Scope,
94 };
95
96 const While = struct {
97 base: Scope,
98 };
99};
100
101const TransResult = struct {
102 node: *ast.Node,
103 node_scope: *Scope,
104 child_scope: *Scope,
105};
106
107const Context = struct {
108 tree: *ast.Tree,
109 source_buffer: *std.Buffer,
110 err: Error,
111 source_manager: *ZigClangSourceManager,
112 decl_table: DeclTable,
113 global_scope: *Scope.Root,
114 mode: Mode,
115
116 fn a(c: *Context) *std.mem.Allocator {
117 return &c.tree.arena_allocator.allocator;
118 }
119
120 /// Convert a null-terminated C string to a slice allocated in the arena
121 fn str(c: *Context, s: [*]const u8) ![]u8 {
122 return std.mem.dupe(c.a(), u8, std.mem.toSliceConst(u8, s));
123 }
124
125 /// Convert a clang source location to a file:line:column string
126 fn locStr(c: *Context, loc: ZigClangSourceLocation) ![]u8 {
127 const spelling_loc = ZigClangSourceManager_getSpellingLoc(c.source_manager, loc);
128 const filename_c = ZigClangSourceManager_getFilename(c.source_manager, spelling_loc);
129 const filename = if (filename_c) |s| try c.str(s) else ([]const u8)("(no file)");
130
131 const line = ZigClangSourceManager_getSpellingLineNumber(c.source_manager, spelling_loc);
132 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
133 return std.fmt.allocPrint(c.a(), "{}:{}:{}", filename, line, column);
134 }
135};
136
137pub fn translate(
138 backing_allocator: *std.mem.Allocator,
139 args_begin: [*]?[*]const u8,
140 args_end: [*]?[*]const u8,
141 mode: Mode,
142 errors: *[]ClangErrMsg,
143 resources_path: [*]const u8,
144) !*ast.Tree {
145 const ast_unit = ZigClangLoadFromCommandLine(
146 args_begin,
147 args_end,
148 &errors.ptr,
149 &errors.len,
150 resources_path,
151 ) orelse {
152 if (errors.len == 0) return error.OutOfMemory;
153 return error.SemanticAnalyzeFail;
154 };
155 defer ZigClangASTUnit_delete(ast_unit);
156
157 var tree_arena = std.heap.ArenaAllocator.init(backing_allocator);
158 errdefer tree_arena.deinit();
159 var arena = &tree_arena.allocator;
160
161 const root_node = try arena.create(ast.Node.Root);
162 root_node.* = ast.Node.Root{
163 .base = ast.Node{ .id = ast.Node.Id.Root },
164 .decls = ast.Node.Root.DeclList.init(arena),
165 .doc_comments = null,
166 // initialized with the eof token at the end
167 .eof_token = undefined,
168 };
169
170 const tree = try arena.create(ast.Tree);
171 tree.* = ast.Tree{
172 .source = undefined, // need to use Buffer.toOwnedSlice later
173 .root_node = root_node,
174 .arena_allocator = undefined,
175 .tokens = ast.Tree.TokenList.init(arena),
176 .errors = ast.Tree.ErrorList.init(arena),
177 };
178 tree.arena_allocator = tree_arena;
179 arena = &tree.arena_allocator.allocator;
180
181 var source_buffer = try std.Buffer.initSize(arena, 0);
182
183 var context = Context{
184 .tree = tree,
185 .source_buffer = &source_buffer,
186 .source_manager = ZigClangASTUnit_getSourceManager(ast_unit),
187 .err = undefined,
188 .decl_table = DeclTable.init(arena),
189 .global_scope = try arena.create(Scope.Root),
190 .mode = mode,
191 };
192 context.global_scope.* = Scope.Root{
193 .base = Scope{
194 .id = Scope.Id.Root,
195 .parent = null,
196 },
197 };
198
199 if (!ZigClangASTUnit_visitLocalTopLevelDecls(ast_unit, &context, declVisitorC)) {
200 return context.err;
201 }
202
203 _ = try appendToken(&context, .Eof, "");
204 tree.source = source_buffer.toOwnedSlice();
205 if (false) {
206 std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", tree.source);
207 var i: usize = 0;
208 while (i < tree.tokens.len) : (i += 1) {
209 const token = tree.tokens.at(i);
210 std.debug.warn("{}\n", token);
211 }
212 }
213 return tree;
214}
215
216extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
217 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
218 declVisitor(c, decl) catch |err| {
219 c.err = err;
220 return false;
221 };
222 return true;
223}
224
225fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
226 switch (ZigClangDecl_getKind(decl)) {
227 .Function => {
228 return visitFnDecl(c, @ptrCast(*const ZigClangFunctionDecl, decl));
229 },
230 .Typedef => {
231 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for typedefs");
232 },
233 .Enum => {
234 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for enums");
235 },
236 .Record => {
237 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for structs");
238 },
239 .Var => {
240 try emitWarning(c, ZigClangDecl_getLocation(decl), "TODO implement translate-c for variables");
241 },
242 else => {
243 const decl_name = try c.str(ZigClangDecl_getDeclKindName(decl));
244 try emitWarning(c, ZigClangDecl_getLocation(decl), "ignoring {} declaration", decl_name);
245 },
246 }
247}
248
249fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
250 if (try c.decl_table.put(@ptrToInt(fn_decl), {})) |_| return; // Avoid processing this decl twice
251 const rp = makeRestorePoint(c);
252 const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
253 const fn_decl_loc = ZigClangFunctionDecl_getLocation(fn_decl);
254 const fn_qt = ZigClangFunctionDecl_getType(fn_decl);
255 const fn_type = ZigClangQualType_getTypePtr(fn_qt);
256 var scope = &c.global_scope.base;
257 const has_body = ZigClangFunctionDecl_hasBody(fn_decl);
258 const storage_class = ZigClangFunctionDecl_getStorageClass(fn_decl);
259 const decl_ctx = FnDeclContext{
260 .fn_name = fn_name,
261 .has_body = has_body,
262 .storage_class = storage_class,
263 .scope = &scope,
264 .is_export = switch (storage_class) {
265 .None => has_body,
266 .Extern, .Static => false,
267 .PrivateExtern => return failDecl(c, fn_decl_loc, fn_name, "unsupported storage class: private extern"),
268 .Auto => unreachable, // Not legal on functions
269 .Register => unreachable, // Not legal on functions
270 },
271 };
272 const proto_node = switch (ZigClangType_getTypeClass(fn_type)) {
273 .FunctionProto => blk: {
274 const fn_proto_type = @ptrCast(*const ZigClangFunctionProtoType, fn_type);
275 break :blk transFnProto(rp, fn_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) {
276 error.UnsupportedType => {
277 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
278 },
279 error.OutOfMemory => return error.OutOfMemory,
280 };
281 },
282 .FunctionNoProto => blk: {
283 const fn_no_proto_type = @ptrCast(*const ZigClangFunctionType, fn_type);
284 break :blk transFnNoProto(rp, fn_no_proto_type, fn_decl_loc, decl_ctx) catch |err| switch (err) {
285 error.UnsupportedType => {
286 return failDecl(c, fn_decl_loc, fn_name, "unable to resolve prototype of function");
287 },
288 error.OutOfMemory => return error.OutOfMemory,
289 };
290 },
291 else => unreachable,
292 };
293
294 if (!decl_ctx.has_body) {
295 const semi_tok = try appendToken(c, .Semicolon, ";");
296 return addTopLevelDecl(c, fn_name, &proto_node.base);
297 }
298
299 // actual function definition with body
300 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
301 const result = transStmt(rp, scope, body_stmt, .unused, .r_value) catch |err| switch (err) {
302 error.OutOfMemory => return error.OutOfMemory,
303 error.UnsupportedTranslation => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function"),
304 };
305 assert(result.node.id == ast.Node.Id.Block);
306 proto_node.body_node = result.node;
307
308 return addTopLevelDecl(c, fn_name, &proto_node.base);
309}
310
311const ResultUsed = enum {
312 used,
313 unused,
314};
315
316const LRValue = enum {
317 l_value,
318 r_value,
319};
320
321fn transStmt(
322 rp: RestorePoint,
323 scope: *Scope,
324 stmt: *const ZigClangStmt,
325 result_used: ResultUsed,
326 lrvalue: LRValue,
327) !TransResult {
328 const sc = ZigClangStmt_getStmtClass(stmt);
329 switch (sc) {
330 .CompoundStmtClass => return transCompoundStmt(rp, scope, @ptrCast(*const ZigClangCompoundStmt, stmt)),
331 else => {
332 return revertAndWarn(
333 rp,
334 error.UnsupportedTranslation,
335 ZigClangStmt_getBeginLoc(stmt),
336 "TODO implement translation of stmt class {}",
337 @tagName(sc),
338 );
339 },
340 }
341}
342
343fn transCompoundStmtInline(
344 rp: RestorePoint,
345 parent_scope: *Scope,
346 stmt: *const ZigClangCompoundStmt,
347 block_node: *ast.Node.Block,
348) TransError!TransResult {
349 var it = ZigClangCompoundStmt_body_begin(stmt);
350 const end_it = ZigClangCompoundStmt_body_end(stmt);
351 var scope = parent_scope;
352 while (it != end_it) : (it += 1) {
353 const result = try transStmt(rp, scope, it.*, .unused, .r_value);
354 scope = result.child_scope;
355 try block_node.statements.push(result.node);
356 }
357 return TransResult{
358 .node = &block_node.base,
359 .child_scope = scope,
360 .node_scope = scope,
361 };
362}
363
364fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) !TransResult {
365 const lbrace_tok = try appendToken(rp.c, .LBrace, "{");
366 const block_scope = try Scope.Block.create(rp.c, scope, lbrace_tok);
367 const inline_result = try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
368 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
369 return TransResult{
370 .node = &block_scope.block_node.base,
371 .node_scope = inline_result.node_scope,
372 .child_scope = inline_result.child_scope,
373 };
374}
375
376fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
377 try c.tree.root_node.decls.push(decl_node);
378}
379
380fn transQualType(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigClangSourceLocation) Error!*ast.Node {
381 return transType(rp, ZigClangQualType_getTypePtr(qt), source_loc);
382}
383
384fn qualTypeCanon(qt: ZigClangQualType) *const ZigClangType {
385 const canon = ZigClangQualType_getCanonicalType(qt);
386 return ZigClangQualType_getTypePtr(canon);
387}
388
389const RestorePoint = struct {
390 c: *Context,
391 token_index: ast.TokenIndex,
392 src_buf_index: usize,
393
394 fn activate(self: RestorePoint) void {
395 self.c.tree.tokens.shrink(self.token_index);
396 self.c.source_buffer.shrink(self.src_buf_index);
397 }
398};
399
400fn makeRestorePoint(c: *Context) RestorePoint {
401 return RestorePoint{
402 .c = c,
403 .token_index = c.tree.tokens.len,
404 .src_buf_index = c.source_buffer.len(),
405 };
406}
407
408fn transType(rp: RestorePoint, ty: *const ZigClangType, source_loc: ZigClangSourceLocation) Error!*ast.Node {
409 switch (ZigClangType_getTypeClass(ty)) {
410 .Builtin => {
411 const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
412 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
413 .Void => return appendIdentifier(rp.c, "c_void"),
414 .Bool => return appendIdentifier(rp.c, "bool"),
415 .Char_U, .UChar, .Char_S, .Char8 => return appendIdentifier(rp.c, "u8"),
416 .SChar => return appendIdentifier(rp.c, "i8"),
417 .UShort => return appendIdentifier(rp.c, "c_ushort"),
418 .UInt => return appendIdentifier(rp.c, "c_uint"),
419 .ULong => return appendIdentifier(rp.c, "c_ulong"),
420 .ULongLong => return appendIdentifier(rp.c, "c_ulonglong"),
421 .Short => return appendIdentifier(rp.c, "c_short"),
422 .Int => return appendIdentifier(rp.c, "c_int"),
423 .Long => return appendIdentifier(rp.c, "c_long"),
424 .LongLong => return appendIdentifier(rp.c, "c_longlong"),
425 .UInt128 => return appendIdentifier(rp.c, "u128"),
426 .Int128 => return appendIdentifier(rp.c, "i128"),
427 .Float => return appendIdentifier(rp.c, "f32"),
428 .Double => return appendIdentifier(rp.c, "f64"),
429 .Float128 => return appendIdentifier(rp.c, "f128"),
430 .Float16 => return appendIdentifier(rp.c, "f16"),
431 .LongDouble => return appendIdentifier(rp.c, "c_longdouble"),
432 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported builtin type"),
433 }
434 },
435 .FunctionProto => {
436 const fn_proto_ty = @ptrCast(*const ZigClangFunctionProtoType, ty);
437 const fn_proto = try transFnProto(rp, fn_proto_ty, source_loc, null);
438 return &fn_proto.base;
439 },
440 else => {
441 const type_name = rp.c.str(ZigClangType_getTypeClassName(ty));
442 return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported type: '{}'", type_name);
443 },
444 }
445}
446
447const FnDeclContext = struct {
448 fn_name: []const u8,
449 has_body: bool,
450 storage_class: ZigClangStorageClass,
451 scope: **Scope,
452 is_export: bool,
453};
454
455fn transCC(
456 rp: RestorePoint,
457 fn_ty: *const ZigClangFunctionType,
458 source_loc: ZigClangSourceLocation,
459) !CallingConvention {
460 const clang_cc = ZigClangFunctionType_getCallConv(fn_ty);
461 switch (clang_cc) {
462 .C => return CallingConvention.C,
463 .X86StdCall => return CallingConvention.Stdcall,
464 else => return revertAndWarn(rp, error.UnsupportedType, source_loc, "unsupported calling convention: {}", @tagName(clang_cc)),
465 }
466}
467
468fn transFnProto(
469 rp: RestorePoint,
470 fn_proto_ty: *const ZigClangFunctionProtoType,
471 source_loc: ZigClangSourceLocation,
472 fn_decl_context: ?FnDeclContext,
473) !*ast.Node.FnProto {
474 const fn_ty = @ptrCast(*const ZigClangFunctionType, fn_proto_ty);
475 const cc = try transCC(rp, fn_ty, source_loc);
476 const is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty);
477 const param_count: usize = ZigClangFunctionProtoType_getNumParams(fn_proto_ty);
478 var i: usize = 0;
479 while (i < param_count) : (i += 1) {
480 return revertAndWarn(rp, error.UnsupportedType, source_loc, "TODO: implement parameters for FunctionProto in transType");
481 }
482
483 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc);
484}
485
486fn transFnNoProto(
487 rp: RestorePoint,
488 fn_ty: *const ZigClangFunctionType,
489 source_loc: ZigClangSourceLocation,
490 fn_decl_context: ?FnDeclContext,
491) !*ast.Node.FnProto {
492 const cc = try transCC(rp, fn_ty, source_loc);
493 const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true;
494 return finishTransFnProto(rp, fn_ty, source_loc, fn_decl_context, is_var_args, cc);
495}
496
497fn finishTransFnProto(
498 rp: RestorePoint,
499 fn_ty: *const ZigClangFunctionType,
500 source_loc: ZigClangSourceLocation,
501 fn_decl_context: ?FnDeclContext,
502 is_var_args: bool,
503 cc: CallingConvention,
504) !*ast.Node.FnProto {
505 const is_export = if (fn_decl_context) |ctx| ctx.is_export else false;
506
507 // TODO check for always_inline attribute
508 // TODO check for align attribute
509
510 // pub extern fn name(...) T
511 const pub_tok = try appendToken(rp.c, .Keyword_pub, "pub");
512 const cc_tok = if (cc == .Stdcall) try appendToken(rp.c, .Keyword_stdcallcc, "stdcallcc") else null;
513 const extern_export_inline_tok = if (is_export)
514 try appendToken(rp.c, .Keyword_export, "export")
515 else if (cc == .C)
516 try appendToken(rp.c, .Keyword_extern, "extern")
517 else
518 null;
519 const fn_tok = try appendToken(rp.c, .Keyword_fn, "fn");
520 const name_tok = if (fn_decl_context) |ctx| try appendToken(rp.c, .Identifier, ctx.fn_name) else null;
521 const lparen_tok = try appendToken(rp.c, .LParen, "(");
522 const var_args_tok = if (is_var_args) try appendToken(rp.c, .Ellipsis3, "...") else null;
523 const rparen_tok = try appendToken(rp.c, .RParen, ")");
524
525 const return_type_node = blk: {
526 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
527 break :blk try appendIdentifier(rp.c, "noreturn");
528 } else {
529 const return_qt = ZigClangFunctionType_getReturnType(fn_ty);
530 if (ZigClangType_isVoidType(qualTypeCanon(return_qt))) {
531 break :blk try appendIdentifier(rp.c, "void");
532 } else {
533 break :blk transQualType(rp, return_qt, source_loc) catch |err| switch (err) {
534 error.UnsupportedType => {
535 try emitWarning(rp.c, source_loc, "unsupported function proto return type");
536 return err;
537 },
538 error.OutOfMemory => return error.OutOfMemory,
539 };
540 }
541 }
542 };
543
544 const fn_proto = try rp.c.a().create(ast.Node.FnProto);
545 fn_proto.* = ast.Node.FnProto{
546 .base = ast.Node{ .id = ast.Node.Id.FnProto },
547 .doc_comments = null,
548 .visib_token = pub_tok,
549 .fn_token = fn_tok,
550 .name_token = name_tok,
551 .params = ast.Node.FnProto.ParamList.init(rp.c.a()),
552 .return_type = ast.Node.FnProto.ReturnType{ .Explicit = return_type_node },
553 .var_args_token = null, // TODO this field is broken in the AST data model
554 .extern_export_inline_token = extern_export_inline_tok,
555 .cc_token = cc_tok,
556 .async_attr = null,
557 .body_node = null,
558 .lib_name = null,
559 .align_expr = null,
560 .section_expr = null,
561 };
562 if (is_var_args) {
563 const var_arg_node = try rp.c.a().create(ast.Node.ParamDecl);
564 var_arg_node.* = ast.Node.ParamDecl{
565 .base = ast.Node{ .id = ast.Node.Id.ParamDecl },
566 .doc_comments = null,
567 .comptime_token = null,
568 .noalias_token = null,
569 .name_token = null,
570 .type_node = undefined,
571 .var_args_token = var_args_tok,
572 };
573 try fn_proto.params.push(&var_arg_node.base);
574 }
575 return fn_proto;
576}
577
578fn revertAndWarn(
579 rp: RestorePoint,
580 err: var,
581 source_loc: ZigClangSourceLocation,
582 comptime format: []const u8,
583 args: ...,
584) (@typeOf(err) || error{OutOfMemory}) {
585 rp.activate();
586 try emitWarning(rp.c, source_loc, format, args);
587 return err;
588}
589
590fn emitWarning(c: *Context, loc: ZigClangSourceLocation, comptime format: []const u8, args: ...) !void {
591 _ = try appendTokenFmt(c, .LineComment, "// {}: warning: " ++ format, c.locStr(loc), args);
592}
593
594fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comptime format: []const u8, args: ...) !void {
595 // const name = @compileError(msg);
596 const const_tok = try appendToken(c, .Keyword_const, "const");
597 const name_tok = try appendToken(c, .Identifier, name);
598 const eq_tok = try appendToken(c, .Equal, "=");
599 const builtin_tok = try appendToken(c, .Builtin, "@compileError");
600 const lparen_tok = try appendToken(c, .LParen, "(");
601 const msg_tok = try appendTokenFmt(c, .StringLiteral, "\"" ++ format ++ "\"", args);
602 const rparen_tok = try appendToken(c, .RParen, ")");
603 const semi_tok = try appendToken(c, .Semicolon, ";");
604
605 const msg_node = try c.a().create(ast.Node.StringLiteral);
606 msg_node.* = ast.Node.StringLiteral{
607 .base = ast.Node{ .id = ast.Node.Id.StringLiteral },
608 .token = msg_tok,
609 };
610
611 const call_node = try c.a().create(ast.Node.BuiltinCall);
612 call_node.* = ast.Node.BuiltinCall{
613 .base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
614 .builtin_token = builtin_tok,
615 .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
616 .rparen_token = rparen_tok,
617 };
618 try call_node.params.push(&msg_node.base);
619
620 const var_decl_node = try c.a().create(ast.Node.VarDecl);
621 var_decl_node.* = ast.Node.VarDecl{
622 .base = ast.Node{ .id = ast.Node.Id.VarDecl },
623 .doc_comments = null,
624 .visib_token = null,
625 .thread_local_token = null,
626 .name_token = name_tok,
627 .eq_token = eq_tok,
628 .mut_token = const_tok,
629 .comptime_token = null,
630 .extern_export_token = null,
631 .lib_name = null,
632 .type_node = null,
633 .align_node = null,
634 .section_node = null,
635 .init_node = &call_node.base,
636 .semicolon_token = semi_tok,
637 };
638 try c.tree.root_node.decls.push(&var_decl_node.base);
639}
640
641fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenIndex {
642 return appendTokenFmt(c, token_id, "{}", bytes);
643}
644
645fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: ...) !ast.TokenIndex {
646 const S = struct {
647 fn callback(context: *Context, bytes: []const u8) error{OutOfMemory}!void {
648 return context.source_buffer.append(bytes);
649 }
650 };
651 const start_index = c.source_buffer.len();
652 errdefer c.source_buffer.shrink(start_index);
653
654 try std.fmt.format(c, error{OutOfMemory}, S.callback, format, args);
655 const end_index = c.source_buffer.len();
656 const token_index = c.tree.tokens.len;
657 const new_token = try c.tree.tokens.addOne();
658 errdefer c.tree.tokens.shrink(token_index);
659
660 new_token.* = Token{
661 .id = token_id,
662 .start = start_index,
663 .end = end_index,
664 };
665 try c.source_buffer.appendByte('\n');
666
667 return token_index;
668}
669
670fn appendIdentifier(c: *Context, name: []const u8) !*ast.Node {
671 const token_index = try appendToken(c, .Identifier, name);
672 const identifier = try c.a().create(ast.Node.Identifier);
673 identifier.* = ast.Node.Identifier{
674 .base = ast.Node{ .id = ast.Node.Id.Identifier },
675 .token = token_index,
676 };
677 return &identifier.base;
678}
679
680pub fn freeErrors(errors: []ClangErrMsg) void {
681 ZigClangErrorMsg_delete(errors.ptr, errors.len);
682}
src-self-hosted/value.zig+4-4
......@@ -538,21 +538,21 @@ pub const Value = struct {
538538 switch (self.base.typ.id) {
539539 Type.Id.Int => {
540540 const type_ref = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
541 if (self.big_int.len == 0) {
541 if (self.big_int.len() == 0) {
542542 return llvm.ConstNull(type_ref);
543543 }
544 const unsigned_val = if (self.big_int.len == 1) blk: {
544 const unsigned_val = if (self.big_int.len() == 1) blk: {
545545 break :blk llvm.ConstInt(type_ref, self.big_int.limbs[0], @boolToInt(false));
546546 } else if (@sizeOf(std.math.big.Limb) == @sizeOf(u64)) blk: {
547547 break :blk llvm.ConstIntOfArbitraryPrecision(
548548 type_ref,
549 @intCast(c_uint, self.big_int.len),
549 @intCast(c_uint, self.big_int.len()),
550550 @ptrCast([*]u64, self.big_int.limbs.ptr),
551551 );
552552 } else {
553553 @compileError("std.math.Big.Int.Limb size does not match LLVM");
554554 };
555 return if (self.big_int.positive) unsigned_val else llvm.ConstNeg(unsigned_val);
555 return if (self.big_int.isPositive()) unsigned_val else llvm.ConstNeg(unsigned_val);
556556 },
557557 Type.Id.ComptimeInt => unreachable,
558558 else => unreachable,
src/all_types.hpp+12-1
......@@ -55,7 +55,7 @@ struct IrExecutable {
5555 size_t mem_slot_count;
5656 size_t next_debug_id;
5757 size_t *backward_branch_count;
58 size_t backward_branch_quota;
58 size_t *backward_branch_quota;
5959 ZigFn *fn_entry;
6060 Buf *c_import_buf;
6161 AstNode *source_node;
......@@ -1350,6 +1350,7 @@ struct ZigFn {
13501350 IrExecutable ir_executable;
13511351 IrExecutable analyzed_executable;
13521352 size_t prealloc_bbc;
1353 size_t prealloc_backward_branch_quota;
13531354 AstNode **param_source_nodes;
13541355 Buf **param_names;
13551356
......@@ -1855,10 +1856,13 @@ struct CodeGen {
18551856 bool strip_debug_symbols;
18561857 bool is_test_build;
18571858 bool is_single_threaded;
1859 bool want_single_threaded;
18581860 bool linker_rdynamic;
18591861 bool each_lib_rpath;
18601862 bool is_dummy_so;
18611863 bool disable_gen_h;
1864 bool bundle_compiler_rt;
1865 bool disable_stack_probing;
18621866
18631867 Buf *mmacosx_version_min;
18641868 Buf *mios_version_min;
......@@ -2291,6 +2295,7 @@ enum IrInstructionId {
22912295 IrInstructionIdVectorToArray,
22922296 IrInstructionIdArrayToVector,
22932297 IrInstructionIdAssertZero,
2298 IrInstructionIdAssertNonNull,
22942299};
22952300
22962301struct IrInstruction {
......@@ -3480,6 +3485,12 @@ struct IrInstructionAssertZero {
34803485 IrInstruction *target;
34813486};
34823487
3488struct IrInstructionAssertNonNull {
3489 IrInstruction base;
3490
3491 IrInstruction *target;
3492};
3493
34833494static const size_t slice_ptr_index = 0;
34843495static const size_t slice_len_index = 1;
34853496
src/analyze.cpp+94-59
......@@ -969,8 +969,9 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no
969969 Buf *type_name)
970970{
971971 size_t backward_branch_count = 0;
972 size_t backward_branch_quota = default_backward_branch_quota;
972973 return ir_eval_const_value(g, scope, node, type_entry,
973 &backward_branch_count, default_backward_branch_quota,
974 &backward_branch_count, &backward_branch_quota,
974975 nullptr, nullptr, node, type_name, nullptr, nullptr);
975976}
976977
......@@ -1907,6 +1908,18 @@ static Error resolve_union_type(CodeGen *g, ZigType *union_type) {
19071908 return ErrorNone;
19081909}
19091910
1911static bool type_is_valid_extern_enum_tag(CodeGen *g, ZigType *ty) {
1912 // Only integer types are allowed by the C ABI
1913 if(ty->id != ZigTypeIdInt)
1914 return false;
1915
1916 // According to the ANSI C standard the enumeration type should be either a
1917 // signed char, a signed integer or an unsigned one. But GCC/Clang allow
1918 // other integral types as a compiler extension so let's accomodate them
1919 // aswell.
1920 return type_allowed_in_extern(g, ty);
1921}
1922
19101923static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
19111924 assert(enum_type->id == ZigTypeIdEnum);
19121925
......@@ -1964,7 +1977,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
19641977 enum_type->abi_size = tag_int_type->abi_size;
19651978 enum_type->abi_align = tag_int_type->abi_align;
19661979
1967 // TODO: Are extern enums allowed to have an init_arg_expr?
19681980 if (decl_node->data.container_decl.init_arg_expr != nullptr) {
19691981 ZigType *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr);
19701982 if (type_is_invalid(wanted_tag_int_type)) {
......@@ -1973,24 +1985,29 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
19731985 enum_type->data.enumeration.is_invalid = true;
19741986 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
19751987 buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
1976 } else if (wanted_tag_int_type->data.integral.is_signed) {
1977 enum_type->data.enumeration.is_invalid = true;
1978 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1979 buf_sprintf("expected unsigned integer, found '%s'", buf_ptr(&wanted_tag_int_type->name)));
1980 } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) {
1988 } else if (enum_type->data.enumeration.layout == ContainerLayoutExtern &&
1989 !type_is_valid_extern_enum_tag(g, wanted_tag_int_type)) {
19811990 enum_type->data.enumeration.is_invalid = true;
1982 add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1983 buf_sprintf("'%s' too small to hold all bits; must be at least '%s'",
1984 buf_ptr(&wanted_tag_int_type->name), buf_ptr(&tag_int_type->name)));
1991 ErrorMsg *msg = add_node_error(g, decl_node->data.container_decl.init_arg_expr,
1992 buf_sprintf("'%s' is not a valid tag type for an extern enum",
1993 buf_ptr(&wanted_tag_int_type->name)));
1994 add_error_note(g, msg, decl_node->data.container_decl.init_arg_expr,
1995 buf_sprintf("any integral type of size 8, 16, 32, 64 or 128 bit is valid"));
19851996 } else {
19861997 tag_int_type = wanted_tag_int_type;
19871998 }
19881999 }
2000
19892001 enum_type->data.enumeration.tag_int_type = tag_int_type;
19902002 enum_type->size_in_bits = tag_int_type->size_in_bits;
19912003 enum_type->abi_size = tag_int_type->abi_size;
19922004 enum_type->abi_align = tag_int_type->abi_align;
19932005
2006 BigInt bi_one;
2007 bigint_init_unsigned(&bi_one, 1);
2008
2009 TypeEnumField *last_enum_field = nullptr;
2010
19942011 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
19952012 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
19962013 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
......@@ -2016,60 +2033,58 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
20162033
20172034 AstNode *tag_value = field_node->data.struct_field.value;
20182035
2019 // In this first pass we resolve explicit tag values.
2020 // In a second pass we will fill in the unspecified ones.
20212036 if (tag_value != nullptr) {
2037 // A user-specified value is available
20222038 ConstExprValue *result = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr);
20232039 if (type_is_invalid(result->type)) {
20242040 enum_type->data.enumeration.is_invalid = true;
20252041 continue;
20262042 }
2043
20272044 assert(result->special != ConstValSpecialRuntime);
2028 assert(result->type->id == ZigTypeIdInt ||
2029 result->type->id == ZigTypeIdComptimeInt);
2030 auto entry = occupied_tag_values.put_unique(result->data.x_bigint, tag_value);
2031 if (entry == nullptr) {
2032 bigint_init_bigint(&type_enum_field->value, &result->data.x_bigint);
2045 assert(result->type->id == ZigTypeIdInt || result->type->id == ZigTypeIdComptimeInt);
2046
2047 bigint_init_bigint(&type_enum_field->value, &result->data.x_bigint);
2048 } else {
2049 // No value was explicitly specified: allocate the last value + 1
2050 // or, if this is the first element, zero
2051 if (last_enum_field != nullptr) {
2052 bigint_add(&type_enum_field->value, &last_enum_field->value, &bi_one);
20332053 } else {
2034 Buf *val_buf = buf_alloc();
2035 bigint_append_buf(val_buf, &result->data.x_bigint, 10);
2054 bigint_init_unsigned(&type_enum_field->value, 0);
2055 }
20362056
2037 ErrorMsg *msg = add_node_error(g, tag_value,
2038 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2039 add_error_note(g, msg, entry->value,
2040 buf_sprintf("other occurrence here"));
2057 // Make sure we can represent this number with tag_int_type
2058 if (!bigint_fits_in_bits(&type_enum_field->value,
2059 tag_int_type->size_in_bits,
2060 tag_int_type->data.integral.is_signed)) {
20412061 enum_type->data.enumeration.is_invalid = true;
2042 continue;
2062
2063 Buf *val_buf = buf_alloc();
2064 bigint_append_buf(val_buf, &type_enum_field->value, 10);
2065 add_node_error(g, field_node,
2066 buf_sprintf("enumeration value %s too large for type '%s'",
2067 buf_ptr(val_buf), buf_ptr(&tag_int_type->name)));
2068
2069 break;
20432070 }
20442071 }
2045 }
20462072
2047 // Now iterate again and populate the unspecified tag values
2048 uint32_t next_maybe_unoccupied_index = 0;
2073 // Make sure the value is unique
2074 auto entry = occupied_tag_values.put_unique(type_enum_field->value, field_node);
2075 if (entry != nullptr) {
2076 enum_type->data.enumeration.is_invalid = true;
20492077
2050 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) {
2051 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i);
2052 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i];
2053 AstNode *tag_value = field_node->data.struct_field.value;
2078 Buf *val_buf = buf_alloc();
2079 bigint_append_buf(val_buf, &type_enum_field->value, 10);
20542080
2055 if (tag_value == nullptr) {
2056 if (occupied_tag_values.size() == 0) {
2057 bigint_init_unsigned(&type_enum_field->value, next_maybe_unoccupied_index);
2058 next_maybe_unoccupied_index += 1;
2059 } else {
2060 BigInt proposed_value;
2061 for (;;) {
2062 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index);
2063 next_maybe_unoccupied_index += 1;
2064 auto entry = occupied_tag_values.put_unique(proposed_value, field_node);
2065 if (entry != nullptr) {
2066 continue;
2067 }
2068 break;
2069 }
2070 bigint_init_bigint(&type_enum_field->value, &proposed_value);
2071 }
2081 ErrorMsg *msg = add_node_error(g, field_node,
2082 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf)));
2083 add_error_note(g, msg, entry->value,
2084 buf_sprintf("other occurrence here"));
20722085 }
2086
2087 last_enum_field = type_enum_field;
20732088 }
20742089
20752090 enum_type->data.enumeration.zero_bits_loop_flag = false;
......@@ -2607,7 +2622,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
26072622 return ErrorNone;
26082623}
26092624
2610static void get_fully_qualified_decl_name(Buf *buf, Tld *tld) {
2625static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, bool is_test) {
26112626 buf_resize(buf, 0);
26122627
26132628 Scope *scope = tld->parent_scope;
......@@ -2617,15 +2632,23 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld) {
26172632 ScopeDecls *decls_scope = reinterpret_cast<ScopeDecls *>(scope);
26182633 buf_append_buf(buf, &decls_scope->container_type->name);
26192634 if (buf_len(buf) != 0) buf_append_char(buf, NAMESPACE_SEP_CHAR);
2620 buf_append_buf(buf, tld->name);
2635 if (is_test) {
2636 buf_append_str(buf, "test \"");
2637 buf_append_buf(buf, tld->name);
2638 buf_append_char(buf, '"');
2639 } else {
2640 buf_append_buf(buf, tld->name);
2641 }
26212642}
26222643
26232644ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
26242645 ZigFn *fn_entry = allocate<ZigFn>(1);
26252646
2647 fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
2648
26262649 fn_entry->codegen = g;
26272650 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
2628 fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
2651 fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota;
26292652 fn_entry->analyzed_executable.fn_entry = fn_entry;
26302653 fn_entry->ir_executable.fn_entry = fn_entry;
26312654 fn_entry->fn_inline = inline_value;
......@@ -2726,7 +2749,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
27262749 if (fn_proto->is_export || is_extern) {
27272750 buf_init_from_buf(&fn_table_entry->symbol_name, tld_fn->base.name);
27282751 } else {
2729 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base);
2752 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, false);
27302753 }
27312754
27322755 if (fn_proto->is_export) {
......@@ -2787,7 +2810,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
27872810 } else if (source_node->type == NodeTypeTestDecl) {
27882811 ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
27892812
2790 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base);
2813 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, true);
27912814
27922815 tld_fn->fn_entry = fn_table_entry;
27932816
......@@ -3722,7 +3745,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
37223745 }
37233746 if (g->verbose_ir) {
37243747 fprintf(stderr, "\n");
3725 ast_render(g, stderr, fn_table_entry->body_node, 4);
3748 ast_render(stderr, fn_table_entry->body_node, 4);
37263749 fprintf(stderr, "\n{ // (IR)\n");
37273750 ir_print(g, stderr, &fn_table_entry->ir_executable, 4);
37283751 fprintf(stderr, "}\n");
......@@ -5155,11 +5178,10 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
51555178 if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) {
51565179 TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag);
51575180 assert(field != nullptr);
5158 if (type_has_bits(field->type_entry)) {
5159 zig_panic("TODO const expr analyze union field value for equality");
5160 } else {
5181 if (!type_has_bits(field->type_entry))
51615182 return true;
5162 }
5183 assert(find_union_field_by_tag(a->type, &union2->tag) != nullptr);
5184 return const_values_equal(g, union1->payload, union2->payload);
51635185 }
51645186 return false;
51655187 }
......@@ -6070,7 +6092,7 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents) {
60706092 if (g->enable_cache) {
60716093 return cache_add_file_fetch(&g->cache_hash, resolved_path, contents);
60726094 } else {
6073 return os_fetch_file_path(resolved_path, contents, false);
6095 return os_fetch_file_path(resolved_path, contents);
60746096 }
60756097}
60766098
......@@ -7222,3 +7244,16 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) {
72227244 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
72237245 return type->llvm_di_type;
72247246}
7247
7248void src_assert(bool ok, AstNode *source_node) {
7249 if (ok) return;
7250 if (source_node == nullptr) {
7251 fprintf(stderr, "when analyzing (unknown source location): ");
7252 } else {
7253 fprintf(stderr, "when analyzing %s:%u:%u: ",
7254 buf_ptr(source_node->owner->data.structure.root_struct->path),
7255 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
7256 }
7257 const char *msg = "assertion failed";
7258 stage2_panic(msg, strlen(msg));
7259}
src/analyze.hpp+4
......@@ -247,4 +247,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
247247LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type);
248248ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
249249
250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);
251
252void src_assert(bool ok, AstNode *source_node);
253
250254#endif
src/ast_render.cpp+2-4
......@@ -296,7 +296,6 @@ void ast_print(FILE *f, AstNode *node, int indent) {
296296
297297
298298struct AstRender {
299 CodeGen *codegen;
300299 int indent;
301300 int indent_size;
302301 FILE *f;
......@@ -633,7 +632,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
633632 if (is_printable(c)) {
634633 fprintf(ar->f, "'%c'", c);
635634 } else {
636 fprintf(ar->f, "'\\x%x'", (int)c);
635 fprintf(ar->f, "'\\x%02x'", (int)c);
637636 }
638637 break;
639638 }
......@@ -1170,9 +1169,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
11701169}
11711170
11721171
1173void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
1172void ast_render(FILE *f, AstNode *node, int indent_size) {
11741173 AstRender ar = {0};
1175 ar.codegen = codegen;
11761174 ar.f = f;
11771175 ar.indent_size = indent_size;
11781176 ar.indent = 0;
src/ast_render.hpp+1-1
......@@ -15,6 +15,6 @@
1515
1616void ast_print(FILE *f, AstNode *node, int indent);
1717
18void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
18void ast_render(FILE *f, AstNode *node, int indent_size);
1919
2020#endif
src/bigint.cpp+10-3
......@@ -1395,7 +1395,7 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
13951395 uint64_t shift_amt = bigint_as_unsigned(op2);
13961396
13971397 if (op1->digit_count == 1) {
1398 dest->data.digit = op1_digits[0] >> shift_amt;
1398 dest->data.digit = (shift_amt < 64) ? op1_digits[0] >> shift_amt : 0;
13991399 dest->digit_count = 1;
14001400 dest->is_negative = op1->is_negative;
14011401 bigint_normalize(dest);
......@@ -1410,12 +1410,19 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) {
14101410 }
14111411
14121412 dest->digit_count = op1->digit_count - digit_shift_count;
1413 dest->data.digits = allocate<uint64_t>(dest->digit_count);
1413 uint64_t *digits;
1414 if (dest->digit_count == 1) {
1415 digits = &dest->data.digit;
1416 } else {
1417 digits = allocate<uint64_t>(dest->digit_count);
1418 dest->data.digits = digits;
1419 }
1420
14141421 uint64_t carry = 0;
14151422 for (size_t op_digit_index = op1->digit_count - 1;;) {
14161423 uint64_t digit = op1_digits[op_digit_index];
14171424 size_t dest_digit_index = op_digit_index - digit_shift_count;
1418 dest->data.digits[dest_digit_index] = carry | (digit >> leftover_shift_count);
1425 digits[dest_digit_index] = carry | (digit >> leftover_shift_count);
14191426 carry = digit << (64 - leftover_shift_count);
14201427
14211428 if (dest_digit_index == 0) { break; }
src/buffer.hpp-1
......@@ -10,7 +10,6 @@
1010
1111#include "list.hpp"
1212
13#include <assert.h>
1413#include <stdint.h>
1514#include <ctype.h>
1615#include <stdarg.h>
src/c_tokenizer.cpp+20
......@@ -124,6 +124,8 @@ static void begin_token(CTokenize *ctok, CTokId id) {
124124 case CTokIdAsterisk:
125125 case CTokIdBang:
126126 case CTokIdTilde:
127 case CTokIdShl:
128 case CTokIdLt:
127129 break;
128130 }
129131}
......@@ -223,6 +225,10 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
223225 begin_token(ctok, CTokIdDot);
224226 end_token(ctok);
225227 break;
228 case '<':
229 begin_token(ctok, CTokIdLt);
230 ctok->state = CTokStateGotLt;
231 break;
226232 case '(':
227233 begin_token(ctok, CTokIdLParen);
228234 end_token(ctok);
......@@ -251,6 +257,19 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
251257 return mark_error(ctok);
252258 }
253259 break;
260 case CTokStateGotLt:
261 switch (*c) {
262 case '<':
263 ctok->cur_tok->id = CTokIdShl;
264 end_token(ctok);
265 ctok->state = CTokStateStart;
266 break;
267 default:
268 end_token(ctok);
269 ctok->state = CTokStateStart;
270 continue;
271 }
272 break;
254273 case CTokStateFloat:
255274 switch (*c) {
256275 case '.':
......@@ -791,6 +810,7 @@ found_end_of_macro:
791810 case CTokStateNumLitIntSuffixL:
792811 case CTokStateNumLitIntSuffixUL:
793812 case CTokStateNumLitIntSuffixLL:
813 case CTokStateGotLt:
794814 end_token(ctok);
795815 break;
796816 case CTokStateFloat:
src/c_tokenizer.hpp+3
......@@ -25,6 +25,8 @@ enum CTokId {
2525 CTokIdAsterisk,
2626 CTokIdBang,
2727 CTokIdTilde,
28 CTokIdShl,
29 CTokIdLt,
2830};
2931
3032enum CNumLitSuffix {
......@@ -78,6 +80,7 @@ enum CTokState {
7880 CTokStateNumLitIntSuffixL,
7981 CTokStateNumLitIntSuffixLL,
8082 CTokStateNumLitIntSuffixUL,
83 CTokStateGotLt,
8184};
8285
8386struct CTokenize {
src/cache_hash.cpp+14-14
......@@ -256,10 +256,10 @@ static Error populate_file_hash(CacheHash *ch, CacheHashFile *chf, Buf *contents
256256 }
257257
258258 if ((err = hash_file(chf->bin_digest, this_file, contents))) {
259 os_file_close(this_file);
259 os_file_close(&this_file);
260260 return err;
261261 }
262 os_file_close(this_file);
262 os_file_close(&this_file);
263263
264264 blake2b_update(&ch->blake, chf->bin_digest, 48);
265265
......@@ -300,7 +300,7 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
300300 Buf line_buf = BUF_INIT;
301301 buf_resize(&line_buf, 512);
302302 if ((err = os_file_read_all(ch->manifest_file, &line_buf))) {
303 os_file_close(ch->manifest_file);
303 os_file_close(&ch->manifest_file);
304304 return err;
305305 }
306306
......@@ -389,14 +389,14 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
389389 OsFileAttr actual_attr;
390390 if ((err = os_file_open_r(chf->path, &this_file, &actual_attr))) {
391391 fprintf(stderr, "Unable to open %s\n: %s", buf_ptr(chf->path), err_str(err));
392 os_file_close(ch->manifest_file);
392 os_file_close(&ch->manifest_file);
393393 return ErrorCacheUnavailable;
394394 }
395395 if (chf->attr.mtime.sec == actual_attr.mtime.sec &&
396396 chf->attr.mtime.nsec == actual_attr.mtime.nsec &&
397397 chf->attr.inode == actual_attr.inode)
398398 {
399 os_file_close(this_file);
399 os_file_close(&this_file);
400400 } else {
401401 // we have to recompute the digest.
402402 // later we'll rewrite the manifest with the new mtime/digest values
......@@ -411,11 +411,11 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
411411
412412 uint8_t actual_digest[48];
413413 if ((err = hash_file(actual_digest, this_file, nullptr))) {
414 os_file_close(this_file);
415 os_file_close(ch->manifest_file);
414 os_file_close(&this_file);
415 os_file_close(&ch->manifest_file);
416416 return err;
417417 }
418 os_file_close(this_file);
418 os_file_close(&this_file);
419419 if (memcmp(chf->bin_digest, actual_digest, 48) != 0) {
420420 memcpy(chf->bin_digest, actual_digest, 48);
421421 // keep going until we have the input file digests
......@@ -433,12 +433,12 @@ Error cache_hit(CacheHash *ch, Buf *out_digest) {
433433 CacheHashFile *chf = &ch->files.at(file_i);
434434 if ((err = populate_file_hash(ch, chf, nullptr))) {
435435 fprintf(stderr, "Unable to hash %s: %s\n", buf_ptr(chf->path), err_str(err));
436 os_file_close(ch->manifest_file);
436 os_file_close(&ch->manifest_file);
437437 return ErrorCacheUnavailable;
438438 }
439439 }
440 if (return_code != ErrorNone) {
441 os_file_close(ch->manifest_file);
440 if (return_code != ErrorNone && return_code != ErrorInvalidFormat) {
441 os_file_close(&ch->manifest_file);
442442 }
443443 return return_code;
444444 }
......@@ -453,7 +453,7 @@ Error cache_add_file_fetch(CacheHash *ch, Buf *resolved_path, Buf *contents) {
453453 CacheHashFile *chf = ch->files.add_one();
454454 chf->path = resolved_path;
455455 if ((err = populate_file_hash(ch, chf, contents))) {
456 os_file_close(ch->manifest_file);
456 os_file_close(&ch->manifest_file);
457457 return err;
458458 }
459459
......@@ -469,7 +469,7 @@ Error cache_add_file(CacheHash *ch, Buf *path) {
469469Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) {
470470 Error err;
471471 Buf *contents = buf_alloc();
472 if ((err = os_fetch_file_path(dep_file_path, contents, false))) {
472 if ((err = os_fetch_file_path(dep_file_path, contents))) {
473473 if (verbose) {
474474 fprintf(stderr, "unable to read .d file: %s\n", err_str(err));
475475 }
......@@ -586,6 +586,6 @@ void cache_release(CacheHash *ch) {
586586 }
587587 }
588588
589 os_file_close(ch->manifest_file);
589 os_file_close(&ch->manifest_file);
590590}
591591
src/codegen.cpp+353-156
......@@ -19,6 +19,7 @@
1919#include "target.hpp"
2020#include "util.hpp"
2121#include "zig_llvm.h"
22#include "userland.h"
2223
2324#include <stdio.h>
2425#include <errno.h>
......@@ -92,7 +93,7 @@ static const char *symbols_that_llvm_depends_on[] = {
9293};
9394
9495CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
95 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir,
96 OutType out_type, BuildMode build_mode, Buf *override_lib_dir, Buf *override_std_dir,
9697 ZigLibCInstallation *libc, Buf *cache_dir)
9798{
9899 CodeGen *g = allocate<CodeGen>(1);
......@@ -100,19 +101,24 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
100101 codegen_add_time_event(g, "Initialize");
101102
102103 g->libc = libc;
103 g->zig_lib_dir = zig_lib_dir;
104104 g->zig_target = target;
105105 g->cache_dir = cache_dir;
106106
107 if (override_lib_dir == nullptr) {
108 g->zig_lib_dir = get_zig_lib_dir();
109 } else {
110 g->zig_lib_dir = override_lib_dir;
111 }
112
107113 if (override_std_dir == nullptr) {
108114 g->zig_std_dir = buf_alloc();
109 os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
115 os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
110116 } else {
111117 g->zig_std_dir = override_std_dir;
112118 }
113119
114120 g->zig_c_headers_dir = buf_alloc();
115 os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
121 os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
116122
117123 g->build_mode = build_mode;
118124 g->out_type = out_type;
......@@ -393,6 +399,15 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
393399 }
394400}
395401
402static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) {
403 // Windows already emits its own stack probes
404 if (!g->disable_stack_probing && g->zig_target->os != OsWindows &&
405 (g->zig_target->arch == ZigLLVM_x86 ||
406 g->zig_target->arch == ZigLLVM_x86_64)) {
407 addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack");
408 }
409}
410
396411static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
397412 switch (id) {
398413 case GlobalLinkageIdInternal:
......@@ -424,7 +439,7 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
424439}
425440
426441static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
427 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) {
442 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) {
428443 LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
429444 }
430445}
......@@ -495,6 +510,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
495510 auto entry = g->exported_symbol_names.maybe_get(symbol_name);
496511 if (entry == nullptr) {
497512 fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
513
514 if (target_is_wasm(g->zig_target)) {
515 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
516 AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto;
517 if (fn_proto-> is_extern && fn_proto->lib_name != nullptr ) {
518 addLLVMFnAttrStr(fn_table_entry->llvm_value, "wasm-import-module", buf_ptr(fn_proto->lib_name));
519 }
520 }
498521 } else {
499522 assert(entry->value->id == TldIdFn);
500523 TldFn *tld_fn = reinterpret_cast<TldFn *>(entry->value);
......@@ -573,6 +596,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
573596 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
574597 addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
575598 }
599
600 add_probe_stack_attr(g, fn_table_entry->llvm_value);
576601 }
577602 } else {
578603 maybe_import_dll(g, fn_table_entry->llvm_value, linkage);
......@@ -983,10 +1008,19 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
9831008 LLVMBuildUnreachable(g->builder);
9841009}
9851010
1011// TODO update most callsites to call gen_assertion instead of this
9861012static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
9871013 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
9881014}
9891015
1016static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {
1017 if (ir_want_runtime_safety(g, source_instruction)) {
1018 gen_safety_crash(g, msg_id);
1019 } else {
1020 LLVMBuildUnreachable(g->builder);
1021 }
1022}
1023
9901024static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
9911025 if (g->stacksave_fn_val)
9921026 return g->stacksave_fn_val;
......@@ -1022,7 +1056,7 @@ static LLVMValueRef get_write_register_fn_val(CodeGen *g) {
10221056 // !0 = !{!"sp\00"}
10231057
10241058 LLVMTypeRef param_types[] = {
1025 LLVMMetadataTypeInContext(LLVMGetGlobalContext()),
1059 LLVMMetadataTypeInContext(LLVMGetGlobalContext()),
10261060 LLVMIntType(g->pointer_size_bytes * 8),
10271061 };
10281062
......@@ -1541,11 +1575,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
15411575 LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2);
15421576
15431577 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
1544 LLVMTypeRef arg_types[] = {
1545 get_llvm_type(g, g->ptr_to_stack_trace_type),
1546 get_llvm_type(g, g->err_tag_type),
1547 };
1548 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
1578 LLVMTypeRef fn_type_ref;
1579 if (g->have_err_ret_tracing) {
1580 LLVMTypeRef arg_types[] = {
1581 get_llvm_type(g, g->ptr_to_stack_trace_type),
1582 get_llvm_type(g, g->err_tag_type),
1583 };
1584 fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false);
1585 } else {
1586 LLVMTypeRef arg_types[] = {
1587 get_llvm_type(g, g->err_tag_type),
1588 };
1589 fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false);
1590 }
15491591 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
15501592 addLLVMFnAttr(fn_val, "noreturn");
15511593 addLLVMFnAttr(fn_val, "cold");
......@@ -1567,7 +1609,15 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
15671609 LLVMPositionBuilderAtEnd(g->builder, entry_block);
15681610 ZigLLVMClearCurrentDebugLocation(g->builder);
15691611
1570 LLVMValueRef err_val = LLVMGetParam(fn_val, 1);
1612 LLVMValueRef err_ret_trace_arg;
1613 LLVMValueRef err_val;
1614 if (g->have_err_ret_tracing) {
1615 err_ret_trace_arg = LLVMGetParam(fn_val, 0);
1616 err_val = LLVMGetParam(fn_val, 1);
1617 } else {
1618 err_ret_trace_arg = nullptr;
1619 err_val = LLVMGetParam(fn_val, 0);
1620 }
15711621
15721622 LLVMValueRef err_table_indices[] = {
15731623 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
......@@ -1589,7 +1639,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
15891639 LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, "");
15901640 gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);
15911641
1592 gen_panic(g, global_slice, LLVMGetParam(fn_val, 0));
1642 gen_panic(g, global_slice, err_ret_trace_arg);
15931643
15941644 LLVMPositionBuilderAtEnd(g->builder, prev_block);
15951645 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
......@@ -1625,17 +1675,26 @@ static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope) {
16251675
16261676static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *scope) {
16271677 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
1628 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope);
1629 if (err_ret_trace_val == nullptr) {
1630 ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g);
1631 err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type));
1678 LLVMValueRef call_instruction;
1679 if (g->have_err_ret_tracing) {
1680 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope);
1681 if (err_ret_trace_val == nullptr) {
1682 ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g);
1683 err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type));
1684 }
1685 LLVMValueRef args[] = {
1686 err_ret_trace_val,
1687 err_val,
1688 };
1689 call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2,
1690 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
1691 } else {
1692 LLVMValueRef args[] = {
1693 err_val,
1694 };
1695 call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1,
1696 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, "");
16321697 }
1633 LLVMValueRef args[] = {
1634 err_ret_trace_val,
1635 err_val,
1636 };
1637 LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, get_llvm_cc(g, CallingConventionUnspecified),
1638 ZigLLVM_FnInlineAuto, "");
16391698 LLVMSetTailCall(call_instruction, true);
16401699 LLVMBuildUnreachable(g->builder);
16411700}
......@@ -3452,6 +3511,15 @@ static bool want_valgrind_support(CodeGen *g) {
34523511 zig_unreachable();
34533512}
34543513
3514static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef byte_count) {
3515 static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
3516 ZigType *usize = g->builtin_types.entry_usize;
3517 LLVMValueRef zero = LLVMConstInt(usize->llvm_type, 0, false);
3518 LLVMValueRef req = LLVMConstInt(usize->llvm_type, VG_USERREQ__MAKE_MEM_UNDEFINED, false);
3519 LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->llvm_type, "");
3520 gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero);
3521}
3522
34553523static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) {
34563524 assert(type_has_bits(value_type));
34573525 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type));
......@@ -3466,11 +3534,7 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
34663534 ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false);
34673535 // then tell valgrind that the memory is undefined even though we just memset it
34683536 if (want_valgrind_support(g)) {
3469 static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545;
3470 LLVMValueRef zero = LLVMConstInt(usize->llvm_type, 0, false);
3471 LLVMValueRef req = LLVMConstInt(usize->llvm_type, VG_USERREQ__MAKE_MEM_UNDEFINED, false);
3472 LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->llvm_type, "");
3473 gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero);
3537 gen_valgrind_undef(g, dest_ptr, byte_count);
34743538 }
34753539}
34763540
......@@ -3480,14 +3544,14 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
34803544 if (!type_has_bits(ptr_type))
34813545 return nullptr;
34823546
3483 bool have_init_expr = !value_is_all_undef(&instruction->value->value);
3547 bool have_init_expr = !value_is_all_undef(&instruction->value->value);
34843548 if (have_init_expr) {
34853549 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
34863550 LLVMValueRef value = ir_llvm_value(g, instruction->value);
34873551 gen_assign_raw(g, ptr, ptr_type, value);
34883552 } else if (ir_want_runtime_safety(g, &instruction->base)) {
34893553 gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value.type,
3490 ir_llvm_value(g, instruction->ptr));
3554 ir_llvm_value(g, instruction->ptr));
34913555 }
34923556 return nullptr;
34933557}
......@@ -3690,7 +3754,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
36903754 }
36913755 FnWalk fn_walk = {};
36923756 fn_walk.id = FnWalkIdCall;
3693 fn_walk.data.call.inst = instruction;
3757 fn_walk.data.call.inst = instruction;
36943758 fn_walk.data.call.is_var_args = is_var_args;
36953759 fn_walk.data.call.gen_param_values = &gen_param_values;
36963760 walk_function_params(g, fn_type, &fn_walk);
......@@ -3710,7 +3774,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
37103774
37113775 LLVMCallConv llvm_cc = get_llvm_cc(g, cc);
37123776 LLVMValueRef result;
3713
3777
37143778 if (instruction->new_stack == nullptr) {
37153779 result = ZigLLVMBuildCall(g->builder, fn_val,
37163780 gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, fn_inline, "");
......@@ -3968,19 +4032,19 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
39684032}
39694033
39704034static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) {
3971 assert(maybe_type->id == ZigTypeIdOptional);
4035 assert(maybe_type->id == ZigTypeIdOptional ||
4036 (maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero));
4037
39724038 ZigType *child_type = maybe_type->data.maybe.child_type;
3973 if (!type_has_bits(child_type)) {
4039 if (!type_has_bits(child_type))
39744040 return maybe_handle;
3975 } else {
3976 bool is_scalar = !handle_is_ptr(maybe_type);
3977 if (is_scalar) {
3978 return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
3979 } else {
3980 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
3981 return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
3982 }
3983 }
4041
4042 bool is_scalar = !handle_is_ptr(maybe_type);
4043 if (is_scalar)
4044 return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
4045
4046 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
4047 return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
39844048}
39854049
39864050static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable,
......@@ -4001,8 +4065,8 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
40014065 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
40024066 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
40034067 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
4004 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
40054068 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");
4069 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
40064070 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
40074071
40084072 LLVMPositionBuilderAtEnd(g->builder, fail_block);
......@@ -4190,7 +4254,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
41904254 LLVMTypeRef tag_int_llvm_type = get_llvm_type(g, tag_int_type);
41914255 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(get_llvm_type(g, u8_slice_type), 0),
41924256 &tag_int_llvm_type, 1, false);
4193
4257
41944258 Buf *fn_name = get_mangled_name(g, buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name)), false);
41954259 LLVMValueRef fn_val = LLVMAddFunction(g->module, buf_ptr(fn_name), fn_type_ref);
41964260 LLVMSetLinkage(fn_val, LLVMInternalLinkage);
......@@ -4490,17 +4554,27 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrI
44904554
44914555static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrInstructionMemset *instruction) {
44924556 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
4493 LLVMValueRef char_val = ir_llvm_value(g, instruction->byte);
44944557 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
44954558
44964559 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
4497
44984560 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, "");
44994561
45004562 ZigType *ptr_type = instruction->dest_ptr->value.type;
45014563 assert(ptr_type->id == ZigTypeIdPointer);
45024564
4503 ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, char_val, len_val, get_ptr_align(g, ptr_type), ptr_type->data.pointer.is_volatile);
4565 bool val_is_undef = value_is_all_undef(&instruction->byte->value);
4566 LLVMValueRef fill_char;
4567 if (val_is_undef) {
4568 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
4569 } else {
4570 fill_char = ir_llvm_value(g, instruction->byte);
4571 }
4572 ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, fill_char, len_val, get_ptr_align(g, ptr_type),
4573 ptr_type->data.pointer.is_volatile);
4574
4575 if (val_is_undef && want_valgrind_support(g)) {
4576 gen_valgrind_undef(g, dest_ptr_casted, len_val);
4577 }
45044578 return nullptr;
45054579}
45064580
......@@ -5422,6 +5496,31 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable,
54225496 return nullptr;
54235497}
54245498
5499static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executable,
5500 IrInstructionAssertNonNull *instruction)
5501{
5502 LLVMValueRef target = ir_llvm_value(g, instruction->target);
5503 ZigType *target_type = instruction->target->value.type;
5504
5505 if (target_type->id == ZigTypeIdPointer) {
5506 assert(target_type->data.pointer.ptr_len == PtrLenC);
5507 LLVMValueRef non_null_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target,
5508 LLVMConstNull(get_llvm_type(g, target_type)), "");
5509
5510 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullFail");
5511 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullOk");
5512 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
5513
5514 LLVMPositionBuilderAtEnd(g->builder, fail_block);
5515 gen_assertion(g, PanicMsgIdUnwrapOptionalFail, &instruction->base);
5516
5517 LLVMPositionBuilderAtEnd(g->builder, ok_block);
5518 } else {
5519 zig_unreachable();
5520 }
5521 return nullptr;
5522}
5523
54255524static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
54265525 AstNode *source_node = instruction->source_node;
54275526 Scope *scope = instruction->scope;
......@@ -5676,6 +5775,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56765775 return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
56775776 case IrInstructionIdAssertZero:
56785777 return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);
5778 case IrInstructionIdAssertNonNull:
5779 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
56795780 case IrInstructionIdResizeSlice:
56805781 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
56815782 }
......@@ -6585,7 +6686,7 @@ static void validate_inline_fns(CodeGen *g) {
65856686}
65866687
65876688static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {
6588 if (var->is_thread_local && !g->is_single_threaded) {
6689 if (var->is_thread_local && (!g->is_single_threaded || var->linkage != VarLinkageInternal)) {
65896690 LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
65906691 }
65916692}
......@@ -6905,7 +7006,7 @@ static void do_code_gen(CodeGen *g) {
69057006 ir_render(g, fn_table_entry);
69067007
69077008 }
6908
7009
69097010 assert(!g->errors.length);
69107011
69117012 if (buf_len(&g->global_asm) != 0) {
......@@ -6942,6 +7043,11 @@ static void zig_llvm_emit_output(CodeGen *g) {
69427043 }
69437044 validate_inline_fns(g);
69447045 g->link_objects.append(output_path);
7046 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||
7047 (g->out_type == OutTypeLib && !g->is_dynamic)))
7048 {
7049 zig_link_add_compiler_rt(g);
7050 }
69457051 break;
69467052
69477053 case EmitFileTypeAssembly:
......@@ -7337,9 +7443,26 @@ static bool detect_pic(CodeGen *g) {
73377443 zig_unreachable();
73387444}
73397445
7446static bool detect_single_threaded(CodeGen *g) {
7447 if (g->want_single_threaded)
7448 return true;
7449 if (target_is_single_threaded(g->zig_target)) {
7450 return true;
7451 }
7452 return false;
7453}
7454
7455static bool detect_err_ret_tracing(CodeGen *g) {
7456 return !target_is_wasm(g->zig_target) &&
7457 g->build_mode != BuildModeFastRelease &&
7458 g->build_mode != BuildModeSmallRelease;
7459}
7460
73407461Buf *codegen_generate_builtin_source(CodeGen *g) {
73417462 g->have_dynamic_link = detect_dynamic_link(g);
73427463 g->have_pic = detect_pic(g);
7464 g->is_single_threaded = detect_single_threaded(g);
7465 g->have_err_ret_tracing = detect_err_ret_tracing(g);
73437466
73447467 Buf *contents = buf_alloc();
73457468
......@@ -7696,7 +7819,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
76967819 assert(ContainerLayoutAuto == 0);
76977820 assert(ContainerLayoutExtern == 1);
76987821 assert(ContainerLayoutPacked == 2);
7699
7822
77007823 assert(CallingConventionUnspecified == 0);
77017824 assert(CallingConventionC == 1);
77027825 assert(CallingConventionCold == 2);
......@@ -7814,7 +7937,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
78147937 Buf *contents;
78157938 if (hit) {
78167939 contents = buf_alloc();
7817 if ((err = os_fetch_file_path(builtin_zig_path, contents, false))) {
7940 if ((err = os_fetch_file_path(builtin_zig_path, contents))) {
78187941 fprintf(stderr, "Unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err));
78197942 exit(1);
78207943 }
......@@ -7844,6 +7967,12 @@ static void init(CodeGen *g) {
78447967
78457968 g->have_dynamic_link = detect_dynamic_link(g);
78467969 g->have_pic = detect_pic(g);
7970 g->is_single_threaded = detect_single_threaded(g);
7971 g->have_err_ret_tracing = detect_err_ret_tracing(g);
7972
7973 if (target_is_single_threaded(g->zig_target)) {
7974 g->is_single_threaded = true;
7975 }
78477976
78487977 if (g->is_test_build) {
78497978 g->subsystem = TargetSubsystemConsole;
......@@ -7953,8 +8082,6 @@ static void init(CodeGen *g) {
79538082 }
79548083 }
79558084
7956 g->have_err_ret_tracing = g->build_mode != BuildModeFastRelease && g->build_mode != BuildModeSmallRelease;
7957
79588085 define_builtin_fns(g);
79598086 Error err;
79608087 if ((err = define_builtin_compile_vars(g))) {
......@@ -8093,7 +8220,126 @@ static void detect_libc(CodeGen *g) {
80938220 }
80948221}
80958222
8096AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) {
8223// does not add the "cc" arg
8224void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c) {
8225 if (translate_c) {
8226 args.append("-x");
8227 args.append("c");
8228 }
8229
8230 if (out_dep_path != nullptr) {
8231 args.append("-MD");
8232 args.append("-MV");
8233 args.append("-MF");
8234 args.append(out_dep_path);
8235 }
8236
8237 args.append("-nostdinc");
8238 args.append("-fno-spell-checking");
8239
8240 if (translate_c) {
8241 // this gives us access to preprocessing entities, presumably at
8242 // the cost of performance
8243 args.append("-Xclang");
8244 args.append("-detailed-preprocessing-record");
8245 } else {
8246 switch (g->err_color) {
8247 case ErrColorAuto:
8248 break;
8249 case ErrColorOff:
8250 args.append("-fno-color-diagnostics");
8251 args.append("-fno-caret-diagnostics");
8252 break;
8253 case ErrColorOn:
8254 args.append("-fcolor-diagnostics");
8255 args.append("-fcaret-diagnostics");
8256 break;
8257 }
8258 }
8259
8260 args.append("-isystem");
8261 args.append(buf_ptr(g->zig_c_headers_dir));
8262
8263 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
8264 Buf *include_dir = g->libc_include_dir_list[i];
8265 args.append("-isystem");
8266 args.append(buf_ptr(include_dir));
8267 }
8268
8269 if (g->zig_target->is_native) {
8270 args.append("-march=native");
8271 } else {
8272 args.append("-target");
8273 args.append(buf_ptr(&g->triple_str));
8274 }
8275 if (g->zig_target->os == OsFreestanding) {
8276 args.append("-ffreestanding");
8277 }
8278
8279 if (!g->strip_debug_symbols) {
8280 args.append("-g");
8281 }
8282
8283 switch (g->build_mode) {
8284 case BuildModeDebug:
8285 // windows c runtime requires -D_DEBUG if using debug libraries
8286 args.append("-D_DEBUG");
8287
8288 if (g->libc_link_lib != nullptr) {
8289 args.append("-fstack-protector-strong");
8290 args.append("--param");
8291 args.append("ssp-buffer-size=4");
8292 } else {
8293 args.append("-fno-stack-protector");
8294 }
8295 args.append("-fno-omit-frame-pointer");
8296 break;
8297 case BuildModeSafeRelease:
8298 // See the comment in the BuildModeFastRelease case for why we pass -O2 rather
8299 // than -O3 here.
8300 args.append("-O2");
8301 if (g->libc_link_lib != nullptr) {
8302 args.append("-D_FORTIFY_SOURCE=2");
8303 args.append("-fstack-protector-strong");
8304 args.append("--param");
8305 args.append("ssp-buffer-size=4");
8306 } else {
8307 args.append("-fno-stack-protector");
8308 }
8309 args.append("-fomit-frame-pointer");
8310 break;
8311 case BuildModeFastRelease:
8312 args.append("-DNDEBUG");
8313 // Here we pass -O2 rather than -O3 because, although we do the equivalent of
8314 // -O3 in Zig code, the justification for the difference here is that Zig
8315 // has better detection and prevention of undefined behavior, so -O3 is safer for
8316 // Zig code than it is for C code. Also, C programmers are used to their code
8317 // running in -O2 and thus the -O3 path has been tested less.
8318 args.append("-O2");
8319 args.append("-fno-stack-protector");
8320 args.append("-fomit-frame-pointer");
8321 break;
8322 case BuildModeSmallRelease:
8323 args.append("-DNDEBUG");
8324 args.append("-Os");
8325 args.append("-fno-stack-protector");
8326 args.append("-fomit-frame-pointer");
8327 break;
8328 }
8329
8330 if (target_supports_fpic(g->zig_target) && g->have_pic) {
8331 args.append("-fPIC");
8332 }
8333
8334 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
8335 args.append(g->clang_argv[arg_i]);
8336 }
8337
8338
8339}
8340
8341void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) {
8342 Error err;
80978343 Buf *src_basename = buf_alloc();
80988344 Buf *src_dirname = buf_alloc();
80998345 os_path_split(full_path, src_dirname, src_basename);
......@@ -8105,13 +8351,47 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) {
81058351
81068352 init(g);
81078353
8108 ZigList<ErrorMsg *> errors = {0};
8354 Stage2TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
8355 Stage2TranslateModeImport : Stage2TranslateModeTranslate;
8356
8357
8358 ZigList<const char *> clang_argv = {0};
8359 add_cc_args(g, clang_argv, nullptr, true);
8360
8361 clang_argv.append(buf_ptr(full_path));
8362
8363 if (g->verbose_cc) {
8364 fprintf(stderr, "clang");
8365 for (size_t i = 0; i < clang_argv.length; i += 1) {
8366 fprintf(stderr, " %s", clang_argv.at(i));
8367 }
8368 fprintf(stderr, "\n");
8369 }
8370
8371 clang_argv.append(nullptr); // to make the [start...end] argument work
8372
8373 const char *resources_path = buf_ptr(g->zig_c_headers_dir);
8374 Stage2ErrorMsg *errors_ptr;
8375 size_t errors_len;
8376 Stage2Ast *ast;
81098377 AstNode *root_node;
8110 Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr);
81118378
8112 if (err == ErrorCCompileErrors && errors.length > 0) {
8113 for (size_t i = 0; i < errors.length; i += 1) {
8114 ErrorMsg *err_msg = errors.at(i);
8379 if (use_userland_implementation) {
8380 err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
8381 &clang_argv.at(0), &clang_argv.last(), trans_mode, resources_path);
8382 } else {
8383 err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
8384 trans_mode, resources_path);
8385 }
8386
8387 if (err == ErrorCCompileErrors && errors_len > 0) {
8388 for (size_t i = 0; i < errors_len; i += 1) {
8389 Stage2ErrorMsg *clang_err = &errors_ptr[i];
8390 ErrorMsg *err_msg = err_msg_create_with_offset(
8391 clang_err->filename_ptr ?
8392 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
8393 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
8394 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
81158395 print_err_msg(err_msg, g->err_color);
81168396 }
81178397 exit(1);
......@@ -8122,7 +8402,12 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path) {
81228402 exit(1);
81238403 }
81248404
8125 return root_node;
8405
8406 if (use_userland_implementation) {
8407 stage2_render_ast(ast, out_file);
8408 } else {
8409 ast_render(out_file, root_node, 4);
8410 }
81268411}
81278412
81288413static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *basename) {
......@@ -8233,7 +8518,7 @@ static void gen_root_source(CodeGen *g) {
82338518 Error err;
82348519 // No need for using the caching system for this file fetch because it is handled
82358520 // separately.
8236 if ((err = os_fetch_file_path(resolved_path, source_code, true))) {
8521 if ((err = os_fetch_file_path(resolved_path, source_code))) {
82378522 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err));
82388523 exit(1);
82398524 }
......@@ -8308,7 +8593,7 @@ static void gen_global_asm(CodeGen *g) {
83088593 Buf *asm_file = g->assembly_files.at(i);
83098594 // No need to use the caching system for these fetches because they
83108595 // are handled separately.
8311 if ((err = os_fetch_file_path(asm_file, &contents, false))) {
8596 if ((err = os_fetch_file_path(asm_file, &contents))) {
83128597 zig_panic("Unable to read %s: %s", buf_ptr(asm_file), err_str(err));
83138598 }
83148599 buf_append_buf(&g->global_asm, &contents);
......@@ -8441,90 +8726,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
84418726 args.append("cc");
84428727
84438728 Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path));
8444 args.append("-MD");
8445 args.append("-MV");
8446 args.append("-MF");
8447 args.append(buf_ptr(out_dep_path));
8448
8449 args.append("-nostdinc");
8450 args.append("-fno-spell-checking");
8451
8452 switch (g->err_color) {
8453 case ErrColorAuto:
8454 break;
8455 case ErrColorOff:
8456 args.append("-fno-color-diagnostics");
8457 args.append("-fno-caret-diagnostics");
8458 break;
8459 case ErrColorOn:
8460 args.append("-fcolor-diagnostics");
8461 args.append("-fcaret-diagnostics");
8462 break;
8463 }
8464
8465 args.append("-isystem");
8466 args.append(buf_ptr(g->zig_c_headers_dir));
8467
8468 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
8469 Buf *include_dir = g->libc_include_dir_list[i];
8470 args.append("-isystem");
8471 args.append(buf_ptr(include_dir));
8472 }
8473
8474 if (g->zig_target->is_native) {
8475 args.append("-march=native");
8476 } else {
8477 args.append("-target");
8478 args.append(buf_ptr(&g->triple_str));
8479 }
8480
8481 if (!g->strip_debug_symbols) {
8482 args.append("-g");
8483 }
8484
8485 switch (g->build_mode) {
8486 case BuildModeDebug:
8487 if (g->libc_link_lib != nullptr) {
8488 args.append("-fstack-protector-strong");
8489 args.append("--param");
8490 args.append("ssp-buffer-size=4");
8491 } else {
8492 args.append("-fno-stack-protector");
8493 }
8494 args.append("-fno-omit-frame-pointer");
8495 break;
8496 case BuildModeSafeRelease:
8497 // See the comment in the BuildModeFastRelease case for why we pass -O2 rather
8498 // than -O3 here.
8499 args.append("-O2");
8500 if (g->libc_link_lib != nullptr) {
8501 args.append("-D_FORTIFY_SOURCE=2");
8502 args.append("-fstack-protector-strong");
8503 args.append("--param");
8504 args.append("ssp-buffer-size=4");
8505 } else {
8506 args.append("-fno-stack-protector");
8507 }
8508 args.append("-fomit-frame-pointer");
8509 break;
8510 case BuildModeFastRelease:
8511 args.append("-DNDEBUG");
8512 // Here we pass -O2 rather than -O3 because, although we do the equivalent of
8513 // -O3 in Zig code, the justification for the difference here is that Zig
8514 // has better detection and prevention of undefined behavior, so -O3 is safer for
8515 // Zig code than it is for C code. Also, C programmers are used to their code
8516 // running in -O2 and thus the -O3 path has been tested less.
8517 args.append("-O2");
8518 args.append("-fno-stack-protector");
8519 args.append("-fomit-frame-pointer");
8520 break;
8521 case BuildModeSmallRelease:
8522 args.append("-DNDEBUG");
8523 args.append("-Os");
8524 args.append("-fno-stack-protector");
8525 args.append("-fomit-frame-pointer");
8526 break;
8527 }
8729 add_cc_args(g, args, buf_ptr(out_dep_path), false);
85288730
85298731 args.append("-o");
85308732 args.append(buf_ptr(out_obj_path));
......@@ -8532,19 +8734,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
85328734 args.append("-c");
85338735 args.append(buf_ptr(c_source_file));
85348736
8535 if (target_supports_fpic(g->zig_target) && g->have_pic) {
8536 args.append("-fPIC");
8537 }
8538
8539 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
8540 args.append(g->clang_argv[arg_i]);
8541 }
8542
85438737 for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) {
85448738 args.append(c_file->args.at(arg_i));
85458739 }
85468740
8547
85488741 if (g->verbose_cc) {
85498742 print_zig_cc_cmd("zig", &args);
85508743 }
......@@ -9158,6 +9351,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
91589351 cache_bool(ch, g->linker_rdynamic);
91599352 cache_bool(ch, g->each_lib_rpath);
91609353 cache_bool(ch, g->disable_gen_h);
9354 cache_bool(ch, g->bundle_compiler_rt);
9355 cache_bool(ch, g->disable_stack_probing);
91619356 cache_bool(ch, want_valgrind_support(g));
91629357 cache_bool(ch, g->have_pic);
91639358 cache_bool(ch, g->have_dynamic_link);
......@@ -9268,6 +9463,8 @@ void codegen_build_and_link(CodeGen *g) {
92689463
92699464 g->have_dynamic_link = detect_dynamic_link(g);
92709465 g->have_pic = detect_pic(g);
9466 g->is_single_threaded = detect_single_threaded(g);
9467 g->have_err_ret_tracing = detect_err_ret_tracing(g);
92719468 detect_libc(g);
92729469 detect_dynamic_linker(g);
92739470
src/codegen.hpp+3-1
......@@ -12,6 +12,7 @@
1212#include "errmsg.hpp"
1313#include "target.hpp"
1414#include "libc_installation.hpp"
15#include "userland.h"
1516
1617#include <stdio.h>
1718
......@@ -43,6 +44,7 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
4344void codegen_add_time_event(CodeGen *g, const char *name);
4445void codegen_print_timing_report(CodeGen *g, FILE *f);
4546void codegen_link(CodeGen *g);
47void zig_link_add_compiler_rt(CodeGen *g);
4648void codegen_build_and_link(CodeGen *g);
4749
4850ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path,
......@@ -50,7 +52,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
5052void codegen_add_assembly(CodeGen *g, Buf *path);
5153void codegen_add_object(CodeGen *g, Buf *object_path);
5254
53AstNode *codegen_translate_c(CodeGen *g, Buf *path);
55void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation);
5456
5557Buf *codegen_generate_builtin_source(CodeGen *g);
5658
src/compiler.cpp+4-4
......@@ -179,24 +179,24 @@ Buf *get_zig_lib_dir(void) {
179179 return &saved_lib_dir;
180180}
181181
182Buf *get_zig_std_dir() {
182Buf *get_zig_std_dir(Buf *zig_lib_dir) {
183183 if (saved_std_dir.list.length != 0) {
184184 return &saved_std_dir;
185185 }
186186 buf_resize(&saved_std_dir, 0);
187187
188 os_path_join(get_zig_lib_dir(), buf_create_from_str("std"), &saved_std_dir);
188 os_path_join(zig_lib_dir, buf_create_from_str("std"), &saved_std_dir);
189189
190190 return &saved_std_dir;
191191}
192192
193Buf *get_zig_special_dir() {
193Buf *get_zig_special_dir(Buf *zig_lib_dir) {
194194 if (saved_special_dir.list.length != 0) {
195195 return &saved_special_dir;
196196 }
197197 buf_resize(&saved_special_dir, 0);
198198
199 os_path_join(get_zig_std_dir(), buf_sprintf("special"), &saved_special_dir);
199 os_path_join(get_zig_std_dir(zig_lib_dir), buf_sprintf("special"), &saved_special_dir);
200200
201201 return &saved_special_dir;
202202}
src/compiler.hpp+2-2
......@@ -16,7 +16,7 @@ Error get_compiler_id(Buf **result);
1616Buf *get_self_dynamic_linker_path(void);
1717
1818Buf *get_zig_lib_dir(void);
19Buf *get_zig_special_dir(void);
20Buf *get_zig_std_dir(void);
19Buf *get_zig_special_dir(Buf *zig_lib_dir);
20Buf *get_zig_std_dir(Buf *zig_lib_dir);
2121
2222#endif
src/error.cpp+4
......@@ -50,6 +50,10 @@ const char *err_str(Error err) {
5050 case ErrorUnexpectedWriteFailure: return "unexpected write failure";
5151 case ErrorUnexpectedSeekFailure: return "unexpected seek failure";
5252 case ErrorUnexpectedFileTruncationFailure: return "unexpected file truncation failure";
53 case ErrorUnimplemented: return "unimplemented";
54 case ErrorOperationAborted: return "operation aborted";
55 case ErrorBrokenPipe: return "broken pipe";
56 case ErrorNoSpaceLeft: return "no space left";
5357 }
5458 return "(invalid error)";
5559}
src/error.hpp+2-48
......@@ -8,56 +8,10 @@
88#ifndef ERROR_HPP
99#define ERROR_HPP
1010
11#include <assert.h>
12
13enum Error {
14 ErrorNone,
15 ErrorNoMem,
16 ErrorInvalidFormat,
17 ErrorSemanticAnalyzeFail,
18 ErrorAccess,
19 ErrorInterrupted,
20 ErrorSystemResources,
21 ErrorFileNotFound,
22 ErrorFileSystem,
23 ErrorFileTooBig,
24 ErrorDivByZero,
25 ErrorOverflow,
26 ErrorPathAlreadyExists,
27 ErrorUnexpected,
28 ErrorExactDivRemainder,
29 ErrorNegativeDenominator,
30 ErrorShiftedOutOneBits,
31 ErrorCCompileErrors,
32 ErrorEndOfFile,
33 ErrorIsDir,
34 ErrorNotDir,
35 ErrorUnsupportedOperatingSystem,
36 ErrorSharingViolation,
37 ErrorPipeBusy,
38 ErrorPrimitiveTypeNotFound,
39 ErrorCacheUnavailable,
40 ErrorPathTooLong,
41 ErrorCCompilerCannotFindFile,
42 ErrorReadingDepFile,
43 ErrorInvalidDepFile,
44 ErrorMissingArchitecture,
45 ErrorMissingOperatingSystem,
46 ErrorUnknownArchitecture,
47 ErrorUnknownOperatingSystem,
48 ErrorUnknownABI,
49 ErrorInvalidFilename,
50 ErrorDiskQuota,
51 ErrorDiskSpace,
52 ErrorUnexpectedWriteFailure,
53 ErrorUnexpectedSeekFailure,
54 ErrorUnexpectedFileTruncationFailure,
55};
11#include "userland.h"
5612
5713const char *err_str(Error err);
5814
59static inline void assertNoError(Error err) {
60 assert(err == ErrorNone);
61}
15#define assertNoError(err) assert((err) == ErrorNone);
6216
6317#endif
src/ir.cpp+291-88
......@@ -188,6 +188,19 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
188188 assert(get_src_ptr_type(const_val->type) != nullptr);
189189 assert(const_val->special == ConstValSpecialStatic);
190190 ConstExprValue *result;
191
192 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
193 case OnePossibleValueInvalid:
194 zig_unreachable();
195 case OnePossibleValueYes:
196 result = create_const_vals(1);
197 result->type = const_val->type->data.pointer.child_type;
198 result->special = ConstValSpecialStatic;
199 return result;
200 case OnePossibleValueNo:
201 break;
202 }
203
191204 switch (const_val->data.x_ptr.special) {
192205 case ConstPtrSpecialInvalid:
193206 zig_unreachable();
......@@ -356,6 +369,18 @@ static void ir_ref_var(ZigVar *var) {
356369 var->ref_count += 1;
357370}
358371
372ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
373 ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type,
374 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr,
375 node, nullptr, ira->new_irb.exec, nullptr);
376
377 if (type_is_invalid(result->type))
378 return ira->codegen->builtin_types.entry_invalid;
379
380 assert(result->special != ConstValSpecialRuntime);
381 return result->data.x_type;
382}
383
359384static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) {
360385 IrBasicBlock *result = allocate<IrBasicBlock>(1);
361386 result->scope = scope;
......@@ -978,6 +1003,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) {
9781003 return IrInstructionIdAssertZero;
9791004}
9801005
1006static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) {
1007 return IrInstructionIdAssertNonNull;
1008}
1009
9811010template<typename T>
9821011static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
9831012 T *special_instruction = allocate<T>(1);
......@@ -3012,6 +3041,19 @@ static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source
30123041 return &instruction->base;
30133042}
30143043
3044static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction,
3045 IrInstruction *target)
3046{
3047 IrInstructionAssertNonNull *instruction = ir_build_instruction<IrInstructionAssertNonNull>(&ira->new_irb,
3048 source_instruction->scope, source_instruction->source_node);
3049 instruction->base.value.type = ira->codegen->builtin_types.entry_void;
3050 instruction->target = target;
3051
3052 ir_ref_instruction(target, ira->new_irb.current_basic_block);
3053
3054 return &instruction->base;
3055}
3056
30153057static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
30163058 results[ReturnKindUnconditional] = 0;
30173059 results[ReturnKindError] = 0;
......@@ -5391,10 +5433,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
53915433 add_node_error(irb->codegen, variable_declaration->section_expr,
53925434 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
53935435 }
5394 if (variable_declaration->threadlocal_tok != nullptr) {
5395 add_token_error(irb->codegen, node->owner, variable_declaration->threadlocal_tok,
5396 buf_sprintf("function-local variable '%s' cannot be threadlocal", buf_ptr(variable_declaration->symbol)));
5397 }
5436
5437 // Parser should ensure that this never happens
5438 assert(variable_declaration->threadlocal_tok == nullptr);
53985439
53995440 // Temporarily set the name of the IrExecutable to the VariableDeclaration
54005441 // so that the struct or enum from the init expression inherits the name.
......@@ -5767,8 +5808,10 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
57675808
57685809 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
57695810
5770 if (!instr_is_unreachable(body_result))
5811 if (!instr_is_unreachable(body_result)) {
5812 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
57715813 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
5814 }
57725815
57735816 ir_set_cursor_at_end_and_append_block(irb, continue_block);
57745817 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
......@@ -7891,6 +7934,11 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
78917934 return ir_add_error_node(ira, source_instruction->source_node, msg);
78927935}
78937936
7937static void ir_assert(bool ok, IrInstruction *source_instruction) {
7938 if (ok) return;
7939 src_assert(ok, source_instruction->source_node);
7940}
7941
78947942// This function takes a comptime ptr and makes the child const value conform to the type
78957943// described by the pointer.
78967944static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
......@@ -7943,7 +7991,7 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
79437991 return &codegen->invalid_instruction->value;
79447992 }
79457993 }
7946 return &codegen->invalid_instruction->value;
7994 zig_unreachable();
79477995}
79487996
79497997static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {
......@@ -8088,6 +8136,8 @@ static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {
80888136 case 64:
80898137 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat);
80908138 break;
8139 case 80:
8140 zig_panic("TODO");
80918141 case 128:
80928142 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat);
80938143 break;
......@@ -9904,6 +9954,7 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *t
99049954
99059955static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
99069956 ConstGlobalRefs *global_refs = dest->global_refs;
9957 assert(!same_global_refs || src->global_refs != nullptr);
99079958 *dest = *src;
99089959 if (!same_global_refs) {
99099960 dest->global_refs = global_refs;
......@@ -9949,6 +10000,8 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
994910000 case 64:
995010001 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat);
995110002 break;
10003 case 80:
10004 zig_panic("TODO");
995210005 case 128:
995310006 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat);
995410007 break;
......@@ -9978,6 +10031,8 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
997810031 case 64:
997910032 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat);
998010033 break;
10034 case 80:
10035 zig_panic("TODO");
998110036 case 128:
998210037 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat);
998310038 break;
......@@ -10170,6 +10225,7 @@ static void ir_finish_bb(IrAnalyze *ira) {
1017010225 ira->instruction_index += 1;
1017110226 }
1017210227
10228 size_t my_old_bb_index = ira->old_bb_index;
1017310229 ira->old_bb_index += 1;
1017410230
1017510231 bool need_repeat = true;
......@@ -10180,7 +10236,7 @@ static void ir_finish_bb(IrAnalyze *ira) {
1018010236 ira->old_bb_index += 1;
1018110237 continue;
1018210238 }
10183 if (old_bb->other->instruction_list.length != 0) {
10239 if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) {
1018410240 ira->old_bb_index += 1;
1018510241 continue;
1018610242 }
......@@ -10205,16 +10261,18 @@ static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
1020510261
1020610262static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) {
1020710263 size_t *bbc = ira->new_irb.exec->backward_branch_count;
10208 size_t quota = ira->new_irb.exec->backward_branch_quota;
10264 size_t *quota = ira->new_irb.exec->backward_branch_quota;
1020910265
1021010266 // If we're already over quota, we've already given an error message for this.
10211 if (*bbc > quota) {
10267 if (*bbc > *quota) {
10268 assert(ira->codegen->errors.length > 0);
1021210269 return false;
1021310270 }
1021410271
1021510272 *bbc += 1;
10216 if (*bbc > quota) {
10217 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));
10273 if (*bbc > *quota) {
10274 ir_add_error(ira, source_instruction,
10275 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota));
1021810276 return false;
1021910277 }
1022010278 return true;
......@@ -10249,6 +10307,12 @@ static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instru
1024910307 return result;
1025010308}
1025110309
10310static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
10311 IrInstruction *result = ir_const(ira, source_instruction, ty);
10312 result->value.special = ConstValSpecialUndef;
10313 return result;
10314}
10315
1025210316static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
1025310317 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
1025410318}
......@@ -10295,7 +10359,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
1029510359}
1029610360
1029710361ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
10298 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
10362 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
1029910363 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
1030010364 IrExecutable *parent_exec, AstNode *expected_type_source_node)
1030110365{
......@@ -10317,7 +10381,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
1031710381
1031810382 if (codegen->verbose_ir) {
1031910383 fprintf(stderr, "\nSource: ");
10320 ast_render(codegen, stderr, node, 4);
10384 ast_render(stderr, node, 4);
1032110385 fprintf(stderr, "\n{ // (IR)\n");
1032210386 ir_print(codegen, stderr, ir_executable, 2);
1032310387 fprintf(stderr, "}\n");
......@@ -10562,19 +10626,34 @@ static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *so
1056210626 assert(instr_is_comptime(value));
1056310627
1056410628 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
10565 assert(val);
10629 assert(val != nullptr);
1056610630
10567 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, source_instr->scope, source_instr->source_node);
10568 const_instruction->base.value.special = ConstValSpecialStatic;
10631 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
10632 result->value.special = ConstValSpecialStatic;
1056910633 if (get_codegen_ptr_type(wanted_type) != nullptr) {
10570 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialNull;
10634 result->value.data.x_ptr.special = ConstPtrSpecialNull;
1057110635 } else if (is_opt_err_set(wanted_type)) {
10572 const_instruction->base.value.data.x_err_set = nullptr;
10636 result->value.data.x_err_set = nullptr;
1057310637 } else {
10574 const_instruction->base.value.data.x_optional = nullptr;
10638 result->value.data.x_optional = nullptr;
1057510639 }
10576 const_instruction->base.value.type = wanted_type;
10577 return &const_instruction->base;
10640 return result;
10641}
10642
10643static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr,
10644 IrInstruction *value, ZigType *wanted_type)
10645{
10646 assert(wanted_type->id == ZigTypeIdPointer);
10647 assert(wanted_type->data.pointer.ptr_len == PtrLenC);
10648 assert(instr_is_comptime(value));
10649
10650 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
10651 assert(val != nullptr);
10652
10653 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
10654 result->value.data.x_ptr.special = ConstPtrSpecialNull;
10655 result->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
10656 return result;
1057810657}
1057910658
1058010659static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value,
......@@ -11576,6 +11655,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1157611655 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);
1157711656 }
1157811657
11658 // cast from null literal to C pointer
11659 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC &&
11660 actual_type->id == ZigTypeIdNull)
11661 {
11662 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type);
11663 }
11664
1157911665 // cast from [N]T to E![]const T
1158011666 if (wanted_type->id == ZigTypeIdErrorUnion &&
1158111667 is_slice(wanted_type->data.error_union.payload_type) &&
......@@ -12193,14 +12279,12 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1219312279
1219412280 IrBinOp op_id = bin_op_instruction->op_id;
1219512281 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq);
12196 if (is_equality_cmp &&
12282 if (is_equality_cmp && op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) {
12283 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq));
12284 } else if (is_equality_cmp &&
1219712285 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) ||
12198 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional) ||
12199 (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull)))
12286 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional)))
1220012287 {
12201 if (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) {
12202 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq));
12203 }
1220412288 IrInstruction *maybe_op;
1220512289 if (op1->value.type->id == ZigTypeIdNull) {
1220612290 maybe_op = op2;
......@@ -12222,6 +12306,44 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1222212306 source_node, maybe_op);
1222312307 is_non_null->value.type = ira->codegen->builtin_types.entry_bool;
1222412308
12309 if (op_id == IrBinOpCmpEq) {
12310 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope,
12311 bin_op_instruction->base.source_node, is_non_null);
12312 result->value.type = ira->codegen->builtin_types.entry_bool;
12313 return result;
12314 } else {
12315 return is_non_null;
12316 }
12317 } else if (is_equality_cmp &&
12318 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer &&
12319 op2->value.type->data.pointer.ptr_len == PtrLenC) ||
12320 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer &&
12321 op1->value.type->data.pointer.ptr_len == PtrLenC)))
12322 {
12323 IrInstruction *c_ptr_op;
12324 if (op1->value.type->id == ZigTypeIdNull) {
12325 c_ptr_op = op2;
12326 } else if (op2->value.type->id == ZigTypeIdNull) {
12327 c_ptr_op = op1;
12328 } else {
12329 zig_unreachable();
12330 }
12331 if (instr_is_comptime(c_ptr_op)) {
12332 ConstExprValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk);
12333 if (!c_ptr_val)
12334 return ira->codegen->invalid_instruction;
12335 if (c_ptr_val->special == ConstValSpecialUndef)
12336 return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool);
12337 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
12338 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
12339 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
12340 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null;
12341 return ir_const_bool(ira, &bin_op_instruction->base, bool_result);
12342 }
12343 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope,
12344 source_node, c_ptr_op);
12345 is_non_null->value.type = ira->codegen->builtin_types.entry_bool;
12346
1222512347 if (op_id == IrBinOpCmpEq) {
1222612348 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope,
1222712349 bin_op_instruction->base.source_node, is_non_null);
......@@ -12231,8 +12353,9 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
1223112353 return is_non_null;
1223212354 }
1223312355 } else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) {
12234 ir_add_error_node(ira, source_node, buf_sprintf("only optionals (not '%s') can compare to null",
12235 buf_ptr(&(op1->value.type->id == ZigTypeIdNull ? op2->value.type->name : op1->value.type->name))));
12356 ZigType *non_null_type = (op1->value.type->id == ZigTypeIdNull) ? op2->value.type : op1->value.type;
12357 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null",
12358 buf_ptr(&non_null_type->name)));
1223612359 return ira->codegen->invalid_instruction;
1223712360 }
1223812361
......@@ -13828,11 +13951,12 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
1382813951 zig_unreachable();
1382913952}
1383013953
13831static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, ZigType *fn_type,
13832 IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst)
13954static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,
13955 ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
13956 IrInstruction *async_allocator_inst)
1383313957{
1383413958 Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
13835 assert(async_allocator_inst->value.type->id == ZigTypeIdPointer);
13959 ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
1383613960 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
1383713961 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
1383813962 async_allocator_inst, container_type);
......@@ -13840,7 +13964,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
1384013964 return ira->codegen->invalid_instruction;
1384113965 }
1384213966 ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
13843 assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer);
13967 ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base);
1384413968
1384513969 ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
1384613970 if (realloc_fn_type->id != ZigTypeIdFn) {
......@@ -13875,7 +13999,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
1387513999 IrInstruction *casted_arg;
1387614000 if (param_decl_node->data.param_decl.var_token == nullptr) {
1387714001 AstNode *param_type_node = param_decl_node->data.param_decl.type;
13878 ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node);
14002 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
1387914003 if (type_is_invalid(param_type))
1388014004 return false;
1388114005
......@@ -13915,7 +14039,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1391514039 } else {
1391614040 if (param_decl_node->data.param_decl.var_token == nullptr) {
1391714041 AstNode *param_type_node = param_decl_node->data.param_decl.type;
13918 ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
14042 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
1391914043 if (type_is_invalid(param_type))
1392014044 return false;
1392114045
......@@ -14296,7 +14420,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1429614420 }
1429714421
1429814422 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
14299 ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node);
14423 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node);
1430014424 if (type_is_invalid(specified_return_type))
1430114425 return ira->codegen->invalid_instruction;
1430214426 ZigType *return_type;
......@@ -14532,7 +14656,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1453214656
1453314657 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
1453414658 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
14535 ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
14659 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
1453614660 if (type_is_invalid(specified_return_type))
1453714661 return ira->codegen->invalid_instruction;
1453814662 if (fn_proto_node->data.fn_proto.auto_err_set) {
......@@ -14559,7 +14683,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
1455914683 if (call_instruction->is_async) {
1456014684 AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type;
1456114685 if (async_allocator_type_node != nullptr) {
14562 ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node);
14686 ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node);
1456314687 if (type_is_invalid(async_allocator_type))
1456414688 return ira->codegen->invalid_instruction;
1456514689 inst_fn_type_id.async_allocator_type = async_allocator_type;
......@@ -15822,7 +15946,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
1582215946 }
1582315947 }
1582415948
15825 if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
15949 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
1582615950 ErrorMsg *msg = ir_add_error_node(ira, source_node,
1582715951 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
1582815952 buf_ptr(lib_name)));
......@@ -16696,16 +16820,16 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
1669616820 case ZigTypeIdUnreachable:
1669716821 case ZigTypeIdUndefined:
1669816822 case ZigTypeIdNull:
16699 case ZigTypeIdComptimeFloat:
16700 case ZigTypeIdComptimeInt:
16701 case ZigTypeIdEnumLiteral:
1670216823 case ZigTypeIdBoundFn:
16703 case ZigTypeIdMetaType:
1670416824 case ZigTypeIdArgTuple:
1670516825 case ZigTypeIdOpaque:
16706 ir_add_error_node(ira, size_of_instruction->base.source_node,
16826 ir_add_error_node(ira, type_value->source_node,
1670716827 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
1670816828 return ira->codegen->invalid_instruction;
16829 case ZigTypeIdMetaType:
16830 case ZigTypeIdEnumLiteral:
16831 case ZigTypeIdComptimeFloat:
16832 case ZigTypeIdComptimeInt:
1670916833 case ZigTypeIdVoid:
1671016834 case ZigTypeIdBool:
1671116835 case ZigTypeIdInt:
......@@ -16732,11 +16856,30 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
1673216856static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
1673316857 ZigType *type_entry = value->value.type;
1673416858
16735 if (type_entry->id == ZigTypeIdOptional) {
16859 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) {
1673616860 if (instr_is_comptime(value)) {
16737 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad);
16738 if (!maybe_val)
16861 ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk);
16862 if (c_ptr_val == nullptr)
16863 return ira->codegen->invalid_instruction;
16864 if (c_ptr_val->special == ConstValSpecialUndef)
16865 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool);
16866 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
16867 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
16868 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
16869 return ir_const_bool(ira, source_inst, !is_null);
16870 }
16871
16872 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb,
16873 source_inst->scope, source_inst->source_node, value);
16874 result->value.type = ira->codegen->builtin_types.entry_bool;
16875 return result;
16876 } else if (type_entry->id == ZigTypeIdOptional) {
16877 if (instr_is_comptime(value)) {
16878 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk);
16879 if (maybe_val == nullptr)
1673916880 return ira->codegen->invalid_instruction;
16881 if (maybe_val->special == ConstValSpecialUndef)
16882 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool);
1674016883
1674116884 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val));
1674216885 }
......@@ -16770,6 +16913,32 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
1677016913 if (type_is_invalid(type_entry))
1677116914 return ira->codegen->invalid_instruction;
1677216915
16916 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) {
16917 if (instr_is_comptime(base_ptr)) {
16918 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
16919 if (!val)
16920 return ira->codegen->invalid_instruction;
16921 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
16922 ConstExprValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
16923 if (c_ptr_val == nullptr)
16924 return ira->codegen->invalid_instruction;
16925 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
16926 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
16927 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
16928 if (is_null) {
16929 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
16930 return ira->codegen->invalid_instruction;
16931 }
16932 return base_ptr;
16933 }
16934 }
16935 if (!safety_check_on)
16936 return base_ptr;
16937 IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr);
16938 ir_build_assert_non_null(ira, source_instr, c_ptr_val);
16939 return base_ptr;
16940 }
16941
1677316942 if (type_entry->id != ZigTypeIdOptional) {
1677416943 ir_add_error_node(ira, base_ptr->source_node,
1677516944 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name)));
......@@ -16784,11 +16953,11 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
1678416953 ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
1678516954 if (!val)
1678616955 return ira->codegen->invalid_instruction;
16787 ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
16788 if (maybe_val == nullptr)
16789 return ira->codegen->invalid_instruction;
16790
1679116956 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
16957 ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
16958 if (maybe_val == nullptr)
16959 return ira->codegen->invalid_instruction;
16960
1679216961 if (optional_value_is_null(maybe_val)) {
1679316962 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
1679416963 return ira->codegen->invalid_instruction;
......@@ -17435,6 +17604,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1743517604 ConstExprValue const_val = {};
1743617605 const_val.special = ConstValSpecialStatic;
1743717606 const_val.type = container_type;
17607 // const_val.global_refs = allocate<ConstGlobalRefs>(1);
1743817608 const_val.data.x_struct.fields = create_const_vals(actual_field_count);
1743917609 for (size_t i = 0; i < instr_field_count; i += 1) {
1744017610 IrInstructionContainerInitFieldsField *field = &fields[i];
......@@ -17498,7 +17668,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1749817668 if (const_val.special == ConstValSpecialStatic) {
1749917669 IrInstruction *result = ir_const(ira, instruction, nullptr);
1750017670 ConstExprValue *out_val = &result->value;
17501 copy_const_val(out_val, &const_val, true);
17671 copy_const_val(out_val, &const_val, false);
1750217672 out_val->type = container_type;
1750317673
1750417674 for (size_t i = 0; i < instr_field_count; i += 1) {
......@@ -17570,6 +17740,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
1757017740 ConstExprValue const_val = {};
1757117741 const_val.special = ConstValSpecialStatic;
1757217742 const_val.type = fixed_size_array_type;
17743 // const_val.global_refs = allocate<ConstGlobalRefs>(1);
1757317744 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
1757417745
1757517746 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
......@@ -17606,8 +17777,6 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
1760617777 if (const_val.special == ConstValSpecialStatic) {
1760717778 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
1760817779 ConstExprValue *out_val = &result->value;
17609 // Make sure to pass same_global_refs=false here in order not to
17610 // zero the global_refs field for `result` (#1608)
1761117780 copy_const_val(out_val, &const_val, false);
1761217781 result->value.type = fixed_size_array_type;
1761317782 for (size_t i = 0; i < elem_count; i += 1) {
......@@ -18961,8 +19130,8 @@ static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ir
1896119130 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota))
1896219131 return ira->codegen->invalid_instruction;
1896319132
18964 if (new_quota > ira->new_irb.exec->backward_branch_quota) {
18965 ira->new_irb.exec->backward_branch_quota = new_quota;
19133 if (new_quota > *ira->new_irb.exec->backward_branch_quota) {
19134 *ira->new_irb.exec->backward_branch_quota = new_quota;
1896619135 }
1896719136
1896819137 return ir_const_void(ira, &instruction->base);
......@@ -19059,24 +19228,50 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
1905919228 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path));
1906019229 }
1906119230
19062 ZigList<ErrorMsg *> errors = {0};
19063
1906419231 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path));
19232
19233 ZigList<const char *> clang_argv = {0};
19234
19235 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true);
19236
19237 clang_argv.append(buf_ptr(&tmp_c_file_path));
19238
19239 if (ira->codegen->verbose_cc) {
19240 fprintf(stderr, "clang");
19241 for (size_t i = 0; i < clang_argv.length; i += 1) {
19242 fprintf(stderr, " %s", clang_argv.at(i));
19243 }
19244 fprintf(stderr, "\n");
19245 }
19246
19247 clang_argv.append(nullptr); // to make the [start...end] argument work
19248
1906519249 AstNode *root_node;
19066 if ((err = parse_h_file(&root_node, &errors, buf_ptr(&tmp_c_file_path), ira->codegen, tmp_dep_file))) {
19250 Stage2ErrorMsg *errors_ptr;
19251 size_t errors_len;
19252
19253 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
19254
19255 if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
19256 &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path)))
19257 {
1906719258 if (err != ErrorCCompileErrors) {
1906819259 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
1906919260 return ira->codegen->invalid_instruction;
1907019261 }
19071 assert(errors.length > 0);
1907219262
1907319263 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed"));
1907419264 if (ira->codegen->libc_link_lib == nullptr) {
1907519265 add_error_note(ira->codegen, parent_err_msg, node,
1907619266 buf_sprintf("libc headers not available; compilation does not link against libc"));
1907719267 }
19078 for (size_t i = 0; i < errors.length; i += 1) {
19079 ErrorMsg *err_msg = errors.at(i);
19268 for (size_t i = 0; i < errors_len; i += 1) {
19269 Stage2ErrorMsg *clang_err = &errors_ptr[i];
19270 ErrorMsg *err_msg = err_msg_create_with_offset(
19271 clang_err->filename_ptr ?
19272 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
19273 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
19274 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
1908019275 err_msg_add_note(parent_err_msg, err_msg);
1908119276 }
1908219277
......@@ -19106,7 +19301,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
1910619301 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
1910719302 return ira->codegen->invalid_instruction;
1910819303 }
19109 ast_render(ira->codegen, out_file, root_node, 4);
19304 ast_render(out_file, root_node, 4);
1911019305 if (fclose(out_file) != 0) {
1911119306 ir_add_error_node(ira, node,
1911219307 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));
......@@ -21026,18 +21221,24 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
2102621221 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
2102721222 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i];
2102821223
21029 IrInstruction *start_value = range->start->child;
21224 IrInstruction *start_value_uncasted = range->start->child;
21225 if (type_is_invalid(start_value_uncasted->value.type))
21226 return ira->codegen->invalid_instruction;
21227 IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type);
2103021228 if (type_is_invalid(start_value->value.type))
2103121229 return ira->codegen->invalid_instruction;
2103221230
21033 IrInstruction *end_value = range->end->child;
21231 IrInstruction *end_value_uncasted = range->end->child;
21232 if (type_is_invalid(end_value_uncasted->value.type))
21233 return ira->codegen->invalid_instruction;
21234 IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type);
2103421235 if (type_is_invalid(end_value->value.type))
2103521236 return ira->codegen->invalid_instruction;
2103621237
21037 assert(start_value->value.type->id == ZigTypeIdErrorSet);
21238 ir_assert(start_value->value.type->id == ZigTypeIdErrorSet, &instruction->base);
2103821239 uint32_t start_index = start_value->value.data.x_err_set->value;
2103921240
21040 assert(end_value->value.type->id == ZigTypeIdErrorSet);
21241 ir_assert(end_value->value.type->id == ZigTypeIdErrorSet, &instruction->base);
2104121242 uint32_t end_index = end_value->value.data.x_err_set->value;
2104221243
2104321244 if (start_index != end_index) {
......@@ -21260,7 +21461,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
2126021461 }
2126121462
2126221463 IrInstruction *result = ir_const(ira, target, result_type);
21263 copy_const_val(&result->value, val, false);
21464 copy_const_val(&result->value, val, true);
2126421465 result->value.type = result_type;
2126521466 return result;
2126621467 }
......@@ -21330,7 +21531,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2133021531 }
2133121532
2133221533 IrInstruction *result = ir_const(ira, source_instr, dest_type);
21333 copy_const_val(&result->value, val, false);
21534 copy_const_val(&result->value, val, true);
2133421535 result->value.type = dest_type;
2133521536
2133621537 // Keep the bigger alignment, it can only help-
......@@ -21562,7 +21763,7 @@ static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNod
2156221763
2156321764static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
2156421765 Error err;
21565 assert(val->special == ConstValSpecialStatic);
21766 src_assert(val->special == ConstValSpecialStatic, source_node);
2156621767 switch (val->type->id) {
2156721768 case ZigTypeIdInvalid:
2156821769 case ZigTypeIdMetaType:
......@@ -21612,7 +21813,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2161221813 zig_panic("TODO buf_read_value_bytes enum packed");
2161321814 case ContainerLayoutExtern: {
2161421815 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type;
21615 assert(tag_int_type->id == ZigTypeIdInt);
21816 src_assert(tag_int_type->id == ZigTypeIdInt, source_node);
2161621817 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count,
2161721818 codegen->is_big_endian, tag_int_type->data.integral.is_signed);
2161821819 return ErrorNone;
......@@ -21667,7 +21868,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
2166721868 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
2166821869 while (src_i < src_field_count) {
2166921870 TypeStructField *field = &val->type->data.structure.fields[src_i];
21670 assert(field->gen_index != SIZE_MAX);
21871 src_assert(field->gen_index != SIZE_MAX, source_node);
2167121872 if (field->gen_index != gen_i)
2167221873 break;
2167321874 ConstExprValue *field_val = &val->data.x_struct.fields[src_i];
......@@ -21743,10 +21944,10 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
2174321944 Error err;
2174421945
2174521946 ZigType *src_type = value->value.type;
21746 assert(get_codegen_ptr_type(src_type) == nullptr);
21747 assert(type_can_bit_cast(src_type));
21748 assert(get_codegen_ptr_type(dest_type) == nullptr);
21749 assert(type_can_bit_cast(dest_type));
21947 ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr);
21948 ir_assert(type_can_bit_cast(src_type), source_instr);
21949 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr);
21950 ir_assert(type_can_bit_cast(dest_type), source_instr);
2175021951
2175121952 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown)))
2175221953 return ira->codegen->invalid_instruction;
......@@ -21836,8 +22037,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
2183622037static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
2183722038 ZigType *ptr_type)
2183822039{
21839 assert(get_src_ptr_type(ptr_type) != nullptr);
21840 assert(type_has_bits(ptr_type));
22040 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr);
22041 ir_assert(type_has_bits(ptr_type), source_instr);
2184122042
2184222043 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize);
2184322044 if (type_is_invalid(casted_int->value.type))
......@@ -21936,7 +22137,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
2193622137 case TldIdFn: {
2193722138 TldFn *tld_fn = (TldFn *)tld;
2193822139 ZigFn *fn_entry = tld_fn->fn_entry;
21939 assert(fn_entry->type_entry);
22140 ir_assert(fn_entry->type_entry, &instruction->base);
2194022141
2194122142 if (tld_fn->extern_lib_name != nullptr) {
2194222143 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node);
......@@ -22134,7 +22335,7 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
2213422335 ZigType *result_type = fn_type_id->param_info[arg_index].type;
2213522336 if (result_type == nullptr) {
2213622337 // Args are only unresolved if our function is generic.
22137 assert(fn_type->data.fn.is_generic);
22338 ir_assert(fn_type->data.fn.is_generic, &instruction->base);
2213822339
2213922340 ir_add_error(ira, arg_index_inst,
2214022341 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
......@@ -22220,7 +22421,7 @@ static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstru
2222022421 return ira->codegen->invalid_instruction;
2222122422
2222222423 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
22223 assert(fn_entry != nullptr);
22424 ir_assert(fn_entry != nullptr, &instruction->base);
2222422425 IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
2222522426 coro_id, coro_mem_ptr);
2222622427 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
......@@ -22458,7 +22659,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
2245822659 }
2245922660
2246022661 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) {
22461 assert(instruction->ordering != nullptr);
22662 ir_assert(instruction->ordering != nullptr, &instruction->base);
2246222663 ir_add_error(ira, instruction->ordering,
2246322664 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel"));
2246422665 return ira->codegen->invalid_instruction;
......@@ -22466,7 +22667,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
2246622667
2246722668 if (instr_is_comptime(casted_ptr)) {
2246822669 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr);
22469 assert(result->value.type != nullptr);
22670 ir_assert(result->value.type != nullptr, &instruction->base);
2247022671 return result;
2247122672 }
2247222673
......@@ -22496,7 +22697,7 @@ static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, I
2249622697 return ira->codegen->invalid_instruction;
2249722698
2249822699 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
22499 assert(fn_entry != nullptr);
22700 ir_assert(fn_entry != nullptr, &instruction->base);
2250022701
2250122702 if (type_can_fail(promise_result_type)) {
2250222703 fn_entry->calls_or_awaits_errorable_fn = true;
......@@ -22512,9 +22713,9 @@ static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira
2251222713 if (type_is_invalid(coro_promise_ptr->value.type))
2251322714 return ira->codegen->invalid_instruction;
2251422715
22515 assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer);
22716 ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base);
2251622717 ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type;
22517 assert(promise_frame_type->id == ZigTypeIdStruct);
22718 ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base);
2251822719 ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry;
2251922720
2252022721 if (!type_can_fail(promise_result_type)) {
......@@ -22606,7 +22807,7 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS
2260622807 return result;
2260722808 }
2260822809
22609 assert(float_type->id == ZigTypeIdFloat);
22810 ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base);
2261022811 if (float_type->data.floating.bit_count != 16 &&
2261122812 float_type->data.floating.bit_count != 32 &&
2261222813 float_type->data.floating.bit_count != 64) {
......@@ -22817,6 +23018,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2281723018 case IrInstructionIdArrayToVector:
2281823019 case IrInstructionIdVectorToArray:
2281923020 case IrInstructionIdAssertZero:
23021 case IrInstructionIdAssertNonNull:
2282023022 case IrInstructionIdResizeSlice:
2282123023 case IrInstructionIdLoadPtrGen:
2282223024 case IrInstructionIdBitCastGen:
......@@ -23096,7 +23298,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2309623298
2309723299static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
2309823300 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
23099 assert(new_instruction->value.type != nullptr);
23301 ir_assert(new_instruction->value.type != nullptr, old_instruction);
2310023302 old_instruction->child = new_instruction;
2310123303 return new_instruction;
2310223304}
......@@ -23221,6 +23423,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2322123423 case IrInstructionIdCmpxchgGen:
2322223424 case IrInstructionIdCmpxchgSrc:
2322323425 case IrInstructionIdAssertZero:
23426 case IrInstructionIdAssertNonNull:
2322423427 case IrInstructionIdResizeSlice:
2322523428 case IrInstructionIdGlobalAsm:
2322623429 return true;
src/ir.hpp+1-1
......@@ -14,7 +14,7 @@ bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_executable
1414bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
1515
1616ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
17 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
17 ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
1818 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
1919 IrExecutable *parent_exec, AstNode *expected_type_source_node);
2020
src/ir_print.cpp+9
......@@ -1003,6 +1003,12 @@ static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruct
10031003 fprintf(irp->f, ")");
10041004}
10051005
1006static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *instruction) {
1007 fprintf(irp->f, "AssertNonNull(");
1008 ir_print_other_instruction(irp, instruction->target);
1009 fprintf(irp->f, ")");
1010}
1011
10061012static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
10071013 fprintf(irp->f, "@resizeSlice(");
10081014 ir_print_other_instruction(irp, instruction->operand);
......@@ -1880,6 +1886,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
18801886 case IrInstructionIdAssertZero:
18811887 ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
18821888 break;
1889 case IrInstructionIdAssertNonNull:
1890 ir_print_assert_non_null(irp, (IrInstructionAssertNonNull *)instruction);
1891 break;
18831892 case IrInstructionIdResizeSlice:
18841893 ir_print_resize_slice(irp, (IrInstructionResizeSlice *)instruction);
18851894 break;
src/libc_installation.cpp+30-6
......@@ -14,6 +14,7 @@ static const char *zig_libc_keys[] = {
1414 "include_dir",
1515 "sys_include_dir",
1616 "crt_dir",
17 "static_crt_dir",
1718 "msvc_lib_dir",
1819 "kernel32_lib_dir",
1920};
......@@ -34,6 +35,7 @@ static void zig_libc_init_empty(ZigLibCInstallation *libc) {
3435 buf_init_from_str(&libc->include_dir, "");
3536 buf_init_from_str(&libc->sys_include_dir, "");
3637 buf_init_from_str(&libc->crt_dir, "");
38 buf_init_from_str(&libc->static_crt_dir, "");
3739 buf_init_from_str(&libc->msvc_lib_dir, "");
3840 buf_init_from_str(&libc->kernel32_lib_dir, "");
3941}
......@@ -45,7 +47,7 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
4547 bool found_keys[array_length(zig_libc_keys)] = {};
4648
4749 Buf *contents = buf_alloc();
48 if ((err = os_fetch_file_path(libc_file, contents, false))) {
50 if ((err = os_fetch_file_path(libc_file, contents))) {
4951 if (err != ErrorFileNotFound && verbose) {
5052 fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err));
5153 }
......@@ -74,8 +76,9 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
7476 match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
7577 match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->sys_include_dir);
7678 match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir);
77 match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->msvc_lib_dir);
78 match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->kernel32_lib_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);
7982 }
8083
8184 for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
......@@ -110,6 +113,15 @@ Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget
110113 }
111114 }
112115
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
113125 if (buf_len(&libc->msvc_lib_dir) == 0) {
114126 if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
115127 if (verbose) {
......@@ -311,6 +323,10 @@ static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool
311323#endif
312324
313325#if defined(ZIG_OS_WINDOWS)
326static Error zig_libc_find_native_static_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
327 return zig_libc_cc_print_file_name("crtbegin.o", &self->static_crt_dir, true, verbose);
328}
329
314330static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
315331 Error err;
316332 if ((err = os_get_win32_ucrt_include_path(sdk, &self->include_dir))) {
......@@ -322,7 +338,7 @@ static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self,
322338 return ErrorNone;
323339}
324340
325static Error zig_libc_find_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
341static Error zig_libc_find_native_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
326342 bool verbose)
327343{
328344 Error err;
......@@ -398,11 +414,16 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
398414 "# On POSIX it's the directory that includes `sys/errno.h`.\n"
399415 "sys_include_dir=%s\n"
400416 "\n"
401 "# The directory that contains `crt1.o`.\n"
417 "# The directory that contains `crt1.o` or `crt2.o`.\n"
402418 "# On POSIX, can be found with `cc -print-file-name=crt1.o`.\n"
403419 "# Not needed when targeting MacOS.\n"
404420 "crt_dir=%s\n"
405421 "\n"
422 "# The directory that contains `crtbegin.o`.\n"
423 "# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.\n"
424 "# Not needed when targeting MacOS.\n"
425 "static_crt_dir=%s\n"
426 "\n"
406427 "# The directory that contains `vcruntime.lib`.\n"
407428 "# Only needed when targeting MSVC on Windows.\n"
408429 "msvc_lib_dir=%s\n"
......@@ -415,6 +436,7 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
415436 buf_ptr(&self->include_dir),
416437 buf_ptr(&self->sys_include_dir),
417438 buf_ptr(&self->crt_dir),
439 buf_ptr(&self->static_crt_dir),
418440 buf_ptr(&self->msvc_lib_dir),
419441 buf_ptr(&self->kernel32_lib_dir)
420442 );
......@@ -431,6 +453,8 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
431453 return err;
432454 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
433455 return err;
456 if ((err = zig_libc_find_native_static_crt_dir_posix(self, verbose)))
457 return err;
434458 return ErrorNone;
435459 } else {
436460 ZigWindowsSDK *sdk;
......@@ -444,7 +468,7 @@ Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
444468 return err;
445469 if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
446470 return err;
447 if ((err = zig_libc_find_crt_dir_windows(self, sdk, &native_target, verbose)))
471 if ((err = zig_libc_find_native_crt_dir_windows(self, sdk, &native_target, verbose)))
448472 return err;
449473 return ErrorNone;
450474 case ZigFindWindowsSdkErrorOutOfMemory:
src/libc_installation.hpp+1-2
......@@ -19,6 +19,7 @@ struct ZigLibCInstallation {
1919 Buf include_dir;
2020 Buf sys_include_dir;
2121 Buf crt_dir;
22 Buf static_crt_dir;
2223 Buf msvc_lib_dir;
2324 Buf kernel32_lib_dir;
2425};
......@@ -29,8 +30,6 @@ void zig_libc_render(ZigLibCInstallation *self, FILE *file);
2930
3031Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
3132
32#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_WINDOWS)
3333Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose);
34#endif
3534
3635#endif
src/link.cpp+191-117
......@@ -25,6 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou
2525 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
2626 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());
2727 child_gen->disable_gen_h = true;
28 child_gen->disable_stack_probing = true;
2829 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
2930 child_gen->verbose_ast = parent_gen->verbose_ast;
3031 child_gen->verbose_link = parent_gen->verbose_link;
......@@ -772,17 +773,15 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
772773 }
773774}
774775
775static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path) {
776static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, OutType child_out_type) {
776777 // The Mach-O LLD code is not well maintained, and trips an assertion
777778 // when we link compiler_rt and builtin as libraries rather than objects.
778779 // Here we workaround this by having compiler_rt and builtin be objects.
779780 // TODO write our own linker. https://github.com/ziglang/zig/issues/1535
780 OutType child_out_type = OutTypeLib;
781781 if (parent_gen->zig_target->os == OsMacOSX) {
782782 child_out_type = OutTypeObj;
783783 }
784784
785
786785 CodeGen *child_gen = create_child_codegen(parent_gen, full_path, child_out_type,
787786 parent_gen->libc);
788787 codegen_set_out_name(child_gen, buf_create_from_str(aname));
......@@ -804,14 +803,14 @@ static Buf *build_a(CodeGen *parent_gen, const char *aname) {
804803 Buf *full_path = buf_alloc();
805804 os_path_join(parent_gen->zig_std_special_dir, source_basename, full_path);
806805
807 return build_a_raw(parent_gen, aname, full_path);
806 return build_a_raw(parent_gen, aname, full_path, OutTypeLib);
808807}
809808
810static Buf *build_compiler_rt(CodeGen *parent_gen) {
809static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type) {
811810 Buf *full_path = buf_alloc();
812811 os_path_join(parent_gen->zig_std_special_dir, buf_create_from_str("compiler_rt.zig"), full_path);
813812
814 return build_a_raw(parent_gen, "compiler_rt", full_path);
813 return build_a_raw(parent_gen, "compiler_rt", full_path, child_out_type);
815814}
816815
817816static const char *get_darwin_arch_string(const ZigTarget *t) {
......@@ -1006,7 +1005,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
10061005 lj->args.append(buf_ptr(builtin_a_path));
10071006 }
10081007
1009 Buf *compiler_rt_o_path = build_compiler_rt(g);
1008 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
10101009 lj->args.append(buf_ptr(compiler_rt_o_path));
10111010 }
10121011
......@@ -1091,16 +1090,35 @@ static void construct_linker_job_wasm(LinkJob *lj) {
10911090 CodeGen *g = lj->codegen;
10921091
10931092 lj->args.append("-error-limit=0");
1094 lj->args.append("--no-entry"); // So lld doesn't look for _start.
1093
1094 if (g->zig_target->os != OsWASI) {
1095 lj->args.append("--no-entry"); // So lld doesn't look for _start.
1096 }
10951097 lj->args.append("--allow-undefined");
1096 lj->args.append("--export-all");
10971098 lj->args.append("-o");
10981099 lj->args.append(buf_ptr(&g->output_file_path));
10991100
1101 auto export_it = g->exported_symbol_names.entry_iterator();
1102 decltype(g->exported_symbol_names)::Entry *curr_entry = nullptr;
1103 while ((curr_entry = export_it.next()) != nullptr) {
1104 Buf *arg = buf_sprintf("--export=%s", buf_ptr(curr_entry->key));
1105 lj->args.append(buf_ptr(arg));
1106 }
1107
11001108 // .o files
11011109 for (size_t i = 0; i < g->link_objects.length; i += 1) {
11021110 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
11031111 }
1112
1113 if (g->out_type == OutTypeExe) {
1114 if (g->libc_link_lib == nullptr) {
1115 Buf *builtin_a_path = build_a(g, "builtin");
1116 lj->args.append(buf_ptr(builtin_a_path));
1117 }
1118
1119 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
1120 lj->args.append(buf_ptr(compiler_rt_o_path));
1121 }
11041122}
11051123
11061124static void coff_append_machine_arg(CodeGen *g, ZigList<const char *> *list) {
......@@ -1124,53 +1142,121 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si
11241142}
11251143
11261144static void add_uefi_link_args(LinkJob *lj) {
1127 lj->args.append("/BASE:0");
1128 lj->args.append("/ENTRY:EfiMain");
1129 lj->args.append("/OPT:REF");
1130 lj->args.append("/SAFESEH:NO");
1131 lj->args.append("/MERGE:.rdata=.data");
1132 lj->args.append("/ALIGN:32");
1133 lj->args.append("/NODEFAULTLIB");
1134 lj->args.append("/SECTION:.xdata,D");
1145 lj->args.append("-BASE:0");
1146 lj->args.append("-ENTRY:EfiMain");
1147 lj->args.append("-OPT:REF");
1148 lj->args.append("-SAFESEH:NO");
1149 lj->args.append("-MERGE:.rdata=.data");
1150 lj->args.append("-ALIGN:32");
1151 lj->args.append("-NODEFAULTLIB");
1152 lj->args.append("-SECTION:.xdata,D");
11351153}
11361154
1137static void add_nt_link_args(LinkJob *lj, bool is_library) {
1155static void add_msvc_link_args(LinkJob *lj, bool is_library) {
11381156 CodeGen *g = lj->codegen;
11391157
1140 if (lj->link_in_crt) {
1141 // TODO: https://github.com/ziglang/zig/issues/2064
1142 bool is_dynamic = true; // g->is_dynamic;
1143 const char *lib_str = is_dynamic ? "" : "lib";
1144 const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
1145
1146 if (!is_dynamic) {
1147 Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);
1148 lj->args.append(buf_ptr(cmt_lib_name));
1149 } else {
1150 Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);
1151 lj->args.append(buf_ptr(msvcrt_lib_name));
1152 }
1158 // TODO: https://github.com/ziglang/zig/issues/2064
1159 bool is_dynamic = true; // g->is_dynamic;
1160 const char *lib_str = is_dynamic ? "" : "lib";
1161 const char *d_str = (g->build_mode == BuildModeDebug) ? "d" : "";
1162
1163 if (!is_dynamic) {
1164 Buf *cmt_lib_name = buf_sprintf("libcmt%s.lib", d_str);
1165 lj->args.append(buf_ptr(cmt_lib_name));
1166 } else {
1167 Buf *msvcrt_lib_name = buf_sprintf("msvcrt%s.lib", d_str);
1168 lj->args.append(buf_ptr(msvcrt_lib_name));
1169 }
1170
1171 Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);
1172 lj->args.append(buf_ptr(vcruntime_lib_name));
11531173
1154 Buf *vcruntime_lib_name = buf_sprintf("%svcruntime%s.lib", lib_str, d_str);
1155 lj->args.append(buf_ptr(vcruntime_lib_name));
1174 Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);
1175 lj->args.append(buf_ptr(crt_lib_name));
11561176
1157 Buf *crt_lib_name = buf_sprintf("%sucrt%s.lib", lib_str, d_str);
1158 lj->args.append(buf_ptr(crt_lib_name));
1177 //Visual C++ 2015 Conformance Changes
1178 //https://msdn.microsoft.com/en-us/library/bb531344.aspx
1179 lj->args.append("legacy_stdio_definitions.lib");
11591180
1160 //Visual C++ 2015 Conformance Changes
1161 //https://msdn.microsoft.com/en-us/library/bb531344.aspx
1162 lj->args.append("legacy_stdio_definitions.lib");
1181 // msvcrt depends on kernel32 and ntdll
1182 lj->args.append("kernel32.lib");
1183 lj->args.append("ntdll.lib");
1184}
1185
1186static const char *get_libc_file(ZigLibCInstallation *lib, const char *file) {
1187 Buf *out_buf = buf_alloc();
1188 os_path_join(&lib->crt_dir, buf_create_from_str(file), out_buf);
1189 return buf_ptr(out_buf);
1190}
1191
1192static const char *get_libc_static_file(ZigLibCInstallation *lib, const char *file) {
1193 Buf *out_buf = buf_alloc();
1194 os_path_join(&lib->static_crt_dir, buf_create_from_str(file), out_buf);
1195 return buf_ptr(out_buf);
1196}
1197
1198static void add_mingw_link_args(LinkJob *lj, bool is_library) {
1199 CodeGen *g = lj->codegen;
11631200
1164 // msvcrt depends on kernel32 and ntdll
1165 lj->args.append("kernel32.lib");
1166 lj->args.append("ntdll.lib");
1201 bool is_dll = g->out_type == OutTypeLib && g->is_dynamic;
1202
1203 if (g->zig_target->arch == ZigLLVM_x86) {
1204 lj->args.append("-ALTERNATENAME:__image_base__=___ImageBase");
1205 } else {
1206 lj->args.append("-ALTERNATENAME:__image_base__=__ImageBase");
1207 }
1208
1209 if (is_dll) {
1210 lj->args.append(get_libc_file(g->libc, "dllcrt2.o"));
1211 } else {
1212 lj->args.append(get_libc_file(g->libc, "crt2.o"));
1213 }
1214
1215 lj->args.append(get_libc_static_file(g->libc, "crtbegin.o"));
1216
1217 lj->args.append(get_libc_file(g->libc, "libmingw32.a"));
1218
1219 if (is_dll) {
1220 lj->args.append(get_libc_static_file(g->libc, "libgcc_s.a"));
1221 lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
1222 } else {
1223 lj->args.append(get_libc_static_file(g->libc, "libgcc.a"));
1224 lj->args.append(get_libc_static_file(g->libc, "libgcc_eh.a"));
1225 }
1226
1227 lj->args.append(get_libc_static_file(g->libc, "libssp.a"));
1228 lj->args.append(get_libc_file(g->libc, "libmoldname.a"));
1229 lj->args.append(get_libc_file(g->libc, "libmingwex.a"));
1230 lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));
1231
1232 if (g->subsystem == TargetSubsystemWindows) {
1233 lj->args.append(get_libc_file(g->libc, "libgdi32.a"));
1234 lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));
1235 }
1236
1237 lj->args.append(get_libc_file(g->libc, "libadvapi32.a"));
1238 lj->args.append(get_libc_file(g->libc, "libadvapi32.a"));
1239 lj->args.append(get_libc_file(g->libc, "libshell32.a"));
1240 lj->args.append(get_libc_file(g->libc, "libuser32.a"));
1241 lj->args.append(get_libc_file(g->libc, "libkernel32.a"));
1242
1243 lj->args.append(get_libc_static_file(g->libc, "crtend.o"));
1244}
1245
1246static void add_win_link_args(LinkJob *lj, bool is_library) {
1247 if (lj->link_in_crt) {
1248 if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
1249 add_mingw_link_args(lj, is_library);
1250 } else {
1251 add_msvc_link_args(lj, is_library);
1252 }
11671253 } else {
1168 lj->args.append("/NODEFAULTLIB");
1254 lj->args.append("-NODEFAULTLIB");
11691255 if (!is_library) {
1170 if (g->have_winmain) {
1171 lj->args.append("/ENTRY:WinMain");
1256 if (lj->codegen->have_winmain) {
1257 lj->args.append("-ENTRY:WinMain");
11721258 } else {
1173 lj->args.append("/ENTRY:WinMainCRTStartup");
1259 lj->args.append("-ENTRY:WinMainCRTStartup");
11741260 }
11751261 }
11761262 }
......@@ -1180,87 +1266,93 @@ static void construct_linker_job_coff(LinkJob *lj) {
11801266 Error err;
11811267 CodeGen *g = lj->codegen;
11821268
1183 lj->args.append("/ERRORLIMIT:0");
1269 lj->args.append("-ERRORLIMIT:0");
11841270
1185 lj->args.append("/NOLOGO");
1271 lj->args.append("-NOLOGO");
11861272
11871273 if (!g->strip_debug_symbols) {
1188 lj->args.append("/DEBUG");
1274 lj->args.append("-DEBUG");
11891275 }
11901276
11911277 if (g->out_type == OutTypeExe) {
11921278 // TODO compile time stack upper bound detection
1193 lj->args.append("/STACK:16777216");
1279 lj->args.append("-STACK:16777216");
11941280 }
11951281
11961282 coff_append_machine_arg(g, &lj->args);
11971283
11981284 bool is_library = g->out_type == OutTypeLib;
1285 if (is_library && g->is_dynamic) {
1286 lj->args.append("-DLL");
1287 }
1288
1289 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
1290
1291 if (g->libc_link_lib != nullptr) {
1292 assert(g->libc != nullptr);
1293
1294 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
1295
1296 if (target_abi_is_gnu(g->zig_target->abi)) {
1297 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));
1298 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));
1299 } else {
1300 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
1301 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
1302 }
1303 }
1304
1305 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1306 const char *lib_dir = g->lib_dirs.at(i);
1307 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
1308 }
1309
1310 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1311 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1312 }
1313
11991314 switch (g->subsystem) {
12001315 case TargetSubsystemAuto:
12011316 if (g->zig_target->os == OsUefi) {
12021317 add_uefi_link_args(lj);
12031318 } else {
1204 add_nt_link_args(lj, is_library);
1319 add_win_link_args(lj, is_library);
12051320 }
12061321 break;
12071322 case TargetSubsystemConsole:
1208 lj->args.append("/SUBSYSTEM:console");
1209 add_nt_link_args(lj, is_library);
1323 lj->args.append("-SUBSYSTEM:console");
1324 add_win_link_args(lj, is_library);
12101325 break;
12111326 case TargetSubsystemEfiApplication:
1212 lj->args.append("/SUBSYSTEM:efi_application");
1327 lj->args.append("-SUBSYSTEM:efi_application");
12131328 add_uefi_link_args(lj);
12141329 break;
12151330 case TargetSubsystemEfiBootServiceDriver:
1216 lj->args.append("/SUBSYSTEM:efi_boot_service_driver");
1331 lj->args.append("-SUBSYSTEM:efi_boot_service_driver");
12171332 add_uefi_link_args(lj);
12181333 break;
12191334 case TargetSubsystemEfiRom:
1220 lj->args.append("/SUBSYSTEM:efi_rom");
1335 lj->args.append("-SUBSYSTEM:efi_rom");
12211336 add_uefi_link_args(lj);
12221337 break;
12231338 case TargetSubsystemEfiRuntimeDriver:
1224 lj->args.append("/SUBSYSTEM:efi_runtime_driver");
1339 lj->args.append("-SUBSYSTEM:efi_runtime_driver");
12251340 add_uefi_link_args(lj);
12261341 break;
12271342 case TargetSubsystemNative:
1228 lj->args.append("/SUBSYSTEM:native");
1229 add_nt_link_args(lj, is_library);
1343 lj->args.append("-SUBSYSTEM:native");
1344 add_win_link_args(lj, is_library);
12301345 break;
12311346 case TargetSubsystemPosix:
1232 lj->args.append("/SUBSYSTEM:posix");
1233 add_nt_link_args(lj, is_library);
1347 lj->args.append("-SUBSYSTEM:posix");
1348 add_win_link_args(lj, is_library);
12341349 break;
12351350 case TargetSubsystemWindows:
1236 lj->args.append("/SUBSYSTEM:windows");
1237 add_nt_link_args(lj, is_library);
1351 lj->args.append("-SUBSYSTEM:windows");
1352 add_win_link_args(lj, is_library);
12381353 break;
12391354 }
12401355
1241 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));
1242
1243 if (g->libc_link_lib != nullptr) {
1244 assert(g->libc != nullptr);
1245
1246 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));
1247 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));
1248 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));
1249 }
1250
1251 if (is_library && g->is_dynamic) {
1252 lj->args.append("-DLL");
1253 }
1254
1255 for (size_t i = 0; i < g->lib_dirs.length; i += 1) {
1256 const char *lib_dir = g->lib_dirs.at(i);
1257 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", lib_dir)));
1258 }
1259
1260 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1261 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1262 }
1263
12641356 if (g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) {
12651357 if (g->libc_link_lib == nullptr && !g->is_dummy_so) {
12661358 Buf *builtin_a_path = build_a(g, "builtin");
......@@ -1268,7 +1360,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
12681360 }
12691361
12701362 // msvc compiler_rt is missing some stuff, so we still build it and rely on weak linkage
1271 Buf *compiler_rt_o_path = build_compiler_rt(g);
1363 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
12721364 lj->args.append(buf_ptr(compiler_rt_o_path));
12731365 }
12741366
......@@ -1280,11 +1372,10 @@ static void construct_linker_job_coff(LinkJob *lj) {
12801372 continue;
12811373 }
12821374 if (link_lib->provided_explicitly) {
1283 if (lj->codegen->zig_target->abi == ZigLLVM_GNU) {
1284 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
1285 lj->args.append(buf_ptr(arg));
1286 }
1287 else {
1375 if (target_abi_is_gnu(lj->codegen->zig_target->abi)) {
1376 Buf *lib_name = buf_sprintf("lib%s.a", buf_ptr(link_lib->name));
1377 lj->args.append(buf_ptr(lib_name));
1378 } else {
12881379 lj->args.append(buf_ptr(link_lib->name));
12891380 }
12901381 } else {
......@@ -1416,18 +1507,6 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
14161507 }
14171508}
14181509
1419static bool darwin_version_lt(DarwinPlatform *platform, int major, int minor) {
1420 if (platform->major < major) {
1421 return true;
1422 } else if (platform->major > major) {
1423 return false;
1424 }
1425 if (platform->minor < minor) {
1426 return true;
1427 }
1428 return false;
1429}
1430
14311510static void construct_linker_job_macho(LinkJob *lj) {
14321511 CodeGen *g = lj->codegen;
14331512
......@@ -1524,7 +1603,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
15241603
15251604 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
15261605 if (g->out_type == OutTypeExe || is_dyn_lib) {
1527 Buf *compiler_rt_o_path = build_compiler_rt(g);
1606 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeLib);
15281607 lj->args.append(buf_ptr(compiler_rt_o_path));
15291608 }
15301609
......@@ -1552,16 +1631,6 @@ static void construct_linker_job_macho(LinkJob *lj) {
15521631 lj->args.append("dynamic_lookup");
15531632 }
15541633
1555 if (platform.kind == MacOS) {
1556 if (darwin_version_lt(&platform, 10, 5)) {
1557 lj->args.append("-lgcc_s.10.4");
1558 } else if (darwin_version_lt(&platform, 10, 6)) {
1559 lj->args.append("-lgcc_s.10.5");
1560 }
1561 } else {
1562 zig_panic("TODO");
1563 }
1564
15651634 for (size_t i = 0; i < g->darwin_frameworks.length; i += 1) {
15661635 lj->args.append("-framework");
15671636 lj->args.append(buf_ptr(g->darwin_frameworks.at(i)));
......@@ -1585,6 +1654,11 @@ static void construct_linker_job(LinkJob *lj) {
15851654 }
15861655}
15871656
1657void zig_link_add_compiler_rt(CodeGen *g) {
1658 Buf *compiler_rt_o_path = build_compiler_rt(g, OutTypeObj);
1659 g->link_objects.append(compiler_rt_o_path);
1660}
1661
15881662void codegen_link(CodeGen *g) {
15891663 codegen_add_time_event(g, "Build Dependencies");
15901664
......@@ -1611,14 +1685,14 @@ void codegen_link(CodeGen *g) {
16111685 if (g->out_type == OutTypeLib && !g->is_dynamic) {
16121686 ZigList<const char *> file_names = {};
16131687 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1614 file_names.append((const char *)buf_ptr(g->link_objects.at(i)));
1688 file_names.append(buf_ptr(g->link_objects.at(i)));
16151689 }
16161690 ZigLLVM_OSType os_type = get_llvm_os_type(g->zig_target->os);
16171691 codegen_add_time_event(g, "LLVM Link");
16181692 if (g->verbose_link) {
16191693 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));
1620 for (size_t i = 0; i < g->link_objects.length; i += 1) {
1621 fprintf(stderr, " %s", (const char *)buf_ptr(g->link_objects.at(i)));
1694 for (size_t i = 0; i < file_names.length; i += 1) {
1695 fprintf(stderr, " %s", file_names.at(i));
16221696 }
16231697 fprintf(stderr, "\n");
16241698 }
src/list.hpp-2
......@@ -10,8 +10,6 @@
1010
1111#include "util.hpp"
1212
13#include <assert.h>
14
1513template<typename T>
1614struct ZigList {
1715 void deinit() {
src/main.cpp+87-82
......@@ -14,6 +14,7 @@
1414#include "os.hpp"
1515#include "target.hpp"
1616#include "libc_installation.hpp"
17#include "userland.h"
1718
1819#include <stdio.h>
1920
......@@ -40,6 +41,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
4041 " libc [paths_file] Display native libc paths file or validate one\n"
4142 " run [source] [-- [args]] create executable and run immediately\n"
4243 " translate-c [source] convert c code to zig code\n"
44 " translate-c-2 [source] experimental self-hosted translate-c\n"
4345 " targets list available compilation targets\n"
4446 " test [source] create and run a test build\n"
4547 " version print version number and exit\n"
......@@ -52,11 +54,12 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
5254 " --cache [auto|off|on] build in cache, print output path to stdout\n"
5355 " --color [auto|off|on] enable or disable colored error messages\n"
5456 " --disable-gen-h do not generate a C header file (.h)\n"
55 " --disable-pic disable Position Independent Code\n"
56 " --enable-pic enable Position Independent Code\n"
5757 " --disable-valgrind omit valgrind client requests in debug builds\n"
5858 " --enable-valgrind include valgrind client requests release builds\n"
59 " --disable-stack-probing workaround for macosx\n"
5960 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
61 " -fPIC enable Position Independent Code\n"
62 " -fno-PIC disable Position Independent Code\n"
6063 " -ftime-report print timing diagnostics\n"
6164 " --libc [file] Provide a file which specifies libc paths\n"
6265 " --name [name] override output name\n"
......@@ -84,6 +87,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
8487 " --override-std-dir [arg] use an alternate Zig standard library\n"
8588 "\n"
8689 "Link Options:\n"
90 " --bundle-compiler-rt [path] for static libraries, include compiler-rt symbols\n"
8791 " --dynamic-linker [path] set the path to ld.so\n"
8892 " --each-lib-rpath add rpath for each used dynamic library\n"
8993 " --library [lib] link against lib\n"
......@@ -131,19 +135,6 @@ static int print_libc_usage(const char *arg0, FILE *file, int return_code) {
131135 return return_code;
132136}
133137
134static const char *ZIG_ZEN = "\n"
135" * Communicate intent precisely.\n"
136" * Edge cases matter.\n"
137" * Favor reading code over writing code.\n"
138" * Only one obvious way to do things.\n"
139" * Runtime crashes are better than bugs.\n"
140" * Compile errors are better than runtime crashes.\n"
141" * Incremental improvements.\n"
142" * Avoid local maximums.\n"
143" * Reduce the amount one must remember.\n"
144" * Minimize energy spent on coding style.\n"
145" * Together we serve end users.\n";
146
147138static bool arch_available_in_llvm(ZigLLVM_ArchType arch) {
148139 LLVMTargetRef target_ref;
149140 char *err_msg = nullptr;
......@@ -211,6 +202,7 @@ enum Cmd {
211202 CmdTargets,
212203 CmdTest,
213204 CmdTranslateC,
205 CmdTranslateCUserland,
214206 CmdVersion,
215207 CmdZen,
216208 CmdLibC,
......@@ -324,7 +316,7 @@ int main(int argc, char **argv) {
324316 return print_error_usage(arg0);
325317 }
326318 Buf *cmd_template_path = buf_alloc();
327 os_path_join(get_zig_special_dir(), buf_create_from_str(init_cmd), cmd_template_path);
319 os_path_join(get_zig_special_dir(get_zig_lib_dir()), buf_create_from_str(init_cmd), cmd_template_path);
328320 Buf *build_zig_path = buf_alloc();
329321 os_path_join(cmd_template_path, buf_create_from_str("build.zig"), build_zig_path);
330322 Buf *src_dir_path = buf_alloc();
......@@ -341,7 +333,7 @@ int main(int argc, char **argv) {
341333 os_path_split(cwd, nullptr, cwd_basename);
342334
343335 Buf *build_zig_contents = buf_alloc();
344 if ((err = os_fetch_file_path(build_zig_path, build_zig_contents, false))) {
336 if ((err = os_fetch_file_path(build_zig_path, build_zig_contents))) {
345337 fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(build_zig_path), err_str(err));
346338 return EXIT_FAILURE;
347339 }
......@@ -356,7 +348,7 @@ int main(int argc, char **argv) {
356348 }
357349
358350 Buf *main_zig_contents = buf_alloc();
359 if ((err = os_fetch_file_path(main_zig_path, main_zig_contents, false))) {
351 if ((err = os_fetch_file_path(main_zig_path, main_zig_contents))) {
360352 fprintf(stderr, "Unable to read %s: %s\n", buf_ptr(main_zig_path), err_str(err));
361353 return EXIT_FAILURE;
362354 }
......@@ -450,9 +442,12 @@ int main(int argc, char **argv) {
450442 int runtime_args_start = -1;
451443 bool system_linker_hack = false;
452444 TargetSubsystem subsystem = TargetSubsystemAuto;
453 bool is_single_threaded = false;
445 bool want_single_threaded = false;
454446 bool disable_gen_h = false;
447 bool bundle_compiler_rt = false;
448 bool disable_stack_probing = false;
455449 Buf *override_std_dir = nullptr;
450 Buf *override_lib_dir = nullptr;
456451 Buf *main_pkg_path = nullptr;
457452 ValgrindSupport valgrind_support = ValgrindSupportAuto;
458453 WantPIC want_pic = WantPICAuto;
......@@ -486,13 +481,27 @@ int main(int argc, char **argv) {
486481 } else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) {
487482 cache_dir = argv[i + 1];
488483 i += 1;
484 } else if (i + 1 < argc && strcmp(argv[i], "--override-std-dir") == 0) {
485 override_std_dir = buf_create_from_str(argv[i + 1]);
486 i += 1;
487
488 args.append("--override-std-dir");
489 args.append(buf_ptr(override_std_dir));
490 } else if (i + 1 < argc && strcmp(argv[i], "--override-lib-dir") == 0) {
491 override_lib_dir = buf_create_from_str(argv[i + 1]);
492 i += 1;
493
494 args.append("--override-lib-dir");
495 args.append(buf_ptr(override_lib_dir));
489496 } else {
490497 args.append(argv[i]);
491498 }
492499 }
493500
501 Buf *zig_lib_dir = (override_lib_dir == nullptr) ? get_zig_lib_dir() : override_lib_dir;
502
494503 Buf *build_runner_path = buf_alloc();
495 os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
504 os_path_join(get_zig_special_dir(zig_lib_dir), buf_create_from_str("build_runner.zig"), build_runner_path);
496505
497506 ZigTarget target;
498507 get_native_target(&target);
......@@ -512,7 +521,7 @@ int main(int argc, char **argv) {
512521 }
513522
514523 CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,
515 BuildModeDebug, get_zig_lib_dir(), override_std_dir, nullptr, &full_cache_dir);
524 BuildModeDebug, override_lib_dir, override_std_dir, nullptr, &full_cache_dir);
516525 g->valgrind_support = valgrind_support;
517526 g->enable_time_report = timing_info;
518527 codegen_set_out_name(g, buf_create_from_str("build"));
......@@ -532,23 +541,25 @@ int main(int argc, char **argv) {
532541 "Usage: %s build [options]\n"
533542 "\n"
534543 "General Options:\n"
535 " --help Print this help and exit\n"
536 " --verbose Print commands before executing them\n"
537 " --prefix [path] Override default install prefix\n"
538 " --search-prefix [path] Add a path to look for binaries, libraries, headers\n"
544 " --help Print this help and exit\n"
545 " --verbose Print commands before executing them\n"
546 " --prefix [path] Override default install prefix\n"
547 " --search-prefix [path] Add a path to look for binaries, libraries, headers\n"
539548 "\n"
540549 "Project-specific options become available when the build file is found.\n"
541550 "\n"
542551 "Advanced Options:\n"
543 " --build-file [file] Override path to build.zig\n"
544 " --cache-dir [path] Override path to cache directory\n"
545 " --verbose-tokenize Enable compiler debug output for tokenization\n"
546 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
547 " --verbose-link Enable compiler debug output for linking\n"
548 " --verbose-ir Enable compiler debug output for Zig IR\n"
549 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
550 " --verbose-cimport Enable compiler debug output for C imports\n"
551 " --verbose-cc Enable compiler debug output for C compilation\n"
552 " --build-file [file] Override path to build.zig\n"
553 " --cache-dir [path] Override path to cache directory\n"
554 " --override-std-dir [arg] Override path to Zig standard library\n"
555 " --override-lib-dir [arg] Override path to Zig lib library\n"
556 " --verbose-tokenize Enable compiler debug output for tokenization\n"
557 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
558 " --verbose-link Enable compiler debug output for linking\n"
559 " --verbose-ir Enable compiler debug output for Zig IR\n"
560 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
561 " --verbose-cimport Enable compiler debug output for C imports\n"
562 " --verbose-cc Enable compiler debug output for C compilation\n"
552563 "\n"
553564 , zig_exe_path);
554565 return EXIT_SUCCESS;
......@@ -581,36 +592,7 @@ int main(int argc, char **argv) {
581592 }
582593 return (term.how == TerminationIdClean) ? term.code : -1;
583594 } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
584 init_all_targets();
585 ZigTarget target;
586 get_native_target(&target);
587 Buf *fmt_runner_path = buf_alloc();
588 os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
589 Buf *cache_dir_buf = buf_create_from_str(cache_dir ? cache_dir : default_zig_cache_name);
590 CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe,
591 BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr, cache_dir_buf);
592 g->valgrind_support = valgrind_support;
593 g->is_single_threaded = true;
594 codegen_set_out_name(g, buf_create_from_str("fmt"));
595 g->enable_cache = true;
596
597 codegen_build_and_link(g);
598
599 // TODO standardize os.cpp so that the args are supposed to have the exe
600 ZigList<const char*> args_with_exe = {0};
601 ZigList<const char*> args_without_exe = {0};
602 const char *exec_path = buf_ptr(&g->output_file_path);
603 args_with_exe.append(exec_path);
604 for (int i = 2; i < argc; i += 1) {
605 args_with_exe.append(argv[i]);
606 args_without_exe.append(argv[i]);
607 }
608 args_with_exe.append(nullptr);
609 os_execv(exec_path, args_with_exe.items);
610
611 Termination term;
612 os_spawn_process(exec_path, args_without_exe, &term);
613 return term.code;
595 return stage2_fmt(argc, argv);
614596 }
615597
616598 for (int i = 1; i < argc; i += 1) {
......@@ -664,16 +646,20 @@ int main(int argc, char **argv) {
664646 valgrind_support = ValgrindSupportEnabled;
665647 } else if (strcmp(arg, "--disable-valgrind") == 0) {
666648 valgrind_support = ValgrindSupportDisabled;
667 } else if (strcmp(arg, "--enable-pic") == 0) {
649 } else if (strcmp(arg, "-fPIC") == 0) {
668650 want_pic = WantPICEnabled;
669 } else if (strcmp(arg, "--disable-pic") == 0) {
651 } else if (strcmp(arg, "-fno-PIC") == 0) {
670652 want_pic = WantPICDisabled;
671653 } else if (strcmp(arg, "--system-linker-hack") == 0) {
672654 system_linker_hack = true;
673655 } else if (strcmp(arg, "--single-threaded") == 0) {
674 is_single_threaded = true;
656 want_single_threaded = true;
675657 } else if (strcmp(arg, "--disable-gen-h") == 0) {
676658 disable_gen_h = true;
659 } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
660 bundle_compiler_rt = true;
661 } else if (strcmp(arg, "--disable-stack-probing") == 0) {
662 disable_stack_probing = true;
677663 } else if (strcmp(arg, "--test-cmd-bin") == 0) {
678664 test_exec_args.append(nullptr);
679665 } else if (arg[1] == 'L' && arg[2] != 0) {
......@@ -757,6 +743,8 @@ int main(int argc, char **argv) {
757743 llvm_argv.append(argv[i]);
758744 } else if (strcmp(arg, "--override-std-dir") == 0) {
759745 override_std_dir = buf_create_from_str(argv[i]);
746 } else if (strcmp(arg, "--override-lib-dir") == 0) {
747 override_lib_dir = buf_create_from_str(argv[i]);
760748 } else if (strcmp(arg, "--main-pkg-path") == 0) {
761749 main_pkg_path = buf_create_from_str(argv[i]);
762750 } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
......@@ -775,7 +763,11 @@ int main(int argc, char **argv) {
775763 if (argv[i][0] == '-') {
776764 c_file->args.append(argv[i]);
777765 i += 1;
778 continue;
766 if (i < argc) {
767 continue;
768 }
769
770 break;
779771 } else {
780772 c_file->source_path = argv[i];
781773 c_source_files.append(c_file);
......@@ -867,6 +859,8 @@ int main(int argc, char **argv) {
867859 cmd = CmdLibC;
868860 } else if (strcmp(arg, "translate-c") == 0) {
869861 cmd = CmdTranslateC;
862 } else if (strcmp(arg, "translate-c-2") == 0) {
863 cmd = CmdTranslateCUserland;
870864 } else if (strcmp(arg, "test") == 0) {
871865 cmd = CmdTest;
872866 out_type = OutTypeExe;
......@@ -883,6 +877,7 @@ int main(int argc, char **argv) {
883877 case CmdBuild:
884878 case CmdRun:
885879 case CmdTranslateC:
880 case CmdTranslateCUserland:
886881 case CmdTest:
887882 case CmdLibC:
888883 if (!in_file) {
......@@ -959,10 +954,10 @@ int main(int argc, char **argv) {
959954 }
960955 case CmdBuiltin: {
961956 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
962 out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr, nullptr);
957 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
963958 g->valgrind_support = valgrind_support;
964959 g->want_pic = want_pic;
965 g->is_single_threaded = is_single_threaded;
960 g->want_single_threaded = want_single_threaded;
966961 Buf *builtin_source = codegen_generate_builtin_source(g);
967962 if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
968963 fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));
......@@ -973,6 +968,7 @@ int main(int argc, char **argv) {
973968 case CmdRun:
974969 case CmdBuild:
975970 case CmdTranslateC:
971 case CmdTranslateCUserland:
976972 case CmdTest:
977973 {
978974 if (cmd == CmdBuild && !in_file && objects.length == 0 && asm_files.length == 0 &&
......@@ -985,14 +981,16 @@ int main(int argc, char **argv) {
985981 " * --assembly argument\n"
986982 " * --c-source argument\n");
987983 return print_error_usage(arg0);
988 } else if ((cmd == CmdTranslateC || cmd == CmdTest || cmd == CmdRun) && !in_file) {
984 } else if ((cmd == CmdTranslateC || cmd == CmdTranslateCUserland ||
985 cmd == CmdTest || cmd == CmdRun) && !in_file)
986 {
989987 fprintf(stderr, "Expected source file argument.\n");
990988 return print_error_usage(arg0);
991989 }
992990
993991 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
994992
995 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
993 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC || cmd == CmdTranslateCUserland);
996994
997995 if (cmd == CmdRun) {
998996 out_name = "run";
......@@ -1026,7 +1024,8 @@ int main(int argc, char **argv) {
10261024 return print_error_usage(arg0);
10271025 }
10281026
1029 Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;
1027 Buf *zig_root_source_file = (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) ?
1028 nullptr : in_file_buf;
10301029
10311030 if (cmd == CmdRun && buf_out_name == nullptr) {
10321031 buf_out_name = buf_create_from_str("run");
......@@ -1050,7 +1049,7 @@ int main(int argc, char **argv) {
10501049 cache_dir_buf = buf_create_from_str(cache_dir);
10511050 }
10521051 CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
1053 get_zig_lib_dir(), override_std_dir, libc, cache_dir_buf);
1052 override_lib_dir, override_std_dir, libc, cache_dir_buf);
10541053 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
10551054 g->valgrind_support = valgrind_support;
10561055 g->want_pic = want_pic;
......@@ -1060,7 +1059,7 @@ int main(int argc, char **argv) {
10601059 codegen_set_out_name(g, buf_out_name);
10611060 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
10621061 codegen_set_is_test(g, cmd == CmdTest);
1063 g->is_single_threaded = is_single_threaded;
1062 g->want_single_threaded = want_single_threaded;
10641063 codegen_set_linker_script(g, linker_script);
10651064 if (each_lib_rpath)
10661065 codegen_set_each_lib_rpath(g, each_lib_rpath);
......@@ -1079,6 +1078,8 @@ int main(int argc, char **argv) {
10791078 g->verbose_cc = verbose_cc;
10801079 g->output_dir = output_dir;
10811080 g->disable_gen_h = disable_gen_h;
1081 g->bundle_compiler_rt = bundle_compiler_rt;
1082 g->disable_stack_probing = disable_stack_probing;
10821083 codegen_set_errmsg_color(g, color);
10831084 g->system_linker_hack = system_linker_hack;
10841085
......@@ -1144,14 +1145,15 @@ int main(int argc, char **argv) {
11441145 codegen_print_timing_report(g, stdout);
11451146
11461147 if (cmd == CmdRun) {
1148 const char *exec_path = buf_ptr(&g->output_file_path);
11471149 ZigList<const char*> args = {0};
1150
1151 args.append(exec_path);
11481152 if (runtime_args_start != -1) {
11491153 for (int i = runtime_args_start; i < argc; ++i) {
11501154 args.append(argv[i]);
11511155 }
11521156 }
1153
1154 const char *exec_path = buf_ptr(&g->output_file_path);
11551157 args.append(nullptr);
11561158
11571159 os_execv(exec_path, args.items);
......@@ -1169,9 +1171,8 @@ int main(int argc, char **argv) {
11691171 } else {
11701172 zig_unreachable();
11711173 }
1172 } else if (cmd == CmdTranslateC) {
1173 AstNode *root_node = codegen_translate_c(g, in_file_buf);
1174 ast_render(g, stdout, root_node, 4);
1174 } else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
1175 codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
11751176 if (timing_info)
11761177 codegen_print_timing_report(g, stderr);
11771178 return EXIT_SUCCESS;
......@@ -1228,9 +1229,13 @@ int main(int argc, char **argv) {
12281229 case CmdVersion:
12291230 printf("%s\n", ZIG_VERSION_STRING);
12301231 return EXIT_SUCCESS;
1231 case CmdZen:
1232 printf("%s\n", ZIG_ZEN);
1232 case CmdZen: {
1233 const char *ptr;
1234 size_t len;
1235 stage2_zen(&ptr, &len);
1236 fwrite(ptr, len, 1, stdout);
12331237 return EXIT_SUCCESS;
1238 }
12341239 case CmdTargets:
12351240 return print_target_list(stdout);
12361241 case CmdNone:
src/os.cpp+18-35
......@@ -751,39 +751,15 @@ Buf os_path_resolve(Buf **paths_ptr, size_t paths_len) {
751751#endif
752752}
753753
754Error os_fetch_file(FILE *f, Buf *out_buf, bool skip_shebang) {
754Error os_fetch_file(FILE *f, Buf *out_buf) {
755755 static const ssize_t buf_size = 0x2000;
756756 buf_resize(out_buf, buf_size);
757757 ssize_t actual_buf_len = 0;
758758
759 bool first_read = true;
760
761759 for (;;) {
762760 size_t amt_read = fread(buf_ptr(out_buf) + actual_buf_len, 1, buf_size, f);
763761 actual_buf_len += amt_read;
764762
765 if (skip_shebang && first_read && buf_starts_with_str(out_buf, "#!")) {
766 size_t i = 0;
767 while (true) {
768 if (i > buf_len(out_buf)) {
769 zig_panic("shebang line exceeded %zd characters", buf_size);
770 }
771
772 size_t current_pos = i;
773 i += 1;
774
775 if (out_buf->list.at(current_pos) == '\n') {
776 break;
777 }
778 }
779
780 ZigList<char> *list = &out_buf->list;
781 memmove(list->items, list->items + i, list->length - i);
782 list->length -= i;
783
784 actual_buf_len -= i;
785 }
786
787763 if (amt_read != buf_size) {
788764 if (feof(f)) {
789765 buf_resize(out_buf, actual_buf_len);
......@@ -794,7 +770,6 @@ Error os_fetch_file(FILE *f, Buf *out_buf, bool skip_shebang) {
794770 }
795771
796772 buf_resize(out_buf, actual_buf_len + buf_size);
797 first_read = false;
798773 }
799774 zig_unreachable();
800775}
......@@ -864,8 +839,8 @@ static Error os_exec_process_posix(const char *exe, ZigList<const char *> &args,
864839
865840 FILE *stdout_f = fdopen(stdout_pipe[0], "rb");
866841 FILE *stderr_f = fdopen(stderr_pipe[0], "rb");
867 Error err1 = os_fetch_file(stdout_f, out_stdout, false);
868 Error err2 = os_fetch_file(stderr_f, out_stderr, false);
842 Error err1 = os_fetch_file(stdout_f, out_stdout);
843 Error err2 = os_fetch_file(stderr_f, out_stderr);
869844
870845 fclose(stdout_f);
871846 fclose(stderr_f);
......@@ -1097,7 +1072,7 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
10971072 }
10981073}
10991074
1100Error os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang) {
1075Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
11011076 FILE *f = fopen(buf_ptr(full_path), "rb");
11021077 if (!f) {
11031078 switch (errno) {
......@@ -1116,7 +1091,7 @@ Error os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang) {
11161091 return ErrorFileSystem;
11171092 }
11181093 }
1119 Error result = os_fetch_file(f, out_contents, skip_shebang);
1094 Error result = os_fetch_file(f, out_contents);
11201095 fclose(f);
11211096 return result;
11221097}
......@@ -1772,8 +1747,14 @@ Error os_get_app_data_dir(Buf *out_path, const char *appname) {
17721747 // TODO use /etc/passwd
17731748 return ErrorFileNotFound;
17741749 }
1775 buf_resize(out_path, 0);
1776 buf_appendf(out_path, "%s/.local/share/%s", home_dir, appname);
1750 if (home_dir[0] == 0) {
1751 return ErrorFileNotFound;
1752 }
1753 buf_init_from_str(out_path, home_dir);
1754 if (buf_ptr(out_path)[buf_len(out_path) - 1] != '/') {
1755 buf_append_char(out_path, '/');
1756 }
1757 buf_appendf(out_path, ".local/share/%s", appname);
17771758 return ErrorNone;
17781759#endif
17791760}
......@@ -2081,11 +2062,13 @@ Error os_file_overwrite(OsFile file, Buf *contents) {
20812062#endif
20822063}
20832064
2084void os_file_close(OsFile file) {
2065void os_file_close(OsFile *file) {
20852066#if defined(ZIG_OS_WINDOWS)
2086 CloseHandle(file);
2067 CloseHandle(*file);
2068 *file = NULL;
20872069#else
2088 close(file);
2070 close(*file);
2071 *file = -1;
20892072#endif
20902073}
20912074
src/os.hpp+3-3
......@@ -121,13 +121,13 @@ Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
121121Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
122122Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
123123Error ATTRIBUTE_MUST_USE os_file_overwrite(OsFile file, Buf *contents);
124void os_file_close(OsFile file);
124void os_file_close(OsFile *file);
125125
126126Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
127127Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
128128
129Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents, bool skip_shebang);
130Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents, bool skip_shebang);
129Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
130Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);
131131
132132Error ATTRIBUTE_MUST_USE os_get_cwd(Buf *out_cwd);
133133
src/parser.cpp+57-57
......@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
577577
578578// TopLevelDecl
579579// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
580// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
580// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
581581// / KEYWORD_use Expr SEMICOLON
582582static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
583583 Token *first = eat_token_if(pc, TokenIdKeywordExport);
......@@ -591,17 +591,22 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
591591 lib_name = eat_token_if(pc, TokenIdStringLiteral);
592592
593593 if (first->id != TokenIdKeywordInline) {
594 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
594595 AstNode *var_decl = ast_parse_var_decl(pc);
595596 if (var_decl != nullptr) {
596597 assert(var_decl->type == NodeTypeVariableDeclaration);
597598 var_decl->line = first->start_line;
598599 var_decl->column = first->start_column;
600 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
599601 var_decl->data.variable_declaration.visib_mod = visib_mod;
600602 var_decl->data.variable_declaration.is_extern = first->id == TokenIdKeywordExtern;
601603 var_decl->data.variable_declaration.is_export = first->id == TokenIdKeywordExport;
602604 var_decl->data.variable_declaration.lib_name = token_buf(lib_name);
603605 return var_decl;
604606 }
607
608 if (thread_local_kw != nullptr)
609 put_back_token(pc);
605610 }
606611
607612 AstNode *fn_proto = ast_parse_fn_proto(pc);
......@@ -632,13 +637,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
632637 ast_invalid_token_error(pc, peek_token(pc));
633638 }
634639
640 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
635641 AstNode *var_decl = ast_parse_var_decl(pc);
636642 if (var_decl != nullptr) {
637643 assert(var_decl->type == NodeTypeVariableDeclaration);
638644 var_decl->data.variable_declaration.visib_mod = visib_mod;
645 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
639646 return var_decl;
640647 }
641648
649 if (thread_local_kw != nullptr)
650 put_back_token(pc);
651
642652 AstNode *fn_proto = ast_parse_fn_proto(pc);
643653 if (fn_proto != nullptr) {
644654 AstNode *body = ast_parse_block(pc);
......@@ -741,17 +751,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
741751
742752// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
743753static AstNode *ast_parse_var_decl(ParseContext *pc) {
744 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
745754 Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
746755 if (mut_kw == nullptr)
747756 mut_kw = eat_token_if(pc, TokenIdKeywordVar);
748 if (mut_kw == nullptr) {
749 if (thread_local_kw == nullptr) {
750 return nullptr;
751 } else {
752 ast_invalid_token_error(pc, peek_token(pc));
753 }
754 }
757 if (mut_kw == nullptr)
758 return nullptr;
759
755760 Token *identifier = expect_token(pc, TokenIdSymbol);
756761 AstNode *type_expr = nullptr;
757762 if (eat_token_if(pc, TokenIdColon) != nullptr)
......@@ -766,7 +771,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
766771 expect_token(pc, TokenIdSemicolon);
767772
768773 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
769 res->data.variable_declaration.threadlocal_tok = thread_local_kw;
770774 res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
771775 res->data.variable_declaration.symbol = token_buf(identifier);
772776 res->data.variable_declaration.type = type_expr;
......@@ -952,17 +956,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
952956
953957// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
954958static AstNode *ast_parse_loop_statement(ParseContext *pc) {
955 Token *label = ast_parse_block_label(pc);
956 Token *first = label;
957
958959 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
959 if (first == nullptr)
960 first = inline_token;
961
962960 AstNode *for_statement = ast_parse_for_statement(pc);
963961 if (for_statement != nullptr) {
964962 assert(for_statement->type == NodeTypeForExpr);
965 for_statement->data.for_expr.name = token_buf(label);
966963 for_statement->data.for_expr.is_inline = inline_token != nullptr;
967964 return for_statement;
968965 }
......@@ -970,12 +967,11 @@ static AstNode *ast_parse_loop_statement(ParseContext *pc) {
970967 AstNode *while_statement = ast_parse_while_statement(pc);
971968 if (while_statement != nullptr) {
972969 assert(while_statement->type == NodeTypeWhileExpr);
973 while_statement->data.while_expr.name = token_buf(label);
974970 while_statement->data.while_expr.is_inline = inline_token != nullptr;
975971 return while_statement;
976972 }
977973
978 if (first != nullptr)
974 if (inline_token != nullptr)
979975 ast_invalid_token_error(pc, peek_token(pc));
980976 return nullptr;
981977}
......@@ -1117,7 +1113,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {
11171113
11181114// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
11191115static AstNode *ast_parse_compare_expr(ParseContext *pc) {
1120 return ast_parse_bin_op_expr(pc, BinOpChainInf, ast_parse_compare_op, ast_parse_bitwise_expr);
1116 return ast_parse_bin_op_expr(pc, BinOpChainOnce, ast_parse_compare_op, ast_parse_bitwise_expr);
11211117}
11221118
11231119// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
......@@ -1162,10 +1158,6 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
11621158// / Block
11631159// / CurlySuffixExpr
11641160static AstNode *ast_parse_primary_expr(ParseContext *pc) {
1165 AstNode *enum_lit = ast_parse_enum_lit(pc);
1166 if (enum_lit != nullptr)
1167 return enum_lit;
1168
11691161 AstNode *asm_expr = ast_parse_asm_expr(pc);
11701162 if (asm_expr != nullptr)
11711163 return asm_expr;
......@@ -1246,11 +1238,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
12461238 }
12471239
12481240 AstNode *block = ast_parse_block(pc);
1249 if (block != nullptr) {
1250 assert(block->type == NodeTypeBlock);
1251 block->data.block.name = token_buf(label);
1241 if (block != nullptr)
12521242 return block;
1253 }
12541243
12551244 AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);
12561245 if (curly_suffix != nullptr)
......@@ -1503,6 +1492,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
15031492// <- BUILTINIDENTIFIER FnCallArguments
15041493// / CHAR_LITERAL
15051494// / ContainerDecl
1495// / DOT IDENTIFIER
15061496// / ErrorSetDecl
15071497// / FLOAT
15081498// / FnProto
......@@ -1563,6 +1553,10 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
15631553 if (container_decl != nullptr)
15641554 return container_decl;
15651555
1556 AstNode *enum_lit = ast_parse_enum_lit(pc);
1557 if (enum_lit != nullptr)
1558 return enum_lit;
1559
15661560 AstNode *error_set_decl = ast_parse_error_set_decl(pc);
15671561 if (error_set_decl != nullptr)
15681562 return error_set_decl;
......@@ -1672,32 +1666,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
16721666
16731667// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
16741668static AstNode *ast_parse_container_decl(ParseContext *pc) {
1675 Token *extern_token = eat_token_if(pc, TokenIdKeywordExtern);
1676 if (extern_token != nullptr) {
1677 AstNode *res = ast_parse_container_decl_auto(pc);
1678 if (res == nullptr) {
1679 put_back_token(pc);
1680 return nullptr;
1681 }
1669 Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1670 if (layout_token == nullptr)
1671 layout_token = eat_token_if(pc, TokenIdKeywordPacked);
16821672
1683 assert(res->type == NodeTypeContainerDecl);
1684 res->line = extern_token->start_line;
1685 res->column = extern_token->start_column;
1686 res->data.container_decl.layout = ContainerLayoutExtern;
1687 return res;
1673 AstNode *res = ast_parse_container_decl_auto(pc);
1674 if (res == nullptr) {
1675 if (layout_token != nullptr)
1676 put_back_token(pc);
1677 return nullptr;
16881678 }
16891679
1690 Token *packed_token = eat_token_if(pc, TokenIdKeywordPacked);
1691 if (packed_token != nullptr) {
1692 AstNode *res = ast_expect(pc, ast_parse_container_decl_auto);
1693 assert(res->type == NodeTypeContainerDecl);
1694 res->line = packed_token->start_line;
1695 res->column = packed_token->start_column;
1696 res->data.container_decl.layout = ContainerLayoutPacked;
1697 return res;
1680 assert(res->type == NodeTypeContainerDecl);
1681 if (layout_token != nullptr) {
1682 res->line = layout_token->start_line;
1683 res->column = layout_token->start_column;
1684 res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
1685 ? ContainerLayoutExtern
1686 : ContainerLayoutPacked;
16981687 }
1699
1700 return ast_parse_container_decl_auto(pc);
1688 return res;
17011689}
17021690
17031691// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
......@@ -1971,7 +1959,14 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
19711959 return nullptr;
19721960
19731961 Token *name = expect_token(pc, TokenIdSymbol);
1974 expect_token(pc, TokenIdEq);
1962 if (eat_token_if(pc, TokenIdEq) == nullptr) {
1963 // Because ".Name" can also be intepreted as an enum literal, we should put back
1964 // those two tokens again so that the parser can try to parse them as the enum
1965 // literal later.
1966 put_back_token(pc);
1967 put_back_token(pc);
1968 return nullptr;
1969 }
19751970 AstNode *expr = ast_expect(pc, ast_parse_expr);
19761971
19771972 AstNode *res = ast_create_node(pc, NodeTypeStructValueField, first);
......@@ -2750,12 +2745,19 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
27502745}
27512746
27522747// ContainerDeclType
2753// <- (KEYWORD_struct / KEYWORD_enum) (LPAREN Expr RPAREN)?
2748// <- KEYWORD_struct
2749// / KEYWORD_enum (LPAREN Expr RPAREN)?
27542750// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
27552751static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
27562752 Token *first = eat_token_if(pc, TokenIdKeywordStruct);
2757 if (first == nullptr)
2758 first = eat_token_if(pc, TokenIdKeywordEnum);
2753 if (first != nullptr) {
2754 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
2755 res->data.container_decl.init_arg_expr = nullptr;
2756 res->data.container_decl.kind = ContainerKindStruct;
2757 return res;
2758 }
2759
2760 first = eat_token_if(pc, TokenIdKeywordEnum);
27592761 if (first != nullptr) {
27602762 AstNode *init_arg_expr = nullptr;
27612763 if (eat_token_if(pc, TokenIdLParen) != nullptr) {
......@@ -2764,9 +2766,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
27642766 }
27652767 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
27662768 res->data.container_decl.init_arg_expr = init_arg_expr;
2767 res->data.container_decl.kind = first->id == TokenIdKeywordStruct
2768 ? ContainerKindStruct
2769 : ContainerKindEnum;
2769 res->data.container_decl.kind = ContainerKindEnum;
27702770 return res;
27712771 }
27722772
src/target.cpp+26-1
......@@ -894,10 +894,25 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
894894 case CIntTypeCount:
895895 zig_unreachable();
896896 }
897 case OsIOS:
898 switch (id) {
899 case CIntTypeShort:
900 case CIntTypeUShort:
901 return 16;
902 case CIntTypeInt:
903 case CIntTypeUInt:
904 return 32;
905 case CIntTypeLong:
906 case CIntTypeULong:
907 case CIntTypeLongLong:
908 case CIntTypeULongLong:
909 return 64;
910 case CIntTypeCount:
911 zig_unreachable();
912 }
897913 case OsAnanas:
898914 case OsCloudABI:
899915 case OsDragonFly:
900 case OsIOS:
901916 case OsKFreeBSD:
902917 case OsLv2:
903918 case OsSolaris:
......@@ -950,6 +965,8 @@ const char *target_exe_file_ext(const ZigTarget *target) {
950965 return ".exe";
951966 } else if (target->os == OsUefi) {
952967 return ".efi";
968 } else if (target_is_wasm(target)) {
969 return ".wasm";
953970 } else {
954971 return "";
955972 }
......@@ -1350,6 +1367,14 @@ bool target_is_musl(const ZigTarget *target) {
13501367 return target->os == OsLinux && target_abi_is_musl(target->abi);
13511368}
13521369
1370bool target_is_wasm(const ZigTarget *target) {
1371 return target->arch == ZigLLVM_wasm32 || target->arch == ZigLLVM_wasm64;
1372}
1373
1374bool target_is_single_threaded(const ZigTarget *target) {
1375 return target_is_wasm(target);
1376}
1377
13531378ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
13541379 switch (os) {
13551380 case OsFreestanding:
src/target.hpp+2
......@@ -170,6 +170,8 @@ bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi);
170170bool target_abi_is_musl(ZigLLVM_EnvironmentType abi);
171171bool target_is_glibc(const ZigTarget *target);
172172bool target_is_musl(const ZigTarget *target);
173bool target_is_wasm(const ZigTarget *target);
174bool target_is_single_threaded(const ZigTarget *target);
173175
174176uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
175177
src/translate_c.cpp+1628-1591
......@@ -76,10 +76,9 @@ struct TransScopeWhile {
7676};
7777
7878struct Context {
79 ZigList<ErrorMsg *> *errors;
79 AstNode *root;
8080 VisibMod visib_mod;
8181 bool want_export;
82 AstNode *root;
8382 HashMap<const void *, AstNode *, ptr_hash, ptr_eq> decl_table;
8483 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> macro_table;
8584 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> global_table;
......@@ -112,19 +111,39 @@ static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *paren
112111
113112static TransScopeBlock *trans_scope_block_find(TransScope *scope);
114113
115static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl);
116static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl);
117static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl);
114static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl);
115static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl);
116static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl);
118117
119static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt,
118static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
120119 ResultUsed result_used, TransLRValue lrval,
121120 AstNode **out_node, TransScope **out_child_scope,
122121 TransScope **out_node_scope);
123static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node);
124static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
125static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc);
126static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
127static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc);
122static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node);
123static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval);
124static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc);
125static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc);
126static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope,
127 const ZigClangExpr *expr, TransLRValue lrval);
128static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
129 ZigClangSourceLocation source_loc);
130static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt);
131
132static const ZigClangAPSInt *bitcast(const llvm::APSInt *src) {
133 return reinterpret_cast<const ZigClangAPSInt *>(src);
134}
135
136static const ZigClangAPValue *bitcast(const clang::APValue *src) {
137 return reinterpret_cast<const ZigClangAPValue *>(src);
138}
139
140static const ZigClangStmt *bitcast(const clang::Stmt *src) {
141 return reinterpret_cast<const ZigClangStmt *>(src);
142}
143
144static const ZigClangExpr *bitcast(const clang::Expr *src) {
145 return reinterpret_cast<const ZigClangExpr *>(src);
146}
128147
129148static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
130149 ZigClangSourceLocation dest;
......@@ -136,14 +155,14 @@ static ZigClangQualType bitcast(clang::QualType src) {
136155 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangQualType));
137156 return dest;
138157}
139static clang::QualType bitcast(ZigClangQualType src) {
140 clang::QualType dest;
141 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangQualType));
142 return dest;
143}
158//static clang::QualType bitcast(ZigClangQualType src) {
159// clang::QualType dest;
160// memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangQualType));
161// return dest;
162//}
144163
145164ATTRIBUTE_PRINTF(3, 4)
146static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, const char *format, ...) {
165static void emit_warning(Context *c, ZigClangSourceLocation sl, const char *format, ...) {
147166 if (!c->warnings_on) {
148167 return;
149168 }
......@@ -153,7 +172,6 @@ static void emit_warning(Context *c, const clang::SourceLocation &clang_sl, cons
153172 Buf *msg = buf_vprintf(format, ap);
154173 va_end(ap);
155174
156 ZigClangSourceLocation sl = bitcast(clang_sl);
157175 const char *filename_bytes = ZigClangSourceManager_getFilename(c->source_manager,
158176 ZigClangSourceManager_getSpellingLoc(c->source_manager, sl));
159177 Buf *path;
......@@ -489,107 +507,99 @@ static Buf *string_ref_to_buf(llvm::StringRef string_ref) {
489507 return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size());
490508}
491509
492static const char *decl_name(const clang::Decl *decl) {
493 const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);
494 return (const char *)named_decl->getName().bytes_begin();
495}
496
497static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
510static AstNode *trans_create_node_apint(Context *c, const ZigClangAPSInt *aps_int) {
498511 AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
499512 node->data.int_literal.bigint = allocate<BigInt>(1);
500 bool is_negative = aps_int.isSigned() && aps_int.isNegative();
513 bool is_negative = ZigClangAPSInt_isSigned(aps_int) && ZigClangAPSInt_isNegative(aps_int);
501514 if (!is_negative) {
502 bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), false);
515 bigint_init_data(node->data.int_literal.bigint,
516 ZigClangAPSInt_getRawData(aps_int),
517 ZigClangAPSInt_getNumWords(aps_int),
518 false);
503519 return node;
504520 }
505 llvm::APSInt negated = -aps_int;
506 bigint_init_data(node->data.int_literal.bigint, negated.getRawData(), negated.getNumWords(), true);
521 const ZigClangAPSInt *negated = ZigClangAPSInt_negate(aps_int);
522 bigint_init_data(node->data.int_literal.bigint, ZigClangAPSInt_getRawData(negated),
523 ZigClangAPSInt_getNumWords(negated), true);
524 ZigClangAPSInt_free(negated);
507525 return node;
526}
508527
528static AstNode *trans_create_node_apfloat(Context *c, const llvm::APFloat &ap_float) {
529 uint8_t buf[128];
530 size_t written = ap_float.convertToHexString((char *)buf, 0, false,
531 llvm::APFloat::rmNearestTiesToEven);
532 AstNode *node = trans_create_node(c, NodeTypeFloatLiteral);
533 node->data.float_literal.bigfloat = allocate<BigFloat>(1);
534 if (bigfloat_init_buf(node->data.float_literal.bigfloat, buf, written)) {
535 node->data.float_literal.overflow = true;
536 }
537 return node;
509538}
510539
511static const clang::Type *qual_type_canon(clang::QualType qt) {
512 return qt.getCanonicalType().getTypePtr();
540static const ZigClangType *qual_type_canon(ZigClangQualType qt) {
541 ZigClangQualType canon = ZigClangQualType_getCanonicalType(qt);
542 return ZigClangQualType_getTypePtr(canon);
513543}
514544
515static clang::QualType get_expr_qual_type(Context *c, const clang::Expr *expr) {
545static ZigClangQualType get_expr_qual_type(Context *c, const ZigClangExpr *expr) {
516546 // String literals in C are `char *` but they should really be `const char *`.
517 if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
518 const clang::ImplicitCastExpr *cast_expr = static_cast<const clang::ImplicitCastExpr *>(expr);
519 if (cast_expr->getCastKind() == clang::CK_ArrayToPointerDecay) {
520 const clang::Expr *sub_expr = cast_expr->getSubExpr();
521 if (sub_expr->getStmtClass() == clang::Stmt::StringLiteralClass) {
522 clang::QualType array_qt = sub_expr->getType();
523 const clang::ArrayType *array_type = static_cast<const clang::ArrayType *>(array_qt.getTypePtr());
524 clang::QualType pointee_qt = array_type->getElementType();
525 pointee_qt.addConst();
526 return bitcast(ZigClangASTContext_getPointerType(c->ctx, bitcast(pointee_qt)));
547 if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
548 const clang::ImplicitCastExpr *cast_expr = reinterpret_cast<const clang::ImplicitCastExpr *>(expr);
549 if ((ZigClangCK)cast_expr->getCastKind() == ZigClangCK_ArrayToPointerDecay) {
550 const ZigClangExpr *sub_expr = bitcast(cast_expr->getSubExpr());
551 if (ZigClangExpr_getStmtClass(sub_expr) == ZigClangStmt_StringLiteralClass) {
552 ZigClangQualType array_qt = ZigClangExpr_getType(sub_expr);
553 const clang::ArrayType *array_type = reinterpret_cast<const clang::ArrayType *>(
554 ZigClangQualType_getTypePtr(array_qt));
555 ZigClangQualType pointee_qt = bitcast(array_type->getElementType());
556 ZigClangQualType_addConst(&pointee_qt);
557 return ZigClangASTContext_getPointerType(c->ctx, pointee_qt);
527558 }
528559 }
529560 }
530 return expr->getType();
561 return ZigClangExpr_getType(expr);
531562}
532563
533static clang::QualType get_expr_qual_type_before_implicit_cast(Context *c, const clang::Expr *expr) {
534 if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
535 const clang::ImplicitCastExpr *cast_expr = static_cast<const clang::ImplicitCastExpr *>(expr);
536 return get_expr_qual_type(c, cast_expr->getSubExpr());
564static ZigClangQualType get_expr_qual_type_before_implicit_cast(Context *c, const ZigClangExpr *expr) {
565 if (ZigClangExpr_getStmtClass(expr) == ZigClangStmt_ImplicitCastExprClass) {
566 const clang::ImplicitCastExpr *cast_expr = reinterpret_cast<const clang::ImplicitCastExpr *>(expr);
567 return get_expr_qual_type(c, bitcast(cast_expr->getSubExpr()));
537568 }
538 return expr->getType();
569 return ZigClangExpr_getType(expr);
539570}
540571
541static AstNode *get_expr_type(Context *c, const clang::Expr *expr) {
542 return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getBeginLoc());
543}
544
545static bool qual_types_equal(clang::QualType t1, clang::QualType t2) {
546 if (t1.isConstQualified() != t2.isConstQualified()) {
547 return false;
548 }
549 if (t1.isVolatileQualified() != t2.isVolatileQualified()) {
550 return false;
551 }
552 if (t1.isRestrictQualified() != t2.isRestrictQualified()) {
553 return false;
554 }
555 return t1.getTypePtr() == t2.getTypePtr();
572static AstNode *get_expr_type(Context *c, const ZigClangExpr *expr) {
573 return trans_qual_type(c, get_expr_qual_type(c, expr), ZigClangExpr_getBeginLoc(expr));
556574}
557575
558576static bool is_c_void_type(AstNode *node) {
559577 return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
560578}
561579
562static bool expr_types_equal(Context *c, const clang::Expr *expr1, const clang::Expr *expr2) {
563 clang::QualType t1 = get_expr_qual_type(c, expr1);
564 clang::QualType t2 = get_expr_qual_type(c, expr2);
565
566 return qual_types_equal(t1, t2);
580static bool qual_type_is_ptr(ZigClangQualType qt) {
581 const ZigClangType *ty = qual_type_canon(qt);
582 return ZigClangType_getTypeClass(ty) == ZigClangType_Pointer;
567583}
568584
569static bool qual_type_is_ptr(clang::QualType qt) {
570 const clang::Type *ty = qual_type_canon(qt);
571 return ty->getTypeClass() == clang::Type::Pointer;
572}
573
574static const clang::FunctionProtoType *qual_type_get_fn_proto(clang::QualType qt, bool *is_ptr) {
575 const clang::Type *ty = qual_type_canon(qt);
585static const clang::FunctionProtoType *qual_type_get_fn_proto(ZigClangQualType qt, bool *is_ptr) {
586 const ZigClangType *ty = qual_type_canon(qt);
576587 *is_ptr = false;
577588
578 if (ty->getTypeClass() == clang::Type::Pointer) {
589 if (ZigClangType_getTypeClass(ty) == ZigClangType_Pointer) {
579590 *is_ptr = true;
580 const clang::PointerType *pointer_ty = static_cast<const clang::PointerType*>(ty);
581 clang::QualType child_qt = pointer_ty->getPointeeType();
582 ty = child_qt.getTypePtr();
591 ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
592 ty = ZigClangQualType_getTypePtr(child_qt);
583593 }
584594
585 if (ty->getTypeClass() == clang::Type::FunctionProto) {
586 return static_cast<const clang::FunctionProtoType*>(ty);
595 if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionProto) {
596 return reinterpret_cast<const clang::FunctionProtoType*>(ty);
587597 }
588598
589599 return nullptr;
590600}
591601
592static bool qual_type_is_fn_ptr(clang::QualType qt) {
602static bool qual_type_is_fn_ptr(ZigClangQualType qt) {
593603 bool is_ptr;
594604 if (qual_type_get_fn_proto(qt, &is_ptr)) {
595605 return is_ptr;
......@@ -598,31 +608,31 @@ static bool qual_type_is_fn_ptr(clang::QualType qt) {
598608 return false;
599609}
600610
601static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, const clang::SourceLocation &source_loc) {
602 const clang::Type *ty = qt.getTypePtr();
603 switch (ty->getTypeClass()) {
604 case clang::Type::Builtin:
611static uint32_t qual_type_int_bit_width(Context *c, const ZigClangQualType qt, ZigClangSourceLocation source_loc) {
612 const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
613 switch (ZigClangType_getTypeClass(ty)) {
614 case ZigClangType_Builtin:
605615 {
606 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(ty);
607 switch (builtin_ty->getKind()) {
608 case clang::BuiltinType::Char_U:
609 case clang::BuiltinType::UChar:
610 case clang::BuiltinType::Char_S:
611 case clang::BuiltinType::SChar:
616 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
617 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
618 case ZigClangBuiltinTypeChar_U:
619 case ZigClangBuiltinTypeUChar:
620 case ZigClangBuiltinTypeChar_S:
621 case ZigClangBuiltinTypeSChar:
612622 return 8;
613 case clang::BuiltinType::UInt128:
614 case clang::BuiltinType::Int128:
623 case ZigClangBuiltinTypeUInt128:
624 case ZigClangBuiltinTypeInt128:
615625 return 128;
616626 default:
617627 return 0;
618628 }
619629 zig_unreachable();
620630 }
621 case clang::Type::Typedef:
631 case ZigClangType_Typedef:
622632 {
623 const clang::TypedefType *typedef_ty = static_cast<const clang::TypedefType*>(ty);
624 const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
625 const char *type_name = decl_name(typedef_decl);
633 const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
634 const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
635 const char *type_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl);
626636 if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) {
627637 return 8;
628638 } else if (strcmp(type_name, "uint16_t") == 0 || strcmp(type_name, "int16_t") == 0) {
......@@ -642,8 +652,8 @@ static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, c
642652}
643653
644654
645static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt,
646 const clang::SourceLocation &source_loc)
655static AstNode *qual_type_to_log2_int_ref(Context *c, const ZigClangQualType qt,
656 ZigClangSourceLocation source_loc)
647657{
648658 uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc);
649659 if (int_bit_width != 0) {
......@@ -675,37 +685,76 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt,
675685 return log2int_fn_call;
676686}
677687
678static bool qual_type_child_is_fn_proto(const clang::QualType &qt) {
679 if (qt.getTypePtr()->getTypeClass() == clang::Type::Paren) {
680 const clang::ParenType *paren_type = static_cast<const clang::ParenType *>(qt.getTypePtr());
688static bool qual_type_child_is_fn_proto(ZigClangQualType qt) {
689 const ZigClangType *ty = ZigClangQualType_getTypePtr(qt);
690 if (ZigClangType_getTypeClass(ty) == ZigClangType_Paren) {
691 const clang::ParenType *paren_type = reinterpret_cast<const clang::ParenType *>(ty);
681692 if (paren_type->getInnerType()->getTypeClass() == clang::Type::FunctionProto) {
682693 return true;
683694 }
684 } else if (qt.getTypePtr()->getTypeClass() == clang::Type::Attributed) {
685 const clang::AttributedType *attr_type = static_cast<const clang::AttributedType *>(qt.getTypePtr());
686 return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
695 } else if (ZigClangType_getTypeClass(ty) == ZigClangType_Attributed) {
696 const clang::AttributedType *attr_type = reinterpret_cast<const clang::AttributedType *>(ty);
697 return qual_type_child_is_fn_proto(bitcast(attr_type->getEquivalentType()));
687698 }
688699 return false;
689700}
690701
691static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,
692 clang::QualType src_type, AstNode *expr)
702static AstNode* trans_c_ptr_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
703 ZigClangQualType src_type, AstNode *expr)
704{
705 const ZigClangType *ty = ZigClangQualType_getTypePtr(dest_type);
706 const ZigClangQualType child_type = ZigClangType_getPointeeType(ty);
707
708 AstNode *dest_type_node = trans_type(c, ty, source_location);
709 AstNode *child_type_node = trans_qual_type(c, child_type, source_location);
710
711 // Implicit downcasting from higher to lower alignment values is forbidden,
712 // use @alignCast to side-step this problem
713 AstNode *ptrcast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
714 ptrcast_node->data.fn_call_expr.params.append(dest_type_node);
715
716 if (ZigClangType_isVoidType(qual_type_canon(child_type))) {
717 // void has 1-byte alignment
718 ptrcast_node->data.fn_call_expr.params.append(expr);
719 } else {
720 AstNode *alignof_node = trans_create_node_builtin_fn_call_str(c, "alignOf");
721 alignof_node->data.fn_call_expr.params.append(child_type_node);
722 AstNode *aligncast_node = trans_create_node_builtin_fn_call_str(c, "alignCast");
723 aligncast_node->data.fn_call_expr.params.append(alignof_node);
724 aligncast_node->data.fn_call_expr.params.append(expr);
725
726 ptrcast_node->data.fn_call_expr.params.append(aligncast_node);
727 }
728
729 return ptrcast_node;
730}
731
732static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location, ZigClangQualType dest_type,
733 ZigClangQualType src_type, AstNode *expr)
693734{
694735 // The only way void pointer casts are valid C code, is if
695736 // the value of the expression is ignored. We therefore just
696737 // return the expr, and let the system that ignores values
697738 // translate this correctly.
698 if (qual_type_canon(dest_type)->isVoidType()) {
739 if (ZigClangType_isVoidType(qual_type_canon(dest_type))) {
699740 return expr;
700741 }
701 if (qual_types_equal(dest_type, src_type)) {
742 if (ZigClangQualType_eq(dest_type, src_type)) {
702743 return expr;
703744 }
704745 if (qual_type_is_ptr(dest_type) && qual_type_is_ptr(src_type)) {
705 AstNode *ptr_cast_node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
706 ptr_cast_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
707 ptr_cast_node->data.fn_call_expr.params.append(expr);
708 return ptr_cast_node;
746 return trans_c_ptr_cast(c, source_location, dest_type, src_type, expr);
747 }
748 if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
749 AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
750 addr_node->data.fn_call_expr.params.append(expr);
751 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);
752 }
753 if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
754 AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
755 ptr_node->data.fn_call_expr.params.append(trans_qual_type(c, dest_type, source_location));
756 ptr_node->data.fn_call_expr.params.append(expr);
757 return ptr_node;
709758 }
710759 // TODO: maybe widen to increase size
711760 // TODO: maybe bitcast to change sign
......@@ -713,72 +762,72 @@ static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_loc
713762 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
714763}
715764
716static bool c_is_signed_integer(Context *c, clang::QualType qt) {
717 const clang::Type *c_type = qual_type_canon(qt);
718 if (c_type->getTypeClass() != clang::Type::Builtin)
765static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
766 const ZigClangType *c_type = qual_type_canon(qt);
767 if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
719768 return false;
720 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(c_type);
721 switch (builtin_ty->getKind()) {
722 case clang::BuiltinType::SChar:
723 case clang::BuiltinType::Short:
724 case clang::BuiltinType::Int:
725 case clang::BuiltinType::Long:
726 case clang::BuiltinType::LongLong:
727 case clang::BuiltinType::Int128:
728 case clang::BuiltinType::WChar_S:
769 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
770 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
771 case ZigClangBuiltinTypeSChar:
772 case ZigClangBuiltinTypeShort:
773 case ZigClangBuiltinTypeInt:
774 case ZigClangBuiltinTypeLong:
775 case ZigClangBuiltinTypeLongLong:
776 case ZigClangBuiltinTypeInt128:
777 case ZigClangBuiltinTypeWChar_S:
729778 return true;
730779 default:
731780 return false;
732781 }
733782}
734783
735static bool c_is_unsigned_integer(Context *c, clang::QualType qt) {
736 const clang::Type *c_type = qual_type_canon(qt);
737 if (c_type->getTypeClass() != clang::Type::Builtin)
784static bool c_is_unsigned_integer(Context *c, ZigClangQualType qt) {
785 const ZigClangType *c_type = qual_type_canon(qt);
786 if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
738787 return false;
739 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(c_type);
740 switch (builtin_ty->getKind()) {
741 case clang::BuiltinType::Char_U:
742 case clang::BuiltinType::UChar:
743 case clang::BuiltinType::Char_S:
744 case clang::BuiltinType::UShort:
745 case clang::BuiltinType::UInt:
746 case clang::BuiltinType::ULong:
747 case clang::BuiltinType::ULongLong:
748 case clang::BuiltinType::UInt128:
749 case clang::BuiltinType::WChar_U:
788 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
789 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
790 case ZigClangBuiltinTypeChar_U:
791 case ZigClangBuiltinTypeUChar:
792 case ZigClangBuiltinTypeChar_S:
793 case ZigClangBuiltinTypeUShort:
794 case ZigClangBuiltinTypeUInt:
795 case ZigClangBuiltinTypeULong:
796 case ZigClangBuiltinTypeULongLong:
797 case ZigClangBuiltinTypeUInt128:
798 case ZigClangBuiltinTypeWChar_U:
750799 return true;
751800 default:
752801 return false;
753802 }
754803}
755804
756static bool c_is_builtin_type(Context *c, clang::QualType qt, clang::BuiltinType::Kind kind) {
757 const clang::Type *c_type = qual_type_canon(qt);
758 if (c_type->getTypeClass() != clang::Type::Builtin)
805static bool c_is_builtin_type(Context *c, ZigClangQualType qt, ZigClangBuiltinTypeKind kind) {
806 const ZigClangType *c_type = qual_type_canon(qt);
807 if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
759808 return false;
760 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(c_type);
761 return builtin_ty->getKind() == kind;
809 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
810 return ZigClangBuiltinType_getKind(builtin_ty) == kind;
762811}
763812
764static bool c_is_float(Context *c, clang::QualType qt) {
765 const clang::Type *c_type = qt.getTypePtr();
766 if (c_type->getTypeClass() != clang::Type::Builtin)
813static bool c_is_float(Context *c, ZigClangQualType qt) {
814 const ZigClangType *c_type = ZigClangQualType_getTypePtr(qt);
815 if (ZigClangType_getTypeClass(c_type) != ZigClangType_Builtin)
767816 return false;
768 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(c_type);
769 switch (builtin_ty->getKind()) {
770 case clang::BuiltinType::Half:
771 case clang::BuiltinType::Float:
772 case clang::BuiltinType::Double:
773 case clang::BuiltinType::Float128:
774 case clang::BuiltinType::LongDouble:
817 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(c_type);
818 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
819 case ZigClangBuiltinTypeHalf:
820 case ZigClangBuiltinTypeFloat:
821 case ZigClangBuiltinTypeDouble:
822 case ZigClangBuiltinTypeFloat128:
823 case ZigClangBuiltinTypeLongDouble:
775824 return true;
776825 default:
777826 return false;
778827 }
779828}
780829
781static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) {
830static bool qual_type_has_wrapping_overflow(Context *c, ZigClangQualType qt) {
782831 if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) {
783832 // float and signed integer overflow is undefined behavior.
784833 return false;
......@@ -788,181 +837,182 @@ static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) {
788837 }
789838}
790839
791static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
792 switch (ty->getTypeClass()) {
793 case clang::Type::Builtin: {
794 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(ty);
795 return builtin_ty->getKind() == clang::BuiltinType::Void;
840static bool type_is_opaque(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
841 switch (ZigClangType_getTypeClass(ty)) {
842 case ZigClangType_Builtin: {
843 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
844 return ZigClangBuiltinType_getKind(builtin_ty) == ZigClangBuiltinTypeVoid;
796845 }
797 case clang::Type::Record: {
798 const clang::RecordType *record_ty = static_cast<const clang::RecordType*>(ty);
846 case ZigClangType_Record: {
847 const clang::RecordType *record_ty = reinterpret_cast<const clang::RecordType*>(ty);
799848 return record_ty->getDecl()->getDefinition() == nullptr;
800849 }
801 case clang::Type::Elaborated: {
802 const clang::ElaboratedType *elaborated_ty = static_cast<const clang::ElaboratedType*>(ty);
803 return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
850 case ZigClangType_Elaborated: {
851 const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
852 ZigClangQualType qt = bitcast(elaborated_ty->getNamedType());
853 return type_is_opaque(c, ZigClangQualType_getTypePtr(qt), source_loc);
804854 }
805 case clang::Type::Typedef: {
806 const clang::TypedefType *typedef_ty = static_cast<const clang::TypedefType*>(ty);
807 const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
808 return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
855 case ZigClangType_Typedef: {
856 const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
857 const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
858 ZigClangQualType underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
859 return type_is_opaque(c, ZigClangQualType_getTypePtr(underlying_type), source_loc);
809860 }
810861 default:
811862 return false;
812863 }
813864}
814865
815static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
816 switch (ty->getTypeClass()) {
817 case clang::Type::Builtin:
866static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLocation source_loc) {
867 switch (ZigClangType_getTypeClass(ty)) {
868 case ZigClangType_Builtin:
818869 {
819 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(ty);
820 switch (builtin_ty->getKind()) {
821 case clang::BuiltinType::Void:
870 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType *>(ty);
871 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
872 case ZigClangBuiltinTypeVoid:
822873 return trans_create_node_symbol_str(c, "c_void");
823 case clang::BuiltinType::Bool:
874 case ZigClangBuiltinTypeBool:
824875 return trans_create_node_symbol_str(c, "bool");
825 case clang::BuiltinType::Char_U:
826 case clang::BuiltinType::UChar:
827 case clang::BuiltinType::Char_S:
828 case clang::BuiltinType::Char8:
876 case ZigClangBuiltinTypeChar_U:
877 case ZigClangBuiltinTypeUChar:
878 case ZigClangBuiltinTypeChar_S:
879 case ZigClangBuiltinTypeChar8:
829880 return trans_create_node_symbol_str(c, "u8");
830 case clang::BuiltinType::SChar:
881 case ZigClangBuiltinTypeSChar:
831882 return trans_create_node_symbol_str(c, "i8");
832 case clang::BuiltinType::UShort:
883 case ZigClangBuiltinTypeUShort:
833884 return trans_create_node_symbol_str(c, "c_ushort");
834 case clang::BuiltinType::UInt:
885 case ZigClangBuiltinTypeUInt:
835886 return trans_create_node_symbol_str(c, "c_uint");
836 case clang::BuiltinType::ULong:
887 case ZigClangBuiltinTypeULong:
837888 return trans_create_node_symbol_str(c, "c_ulong");
838 case clang::BuiltinType::ULongLong:
889 case ZigClangBuiltinTypeULongLong:
839890 return trans_create_node_symbol_str(c, "c_ulonglong");
840 case clang::BuiltinType::Short:
891 case ZigClangBuiltinTypeShort:
841892 return trans_create_node_symbol_str(c, "c_short");
842 case clang::BuiltinType::Int:
893 case ZigClangBuiltinTypeInt:
843894 return trans_create_node_symbol_str(c, "c_int");
844 case clang::BuiltinType::Long:
895 case ZigClangBuiltinTypeLong:
845896 return trans_create_node_symbol_str(c, "c_long");
846 case clang::BuiltinType::LongLong:
897 case ZigClangBuiltinTypeLongLong:
847898 return trans_create_node_symbol_str(c, "c_longlong");
848 case clang::BuiltinType::UInt128:
899 case ZigClangBuiltinTypeUInt128:
849900 return trans_create_node_symbol_str(c, "u128");
850 case clang::BuiltinType::Int128:
901 case ZigClangBuiltinTypeInt128:
851902 return trans_create_node_symbol_str(c, "i128");
852 case clang::BuiltinType::Float:
903 case ZigClangBuiltinTypeFloat:
853904 return trans_create_node_symbol_str(c, "f32");
854 case clang::BuiltinType::Double:
905 case ZigClangBuiltinTypeDouble:
855906 return trans_create_node_symbol_str(c, "f64");
856 case clang::BuiltinType::Float128:
907 case ZigClangBuiltinTypeFloat128:
857908 return trans_create_node_symbol_str(c, "f128");
858 case clang::BuiltinType::Float16:
909 case ZigClangBuiltinTypeFloat16:
859910 return trans_create_node_symbol_str(c, "f16");
860 case clang::BuiltinType::LongDouble:
911 case ZigClangBuiltinTypeLongDouble:
861912 return trans_create_node_symbol_str(c, "c_longdouble");
862 case clang::BuiltinType::WChar_U:
863 case clang::BuiltinType::Char16:
864 case clang::BuiltinType::Char32:
865 case clang::BuiltinType::WChar_S:
866 case clang::BuiltinType::Half:
867 case clang::BuiltinType::NullPtr:
868 case clang::BuiltinType::ObjCId:
869 case clang::BuiltinType::ObjCClass:
870 case clang::BuiltinType::ObjCSel:
871 case clang::BuiltinType::OMPArraySection:
872 case clang::BuiltinType::Dependent:
873 case clang::BuiltinType::Overload:
874 case clang::BuiltinType::BoundMember:
875 case clang::BuiltinType::PseudoObject:
876 case clang::BuiltinType::UnknownAny:
877 case clang::BuiltinType::BuiltinFn:
878 case clang::BuiltinType::ARCUnbridgedCast:
879 case clang::BuiltinType::ShortAccum:
880 case clang::BuiltinType::Accum:
881 case clang::BuiltinType::LongAccum:
882 case clang::BuiltinType::UShortAccum:
883 case clang::BuiltinType::UAccum:
884 case clang::BuiltinType::ULongAccum:
885
886 case clang::BuiltinType::OCLImage1dRO:
887 case clang::BuiltinType::OCLImage1dArrayRO:
888 case clang::BuiltinType::OCLImage1dBufferRO:
889 case clang::BuiltinType::OCLImage2dRO:
890 case clang::BuiltinType::OCLImage2dArrayRO:
891 case clang::BuiltinType::OCLImage2dDepthRO:
892 case clang::BuiltinType::OCLImage2dArrayDepthRO:
893 case clang::BuiltinType::OCLImage2dMSAARO:
894 case clang::BuiltinType::OCLImage2dArrayMSAARO:
895 case clang::BuiltinType::OCLImage2dMSAADepthRO:
896 case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
897 case clang::BuiltinType::OCLImage3dRO:
898 case clang::BuiltinType::OCLImage1dWO:
899 case clang::BuiltinType::OCLImage1dArrayWO:
900 case clang::BuiltinType::OCLImage1dBufferWO:
901 case clang::BuiltinType::OCLImage2dWO:
902 case clang::BuiltinType::OCLImage2dArrayWO:
903 case clang::BuiltinType::OCLImage2dDepthWO:
904 case clang::BuiltinType::OCLImage2dArrayDepthWO:
905 case clang::BuiltinType::OCLImage2dMSAAWO:
906 case clang::BuiltinType::OCLImage2dArrayMSAAWO:
907 case clang::BuiltinType::OCLImage2dMSAADepthWO:
908 case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
909 case clang::BuiltinType::OCLImage3dWO:
910 case clang::BuiltinType::OCLImage1dRW:
911 case clang::BuiltinType::OCLImage1dArrayRW:
912 case clang::BuiltinType::OCLImage1dBufferRW:
913 case clang::BuiltinType::OCLImage2dRW:
914 case clang::BuiltinType::OCLImage2dArrayRW:
915 case clang::BuiltinType::OCLImage2dDepthRW:
916 case clang::BuiltinType::OCLImage2dArrayDepthRW:
917 case clang::BuiltinType::OCLImage2dMSAARW:
918 case clang::BuiltinType::OCLImage2dArrayMSAARW:
919 case clang::BuiltinType::OCLImage2dMSAADepthRW:
920 case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
921 case clang::BuiltinType::OCLImage3dRW:
922 case clang::BuiltinType::OCLSampler:
923 case clang::BuiltinType::OCLEvent:
924 case clang::BuiltinType::OCLClkEvent:
925 case clang::BuiltinType::OCLQueue:
926 case clang::BuiltinType::OCLReserveID:
927 case clang::BuiltinType::ShortFract:
928 case clang::BuiltinType::Fract:
929 case clang::BuiltinType::LongFract:
930 case clang::BuiltinType::UShortFract:
931 case clang::BuiltinType::UFract:
932 case clang::BuiltinType::ULongFract:
933 case clang::BuiltinType::SatShortAccum:
934 case clang::BuiltinType::SatAccum:
935 case clang::BuiltinType::SatLongAccum:
936 case clang::BuiltinType::SatUShortAccum:
937 case clang::BuiltinType::SatUAccum:
938 case clang::BuiltinType::SatULongAccum:
939 case clang::BuiltinType::SatShortFract:
940 case clang::BuiltinType::SatFract:
941 case clang::BuiltinType::SatLongFract:
942 case clang::BuiltinType::SatUShortFract:
943 case clang::BuiltinType::SatUFract:
944 case clang::BuiltinType::SatULongFract:
945 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
946 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
947 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
948 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
949 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
950 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
951 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
952 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
953 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
954 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
955 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
956 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
913 case ZigClangBuiltinTypeWChar_U:
914 case ZigClangBuiltinTypeChar16:
915 case ZigClangBuiltinTypeChar32:
916 case ZigClangBuiltinTypeWChar_S:
917 case ZigClangBuiltinTypeHalf:
918 case ZigClangBuiltinTypeNullPtr:
919 case ZigClangBuiltinTypeObjCId:
920 case ZigClangBuiltinTypeObjCClass:
921 case ZigClangBuiltinTypeObjCSel:
922 case ZigClangBuiltinTypeOMPArraySection:
923 case ZigClangBuiltinTypeDependent:
924 case ZigClangBuiltinTypeOverload:
925 case ZigClangBuiltinTypeBoundMember:
926 case ZigClangBuiltinTypePseudoObject:
927 case ZigClangBuiltinTypeUnknownAny:
928 case ZigClangBuiltinTypeBuiltinFn:
929 case ZigClangBuiltinTypeARCUnbridgedCast:
930 case ZigClangBuiltinTypeShortAccum:
931 case ZigClangBuiltinTypeAccum:
932 case ZigClangBuiltinTypeLongAccum:
933 case ZigClangBuiltinTypeUShortAccum:
934 case ZigClangBuiltinTypeUAccum:
935 case ZigClangBuiltinTypeULongAccum:
936
937 case ZigClangBuiltinTypeOCLImage1dRO:
938 case ZigClangBuiltinTypeOCLImage1dArrayRO:
939 case ZigClangBuiltinTypeOCLImage1dBufferRO:
940 case ZigClangBuiltinTypeOCLImage2dRO:
941 case ZigClangBuiltinTypeOCLImage2dArrayRO:
942 case ZigClangBuiltinTypeOCLImage2dDepthRO:
943 case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
944 case ZigClangBuiltinTypeOCLImage2dMSAARO:
945 case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
946 case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
947 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
948 case ZigClangBuiltinTypeOCLImage3dRO:
949 case ZigClangBuiltinTypeOCLImage1dWO:
950 case ZigClangBuiltinTypeOCLImage1dArrayWO:
951 case ZigClangBuiltinTypeOCLImage1dBufferWO:
952 case ZigClangBuiltinTypeOCLImage2dWO:
953 case ZigClangBuiltinTypeOCLImage2dArrayWO:
954 case ZigClangBuiltinTypeOCLImage2dDepthWO:
955 case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
956 case ZigClangBuiltinTypeOCLImage2dMSAAWO:
957 case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
958 case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
959 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
960 case ZigClangBuiltinTypeOCLImage3dWO:
961 case ZigClangBuiltinTypeOCLImage1dRW:
962 case ZigClangBuiltinTypeOCLImage1dArrayRW:
963 case ZigClangBuiltinTypeOCLImage1dBufferRW:
964 case ZigClangBuiltinTypeOCLImage2dRW:
965 case ZigClangBuiltinTypeOCLImage2dArrayRW:
966 case ZigClangBuiltinTypeOCLImage2dDepthRW:
967 case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
968 case ZigClangBuiltinTypeOCLImage2dMSAARW:
969 case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
970 case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
971 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
972 case ZigClangBuiltinTypeOCLImage3dRW:
973 case ZigClangBuiltinTypeOCLSampler:
974 case ZigClangBuiltinTypeOCLEvent:
975 case ZigClangBuiltinTypeOCLClkEvent:
976 case ZigClangBuiltinTypeOCLQueue:
977 case ZigClangBuiltinTypeOCLReserveID:
978 case ZigClangBuiltinTypeShortFract:
979 case ZigClangBuiltinTypeFract:
980 case ZigClangBuiltinTypeLongFract:
981 case ZigClangBuiltinTypeUShortFract:
982 case ZigClangBuiltinTypeUFract:
983 case ZigClangBuiltinTypeULongFract:
984 case ZigClangBuiltinTypeSatShortAccum:
985 case ZigClangBuiltinTypeSatAccum:
986 case ZigClangBuiltinTypeSatLongAccum:
987 case ZigClangBuiltinTypeSatUShortAccum:
988 case ZigClangBuiltinTypeSatUAccum:
989 case ZigClangBuiltinTypeSatULongAccum:
990 case ZigClangBuiltinTypeSatShortFract:
991 case ZigClangBuiltinTypeSatFract:
992 case ZigClangBuiltinTypeSatLongFract:
993 case ZigClangBuiltinTypeSatUShortFract:
994 case ZigClangBuiltinTypeSatUFract:
995 case ZigClangBuiltinTypeSatULongFract:
996 case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
997 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
998 case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
999 case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
1000 case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
1001 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
1002 case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
1003 case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
1004 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
1005 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
1006 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
1007 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
9571008 emit_warning(c, source_loc, "unsupported builtin type");
9581009 return nullptr;
9591010 }
9601011 break;
9611012 }
962 case clang::Type::Pointer:
1013 case ZigClangType_Pointer:
9631014 {
964 const clang::PointerType *pointer_ty = static_cast<const clang::PointerType*>(ty);
965 clang::QualType child_qt = pointer_ty->getPointeeType();
1015 ZigClangQualType child_qt = ZigClangType_getPointeeType(ty);
9661016 AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
9671017 if (child_node == nullptr) {
9681018 emit_warning(c, source_loc, "pointer to unsupported type");
......@@ -973,29 +1023,33 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
9731023 return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
9741024 }
9751025
976 if (type_is_opaque(c, child_qt.getTypePtr(), source_loc)) {
977 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
978 child_qt.isVolatileQualified(), child_node, PtrLenSingle);
1026 if (type_is_opaque(c, ZigClangQualType_getTypePtr(child_qt), source_loc)) {
1027 AstNode *pointer_node = trans_create_node_ptr_type(c,
1028 ZigClangQualType_isConstQualified(child_qt),
1029 ZigClangQualType_isVolatileQualified(child_qt),
1030 child_node, PtrLenSingle);
9791031 return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
9801032 } else {
981 return trans_create_node_ptr_type(c, child_qt.isConstQualified(),
982 child_qt.isVolatileQualified(), child_node, PtrLenC);
1033 return trans_create_node_ptr_type(c,
1034 ZigClangQualType_isConstQualified(child_qt),
1035 ZigClangQualType_isVolatileQualified(child_qt),
1036 child_node, PtrLenC);
9831037 }
9841038 }
985 case clang::Type::Typedef:
1039 case ZigClangType_Typedef:
9861040 {
987 const clang::TypedefType *typedef_ty = static_cast<const clang::TypedefType*>(ty);
988 const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
1041 const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
1042 const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
9891043 return resolve_typedef_decl(c, typedef_decl);
9901044 }
991 case clang::Type::Elaborated:
1045 case ZigClangType_Elaborated:
9921046 {
993 const clang::ElaboratedType *elaborated_ty = static_cast<const clang::ElaboratedType*>(ty);
1047 const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
9941048 switch (elaborated_ty->getKeyword()) {
9951049 case clang::ETK_Struct:
9961050 case clang::ETK_Enum:
9971051 case clang::ETK_Union:
998 return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
1052 return trans_qual_type(c, bitcast(elaborated_ty->getNamedType()), source_loc);
9991053 case clang::ETK_Interface:
10001054 case clang::ETK_Class:
10011055 case clang::ETK_Typename:
......@@ -1004,81 +1058,81 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
10041058 return nullptr;
10051059 }
10061060 }
1007 case clang::Type::FunctionProto:
1008 case clang::Type::FunctionNoProto:
1061 case ZigClangType_FunctionProto:
1062 case ZigClangType_FunctionNoProto:
10091063 {
1010 const clang::FunctionType *fn_ty = static_cast<const clang::FunctionType*>(ty);
1064 const ZigClangFunctionType *fn_ty = reinterpret_cast<const ZigClangFunctionType*>(ty);
10111065
10121066 AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
1013 switch (fn_ty->getCallConv()) {
1014 case clang::CC_C: // __attribute__((cdecl))
1067 switch (ZigClangFunctionType_getCallConv(fn_ty)) {
1068 case ZigClangCallingConv_C: // __attribute__((cdecl))
10151069 proto_node->data.fn_proto.cc = CallingConventionC;
10161070 proto_node->data.fn_proto.is_extern = true;
10171071 break;
1018 case clang::CC_X86StdCall: // __attribute__((stdcall))
1072 case ZigClangCallingConv_X86StdCall: // __attribute__((stdcall))
10191073 proto_node->data.fn_proto.cc = CallingConventionStdcall;
10201074 break;
1021 case clang::CC_X86FastCall: // __attribute__((fastcall))
1075 case ZigClangCallingConv_X86FastCall: // __attribute__((fastcall))
10221076 emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
10231077 return nullptr;
1024 case clang::CC_X86ThisCall: // __attribute__((thiscall))
1078 case ZigClangCallingConv_X86ThisCall: // __attribute__((thiscall))
10251079 emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
10261080 return nullptr;
1027 case clang::CC_X86VectorCall: // __attribute__((vectorcall))
1081 case ZigClangCallingConv_X86VectorCall: // __attribute__((vectorcall))
10281082 emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
10291083 return nullptr;
1030 case clang::CC_X86Pascal: // __attribute__((pascal))
1084 case ZigClangCallingConv_X86Pascal: // __attribute__((pascal))
10311085 emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
10321086 return nullptr;
1033 case clang::CC_Win64: // __attribute__((ms_abi))
1087 case ZigClangCallingConv_Win64: // __attribute__((ms_abi))
10341088 emit_warning(c, source_loc, "unsupported calling convention: win64");
10351089 return nullptr;
1036 case clang::CC_X86_64SysV: // __attribute__((sysv_abi))
1090 case ZigClangCallingConv_X86_64SysV: // __attribute__((sysv_abi))
10371091 emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
10381092 return nullptr;
1039 case clang::CC_X86RegCall:
1093 case ZigClangCallingConv_X86RegCall:
10401094 emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
10411095 return nullptr;
1042 case clang::CC_AAPCS: // __attribute__((pcs("aapcs")))
1096 case ZigClangCallingConv_AAPCS: // __attribute__((pcs("aapcs")))
10431097 emit_warning(c, source_loc, "unsupported calling convention: aapcs");
10441098 return nullptr;
1045 case clang::CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
1099 case ZigClangCallingConv_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
10461100 emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
10471101 return nullptr;
1048 case clang::CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
1102 case ZigClangCallingConv_IntelOclBicc: // __attribute__((intel_ocl_bicc))
10491103 emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
10501104 return nullptr;
1051 case clang::CC_SpirFunction: // default for OpenCL functions on SPIR target
1105 case ZigClangCallingConv_SpirFunction: // default for OpenCL functions on SPIR target
10521106 emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
10531107 return nullptr;
1054 case clang::CC_OpenCLKernel:
1108 case ZigClangCallingConv_OpenCLKernel:
10551109 emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
10561110 return nullptr;
1057 case clang::CC_Swift:
1111 case ZigClangCallingConv_Swift:
10581112 emit_warning(c, source_loc, "unsupported calling convention: Swift");
10591113 return nullptr;
1060 case clang::CC_PreserveMost:
1114 case ZigClangCallingConv_PreserveMost:
10611115 emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
10621116 return nullptr;
1063 case clang::CC_PreserveAll:
1117 case ZigClangCallingConv_PreserveAll:
10641118 emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
10651119 return nullptr;
1066 case clang::CC_AArch64VectorCall:
1120 case ZigClangCallingConv_AArch64VectorCall:
10671121 emit_warning(c, source_loc, "unsupported calling convention: AArch64VectorCall");
10681122 return nullptr;
10691123 }
10701124
1071 if (fn_ty->getNoReturnAttr()) {
1125 if (ZigClangFunctionType_getNoReturnAttr(fn_ty)) {
10721126 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "noreturn");
10731127 } else {
1074 proto_node->data.fn_proto.return_type = trans_qual_type(c, fn_ty->getReturnType(),
1075 source_loc);
1128 proto_node->data.fn_proto.return_type = trans_qual_type(c,
1129 ZigClangFunctionType_getReturnType(fn_ty), source_loc);
10761130 if (proto_node->data.fn_proto.return_type == nullptr) {
10771131 emit_warning(c, source_loc, "unsupported function proto return type");
10781132 return nullptr;
10791133 }
10801134 // convert c_void to actual void (only for return type)
1081 // we do want to look at the AstNode instead of clang::QualType, because
1135 // we do want to look at the AstNode instead of ZigClangQualType, because
10821136 // if they do something like:
10831137 // typedef Foo void;
10841138 // void foo(void) -> Foo;
......@@ -1094,17 +1148,17 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
10941148 proto_node->data.fn_proto.name = buf_create_from_str(fn_name);
10951149 }
10961150
1097 if (ty->getTypeClass() == clang::Type::FunctionNoProto) {
1151 if (ZigClangType_getTypeClass(ty) == ZigClangType_FunctionNoProto) {
10981152 return proto_node;
10991153 }
11001154
1101 const clang::FunctionProtoType *fn_proto_ty = static_cast<const clang::FunctionProtoType*>(ty);
1155 const ZigClangFunctionProtoType *fn_proto_ty = reinterpret_cast<const ZigClangFunctionProtoType*>(ty);
11021156
1103 proto_node->data.fn_proto.is_var_args = fn_proto_ty->isVariadic();
1104 size_t param_count = fn_proto_ty->getNumParams();
1157 proto_node->data.fn_proto.is_var_args = ZigClangFunctionProtoType_isVariadic(fn_proto_ty);
1158 size_t param_count = ZigClangFunctionProtoType_getNumParams(fn_proto_ty);
11051159
11061160 for (size_t i = 0; i < param_count; i += 1) {
1107 clang::QualType qt = fn_proto_ty->getParamType(i);
1161 ZigClangQualType qt = ZigClangFunctionProtoType_getParamType(fn_proto_ty, i);
11081162 AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
11091163
11101164 if (param_type_node == nullptr) {
......@@ -1118,7 +1172,7 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
11181172 if (param_name != nullptr) {
11191173 param_node->data.param_decl.name = buf_create_from_str(param_name);
11201174 }
1121 param_node->data.param_decl.is_noalias = qt.isRestrictQualified();
1175 param_node->data.param_decl.is_noalias = ZigClangQualType_isRestrictQualified(qt);
11221176 param_node->data.param_decl.type = param_type_node;
11231177 proto_node->data.fn_proto.params.append(param_node);
11241178 }
......@@ -1127,20 +1181,20 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
11271181
11281182 return proto_node;
11291183 }
1130 case clang::Type::Record:
1184 case ZigClangType_Record:
11311185 {
1132 const clang::RecordType *record_ty = static_cast<const clang::RecordType*>(ty);
1133 return resolve_record_decl(c, record_ty->getDecl());
1186 const ZigClangRecordType *record_ty = reinterpret_cast<const ZigClangRecordType*>(ty);
1187 return resolve_record_decl(c, ZigClangRecordType_getDecl(record_ty));
11341188 }
1135 case clang::Type::Enum:
1189 case ZigClangType_Enum:
11361190 {
1137 const clang::EnumType *enum_ty = static_cast<const clang::EnumType*>(ty);
1138 return resolve_enum_decl(c, enum_ty->getDecl());
1191 const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType*>(ty);
1192 return resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
11391193 }
1140 case clang::Type::ConstantArray:
1194 case ZigClangType_ConstantArray:
11411195 {
1142 const clang::ConstantArrayType *const_arr_ty = static_cast<const clang::ConstantArrayType *>(ty);
1143 AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
1196 const clang::ConstantArrayType *const_arr_ty = reinterpret_cast<const clang::ConstantArrayType *>(ty);
1197 AstNode *child_type_node = trans_qual_type(c, bitcast(const_arr_ty->getElementType()), source_loc);
11441198 if (child_type_node == nullptr) {
11451199 emit_warning(c, source_loc, "unresolved array element type");
11461200 return nullptr;
......@@ -1149,83 +1203,87 @@ static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::Sourc
11491203 AstNode *size_node = trans_create_node_unsigned(c, size);
11501204 return trans_create_node_array_type(c, size_node, child_type_node);
11511205 }
1152 case clang::Type::Paren:
1206 case ZigClangType_Paren:
11531207 {
1154 const clang::ParenType *paren_ty = static_cast<const clang::ParenType *>(ty);
1155 return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
1208 const clang::ParenType *paren_ty = reinterpret_cast<const clang::ParenType *>(ty);
1209 return trans_qual_type(c, bitcast(paren_ty->getInnerType()), source_loc);
11561210 }
1157 case clang::Type::Decayed:
1211 case ZigClangType_Decayed:
11581212 {
1159 const clang::DecayedType *decayed_ty = static_cast<const clang::DecayedType *>(ty);
1160 return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
1213 const clang::DecayedType *decayed_ty = reinterpret_cast<const clang::DecayedType *>(ty);
1214 return trans_qual_type(c, bitcast(decayed_ty->getDecayedType()), source_loc);
11611215 }
1162 case clang::Type::Attributed:
1216 case ZigClangType_Attributed:
11631217 {
1164 const clang::AttributedType *attributed_ty = static_cast<const clang::AttributedType *>(ty);
1165 return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
1218 const clang::AttributedType *attributed_ty = reinterpret_cast<const clang::AttributedType *>(ty);
1219 return trans_qual_type(c, bitcast(attributed_ty->getEquivalentType()), source_loc);
11661220 }
1167 case clang::Type::IncompleteArray:
1221 case ZigClangType_IncompleteArray:
11681222 {
1169 const clang::IncompleteArrayType *incomplete_array_ty = static_cast<const clang::IncompleteArrayType *>(ty);
1170 clang::QualType child_qt = incomplete_array_ty->getElementType();
1223 const clang::IncompleteArrayType *incomplete_array_ty = reinterpret_cast<const clang::IncompleteArrayType *>(ty);
1224 ZigClangQualType child_qt = bitcast(incomplete_array_ty->getElementType());
11711225 AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc);
11721226 if (child_type_node == nullptr) {
11731227 emit_warning(c, source_loc, "unresolved array element type");
11741228 return nullptr;
11751229 }
1176 AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
1177 child_qt.isVolatileQualified(), child_type_node, PtrLenC);
1230 AstNode *pointer_node = trans_create_node_ptr_type(c,
1231 ZigClangQualType_isConstQualified(child_qt),
1232 ZigClangQualType_isVolatileQualified(child_qt),
1233 child_type_node, PtrLenC);
11781234 return pointer_node;
11791235 }
1180 case clang::Type::BlockPointer:
1181 case clang::Type::LValueReference:
1182 case clang::Type::RValueReference:
1183 case clang::Type::MemberPointer:
1184 case clang::Type::VariableArray:
1185 case clang::Type::DependentSizedArray:
1186 case clang::Type::DependentSizedExtVector:
1187 case clang::Type::Vector:
1188 case clang::Type::ExtVector:
1189 case clang::Type::UnresolvedUsing:
1190 case clang::Type::Adjusted:
1191 case clang::Type::TypeOfExpr:
1192 case clang::Type::TypeOf:
1193 case clang::Type::Decltype:
1194 case clang::Type::UnaryTransform:
1195 case clang::Type::TemplateTypeParm:
1196 case clang::Type::SubstTemplateTypeParm:
1197 case clang::Type::SubstTemplateTypeParmPack:
1198 case clang::Type::TemplateSpecialization:
1199 case clang::Type::Auto:
1200 case clang::Type::InjectedClassName:
1201 case clang::Type::DependentName:
1202 case clang::Type::DependentTemplateSpecialization:
1203 case clang::Type::PackExpansion:
1204 case clang::Type::ObjCObject:
1205 case clang::Type::ObjCInterface:
1206 case clang::Type::Complex:
1207 case clang::Type::ObjCObjectPointer:
1208 case clang::Type::Atomic:
1209 case clang::Type::Pipe:
1210 case clang::Type::ObjCTypeParam:
1211 case clang::Type::DeducedTemplateSpecialization:
1212 case clang::Type::DependentAddressSpace:
1213 case clang::Type::DependentVector:
1214 emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
1236 case ZigClangType_BlockPointer:
1237 case ZigClangType_LValueReference:
1238 case ZigClangType_RValueReference:
1239 case ZigClangType_MemberPointer:
1240 case ZigClangType_VariableArray:
1241 case ZigClangType_DependentSizedArray:
1242 case ZigClangType_DependentSizedExtVector:
1243 case ZigClangType_Vector:
1244 case ZigClangType_ExtVector:
1245 case ZigClangType_UnresolvedUsing:
1246 case ZigClangType_Adjusted:
1247 case ZigClangType_TypeOfExpr:
1248 case ZigClangType_TypeOf:
1249 case ZigClangType_Decltype:
1250 case ZigClangType_UnaryTransform:
1251 case ZigClangType_TemplateTypeParm:
1252 case ZigClangType_SubstTemplateTypeParm:
1253 case ZigClangType_SubstTemplateTypeParmPack:
1254 case ZigClangType_TemplateSpecialization:
1255 case ZigClangType_Auto:
1256 case ZigClangType_InjectedClassName:
1257 case ZigClangType_DependentName:
1258 case ZigClangType_DependentTemplateSpecialization:
1259 case ZigClangType_PackExpansion:
1260 case ZigClangType_ObjCObject:
1261 case ZigClangType_ObjCInterface:
1262 case ZigClangType_Complex:
1263 case ZigClangType_ObjCObjectPointer:
1264 case ZigClangType_Atomic:
1265 case ZigClangType_Pipe:
1266 case ZigClangType_ObjCTypeParam:
1267 case ZigClangType_DeducedTemplateSpecialization:
1268 case ZigClangType_DependentAddressSpace:
1269 case ZigClangType_DependentVector:
1270 emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty));
12151271 return nullptr;
12161272 }
12171273 zig_unreachable();
12181274}
12191275
1220static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc) {
1221 return trans_type(c, qt.getTypePtr(), source_loc);
1276static AstNode *trans_qual_type(Context *c, ZigClangQualType qt, ZigClangSourceLocation source_loc) {
1277 return trans_type(c, ZigClangQualType_getTypePtr(qt), source_loc);
12221278}
12231279
1224static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
1280static int trans_compound_stmt_inline(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
12251281 AstNode *block_node, TransScope **out_node_scope)
12261282{
12271283 assert(block_node->type == NodeTypeBlock);
1228 for (clang::CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
1284 for (ZigClangCompoundStmt_const_body_iterator it = ZigClangCompoundStmt_body_begin(stmt),
1285 end_it = ZigClangCompoundStmt_body_end(stmt); it != end_it; ++it)
1286 {
12291287 AstNode *child_node;
12301288 scope = trans_stmt(c, scope, *it, &child_node);
12311289 if (scope == nullptr)
......@@ -1239,7 +1297,7 @@ static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang
12391297 return ErrorNone;
12401298}
12411299
1242static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
1300static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const ZigClangCompoundStmt *stmt,
12431301 TransScope **out_node_scope)
12441302{
12451303 TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
......@@ -1251,7 +1309,7 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::
12511309static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope,
12521310 const clang::StmtExpr *stmt, TransScope **out_node_scope)
12531311{
1254 AstNode *block = trans_compound_stmt(c, scope, stmt->getSubStmt(), out_node_scope);
1312 AstNode *block = trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt->getSubStmt(), out_node_scope);
12551313 if (block == nullptr)
12561314 return block;
12571315 assert(block->type == NodeTypeBlock);
......@@ -1274,7 +1332,7 @@ static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *
12741332}
12751333
12761334static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {
1277 const clang::Expr *value_expr = stmt->getRetValue();
1335 const ZigClangExpr *value_expr = bitcast(stmt->getRetValue());
12781336 if (value_expr == nullptr) {
12791337 return trans_create_node(c, NodeTypeReturnExpr);
12801338 } else {
......@@ -1289,22 +1347,62 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re
12891347static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) {
12901348 clang::Expr::EvalResult result;
12911349 if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
1292 emit_warning(c, stmt->getBeginLoc(), "invalid integer literal");
1350 emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid integer literal");
1351 return nullptr;
1352 }
1353 AstNode *node = trans_create_node_apint(c, bitcast(&result.Val.getInt()));
1354 return maybe_suppress_result(c, result_used, node);
1355}
1356
1357static AstNode *trans_floating_literal(Context *c, ResultUsed result_used, const clang::FloatingLiteral *stmt) {
1358 llvm::APFloat result{0.0f};
1359 if (!stmt->EvaluateAsFloat(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
1360 emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid floating literal");
12931361 return nullptr;
12941362 }
1295 AstNode *node = trans_create_node_apint(c, result.Val.getInt());
1363 AstNode *node = trans_create_node_apfloat(c, result);
12961364 return maybe_suppress_result(c, result_used, node);
12971365}
12981366
1367static AstNode *trans_character_literal(Context *c, ResultUsed result_used, const clang::CharacterLiteral *stmt) {
1368 switch (stmt->getKind()) {
1369 case clang::CharacterLiteral::CharacterKind::Ascii:
1370 {
1371 unsigned val = stmt->getValue();
1372 // C has a somewhat obscure feature called multi-character character
1373 // constant
1374 if (val > 255)
1375 return trans_create_node_unsigned(c, val);
1376 }
1377 // fallthrough
1378 case clang::CharacterLiteral::CharacterKind::UTF8:
1379 {
1380 AstNode *node = trans_create_node(c, NodeTypeCharLiteral);
1381 node->data.char_literal.value = stmt->getValue();
1382 return maybe_suppress_result(c, result_used, node);
1383 }
1384 case clang::CharacterLiteral::CharacterKind::UTF16:
1385 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 character literals");
1386 return nullptr;
1387 case clang::CharacterLiteral::CharacterKind::UTF32:
1388 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 character literals");
1389 return nullptr;
1390 case clang::CharacterLiteral::CharacterKind::Wide:
1391 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide character literals");
1392 return nullptr;
1393 }
1394 zig_unreachable();
1395}
1396
12991397static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const clang::ConstantExpr *expr) {
13001398 clang::Expr::EvalResult result;
13011399 if (!expr->EvaluateAsConstantExpr(result, clang::Expr::EvaluateForCodeGen,
13021400 *reinterpret_cast<clang::ASTContext *>(c->ctx)))
13031401 {
1304 emit_warning(c, expr->getBeginLoc(), "invalid constant expression");
1402 emit_warning(c, bitcast(expr->getBeginLoc()), "invalid constant expression");
13051403 return nullptr;
13061404 }
1307 AstNode *node = trans_ap_value(c, &result.Val, expr->getType(), expr->getBeginLoc());
1405 AstNode *node = trans_ap_value(c, bitcast(&result.Val), bitcast(expr->getType()), bitcast(expr->getBeginLoc()));
13081406 return maybe_suppress_result(c, result_used, node);
13091407}
13101408
......@@ -1313,9 +1411,9 @@ static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, T
13131411{
13141412 AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
13151413
1316 clang::Expr *cond_expr = stmt->getCond();
1317 clang::Expr *true_expr = stmt->getTrueExpr();
1318 clang::Expr *false_expr = stmt->getFalseExpr();
1414 const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
1415 const ZigClangExpr *true_expr = bitcast(stmt->getTrueExpr());
1416 const ZigClangExpr *false_expr = bitcast(stmt->getFalseExpr());
13191417
13201418 node->data.if_bool_expr.condition = trans_expr(c, ResultUsedYes, scope, cond_expr, TransRValue);
13211419 if (node->data.if_bool_expr.condition == nullptr)
......@@ -1332,7 +1430,9 @@ static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, T
13321430 return maybe_suppress_result(c, result_used, node);
13331431}
13341432
1335static AstNode *trans_create_bin_op(Context *c, TransScope *scope, clang::Expr *lhs, BinOpType bin_op, clang::Expr *rhs) {
1433static AstNode *trans_create_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
1434 BinOpType bin_op, const ZigClangExpr *rhs)
1435{
13361436 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
13371437 node->data.bin_op_expr.bin_op = bin_op;
13381438
......@@ -1347,7 +1447,9 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, clang::Expr *
13471447 return node;
13481448}
13491449
1350static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, clang::Expr *lhs, BinOpType bin_op, clang::Expr *rhs) {
1450static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, const ZigClangExpr *lhs,
1451 BinOpType bin_op, const ZigClangExpr *rhs)
1452{
13511453 assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr);
13521454 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
13531455 node->data.bin_op_expr.bin_op = bin_op;
......@@ -1363,7 +1465,9 @@ static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, clang::E
13631465 return node;
13641466}
13651467
1366static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, clang::Expr *lhs, clang::Expr *rhs) {
1468static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope,
1469 const ZigClangExpr *lhs, const ZigClangExpr *rhs)
1470{
13671471 if (result_used == ResultUsedNo) {
13681472 // common case
13691473 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
......@@ -1414,10 +1518,10 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco
14141518 }
14151519}
14161520
1417static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::QualType result_type,
1418 clang::Expr *lhs_expr, BinOpType bin_op, clang::Expr *rhs_expr)
1521static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQualType result_type,
1522 const ZigClangExpr *lhs_expr, BinOpType bin_op, const ZigClangExpr *rhs_expr)
14191523{
1420 const clang::SourceLocation &rhs_location = rhs_expr->getBeginLoc();
1524 ZigClangSourceLocation rhs_location = ZigClangExpr_getBeginLoc(rhs_expr);
14211525 AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
14221526 // lhs >> u5(rh)
14231527
......@@ -1434,130 +1538,130 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::Qual
14341538static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::BinaryOperator *stmt) {
14351539 switch (stmt->getOpcode()) {
14361540 case clang::BO_PtrMemD:
1437 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemD");
1541 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemD");
14381542 return nullptr;
14391543 case clang::BO_PtrMemI:
1440 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_PtrMemI");
1544 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_PtrMemI");
14411545 return nullptr;
14421546 case clang::BO_Cmp:
1443 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C binary operators: BO_Cmp");
1547 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C binary operators: BO_Cmp");
14441548 return nullptr;
14451549 case clang::BO_Mul: {
1446 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1447 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
1448 stmt->getRHS());
1550 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1551 qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeMultWrap : BinOpTypeMult,
1552 bitcast(stmt->getRHS()));
14491553 return maybe_suppress_result(c, result_used, node);
14501554 }
14511555 case clang::BO_Div:
1452 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1556 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) {
14531557 // unsigned/float division uses the operator
1454 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
1558 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeDiv, bitcast(stmt->getRHS()));
14551559 return maybe_suppress_result(c, result_used, node);
14561560 } else {
14571561 // signed integer division uses @divTrunc
14581562 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
1459 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1563 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
14601564 if (lhs == nullptr) return nullptr;
14611565 fn_call->data.fn_call_expr.params.append(lhs);
1462 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
1566 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransLValue);
14631567 if (rhs == nullptr) return nullptr;
14641568 fn_call->data.fn_call_expr.params.append(rhs);
14651569 return maybe_suppress_result(c, result_used, fn_call);
14661570 }
14671571 case clang::BO_Rem:
1468 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1572 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType()))) {
14691573 // unsigned/float division uses the operator
1470 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
1574 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeMod, bitcast(stmt->getRHS()));
14711575 return maybe_suppress_result(c, result_used, node);
14721576 } else {
14731577 // signed integer division uses @rem
14741578 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
1475 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1579 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
14761580 if (lhs == nullptr) return nullptr;
14771581 fn_call->data.fn_call_expr.params.append(lhs);
1478 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
1582 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransLValue);
14791583 if (rhs == nullptr) return nullptr;
14801584 fn_call->data.fn_call_expr.params.append(rhs);
14811585 return maybe_suppress_result(c, result_used, fn_call);
14821586 }
14831587 case clang::BO_Add: {
1484 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1485 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
1486 stmt->getRHS());
1588 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1589 qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeAddWrap : BinOpTypeAdd,
1590 bitcast(stmt->getRHS()));
14871591 return maybe_suppress_result(c, result_used, node);
14881592 }
14891593 case clang::BO_Sub: {
1490 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1491 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
1492 stmt->getRHS());
1594 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()),
1595 qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())) ? BinOpTypeSubWrap : BinOpTypeSub,
1596 bitcast(stmt->getRHS()));
14931597 return maybe_suppress_result(c, result_used, node);
14941598 }
14951599 case clang::BO_Shl: {
1496 AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());
1600 AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), bitcast(stmt->getLHS()), BinOpTypeBitShiftLeft, bitcast(stmt->getRHS()));
14971601 return maybe_suppress_result(c, result_used, node);
14981602 }
14991603 case clang::BO_Shr: {
1500 AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());
1604 AstNode *node = trans_create_shift_op(c, scope, bitcast(stmt->getType()), bitcast(stmt->getLHS()), BinOpTypeBitShiftRight, bitcast(stmt->getRHS()));
15011605 return maybe_suppress_result(c, result_used, node);
15021606 }
15031607 case clang::BO_LT: {
1504 AstNode *node =trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
1608 AstNode *node =trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpLessThan, bitcast(stmt->getRHS()));
15051609 return maybe_suppress_result(c, result_used, node);
15061610 }
15071611 case clang::BO_GT: {
1508 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
1612 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpGreaterThan, bitcast(stmt->getRHS()));
15091613 return maybe_suppress_result(c, result_used, node);
15101614 }
15111615 case clang::BO_LE: {
1512 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
1616 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpLessOrEq, bitcast(stmt->getRHS()));
15131617 return maybe_suppress_result(c, result_used, node);
15141618 }
15151619 case clang::BO_GE: {
1516 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
1620 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpGreaterOrEq, bitcast(stmt->getRHS()));
15171621 return maybe_suppress_result(c, result_used, node);
15181622 }
15191623 case clang::BO_EQ: {
1520 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());
1624 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpEq, bitcast(stmt->getRHS()));
15211625 return maybe_suppress_result(c, result_used, node);
15221626 }
15231627 case clang::BO_NE: {
1524 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());
1628 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeCmpNotEq, bitcast(stmt->getRHS()));
15251629 return maybe_suppress_result(c, result_used, node);
15261630 }
15271631 case clang::BO_And: {
1528 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());
1632 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinAnd, bitcast(stmt->getRHS()));
15291633 return maybe_suppress_result(c, result_used, node);
15301634 }
15311635 case clang::BO_Xor: {
1532 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());
1636 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinXor, bitcast(stmt->getRHS()));
15331637 return maybe_suppress_result(c, result_used, node);
15341638 }
15351639 case clang::BO_Or: {
1536 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
1640 AstNode *node = trans_create_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBinOr, bitcast(stmt->getRHS()));
15371641 return maybe_suppress_result(c, result_used, node);
15381642 }
15391643 case clang::BO_LAnd: {
1540 AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
1644 AstNode *node = trans_create_bool_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBoolAnd, bitcast(stmt->getRHS()));
15411645 return maybe_suppress_result(c, result_used, node);
15421646 }
15431647 case clang::BO_LOr: {
1544 AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1648 AstNode *node = trans_create_bool_bin_op(c, scope, bitcast(stmt->getLHS()), BinOpTypeBoolOr, bitcast(stmt->getRHS()));
15451649 return maybe_suppress_result(c, result_used, node);
15461650 }
15471651 case clang::BO_Assign:
1548 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
1652 return trans_create_assign(c, result_used, scope, bitcast(stmt->getLHS()), bitcast(stmt->getRHS()));
15491653 case clang::BO_Comma:
15501654 {
15511655 TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
15521656 Buf *label_name = buf_create_from_str("x");
15531657 scope_block->node->data.block.name = label_name;
15541658
1555 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);
1659 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, bitcast(stmt->getLHS()), TransRValue);
15561660 if (lhs == nullptr)
15571661 return nullptr;
15581662 scope_block->node->data.block.statements.append(lhs);
15591663
1560 AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, stmt->getRHS(), TransRValue);
1664 AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, bitcast(stmt->getRHS()), TransRValue);
15611665 if (rhs == nullptr)
15621666 return nullptr;
15631667
......@@ -1584,17 +1688,17 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
15841688static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
15851689 const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
15861690{
1587 const clang::SourceLocation &rhs_location = stmt->getRHS()->getBeginLoc();
1588 AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
1691 ZigClangSourceLocation rhs_location = bitcast(stmt->getRHS()->getBeginLoc());
1692 AstNode *rhs_type = qual_type_to_log2_int_ref(c, bitcast(stmt->getComputationLHSType()), rhs_location);
15891693
15901694 bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();
15911695 if (!use_intermediate_casts && result_used == ResultUsedNo) {
15921696 // simple common case, where the C and Zig are identical:
15931697 // lhs >>= rhs
1594 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1698 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
15951699 if (lhs == nullptr) return nullptr;
15961700
1597 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransRValue);
1701 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransRValue);
15981702 if (rhs == nullptr) return nullptr;
15991703 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
16001704
......@@ -1614,7 +1718,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
16141718 child_scope->node->data.block.name = label_name;
16151719
16161720 // const _ref = &lhs;
1617 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
1721 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getLHS()), TransLValue);
16181722 if (lhs == nullptr) return nullptr;
16191723 AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
16201724 // TODO: avoid name collisions with generated variable names
......@@ -1624,20 +1728,20 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
16241728
16251729 // *_ref = result_type(operation_type(*_ref) >> u5(rhs));
16261730
1627 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getRHS(), TransRValue);
1731 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getRHS()), TransRValue);
16281732 if (rhs == nullptr) return nullptr;
16291733 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);
16301734
16311735 // operation_type(*_ref)
16321736 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
1633 stmt->getComputationLHSType(),
1634 stmt->getLHS()->getType(),
1737 bitcast(stmt->getComputationLHSType()),
1738 bitcast(stmt->getLHS()->getType()),
16351739 trans_create_node_ptr_deref(c, trans_create_node_symbol(c, tmp_var_name)));
16361740
16371741 // result_type(... >> u5(rhs))
16381742 AstNode *result_type_cast = trans_c_cast(c, rhs_location,
1639 stmt->getComputationResultType(),
1640 stmt->getComputationLHSType(),
1743 bitcast(stmt->getComputationResultType()),
1744 bitcast(stmt->getComputationLHSType()),
16411745 trans_create_node_bin_op(c,
16421746 operation_type_cast,
16431747 bin_op,
......@@ -1669,9 +1773,9 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
16691773 if (result_used == ResultUsedNo) {
16701774 // simple common case, where the C and Zig are identical:
16711775 // lhs += rhs
1672 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, stmt->getLHS(), TransLValue);
1776 AstNode *lhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getLHS()), TransLValue);
16731777 if (lhs == nullptr) return nullptr;
1674 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransRValue);
1778 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getRHS()), TransRValue);
16751779 if (rhs == nullptr) return nullptr;
16761780 return trans_create_node_bin_op(c, lhs, assign_op, rhs);
16771781 } else {
......@@ -1688,7 +1792,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
16881792 child_scope->node->data.block.name = label_name;
16891793
16901794 // const _ref = &lhs;
1691 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getLHS(), TransLValue);
1795 AstNode *lhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getLHS()), TransLValue);
16921796 if (lhs == nullptr) return nullptr;
16931797 AstNode *addr_of_lhs = trans_create_node_addr_of(c, lhs);
16941798 // TODO: avoid name collisions with generated variable names
......@@ -1698,7 +1802,7 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
16981802
16991803 // *_ref = *_ref + rhs;
17001804
1701 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, stmt->getRHS(), TransRValue);
1805 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, bitcast(stmt->getRHS()), TransRValue);
17021806 if (rhs == nullptr) return nullptr;
17031807
17041808 AstNode *assign_statement = trans_create_node_bin_op(c,
......@@ -1728,26 +1832,26 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use
17281832{
17291833 switch (stmt->getOpcode()) {
17301834 case clang::BO_MulAssign:
1731 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1835 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
17321836 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
17331837 else
17341838 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
17351839 case clang::BO_DivAssign:
1736 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_DivAssign");
1840 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_DivAssign");
17371841 return nullptr;
17381842 case clang::BO_RemAssign:
1739 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_RemAssign");
1843 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_RemAssign");
17401844 return nullptr;
17411845 case clang::BO_Cmp:
1742 emit_warning(c, stmt->getBeginLoc(), "TODO handle more C compound assign operators: BO_Cmp");
1846 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle more C compound assign operators: BO_Cmp");
17431847 return nullptr;
17441848 case clang::BO_AddAssign:
1745 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1849 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
17461850 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
17471851 else
17481852 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
17491853 case clang::BO_SubAssign:
1750 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
1854 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
17511855 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
17521856 else
17531857 return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
......@@ -1790,202 +1894,265 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use
17901894}
17911895
17921896static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ImplicitCastExpr *stmt) {
1793 switch (stmt->getCastKind()) {
1794 case clang::CK_LValueToRValue:
1795 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1796 case clang::CK_IntegralCast:
1897 switch ((ZigClangCK)stmt->getCastKind()) {
1898 case ZigClangCK_LValueToRValue:
1899 return trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1900 case ZigClangCK_IntegralCast:
17971901 {
1798 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1902 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
17991903 if (target_node == nullptr)
18001904 return nullptr;
1801 AstNode *node = trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),
1802 stmt->getSubExpr()->getType(), target_node);
1905 AstNode *node = trans_c_cast(c, bitcast(stmt->getExprLoc()), bitcast(stmt->getType()),
1906 bitcast(stmt->getSubExpr()->getType()), target_node);
18031907 return maybe_suppress_result(c, result_used, node);
18041908 }
1805 case clang::CK_FunctionToPointerDecay:
1806 case clang::CK_ArrayToPointerDecay:
1909 case ZigClangCK_FunctionToPointerDecay:
1910 case ZigClangCK_ArrayToPointerDecay:
18071911 {
1808 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1912 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
18091913 if (target_node == nullptr)
18101914 return nullptr;
18111915 return maybe_suppress_result(c, result_used, target_node);
18121916 }
1813 case clang::CK_BitCast:
1917 case ZigClangCK_BitCast:
18141918 {
1815 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1919 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
18161920 if (target_node == nullptr)
18171921 return nullptr;
18181922
1819 if (expr_types_equal(c, stmt, stmt->getSubExpr())) {
1820 return target_node;
1821 }
1923 const ZigClangQualType dest_type = get_expr_qual_type(c, bitcast(stmt));
1924 const ZigClangQualType src_type = get_expr_qual_type(c, bitcast(stmt->getSubExpr()));
18221925
1823 AstNode *dest_type_node = get_expr_type(c, stmt);
1824
1825 AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
1826 node->data.fn_call_expr.params.append(dest_type_node);
1827 node->data.fn_call_expr.params.append(target_node);
1828 return maybe_suppress_result(c, result_used, node);
1926 return trans_c_cast(c, bitcast(stmt->getBeginLoc()), dest_type, src_type, target_node);
18291927 }
1830 case clang::CK_NullToPointer:
1831 return trans_create_node_unsigned(c, 0);
1832 case clang::CK_NoOp:
1833 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1834 case clang::CK_Dependent:
1835 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dependent");
1836 return nullptr;
1837 case clang::CK_LValueBitCast:
1838 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_LValueBitCast");
1839 return nullptr;
1840 case clang::CK_BaseToDerived:
1841 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerived");
1842 return nullptr;
1843 case clang::CK_DerivedToBase:
1844 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBase");
1845 return nullptr;
1846 case clang::CK_UncheckedDerivedToBase:
1847 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UncheckedDerivedToBase");
1928 case ZigClangCK_NullToPointer:
1929 return trans_create_node(c, NodeTypeNullLiteral);
1930 case ZigClangCK_NoOp:
1931 return trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
1932 case ZigClangCK_Dependent:
1933 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dependent");
18481934 return nullptr;
1849 case clang::CK_Dynamic:
1850 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_Dynamic");
1935 case ZigClangCK_LValueBitCast:
1936 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_LValueBitCast");
18511937 return nullptr;
1852 case clang::CK_ToUnion:
1853 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ToUnion");
1938 case ZigClangCK_BaseToDerived:
1939 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerived");
18541940 return nullptr;
1855 case clang::CK_NullToMemberPointer:
1856 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_NullToMemberPointer");
1941 case ZigClangCK_DerivedToBase:
1942 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBase");
18571943 return nullptr;
1858 case clang::CK_BaseToDerivedMemberPointer:
1859 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
1944 case ZigClangCK_UncheckedDerivedToBase:
1945 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UncheckedDerivedToBase");
18601946 return nullptr;
1861 case clang::CK_DerivedToBaseMemberPointer:
1862 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
1947 case ZigClangCK_Dynamic:
1948 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_Dynamic");
18631949 return nullptr;
1864 case clang::CK_MemberPointerToBoolean:
1865 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_MemberPointerToBoolean");
1950 case ZigClangCK_ToUnion:
1951 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ToUnion");
18661952 return nullptr;
1867 case clang::CK_ReinterpretMemberPointer:
1868 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_ReinterpretMemberPointer");
1953 case ZigClangCK_NullToMemberPointer:
1954 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_NullToMemberPointer");
18691955 return nullptr;
1870 case clang::CK_UserDefinedConversion:
1871 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation cast CK_UserDefinedConversion");
1956 case ZigClangCK_BaseToDerivedMemberPointer:
1957 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
18721958 return nullptr;
1873 case clang::CK_ConstructorConversion:
1874 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ConstructorConversion");
1959 case ZigClangCK_DerivedToBaseMemberPointer:
1960 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
18751961 return nullptr;
1876 case clang::CK_IntegralToPointer:
1877 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToPointer");
1962 case ZigClangCK_MemberPointerToBoolean:
1963 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_MemberPointerToBoolean");
18781964 return nullptr;
1879 case clang::CK_PointerToIntegral:
1880 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToIntegral");
1965 case ZigClangCK_ReinterpretMemberPointer:
1966 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_ReinterpretMemberPointer");
18811967 return nullptr;
1882 case clang::CK_PointerToBoolean:
1883 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_PointerToBoolean");
1968 case ZigClangCK_UserDefinedConversion:
1969 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation cast CK_UserDefinedConversion");
18841970 return nullptr;
1885 case clang::CK_ToVoid:
1886 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ToVoid");
1971 case ZigClangCK_ConstructorConversion:
1972 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ConstructorConversion");
18871973 return nullptr;
1888 case clang::CK_VectorSplat:
1889 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_VectorSplat");
1890 return nullptr;
1891 case clang::CK_IntegralToBoolean:
1892 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToBoolean");
1893 return nullptr;
1894 case clang::CK_IntegralToFloating:
1895 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralToFloating");
1974 case ZigClangCK_PointerToBoolean:
1975 {
1976 const clang::Expr *expr = stmt->getSubExpr();
1977 AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue);
1978 if (val == nullptr)
1979 return nullptr;
1980
1981 AstNode *val_ptr = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
1982 val_ptr->data.fn_call_expr.params.append(val);
1983
1984 AstNode *zero = trans_create_node_unsigned(c, 0);
1985
1986 // Translate as @ptrToInt((&val) != 0)
1987 return trans_create_node_bin_op(c, val_ptr, BinOpTypeCmpNotEq, zero);
1988 }
1989 case ZigClangCK_ToVoid:
1990 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ToVoid");
18961991 return nullptr;
1897 case clang::CK_FixedPointCast:
1898 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointCast");
1992 case ZigClangCK_VectorSplat:
1993 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_VectorSplat");
18991994 return nullptr;
1900 case clang::CK_FixedPointToBoolean:
1901 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FixedPointToBoolean");
1995 case ZigClangCK_IntegralToBoolean:
1996 {
1997 const clang::Expr *expr = stmt->getSubExpr();
1998
1999 bool expr_val;
2000 if (expr->EvaluateAsBooleanCondition(expr_val, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
2001 return trans_create_node_bool(c, expr_val);
2002 }
2003
2004 AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue);
2005 if (val == nullptr)
2006 return nullptr;
2007
2008 AstNode *zero = trans_create_node_unsigned(c, 0);
2009
2010 // Translate as val != 0
2011 return trans_create_node_bin_op(c, val, BinOpTypeCmpNotEq, zero);
2012 }
2013 case ZigClangCK_PointerToIntegral:
2014 {
2015 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2016 if (target_node == nullptr)
2017 return nullptr;
2018
2019 AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2020 if (dest_type_node == nullptr)
2021 return nullptr;
2022
2023 AstNode *val_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
2024 val_node->data.fn_call_expr.params.append(target_node);
2025 // @ptrToInt always returns a usize
2026 AstNode *node = trans_create_node_builtin_fn_call_str(c, "intCast");
2027 node->data.fn_call_expr.params.append(dest_type_node);
2028 node->data.fn_call_expr.params.append(val_node);
2029
2030 return maybe_suppress_result(c, result_used, node);
2031 }
2032 case ZigClangCK_IntegralToPointer:
2033 {
2034 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2035 if (target_node == nullptr)
2036 return nullptr;
2037
2038 AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2039 if (dest_type_node == nullptr)
2040 return nullptr;
2041
2042 AstNode *node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
2043 node->data.fn_call_expr.params.append(dest_type_node);
2044 node->data.fn_call_expr.params.append(target_node);
2045
2046 return maybe_suppress_result(c, result_used, node);
2047 }
2048 case ZigClangCK_IntegralToFloating:
2049 case ZigClangCK_FloatingToIntegral:
2050 {
2051 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue);
2052 if (target_node == nullptr)
2053 return nullptr;
2054
2055 AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt);
2056 if (dest_type_node == nullptr)
2057 return nullptr;
2058
2059 char const *fn = (ZigClangCK)stmt->getCastKind() == ZigClangCK_IntegralToFloating ?
2060 "intToFloat" : "floatToInt";
2061 AstNode *node = trans_create_node_builtin_fn_call_str(c, fn);
2062 node->data.fn_call_expr.params.append(dest_type_node);
2063 node->data.fn_call_expr.params.append(target_node);
2064
2065 return maybe_suppress_result(c, result_used, node);
2066 }
2067 case ZigClangCK_FixedPointCast:
2068 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointCast");
19022069 return nullptr;
1903 case clang::CK_FloatingToIntegral:
1904 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToIntegral");
2070 case ZigClangCK_FixedPointToBoolean:
2071 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointToBoolean");
19052072 return nullptr;
1906 case clang::CK_FloatingToBoolean:
1907 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingToBoolean");
2073 case ZigClangCK_FloatingToBoolean:
2074 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToBoolean");
19082075 return nullptr;
1909 case clang::CK_BooleanToSignedIntegral:
1910 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BooleanToSignedIntegral");
2076 case ZigClangCK_BooleanToSignedIntegral:
2077 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BooleanToSignedIntegral");
19112078 return nullptr;
1912 case clang::CK_FloatingCast:
1913 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingCast");
2079 case ZigClangCK_FloatingCast:
2080 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingCast");
19142081 return nullptr;
1915 case clang::CK_CPointerToObjCPointerCast:
1916 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CPointerToObjCPointerCast");
2082 case ZigClangCK_CPointerToObjCPointerCast:
2083 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CPointerToObjCPointerCast");
19172084 return nullptr;
1918 case clang::CK_BlockPointerToObjCPointerCast:
1919 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BlockPointerToObjCPointerCast");
2085 case ZigClangCK_BlockPointerToObjCPointerCast:
2086 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BlockPointerToObjCPointerCast");
19202087 return nullptr;
1921 case clang::CK_AnyPointerToBlockPointerCast:
1922 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AnyPointerToBlockPointerCast");
2088 case ZigClangCK_AnyPointerToBlockPointerCast:
2089 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AnyPointerToBlockPointerCast");
19232090 return nullptr;
1924 case clang::CK_ObjCObjectLValueCast:
1925 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ObjCObjectLValueCast");
2091 case ZigClangCK_ObjCObjectLValueCast:
2092 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ObjCObjectLValueCast");
19262093 return nullptr;
1927 case clang::CK_FloatingRealToComplex:
1928 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingRealToComplex");
2094 case ZigClangCK_FloatingRealToComplex:
2095 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingRealToComplex");
19292096 return nullptr;
1930 case clang::CK_FloatingComplexToReal:
1931 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToReal");
2097 case ZigClangCK_FloatingComplexToReal:
2098 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToReal");
19322099 return nullptr;
1933 case clang::CK_FloatingComplexToBoolean:
1934 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToBoolean");
2100 case ZigClangCK_FloatingComplexToBoolean:
2101 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToBoolean");
19352102 return nullptr;
1936 case clang::CK_FloatingComplexCast:
1937 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexCast");
2103 case ZigClangCK_FloatingComplexCast:
2104 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexCast");
19382105 return nullptr;
1939 case clang::CK_FloatingComplexToIntegralComplex:
1940 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_FloatingComplexToIntegralComplex");
2106 case ZigClangCK_FloatingComplexToIntegralComplex:
2107 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingComplexToIntegralComplex");
19412108 return nullptr;
1942 case clang::CK_IntegralRealToComplex:
1943 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralRealToComplex");
2109 case ZigClangCK_IntegralRealToComplex:
2110 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralRealToComplex");
19442111 return nullptr;
1945 case clang::CK_IntegralComplexToReal:
1946 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToReal");
2112 case ZigClangCK_IntegralComplexToReal:
2113 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToReal");
19472114 return nullptr;
1948 case clang::CK_IntegralComplexToBoolean:
1949 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToBoolean");
2115 case ZigClangCK_IntegralComplexToBoolean:
2116 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToBoolean");
19502117 return nullptr;
1951 case clang::CK_IntegralComplexCast:
1952 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexCast");
2118 case ZigClangCK_IntegralComplexCast:
2119 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexCast");
19532120 return nullptr;
1954 case clang::CK_IntegralComplexToFloatingComplex:
1955 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntegralComplexToFloatingComplex");
2121 case ZigClangCK_IntegralComplexToFloatingComplex:
2122 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralComplexToFloatingComplex");
19562123 return nullptr;
1957 case clang::CK_ARCProduceObject:
1958 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCProduceObject");
2124 case ZigClangCK_ARCProduceObject:
2125 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCProduceObject");
19592126 return nullptr;
1960 case clang::CK_ARCConsumeObject:
1961 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCConsumeObject");
2127 case ZigClangCK_ARCConsumeObject:
2128 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCConsumeObject");
19622129 return nullptr;
1963 case clang::CK_ARCReclaimReturnedObject:
1964 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCReclaimReturnedObject");
2130 case ZigClangCK_ARCReclaimReturnedObject:
2131 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCReclaimReturnedObject");
19652132 return nullptr;
1966 case clang::CK_ARCExtendBlockObject:
1967 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ARCExtendBlockObject");
2133 case ZigClangCK_ARCExtendBlockObject:
2134 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ARCExtendBlockObject");
19682135 return nullptr;
1969 case clang::CK_AtomicToNonAtomic:
1970 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AtomicToNonAtomic");
2136 case ZigClangCK_AtomicToNonAtomic:
2137 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AtomicToNonAtomic");
19712138 return nullptr;
1972 case clang::CK_NonAtomicToAtomic:
1973 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_NonAtomicToAtomic");
2139 case ZigClangCK_NonAtomicToAtomic:
2140 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_NonAtomicToAtomic");
19742141 return nullptr;
1975 case clang::CK_CopyAndAutoreleaseBlockObject:
1976 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
2142 case ZigClangCK_CopyAndAutoreleaseBlockObject:
2143 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_CopyAndAutoreleaseBlockObject");
19772144 return nullptr;
1978 case clang::CK_BuiltinFnToFnPtr:
1979 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_BuiltinFnToFnPtr");
2145 case ZigClangCK_BuiltinFnToFnPtr:
2146 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_BuiltinFnToFnPtr");
19802147 return nullptr;
1981 case clang::CK_ZeroToOCLOpaqueType:
1982 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_ZeroToOCLOpaqueType");
2148 case ZigClangCK_ZeroToOCLOpaqueType:
2149 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ZeroToOCLOpaqueType");
19832150 return nullptr;
1984 case clang::CK_AddressSpaceConversion:
1985 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_AddressSpaceConversion");
2151 case ZigClangCK_AddressSpaceConversion:
2152 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_AddressSpaceConversion");
19862153 return nullptr;
1987 case clang::CK_IntToOCLSampler:
1988 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CK_IntToOCLSampler");
2154 case ZigClangCK_IntToOCLSampler:
2155 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntToOCLSampler");
19892156 return nullptr;
19902157 }
19912158 zig_unreachable();
......@@ -1993,7 +2160,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra
19932160
19942161static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::DeclRefExpr *stmt, TransLRValue lrval) {
19952162 const clang::ValueDecl *value_decl = stmt->getDecl();
1996 Buf *c_symbol_name = buf_create_from_str(decl_name(value_decl));
2163 Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)value_decl));
19972164 Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name);
19982165 if (lrval == TransLValue) {
19992166 c->ptr_params.put(zig_symbol_name, true);
......@@ -2004,7 +2171,7 @@ static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::
20042171static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
20052172 const clang::UnaryOperator *stmt, BinOpType assign_op)
20062173{
2007 clang::Expr *op_expr = stmt->getSubExpr();
2174 const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
20082175
20092176 if (result_used == ResultUsedNo) {
20102177 // common case
......@@ -2060,7 +2227,7 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
20602227static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, TransScope *scope,
20612228 const clang::UnaryOperator *stmt, BinOpType assign_op)
20622229{
2063 clang::Expr *op_expr = stmt->getSubExpr();
2230 const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
20642231
20652232 if (result_used == ResultUsedNo) {
20662233 // common case
......@@ -2110,50 +2277,50 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
21102277static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryOperator *stmt) {
21112278 switch (stmt->getOpcode()) {
21122279 case clang::UO_PostInc:
2113 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
2280 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
21142281 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
21152282 else
21162283 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
21172284 case clang::UO_PostDec:
2118 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
2285 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
21192286 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
21202287 else
21212288 return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
21222289 case clang::UO_PreInc:
2123 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
2290 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
21242291 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
21252292 else
21262293 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
21272294 case clang::UO_PreDec:
2128 if (qual_type_has_wrapping_overflow(c, stmt->getType()))
2295 if (qual_type_has_wrapping_overflow(c, bitcast(stmt->getType())))
21292296 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
21302297 else
21312298 return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
21322299 case clang::UO_AddrOf:
21332300 {
2134 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
2301 AstNode *value_node = trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransLValue);
21352302 if (value_node == nullptr)
21362303 return value_node;
21372304 return trans_create_node_addr_of(c, value_node);
21382305 }
21392306 case clang::UO_Deref:
21402307 {
2141 AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
2308 AstNode *value_node = trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransRValue);
21422309 if (value_node == nullptr)
21432310 return nullptr;
2144 bool is_fn_ptr = qual_type_is_fn_ptr(stmt->getSubExpr()->getType());
2311 bool is_fn_ptr = qual_type_is_fn_ptr(bitcast(stmt->getSubExpr()->getType()));
21452312 if (is_fn_ptr)
21462313 return value_node;
21472314 AstNode *unwrapped = trans_create_node_unwrap_null(c, value_node);
21482315 return trans_create_node_ptr_deref(c, unwrapped);
21492316 }
21502317 case clang::UO_Plus:
2151 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Plus");
2318 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Plus");
21522319 return nullptr;
21532320 case clang::UO_Minus:
21542321 {
2155 clang::Expr *op_expr = stmt->getSubExpr();
2156 if (!qual_type_has_wrapping_overflow(c, op_expr->getType())) {
2322 const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
2323 if (!qual_type_has_wrapping_overflow(c, ZigClangExpr_getType(op_expr))) {
21572324 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
21582325 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
21592326
......@@ -2162,7 +2329,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
21622329 return nullptr;
21632330
21642331 return node;
2165 } else if (c_is_unsigned_integer(c, op_expr->getType())) {
2332 } else if (c_is_unsigned_integer(c, ZigClangExpr_getType(op_expr))) {
21662333 // we gotta emit 0 -% x
21672334 AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
21682335 node->data.bin_op_expr.op1 = trans_create_node_unsigned(c, 0);
......@@ -2174,13 +2341,13 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
21742341 node->data.bin_op_expr.bin_op = BinOpTypeSubWrap;
21752342 return node;
21762343 } else {
2177 emit_warning(c, stmt->getBeginLoc(), "C negation with non float non integer");
2344 emit_warning(c, bitcast(stmt->getBeginLoc()), "C negation with non float non integer");
21782345 return nullptr;
21792346 }
21802347 }
21812348 case clang::UO_Not:
21822349 {
2183 clang::Expr *op_expr = stmt->getSubExpr();
2350 const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
21842351 AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
21852352 if (sub_node == nullptr)
21862353 return nullptr;
......@@ -2189,7 +2356,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
21892356 }
21902357 case clang::UO_LNot:
21912358 {
2192 clang::Expr *op_expr = stmt->getSubExpr();
2359 const ZigClangExpr *op_expr = bitcast(stmt->getSubExpr());
21932360 AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
21942361 if (sub_node == nullptr)
21952362 return nullptr;
......@@ -2197,15 +2364,15 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
21972364 return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
21982365 }
21992366 case clang::UO_Real:
2200 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Real");
2367 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Real");
22012368 return nullptr;
22022369 case clang::UO_Imag:
2203 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Imag");
2370 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Imag");
22042371 return nullptr;
22052372 case clang::UO_Extension:
2206 return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
2373 return trans_expr(c, result_used, scope, bitcast(stmt->getSubExpr()), TransLValue);
22072374 case clang::UO_Coawait:
2208 emit_warning(c, stmt->getBeginLoc(), "TODO handle C translation UO_Coawait");
2375 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C translation UO_Coawait");
22092376 return nullptr;
22102377 }
22112378 zig_unreachable();
......@@ -2225,249 +2392,250 @@ static int trans_local_declaration(Context *c, TransScope *scope, const clang::D
22252392 switch (decl->getKind()) {
22262393 case clang::Decl::Var: {
22272394 clang::VarDecl *var_decl = (clang::VarDecl *)decl;
2228 clang::QualType qual_type = var_decl->getTypeSourceInfo()->getType();
2395 ZigClangQualType qual_type = bitcast(var_decl->getTypeSourceInfo()->getType());
22292396 AstNode *init_node = nullptr;
22302397 if (var_decl->hasInit()) {
2231 init_node = trans_expr(c, ResultUsedYes, scope, var_decl->getInit(), TransRValue);
2398 init_node = trans_expr(c, ResultUsedYes, scope, bitcast(var_decl->getInit()), TransRValue);
22322399 if (init_node == nullptr)
22332400 return ErrorUnexpected;
22342401
22352402 } else {
22362403 init_node = trans_create_node(c, NodeTypeUndefinedLiteral);
22372404 }
2238 AstNode *type_node = trans_qual_type(c, qual_type, stmt->getBeginLoc());
2405 AstNode *type_node = trans_qual_type(c, qual_type, bitcast(stmt->getBeginLoc()));
22392406 if (type_node == nullptr)
22402407 return ErrorUnexpected;
22412408
2242 Buf *c_symbol_name = buf_create_from_str(decl_name(var_decl));
2409 Buf *c_symbol_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
22432410
22442411 TransScopeVar *var_scope = trans_scope_var_create(c, scope, c_symbol_name);
22452412 scope = &var_scope->base;
22462413
2247 AstNode *node = trans_create_node_var_decl_local(c, qual_type.isConstQualified(),
2414 AstNode *node = trans_create_node_var_decl_local(c,
2415 ZigClangQualType_isConstQualified(qual_type),
22482416 var_scope->zig_name, type_node, init_node);
22492417
22502418 scope_block->node->data.block.statements.append(node);
22512419 continue;
22522420 }
22532421 case clang::Decl::AccessSpec:
2254 emit_warning(c, stmt->getBeginLoc(), "TODO handle decl kind AccessSpec");
2422 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle decl kind AccessSpec");
22552423 return ErrorUnexpected;
22562424 case clang::Decl::Block:
2257 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Block");
2425 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Block");
22582426 return ErrorUnexpected;
22592427 case clang::Decl::Captured:
2260 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Captured");
2428 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Captured");
22612429 return ErrorUnexpected;
22622430 case clang::Decl::ClassScopeFunctionSpecialization:
2263 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassScopeFunctionSpecialization");
2431 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassScopeFunctionSpecialization");
22642432 return ErrorUnexpected;
22652433 case clang::Decl::Empty:
2266 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Empty");
2434 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Empty");
22672435 return ErrorUnexpected;
22682436 case clang::Decl::Export:
2269 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Export");
2437 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Export");
22702438 return ErrorUnexpected;
22712439 case clang::Decl::ExternCContext:
2272 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExternCContext");
2440 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ExternCContext");
22732441 return ErrorUnexpected;
22742442 case clang::Decl::FileScopeAsm:
2275 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FileScopeAsm");
2443 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FileScopeAsm");
22762444 return ErrorUnexpected;
22772445 case clang::Decl::Friend:
2278 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Friend");
2446 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Friend");
22792447 return ErrorUnexpected;
22802448 case clang::Decl::FriendTemplate:
2281 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FriendTemplate");
2449 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FriendTemplate");
22822450 return ErrorUnexpected;
22832451 case clang::Decl::Import:
2284 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Import");
2452 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Import");
22852453 return ErrorUnexpected;
22862454 case clang::Decl::LinkageSpec:
2287 emit_warning(c, stmt->getBeginLoc(), "TODO handle C LinkageSpec");
2455 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C LinkageSpec");
22882456 return ErrorUnexpected;
22892457 case clang::Decl::Label:
2290 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Label");
2458 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Label");
22912459 return ErrorUnexpected;
22922460 case clang::Decl::Namespace:
2293 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Namespace");
2461 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Namespace");
22942462 return ErrorUnexpected;
22952463 case clang::Decl::NamespaceAlias:
2296 emit_warning(c, stmt->getBeginLoc(), "TODO handle C NamespaceAlias");
2464 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NamespaceAlias");
22972465 return ErrorUnexpected;
22982466 case clang::Decl::ObjCCompatibleAlias:
2299 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCompatibleAlias");
2467 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCompatibleAlias");
23002468 return ErrorUnexpected;
23012469 case clang::Decl::ObjCCategory:
2302 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategory");
2470 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategory");
23032471 return ErrorUnexpected;
23042472 case clang::Decl::ObjCCategoryImpl:
2305 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCCategoryImpl");
2473 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCCategoryImpl");
23062474 return ErrorUnexpected;
23072475 case clang::Decl::ObjCImplementation:
2308 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCImplementation");
2476 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCImplementation");
23092477 return ErrorUnexpected;
23102478 case clang::Decl::ObjCInterface:
2311 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCInterface");
2479 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCInterface");
23122480 return ErrorUnexpected;
23132481 case clang::Decl::ObjCProtocol:
2314 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocol");
2482 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProtocol");
23152483 return ErrorUnexpected;
23162484 case clang::Decl::ObjCMethod:
2317 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMethod");
2485 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCMethod");
23182486 return ErrorUnexpected;
23192487 case clang::Decl::ObjCProperty:
2320 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProperty");
2488 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCProperty");
23212489 return ErrorUnexpected;
23222490 case clang::Decl::BuiltinTemplate:
2323 emit_warning(c, stmt->getBeginLoc(), "TODO handle C BuiltinTemplate");
2491 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C BuiltinTemplate");
23242492 return ErrorUnexpected;
23252493 case clang::Decl::ClassTemplate:
2326 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplate");
2494 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplate");
23272495 return ErrorUnexpected;
23282496 case clang::Decl::FunctionTemplate:
2329 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionTemplate");
2497 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C FunctionTemplate");
23302498 return ErrorUnexpected;
23312499 case clang::Decl::TypeAliasTemplate:
2332 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAliasTemplate");
2500 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAliasTemplate");
23332501 return ErrorUnexpected;
23342502 case clang::Decl::VarTemplate:
2335 emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplate");
2503 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplate");
23362504 return ErrorUnexpected;
23372505 case clang::Decl::TemplateTemplateParm:
2338 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTemplateParm");
2506 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTemplateParm");
23392507 return ErrorUnexpected;
23402508 case clang::Decl::Enum:
2341 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Enum");
2509 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Enum");
23422510 return ErrorUnexpected;
23432511 case clang::Decl::Record:
2344 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Record");
2512 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Record");
23452513 return ErrorUnexpected;
23462514 case clang::Decl::CXXRecord:
2347 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXRecord");
2515 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXRecord");
23482516 return ErrorUnexpected;
23492517 case clang::Decl::ClassTemplateSpecialization:
2350 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplateSpecialization");
2518 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplateSpecialization");
23512519 return ErrorUnexpected;
23522520 case clang::Decl::ClassTemplatePartialSpecialization:
2353 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ClassTemplatePartialSpecialization");
2521 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ClassTemplatePartialSpecialization");
23542522 return ErrorUnexpected;
23552523 case clang::Decl::TemplateTypeParm:
2356 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TemplateTypeParm");
2524 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TemplateTypeParm");
23572525 return ErrorUnexpected;
23582526 case clang::Decl::ObjCTypeParam:
2359 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCTypeParam");
2527 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCTypeParam");
23602528 return ErrorUnexpected;
23612529 case clang::Decl::TypeAlias:
2362 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeAlias");
2530 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TypeAlias");
23632531 return ErrorUnexpected;
23642532 case clang::Decl::Typedef:
2365 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Typedef");
2533 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Typedef");
23662534 return ErrorUnexpected;
23672535 case clang::Decl::UnresolvedUsingTypename:
2368 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingTypename");
2536 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingTypename");
23692537 return ErrorUnexpected;
23702538 case clang::Decl::Using:
2371 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Using");
2539 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Using");
23722540 return ErrorUnexpected;
23732541 case clang::Decl::UsingDirective:
2374 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingDirective");
2542 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingDirective");
23752543 return ErrorUnexpected;
23762544 case clang::Decl::UsingPack:
2377 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingPack");
2545 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingPack");
23782546 return ErrorUnexpected;
23792547 case clang::Decl::UsingShadow:
2380 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UsingShadow");
2548 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UsingShadow");
23812549 return ErrorUnexpected;
23822550 case clang::Decl::ConstructorUsingShadow:
2383 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConstructorUsingShadow");
2551 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ConstructorUsingShadow");
23842552 return ErrorUnexpected;
23852553 case clang::Decl::Binding:
2386 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Binding");
2554 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Binding");
23872555 return ErrorUnexpected;
23882556 case clang::Decl::Field:
2389 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Field");
2557 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Field");
23902558 return ErrorUnexpected;
23912559 case clang::Decl::ObjCAtDefsField:
2392 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtDefsField");
2560 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCAtDefsField");
23932561 return ErrorUnexpected;
23942562 case clang::Decl::ObjCIvar:
2395 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvar");
2563 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCIvar");
23962564 return ErrorUnexpected;
23972565 case clang::Decl::Function:
2398 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Function");
2566 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Function");
23992567 return ErrorUnexpected;
24002568 case clang::Decl::CXXDeductionGuide:
2401 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeductionGuide");
2569 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDeductionGuide");
24022570 return ErrorUnexpected;
24032571 case clang::Decl::CXXMethod:
2404 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMethod");
2572 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXMethod");
24052573 return ErrorUnexpected;
24062574 case clang::Decl::CXXConstructor:
2407 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructor");
2575 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConstructor");
24082576 return ErrorUnexpected;
24092577 case clang::Decl::CXXConversion:
2410 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConversion");
2578 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXConversion");
24112579 return ErrorUnexpected;
24122580 case clang::Decl::CXXDestructor:
2413 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDestructor");
2581 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CXXDestructor");
24142582 return ErrorUnexpected;
24152583 case clang::Decl::MSProperty:
2416 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSProperty");
2584 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C MSProperty");
24172585 return ErrorUnexpected;
24182586 case clang::Decl::NonTypeTemplateParm:
2419 emit_warning(c, stmt->getBeginLoc(), "TODO handle C NonTypeTemplateParm");
2587 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C NonTypeTemplateParm");
24202588 return ErrorUnexpected;
24212589 case clang::Decl::Decomposition:
2422 emit_warning(c, stmt->getBeginLoc(), "TODO handle C Decomposition");
2590 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C Decomposition");
24232591 return ErrorUnexpected;
24242592 case clang::Decl::ImplicitParam:
2425 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitParam");
2593 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ImplicitParam");
24262594 return ErrorUnexpected;
24272595 case clang::Decl::OMPCapturedExpr:
2428 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCapturedExpr");
2596 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPCapturedExpr");
24292597 return ErrorUnexpected;
24302598 case clang::Decl::ParmVar:
2431 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParmVar");
2599 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ParmVar");
24322600 return ErrorUnexpected;
24332601 case clang::Decl::VarTemplateSpecialization:
2434 emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplateSpecialization");
2602 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplateSpecialization");
24352603 return ErrorUnexpected;
24362604 case clang::Decl::VarTemplatePartialSpecialization:
2437 emit_warning(c, stmt->getBeginLoc(), "TODO handle C VarTemplatePartialSpecialization");
2605 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C VarTemplatePartialSpecialization");
24382606 return ErrorUnexpected;
24392607 case clang::Decl::EnumConstant:
2440 emit_warning(c, stmt->getBeginLoc(), "TODO handle C EnumConstant");
2608 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C EnumConstant");
24412609 return ErrorUnexpected;
24422610 case clang::Decl::IndirectField:
2443 emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectField");
2611 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C IndirectField");
24442612 return ErrorUnexpected;
24452613 case clang::Decl::OMPDeclareReduction:
2446 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDeclareReduction");
2614 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPDeclareReduction");
24472615 return ErrorUnexpected;
24482616 case clang::Decl::UnresolvedUsingValue:
2449 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedUsingValue");
2617 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C UnresolvedUsingValue");
24502618 return ErrorUnexpected;
24512619 case clang::Decl::OMPRequires:
2452 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPRequires");
2620 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPRequires");
24532621 return ErrorUnexpected;
24542622 case clang::Decl::OMPThreadPrivate:
2455 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPThreadPrivate");
2623 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C OMPThreadPrivate");
24562624 return ErrorUnexpected;
24572625 case clang::Decl::ObjCPropertyImpl:
2458 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyImpl");
2626 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C ObjCPropertyImpl");
24592627 return ErrorUnexpected;
24602628 case clang::Decl::PragmaComment:
2461 emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaComment");
2629 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaComment");
24622630 return ErrorUnexpected;
24632631 case clang::Decl::PragmaDetectMismatch:
2464 emit_warning(c, stmt->getBeginLoc(), "TODO handle C PragmaDetectMismatch");
2632 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C PragmaDetectMismatch");
24652633 return ErrorUnexpected;
24662634 case clang::Decl::StaticAssert:
2467 emit_warning(c, stmt->getBeginLoc(), "TODO handle C StaticAssert");
2635 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C StaticAssert");
24682636 return ErrorUnexpected;
24692637 case clang::Decl::TranslationUnit:
2470 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TranslationUnit");
2638 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C TranslationUnit");
24712639 return ErrorUnexpected;
24722640 }
24732641 zig_unreachable();
......@@ -2493,7 +2661,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)
24932661 return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast);
24942662}
24952663
2496static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval) {
2664static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr, TransLRValue lrval) {
24972665 AstNode *res = trans_expr(c, result_used, scope, expr, lrval);
24982666 if (res == nullptr)
24992667 return nullptr;
......@@ -2530,146 +2698,145 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
25302698 }
25312699
25322700
2533 const clang::Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr();
2534 auto classs = ty->getTypeClass();
2701 const ZigClangType *ty = ZigClangQualType_getTypePtr(get_expr_qual_type_before_implicit_cast(c, expr));
2702 auto classs = ZigClangType_getTypeClass(ty);
25352703 switch (classs) {
2536 case clang::Type::Builtin:
2704 case ZigClangType_Builtin:
25372705 {
2538 const clang::BuiltinType *builtin_ty = static_cast<const clang::BuiltinType*>(ty);
2539 switch (builtin_ty->getKind()) {
2540 case clang::BuiltinType::Bool:
2541 case clang::BuiltinType::Char_U:
2542 case clang::BuiltinType::UChar:
2543 case clang::BuiltinType::Char_S:
2544 case clang::BuiltinType::SChar:
2545 case clang::BuiltinType::UShort:
2546 case clang::BuiltinType::UInt:
2547 case clang::BuiltinType::ULong:
2548 case clang::BuiltinType::ULongLong:
2549 case clang::BuiltinType::Short:
2550 case clang::BuiltinType::Int:
2551 case clang::BuiltinType::Long:
2552 case clang::BuiltinType::LongLong:
2553 case clang::BuiltinType::UInt128:
2554 case clang::BuiltinType::Int128:
2555 case clang::BuiltinType::Float:
2556 case clang::BuiltinType::Double:
2557 case clang::BuiltinType::Float128:
2558 case clang::BuiltinType::LongDouble:
2559 case clang::BuiltinType::WChar_U:
2560 case clang::BuiltinType::Char8:
2561 case clang::BuiltinType::Char16:
2562 case clang::BuiltinType::Char32:
2563 case clang::BuiltinType::WChar_S:
2564 case clang::BuiltinType::Float16:
2706 const ZigClangBuiltinType *builtin_ty = reinterpret_cast<const ZigClangBuiltinType*>(ty);
2707 switch (ZigClangBuiltinType_getKind(builtin_ty)) {
2708 case ZigClangBuiltinTypeBool:
2709 case ZigClangBuiltinTypeChar_U:
2710 case ZigClangBuiltinTypeUChar:
2711 case ZigClangBuiltinTypeChar_S:
2712 case ZigClangBuiltinTypeSChar:
2713 case ZigClangBuiltinTypeUShort:
2714 case ZigClangBuiltinTypeUInt:
2715 case ZigClangBuiltinTypeULong:
2716 case ZigClangBuiltinTypeULongLong:
2717 case ZigClangBuiltinTypeShort:
2718 case ZigClangBuiltinTypeInt:
2719 case ZigClangBuiltinTypeLong:
2720 case ZigClangBuiltinTypeLongLong:
2721 case ZigClangBuiltinTypeUInt128:
2722 case ZigClangBuiltinTypeInt128:
2723 case ZigClangBuiltinTypeFloat:
2724 case ZigClangBuiltinTypeDouble:
2725 case ZigClangBuiltinTypeFloat128:
2726 case ZigClangBuiltinTypeLongDouble:
2727 case ZigClangBuiltinTypeWChar_U:
2728 case ZigClangBuiltinTypeChar8:
2729 case ZigClangBuiltinTypeChar16:
2730 case ZigClangBuiltinTypeChar32:
2731 case ZigClangBuiltinTypeWChar_S:
2732 case ZigClangBuiltinTypeFloat16:
25652733 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
2566 case clang::BuiltinType::NullPtr:
2734 case ZigClangBuiltinTypeNullPtr:
25672735 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
2568 trans_create_node_unsigned(c, 0));
2569
2570 case clang::BuiltinType::Void:
2571 case clang::BuiltinType::Half:
2572 case clang::BuiltinType::ObjCId:
2573 case clang::BuiltinType::ObjCClass:
2574 case clang::BuiltinType::ObjCSel:
2575 case clang::BuiltinType::OMPArraySection:
2576 case clang::BuiltinType::Dependent:
2577 case clang::BuiltinType::Overload:
2578 case clang::BuiltinType::BoundMember:
2579 case clang::BuiltinType::PseudoObject:
2580 case clang::BuiltinType::UnknownAny:
2581 case clang::BuiltinType::BuiltinFn:
2582 case clang::BuiltinType::ARCUnbridgedCast:
2583 case clang::BuiltinType::OCLImage1dRO:
2584 case clang::BuiltinType::OCLImage1dArrayRO:
2585 case clang::BuiltinType::OCLImage1dBufferRO:
2586 case clang::BuiltinType::OCLImage2dRO:
2587 case clang::BuiltinType::OCLImage2dArrayRO:
2588 case clang::BuiltinType::OCLImage2dDepthRO:
2589 case clang::BuiltinType::OCLImage2dArrayDepthRO:
2590 case clang::BuiltinType::OCLImage2dMSAARO:
2591 case clang::BuiltinType::OCLImage2dArrayMSAARO:
2592 case clang::BuiltinType::OCLImage2dMSAADepthRO:
2593 case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
2594 case clang::BuiltinType::OCLImage3dRO:
2595 case clang::BuiltinType::OCLImage1dWO:
2596 case clang::BuiltinType::OCLImage1dArrayWO:
2597 case clang::BuiltinType::OCLImage1dBufferWO:
2598 case clang::BuiltinType::OCLImage2dWO:
2599 case clang::BuiltinType::OCLImage2dArrayWO:
2600 case clang::BuiltinType::OCLImage2dDepthWO:
2601 case clang::BuiltinType::OCLImage2dArrayDepthWO:
2602 case clang::BuiltinType::OCLImage2dMSAAWO:
2603 case clang::BuiltinType::OCLImage2dArrayMSAAWO:
2604 case clang::BuiltinType::OCLImage2dMSAADepthWO:
2605 case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
2606 case clang::BuiltinType::OCLImage3dWO:
2607 case clang::BuiltinType::OCLImage1dRW:
2608 case clang::BuiltinType::OCLImage1dArrayRW:
2609 case clang::BuiltinType::OCLImage1dBufferRW:
2610 case clang::BuiltinType::OCLImage2dRW:
2611 case clang::BuiltinType::OCLImage2dArrayRW:
2612 case clang::BuiltinType::OCLImage2dDepthRW:
2613 case clang::BuiltinType::OCLImage2dArrayDepthRW:
2614 case clang::BuiltinType::OCLImage2dMSAARW:
2615 case clang::BuiltinType::OCLImage2dArrayMSAARW:
2616 case clang::BuiltinType::OCLImage2dMSAADepthRW:
2617 case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
2618 case clang::BuiltinType::OCLImage3dRW:
2619 case clang::BuiltinType::OCLSampler:
2620 case clang::BuiltinType::OCLEvent:
2621 case clang::BuiltinType::OCLClkEvent:
2622 case clang::BuiltinType::OCLQueue:
2623 case clang::BuiltinType::OCLReserveID:
2624 case clang::BuiltinType::ShortAccum:
2625 case clang::BuiltinType::Accum:
2626 case clang::BuiltinType::LongAccum:
2627 case clang::BuiltinType::UShortAccum:
2628 case clang::BuiltinType::UAccum:
2629 case clang::BuiltinType::ULongAccum:
2630 case clang::BuiltinType::ShortFract:
2631 case clang::BuiltinType::Fract:
2632 case clang::BuiltinType::LongFract:
2633 case clang::BuiltinType::UShortFract:
2634 case clang::BuiltinType::UFract:
2635 case clang::BuiltinType::ULongFract:
2636 case clang::BuiltinType::SatShortAccum:
2637 case clang::BuiltinType::SatAccum:
2638 case clang::BuiltinType::SatLongAccum:
2639 case clang::BuiltinType::SatUShortAccum:
2640 case clang::BuiltinType::SatUAccum:
2641 case clang::BuiltinType::SatULongAccum:
2642 case clang::BuiltinType::SatShortFract:
2643 case clang::BuiltinType::SatFract:
2644 case clang::BuiltinType::SatLongFract:
2645 case clang::BuiltinType::SatUShortFract:
2646 case clang::BuiltinType::SatUFract:
2647 case clang::BuiltinType::SatULongFract:
2648 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
2649 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
2650 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
2651 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
2652 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
2653 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
2654 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
2655 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
2656 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
2657 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
2658 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
2659 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
2736 trans_create_node(c, NodeTypeNullLiteral));
2737
2738 case ZigClangBuiltinTypeVoid:
2739 case ZigClangBuiltinTypeHalf:
2740 case ZigClangBuiltinTypeObjCId:
2741 case ZigClangBuiltinTypeObjCClass:
2742 case ZigClangBuiltinTypeObjCSel:
2743 case ZigClangBuiltinTypeOMPArraySection:
2744 case ZigClangBuiltinTypeDependent:
2745 case ZigClangBuiltinTypeOverload:
2746 case ZigClangBuiltinTypeBoundMember:
2747 case ZigClangBuiltinTypePseudoObject:
2748 case ZigClangBuiltinTypeUnknownAny:
2749 case ZigClangBuiltinTypeBuiltinFn:
2750 case ZigClangBuiltinTypeARCUnbridgedCast:
2751 case ZigClangBuiltinTypeOCLImage1dRO:
2752 case ZigClangBuiltinTypeOCLImage1dArrayRO:
2753 case ZigClangBuiltinTypeOCLImage1dBufferRO:
2754 case ZigClangBuiltinTypeOCLImage2dRO:
2755 case ZigClangBuiltinTypeOCLImage2dArrayRO:
2756 case ZigClangBuiltinTypeOCLImage2dDepthRO:
2757 case ZigClangBuiltinTypeOCLImage2dArrayDepthRO:
2758 case ZigClangBuiltinTypeOCLImage2dMSAARO:
2759 case ZigClangBuiltinTypeOCLImage2dArrayMSAARO:
2760 case ZigClangBuiltinTypeOCLImage2dMSAADepthRO:
2761 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO:
2762 case ZigClangBuiltinTypeOCLImage3dRO:
2763 case ZigClangBuiltinTypeOCLImage1dWO:
2764 case ZigClangBuiltinTypeOCLImage1dArrayWO:
2765 case ZigClangBuiltinTypeOCLImage1dBufferWO:
2766 case ZigClangBuiltinTypeOCLImage2dWO:
2767 case ZigClangBuiltinTypeOCLImage2dArrayWO:
2768 case ZigClangBuiltinTypeOCLImage2dDepthWO:
2769 case ZigClangBuiltinTypeOCLImage2dArrayDepthWO:
2770 case ZigClangBuiltinTypeOCLImage2dMSAAWO:
2771 case ZigClangBuiltinTypeOCLImage2dArrayMSAAWO:
2772 case ZigClangBuiltinTypeOCLImage2dMSAADepthWO:
2773 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO:
2774 case ZigClangBuiltinTypeOCLImage3dWO:
2775 case ZigClangBuiltinTypeOCLImage1dRW:
2776 case ZigClangBuiltinTypeOCLImage1dArrayRW:
2777 case ZigClangBuiltinTypeOCLImage1dBufferRW:
2778 case ZigClangBuiltinTypeOCLImage2dRW:
2779 case ZigClangBuiltinTypeOCLImage2dArrayRW:
2780 case ZigClangBuiltinTypeOCLImage2dDepthRW:
2781 case ZigClangBuiltinTypeOCLImage2dArrayDepthRW:
2782 case ZigClangBuiltinTypeOCLImage2dMSAARW:
2783 case ZigClangBuiltinTypeOCLImage2dArrayMSAARW:
2784 case ZigClangBuiltinTypeOCLImage2dMSAADepthRW:
2785 case ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW:
2786 case ZigClangBuiltinTypeOCLImage3dRW:
2787 case ZigClangBuiltinTypeOCLSampler:
2788 case ZigClangBuiltinTypeOCLEvent:
2789 case ZigClangBuiltinTypeOCLClkEvent:
2790 case ZigClangBuiltinTypeOCLQueue:
2791 case ZigClangBuiltinTypeOCLReserveID:
2792 case ZigClangBuiltinTypeShortAccum:
2793 case ZigClangBuiltinTypeAccum:
2794 case ZigClangBuiltinTypeLongAccum:
2795 case ZigClangBuiltinTypeUShortAccum:
2796 case ZigClangBuiltinTypeUAccum:
2797 case ZigClangBuiltinTypeULongAccum:
2798 case ZigClangBuiltinTypeShortFract:
2799 case ZigClangBuiltinTypeFract:
2800 case ZigClangBuiltinTypeLongFract:
2801 case ZigClangBuiltinTypeUShortFract:
2802 case ZigClangBuiltinTypeUFract:
2803 case ZigClangBuiltinTypeULongFract:
2804 case ZigClangBuiltinTypeSatShortAccum:
2805 case ZigClangBuiltinTypeSatAccum:
2806 case ZigClangBuiltinTypeSatLongAccum:
2807 case ZigClangBuiltinTypeSatUShortAccum:
2808 case ZigClangBuiltinTypeSatUAccum:
2809 case ZigClangBuiltinTypeSatULongAccum:
2810 case ZigClangBuiltinTypeSatShortFract:
2811 case ZigClangBuiltinTypeSatFract:
2812 case ZigClangBuiltinTypeSatLongFract:
2813 case ZigClangBuiltinTypeSatUShortFract:
2814 case ZigClangBuiltinTypeSatUFract:
2815 case ZigClangBuiltinTypeSatULongFract:
2816 case ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload:
2817 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload:
2818 case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload:
2819 case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload:
2820 case ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult:
2821 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult:
2822 case ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult:
2823 case ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult:
2824 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout:
2825 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout:
2826 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin:
2827 case ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin:
26602828 return res;
26612829 }
26622830 break;
26632831 }
2664 case clang::Type::Pointer:
2665 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
2666 trans_create_node_unsigned(c, 0));
2832 case ZigClangType_Pointer:
2833 return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
26672834
2668 case clang::Type::Typedef:
2835 case ZigClangType_Typedef:
26692836 {
2670 const clang::TypedefType *typedef_ty = static_cast<const clang::TypedefType*>(ty);
2671 const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
2672 auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl());
2837 const ZigClangTypedefType *typedef_ty = reinterpret_cast<const ZigClangTypedefType*>(ty);
2838 const ZigClangTypedefNameDecl *typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
2839 auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
26732840 if (existing_entry) {
26742841 return existing_entry->value;
26752842 }
......@@ -2677,19 +2844,20 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
26772844 return res;
26782845 }
26792846
2680 case clang::Type::Enum:
2847 case ZigClangType_Enum:
26812848 {
2682 const clang::EnumType *enum_ty = static_cast<const clang::EnumType*>(ty);
2683 AstNode *enum_type = resolve_enum_decl(c, enum_ty->getDecl());
2849 const ZigClangEnumType *enum_ty = reinterpret_cast<const ZigClangEnumType *>(ty);
2850 AstNode *enum_type = resolve_enum_decl(c, ZigClangEnumType_getDecl(enum_ty));
26842851 return to_enum_zero_cmp(c, res, enum_type);
26852852 }
26862853
2687 case clang::Type::Elaborated:
2854 case ZigClangType_Elaborated:
26882855 {
2689 const clang::ElaboratedType *elaborated_ty = static_cast<const clang::ElaboratedType*>(ty);
2856 const clang::ElaboratedType *elaborated_ty = reinterpret_cast<const clang::ElaboratedType*>(ty);
26902857 switch (elaborated_ty->getKeyword()) {
26912858 case clang::ETK_Enum: {
2692 AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getBeginLoc());
2859 AstNode *enum_type = trans_qual_type(c, bitcast(elaborated_ty->getNamedType()),
2860 ZigClangExpr_getBeginLoc(expr));
26932861 return to_enum_zero_cmp(c, res, enum_type);
26942862 }
26952863 case clang::ETK_Struct:
......@@ -2702,48 +2870,48 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
27022870 }
27032871 }
27042872
2705 case clang::Type::FunctionProto:
2706 case clang::Type::Record:
2707 case clang::Type::ConstantArray:
2708 case clang::Type::Paren:
2709 case clang::Type::Decayed:
2710 case clang::Type::Attributed:
2711 case clang::Type::IncompleteArray:
2712 case clang::Type::BlockPointer:
2713 case clang::Type::LValueReference:
2714 case clang::Type::RValueReference:
2715 case clang::Type::MemberPointer:
2716 case clang::Type::VariableArray:
2717 case clang::Type::DependentSizedArray:
2718 case clang::Type::DependentSizedExtVector:
2719 case clang::Type::Vector:
2720 case clang::Type::ExtVector:
2721 case clang::Type::FunctionNoProto:
2722 case clang::Type::UnresolvedUsing:
2723 case clang::Type::Adjusted:
2724 case clang::Type::TypeOfExpr:
2725 case clang::Type::TypeOf:
2726 case clang::Type::Decltype:
2727 case clang::Type::UnaryTransform:
2728 case clang::Type::TemplateTypeParm:
2729 case clang::Type::SubstTemplateTypeParm:
2730 case clang::Type::SubstTemplateTypeParmPack:
2731 case clang::Type::TemplateSpecialization:
2732 case clang::Type::Auto:
2733 case clang::Type::InjectedClassName:
2734 case clang::Type::DependentName:
2735 case clang::Type::DependentTemplateSpecialization:
2736 case clang::Type::PackExpansion:
2737 case clang::Type::ObjCObject:
2738 case clang::Type::ObjCInterface:
2739 case clang::Type::Complex:
2740 case clang::Type::ObjCObjectPointer:
2741 case clang::Type::Atomic:
2742 case clang::Type::Pipe:
2743 case clang::Type::ObjCTypeParam:
2744 case clang::Type::DeducedTemplateSpecialization:
2745 case clang::Type::DependentAddressSpace:
2746 case clang::Type::DependentVector:
2873 case ZigClangType_FunctionProto:
2874 case ZigClangType_Record:
2875 case ZigClangType_ConstantArray:
2876 case ZigClangType_Paren:
2877 case ZigClangType_Decayed:
2878 case ZigClangType_Attributed:
2879 case ZigClangType_IncompleteArray:
2880 case ZigClangType_BlockPointer:
2881 case ZigClangType_LValueReference:
2882 case ZigClangType_RValueReference:
2883 case ZigClangType_MemberPointer:
2884 case ZigClangType_VariableArray:
2885 case ZigClangType_DependentSizedArray:
2886 case ZigClangType_DependentSizedExtVector:
2887 case ZigClangType_Vector:
2888 case ZigClangType_ExtVector:
2889 case ZigClangType_FunctionNoProto:
2890 case ZigClangType_UnresolvedUsing:
2891 case ZigClangType_Adjusted:
2892 case ZigClangType_TypeOfExpr:
2893 case ZigClangType_TypeOf:
2894 case ZigClangType_Decltype:
2895 case ZigClangType_UnaryTransform:
2896 case ZigClangType_TemplateTypeParm:
2897 case ZigClangType_SubstTemplateTypeParm:
2898 case ZigClangType_SubstTemplateTypeParmPack:
2899 case ZigClangType_TemplateSpecialization:
2900 case ZigClangType_Auto:
2901 case ZigClangType_InjectedClassName:
2902 case ZigClangType_DependentName:
2903 case ZigClangType_DependentTemplateSpecialization:
2904 case ZigClangType_PackExpansion:
2905 case ZigClangType_ObjCObject:
2906 case ZigClangType_ObjCInterface:
2907 case ZigClangType_Complex:
2908 case ZigClangType_ObjCObjectPointer:
2909 case ZigClangType_Atomic:
2910 case ZigClangType_Pipe:
2911 case ZigClangType_ObjCTypeParam:
2912 case ZigClangType_DeducedTemplateSpecialization:
2913 case ZigClangType_DependentAddressSpace:
2914 case ZigClangType_DependentVector:
27472915 return res;
27482916 }
27492917 zig_unreachable();
......@@ -2752,11 +2920,12 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
27522920static AstNode *trans_while_loop(Context *c, TransScope *scope, const clang::WhileStmt *stmt) {
27532921 TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
27542922
2755 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2923 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope,
2924 bitcast(stmt->getCond()), TransRValue);
27562925 if (while_scope->node->data.while_expr.condition == nullptr)
27572926 return nullptr;
27582927
2759 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(),
2928 TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()),
27602929 &while_scope->node->data.while_expr.body);
27612930 if (body_scope == nullptr)
27622931 return nullptr;
......@@ -2769,17 +2938,18 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const clang::I
27692938 // if (c) t else e
27702939 AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
27712940
2772 TransScope *then_scope = trans_stmt(c, scope, stmt->getThen(), &if_node->data.if_bool_expr.then_block);
2941 TransScope *then_scope = trans_stmt(c, scope, bitcast(stmt->getThen()), &if_node->data.if_bool_expr.then_block);
27732942 if (then_scope == nullptr)
27742943 return nullptr;
27752944
27762945 if (stmt->getElse() != nullptr) {
2777 TransScope *else_scope = trans_stmt(c, scope, stmt->getElse(), &if_node->data.if_bool_expr.else_node);
2946 TransScope *else_scope = trans_stmt(c, scope, bitcast(stmt->getElse()), &if_node->data.if_bool_expr.else_node);
27782947 if (else_scope == nullptr)
27792948 return nullptr;
27802949 }
27812950
2782 if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
2951 if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, bitcast(stmt->getCond()),
2952 TransRValue);
27832953 if (if_node->data.if_bool_expr.condition == nullptr)
27842954 return nullptr;
27852955
......@@ -2789,18 +2959,18 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const clang::I
27892959static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::CallExpr *stmt) {
27902960 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
27912961
2792 AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, stmt->getCallee(), TransRValue);
2962 AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getCallee()), TransRValue);
27932963 if (callee_raw_node == nullptr)
27942964 return nullptr;
27952965
27962966 bool is_ptr = false;
2797 const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
2967 const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(bitcast(stmt->getCallee()->getType()), &is_ptr);
27982968 AstNode *callee_node = nullptr;
27992969 if (is_ptr && fn_ty) {
2800 if (stmt->getCallee()->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
2970 if ((ZigClangStmtClass)stmt->getCallee()->getStmtClass() == ZigClangStmt_ImplicitCastExprClass) {
28012971 const clang::ImplicitCastExpr *implicit_cast = static_cast<const clang::ImplicitCastExpr *>(stmt->getCallee());
2802 if (implicit_cast->getCastKind() == clang::CK_FunctionToPointerDecay) {
2803 if (implicit_cast->getSubExpr()->getStmtClass() == clang::Stmt::DeclRefExprClass) {
2972 if ((ZigClangCK)implicit_cast->getCastKind() == ZigClangCK_FunctionToPointerDecay) {
2973 if ((ZigClangStmtClass)implicit_cast->getSubExpr()->getStmtClass() == ZigClangStmt_DeclRefExprClass) {
28042974 const clang::DeclRefExpr *decl_ref = static_cast<const clang::DeclRefExpr *>(implicit_cast->getSubExpr());
28052975 const clang::Decl *decl = decl_ref->getFoundDecl();
28062976 if (decl->getKind() == clang::Decl::Function) {
......@@ -2819,7 +2989,7 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
28192989 node->data.fn_call_expr.fn_ref_expr = callee_node;
28202990
28212991 unsigned num_args = stmt->getNumArgs();
2822 const clang::Expr * const* args = stmt->getArgs();
2992 const ZigClangExpr * const* args = reinterpret_cast<const ZigClangExpr * const*>(stmt->getArgs());
28232993 for (unsigned i = 0; i < num_args; i += 1) {
28242994 AstNode *arg_node = trans_expr(c, ResultUsedYes, scope, args[i], TransRValue);
28252995 if (arg_node == nullptr)
......@@ -2828,7 +2998,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
28282998 node->data.fn_call_expr.params.append(arg_node);
28292999 }
28303000
2831 if (result_used == ResultUsedNo && fn_ty && !qual_type_canon(fn_ty->getReturnType())->isVoidType()) {
3001 if (result_used == ResultUsedNo && fn_ty &&
3002 !ZigClangType_isVoidType(qual_type_canon(bitcast(fn_ty->getReturnType()))))
3003 {
28323004 node = trans_create_node_bin_op(c, trans_create_node_symbol_str(c, "_"), BinOpTypeAssign, node);
28333005 }
28343006
......@@ -2838,7 +3010,7 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
28383010static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope *scope,
28393011 const clang::MemberExpr *stmt)
28403012{
2841 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
3013 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getBase()), TransRValue);
28423014 if (container_node == nullptr)
28433015 return nullptr;
28443016
......@@ -2846,18 +3018,18 @@ static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope
28463018 container_node = trans_create_node_unwrap_null(c, container_node);
28473019 }
28483020
2849 const char *name = decl_name(stmt->getMemberDecl());
3021 const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)stmt->getMemberDecl());
28503022
28513023 AstNode *node = trans_create_node_field_access_str(c, container_node, name);
28523024 return maybe_suppress_result(c, result_used, node);
28533025}
28543026
28553027static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ArraySubscriptExpr *stmt) {
2856 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
3028 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getBase()), TransRValue);
28573029 if (container_node == nullptr)
28583030 return nullptr;
28593031
2860 AstNode *idx_node = trans_expr(c, ResultUsedYes, scope, stmt->getIdx(), TransRValue);
3032 AstNode *idx_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getIdx()), TransRValue);
28613033 if (idx_node == nullptr)
28623034 return nullptr;
28633035
......@@ -2871,11 +3043,12 @@ static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, T
28713043static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
28723044 const clang::CStyleCastExpr *stmt, TransLRValue lrvalue)
28733045{
2874 AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), lrvalue);
3046 AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), lrvalue);
28753047 if (sub_expr_node == nullptr)
28763048 return nullptr;
28773049
2878 AstNode *cast = trans_c_cast(c, stmt->getBeginLoc(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);
3050 AstNode *cast = trans_c_cast(c, bitcast(stmt->getBeginLoc()), bitcast(stmt->getType()),
3051 bitcast(stmt->getSubExpr()->getType()), sub_expr_node);
28793052 if (cast == nullptr)
28803053 return nullptr;
28813054
......@@ -2885,7 +3058,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran
28853058static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used,
28863059 TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt)
28873060{
2888 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getBeginLoc());
3061 AstNode *type_node = trans_qual_type(c, bitcast(stmt->getTypeOfArgument()), bitcast(stmt->getBeginLoc()));
28893062 if (type_node == nullptr)
28903063 return nullptr;
28913064
......@@ -2901,7 +3074,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang:
29013074
29023075 AstNode *body_node;
29033076 TransScope *child_scope;
2904 if (stmt->getBody()->getStmtClass() == clang::Stmt::CompoundStmtClass) {
3077 if ((ZigClangStmtClass)stmt->getBody()->getStmtClass() == ZigClangStmt_CompoundStmtClass) {
29053078 // there's already a block in C, so we'll append our condition to it.
29063079 // c: do {
29073080 // c: a;
......@@ -2914,7 +3087,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang:
29143087 // zig: }
29153088
29163089 // We call the low level function so that we can set child_scope to the scope of the generated block.
2917 if (trans_stmt_extra(c, &while_scope->base, stmt->getBody(), ResultUsedNo, TransRValue, &body_node,
3090 if (trans_stmt_extra(c, &while_scope->base, bitcast(stmt->getBody()), ResultUsedNo, TransRValue, &body_node,
29183091 nullptr, &child_scope))
29193092 {
29203093 return nullptr;
......@@ -2932,7 +3105,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang:
29323105 TransScopeBlock *child_block_scope = trans_scope_block_create(c, &while_scope->base);
29333106 body_node = child_block_scope->node;
29343107 AstNode *child_statement;
2935 child_scope = trans_stmt(c, &child_block_scope->base, stmt->getBody(), &child_statement);
3108 child_scope = trans_stmt(c, &child_block_scope->base, bitcast(stmt->getBody()), &child_statement);
29363109 if (child_scope == nullptr) return nullptr;
29373110 if (child_statement != nullptr) {
29383111 body_node->data.block.statements.append(child_statement);
......@@ -2940,7 +3113,7 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang:
29403113 }
29413114
29423115 // if (!cond) break;
2943 AstNode *condition_node = trans_expr(c, ResultUsedYes, child_scope, stmt->getCond(), TransRValue);
3116 AstNode *condition_node = trans_expr(c, ResultUsedYes, child_scope, bitcast(stmt->getCond()), TransRValue);
29443117 if (condition_node == nullptr) return nullptr;
29453118 AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr);
29463119 terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node);
......@@ -2958,7 +3131,7 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang
29583131 AstNode *loop_block_node;
29593132 TransScopeWhile *while_scope;
29603133 TransScope *cond_scope;
2961 const clang::Stmt *init_stmt = stmt->getInit();
3134 const ZigClangStmt *init_stmt = bitcast(stmt->getInit());
29623135 if (init_stmt == nullptr) {
29633136 while_scope = trans_scope_while_create(c, parent_scope);
29643137 loop_block_node = while_scope->node;
......@@ -2979,35 +3152,27 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang
29793152 child_scope->node->data.block.statements.append(while_scope->node);
29803153 }
29813154
2982 const clang::Stmt *cond_stmt = stmt->getCond();
2983 if (cond_stmt == nullptr) {
3155 const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
3156 if (cond_expr == nullptr) {
29843157 while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
29853158 } else {
2986 if (clang::Expr::classof(cond_stmt)) {
2987 const clang::Expr *cond_expr = static_cast<const clang::Expr*>(cond_stmt);
2988 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue);
3159 while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope,
3160 cond_expr, TransRValue);
29893161
2990 if (while_scope->node->data.while_expr.condition == nullptr)
2991 return nullptr;
2992 } else {
2993 TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt,
2994 &while_scope->node->data.while_expr.condition);
2995 if (end_cond_scope == nullptr)
2996 return nullptr;
2997 }
3162 if (while_scope->node->data.while_expr.condition == nullptr)
3163 return nullptr;
29983164 }
29993165
3000 const clang::Stmt *inc_stmt = stmt->getInc();
3001 if (inc_stmt != nullptr) {
3002 AstNode *inc_node;
3003 TransScope *inc_scope = trans_stmt(c, cond_scope, inc_stmt, &inc_node);
3004 if (inc_scope == nullptr)
3166 const ZigClangExpr *inc_expr = bitcast(stmt->getInc());
3167 if (inc_expr != nullptr) {
3168 AstNode *inc_node = trans_expr(c, ResultUsedNo, cond_scope, inc_expr, TransRValue);
3169 if (inc_node == nullptr)
30053170 return nullptr;
30063171 while_scope->node->data.while_expr.continue_expr = inc_node;
30073172 }
30083173
30093174 AstNode *body_statement;
3010 TransScope *body_scope = trans_stmt(c, &while_scope->base, stmt->getBody(), &body_statement);
3175 TransScope *body_scope = trans_stmt(c, &while_scope->base, bitcast(stmt->getBody()), &body_statement);
30113176 if (body_scope == nullptr)
30123177 return nullptr;
30133178
......@@ -3030,7 +3195,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl
30303195 switch_scope = trans_scope_switch_create(c, &block_scope->base);
30313196 } else {
30323197 AstNode *vars_node;
3033 TransScope *var_scope = trans_stmt(c, &block_scope->base, var_decl_stmt, &vars_node);
3198 TransScope *var_scope = trans_stmt(c, &block_scope->base, (const ZigClangStmt *)var_decl_stmt, &vars_node);
30343199 if (var_scope == nullptr)
30353200 return nullptr;
30363201 if (vars_node != nullptr)
......@@ -3044,7 +3209,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl
30443209 switch_scope->end_label_name = end_label_name;
30453210 block_scope->node->data.block.name = end_label_name;
30463211
3047 const clang::Expr *cond_expr = stmt->getCond();
3212 const ZigClangExpr *cond_expr = bitcast(stmt->getCond());
30483213 assert(cond_expr != nullptr);
30493214
30503215 AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
......@@ -3053,9 +3218,9 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const cl
30533218 switch_scope->switch_node->data.switch_expr.expr = expr_node;
30543219
30553220 AstNode *body_node;
3056 const clang::Stmt *body_stmt = stmt->getBody();
3057 if (body_stmt->getStmtClass() == clang::Stmt::CompoundStmtClass) {
3058 if (trans_compound_stmt_inline(c, &switch_scope->base, (const clang::CompoundStmt *)body_stmt,
3221 const ZigClangStmt *body_stmt = bitcast(stmt->getBody());
3222 if (ZigClangStmt_getStmtClass(body_stmt) == ZigClangStmt_CompoundStmtClass) {
3223 if (trans_compound_stmt_inline(c, &switch_scope->base, (const ZigClangCompoundStmt *)body_stmt,
30593224 block_scope->node, nullptr))
30603225 {
30613226 return nullptr;
......@@ -3092,7 +3257,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::
30923257 *out_node = nullptr;
30933258
30943259 if (stmt->getRHS() != nullptr) {
3095 emit_warning(c, stmt->getBeginLoc(), "TODO support GNU switch case a ... b extension");
3260 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support GNU switch case a ... b extension");
30963261 return ErrorUnexpected;
30973262 }
30983263
......@@ -3105,7 +3270,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::
31053270 {
31063271 // Add the prong
31073272 AstNode *prong_node = trans_create_node(c, NodeTypeSwitchProng);
3108 AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, stmt->getLHS(), TransRValue);
3273 AstNode *item_node = trans_expr(c, ResultUsedYes, &switch_scope->base, bitcast(stmt->getLHS()), TransRValue);
31093274 if (item_node == nullptr)
31103275 return ErrorUnexpected;
31113276 prong_node->data.switch_prong.items.append(item_node);
......@@ -3122,7 +3287,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::
31223287 scope_block->node->data.block.statements.append(case_block);
31233288
31243289 AstNode *sub_stmt_node;
3125 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
3290 TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node);
31263291 if (new_scope == nullptr)
31273292 return ErrorUnexpected;
31283293 if (sub_stmt_node != nullptr)
......@@ -3159,7 +3324,7 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan
31593324 scope_block->node->data.block.statements.append(case_block);
31603325
31613326 AstNode *sub_stmt_node;
3162 TransScope *new_scope = trans_stmt(c, parent_scope, stmt->getSubStmt(), &sub_stmt_node);
3327 TransScope *new_scope = trans_stmt(c, parent_scope, bitcast(stmt->getSubStmt()), &sub_stmt_node);
31633328 if (new_scope == nullptr)
31643329 return ErrorUnexpected;
31653330 if (sub_stmt_node != nullptr)
......@@ -3177,13 +3342,13 @@ static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransSc
31773342 return maybe_suppress_result(c, result_used, node);
31783343 }
31793344 case clang::StringLiteral::UTF16:
3180 emit_warning(c, stmt->getBeginLoc(), "TODO support UTF16 string literals");
3345 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 string literals");
31813346 return nullptr;
31823347 case clang::StringLiteral::UTF32:
3183 emit_warning(c, stmt->getBeginLoc(), "TODO support UTF32 string literals");
3348 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 string literals");
31843349 return nullptr;
31853350 case clang::StringLiteral::Wide:
3186 emit_warning(c, stmt->getBeginLoc(), "TODO support wide string literals");
3351 emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide string literals");
31873352 return nullptr;
31883353 }
31893354 zig_unreachable();
......@@ -3222,45 +3387,45 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_
32223387 return ErrorNone;
32233388}
32243389
3225static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt,
3390static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *stmt,
32263391 ResultUsed result_used, TransLRValue lrvalue,
32273392 AstNode **out_node, TransScope **out_child_scope,
32283393 TransScope **out_node_scope)
32293394{
3230 clang::Stmt::StmtClass sc = stmt->getStmtClass();
3395 ZigClangStmtClass sc = ZigClangStmt_getStmtClass(stmt);
32313396 switch (sc) {
3232 case clang::Stmt::ReturnStmtClass:
3397 case ZigClangStmt_ReturnStmtClass:
32333398 return wrap_stmt(out_node, out_child_scope, scope,
32343399 trans_return_stmt(c, scope, (const clang::ReturnStmt *)stmt));
3235 case clang::Stmt::CompoundStmtClass:
3400 case ZigClangStmt_CompoundStmtClass:
32363401 return wrap_stmt(out_node, out_child_scope, scope,
3237 trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope));
3238 case clang::Stmt::IntegerLiteralClass:
3402 trans_compound_stmt(c, scope, (const ZigClangCompoundStmt *)stmt, out_node_scope));
3403 case ZigClangStmt_IntegerLiteralClass:
32393404 return wrap_stmt(out_node, out_child_scope, scope,
32403405 trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt));
3241 case clang::Stmt::ConditionalOperatorClass:
3406 case ZigClangStmt_ConditionalOperatorClass:
32423407 return wrap_stmt(out_node, out_child_scope, scope,
32433408 trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt));
3244 case clang::Stmt::BinaryOperatorClass:
3409 case ZigClangStmt_BinaryOperatorClass:
32453410 return wrap_stmt(out_node, out_child_scope, scope,
32463411 trans_binary_operator(c, result_used, scope, (const clang::BinaryOperator *)stmt));
3247 case clang::Stmt::CompoundAssignOperatorClass:
3412 case ZigClangStmt_CompoundAssignOperatorClass:
32483413 return wrap_stmt(out_node, out_child_scope, scope,
32493414 trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt));
3250 case clang::Stmt::ImplicitCastExprClass:
3415 case ZigClangStmt_ImplicitCastExprClass:
32513416 return wrap_stmt(out_node, out_child_scope, scope,
32523417 trans_implicit_cast_expr(c, result_used, scope, (const clang::ImplicitCastExpr *)stmt));
3253 case clang::Stmt::DeclRefExprClass:
3418 case ZigClangStmt_DeclRefExprClass:
32543419 return wrap_stmt(out_node, out_child_scope, scope,
32553420 trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue));
3256 case clang::Stmt::UnaryOperatorClass:
3421 case ZigClangStmt_UnaryOperatorClass:
32573422 return wrap_stmt(out_node, out_child_scope, scope,
32583423 trans_unary_operator(c, result_used, scope, (const clang::UnaryOperator *)stmt));
3259 case clang::Stmt::DeclStmtClass:
3424 case ZigClangStmt_DeclStmtClass:
32603425 return trans_local_declaration(c, scope, (const clang::DeclStmt *)stmt, out_node, out_child_scope);
3261 case clang::Stmt::DoStmtClass:
3262 case clang::Stmt::WhileStmtClass: {
3263 AstNode *while_node = sc == clang::Stmt::DoStmtClass
3426 case ZigClangStmt_DoStmtClass:
3427 case ZigClangStmt_WhileStmtClass: {
3428 AstNode *while_node = sc == ZigClangStmt_DoStmtClass
32643429 ? trans_do_loop(c, scope, (const clang::DoStmt *)stmt)
32653430 : trans_while_loop(c, scope, (const clang::WhileStmt *)stmt);
32663431
......@@ -3273,572 +3438,574 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
32733438
32743439 return wrap_stmt(out_node, out_child_scope, scope, while_node);
32753440 }
3276 case clang::Stmt::IfStmtClass:
3441 case ZigClangStmt_IfStmtClass:
32773442 return wrap_stmt(out_node, out_child_scope, scope,
32783443 trans_if_statement(c, scope, (const clang::IfStmt *)stmt));
3279 case clang::Stmt::CallExprClass:
3444 case ZigClangStmt_CallExprClass:
32803445 return wrap_stmt(out_node, out_child_scope, scope,
32813446 trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));
3282 case clang::Stmt::NullStmtClass:
3447 case ZigClangStmt_NullStmtClass:
32833448 *out_node = trans_create_node(c, NodeTypeBlock);
32843449 *out_child_scope = scope;
32853450 return ErrorNone;
3286 case clang::Stmt::MemberExprClass:
3451 case ZigClangStmt_MemberExprClass:
32873452 return wrap_stmt(out_node, out_child_scope, scope,
32883453 trans_member_expr(c, result_used, scope, (const clang::MemberExpr *)stmt));
3289 case clang::Stmt::ArraySubscriptExprClass:
3454 case ZigClangStmt_ArraySubscriptExprClass:
32903455 return wrap_stmt(out_node, out_child_scope, scope,
32913456 trans_array_subscript_expr(c, result_used, scope, (const clang::ArraySubscriptExpr *)stmt));
3292 case clang::Stmt::CStyleCastExprClass:
3457 case ZigClangStmt_CStyleCastExprClass:
32933458 return wrap_stmt(out_node, out_child_scope, scope,
32943459 trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue));
3295 case clang::Stmt::UnaryExprOrTypeTraitExprClass:
3460 case ZigClangStmt_UnaryExprOrTypeTraitExprClass:
32963461 return wrap_stmt(out_node, out_child_scope, scope,
32973462 trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt));
3298 case clang::Stmt::ForStmtClass: {
3463 case ZigClangStmt_ForStmtClass: {
32993464 AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt);
33003465 return wrap_stmt(out_node, out_child_scope, scope, node);
33013466 }
3302 case clang::Stmt::StringLiteralClass:
3467 case ZigClangStmt_StringLiteralClass:
33033468 return wrap_stmt(out_node, out_child_scope, scope,
33043469 trans_string_literal(c, result_used, scope, (const clang::StringLiteral *)stmt));
3305 case clang::Stmt::BreakStmtClass:
3470 case ZigClangStmt_BreakStmtClass:
33063471 return wrap_stmt(out_node, out_child_scope, scope,
33073472 trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt));
3308 case clang::Stmt::ContinueStmtClass:
3473 case ZigClangStmt_ContinueStmtClass:
33093474 return wrap_stmt(out_node, out_child_scope, scope,
33103475 trans_continue_stmt(c, scope, (const clang::ContinueStmt *)stmt));
3311 case clang::Stmt::ParenExprClass:
3476 case ZigClangStmt_ParenExprClass:
33123477 return wrap_stmt(out_node, out_child_scope, scope,
3313 trans_expr(c, result_used, scope, ((const clang::ParenExpr*)stmt)->getSubExpr(), lrvalue));
3314 case clang::Stmt::SwitchStmtClass:
3478 trans_expr(c, result_used, scope,
3479 bitcast(((const clang::ParenExpr*)stmt)->getSubExpr()), lrvalue));
3480 case ZigClangStmt_SwitchStmtClass:
33153481 return wrap_stmt(out_node, out_child_scope, scope,
33163482 trans_switch_stmt(c, scope, (const clang::SwitchStmt *)stmt));
3317 case clang::Stmt::CaseStmtClass:
3483 case ZigClangStmt_CaseStmtClass:
33183484 return trans_switch_case(c, scope, (const clang::CaseStmt *)stmt, out_node, out_child_scope);
3319 case clang::Stmt::DefaultStmtClass:
3485 case ZigClangStmt_DefaultStmtClass:
33203486 return trans_switch_default(c, scope, (const clang::DefaultStmt *)stmt, out_node, out_child_scope);
3321 case clang::Stmt::ConstantExprClass:
3487 case ZigClangStmt_ConstantExprClass:
33223488 return wrap_stmt(out_node, out_child_scope, scope,
33233489 trans_constant_expr(c, result_used, (const clang::ConstantExpr *)stmt));
3324 case clang::Stmt::PredefinedExprClass:
3490 case ZigClangStmt_PredefinedExprClass:
33253491 return wrap_stmt(out_node, out_child_scope, scope,
33263492 trans_predefined_expr(c, result_used, scope, (const clang::PredefinedExpr *)stmt));
3327 case clang::Stmt::StmtExprClass:
3493 case ZigClangStmt_StmtExprClass:
33283494 return wrap_stmt(out_node, out_child_scope, scope,
33293495 trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope));
3330 case clang::Stmt::NoStmtClass:
3331 emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoStmtClass");
3332 return ErrorUnexpected;
3333 case clang::Stmt::GCCAsmStmtClass:
3334 emit_warning(c, stmt->getBeginLoc(), "TODO handle C GCCAsmStmtClass");
3496 case ZigClangStmt_NoStmtClass:
3497 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoStmtClass");
33353498 return ErrorUnexpected;
3336 case clang::Stmt::MSAsmStmtClass:
3337 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSAsmStmtClass");
3499 case ZigClangStmt_GCCAsmStmtClass:
3500 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GCCAsmStmtClass");
33383501 return ErrorUnexpected;
3339 case clang::Stmt::AttributedStmtClass:
3340 emit_warning(c, stmt->getBeginLoc(), "TODO handle C AttributedStmtClass");
3502 case ZigClangStmt_MSAsmStmtClass:
3503 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSAsmStmtClass");
33413504 return ErrorUnexpected;
3342 case clang::Stmt::CXXCatchStmtClass:
3343 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXCatchStmtClass");
3505 case ZigClangStmt_AttributedStmtClass:
3506 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AttributedStmtClass");
33443507 return ErrorUnexpected;
3345 case clang::Stmt::CXXForRangeStmtClass:
3346 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXForRangeStmtClass");
3508 case ZigClangStmt_CXXCatchStmtClass:
3509 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXCatchStmtClass");
33473510 return ErrorUnexpected;
3348 case clang::Stmt::CXXTryStmtClass:
3349 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTryStmtClass");
3511 case ZigClangStmt_CXXForRangeStmtClass:
3512 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXForRangeStmtClass");
33503513 return ErrorUnexpected;
3351 case clang::Stmt::CapturedStmtClass:
3352 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CapturedStmtClass");
3514 case ZigClangStmt_CXXTryStmtClass:
3515 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTryStmtClass");
33533516 return ErrorUnexpected;
3354 case clang::Stmt::CoreturnStmtClass:
3355 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoreturnStmtClass");
3517 case ZigClangStmt_CapturedStmtClass:
3518 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CapturedStmtClass");
33563519 return ErrorUnexpected;
3357 case clang::Stmt::CoroutineBodyStmtClass:
3358 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoroutineBodyStmtClass");
3520 case ZigClangStmt_CoreturnStmtClass:
3521 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoreturnStmtClass");
33593522 return ErrorUnexpected;
3360 case clang::Stmt::BinaryConditionalOperatorClass:
3361 emit_warning(c, stmt->getBeginLoc(), "TODO handle C BinaryConditionalOperatorClass");
3523 case ZigClangStmt_CoroutineBodyStmtClass:
3524 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoroutineBodyStmtClass");
33623525 return ErrorUnexpected;
3363 case clang::Stmt::AddrLabelExprClass:
3364 emit_warning(c, stmt->getBeginLoc(), "TODO handle C AddrLabelExprClass");
3526 case ZigClangStmt_BinaryConditionalOperatorClass:
3527 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BinaryConditionalOperatorClass");
33653528 return ErrorUnexpected;
3366 case clang::Stmt::ArrayInitIndexExprClass:
3367 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitIndexExprClass");
3529 case ZigClangStmt_AddrLabelExprClass:
3530 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AddrLabelExprClass");
33683531 return ErrorUnexpected;
3369 case clang::Stmt::ArrayInitLoopExprClass:
3370 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayInitLoopExprClass");
3532 case ZigClangStmt_ArrayInitIndexExprClass:
3533 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitIndexExprClass");
33713534 return ErrorUnexpected;
3372 case clang::Stmt::ArrayTypeTraitExprClass:
3373 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ArrayTypeTraitExprClass");
3535 case ZigClangStmt_ArrayInitLoopExprClass:
3536 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayInitLoopExprClass");
33743537 return ErrorUnexpected;
3375 case clang::Stmt::AsTypeExprClass:
3376 emit_warning(c, stmt->getBeginLoc(), "TODO handle C AsTypeExprClass");
3538 case ZigClangStmt_ArrayTypeTraitExprClass:
3539 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ArrayTypeTraitExprClass");
33773540 return ErrorUnexpected;
3378 case clang::Stmt::AtomicExprClass:
3379 emit_warning(c, stmt->getBeginLoc(), "TODO handle C AtomicExprClass");
3541 case ZigClangStmt_AsTypeExprClass:
3542 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AsTypeExprClass");
33803543 return ErrorUnexpected;
3381 case clang::Stmt::BlockExprClass:
3382 emit_warning(c, stmt->getBeginLoc(), "TODO handle C BlockExprClass");
3544 case ZigClangStmt_AtomicExprClass:
3545 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C AtomicExprClass");
33833546 return ErrorUnexpected;
3384 case clang::Stmt::CXXBindTemporaryExprClass:
3385 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBindTemporaryExprClass");
3547 case ZigClangStmt_BlockExprClass:
3548 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C BlockExprClass");
33863549 return ErrorUnexpected;
3387 case clang::Stmt::CXXBoolLiteralExprClass:
3388 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXBoolLiteralExprClass");
3550 case ZigClangStmt_CXXBindTemporaryExprClass:
3551 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBindTemporaryExprClass");
33893552 return ErrorUnexpected;
3390 case clang::Stmt::CXXConstructExprClass:
3391 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstructExprClass");
3553 case ZigClangStmt_CXXBoolLiteralExprClass:
3554 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXBoolLiteralExprClass");
33923555 return ErrorUnexpected;
3393 case clang::Stmt::CXXTemporaryObjectExprClass:
3394 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTemporaryObjectExprClass");
3556 case ZigClangStmt_CXXConstructExprClass:
3557 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstructExprClass");
33953558 return ErrorUnexpected;
3396 case clang::Stmt::CXXDefaultArgExprClass:
3397 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultArgExprClass");
3559 case ZigClangStmt_CXXTemporaryObjectExprClass:
3560 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTemporaryObjectExprClass");
33983561 return ErrorUnexpected;
3399 case clang::Stmt::CXXDefaultInitExprClass:
3400 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDefaultInitExprClass");
3562 case ZigClangStmt_CXXDefaultArgExprClass:
3563 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultArgExprClass");
34013564 return ErrorUnexpected;
3402 case clang::Stmt::CXXDeleteExprClass:
3403 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDeleteExprClass");
3565 case ZigClangStmt_CXXDefaultInitExprClass:
3566 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDefaultInitExprClass");
34043567 return ErrorUnexpected;
3405 case clang::Stmt::CXXDependentScopeMemberExprClass:
3406 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDependentScopeMemberExprClass");
3568 case ZigClangStmt_CXXDeleteExprClass:
3569 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDeleteExprClass");
34073570 return ErrorUnexpected;
3408 case clang::Stmt::CXXFoldExprClass:
3409 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFoldExprClass");
3571 case ZigClangStmt_CXXDependentScopeMemberExprClass:
3572 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDependentScopeMemberExprClass");
34103573 return ErrorUnexpected;
3411 case clang::Stmt::CXXInheritedCtorInitExprClass:
3412 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXInheritedCtorInitExprClass");
3574 case ZigClangStmt_CXXFoldExprClass:
3575 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFoldExprClass");
34133576 return ErrorUnexpected;
3414 case clang::Stmt::CXXNewExprClass:
3415 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNewExprClass");
3577 case ZigClangStmt_CXXInheritedCtorInitExprClass:
3578 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXInheritedCtorInitExprClass");
34163579 return ErrorUnexpected;
3417 case clang::Stmt::CXXNoexceptExprClass:
3418 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNoexceptExprClass");
3580 case ZigClangStmt_CXXNewExprClass:
3581 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNewExprClass");
34193582 return ErrorUnexpected;
3420 case clang::Stmt::CXXNullPtrLiteralExprClass:
3421 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXNullPtrLiteralExprClass");
3583 case ZigClangStmt_CXXNoexceptExprClass:
3584 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNoexceptExprClass");
34223585 return ErrorUnexpected;
3423 case clang::Stmt::CXXPseudoDestructorExprClass:
3424 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXPseudoDestructorExprClass");
3586 case ZigClangStmt_CXXNullPtrLiteralExprClass:
3587 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXNullPtrLiteralExprClass");
34253588 return ErrorUnexpected;
3426 case clang::Stmt::CXXScalarValueInitExprClass:
3427 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXScalarValueInitExprClass");
3589 case ZigClangStmt_CXXPseudoDestructorExprClass:
3590 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXPseudoDestructorExprClass");
34283591 return ErrorUnexpected;
3429 case clang::Stmt::CXXStdInitializerListExprClass:
3430 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStdInitializerListExprClass");
3592 case ZigClangStmt_CXXScalarValueInitExprClass:
3593 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXScalarValueInitExprClass");
34313594 return ErrorUnexpected;
3432 case clang::Stmt::CXXThisExprClass:
3433 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThisExprClass");
3595 case ZigClangStmt_CXXStdInitializerListExprClass:
3596 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStdInitializerListExprClass");
34343597 return ErrorUnexpected;
3435 case clang::Stmt::CXXThrowExprClass:
3436 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXThrowExprClass");
3598 case ZigClangStmt_CXXThisExprClass:
3599 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThisExprClass");
34373600 return ErrorUnexpected;
3438 case clang::Stmt::CXXTypeidExprClass:
3439 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXTypeidExprClass");
3601 case ZigClangStmt_CXXThrowExprClass:
3602 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXThrowExprClass");
34403603 return ErrorUnexpected;
3441 case clang::Stmt::CXXUnresolvedConstructExprClass:
3442 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUnresolvedConstructExprClass");
3604 case ZigClangStmt_CXXTypeidExprClass:
3605 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXTypeidExprClass");
34433606 return ErrorUnexpected;
3444 case clang::Stmt::CXXUuidofExprClass:
3445 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXUuidofExprClass");
3607 case ZigClangStmt_CXXUnresolvedConstructExprClass:
3608 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUnresolvedConstructExprClass");
34463609 return ErrorUnexpected;
3447 case clang::Stmt::CUDAKernelCallExprClass:
3448 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CUDAKernelCallExprClass");
3610 case ZigClangStmt_CXXUuidofExprClass:
3611 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXUuidofExprClass");
34493612 return ErrorUnexpected;
3450 case clang::Stmt::CXXMemberCallExprClass:
3451 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXMemberCallExprClass");
3613 case ZigClangStmt_CUDAKernelCallExprClass:
3614 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CUDAKernelCallExprClass");
34523615 return ErrorUnexpected;
3453 case clang::Stmt::CXXOperatorCallExprClass:
3454 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXOperatorCallExprClass");
3616 case ZigClangStmt_CXXMemberCallExprClass:
3617 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXMemberCallExprClass");
34553618 return ErrorUnexpected;
3456 case clang::Stmt::UserDefinedLiteralClass:
3457 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UserDefinedLiteralClass");
3619 case ZigClangStmt_CXXOperatorCallExprClass:
3620 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXOperatorCallExprClass");
34583621 return ErrorUnexpected;
3459 case clang::Stmt::CXXFunctionalCastExprClass:
3460 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXFunctionalCastExprClass");
3622 case ZigClangStmt_UserDefinedLiteralClass:
3623 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UserDefinedLiteralClass");
34613624 return ErrorUnexpected;
3462 case clang::Stmt::CXXConstCastExprClass:
3463 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXConstCastExprClass");
3625 case ZigClangStmt_CXXFunctionalCastExprClass:
3626 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXFunctionalCastExprClass");
34643627 return ErrorUnexpected;
3465 case clang::Stmt::CXXDynamicCastExprClass:
3466 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXDynamicCastExprClass");
3628 case ZigClangStmt_CXXConstCastExprClass:
3629 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXConstCastExprClass");
34673630 return ErrorUnexpected;
3468 case clang::Stmt::CXXReinterpretCastExprClass:
3469 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXReinterpretCastExprClass");
3631 case ZigClangStmt_CXXDynamicCastExprClass:
3632 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXDynamicCastExprClass");
34703633 return ErrorUnexpected;
3471 case clang::Stmt::CXXStaticCastExprClass:
3472 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CXXStaticCastExprClass");
3634 case ZigClangStmt_CXXReinterpretCastExprClass:
3635 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXReinterpretCastExprClass");
34733636 return ErrorUnexpected;
3474 case clang::Stmt::ObjCBridgedCastExprClass:
3475 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBridgedCastExprClass");
3637 case ZigClangStmt_CXXStaticCastExprClass:
3638 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CXXStaticCastExprClass");
34763639 return ErrorUnexpected;
3477 case clang::Stmt::CharacterLiteralClass:
3478 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CharacterLiteralClass");
3640 case ZigClangStmt_ObjCBridgedCastExprClass:
3641 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBridgedCastExprClass");
34793642 return ErrorUnexpected;
3480 case clang::Stmt::ChooseExprClass:
3481 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ChooseExprClass");
3643 case ZigClangStmt_CharacterLiteralClass:
3644 return wrap_stmt(out_node, out_child_scope, scope,
3645 trans_character_literal(c, result_used, (const clang::CharacterLiteral *)stmt));
34823646 return ErrorUnexpected;
3483 case clang::Stmt::CompoundLiteralExprClass:
3484 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CompoundLiteralExprClass");
3647 case ZigClangStmt_ChooseExprClass:
3648 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ChooseExprClass");
34853649 return ErrorUnexpected;
3486 case clang::Stmt::ConvertVectorExprClass:
3487 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ConvertVectorExprClass");
3650 case ZigClangStmt_CompoundLiteralExprClass:
3651 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CompoundLiteralExprClass");
34883652 return ErrorUnexpected;
3489 case clang::Stmt::CoawaitExprClass:
3490 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoawaitExprClass");
3653 case ZigClangStmt_ConvertVectorExprClass:
3654 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ConvertVectorExprClass");
34913655 return ErrorUnexpected;
3492 case clang::Stmt::CoyieldExprClass:
3493 emit_warning(c, stmt->getBeginLoc(), "TODO handle C CoyieldExprClass");
3656 case ZigClangStmt_CoawaitExprClass:
3657 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoawaitExprClass");
34943658 return ErrorUnexpected;
3495 case clang::Stmt::DependentCoawaitExprClass:
3496 emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentCoawaitExprClass");
3659 case ZigClangStmt_CoyieldExprClass:
3660 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CoyieldExprClass");
34973661 return ErrorUnexpected;
3498 case clang::Stmt::DependentScopeDeclRefExprClass:
3499 emit_warning(c, stmt->getBeginLoc(), "TODO handle C DependentScopeDeclRefExprClass");
3662 case ZigClangStmt_DependentCoawaitExprClass:
3663 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentCoawaitExprClass");
35003664 return ErrorUnexpected;
3501 case clang::Stmt::DesignatedInitExprClass:
3502 emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitExprClass");
3665 case ZigClangStmt_DependentScopeDeclRefExprClass:
3666 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DependentScopeDeclRefExprClass");
35033667 return ErrorUnexpected;
3504 case clang::Stmt::DesignatedInitUpdateExprClass:
3505 emit_warning(c, stmt->getBeginLoc(), "TODO handle C DesignatedInitUpdateExprClass");
3668 case ZigClangStmt_DesignatedInitExprClass:
3669 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitExprClass");
35063670 return ErrorUnexpected;
3507 case clang::Stmt::ExpressionTraitExprClass:
3508 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExpressionTraitExprClass");
3671 case ZigClangStmt_DesignatedInitUpdateExprClass:
3672 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C DesignatedInitUpdateExprClass");
35093673 return ErrorUnexpected;
3510 case clang::Stmt::ExtVectorElementExprClass:
3511 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExtVectorElementExprClass");
3674 case ZigClangStmt_ExpressionTraitExprClass:
3675 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExpressionTraitExprClass");
35123676 return ErrorUnexpected;
3513 case clang::Stmt::FixedPointLiteralClass:
3514 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FixedPointLiteralClass");
3677 case ZigClangStmt_ExtVectorElementExprClass:
3678 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExtVectorElementExprClass");
35153679 return ErrorUnexpected;
3516 case clang::Stmt::FloatingLiteralClass:
3517 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FloatingLiteralClass");
3680 case ZigClangStmt_FixedPointLiteralClass:
3681 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FixedPointLiteralClass");
35183682 return ErrorUnexpected;
3519 case clang::Stmt::ExprWithCleanupsClass:
3520 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ExprWithCleanupsClass");
3683 case ZigClangStmt_FloatingLiteralClass:
3684 return wrap_stmt(out_node, out_child_scope, scope,
3685 trans_floating_literal(c, result_used, (const clang::FloatingLiteral *)stmt));
3686 case ZigClangStmt_ExprWithCleanupsClass:
3687 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExprWithCleanupsClass");
35213688 return ErrorUnexpected;
3522 case clang::Stmt::FunctionParmPackExprClass:
3523 emit_warning(c, stmt->getBeginLoc(), "TODO handle C FunctionParmPackExprClass");
3689 case ZigClangStmt_FunctionParmPackExprClass:
3690 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FunctionParmPackExprClass");
35243691 return ErrorUnexpected;
3525 case clang::Stmt::GNUNullExprClass:
3526 emit_warning(c, stmt->getBeginLoc(), "TODO handle C GNUNullExprClass");
3692 case ZigClangStmt_GNUNullExprClass:
3693 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GNUNullExprClass");
35273694 return ErrorUnexpected;
3528 case clang::Stmt::GenericSelectionExprClass:
3529 emit_warning(c, stmt->getBeginLoc(), "TODO handle C GenericSelectionExprClass");
3695 case ZigClangStmt_GenericSelectionExprClass:
3696 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GenericSelectionExprClass");
35303697 return ErrorUnexpected;
3531 case clang::Stmt::ImaginaryLiteralClass:
3532 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImaginaryLiteralClass");
3698 case ZigClangStmt_ImaginaryLiteralClass:
3699 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImaginaryLiteralClass");
35333700 return ErrorUnexpected;
3534 case clang::Stmt::ImplicitValueInitExprClass:
3535 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ImplicitValueInitExprClass");
3701 case ZigClangStmt_ImplicitValueInitExprClass:
3702 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ImplicitValueInitExprClass");
35363703 return ErrorUnexpected;
3537 case clang::Stmt::InitListExprClass:
3538 emit_warning(c, stmt->getBeginLoc(), "TODO handle C InitListExprClass");
3704 case ZigClangStmt_InitListExprClass:
3705 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C InitListExprClass");
35393706 return ErrorUnexpected;
3540 case clang::Stmt::LambdaExprClass:
3541 emit_warning(c, stmt->getBeginLoc(), "TODO handle C LambdaExprClass");
3707 case ZigClangStmt_LambdaExprClass:
3708 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LambdaExprClass");
35423709 return ErrorUnexpected;
3543 case clang::Stmt::MSPropertyRefExprClass:
3544 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertyRefExprClass");
3710 case ZigClangStmt_MSPropertyRefExprClass:
3711 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertyRefExprClass");
35453712 return ErrorUnexpected;
3546 case clang::Stmt::MSPropertySubscriptExprClass:
3547 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSPropertySubscriptExprClass");
3713 case ZigClangStmt_MSPropertySubscriptExprClass:
3714 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSPropertySubscriptExprClass");
35483715 return ErrorUnexpected;
3549 case clang::Stmt::MaterializeTemporaryExprClass:
3550 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MaterializeTemporaryExprClass");
3716 case ZigClangStmt_MaterializeTemporaryExprClass:
3717 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MaterializeTemporaryExprClass");
35513718 return ErrorUnexpected;
3552 case clang::Stmt::NoInitExprClass:
3553 emit_warning(c, stmt->getBeginLoc(), "TODO handle C NoInitExprClass");
3719 case ZigClangStmt_NoInitExprClass:
3720 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C NoInitExprClass");
35543721 return ErrorUnexpected;
3555 case clang::Stmt::OMPArraySectionExprClass:
3556 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPArraySectionExprClass");
3722 case ZigClangStmt_OMPArraySectionExprClass:
3723 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPArraySectionExprClass");
35573724 return ErrorUnexpected;
3558 case clang::Stmt::ObjCArrayLiteralClass:
3559 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCArrayLiteralClass");
3725 case ZigClangStmt_ObjCArrayLiteralClass:
3726 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCArrayLiteralClass");
35603727 return ErrorUnexpected;
3561 case clang::Stmt::ObjCAvailabilityCheckExprClass:
3562 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAvailabilityCheckExprClass");
3728 case ZigClangStmt_ObjCAvailabilityCheckExprClass:
3729 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAvailabilityCheckExprClass");
35633730 return ErrorUnexpected;
3564 case clang::Stmt::ObjCBoolLiteralExprClass:
3565 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoolLiteralExprClass");
3731 case ZigClangStmt_ObjCBoolLiteralExprClass:
3732 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoolLiteralExprClass");
35663733 return ErrorUnexpected;
3567 case clang::Stmt::ObjCBoxedExprClass:
3568 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCBoxedExprClass");
3734 case ZigClangStmt_ObjCBoxedExprClass:
3735 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBoxedExprClass");
35693736 return ErrorUnexpected;
3570 case clang::Stmt::ObjCDictionaryLiteralClass:
3571 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCDictionaryLiteralClass");
3737 case ZigClangStmt_ObjCDictionaryLiteralClass:
3738 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCDictionaryLiteralClass");
35723739 return ErrorUnexpected;
3573 case clang::Stmt::ObjCEncodeExprClass:
3574 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCEncodeExprClass");
3740 case ZigClangStmt_ObjCEncodeExprClass:
3741 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCEncodeExprClass");
35753742 return ErrorUnexpected;
3576 case clang::Stmt::ObjCIndirectCopyRestoreExprClass:
3577 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIndirectCopyRestoreExprClass");
3743 case ZigClangStmt_ObjCIndirectCopyRestoreExprClass:
3744 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIndirectCopyRestoreExprClass");
35783745 return ErrorUnexpected;
3579 case clang::Stmt::ObjCIsaExprClass:
3580 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIsaExprClass");
3746 case ZigClangStmt_ObjCIsaExprClass:
3747 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIsaExprClass");
35813748 return ErrorUnexpected;
3582 case clang::Stmt::ObjCIvarRefExprClass:
3583 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCIvarRefExprClass");
3749 case ZigClangStmt_ObjCIvarRefExprClass:
3750 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCIvarRefExprClass");
35843751 return ErrorUnexpected;
3585 case clang::Stmt::ObjCMessageExprClass:
3586 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCMessageExprClass");
3752 case ZigClangStmt_ObjCMessageExprClass:
3753 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCMessageExprClass");
35873754 return ErrorUnexpected;
3588 case clang::Stmt::ObjCPropertyRefExprClass:
3589 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCPropertyRefExprClass");
3755 case ZigClangStmt_ObjCPropertyRefExprClass:
3756 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCPropertyRefExprClass");
35903757 return ErrorUnexpected;
3591 case clang::Stmt::ObjCProtocolExprClass:
3592 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCProtocolExprClass");
3758 case ZigClangStmt_ObjCProtocolExprClass:
3759 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCProtocolExprClass");
35933760 return ErrorUnexpected;
3594 case clang::Stmt::ObjCSelectorExprClass:
3595 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSelectorExprClass");
3761 case ZigClangStmt_ObjCSelectorExprClass:
3762 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSelectorExprClass");
35963763 return ErrorUnexpected;
3597 case clang::Stmt::ObjCStringLiteralClass:
3598 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCStringLiteralClass");
3764 case ZigClangStmt_ObjCStringLiteralClass:
3765 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCStringLiteralClass");
35993766 return ErrorUnexpected;
3600 case clang::Stmt::ObjCSubscriptRefExprClass:
3601 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCSubscriptRefExprClass");
3767 case ZigClangStmt_ObjCSubscriptRefExprClass:
3768 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCSubscriptRefExprClass");
36023769 return ErrorUnexpected;
3603 case clang::Stmt::OffsetOfExprClass:
3604 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OffsetOfExprClass");
3770 case ZigClangStmt_OffsetOfExprClass:
3771 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OffsetOfExprClass");
36053772 return ErrorUnexpected;
3606 case clang::Stmt::OpaqueValueExprClass:
3607 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OpaqueValueExprClass");
3773 case ZigClangStmt_OpaqueValueExprClass:
3774 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OpaqueValueExprClass");
36083775 return ErrorUnexpected;
3609 case clang::Stmt::UnresolvedLookupExprClass:
3610 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedLookupExprClass");
3776 case ZigClangStmt_UnresolvedLookupExprClass:
3777 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedLookupExprClass");
36113778 return ErrorUnexpected;
3612 case clang::Stmt::UnresolvedMemberExprClass:
3613 emit_warning(c, stmt->getBeginLoc(), "TODO handle C UnresolvedMemberExprClass");
3779 case ZigClangStmt_UnresolvedMemberExprClass:
3780 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C UnresolvedMemberExprClass");
36143781 return ErrorUnexpected;
3615 case clang::Stmt::PackExpansionExprClass:
3616 emit_warning(c, stmt->getBeginLoc(), "TODO handle C PackExpansionExprClass");
3782 case ZigClangStmt_PackExpansionExprClass:
3783 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PackExpansionExprClass");
36173784 return ErrorUnexpected;
3618 case clang::Stmt::ParenListExprClass:
3619 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ParenListExprClass");
3785 case ZigClangStmt_ParenListExprClass:
3786 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ParenListExprClass");
36203787 return ErrorUnexpected;
3621 case clang::Stmt::PseudoObjectExprClass:
3622 emit_warning(c, stmt->getBeginLoc(), "TODO handle C PseudoObjectExprClass");
3788 case ZigClangStmt_PseudoObjectExprClass:
3789 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C PseudoObjectExprClass");
36233790 return ErrorUnexpected;
3624 case clang::Stmt::ShuffleVectorExprClass:
3625 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ShuffleVectorExprClass");
3791 case ZigClangStmt_ShuffleVectorExprClass:
3792 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ShuffleVectorExprClass");
36263793 return ErrorUnexpected;
3627 case clang::Stmt::SizeOfPackExprClass:
3628 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SizeOfPackExprClass");
3794 case ZigClangStmt_SizeOfPackExprClass:
3795 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SizeOfPackExprClass");
36293796 return ErrorUnexpected;
3630 case clang::Stmt::SubstNonTypeTemplateParmExprClass:
3631 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmExprClass");
3797 case ZigClangStmt_SubstNonTypeTemplateParmExprClass:
3798 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmExprClass");
36323799 return ErrorUnexpected;
3633 case clang::Stmt::SubstNonTypeTemplateParmPackExprClass:
3634 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
3800 case ZigClangStmt_SubstNonTypeTemplateParmPackExprClass:
3801 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
36353802 return ErrorUnexpected;
3636 case clang::Stmt::TypeTraitExprClass:
3637 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypeTraitExprClass");
3803 case ZigClangStmt_TypeTraitExprClass:
3804 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypeTraitExprClass");
36383805 return ErrorUnexpected;
3639 case clang::Stmt::TypoExprClass:
3640 emit_warning(c, stmt->getBeginLoc(), "TODO handle C TypoExprClass");
3806 case ZigClangStmt_TypoExprClass:
3807 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C TypoExprClass");
36413808 return ErrorUnexpected;
3642 case clang::Stmt::VAArgExprClass:
3643 emit_warning(c, stmt->getBeginLoc(), "TODO handle C VAArgExprClass");
3809 case ZigClangStmt_VAArgExprClass:
3810 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C VAArgExprClass");
36443811 return ErrorUnexpected;
3645 case clang::Stmt::GotoStmtClass:
3646 emit_warning(c, stmt->getBeginLoc(), "TODO handle C GotoStmtClass");
3812 case ZigClangStmt_GotoStmtClass:
3813 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C GotoStmtClass");
36473814 return ErrorUnexpected;
3648 case clang::Stmt::IndirectGotoStmtClass:
3649 emit_warning(c, stmt->getBeginLoc(), "TODO handle C IndirectGotoStmtClass");
3815 case ZigClangStmt_IndirectGotoStmtClass:
3816 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C IndirectGotoStmtClass");
36503817 return ErrorUnexpected;
3651 case clang::Stmt::LabelStmtClass:
3652 emit_warning(c, stmt->getBeginLoc(), "TODO handle C LabelStmtClass");
3818 case ZigClangStmt_LabelStmtClass:
3819 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C LabelStmtClass");
36533820 return ErrorUnexpected;
3654 case clang::Stmt::MSDependentExistsStmtClass:
3655 emit_warning(c, stmt->getBeginLoc(), "TODO handle C MSDependentExistsStmtClass");
3821 case ZigClangStmt_MSDependentExistsStmtClass:
3822 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C MSDependentExistsStmtClass");
36563823 return ErrorUnexpected;
3657 case clang::Stmt::OMPAtomicDirectiveClass:
3658 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPAtomicDirectiveClass");
3824 case ZigClangStmt_OMPAtomicDirectiveClass:
3825 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPAtomicDirectiveClass");
36593826 return ErrorUnexpected;
3660 case clang::Stmt::OMPBarrierDirectiveClass:
3661 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPBarrierDirectiveClass");
3827 case ZigClangStmt_OMPBarrierDirectiveClass:
3828 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPBarrierDirectiveClass");
36623829 return ErrorUnexpected;
3663 case clang::Stmt::OMPCancelDirectiveClass:
3664 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancelDirectiveClass");
3830 case ZigClangStmt_OMPCancelDirectiveClass:
3831 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancelDirectiveClass");
36653832 return ErrorUnexpected;
3666 case clang::Stmt::OMPCancellationPointDirectiveClass:
3667 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCancellationPointDirectiveClass");
3833 case ZigClangStmt_OMPCancellationPointDirectiveClass:
3834 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCancellationPointDirectiveClass");
36683835 return ErrorUnexpected;
3669 case clang::Stmt::OMPCriticalDirectiveClass:
3670 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPCriticalDirectiveClass");
3836 case ZigClangStmt_OMPCriticalDirectiveClass:
3837 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPCriticalDirectiveClass");
36713838 return ErrorUnexpected;
3672 case clang::Stmt::OMPFlushDirectiveClass:
3673 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPFlushDirectiveClass");
3839 case ZigClangStmt_OMPFlushDirectiveClass:
3840 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPFlushDirectiveClass");
36743841 return ErrorUnexpected;
3675 case clang::Stmt::OMPDistributeDirectiveClass:
3676 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeDirectiveClass");
3842 case ZigClangStmt_OMPDistributeDirectiveClass:
3843 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeDirectiveClass");
36773844 return ErrorUnexpected;
3678 case clang::Stmt::OMPDistributeParallelForDirectiveClass:
3679 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForDirectiveClass");
3845 case ZigClangStmt_OMPDistributeParallelForDirectiveClass:
3846 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForDirectiveClass");
36803847 return ErrorUnexpected;
3681 case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass:
3682 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
3848 case ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass:
3849 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
36833850 return ErrorUnexpected;
3684 case clang::Stmt::OMPDistributeSimdDirectiveClass:
3685 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPDistributeSimdDirectiveClass");
3851 case ZigClangStmt_OMPDistributeSimdDirectiveClass:
3852 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPDistributeSimdDirectiveClass");
36863853 return ErrorUnexpected;
3687 case clang::Stmt::OMPForDirectiveClass:
3688 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForDirectiveClass");
3854 case ZigClangStmt_OMPForDirectiveClass:
3855 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForDirectiveClass");
36893856 return ErrorUnexpected;
3690 case clang::Stmt::OMPForSimdDirectiveClass:
3691 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPForSimdDirectiveClass");
3857 case ZigClangStmt_OMPForSimdDirectiveClass:
3858 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPForSimdDirectiveClass");
36923859 return ErrorUnexpected;
3693 case clang::Stmt::OMPParallelForDirectiveClass:
3694 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForDirectiveClass");
3860 case ZigClangStmt_OMPParallelForDirectiveClass:
3861 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForDirectiveClass");
36953862 return ErrorUnexpected;
3696 case clang::Stmt::OMPParallelForSimdDirectiveClass:
3697 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelForSimdDirectiveClass");
3863 case ZigClangStmt_OMPParallelForSimdDirectiveClass:
3864 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelForSimdDirectiveClass");
36983865 return ErrorUnexpected;
3699 case clang::Stmt::OMPSimdDirectiveClass:
3700 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSimdDirectiveClass");
3866 case ZigClangStmt_OMPSimdDirectiveClass:
3867 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSimdDirectiveClass");
37013868 return ErrorUnexpected;
3702 case clang::Stmt::OMPTargetParallelForSimdDirectiveClass:
3703 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
3869 case ZigClangStmt_OMPTargetParallelForSimdDirectiveClass:
3870 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
37043871 return ErrorUnexpected;
3705 case clang::Stmt::OMPTargetSimdDirectiveClass:
3706 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetSimdDirectiveClass");
3872 case ZigClangStmt_OMPTargetSimdDirectiveClass:
3873 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetSimdDirectiveClass");
37073874 return ErrorUnexpected;
3708 case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass:
3709 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
3875 case ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass:
3876 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
37103877 return ErrorUnexpected;
3711 case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
3712 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
3878 case ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass:
3879 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
37133880 return ErrorUnexpected;
3714 case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
3715 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
3881 case ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
3882 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
37163883 return ErrorUnexpected;
3717 case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
3718 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
3884 case ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass:
3885 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
37193886 return ErrorUnexpected;
3720 case clang::Stmt::OMPTaskLoopDirectiveClass:
3721 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopDirectiveClass");
3887 case ZigClangStmt_OMPTaskLoopDirectiveClass:
3888 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopDirectiveClass");
37223889 return ErrorUnexpected;
3723 case clang::Stmt::OMPTaskLoopSimdDirectiveClass:
3724 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskLoopSimdDirectiveClass");
3890 case ZigClangStmt_OMPTaskLoopSimdDirectiveClass:
3891 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskLoopSimdDirectiveClass");
37253892 return ErrorUnexpected;
3726 case clang::Stmt::OMPTeamsDistributeDirectiveClass:
3727 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeDirectiveClass");
3893 case ZigClangStmt_OMPTeamsDistributeDirectiveClass:
3894 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeDirectiveClass");
37283895 return ErrorUnexpected;
3729 case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass:
3730 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
3896 case ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass:
3897 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
37313898 return ErrorUnexpected;
3732 case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
3733 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
3899 case ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass:
3900 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
37343901 return ErrorUnexpected;
3735 case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass:
3736 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
3902 case ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass:
3903 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
37373904 return ErrorUnexpected;
3738 case clang::Stmt::OMPMasterDirectiveClass:
3739 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPMasterDirectiveClass");
3905 case ZigClangStmt_OMPMasterDirectiveClass:
3906 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPMasterDirectiveClass");
37403907 return ErrorUnexpected;
3741 case clang::Stmt::OMPOrderedDirectiveClass:
3742 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPOrderedDirectiveClass");
3908 case ZigClangStmt_OMPOrderedDirectiveClass:
3909 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPOrderedDirectiveClass");
37433910 return ErrorUnexpected;
3744 case clang::Stmt::OMPParallelDirectiveClass:
3745 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelDirectiveClass");
3911 case ZigClangStmt_OMPParallelDirectiveClass:
3912 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelDirectiveClass");
37463913 return ErrorUnexpected;
3747 case clang::Stmt::OMPParallelSectionsDirectiveClass:
3748 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPParallelSectionsDirectiveClass");
3914 case ZigClangStmt_OMPParallelSectionsDirectiveClass:
3915 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPParallelSectionsDirectiveClass");
37493916 return ErrorUnexpected;
3750 case clang::Stmt::OMPSectionDirectiveClass:
3751 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionDirectiveClass");
3917 case ZigClangStmt_OMPSectionDirectiveClass:
3918 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionDirectiveClass");
37523919 return ErrorUnexpected;
3753 case clang::Stmt::OMPSectionsDirectiveClass:
3754 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSectionsDirectiveClass");
3920 case ZigClangStmt_OMPSectionsDirectiveClass:
3921 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSectionsDirectiveClass");
37553922 return ErrorUnexpected;
3756 case clang::Stmt::OMPSingleDirectiveClass:
3757 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPSingleDirectiveClass");
3923 case ZigClangStmt_OMPSingleDirectiveClass:
3924 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPSingleDirectiveClass");
37583925 return ErrorUnexpected;
3759 case clang::Stmt::OMPTargetDataDirectiveClass:
3760 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDataDirectiveClass");
3926 case ZigClangStmt_OMPTargetDataDirectiveClass:
3927 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDataDirectiveClass");
37613928 return ErrorUnexpected;
3762 case clang::Stmt::OMPTargetDirectiveClass:
3763 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetDirectiveClass");
3929 case ZigClangStmt_OMPTargetDirectiveClass:
3930 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetDirectiveClass");
37643931 return ErrorUnexpected;
3765 case clang::Stmt::OMPTargetEnterDataDirectiveClass:
3766 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetEnterDataDirectiveClass");
3932 case ZigClangStmt_OMPTargetEnterDataDirectiveClass:
3933 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetEnterDataDirectiveClass");
37673934 return ErrorUnexpected;
3768 case clang::Stmt::OMPTargetExitDataDirectiveClass:
3769 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetExitDataDirectiveClass");
3935 case ZigClangStmt_OMPTargetExitDataDirectiveClass:
3936 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetExitDataDirectiveClass");
37703937 return ErrorUnexpected;
3771 case clang::Stmt::OMPTargetParallelDirectiveClass:
3772 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelDirectiveClass");
3938 case ZigClangStmt_OMPTargetParallelDirectiveClass:
3939 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelDirectiveClass");
37733940 return ErrorUnexpected;
3774 case clang::Stmt::OMPTargetParallelForDirectiveClass:
3775 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetParallelForDirectiveClass");
3941 case ZigClangStmt_OMPTargetParallelForDirectiveClass:
3942 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetParallelForDirectiveClass");
37763943 return ErrorUnexpected;
3777 case clang::Stmt::OMPTargetTeamsDirectiveClass:
3778 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetTeamsDirectiveClass");
3944 case ZigClangStmt_OMPTargetTeamsDirectiveClass:
3945 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetTeamsDirectiveClass");
37793946 return ErrorUnexpected;
3780 case clang::Stmt::OMPTargetUpdateDirectiveClass:
3781 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTargetUpdateDirectiveClass");
3947 case ZigClangStmt_OMPTargetUpdateDirectiveClass:
3948 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTargetUpdateDirectiveClass");
37823949 return ErrorUnexpected;
3783 case clang::Stmt::OMPTaskDirectiveClass:
3784 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskDirectiveClass");
3950 case ZigClangStmt_OMPTaskDirectiveClass:
3951 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskDirectiveClass");
37853952 return ErrorUnexpected;
3786 case clang::Stmt::OMPTaskgroupDirectiveClass:
3787 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskgroupDirectiveClass");
3953 case ZigClangStmt_OMPTaskgroupDirectiveClass:
3954 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskgroupDirectiveClass");
37883955 return ErrorUnexpected;
3789 case clang::Stmt::OMPTaskwaitDirectiveClass:
3790 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskwaitDirectiveClass");
3956 case ZigClangStmt_OMPTaskwaitDirectiveClass:
3957 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskwaitDirectiveClass");
37913958 return ErrorUnexpected;
3792 case clang::Stmt::OMPTaskyieldDirectiveClass:
3793 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTaskyieldDirectiveClass");
3959 case ZigClangStmt_OMPTaskyieldDirectiveClass:
3960 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTaskyieldDirectiveClass");
37943961 return ErrorUnexpected;
3795 case clang::Stmt::OMPTeamsDirectiveClass:
3796 emit_warning(c, stmt->getBeginLoc(), "TODO handle C OMPTeamsDirectiveClass");
3962 case ZigClangStmt_OMPTeamsDirectiveClass:
3963 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C OMPTeamsDirectiveClass");
37973964 return ErrorUnexpected;
3798 case clang::Stmt::ObjCAtCatchStmtClass:
3799 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtCatchStmtClass");
3965 case ZigClangStmt_ObjCAtCatchStmtClass:
3966 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtCatchStmtClass");
38003967 return ErrorUnexpected;
3801 case clang::Stmt::ObjCAtFinallyStmtClass:
3802 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtFinallyStmtClass");
3968 case ZigClangStmt_ObjCAtFinallyStmtClass:
3969 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtFinallyStmtClass");
38033970 return ErrorUnexpected;
3804 case clang::Stmt::ObjCAtSynchronizedStmtClass:
3805 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtSynchronizedStmtClass");
3971 case ZigClangStmt_ObjCAtSynchronizedStmtClass:
3972 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtSynchronizedStmtClass");
38063973 return ErrorUnexpected;
3807 case clang::Stmt::ObjCAtThrowStmtClass:
3808 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtThrowStmtClass");
3974 case ZigClangStmt_ObjCAtThrowStmtClass:
3975 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtThrowStmtClass");
38093976 return ErrorUnexpected;
3810 case clang::Stmt::ObjCAtTryStmtClass:
3811 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAtTryStmtClass");
3977 case ZigClangStmt_ObjCAtTryStmtClass:
3978 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAtTryStmtClass");
38123979 return ErrorUnexpected;
3813 case clang::Stmt::ObjCAutoreleasePoolStmtClass:
3814 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCAutoreleasePoolStmtClass");
3980 case ZigClangStmt_ObjCAutoreleasePoolStmtClass:
3981 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCAutoreleasePoolStmtClass");
38153982 return ErrorUnexpected;
3816 case clang::Stmt::ObjCForCollectionStmtClass:
3817 emit_warning(c, stmt->getBeginLoc(), "TODO handle C ObjCForCollectionStmtClass");
3983 case ZigClangStmt_ObjCForCollectionStmtClass:
3984 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCForCollectionStmtClass");
38183985 return ErrorUnexpected;
3819 case clang::Stmt::SEHExceptStmtClass:
3820 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHExceptStmtClass");
3986 case ZigClangStmt_SEHExceptStmtClass:
3987 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHExceptStmtClass");
38213988 return ErrorUnexpected;
3822 case clang::Stmt::SEHFinallyStmtClass:
3823 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHFinallyStmtClass");
3989 case ZigClangStmt_SEHFinallyStmtClass:
3990 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHFinallyStmtClass");
38243991 return ErrorUnexpected;
3825 case clang::Stmt::SEHLeaveStmtClass:
3826 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHLeaveStmtClass");
3992 case ZigClangStmt_SEHLeaveStmtClass:
3993 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHLeaveStmtClass");
38273994 return ErrorUnexpected;
3828 case clang::Stmt::SEHTryStmtClass:
3829 emit_warning(c, stmt->getBeginLoc(), "TODO handle C SEHTryStmtClass");
3995 case ZigClangStmt_SEHTryStmtClass:
3996 emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C SEHTryStmtClass");
38303997 return ErrorUnexpected;
38313998 }
38323999 zig_unreachable();
38334000}
38344001
38354002// Returns null if there was an error
3836static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr,
4003static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const ZigClangExpr *expr,
38374004 TransLRValue lrval)
38384005{
38394006 AstNode *result_node;
38404007 TransScope *result_scope;
3841 if (trans_stmt_extra(c, scope, expr, result_used, lrval, &result_node, &result_scope, nullptr)) {
4008 if (trans_stmt_extra(c, scope, (const ZigClangStmt *)expr, result_used, lrval, &result_node, &result_scope, nullptr)) {
38424009 return nullptr;
38434010 }
38444011 return result_node;
......@@ -3846,7 +4013,7 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope
38464013
38474014// Statements have no result and no concept of L or R value.
38484015// Returns child scope, or null if there was an error
3849static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node) {
4016static TransScope *trans_stmt(Context *c, TransScope *scope, const ZigClangStmt *stmt, AstNode **out_node) {
38504017 TransScope *child_scope;
38514018 if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) {
38524019 return nullptr;
......@@ -3854,34 +4021,36 @@ static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *
38544021 return child_scope;
38554022}
38564023
3857static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
3858 Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
4024static void visit_fn_decl(Context *c, const ZigClangFunctionDecl *fn_decl) {
4025 Buf *fn_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)fn_decl));
38594026
38604027 if (get_global(c, fn_name)) {
38614028 // we already saw this function
38624029 return;
38634030 }
38644031
3865 AstNode *proto_node = trans_qual_type(c, fn_decl->getType(), fn_decl->getLocation());
4032 AstNode *proto_node = trans_qual_type(c, ZigClangFunctionDecl_getType(fn_decl),
4033 ZigClangFunctionDecl_getLocation(fn_decl));
38664034 if (proto_node == nullptr) {
3867 emit_warning(c, fn_decl->getLocation(), "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
4035 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl),
4036 "unable to resolve prototype of function '%s'", buf_ptr(fn_name));
38684037 return;
38694038 }
38704039
38714040 proto_node->data.fn_proto.name = fn_name;
3872 proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
4041 proto_node->data.fn_proto.is_extern = !ZigClangFunctionDecl_hasBody(fn_decl);
38734042
3874 clang::StorageClass sc = fn_decl->getStorageClass();
3875 if (sc == clang::SC_None) {
4043 ZigClangStorageClass sc = ZigClangFunctionDecl_getStorageClass(fn_decl);
4044 if (sc == ZigClangStorageClass_None) {
38764045 proto_node->data.fn_proto.visib_mod = c->visib_mod;
3877 proto_node->data.fn_proto.is_export = fn_decl->hasBody() ? c->want_export : false;
3878 } else if (sc == clang::SC_Extern || sc == clang::SC_Static) {
4046 proto_node->data.fn_proto.is_export = ZigClangFunctionDecl_hasBody(fn_decl) ? c->want_export : false;
4047 } else if (sc == ZigClangStorageClass_Extern || sc == ZigClangStorageClass_Static) {
38794048 proto_node->data.fn_proto.visib_mod = c->visib_mod;
3880 } else if (sc == clang::SC_PrivateExtern) {
3881 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
4049 } else if (sc == ZigClangStorageClass_PrivateExtern) {
4050 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: private extern");
38824051 return;
38834052 } else {
3884 emit_warning(c, fn_decl->getLocation(), "unsupported storage class: unknown");
4053 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unsupported storage class: unknown");
38854054 return;
38864055 }
38874056
......@@ -3889,8 +4058,8 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
38894058
38904059 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
38914060 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
3892 const clang::ParmVarDecl *param = fn_decl->getParamDecl(i);
3893 const char *name = decl_name(param);
4061 const ZigClangParmVarDecl *param = ZigClangFunctionDecl_getParamDecl(fn_decl, i);
4062 const char *name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)param);
38944063
38954064 Buf *proto_param_name;
38964065 if (strlen(name) != 0) {
......@@ -3908,7 +4077,7 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
39084077 param_node->data.param_decl.name = scope_var->zig_name;
39094078 }
39104079
3911 if (!fn_decl->hasBody()) {
4080 if (!ZigClangFunctionDecl_hasBody(fn_decl)) {
39124081 // just a prototype
39134082 add_top_level_decl(c, proto_node->data.fn_proto.name, proto_node);
39144083 return;
......@@ -3916,11 +4085,11 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
39164085
39174086 // actual function definition with body
39184087 c->ptr_params.clear();
3919 clang::Stmt *body = fn_decl->getBody();
4088 const ZigClangStmt *body = ZigClangFunctionDecl_getBody(fn_decl);
39204089 AstNode *actual_body_node;
39214090 TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
39224091 if (result_scope == nullptr) {
3923 emit_warning(c, fn_decl->getLocation(), "unable to translate function");
4092 emit_warning(c, ZigClangFunctionDecl_getLocation(fn_decl), "unable to translate function");
39244093 return;
39254094 }
39264095 assert(actual_body_node != nullptr);
......@@ -3958,20 +4127,20 @@ static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
39584127 add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node);
39594128}
39604129
3961static AstNode *resolve_typdef_as_builtin(Context *c, const clang::TypedefNameDecl *typedef_decl, const char *primitive_name) {
4130static AstNode *resolve_typdef_as_builtin(Context *c, const ZigClangTypedefNameDecl *typedef_decl, const char *primitive_name) {
39624131 AstNode *node = trans_create_node_symbol_str(c, primitive_name);
39634132 c->decl_table.put(typedef_decl, node);
39644133 return node;
39654134}
39664135
3967static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl) {
3968 auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl());
4136static AstNode *resolve_typedef_decl(Context *c, const ZigClangTypedefNameDecl *typedef_decl) {
4137 auto existing_entry = c->decl_table.maybe_get((void*)ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl));
39694138 if (existing_entry) {
39704139 return existing_entry->value;
39714140 }
39724141
3973 clang::QualType child_qt = typedef_decl->getUnderlyingType();
3974 Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
4142 ZigClangQualType child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
4143 Buf *type_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)typedef_decl));
39754144
39764145 if (buf_eql_str(type_name, "uint8_t")) {
39774146 return resolve_typdef_as_builtin(c, typedef_decl, "u8");
......@@ -4005,11 +4174,12 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t
40054174
40064175 // trans_qual_type here might cause us to look at this typedef again so we put the item in the map first
40074176 AstNode *symbol_node = trans_create_node_symbol(c, type_name);
4008 c->decl_table.put(typedef_decl->getCanonicalDecl(), symbol_node);
4177 c->decl_table.put(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl), symbol_node);
40094178
4010 AstNode *type_node = trans_qual_type(c, child_qt, typedef_decl->getLocation());
4179 AstNode *type_node = trans_qual_type(c, child_qt, ZigClangTypedefNameDecl_getLocation(typedef_decl));
40114180 if (type_node == nullptr) {
4012 emit_warning(c, typedef_decl->getLocation(), "typedef %s - unresolved child type", buf_ptr(type_name));
4181 emit_warning(c, ZigClangTypedefNameDecl_getLocation(typedef_decl),
4182 "typedef %s - unresolved child type", buf_ptr(type_name));
40134183 c->decl_table.put(typedef_decl, nullptr);
40144184 // TODO add global var with type_name equal to @compileError("unable to resolve C type")
40154185 return nullptr;
......@@ -4019,33 +4189,33 @@ static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *t
40194189 return symbol_node;
40204190}
40214191
4022struct AstNode *demote_enum_to_opaque(Context *c, const clang::EnumDecl *enum_decl,
4023 Buf *full_type_name, Buf *bare_name)
4192struct AstNode *demote_enum_to_opaque(Context *c, const ZigClangEnumDecl *enum_decl, Buf *full_type_name,
4193 Buf *bare_name)
40244194{
40254195 AstNode *opaque_node = trans_create_node_opaque(c);
40264196 if (full_type_name == nullptr) {
4027 c->decl_table.put(enum_decl->getCanonicalDecl(), opaque_node);
4197 c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), opaque_node);
40284198 return opaque_node;
40294199 }
40304200 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
40314201 add_global_weak_alias(c, bare_name, full_type_name);
40324202 add_global_var(c, full_type_name, opaque_node);
4033 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
4203 c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
40344204 return symbol_node;
40354205}
40364206
4037static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) {
4038 auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl());
4207static AstNode *resolve_enum_decl(Context *c, const ZigClangEnumDecl *enum_decl) {
4208 auto existing_entry = c->decl_table.maybe_get(ZigClangEnumDecl_getCanonicalDecl(enum_decl));
40394209 if (existing_entry) {
40404210 return existing_entry->value;
40414211 }
40424212
4043 const char *raw_name = decl_name(enum_decl);
4213 const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_decl);
40444214 bool is_anonymous = (raw_name[0] == 0);
40454215 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
40464216 Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
40474217
4048 const clang::EnumDecl *enum_def = enum_decl->getDefinition();
4218 const ZigClangEnumDecl *enum_def = ZigClangEnumDecl_getDefinition(enum_decl);
40494219 if (!enum_def) {
40504220 return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
40514221 }
......@@ -4053,8 +4223,8 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
40534223
40544224 bool pure_enum = true;
40554225 uint32_t field_count = 0;
4056 for (auto it = enum_def->enumerator_begin(),
4057 it_end = enum_def->enumerator_end();
4226 for (auto it = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_begin(),
4227 it_end = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_end();
40584228 it != it_end; ++it, field_count += 1)
40594229 {
40604230 const clang::EnumConstantDecl *enum_const = *it;
......@@ -4062,7 +4232,8 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
40624232 pure_enum = false;
40634233 }
40644234 }
4065 AstNode *tag_int_type = trans_qual_type(c, enum_decl->getIntegerType(), enum_decl->getLocation());
4235 AstNode *tag_int_type = trans_qual_type(c, ZigClangEnumDecl_getIntegerType(enum_decl),
4236 ZigClangEnumDecl_getLocation(enum_decl));
40664237 assert(tag_int_type);
40674238
40684239 AstNode *enum_node = trans_create_node(c, NodeTypeContainerDecl);
......@@ -4071,20 +4242,20 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
40714242 // TODO only emit this tag type if the enum tag type is not the default.
40724243 // I don't know what the default is, need to figure out how clang is deciding.
40734244 // it appears to at least be different across gcc/msvc
4074 if (!c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::UInt) &&
4075 !c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::Int))
4245 if (!c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeUInt) &&
4246 !c_is_builtin_type(c, ZigClangEnumDecl_getIntegerType(enum_decl), ZigClangBuiltinTypeInt))
40764247 {
40774248 enum_node->data.container_decl.init_arg_expr = tag_int_type;
40784249 }
40794250 enum_node->data.container_decl.fields.resize(field_count);
40804251 uint32_t i = 0;
4081 for (auto it = enum_def->enumerator_begin(),
4082 it_end = enum_def->enumerator_end();
4252 for (auto it = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_begin(),
4253 it_end = reinterpret_cast<const clang::EnumDecl *>(enum_def)->enumerator_end();
40834254 it != it_end; ++it, i += 1)
40844255 {
40854256 const clang::EnumConstantDecl *enum_const = *it;
40864257
4087 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
4258 Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
40884259 Buf *field_name;
40894260 if (bare_name != nullptr && buf_starts_with_buf(enum_val_name, bare_name)) {
40904261 field_name = buf_slice(enum_val_name, buf_len(bare_name), buf_len(enum_val_name));
......@@ -4092,7 +4263,8 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
40924263 field_name = enum_val_name;
40934264 }
40944265
4095 AstNode *int_node = pure_enum && !is_anonymous ? nullptr : trans_create_node_apint(c, enum_const->getInitVal());
4266 AstNode *int_node = pure_enum && !is_anonymous ?
4267 nullptr : trans_create_node_apint(c, bitcast(&enum_const->getInitVal()));
40964268 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
40974269 field_node->data.struct_field.name = field_name;
40984270 field_node->data.struct_field.type = nullptr;
......@@ -4102,7 +4274,7 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
41024274 // in C each enum value is in the global namespace. so we put them there too.
41034275 // at this point we can rely on the enum emitting successfully
41044276 if (is_anonymous) {
4105 Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
4277 Buf *enum_val_name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)enum_const));
41064278 add_global_var(c, enum_val_name, int_node);
41074279 } else {
41084280 AstNode *field_access_node = trans_create_node_field_access(c,
......@@ -4112,73 +4284,74 @@ static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl)
41124284 }
41134285
41144286 if (is_anonymous) {
4115 c->decl_table.put(enum_decl->getCanonicalDecl(), enum_node);
4287 c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), enum_node);
41164288 return enum_node;
41174289 } else {
41184290 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
41194291 add_global_weak_alias(c, bare_name, full_type_name);
41204292 add_global_var(c, full_type_name, enum_node);
4121 c->decl_table.put(enum_decl->getCanonicalDecl(), symbol_node);
4293 c->decl_table.put(ZigClangEnumDecl_getCanonicalDecl(enum_decl), symbol_node);
41224294 return enum_node;
41234295 }
41244296}
41254297
4126static AstNode *demote_struct_to_opaque(Context *c, const clang::RecordDecl *record_decl,
4298static AstNode *demote_struct_to_opaque(Context *c, const ZigClangRecordDecl *record_decl,
41274299 Buf *full_type_name, Buf *bare_name)
41284300{
41294301 AstNode *opaque_node = trans_create_node_opaque(c);
41304302 if (full_type_name == nullptr) {
4131 c->decl_table.put(record_decl->getCanonicalDecl(), opaque_node);
4303 c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), opaque_node);
41324304 return opaque_node;
41334305 }
41344306 AstNode *symbol_node = trans_create_node_symbol(c, full_type_name);
41354307 add_global_weak_alias(c, bare_name, full_type_name);
41364308 add_global_var(c, full_type_name, opaque_node);
4137 c->decl_table.put(record_decl->getCanonicalDecl(), symbol_node);
4309 c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), symbol_node);
41384310 return symbol_node;
41394311}
41404312
4141static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl) {
4142 auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
4313static AstNode *resolve_record_decl(Context *c, const ZigClangRecordDecl *record_decl) {
4314 auto existing_entry = c->decl_table.maybe_get(ZigClangRecordDecl_getCanonicalDecl(record_decl));
41434315 if (existing_entry) {
41444316 return existing_entry->value;
41454317 }
41464318
4147 const char *raw_name = decl_name(record_decl);
4319 const char *raw_name = ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)record_decl);
41484320 const char *container_kind_name;
41494321 ContainerKind container_kind;
4150 if (record_decl->isUnion()) {
4322 if (ZigClangRecordDecl_isUnion(record_decl)) {
41514323 container_kind_name = "union";
41524324 container_kind = ContainerKindUnion;
4153 } else if (record_decl->isStruct()) {
4325 } else if (ZigClangRecordDecl_isStruct(record_decl)) {
41544326 container_kind_name = "struct";
41554327 container_kind = ContainerKindStruct;
41564328 } else {
4157 emit_warning(c, record_decl->getLocation(), "skipping record %s, not a struct or union", raw_name);
4158 c->decl_table.put(record_decl->getCanonicalDecl(), nullptr);
4329 emit_warning(c, ZigClangRecordDecl_getLocation(record_decl),
4330 "skipping record %s, not a struct or union", raw_name);
4331 c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), nullptr);
41594332 return nullptr;
41604333 }
41614334
4162 bool is_anonymous = record_decl->isAnonymousStructOrUnion() || raw_name[0] == 0;
4335 bool is_anonymous = ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl) || raw_name[0] == 0;
41634336 Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
41644337 Buf *full_type_name = (bare_name == nullptr) ?
41654338 nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name));
41664339
4167 clang::RecordDecl *record_def = record_decl->getDefinition();
4340 const ZigClangRecordDecl *record_def = ZigClangRecordDecl_getDefinition(record_decl);
41684341 if (record_def == nullptr) {
41694342 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
41704343 }
41714344
41724345 // count fields and validate
41734346 uint32_t field_count = 0;
4174 for (auto it = record_def->field_begin(),
4175 it_end = record_def->field_end();
4347 for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
4348 it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
41764349 it != it_end; ++it, field_count += 1)
41774350 {
41784351 const clang::FieldDecl *field_decl = *it;
41794352
41804353 if (field_decl->isBitField()) {
4181 emit_warning(c, field_decl->getLocation(), "%s %s demoted to opaque type - has bitfield",
4354 emit_warning(c, bitcast(field_decl->getLocation()), "%s %s demoted to opaque type - has bitfield",
41824355 container_kind_name,
41834356 is_anonymous ? "(anon)" : buf_ptr(bare_name));
41844357 return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
......@@ -4195,24 +4368,25 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_
41954368
41964369 // must be before fields in case a circular reference happens
41974370 if (is_anonymous) {
4198 c->decl_table.put(record_decl->getCanonicalDecl(), struct_node);
4371 c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), struct_node);
41994372 } else {
4200 c->decl_table.put(record_decl->getCanonicalDecl(), trans_create_node_symbol(c, full_type_name));
4373 c->decl_table.put(ZigClangRecordDecl_getCanonicalDecl(record_decl), trans_create_node_symbol(c, full_type_name));
42014374 }
42024375
42034376 uint32_t i = 0;
4204 for (auto it = record_def->field_begin(),
4205 it_end = record_def->field_end();
4377 for (auto it = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_begin(),
4378 it_end = reinterpret_cast<const clang::RecordDecl *>(record_def)->field_end();
42064379 it != it_end; ++it, i += 1)
42074380 {
42084381 const clang::FieldDecl *field_decl = *it;
42094382
42104383 AstNode *field_node = trans_create_node(c, NodeTypeStructField);
4211 field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
4212 field_node->data.struct_field.type = trans_qual_type(c, field_decl->getType(), field_decl->getLocation());
4384 field_node->data.struct_field.name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)field_decl));
4385 field_node->data.struct_field.type = trans_qual_type(c, bitcast(field_decl->getType()),
4386 bitcast(field_decl->getLocation()));
42134387
42144388 if (field_node->data.struct_field.type == nullptr) {
4215 emit_warning(c, field_decl->getLocation(),
4389 emit_warning(c, bitcast(field_decl->getLocation()),
42164390 "%s %s demoted to opaque type - unresolved type",
42174391 container_kind_name,
42184392 is_anonymous ? "(anon)" : buf_ptr(bare_name));
......@@ -4232,17 +4406,19 @@ static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_
42324406 }
42334407}
42344408
4235static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc) {
4236 switch (ap_value->getKind()) {
4237 case clang::APValue::Int:
4238 return trans_create_node_apint(c, ap_value->getInt());
4239 case clang::APValue::Uninitialized:
4409static AstNode *trans_ap_value(Context *c, const ZigClangAPValue *ap_value, ZigClangQualType qt,
4410 ZigClangSourceLocation source_loc)
4411{
4412 switch (ZigClangAPValue_getKind(ap_value)) {
4413 case ZigClangAPValueInt:
4414 return trans_create_node_apint(c, ZigClangAPValue_getInt(ap_value));
4415 case ZigClangAPValueUninitialized:
42404416 return trans_create_node(c, NodeTypeUndefinedLiteral);
4241 case clang::APValue::Array: {
4417 case ZigClangAPValueArray: {
42424418 emit_warning(c, source_loc, "TODO add a test case for this code");
42434419
4244 unsigned init_count = ap_value->getArrayInitializedElts();
4245 unsigned all_count = ap_value->getArraySize();
4420 unsigned init_count = ZigClangAPValue_getArrayInitializedElts(ap_value);
4421 unsigned all_count = ZigClangAPValue_getArraySize(ap_value);
42464422 unsigned leftover_count = all_count - init_count;
42474423 AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr);
42484424 AstNode *arr_type_node = trans_qual_type(c, qt, source_loc);
......@@ -4252,11 +4428,12 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual
42524428 init_node->data.container_init_expr.type = arr_type_node;
42534429 init_node->data.container_init_expr.kind = ContainerInitKindArray;
42544430
4255 clang::QualType child_qt = qt.getTypePtr()->getAsArrayTypeUnsafe()->getElementType();
4431 const clang::Type *qt_type = reinterpret_cast<const clang::Type *>(ZigClangQualType_getTypePtr(qt));
4432 ZigClangQualType child_qt = bitcast(qt_type->getAsArrayTypeUnsafe()->getElementType());
42564433
42574434 for (size_t i = 0; i < init_count; i += 1) {
4258 clang::APValue &elem_ap_val = ap_value->getArrayInitializedElt(i);
4259 AstNode *elem_node = trans_ap_value(c, &elem_ap_val, child_qt, source_loc);
4435 const ZigClangAPValue *elem_ap_val = ZigClangAPValue_getArrayInitializedElt(ap_value, i);
4436 AstNode *elem_node = trans_ap_value(c, elem_ap_val, child_qt, source_loc);
42604437 if (elem_node == nullptr)
42614438 return nullptr;
42624439 init_node->data.container_init_expr.entries.append(elem_node);
......@@ -4265,8 +4442,8 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual
42654442 return init_node;
42664443 }
42674444
4268 clang::APValue &filler_ap_val = ap_value->getArrayFiller();
4269 AstNode *filler_node = trans_ap_value(c, &filler_ap_val, child_qt, source_loc);
4445 const ZigClangAPValue *filler_ap_val = ZigClangAPValue_getArrayFiller(ap_value);
4446 AstNode *filler_node = trans_ap_value(c, filler_ap_val, child_qt, source_loc);
42704447 if (filler_node == nullptr)
42714448 return nullptr;
42724449
......@@ -4293,37 +4470,37 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual
42934470
42944471 return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node);
42954472 }
4296 case clang::APValue::LValue: {
4297 const clang::APValue::LValueBase lval_base = ap_value->getLValueBase();
4298 if (const clang::Expr *expr = lval_base.dyn_cast<const clang::Expr *>()) {
4473 case ZigClangAPValueLValue: {
4474 const ZigClangAPValueLValueBase lval_base = ZigClangAPValue_getLValueBase(ap_value);
4475 if (const ZigClangExpr *expr = ZigClangAPValueLValueBase_dyn_cast_Expr(lval_base)) {
42994476 return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
43004477 }
43014478 //const clang::ValueDecl *value_decl = lval_base.get<const clang::ValueDecl *>();
43024479 emit_warning(c, source_loc, "TODO handle initializer LValue clang::ValueDecl");
43034480 return nullptr;
43044481 }
4305 case clang::APValue::Float:
4482 case ZigClangAPValueFloat:
43064483 emit_warning(c, source_loc, "unsupported initializer value kind: Float");
43074484 return nullptr;
4308 case clang::APValue::ComplexInt:
4485 case ZigClangAPValueComplexInt:
43094486 emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt");
43104487 return nullptr;
4311 case clang::APValue::ComplexFloat:
4488 case ZigClangAPValueComplexFloat:
43124489 emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat");
43134490 return nullptr;
4314 case clang::APValue::Vector:
4491 case ZigClangAPValueVector:
43154492 emit_warning(c, source_loc, "unsupported initializer value kind: Vector");
43164493 return nullptr;
4317 case clang::APValue::Struct:
4494 case ZigClangAPValueStruct:
43184495 emit_warning(c, source_loc, "unsupported initializer value kind: Struct");
43194496 return nullptr;
4320 case clang::APValue::Union:
4497 case ZigClangAPValueUnion:
43214498 emit_warning(c, source_loc, "unsupported initializer value kind: Union");
43224499 return nullptr;
4323 case clang::APValue::MemberPointer:
4500 case ZigClangAPValueMemberPointer:
43244501 emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer");
43254502 return nullptr;
4326 case clang::APValue::AddrLabelDiff:
4503 case ZigClangAPValueAddrLabelDiff:
43274504 emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff");
43284505 return nullptr;
43294506 }
......@@ -4331,42 +4508,42 @@ static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::Qual
43314508}
43324509
43334510static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
4334 Buf *name = buf_create_from_str(decl_name(var_decl));
4511 Buf *name = buf_create_from_str(ZigClangDecl_getName_bytes_begin((const ZigClangDecl *)var_decl));
43354512
43364513 switch (var_decl->getTLSKind()) {
43374514 case clang::VarDecl::TLS_None:
43384515 break;
43394516 case clang::VarDecl::TLS_Static:
4340 emit_warning(c, var_decl->getLocation(),
4517 emit_warning(c, bitcast(var_decl->getLocation()),
43414518 "ignoring variable '%s' - static thread local storage", buf_ptr(name));
43424519 return;
43434520 case clang::VarDecl::TLS_Dynamic:
4344 emit_warning(c, var_decl->getLocation(),
4521 emit_warning(c, bitcast(var_decl->getLocation()),
43454522 "ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
43464523 return;
43474524 }
43484525
4349 clang::QualType qt = var_decl->getType();
4350 AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
4526 ZigClangQualType qt = bitcast(var_decl->getType());
4527 AstNode *var_type = trans_qual_type(c, qt, bitcast(var_decl->getLocation()));
43514528 if (var_type == nullptr) {
4352 emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
4529 emit_warning(c, bitcast(var_decl->getLocation()), "ignoring variable '%s' - unresolved type", buf_ptr(name));
43534530 return;
43544531 }
43554532
43564533 bool is_extern = var_decl->hasExternalStorage();
43574534 bool is_static = var_decl->isFileVarDecl();
4358 bool is_const = qt.isConstQualified();
4535 bool is_const = ZigClangQualType_isConstQualified(qt);
43594536
43604537 if (is_static && !is_extern) {
43614538 AstNode *init_node;
43624539 if (var_decl->hasInit()) {
4363 clang::APValue *ap_value = var_decl->evaluateValue();
4540 const ZigClangAPValue *ap_value = bitcast(var_decl->evaluateValue());
43644541 if (ap_value == nullptr) {
4365 emit_warning(c, var_decl->getLocation(),
4542 emit_warning(c, bitcast(var_decl->getLocation()),
43664543 "ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
43674544 return;
43684545 }
4369 init_node = trans_ap_value(c, ap_value, qt, var_decl->getLocation());
4546 init_node = trans_ap_value(c, ap_value, qt, bitcast(var_decl->getLocation()));
43704547 if (init_node == nullptr)
43714548 return;
43724549 } else {
......@@ -4385,33 +4562,32 @@ static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
43854562 return;
43864563 }
43874564
4388 emit_warning(c, var_decl->getLocation(),
4565 emit_warning(c, bitcast(var_decl->getLocation()),
43894566 "ignoring variable '%s' - non-extern, non-static variable", buf_ptr(name));
43904567 return;
43914568}
43924569
4393static bool decl_visitor(void *context, const ZigClangDecl *zdecl) {
4394 const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zdecl);
4570static bool decl_visitor(void *context, const ZigClangDecl *decl) {
43954571 Context *c = (Context*)context;
43964572
4397 switch (decl->getKind()) {
4398 case clang::Decl::Function:
4399 visit_fn_decl(c, static_cast<const clang::FunctionDecl*>(decl));
4573 switch (ZigClangDecl_getKind(decl)) {
4574 case ZigClangDeclFunction:
4575 visit_fn_decl(c, reinterpret_cast<const ZigClangFunctionDecl*>(decl));
44004576 break;
4401 case clang::Decl::Typedef:
4402 resolve_typedef_decl(c, static_cast<const clang::TypedefNameDecl *>(decl));
4577 case ZigClangDeclTypedef:
4578 resolve_typedef_decl(c, reinterpret_cast<const ZigClangTypedefNameDecl *>(decl));
44034579 break;
4404 case clang::Decl::Enum:
4405 resolve_enum_decl(c, static_cast<const clang::EnumDecl *>(decl));
4580 case ZigClangDeclEnum:
4581 resolve_enum_decl(c, reinterpret_cast<const ZigClangEnumDecl *>(decl));
44064582 break;
4407 case clang::Decl::Record:
4408 resolve_record_decl(c, static_cast<const clang::RecordDecl *>(decl));
4583 case ZigClangDeclRecord:
4584 resolve_record_decl(c, reinterpret_cast<const ZigClangRecordDecl *>(decl));
44094585 break;
4410 case clang::Decl::Var:
4411 visit_var_decl(c, static_cast<const clang::VarDecl *>(decl));
4586 case ZigClangDeclVar:
4587 visit_var_decl(c, reinterpret_cast<const clang::VarDecl *>(decl));
44124588 break;
44134589 default:
4414 emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
4590 emit_warning(c, ZigClangDecl_getLocation(decl), "ignoring %s decl", ZigClangDecl_getDeclKindName(decl));
44154591 }
44164592
44174593 return true;
......@@ -4720,6 +4896,8 @@ static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok
47204896 case CTokIdAsterisk:
47214897 case CTokIdBang:
47224898 case CTokIdTilde:
4899 case CTokIdShl:
4900 case CTokIdLt:
47234901 // not able to make sense of this
47244902 return nullptr;
47254903 }
......@@ -4751,6 +4929,13 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
47514929 *tok_i += 1;
47524930
47534931 node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
4932 } else if (first_tok->id == CTokIdShl) {
4933 *tok_i += 1;
4934
4935 AstNode *rhs_node = parse_ctok_expr(c, ctok, tok_i);
4936 if (rhs_node == nullptr)
4937 return nullptr;
4938 node = trans_create_node_bin_op(c, node, BinOpTypeBitShiftLeft, rhs_node);
47544939 } else {
47554940 return node;
47564941 }
......@@ -4846,10 +5031,10 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
48465031 clang::MacroDefinitionRecord *macro = static_cast<clang::MacroDefinitionRecord *>(entity);
48475032 const char *raw_name = macro->getName()->getNameStart();
48485033 clang::SourceRange range = macro->getSourceRange();
4849 clang::SourceLocation begin_loc = range.getBegin();
4850 clang::SourceLocation end_loc = range.getEnd();
5034 ZigClangSourceLocation begin_loc = bitcast(range.getBegin());
5035 ZigClangSourceLocation end_loc = bitcast(range.getEnd());
48515036
4852 if (begin_loc == end_loc) {
5037 if (ZigClangSourceLocation_eq(begin_loc, end_loc)) {
48535038 // this means it is a macro without a value
48545039 // we don't care about such things
48555040 continue;
......@@ -4859,21 +5044,22 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
48595044 continue;
48605045 }
48615046
4862 const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, bitcast(begin_loc));
5047 const char *begin_c = ZigClangSourceManager_getCharacterData(c->source_manager, begin_loc);
48635048 process_macro(c, &ctok, name, begin_c);
48645049 }
48655050 }
48665051 }
48675052}
48685053
4869Error parse_h_file(AstNode **out_root_node, ZigList<ErrorMsg *> *errors, const char *target_file,
4870 CodeGen *codegen, Buf *tmp_dep_file)
5054Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
5055 Stage2ErrorMsg **errors_ptr, size_t *errors_len,
5056 const char **args_begin, const char **args_end,
5057 Stage2TranslateMode mode, const char *resources_path)
48715058{
48725059 Context context = {0};
48735060 Context *c = &context;
48745061 c->warnings_on = codegen->verbose_cimport;
4875 c->errors = errors;
4876 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
5062 if (mode == Stage2TranslateModeImport) {
48775063 c->visib_mod = VisibModPub;
48785064 c->want_export = false;
48795065 } else {
......@@ -4887,161 +5073,10 @@ Error parse_h_file(AstNode **out_root_node, ZigList<ErrorMsg *> *errors, const c
48875073 c->codegen = codegen;
48885074 c->global_scope = trans_scope_root_create(c);
48895075
4890 ZigList<const char *> clang_argv = {0};
4891
4892 clang_argv.append("-x");
4893 clang_argv.append("c");
4894
4895 if (tmp_dep_file != nullptr) {
4896 clang_argv.append("-MD");
4897 clang_argv.append("-MV");
4898 clang_argv.append("-MF");
4899 clang_argv.append(buf_ptr(tmp_dep_file));
4900 }
4901
4902 if (c->codegen->zig_target->is_native) {
4903 char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");
4904 if (ZIG_PARSEC_CFLAGS) {
4905 Buf tmp_buf = BUF_INIT;
4906 char *start = ZIG_PARSEC_CFLAGS;
4907 char *space = strstr(start, " ");
4908 while (space) {
4909 if (space - start > 0) {
4910 buf_init_from_mem(&tmp_buf, start, space - start);
4911 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
4912 }
4913 start = space + 1;
4914 space = strstr(start, " ");
4915 }
4916 buf_init_from_str(&tmp_buf, start);
4917 clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
4918 }
4919 }
4920
4921 clang_argv.append("-nobuiltininc");
4922 clang_argv.append("-nostdinc");
4923 clang_argv.append("-nostdinc++");
4924 if (codegen->libc_link_lib == nullptr) {
4925 clang_argv.append("-nolibc");
4926 }
4927
4928 clang_argv.append("-isystem");
4929 clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
4930
4931 for (size_t i = 0; i < codegen->libc_include_dir_len; i += 1) {
4932 Buf *include_dir = codegen->libc_include_dir_list[i];
4933 clang_argv.append("-isystem");
4934 clang_argv.append(buf_ptr(include_dir));
4935 }
4936
4937 // windows c runtime requires -D_DEBUG if using debug libraries
4938 if (codegen->build_mode == BuildModeDebug) {
4939 clang_argv.append("-D_DEBUG");
4940 }
4941
4942 for (size_t i = 0; i < codegen->clang_argv_len; i += 1) {
4943 clang_argv.append(codegen->clang_argv[i]);
4944 }
4945
4946 // we don't need spell checking and it slows things down
4947 clang_argv.append("-fno-spell-checking");
4948
4949 // this gives us access to preprocessing entities, presumably at
4950 // the cost of performance
4951 clang_argv.append("-Xclang");
4952 clang_argv.append("-detailed-preprocessing-record");
4953
4954 if (c->codegen->zig_target->is_native) {
4955 clang_argv.append("-march=native");
4956 } else {
4957 clang_argv.append("-target");
4958 clang_argv.append(buf_ptr(&c->codegen->triple_str));
4959 }
4960
4961 clang_argv.append(target_file);
4962
4963 if (codegen->verbose_cc) {
4964 fprintf(stderr, "clang");
4965 for (size_t i = 0; i < clang_argv.length; i += 1) {
4966 fprintf(stderr, " %s", clang_argv.at(i));
4967 }
4968 fprintf(stderr, "\n");
4969 }
4970
4971 // to make the [start...end] argument work
4972 clang_argv.append(nullptr);
4973
4974 clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
4975
4976 std::shared_ptr<clang::PCHContainerOperations> pch_container_ops = std::make_shared<clang::PCHContainerOperations>();
4977
4978 bool only_local_decls = true;
4979 bool capture_diagnostics = true;
4980 bool user_files_are_volatile = true;
4981 bool allow_pch_with_compiler_errors = false;
4982 bool single_file_parse = false;
4983 bool for_serialization = false;
4984 const char *resources_path = buf_ptr(codegen->zig_c_headers_dir);
4985 std::unique_ptr<clang::ASTUnit> err_unit;
4986 ZigClangASTUnit *ast_unit = reinterpret_cast<ZigClangASTUnit *>(clang::ASTUnit::LoadFromCommandLine(
4987 &clang_argv.at(0), &clang_argv.last(),
4988 pch_container_ops, diags, resources_path,
4989 only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete,
4990 false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
4991 single_file_parse, user_files_are_volatile, for_serialization, clang::None, &err_unit,
4992 nullptr));
4993
4994 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
4995 if (!ast_unit && !err_unit) {
4996 return ErrorFileSystem;
4997 }
4998
4999 if (diags->getClient()->getNumErrors() > 0) {
5000 if (ast_unit) {
5001 err_unit = std::unique_ptr<clang::ASTUnit>(reinterpret_cast<clang::ASTUnit *>(ast_unit));
5002 }
5003
5004 for (clang::ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
5005 it_end = err_unit->stored_diag_end();
5006 it != it_end; ++it)
5007 {
5008 switch (it->getLevel()) {
5009 case clang::DiagnosticsEngine::Ignored:
5010 case clang::DiagnosticsEngine::Note:
5011 case clang::DiagnosticsEngine::Remark:
5012 case clang::DiagnosticsEngine::Warning:
5013 continue;
5014 case clang::DiagnosticsEngine::Error:
5015 case clang::DiagnosticsEngine::Fatal:
5016 break;
5017 }
5018 llvm::StringRef msg_str_ref = it->getMessage();
5019 Buf *msg = string_ref_to_buf(msg_str_ref);
5020 clang::FullSourceLoc fsl = it->getLocation();
5021 if (fsl.hasManager()) {
5022 clang::FileID file_id = fsl.getFileID();
5023 clang::StringRef filename = fsl.getManager().getFilename(fsl);
5024 unsigned line = fsl.getSpellingLineNumber() - 1;
5025 unsigned column = fsl.getSpellingColumnNumber() - 1;
5026 unsigned offset = fsl.getManager().getFileOffset(fsl);
5027 const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
5028 Buf *path;
5029 if (filename.empty()) {
5030 path = buf_alloc();
5031 } else {
5032 path = string_ref_to_buf(filename);
5033 }
5034
5035 ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
5036
5037 c->errors->append(err_msg);
5038 } else {
5039 // NOTE the only known way this gets triggered right now is if you have a lot of errors
5040 // clang emits "too many errors emitted, stopping now"
5041 fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg));
5042 }
5043 }
5044
5076 ZigClangASTUnit *ast_unit = ZigClangLoadFromCommandLine(args_begin, args_end, errors_ptr, errors_len,
5077 resources_path);
5078 if (ast_unit == nullptr) {
5079 if (*errors_len == 0) return ErrorNoMem;
50455080 return ErrorCCompileErrors;
50465081 }
50475082
......@@ -5059,5 +5094,7 @@ Error parse_h_file(AstNode **out_root_node, ZigList<ErrorMsg *> *errors, const c
50595094
50605095 *out_root_node = c->root;
50615096
5097 ZigClangASTUnit_delete(ast_unit);
5098
50625099 return ErrorNone;
50635100}
src/translate_c.hpp+4-2
......@@ -11,7 +11,9 @@
1111
1212#include "all_types.hpp"
1313
14Error parse_h_file(AstNode **out_root_node, ZigList<ErrorMsg *> *errors, const char *target_file,
15 CodeGen *codegen, Buf *tmp_dep_file);
14Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
15 Stage2ErrorMsg **errors_ptr, size_t *errors_len,
16 const char **args_begin, const char **args_end,
17 Stage2TranslateMode mode, const char *resources_path);
1618
1719#endif
src/userland.cpp created+44
......@@ -0,0 +1,44 @@
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 "ast_render.hpp"
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10Error stage2_translate_c(struct Stage2Ast **out_ast,
11 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
12 const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
13 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_panic(const char *ptr, size_t len) {
30 fwrite(ptr, 1, len, stderr);
31 fprintf(stderr, "\n");
32 fflush(stderr);
33 abort();
34}
35
36void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) {
37 const char *msg = "stage0 called stage2_render_ast";
38 stage2_panic(msg, strlen(msg));
39}
40
41int stage2_fmt(int argc, char **argv) {
42 const char *msg = "stage0 called stage2_fmt";
43 stage2_panic(msg, strlen(msg));
44}
src/userland.h created+120
......@@ -0,0 +1,120 @@
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 <stdio.h>
13
14#ifdef __cplusplus
15#define ZIG_EXTERN_C extern "C"
16#else
17#define ZIG_EXTERN_C
18#endif
19
20#if defined(_MSC_VER)
21#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn)
22#else
23#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn))
24#endif
25
26// ABI warning: the types and declarations in this file must match both those in
27// userland.cpp and src-self-hosted/stage1.zig.
28
29// ABI warning
30enum Error {
31 ErrorNone,
32 ErrorNoMem,
33 ErrorInvalidFormat,
34 ErrorSemanticAnalyzeFail,
35 ErrorAccess,
36 ErrorInterrupted,
37 ErrorSystemResources,
38 ErrorFileNotFound,
39 ErrorFileSystem,
40 ErrorFileTooBig,
41 ErrorDivByZero,
42 ErrorOverflow,
43 ErrorPathAlreadyExists,
44 ErrorUnexpected,
45 ErrorExactDivRemainder,
46 ErrorNegativeDenominator,
47 ErrorShiftedOutOneBits,
48 ErrorCCompileErrors,
49 ErrorEndOfFile,
50 ErrorIsDir,
51 ErrorNotDir,
52 ErrorUnsupportedOperatingSystem,
53 ErrorSharingViolation,
54 ErrorPipeBusy,
55 ErrorPrimitiveTypeNotFound,
56 ErrorCacheUnavailable,
57 ErrorPathTooLong,
58 ErrorCCompilerCannotFindFile,
59 ErrorReadingDepFile,
60 ErrorInvalidDepFile,
61 ErrorMissingArchitecture,
62 ErrorMissingOperatingSystem,
63 ErrorUnknownArchitecture,
64 ErrorUnknownOperatingSystem,
65 ErrorUnknownABI,
66 ErrorInvalidFilename,
67 ErrorDiskQuota,
68 ErrorDiskSpace,
69 ErrorUnexpectedWriteFailure,
70 ErrorUnexpectedSeekFailure,
71 ErrorUnexpectedFileTruncationFailure,
72 ErrorUnimplemented,
73 ErrorOperationAborted,
74 ErrorBrokenPipe,
75 ErrorNoSpaceLeft,
76};
77
78// ABI warning
79enum Stage2TranslateMode {
80 Stage2TranslateModeImport,
81 Stage2TranslateModeTranslate,
82};
83
84// ABI warning
85struct Stage2ErrorMsg {
86 const char *filename_ptr; // can be null
87 size_t filename_len;
88 const char *msg_ptr;
89 size_t msg_len;
90 const char *source; // valid until the ASTUnit is freed. can be null
91 unsigned line; // 0 based
92 unsigned column; // 0 based
93 unsigned offset; // byte offset into source
94};
95
96// ABI warning
97struct Stage2Ast;
98
99// ABI warning
100ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
101 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
102 const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
103 const char *resources_path);
104
105// ABI warning
106ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
107
108// ABI warning
109ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
110
111// ABI warning
112ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
113
114// ABI warning
115ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
116
117// ABI warning
118ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
119
120#endif
src/util.cpp+9-1
......@@ -10,17 +10,25 @@
1010#include <stdarg.h>
1111
1212#include "util.hpp"
13#include "userland.h"
1314
1415void zig_panic(const char *format, ...) {
1516 va_list ap;
1617 va_start(ap, format);
1718 vfprintf(stderr, format, ap);
18 fprintf(stderr, "\n");
1919 fflush(stderr);
2020 va_end(ap);
21 stage2_panic(nullptr, 0);
2122 abort();
2223}
2324
25void assert(bool ok) {
26 if (!ok) {
27 const char *msg = "Assertion failed. This is a bug in the Zig compiler.";
28 stage2_panic(msg, strlen(msg));
29 }
30}
31
2432uint32_t int_hash(int i) {
2533 return (uint32_t)(i % UINT32_MAX);
2634}
src/util.hpp+4
......@@ -48,6 +48,10 @@ void zig_panic(const char *format, ...);
4848
4949#define zig_unreachable() zig_panic("unreachable: %s:%s:%d", __FILE__, __func__, __LINE__)
5050
51// Assertions in stage1 are always on, and they call zig @panic.
52#undef assert
53void assert(bool ok);
54
5155#if defined(_MSC_VER)
5256static inline int clzll(unsigned long long mask) {
5357 unsigned long lz;
src/zig_clang.cpp+1667-50
......@@ -28,41 +28,41 @@
2828#endif
2929
3030// Detect additions to the enum
31void zig2clang_BO(ZigClangBO op) {
31void ZigClang_detect_enum_BO(clang::BinaryOperatorKind op) {
3232 switch (op) {
33 case ZigClangBO_PtrMemD:
34 case ZigClangBO_PtrMemI:
35 case ZigClangBO_Cmp:
36 case ZigClangBO_Mul:
37 case ZigClangBO_Div:
38 case ZigClangBO_Rem:
39 case ZigClangBO_Add:
40 case ZigClangBO_Sub:
41 case ZigClangBO_Shl:
42 case ZigClangBO_Shr:
43 case ZigClangBO_LT:
44 case ZigClangBO_GT:
45 case ZigClangBO_LE:
46 case ZigClangBO_GE:
47 case ZigClangBO_EQ:
48 case ZigClangBO_NE:
49 case ZigClangBO_And:
50 case ZigClangBO_Xor:
51 case ZigClangBO_Or:
52 case ZigClangBO_LAnd:
53 case ZigClangBO_LOr:
54 case ZigClangBO_Assign:
55 case ZigClangBO_Comma:
56 case ZigClangBO_MulAssign:
57 case ZigClangBO_DivAssign:
58 case ZigClangBO_RemAssign:
59 case ZigClangBO_AddAssign:
60 case ZigClangBO_SubAssign:
61 case ZigClangBO_ShlAssign:
62 case ZigClangBO_ShrAssign:
63 case ZigClangBO_AndAssign:
64 case ZigClangBO_XorAssign:
65 case ZigClangBO_OrAssign:
33 case clang::BO_PtrMemD:
34 case clang::BO_PtrMemI:
35 case clang::BO_Cmp:
36 case clang::BO_Mul:
37 case clang::BO_Div:
38 case clang::BO_Rem:
39 case clang::BO_Add:
40 case clang::BO_Sub:
41 case clang::BO_Shl:
42 case clang::BO_Shr:
43 case clang::BO_LT:
44 case clang::BO_GT:
45 case clang::BO_LE:
46 case clang::BO_GE:
47 case clang::BO_EQ:
48 case clang::BO_NE:
49 case clang::BO_And:
50 case clang::BO_Xor:
51 case clang::BO_Or:
52 case clang::BO_LAnd:
53 case clang::BO_LOr:
54 case clang::BO_Assign:
55 case clang::BO_Comma:
56 case clang::BO_MulAssign:
57 case clang::BO_DivAssign:
58 case clang::BO_RemAssign:
59 case clang::BO_AddAssign:
60 case clang::BO_SubAssign:
61 case clang::BO_ShlAssign:
62 case clang::BO_ShrAssign:
63 case clang::BO_AndAssign:
64 case clang::BO_XorAssign:
65 case clang::BO_OrAssign:
6666 break;
6767 }
6868}
......@@ -101,23 +101,23 @@ static_assert((clang::BinaryOperatorKind)ZigClangBO_SubAssign == clang::BO_SubAs
101101static_assert((clang::BinaryOperatorKind)ZigClangBO_Xor == clang::BO_Xor, "");
102102static_assert((clang::BinaryOperatorKind)ZigClangBO_XorAssign == clang::BO_XorAssign, "");
103103
104// This function detects additions to the enum
105void zig2clang_UO(ZigClangUO op) {
104// Detect additions to the enum
105void ZigClang_detect_enum_UO(clang::UnaryOperatorKind op) {
106106 switch (op) {
107 case ZigClangUO_AddrOf:
108 case ZigClangUO_Coawait:
109 case ZigClangUO_Deref:
110 case ZigClangUO_Extension:
111 case ZigClangUO_Imag:
112 case ZigClangUO_LNot:
113 case ZigClangUO_Minus:
114 case ZigClangUO_Not:
115 case ZigClangUO_Plus:
116 case ZigClangUO_PostDec:
117 case ZigClangUO_PostInc:
118 case ZigClangUO_PreDec:
119 case ZigClangUO_PreInc:
120 case ZigClangUO_Real:
107 case clang::UO_AddrOf:
108 case clang::UO_Coawait:
109 case clang::UO_Deref:
110 case clang::UO_Extension:
111 case clang::UO_Imag:
112 case clang::UO_LNot:
113 case clang::UO_Minus:
114 case clang::UO_Not:
115 case clang::UO_Plus:
116 case clang::UO_PostDec:
117 case clang::UO_PostInc:
118 case clang::UO_PreDec:
119 case clang::UO_PreInc:
120 case clang::UO_Real:
121121 break;
122122 }
123123}
......@@ -137,6 +137,1125 @@ static_assert((clang::UnaryOperatorKind)ZigClangUO_PreDec == clang::UO_PreDec, "
137137static_assert((clang::UnaryOperatorKind)ZigClangUO_PreInc == clang::UO_PreInc, "");
138138static_assert((clang::UnaryOperatorKind)ZigClangUO_Real == clang::UO_Real, "");
139139
140// Detect additions to the enum
141void ZigClang_detect_enum_CK(clang::CastKind x) {
142 switch (x) {
143 case clang::CK_ARCConsumeObject:
144 case clang::CK_ARCExtendBlockObject:
145 case clang::CK_ARCProduceObject:
146 case clang::CK_ARCReclaimReturnedObject:
147 case clang::CK_AddressSpaceConversion:
148 case clang::CK_AnyPointerToBlockPointerCast:
149 case clang::CK_ArrayToPointerDecay:
150 case clang::CK_AtomicToNonAtomic:
151 case clang::CK_BaseToDerived:
152 case clang::CK_BaseToDerivedMemberPointer:
153 case clang::CK_BitCast:
154 case clang::CK_BlockPointerToObjCPointerCast:
155 case clang::CK_BooleanToSignedIntegral:
156 case clang::CK_BuiltinFnToFnPtr:
157 case clang::CK_CPointerToObjCPointerCast:
158 case clang::CK_ConstructorConversion:
159 case clang::CK_CopyAndAutoreleaseBlockObject:
160 case clang::CK_Dependent:
161 case clang::CK_DerivedToBase:
162 case clang::CK_DerivedToBaseMemberPointer:
163 case clang::CK_Dynamic:
164 case clang::CK_FloatingCast:
165 case clang::CK_FloatingComplexCast:
166 case clang::CK_FloatingComplexToBoolean:
167 case clang::CK_FloatingComplexToIntegralComplex:
168 case clang::CK_FloatingComplexToReal:
169 case clang::CK_FloatingRealToComplex:
170 case clang::CK_FloatingToBoolean:
171 case clang::CK_FloatingToIntegral:
172 case clang::CK_FunctionToPointerDecay:
173 case clang::CK_IntToOCLSampler:
174 case clang::CK_IntegralCast:
175 case clang::CK_IntegralComplexCast:
176 case clang::CK_IntegralComplexToBoolean:
177 case clang::CK_IntegralComplexToFloatingComplex:
178 case clang::CK_IntegralComplexToReal:
179 case clang::CK_IntegralRealToComplex:
180 case clang::CK_IntegralToBoolean:
181 case clang::CK_IntegralToFloating:
182 case clang::CK_IntegralToPointer:
183 case clang::CK_LValueBitCast:
184 case clang::CK_LValueToRValue:
185 case clang::CK_MemberPointerToBoolean:
186 case clang::CK_NoOp:
187 case clang::CK_NonAtomicToAtomic:
188 case clang::CK_NullToMemberPointer:
189 case clang::CK_NullToPointer:
190 case clang::CK_ObjCObjectLValueCast:
191 case clang::CK_PointerToBoolean:
192 case clang::CK_PointerToIntegral:
193 case clang::CK_ReinterpretMemberPointer:
194 case clang::CK_ToUnion:
195 case clang::CK_ToVoid:
196 case clang::CK_UncheckedDerivedToBase:
197 case clang::CK_UserDefinedConversion:
198 case clang::CK_VectorSplat:
199 case clang::CK_ZeroToOCLOpaqueType:
200 case clang::CK_FixedPointCast:
201 case clang::CK_FixedPointToBoolean:
202 break;
203 }
204};
205
206static_assert((clang::CastKind)ZigClangCK_Dependent == clang::CK_Dependent, "");
207static_assert((clang::CastKind)ZigClangCK_BitCast == clang::CK_BitCast, "");
208static_assert((clang::CastKind)ZigClangCK_LValueBitCast == clang::CK_LValueBitCast, "");
209static_assert((clang::CastKind)ZigClangCK_LValueToRValue == clang::CK_LValueToRValue, "");
210static_assert((clang::CastKind)ZigClangCK_NoOp == clang::CK_NoOp, "");
211static_assert((clang::CastKind)ZigClangCK_BaseToDerived == clang::CK_BaseToDerived, "");
212static_assert((clang::CastKind)ZigClangCK_DerivedToBase == clang::CK_DerivedToBase, "");
213static_assert((clang::CastKind)ZigClangCK_UncheckedDerivedToBase == clang::CK_UncheckedDerivedToBase, "");
214static_assert((clang::CastKind)ZigClangCK_Dynamic == clang::CK_Dynamic, "");
215static_assert((clang::CastKind)ZigClangCK_ToUnion == clang::CK_ToUnion, "");
216static_assert((clang::CastKind)ZigClangCK_ArrayToPointerDecay == clang::CK_ArrayToPointerDecay, "");
217static_assert((clang::CastKind)ZigClangCK_FunctionToPointerDecay == clang::CK_FunctionToPointerDecay, "");
218static_assert((clang::CastKind)ZigClangCK_NullToPointer == clang::CK_NullToPointer, "");
219static_assert((clang::CastKind)ZigClangCK_NullToMemberPointer == clang::CK_NullToMemberPointer, "");
220static_assert((clang::CastKind)ZigClangCK_BaseToDerivedMemberPointer == clang::CK_BaseToDerivedMemberPointer, "");
221static_assert((clang::CastKind)ZigClangCK_DerivedToBaseMemberPointer == clang::CK_DerivedToBaseMemberPointer, "");
222static_assert((clang::CastKind)ZigClangCK_MemberPointerToBoolean == clang::CK_MemberPointerToBoolean, "");
223static_assert((clang::CastKind)ZigClangCK_ReinterpretMemberPointer == clang::CK_ReinterpretMemberPointer, "");
224static_assert((clang::CastKind)ZigClangCK_UserDefinedConversion == clang::CK_UserDefinedConversion, "");
225static_assert((clang::CastKind)ZigClangCK_ConstructorConversion == clang::CK_ConstructorConversion, "");
226static_assert((clang::CastKind)ZigClangCK_IntegralToPointer == clang::CK_IntegralToPointer, "");
227static_assert((clang::CastKind)ZigClangCK_PointerToIntegral == clang::CK_PointerToIntegral, "");
228static_assert((clang::CastKind)ZigClangCK_PointerToBoolean == clang::CK_PointerToBoolean, "");
229static_assert((clang::CastKind)ZigClangCK_ToVoid == clang::CK_ToVoid, "");
230static_assert((clang::CastKind)ZigClangCK_VectorSplat == clang::CK_VectorSplat, "");
231static_assert((clang::CastKind)ZigClangCK_IntegralCast == clang::CK_IntegralCast, "");
232static_assert((clang::CastKind)ZigClangCK_IntegralToBoolean == clang::CK_IntegralToBoolean, "");
233static_assert((clang::CastKind)ZigClangCK_IntegralToFloating == clang::CK_IntegralToFloating, "");
234static_assert((clang::CastKind)ZigClangCK_FixedPointCast == clang::CK_FixedPointCast, "");
235static_assert((clang::CastKind)ZigClangCK_FixedPointToBoolean == clang::CK_FixedPointToBoolean, "");
236static_assert((clang::CastKind)ZigClangCK_FloatingToIntegral == clang::CK_FloatingToIntegral, "");
237static_assert((clang::CastKind)ZigClangCK_FloatingToBoolean == clang::CK_FloatingToBoolean, "");
238static_assert((clang::CastKind)ZigClangCK_BooleanToSignedIntegral == clang::CK_BooleanToSignedIntegral, "");
239static_assert((clang::CastKind)ZigClangCK_FloatingCast == clang::CK_FloatingCast, "");
240static_assert((clang::CastKind)ZigClangCK_CPointerToObjCPointerCast == clang::CK_CPointerToObjCPointerCast, "");
241static_assert((clang::CastKind)ZigClangCK_BlockPointerToObjCPointerCast == clang::CK_BlockPointerToObjCPointerCast, "");
242static_assert((clang::CastKind)ZigClangCK_AnyPointerToBlockPointerCast == clang::CK_AnyPointerToBlockPointerCast, "");
243static_assert((clang::CastKind)ZigClangCK_ObjCObjectLValueCast == clang::CK_ObjCObjectLValueCast, "");
244static_assert((clang::CastKind)ZigClangCK_FloatingRealToComplex == clang::CK_FloatingRealToComplex, "");
245static_assert((clang::CastKind)ZigClangCK_FloatingComplexToReal == clang::CK_FloatingComplexToReal, "");
246static_assert((clang::CastKind)ZigClangCK_FloatingComplexToBoolean == clang::CK_FloatingComplexToBoolean, "");
247static_assert((clang::CastKind)ZigClangCK_FloatingComplexCast == clang::CK_FloatingComplexCast, "");
248static_assert((clang::CastKind)ZigClangCK_FloatingComplexToIntegralComplex == clang::CK_FloatingComplexToIntegralComplex, "");
249static_assert((clang::CastKind)ZigClangCK_IntegralRealToComplex == clang::CK_IntegralRealToComplex, "");
250static_assert((clang::CastKind)ZigClangCK_IntegralComplexToReal == clang::CK_IntegralComplexToReal, "");
251static_assert((clang::CastKind)ZigClangCK_IntegralComplexToBoolean == clang::CK_IntegralComplexToBoolean, "");
252static_assert((clang::CastKind)ZigClangCK_IntegralComplexCast == clang::CK_IntegralComplexCast, "");
253static_assert((clang::CastKind)ZigClangCK_IntegralComplexToFloatingComplex == clang::CK_IntegralComplexToFloatingComplex, "");
254static_assert((clang::CastKind)ZigClangCK_ARCProduceObject == clang::CK_ARCProduceObject, "");
255static_assert((clang::CastKind)ZigClangCK_ARCConsumeObject == clang::CK_ARCConsumeObject, "");
256static_assert((clang::CastKind)ZigClangCK_ARCReclaimReturnedObject == clang::CK_ARCReclaimReturnedObject, "");
257static_assert((clang::CastKind)ZigClangCK_ARCExtendBlockObject == clang::CK_ARCExtendBlockObject, "");
258static_assert((clang::CastKind)ZigClangCK_AtomicToNonAtomic == clang::CK_AtomicToNonAtomic, "");
259static_assert((clang::CastKind)ZigClangCK_NonAtomicToAtomic == clang::CK_NonAtomicToAtomic, "");
260static_assert((clang::CastKind)ZigClangCK_CopyAndAutoreleaseBlockObject == clang::CK_CopyAndAutoreleaseBlockObject, "");
261static_assert((clang::CastKind)ZigClangCK_BuiltinFnToFnPtr == clang::CK_BuiltinFnToFnPtr, "");
262static_assert((clang::CastKind)ZigClangCK_ZeroToOCLOpaqueType == clang::CK_ZeroToOCLOpaqueType, "");
263static_assert((clang::CastKind)ZigClangCK_AddressSpaceConversion == clang::CK_AddressSpaceConversion, "");
264static_assert((clang::CastKind)ZigClangCK_IntToOCLSampler == clang::CK_IntToOCLSampler, "");
265
266// Detect additions to the enum
267void ZigClang_detect_enum_TypeClass(clang::Type::TypeClass ty) {
268 switch (ty) {
269 case clang::Type::Builtin:
270 case clang::Type::Complex:
271 case clang::Type::Pointer:
272 case clang::Type::BlockPointer:
273 case clang::Type::LValueReference:
274 case clang::Type::RValueReference:
275 case clang::Type::MemberPointer:
276 case clang::Type::ConstantArray:
277 case clang::Type::IncompleteArray:
278 case clang::Type::VariableArray:
279 case clang::Type::DependentSizedArray:
280 case clang::Type::DependentSizedExtVector:
281 case clang::Type::DependentAddressSpace:
282 case clang::Type::Vector:
283 case clang::Type::DependentVector:
284 case clang::Type::ExtVector:
285 case clang::Type::FunctionProto:
286 case clang::Type::FunctionNoProto:
287 case clang::Type::UnresolvedUsing:
288 case clang::Type::Paren:
289 case clang::Type::Typedef:
290 case clang::Type::Adjusted:
291 case clang::Type::Decayed:
292 case clang::Type::TypeOfExpr:
293 case clang::Type::TypeOf:
294 case clang::Type::Decltype:
295 case clang::Type::UnaryTransform:
296 case clang::Type::Record:
297 case clang::Type::Enum:
298 case clang::Type::Elaborated:
299 case clang::Type::Attributed:
300 case clang::Type::TemplateTypeParm:
301 case clang::Type::SubstTemplateTypeParm:
302 case clang::Type::SubstTemplateTypeParmPack:
303 case clang::Type::TemplateSpecialization:
304 case clang::Type::Auto:
305 case clang::Type::DeducedTemplateSpecialization:
306 case clang::Type::InjectedClassName:
307 case clang::Type::DependentName:
308 case clang::Type::DependentTemplateSpecialization:
309 case clang::Type::PackExpansion:
310 case clang::Type::ObjCTypeParam:
311 case clang::Type::ObjCObject:
312 case clang::Type::ObjCInterface:
313 case clang::Type::ObjCObjectPointer:
314 case clang::Type::Pipe:
315 case clang::Type::Atomic:
316 break;
317 }
318}
319
320static_assert((clang::Type::TypeClass)ZigClangType_Builtin == clang::Type::Builtin, "");
321static_assert((clang::Type::TypeClass)ZigClangType_Complex == clang::Type::Complex, "");
322static_assert((clang::Type::TypeClass)ZigClangType_Pointer == clang::Type::Pointer, "");
323static_assert((clang::Type::TypeClass)ZigClangType_BlockPointer == clang::Type::BlockPointer, "");
324static_assert((clang::Type::TypeClass)ZigClangType_LValueReference == clang::Type::LValueReference, "");
325static_assert((clang::Type::TypeClass)ZigClangType_RValueReference == clang::Type::RValueReference, "");
326static_assert((clang::Type::TypeClass)ZigClangType_MemberPointer == clang::Type::MemberPointer, "");
327static_assert((clang::Type::TypeClass)ZigClangType_ConstantArray == clang::Type::ConstantArray, "");
328static_assert((clang::Type::TypeClass)ZigClangType_IncompleteArray == clang::Type::IncompleteArray, "");
329static_assert((clang::Type::TypeClass)ZigClangType_VariableArray == clang::Type::VariableArray, "");
330static_assert((clang::Type::TypeClass)ZigClangType_DependentSizedArray == clang::Type::DependentSizedArray, "");
331static_assert((clang::Type::TypeClass)ZigClangType_DependentSizedExtVector == clang::Type::DependentSizedExtVector, "");
332static_assert((clang::Type::TypeClass)ZigClangType_DependentAddressSpace == clang::Type::DependentAddressSpace, "");
333static_assert((clang::Type::TypeClass)ZigClangType_Vector == clang::Type::Vector, "");
334static_assert((clang::Type::TypeClass)ZigClangType_DependentVector == clang::Type::DependentVector, "");
335static_assert((clang::Type::TypeClass)ZigClangType_ExtVector == clang::Type::ExtVector, "");
336static_assert((clang::Type::TypeClass)ZigClangType_FunctionProto == clang::Type::FunctionProto, "");
337static_assert((clang::Type::TypeClass)ZigClangType_FunctionNoProto == clang::Type::FunctionNoProto, "");
338static_assert((clang::Type::TypeClass)ZigClangType_UnresolvedUsing == clang::Type::UnresolvedUsing, "");
339static_assert((clang::Type::TypeClass)ZigClangType_Paren == clang::Type::Paren, "");
340static_assert((clang::Type::TypeClass)ZigClangType_Typedef == clang::Type::Typedef, "");
341static_assert((clang::Type::TypeClass)ZigClangType_Adjusted == clang::Type::Adjusted, "");
342static_assert((clang::Type::TypeClass)ZigClangType_Decayed == clang::Type::Decayed, "");
343static_assert((clang::Type::TypeClass)ZigClangType_TypeOfExpr == clang::Type::TypeOfExpr, "");
344static_assert((clang::Type::TypeClass)ZigClangType_TypeOf == clang::Type::TypeOf, "");
345static_assert((clang::Type::TypeClass)ZigClangType_Decltype == clang::Type::Decltype, "");
346static_assert((clang::Type::TypeClass)ZigClangType_UnaryTransform == clang::Type::UnaryTransform, "");
347static_assert((clang::Type::TypeClass)ZigClangType_Record == clang::Type::Record, "");
348static_assert((clang::Type::TypeClass)ZigClangType_Enum == clang::Type::Enum, "");
349static_assert((clang::Type::TypeClass)ZigClangType_Elaborated == clang::Type::Elaborated, "");
350static_assert((clang::Type::TypeClass)ZigClangType_Attributed == clang::Type::Attributed, "");
351static_assert((clang::Type::TypeClass)ZigClangType_TemplateTypeParm == clang::Type::TemplateTypeParm, "");
352static_assert((clang::Type::TypeClass)ZigClangType_SubstTemplateTypeParm == clang::Type::SubstTemplateTypeParm, "");
353static_assert((clang::Type::TypeClass)ZigClangType_SubstTemplateTypeParmPack == clang::Type::SubstTemplateTypeParmPack, "");
354static_assert((clang::Type::TypeClass)ZigClangType_TemplateSpecialization == clang::Type::TemplateSpecialization, "");
355static_assert((clang::Type::TypeClass)ZigClangType_Auto == clang::Type::Auto, "");
356static_assert((clang::Type::TypeClass)ZigClangType_DeducedTemplateSpecialization == clang::Type::DeducedTemplateSpecialization, "");
357static_assert((clang::Type::TypeClass)ZigClangType_InjectedClassName == clang::Type::InjectedClassName, "");
358static_assert((clang::Type::TypeClass)ZigClangType_DependentName == clang::Type::DependentName, "");
359static_assert((clang::Type::TypeClass)ZigClangType_DependentTemplateSpecialization == clang::Type::DependentTemplateSpecialization, "");
360static_assert((clang::Type::TypeClass)ZigClangType_PackExpansion == clang::Type::PackExpansion, "");
361static_assert((clang::Type::TypeClass)ZigClangType_ObjCTypeParam == clang::Type::ObjCTypeParam, "");
362static_assert((clang::Type::TypeClass)ZigClangType_ObjCObject == clang::Type::ObjCObject, "");
363static_assert((clang::Type::TypeClass)ZigClangType_ObjCInterface == clang::Type::ObjCInterface, "");
364static_assert((clang::Type::TypeClass)ZigClangType_ObjCObjectPointer == clang::Type::ObjCObjectPointer, "");
365static_assert((clang::Type::TypeClass)ZigClangType_Pipe == clang::Type::Pipe, "");
366static_assert((clang::Type::TypeClass)ZigClangType_Atomic == clang::Type::Atomic, "");
367
368// Detect additions to the enum
369void ZigClang_detect_enum_StmtClass(clang::Stmt::StmtClass x) {
370 switch (x) {
371 case clang::Stmt::NoStmtClass:
372 case clang::Stmt::NullStmtClass:
373 case clang::Stmt::CompoundStmtClass:
374 case clang::Stmt::LabelStmtClass:
375 case clang::Stmt::AttributedStmtClass:
376 case clang::Stmt::IfStmtClass:
377 case clang::Stmt::SwitchStmtClass:
378 case clang::Stmt::WhileStmtClass:
379 case clang::Stmt::DoStmtClass:
380 case clang::Stmt::ForStmtClass:
381 case clang::Stmt::GotoStmtClass:
382 case clang::Stmt::IndirectGotoStmtClass:
383 case clang::Stmt::ContinueStmtClass:
384 case clang::Stmt::BreakStmtClass:
385 case clang::Stmt::ReturnStmtClass:
386 case clang::Stmt::DeclStmtClass:
387 case clang::Stmt::CaseStmtClass:
388 case clang::Stmt::DefaultStmtClass:
389 case clang::Stmt::CapturedStmtClass:
390 case clang::Stmt::GCCAsmStmtClass:
391 case clang::Stmt::MSAsmStmtClass:
392 case clang::Stmt::ObjCAtTryStmtClass:
393 case clang::Stmt::ObjCAtCatchStmtClass:
394 case clang::Stmt::ObjCAtFinallyStmtClass:
395 case clang::Stmt::ObjCAtThrowStmtClass:
396 case clang::Stmt::ObjCAtSynchronizedStmtClass:
397 case clang::Stmt::ObjCForCollectionStmtClass:
398 case clang::Stmt::ObjCAutoreleasePoolStmtClass:
399 case clang::Stmt::CXXCatchStmtClass:
400 case clang::Stmt::CXXTryStmtClass:
401 case clang::Stmt::CXXForRangeStmtClass:
402 case clang::Stmt::CoroutineBodyStmtClass:
403 case clang::Stmt::CoreturnStmtClass:
404 case clang::Stmt::PredefinedExprClass:
405 case clang::Stmt::DeclRefExprClass:
406 case clang::Stmt::IntegerLiteralClass:
407 case clang::Stmt::FixedPointLiteralClass:
408 case clang::Stmt::FloatingLiteralClass:
409 case clang::Stmt::ImaginaryLiteralClass:
410 case clang::Stmt::StringLiteralClass:
411 case clang::Stmt::CharacterLiteralClass:
412 case clang::Stmt::ParenExprClass:
413 case clang::Stmt::UnaryOperatorClass:
414 case clang::Stmt::OffsetOfExprClass:
415 case clang::Stmt::UnaryExprOrTypeTraitExprClass:
416 case clang::Stmt::ArraySubscriptExprClass:
417 case clang::Stmt::OMPArraySectionExprClass:
418 case clang::Stmt::CallExprClass:
419 case clang::Stmt::MemberExprClass:
420 case clang::Stmt::BinaryOperatorClass:
421 case clang::Stmt::CompoundAssignOperatorClass:
422 case clang::Stmt::ConditionalOperatorClass:
423 case clang::Stmt::BinaryConditionalOperatorClass:
424 case clang::Stmt::ImplicitCastExprClass:
425 case clang::Stmt::CStyleCastExprClass:
426 case clang::Stmt::CompoundLiteralExprClass:
427 case clang::Stmt::ExtVectorElementExprClass:
428 case clang::Stmt::InitListExprClass:
429 case clang::Stmt::DesignatedInitExprClass:
430 case clang::Stmt::DesignatedInitUpdateExprClass:
431 case clang::Stmt::ImplicitValueInitExprClass:
432 case clang::Stmt::NoInitExprClass:
433 case clang::Stmt::ArrayInitLoopExprClass:
434 case clang::Stmt::ArrayInitIndexExprClass:
435 case clang::Stmt::ParenListExprClass:
436 case clang::Stmt::VAArgExprClass:
437 case clang::Stmt::GenericSelectionExprClass:
438 case clang::Stmt::PseudoObjectExprClass:
439 case clang::Stmt::ConstantExprClass:
440 case clang::Stmt::AtomicExprClass:
441 case clang::Stmt::AddrLabelExprClass:
442 case clang::Stmt::StmtExprClass:
443 case clang::Stmt::ChooseExprClass:
444 case clang::Stmt::GNUNullExprClass:
445 case clang::Stmt::CXXOperatorCallExprClass:
446 case clang::Stmt::CXXMemberCallExprClass:
447 case clang::Stmt::CXXStaticCastExprClass:
448 case clang::Stmt::CXXDynamicCastExprClass:
449 case clang::Stmt::CXXReinterpretCastExprClass:
450 case clang::Stmt::CXXConstCastExprClass:
451 case clang::Stmt::CXXFunctionalCastExprClass:
452 case clang::Stmt::CXXTypeidExprClass:
453 case clang::Stmt::UserDefinedLiteralClass:
454 case clang::Stmt::CXXBoolLiteralExprClass:
455 case clang::Stmt::CXXNullPtrLiteralExprClass:
456 case clang::Stmt::CXXThisExprClass:
457 case clang::Stmt::CXXThrowExprClass:
458 case clang::Stmt::CXXDefaultArgExprClass:
459 case clang::Stmt::CXXDefaultInitExprClass:
460 case clang::Stmt::CXXScalarValueInitExprClass:
461 case clang::Stmt::CXXStdInitializerListExprClass:
462 case clang::Stmt::CXXNewExprClass:
463 case clang::Stmt::CXXDeleteExprClass:
464 case clang::Stmt::CXXPseudoDestructorExprClass:
465 case clang::Stmt::TypeTraitExprClass:
466 case clang::Stmt::ArrayTypeTraitExprClass:
467 case clang::Stmt::ExpressionTraitExprClass:
468 case clang::Stmt::DependentScopeDeclRefExprClass:
469 case clang::Stmt::CXXConstructExprClass:
470 case clang::Stmt::CXXInheritedCtorInitExprClass:
471 case clang::Stmt::CXXBindTemporaryExprClass:
472 case clang::Stmt::ExprWithCleanupsClass:
473 case clang::Stmt::CXXTemporaryObjectExprClass:
474 case clang::Stmt::CXXUnresolvedConstructExprClass:
475 case clang::Stmt::CXXDependentScopeMemberExprClass:
476 case clang::Stmt::UnresolvedLookupExprClass:
477 case clang::Stmt::UnresolvedMemberExprClass:
478 case clang::Stmt::CXXNoexceptExprClass:
479 case clang::Stmt::PackExpansionExprClass:
480 case clang::Stmt::SizeOfPackExprClass:
481 case clang::Stmt::SubstNonTypeTemplateParmExprClass:
482 case clang::Stmt::SubstNonTypeTemplateParmPackExprClass:
483 case clang::Stmt::FunctionParmPackExprClass:
484 case clang::Stmt::MaterializeTemporaryExprClass:
485 case clang::Stmt::LambdaExprClass:
486 case clang::Stmt::CXXFoldExprClass:
487 case clang::Stmt::CoawaitExprClass:
488 case clang::Stmt::DependentCoawaitExprClass:
489 case clang::Stmt::CoyieldExprClass:
490 case clang::Stmt::ObjCStringLiteralClass:
491 case clang::Stmt::ObjCBoxedExprClass:
492 case clang::Stmt::ObjCArrayLiteralClass:
493 case clang::Stmt::ObjCDictionaryLiteralClass:
494 case clang::Stmt::ObjCEncodeExprClass:
495 case clang::Stmt::ObjCMessageExprClass:
496 case clang::Stmt::ObjCSelectorExprClass:
497 case clang::Stmt::ObjCProtocolExprClass:
498 case clang::Stmt::ObjCIvarRefExprClass:
499 case clang::Stmt::ObjCPropertyRefExprClass:
500 case clang::Stmt::ObjCIsaExprClass:
501 case clang::Stmt::ObjCIndirectCopyRestoreExprClass:
502 case clang::Stmt::ObjCBoolLiteralExprClass:
503 case clang::Stmt::ObjCSubscriptRefExprClass:
504 case clang::Stmt::ObjCAvailabilityCheckExprClass:
505 case clang::Stmt::ObjCBridgedCastExprClass:
506 case clang::Stmt::CUDAKernelCallExprClass:
507 case clang::Stmt::ShuffleVectorExprClass:
508 case clang::Stmt::ConvertVectorExprClass:
509 case clang::Stmt::BlockExprClass:
510 case clang::Stmt::OpaqueValueExprClass:
511 case clang::Stmt::TypoExprClass:
512 case clang::Stmt::MSPropertyRefExprClass:
513 case clang::Stmt::MSPropertySubscriptExprClass:
514 case clang::Stmt::CXXUuidofExprClass:
515 case clang::Stmt::SEHTryStmtClass:
516 case clang::Stmt::SEHExceptStmtClass:
517 case clang::Stmt::SEHFinallyStmtClass:
518 case clang::Stmt::SEHLeaveStmtClass:
519 case clang::Stmt::MSDependentExistsStmtClass:
520 case clang::Stmt::AsTypeExprClass:
521 case clang::Stmt::OMPParallelDirectiveClass:
522 case clang::Stmt::OMPSimdDirectiveClass:
523 case clang::Stmt::OMPForDirectiveClass:
524 case clang::Stmt::OMPForSimdDirectiveClass:
525 case clang::Stmt::OMPSectionsDirectiveClass:
526 case clang::Stmt::OMPSectionDirectiveClass:
527 case clang::Stmt::OMPSingleDirectiveClass:
528 case clang::Stmt::OMPMasterDirectiveClass:
529 case clang::Stmt::OMPCriticalDirectiveClass:
530 case clang::Stmt::OMPParallelForDirectiveClass:
531 case clang::Stmt::OMPParallelForSimdDirectiveClass:
532 case clang::Stmt::OMPParallelSectionsDirectiveClass:
533 case clang::Stmt::OMPTaskDirectiveClass:
534 case clang::Stmt::OMPTaskyieldDirectiveClass:
535 case clang::Stmt::OMPBarrierDirectiveClass:
536 case clang::Stmt::OMPTaskwaitDirectiveClass:
537 case clang::Stmt::OMPTaskgroupDirectiveClass:
538 case clang::Stmt::OMPFlushDirectiveClass:
539 case clang::Stmt::OMPOrderedDirectiveClass:
540 case clang::Stmt::OMPAtomicDirectiveClass:
541 case clang::Stmt::OMPTargetDirectiveClass:
542 case clang::Stmt::OMPTargetDataDirectiveClass:
543 case clang::Stmt::OMPTargetEnterDataDirectiveClass:
544 case clang::Stmt::OMPTargetExitDataDirectiveClass:
545 case clang::Stmt::OMPTargetParallelDirectiveClass:
546 case clang::Stmt::OMPTargetParallelForDirectiveClass:
547 case clang::Stmt::OMPTargetUpdateDirectiveClass:
548 case clang::Stmt::OMPTeamsDirectiveClass:
549 case clang::Stmt::OMPCancellationPointDirectiveClass:
550 case clang::Stmt::OMPCancelDirectiveClass:
551 case clang::Stmt::OMPTaskLoopDirectiveClass:
552 case clang::Stmt::OMPTaskLoopSimdDirectiveClass:
553 case clang::Stmt::OMPDistributeDirectiveClass:
554 case clang::Stmt::OMPDistributeParallelForDirectiveClass:
555 case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass:
556 case clang::Stmt::OMPDistributeSimdDirectiveClass:
557 case clang::Stmt::OMPTargetParallelForSimdDirectiveClass:
558 case clang::Stmt::OMPTargetSimdDirectiveClass:
559 case clang::Stmt::OMPTeamsDistributeDirectiveClass:
560 case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass:
561 case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
562 case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass:
563 case clang::Stmt::OMPTargetTeamsDirectiveClass:
564 case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass:
565 case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
566 case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
567 case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
568 break;
569 }
570}
571
572static_assert((clang::Stmt::StmtClass)ZigClangStmt_NoStmtClass == clang::Stmt::NoStmtClass, "");
573static_assert((clang::Stmt::StmtClass)ZigClangStmt_NullStmtClass == clang::Stmt::NullStmtClass, "");
574static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundStmtClass == clang::Stmt::CompoundStmtClass, "");
575static_assert((clang::Stmt::StmtClass)ZigClangStmt_LabelStmtClass == clang::Stmt::LabelStmtClass, "");
576static_assert((clang::Stmt::StmtClass)ZigClangStmt_AttributedStmtClass == clang::Stmt::AttributedStmtClass, "");
577static_assert((clang::Stmt::StmtClass)ZigClangStmt_IfStmtClass == clang::Stmt::IfStmtClass, "");
578static_assert((clang::Stmt::StmtClass)ZigClangStmt_SwitchStmtClass == clang::Stmt::SwitchStmtClass, "");
579static_assert((clang::Stmt::StmtClass)ZigClangStmt_WhileStmtClass == clang::Stmt::WhileStmtClass, "");
580static_assert((clang::Stmt::StmtClass)ZigClangStmt_DoStmtClass == clang::Stmt::DoStmtClass, "");
581static_assert((clang::Stmt::StmtClass)ZigClangStmt_ForStmtClass == clang::Stmt::ForStmtClass, "");
582static_assert((clang::Stmt::StmtClass)ZigClangStmt_GotoStmtClass == clang::Stmt::GotoStmtClass, "");
583static_assert((clang::Stmt::StmtClass)ZigClangStmt_IndirectGotoStmtClass == clang::Stmt::IndirectGotoStmtClass, "");
584static_assert((clang::Stmt::StmtClass)ZigClangStmt_ContinueStmtClass == clang::Stmt::ContinueStmtClass, "");
585static_assert((clang::Stmt::StmtClass)ZigClangStmt_BreakStmtClass == clang::Stmt::BreakStmtClass, "");
586static_assert((clang::Stmt::StmtClass)ZigClangStmt_ReturnStmtClass == clang::Stmt::ReturnStmtClass, "");
587static_assert((clang::Stmt::StmtClass)ZigClangStmt_DeclStmtClass == clang::Stmt::DeclStmtClass, "");
588static_assert((clang::Stmt::StmtClass)ZigClangStmt_CaseStmtClass == clang::Stmt::CaseStmtClass, "");
589static_assert((clang::Stmt::StmtClass)ZigClangStmt_DefaultStmtClass == clang::Stmt::DefaultStmtClass, "");
590static_assert((clang::Stmt::StmtClass)ZigClangStmt_CapturedStmtClass == clang::Stmt::CapturedStmtClass, "");
591static_assert((clang::Stmt::StmtClass)ZigClangStmt_GCCAsmStmtClass == clang::Stmt::GCCAsmStmtClass, "");
592static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSAsmStmtClass == clang::Stmt::MSAsmStmtClass, "");
593static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtTryStmtClass == clang::Stmt::ObjCAtTryStmtClass, "");
594static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtCatchStmtClass == clang::Stmt::ObjCAtCatchStmtClass, "");
595static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtFinallyStmtClass == clang::Stmt::ObjCAtFinallyStmtClass, "");
596static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtThrowStmtClass == clang::Stmt::ObjCAtThrowStmtClass, "");
597static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAtSynchronizedStmtClass == clang::Stmt::ObjCAtSynchronizedStmtClass, "");
598static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCForCollectionStmtClass == clang::Stmt::ObjCForCollectionStmtClass, "");
599static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAutoreleasePoolStmtClass == clang::Stmt::ObjCAutoreleasePoolStmtClass, "");
600static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXCatchStmtClass == clang::Stmt::CXXCatchStmtClass, "");
601static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTryStmtClass == clang::Stmt::CXXTryStmtClass, "");
602static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXForRangeStmtClass == clang::Stmt::CXXForRangeStmtClass, "");
603static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoroutineBodyStmtClass == clang::Stmt::CoroutineBodyStmtClass, "");
604static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoreturnStmtClass == clang::Stmt::CoreturnStmtClass, "");
605static_assert((clang::Stmt::StmtClass)ZigClangStmt_PredefinedExprClass == clang::Stmt::PredefinedExprClass, "");
606static_assert((clang::Stmt::StmtClass)ZigClangStmt_DeclRefExprClass == clang::Stmt::DeclRefExprClass, "");
607static_assert((clang::Stmt::StmtClass)ZigClangStmt_IntegerLiteralClass == clang::Stmt::IntegerLiteralClass, "");
608static_assert((clang::Stmt::StmtClass)ZigClangStmt_FixedPointLiteralClass == clang::Stmt::FixedPointLiteralClass, "");
609static_assert((clang::Stmt::StmtClass)ZigClangStmt_FloatingLiteralClass == clang::Stmt::FloatingLiteralClass, "");
610static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImaginaryLiteralClass == clang::Stmt::ImaginaryLiteralClass, "");
611static_assert((clang::Stmt::StmtClass)ZigClangStmt_StringLiteralClass == clang::Stmt::StringLiteralClass, "");
612static_assert((clang::Stmt::StmtClass)ZigClangStmt_CharacterLiteralClass == clang::Stmt::CharacterLiteralClass, "");
613static_assert((clang::Stmt::StmtClass)ZigClangStmt_ParenExprClass == clang::Stmt::ParenExprClass, "");
614static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnaryOperatorClass == clang::Stmt::UnaryOperatorClass, "");
615static_assert((clang::Stmt::StmtClass)ZigClangStmt_OffsetOfExprClass == clang::Stmt::OffsetOfExprClass, "");
616static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnaryExprOrTypeTraitExprClass == clang::Stmt::UnaryExprOrTypeTraitExprClass, "");
617static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArraySubscriptExprClass == clang::Stmt::ArraySubscriptExprClass, "");
618static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPArraySectionExprClass == clang::Stmt::OMPArraySectionExprClass, "");
619static_assert((clang::Stmt::StmtClass)ZigClangStmt_CallExprClass == clang::Stmt::CallExprClass, "");
620static_assert((clang::Stmt::StmtClass)ZigClangStmt_MemberExprClass == clang::Stmt::MemberExprClass, "");
621static_assert((clang::Stmt::StmtClass)ZigClangStmt_BinaryOperatorClass == clang::Stmt::BinaryOperatorClass, "");
622static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundAssignOperatorClass == clang::Stmt::CompoundAssignOperatorClass, "");
623static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConditionalOperatorClass == clang::Stmt::ConditionalOperatorClass, "");
624static_assert((clang::Stmt::StmtClass)ZigClangStmt_BinaryConditionalOperatorClass == clang::Stmt::BinaryConditionalOperatorClass, "");
625static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImplicitCastExprClass == clang::Stmt::ImplicitCastExprClass, "");
626static_assert((clang::Stmt::StmtClass)ZigClangStmt_CStyleCastExprClass == clang::Stmt::CStyleCastExprClass, "");
627static_assert((clang::Stmt::StmtClass)ZigClangStmt_CompoundLiteralExprClass == clang::Stmt::CompoundLiteralExprClass, "");
628static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExtVectorElementExprClass == clang::Stmt::ExtVectorElementExprClass, "");
629static_assert((clang::Stmt::StmtClass)ZigClangStmt_InitListExprClass == clang::Stmt::InitListExprClass, "");
630static_assert((clang::Stmt::StmtClass)ZigClangStmt_DesignatedInitExprClass == clang::Stmt::DesignatedInitExprClass, "");
631static_assert((clang::Stmt::StmtClass)ZigClangStmt_DesignatedInitUpdateExprClass == clang::Stmt::DesignatedInitUpdateExprClass, "");
632static_assert((clang::Stmt::StmtClass)ZigClangStmt_ImplicitValueInitExprClass == clang::Stmt::ImplicitValueInitExprClass, "");
633static_assert((clang::Stmt::StmtClass)ZigClangStmt_NoInitExprClass == clang::Stmt::NoInitExprClass, "");
634static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayInitLoopExprClass == clang::Stmt::ArrayInitLoopExprClass, "");
635static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayInitIndexExprClass == clang::Stmt::ArrayInitIndexExprClass, "");
636static_assert((clang::Stmt::StmtClass)ZigClangStmt_ParenListExprClass == clang::Stmt::ParenListExprClass, "");
637static_assert((clang::Stmt::StmtClass)ZigClangStmt_VAArgExprClass == clang::Stmt::VAArgExprClass, "");
638static_assert((clang::Stmt::StmtClass)ZigClangStmt_GenericSelectionExprClass == clang::Stmt::GenericSelectionExprClass, "");
639static_assert((clang::Stmt::StmtClass)ZigClangStmt_PseudoObjectExprClass == clang::Stmt::PseudoObjectExprClass, "");
640static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConstantExprClass == clang::Stmt::ConstantExprClass, "");
641static_assert((clang::Stmt::StmtClass)ZigClangStmt_AtomicExprClass == clang::Stmt::AtomicExprClass, "");
642static_assert((clang::Stmt::StmtClass)ZigClangStmt_AddrLabelExprClass == clang::Stmt::AddrLabelExprClass, "");
643static_assert((clang::Stmt::StmtClass)ZigClangStmt_StmtExprClass == clang::Stmt::StmtExprClass, "");
644static_assert((clang::Stmt::StmtClass)ZigClangStmt_ChooseExprClass == clang::Stmt::ChooseExprClass, "");
645static_assert((clang::Stmt::StmtClass)ZigClangStmt_GNUNullExprClass == clang::Stmt::GNUNullExprClass, "");
646static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXOperatorCallExprClass == clang::Stmt::CXXOperatorCallExprClass, "");
647static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXMemberCallExprClass == clang::Stmt::CXXMemberCallExprClass, "");
648static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXStaticCastExprClass == clang::Stmt::CXXStaticCastExprClass, "");
649static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDynamicCastExprClass == clang::Stmt::CXXDynamicCastExprClass, "");
650static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXReinterpretCastExprClass == clang::Stmt::CXXReinterpretCastExprClass, "");
651static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXConstCastExprClass == clang::Stmt::CXXConstCastExprClass, "");
652static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXFunctionalCastExprClass == clang::Stmt::CXXFunctionalCastExprClass, "");
653static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTypeidExprClass == clang::Stmt::CXXTypeidExprClass, "");
654static_assert((clang::Stmt::StmtClass)ZigClangStmt_UserDefinedLiteralClass == clang::Stmt::UserDefinedLiteralClass, "");
655static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXBoolLiteralExprClass == clang::Stmt::CXXBoolLiteralExprClass, "");
656static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNullPtrLiteralExprClass == clang::Stmt::CXXNullPtrLiteralExprClass, "");
657static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXThisExprClass == clang::Stmt::CXXThisExprClass, "");
658static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXThrowExprClass == clang::Stmt::CXXThrowExprClass, "");
659static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDefaultArgExprClass == clang::Stmt::CXXDefaultArgExprClass, "");
660static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDefaultInitExprClass == clang::Stmt::CXXDefaultInitExprClass, "");
661static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXScalarValueInitExprClass == clang::Stmt::CXXScalarValueInitExprClass, "");
662static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXStdInitializerListExprClass == clang::Stmt::CXXStdInitializerListExprClass, "");
663static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNewExprClass == clang::Stmt::CXXNewExprClass, "");
664static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDeleteExprClass == clang::Stmt::CXXDeleteExprClass, "");
665static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXPseudoDestructorExprClass == clang::Stmt::CXXPseudoDestructorExprClass, "");
666static_assert((clang::Stmt::StmtClass)ZigClangStmt_TypeTraitExprClass == clang::Stmt::TypeTraitExprClass, "");
667static_assert((clang::Stmt::StmtClass)ZigClangStmt_ArrayTypeTraitExprClass == clang::Stmt::ArrayTypeTraitExprClass, "");
668static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExpressionTraitExprClass == clang::Stmt::ExpressionTraitExprClass, "");
669static_assert((clang::Stmt::StmtClass)ZigClangStmt_DependentScopeDeclRefExprClass == clang::Stmt::DependentScopeDeclRefExprClass, "");
670static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXConstructExprClass == clang::Stmt::CXXConstructExprClass, "");
671static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXInheritedCtorInitExprClass == clang::Stmt::CXXInheritedCtorInitExprClass, "");
672static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXBindTemporaryExprClass == clang::Stmt::CXXBindTemporaryExprClass, "");
673static_assert((clang::Stmt::StmtClass)ZigClangStmt_ExprWithCleanupsClass == clang::Stmt::ExprWithCleanupsClass, "");
674static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXTemporaryObjectExprClass == clang::Stmt::CXXTemporaryObjectExprClass, "");
675static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXUnresolvedConstructExprClass == clang::Stmt::CXXUnresolvedConstructExprClass, "");
676static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXDependentScopeMemberExprClass == clang::Stmt::CXXDependentScopeMemberExprClass, "");
677static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnresolvedLookupExprClass == clang::Stmt::UnresolvedLookupExprClass, "");
678static_assert((clang::Stmt::StmtClass)ZigClangStmt_UnresolvedMemberExprClass == clang::Stmt::UnresolvedMemberExprClass, "");
679static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXNoexceptExprClass == clang::Stmt::CXXNoexceptExprClass, "");
680static_assert((clang::Stmt::StmtClass)ZigClangStmt_PackExpansionExprClass == clang::Stmt::PackExpansionExprClass, "");
681static_assert((clang::Stmt::StmtClass)ZigClangStmt_SizeOfPackExprClass == clang::Stmt::SizeOfPackExprClass, "");
682static_assert((clang::Stmt::StmtClass)ZigClangStmt_SubstNonTypeTemplateParmExprClass == clang::Stmt::SubstNonTypeTemplateParmExprClass, "");
683static_assert((clang::Stmt::StmtClass)ZigClangStmt_SubstNonTypeTemplateParmPackExprClass == clang::Stmt::SubstNonTypeTemplateParmPackExprClass, "");
684static_assert((clang::Stmt::StmtClass)ZigClangStmt_FunctionParmPackExprClass == clang::Stmt::FunctionParmPackExprClass, "");
685static_assert((clang::Stmt::StmtClass)ZigClangStmt_MaterializeTemporaryExprClass == clang::Stmt::MaterializeTemporaryExprClass, "");
686static_assert((clang::Stmt::StmtClass)ZigClangStmt_LambdaExprClass == clang::Stmt::LambdaExprClass, "");
687static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXFoldExprClass == clang::Stmt::CXXFoldExprClass, "");
688static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoawaitExprClass == clang::Stmt::CoawaitExprClass, "");
689static_assert((clang::Stmt::StmtClass)ZigClangStmt_DependentCoawaitExprClass == clang::Stmt::DependentCoawaitExprClass, "");
690static_assert((clang::Stmt::StmtClass)ZigClangStmt_CoyieldExprClass == clang::Stmt::CoyieldExprClass, "");
691static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCStringLiteralClass == clang::Stmt::ObjCStringLiteralClass, "");
692static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBoxedExprClass == clang::Stmt::ObjCBoxedExprClass, "");
693static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCArrayLiteralClass == clang::Stmt::ObjCArrayLiteralClass, "");
694static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCDictionaryLiteralClass == clang::Stmt::ObjCDictionaryLiteralClass, "");
695static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCEncodeExprClass == clang::Stmt::ObjCEncodeExprClass, "");
696static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCMessageExprClass == clang::Stmt::ObjCMessageExprClass, "");
697static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCSelectorExprClass == clang::Stmt::ObjCSelectorExprClass, "");
698static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCProtocolExprClass == clang::Stmt::ObjCProtocolExprClass, "");
699static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIvarRefExprClass == clang::Stmt::ObjCIvarRefExprClass, "");
700static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCPropertyRefExprClass == clang::Stmt::ObjCPropertyRefExprClass, "");
701static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIsaExprClass == clang::Stmt::ObjCIsaExprClass, "");
702static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCIndirectCopyRestoreExprClass == clang::Stmt::ObjCIndirectCopyRestoreExprClass, "");
703static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBoolLiteralExprClass == clang::Stmt::ObjCBoolLiteralExprClass, "");
704static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCSubscriptRefExprClass == clang::Stmt::ObjCSubscriptRefExprClass, "");
705static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCAvailabilityCheckExprClass == clang::Stmt::ObjCAvailabilityCheckExprClass, "");
706static_assert((clang::Stmt::StmtClass)ZigClangStmt_ObjCBridgedCastExprClass == clang::Stmt::ObjCBridgedCastExprClass, "");
707static_assert((clang::Stmt::StmtClass)ZigClangStmt_CUDAKernelCallExprClass == clang::Stmt::CUDAKernelCallExprClass, "");
708static_assert((clang::Stmt::StmtClass)ZigClangStmt_ShuffleVectorExprClass == clang::Stmt::ShuffleVectorExprClass, "");
709static_assert((clang::Stmt::StmtClass)ZigClangStmt_ConvertVectorExprClass == clang::Stmt::ConvertVectorExprClass, "");
710static_assert((clang::Stmt::StmtClass)ZigClangStmt_BlockExprClass == clang::Stmt::BlockExprClass, "");
711static_assert((clang::Stmt::StmtClass)ZigClangStmt_OpaqueValueExprClass == clang::Stmt::OpaqueValueExprClass, "");
712static_assert((clang::Stmt::StmtClass)ZigClangStmt_TypoExprClass == clang::Stmt::TypoExprClass, "");
713static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSPropertyRefExprClass == clang::Stmt::MSPropertyRefExprClass, "");
714static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSPropertySubscriptExprClass == clang::Stmt::MSPropertySubscriptExprClass, "");
715static_assert((clang::Stmt::StmtClass)ZigClangStmt_CXXUuidofExprClass == clang::Stmt::CXXUuidofExprClass, "");
716static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHTryStmtClass == clang::Stmt::SEHTryStmtClass, "");
717static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHExceptStmtClass == clang::Stmt::SEHExceptStmtClass, "");
718static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHFinallyStmtClass == clang::Stmt::SEHFinallyStmtClass, "");
719static_assert((clang::Stmt::StmtClass)ZigClangStmt_SEHLeaveStmtClass == clang::Stmt::SEHLeaveStmtClass, "");
720static_assert((clang::Stmt::StmtClass)ZigClangStmt_MSDependentExistsStmtClass == clang::Stmt::MSDependentExistsStmtClass, "");
721static_assert((clang::Stmt::StmtClass)ZigClangStmt_AsTypeExprClass == clang::Stmt::AsTypeExprClass, "");
722static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelDirectiveClass == clang::Stmt::OMPParallelDirectiveClass, "");
723static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSimdDirectiveClass == clang::Stmt::OMPSimdDirectiveClass, "");
724static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForDirectiveClass == clang::Stmt::OMPForDirectiveClass, "");
725static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPForSimdDirectiveClass == clang::Stmt::OMPForSimdDirectiveClass, "");
726static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSectionsDirectiveClass == clang::Stmt::OMPSectionsDirectiveClass, "");
727static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSectionDirectiveClass == clang::Stmt::OMPSectionDirectiveClass, "");
728static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPSingleDirectiveClass == clang::Stmt::OMPSingleDirectiveClass, "");
729static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPMasterDirectiveClass == clang::Stmt::OMPMasterDirectiveClass, "");
730static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCriticalDirectiveClass == clang::Stmt::OMPCriticalDirectiveClass, "");
731static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForDirectiveClass == clang::Stmt::OMPParallelForDirectiveClass, "");
732static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelForSimdDirectiveClass == clang::Stmt::OMPParallelForSimdDirectiveClass, "");
733static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPParallelSectionsDirectiveClass == clang::Stmt::OMPParallelSectionsDirectiveClass, "");
734static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskDirectiveClass == clang::Stmt::OMPTaskDirectiveClass, "");
735static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskyieldDirectiveClass == clang::Stmt::OMPTaskyieldDirectiveClass, "");
736static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPBarrierDirectiveClass == clang::Stmt::OMPBarrierDirectiveClass, "");
737static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskwaitDirectiveClass == clang::Stmt::OMPTaskwaitDirectiveClass, "");
738static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskgroupDirectiveClass == clang::Stmt::OMPTaskgroupDirectiveClass, "");
739static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPFlushDirectiveClass == clang::Stmt::OMPFlushDirectiveClass, "");
740static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPOrderedDirectiveClass == clang::Stmt::OMPOrderedDirectiveClass, "");
741static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPAtomicDirectiveClass == clang::Stmt::OMPAtomicDirectiveClass, "");
742static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetDirectiveClass == clang::Stmt::OMPTargetDirectiveClass, "");
743static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetDataDirectiveClass == clang::Stmt::OMPTargetDataDirectiveClass, "");
744static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetEnterDataDirectiveClass == clang::Stmt::OMPTargetEnterDataDirectiveClass, "");
745static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetExitDataDirectiveClass == clang::Stmt::OMPTargetExitDataDirectiveClass, "");
746static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelDirectiveClass == clang::Stmt::OMPTargetParallelDirectiveClass, "");
747static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelForDirectiveClass == clang::Stmt::OMPTargetParallelForDirectiveClass, "");
748static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetUpdateDirectiveClass == clang::Stmt::OMPTargetUpdateDirectiveClass, "");
749static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDirectiveClass == clang::Stmt::OMPTeamsDirectiveClass, "");
750static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCancellationPointDirectiveClass == clang::Stmt::OMPCancellationPointDirectiveClass, "");
751static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPCancelDirectiveClass == clang::Stmt::OMPCancelDirectiveClass, "");
752static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopDirectiveClass == clang::Stmt::OMPTaskLoopDirectiveClass, "");
753static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTaskLoopSimdDirectiveClass == clang::Stmt::OMPTaskLoopSimdDirectiveClass, "");
754static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeDirectiveClass == clang::Stmt::OMPDistributeDirectiveClass, "");
755static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeParallelForDirectiveClass == clang::Stmt::OMPDistributeParallelForDirectiveClass, "");
756static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPDistributeParallelForSimdDirectiveClass, "");
757static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPDistributeSimdDirectiveClass == clang::Stmt::OMPDistributeSimdDirectiveClass, "");
758static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetParallelForSimdDirectiveClass == clang::Stmt::OMPTargetParallelForSimdDirectiveClass, "");
759static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetSimdDirectiveClass == clang::Stmt::OMPTargetSimdDirectiveClass, "");
760static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeDirectiveClass == clang::Stmt::OMPTeamsDistributeDirectiveClass, "");
761static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeSimdDirectiveClass, "");
762static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass, "");
763static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass, "");
764static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDirectiveClass == clang::Stmt::OMPTargetTeamsDirectiveClass, "");
765static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeDirectiveClass, "");
766static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass, "");
767static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass, "");
768static_assert((clang::Stmt::StmtClass)ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass == clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass, "");
769
770void ZigClang_detect_enum_APValueKind(clang::APValue::ValueKind x) {
771 switch (x) {
772 case clang::APValue::Uninitialized:
773 case clang::APValue::Int:
774 case clang::APValue::Float:
775 case clang::APValue::ComplexInt:
776 case clang::APValue::ComplexFloat:
777 case clang::APValue::LValue:
778 case clang::APValue::Vector:
779 case clang::APValue::Array:
780 case clang::APValue::Struct:
781 case clang::APValue::Union:
782 case clang::APValue::MemberPointer:
783 case clang::APValue::AddrLabelDiff:
784 break;
785 }
786}
787
788static_assert((clang::APValue::ValueKind)ZigClangAPValueUninitialized == clang::APValue::Uninitialized, "");
789static_assert((clang::APValue::ValueKind)ZigClangAPValueInt == clang::APValue::Int, "");
790static_assert((clang::APValue::ValueKind)ZigClangAPValueFloat == clang::APValue::Float, "");
791static_assert((clang::APValue::ValueKind)ZigClangAPValueComplexInt == clang::APValue::ComplexInt, "");
792static_assert((clang::APValue::ValueKind)ZigClangAPValueComplexFloat == clang::APValue::ComplexFloat, "");
793static_assert((clang::APValue::ValueKind)ZigClangAPValueLValue == clang::APValue::LValue, "");
794static_assert((clang::APValue::ValueKind)ZigClangAPValueVector == clang::APValue::Vector, "");
795static_assert((clang::APValue::ValueKind)ZigClangAPValueArray == clang::APValue::Array, "");
796static_assert((clang::APValue::ValueKind)ZigClangAPValueStruct == clang::APValue::Struct, "");
797static_assert((clang::APValue::ValueKind)ZigClangAPValueUnion == clang::APValue::Union, "");
798static_assert((clang::APValue::ValueKind)ZigClangAPValueMemberPointer == clang::APValue::MemberPointer, "");
799static_assert((clang::APValue::ValueKind)ZigClangAPValueAddrLabelDiff == clang::APValue::AddrLabelDiff, "");
800
801
802void ZigClang_detect_enum_DeclKind(clang::Decl::Kind x) {
803 switch (x) {
804 case clang::Decl::AccessSpec:
805 case clang::Decl::Block:
806 case clang::Decl::Captured:
807 case clang::Decl::ClassScopeFunctionSpecialization:
808 case clang::Decl::Empty:
809 case clang::Decl::Export:
810 case clang::Decl::ExternCContext:
811 case clang::Decl::FileScopeAsm:
812 case clang::Decl::Friend:
813 case clang::Decl::FriendTemplate:
814 case clang::Decl::Import:
815 case clang::Decl::LinkageSpec:
816 case clang::Decl::Label:
817 case clang::Decl::Namespace:
818 case clang::Decl::NamespaceAlias:
819 case clang::Decl::ObjCCompatibleAlias:
820 case clang::Decl::ObjCCategory:
821 case clang::Decl::ObjCCategoryImpl:
822 case clang::Decl::ObjCImplementation:
823 case clang::Decl::ObjCInterface:
824 case clang::Decl::ObjCProtocol:
825 case clang::Decl::ObjCMethod:
826 case clang::Decl::ObjCProperty:
827 case clang::Decl::BuiltinTemplate:
828 case clang::Decl::ClassTemplate:
829 case clang::Decl::FunctionTemplate:
830 case clang::Decl::TypeAliasTemplate:
831 case clang::Decl::VarTemplate:
832 case clang::Decl::TemplateTemplateParm:
833 case clang::Decl::Enum:
834 case clang::Decl::Record:
835 case clang::Decl::CXXRecord:
836 case clang::Decl::ClassTemplateSpecialization:
837 case clang::Decl::ClassTemplatePartialSpecialization:
838 case clang::Decl::TemplateTypeParm:
839 case clang::Decl::ObjCTypeParam:
840 case clang::Decl::TypeAlias:
841 case clang::Decl::Typedef:
842 case clang::Decl::UnresolvedUsingTypename:
843 case clang::Decl::Using:
844 case clang::Decl::UsingDirective:
845 case clang::Decl::UsingPack:
846 case clang::Decl::UsingShadow:
847 case clang::Decl::ConstructorUsingShadow:
848 case clang::Decl::Binding:
849 case clang::Decl::Field:
850 case clang::Decl::ObjCAtDefsField:
851 case clang::Decl::ObjCIvar:
852 case clang::Decl::Function:
853 case clang::Decl::CXXDeductionGuide:
854 case clang::Decl::CXXMethod:
855 case clang::Decl::CXXConstructor:
856 case clang::Decl::CXXConversion:
857 case clang::Decl::CXXDestructor:
858 case clang::Decl::MSProperty:
859 case clang::Decl::NonTypeTemplateParm:
860 case clang::Decl::Var:
861 case clang::Decl::Decomposition:
862 case clang::Decl::ImplicitParam:
863 case clang::Decl::OMPCapturedExpr:
864 case clang::Decl::ParmVar:
865 case clang::Decl::VarTemplateSpecialization:
866 case clang::Decl::VarTemplatePartialSpecialization:
867 case clang::Decl::EnumConstant:
868 case clang::Decl::IndirectField:
869 case clang::Decl::OMPDeclareReduction:
870 case clang::Decl::UnresolvedUsingValue:
871 case clang::Decl::OMPRequires:
872 case clang::Decl::OMPThreadPrivate:
873 case clang::Decl::ObjCPropertyImpl:
874 case clang::Decl::PragmaComment:
875 case clang::Decl::PragmaDetectMismatch:
876 case clang::Decl::StaticAssert:
877 case clang::Decl::TranslationUnit:
878 break;
879 }
880}
881
882static_assert((clang::Decl::Kind)ZigClangDeclAccessSpec == clang::Decl::AccessSpec, "");
883static_assert((clang::Decl::Kind)ZigClangDeclBlock == clang::Decl::Block, "");
884static_assert((clang::Decl::Kind)ZigClangDeclCaptured == clang::Decl::Captured, "");
885static_assert((clang::Decl::Kind)ZigClangDeclClassScopeFunctionSpecialization == clang::Decl::ClassScopeFunctionSpecialization, "");
886static_assert((clang::Decl::Kind)ZigClangDeclEmpty == clang::Decl::Empty, "");
887static_assert((clang::Decl::Kind)ZigClangDeclExport == clang::Decl::Export, "");
888static_assert((clang::Decl::Kind)ZigClangDeclExternCContext == clang::Decl::ExternCContext, "");
889static_assert((clang::Decl::Kind)ZigClangDeclFileScopeAsm == clang::Decl::FileScopeAsm, "");
890static_assert((clang::Decl::Kind)ZigClangDeclFriend == clang::Decl::Friend, "");
891static_assert((clang::Decl::Kind)ZigClangDeclFriendTemplate == clang::Decl::FriendTemplate, "");
892static_assert((clang::Decl::Kind)ZigClangDeclImport == clang::Decl::Import, "");
893static_assert((clang::Decl::Kind)ZigClangDeclLinkageSpec == clang::Decl::LinkageSpec, "");
894static_assert((clang::Decl::Kind)ZigClangDeclLabel == clang::Decl::Label, "");
895static_assert((clang::Decl::Kind)ZigClangDeclNamespace == clang::Decl::Namespace, "");
896static_assert((clang::Decl::Kind)ZigClangDeclNamespaceAlias == clang::Decl::NamespaceAlias, "");
897static_assert((clang::Decl::Kind)ZigClangDeclObjCCompatibleAlias == clang::Decl::ObjCCompatibleAlias, "");
898static_assert((clang::Decl::Kind)ZigClangDeclObjCCategory == clang::Decl::ObjCCategory, "");
899static_assert((clang::Decl::Kind)ZigClangDeclObjCCategoryImpl == clang::Decl::ObjCCategoryImpl, "");
900static_assert((clang::Decl::Kind)ZigClangDeclObjCImplementation == clang::Decl::ObjCImplementation, "");
901static_assert((clang::Decl::Kind)ZigClangDeclObjCInterface == clang::Decl::ObjCInterface, "");
902static_assert((clang::Decl::Kind)ZigClangDeclObjCProtocol == clang::Decl::ObjCProtocol, "");
903static_assert((clang::Decl::Kind)ZigClangDeclObjCMethod == clang::Decl::ObjCMethod, "");
904static_assert((clang::Decl::Kind)ZigClangDeclObjCProperty == clang::Decl::ObjCProperty, "");
905static_assert((clang::Decl::Kind)ZigClangDeclBuiltinTemplate == clang::Decl::BuiltinTemplate, "");
906static_assert((clang::Decl::Kind)ZigClangDeclClassTemplate == clang::Decl::ClassTemplate, "");
907static_assert((clang::Decl::Kind)ZigClangDeclFunctionTemplate == clang::Decl::FunctionTemplate, "");
908static_assert((clang::Decl::Kind)ZigClangDeclTypeAliasTemplate == clang::Decl::TypeAliasTemplate, "");
909static_assert((clang::Decl::Kind)ZigClangDeclVarTemplate == clang::Decl::VarTemplate, "");
910static_assert((clang::Decl::Kind)ZigClangDeclTemplateTemplateParm == clang::Decl::TemplateTemplateParm, "");
911static_assert((clang::Decl::Kind)ZigClangDeclEnum == clang::Decl::Enum, "");
912static_assert((clang::Decl::Kind)ZigClangDeclRecord == clang::Decl::Record, "");
913static_assert((clang::Decl::Kind)ZigClangDeclCXXRecord == clang::Decl::CXXRecord, "");
914static_assert((clang::Decl::Kind)ZigClangDeclClassTemplateSpecialization == clang::Decl::ClassTemplateSpecialization, "");
915static_assert((clang::Decl::Kind)ZigClangDeclClassTemplatePartialSpecialization == clang::Decl::ClassTemplatePartialSpecialization, "");
916static_assert((clang::Decl::Kind)ZigClangDeclTemplateTypeParm == clang::Decl::TemplateTypeParm, "");
917static_assert((clang::Decl::Kind)ZigClangDeclObjCTypeParam == clang::Decl::ObjCTypeParam, "");
918static_assert((clang::Decl::Kind)ZigClangDeclTypeAlias == clang::Decl::TypeAlias, "");
919static_assert((clang::Decl::Kind)ZigClangDeclTypedef == clang::Decl::Typedef, "");
920static_assert((clang::Decl::Kind)ZigClangDeclUnresolvedUsingTypename == clang::Decl::UnresolvedUsingTypename, "");
921static_assert((clang::Decl::Kind)ZigClangDeclUsing == clang::Decl::Using, "");
922static_assert((clang::Decl::Kind)ZigClangDeclUsingDirective == clang::Decl::UsingDirective, "");
923static_assert((clang::Decl::Kind)ZigClangDeclUsingPack == clang::Decl::UsingPack, "");
924static_assert((clang::Decl::Kind)ZigClangDeclUsingShadow == clang::Decl::UsingShadow, "");
925static_assert((clang::Decl::Kind)ZigClangDeclConstructorUsingShadow == clang::Decl::ConstructorUsingShadow, "");
926static_assert((clang::Decl::Kind)ZigClangDeclBinding == clang::Decl::Binding, "");
927static_assert((clang::Decl::Kind)ZigClangDeclField == clang::Decl::Field, "");
928static_assert((clang::Decl::Kind)ZigClangDeclObjCAtDefsField == clang::Decl::ObjCAtDefsField, "");
929static_assert((clang::Decl::Kind)ZigClangDeclObjCIvar == clang::Decl::ObjCIvar, "");
930static_assert((clang::Decl::Kind)ZigClangDeclFunction == clang::Decl::Function, "");
931static_assert((clang::Decl::Kind)ZigClangDeclCXXDeductionGuide == clang::Decl::CXXDeductionGuide, "");
932static_assert((clang::Decl::Kind)ZigClangDeclCXXMethod == clang::Decl::CXXMethod, "");
933static_assert((clang::Decl::Kind)ZigClangDeclCXXConstructor == clang::Decl::CXXConstructor, "");
934static_assert((clang::Decl::Kind)ZigClangDeclCXXConversion == clang::Decl::CXXConversion, "");
935static_assert((clang::Decl::Kind)ZigClangDeclCXXDestructor == clang::Decl::CXXDestructor, "");
936static_assert((clang::Decl::Kind)ZigClangDeclMSProperty == clang::Decl::MSProperty, "");
937static_assert((clang::Decl::Kind)ZigClangDeclNonTypeTemplateParm == clang::Decl::NonTypeTemplateParm, "");
938static_assert((clang::Decl::Kind)ZigClangDeclVar == clang::Decl::Var, "");
939static_assert((clang::Decl::Kind)ZigClangDeclDecomposition == clang::Decl::Decomposition, "");
940static_assert((clang::Decl::Kind)ZigClangDeclImplicitParam == clang::Decl::ImplicitParam, "");
941static_assert((clang::Decl::Kind)ZigClangDeclOMPCapturedExpr == clang::Decl::OMPCapturedExpr, "");
942static_assert((clang::Decl::Kind)ZigClangDeclParmVar == clang::Decl::ParmVar, "");
943static_assert((clang::Decl::Kind)ZigClangDeclVarTemplateSpecialization == clang::Decl::VarTemplateSpecialization, "");
944static_assert((clang::Decl::Kind)ZigClangDeclVarTemplatePartialSpecialization == clang::Decl::VarTemplatePartialSpecialization, "");
945static_assert((clang::Decl::Kind)ZigClangDeclEnumConstant == clang::Decl::EnumConstant, "");
946static_assert((clang::Decl::Kind)ZigClangDeclIndirectField == clang::Decl::IndirectField, "");
947static_assert((clang::Decl::Kind)ZigClangDeclOMPDeclareReduction == clang::Decl::OMPDeclareReduction, "");
948static_assert((clang::Decl::Kind)ZigClangDeclUnresolvedUsingValue == clang::Decl::UnresolvedUsingValue, "");
949static_assert((clang::Decl::Kind)ZigClangDeclOMPRequires == clang::Decl::OMPRequires, "");
950static_assert((clang::Decl::Kind)ZigClangDeclOMPThreadPrivate == clang::Decl::OMPThreadPrivate, "");
951static_assert((clang::Decl::Kind)ZigClangDeclObjCPropertyImpl == clang::Decl::ObjCPropertyImpl, "");
952static_assert((clang::Decl::Kind)ZigClangDeclPragmaComment == clang::Decl::PragmaComment, "");
953static_assert((clang::Decl::Kind)ZigClangDeclPragmaDetectMismatch == clang::Decl::PragmaDetectMismatch, "");
954static_assert((clang::Decl::Kind)ZigClangDeclStaticAssert == clang::Decl::StaticAssert, "");
955static_assert((clang::Decl::Kind)ZigClangDeclTranslationUnit == clang::Decl::TranslationUnit, "");
956
957void ZigClang_detect_enum_BuiltinTypeKind(clang::BuiltinType::Kind x) {
958 switch (x) {
959 case clang::BuiltinType::OCLImage1dRO:
960 case clang::BuiltinType::OCLImage1dArrayRO:
961 case clang::BuiltinType::OCLImage1dBufferRO:
962 case clang::BuiltinType::OCLImage2dRO:
963 case clang::BuiltinType::OCLImage2dArrayRO:
964 case clang::BuiltinType::OCLImage2dDepthRO:
965 case clang::BuiltinType::OCLImage2dArrayDepthRO:
966 case clang::BuiltinType::OCLImage2dMSAARO:
967 case clang::BuiltinType::OCLImage2dArrayMSAARO:
968 case clang::BuiltinType::OCLImage2dMSAADepthRO:
969 case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
970 case clang::BuiltinType::OCLImage3dRO:
971 case clang::BuiltinType::OCLImage1dWO:
972 case clang::BuiltinType::OCLImage1dArrayWO:
973 case clang::BuiltinType::OCLImage1dBufferWO:
974 case clang::BuiltinType::OCLImage2dWO:
975 case clang::BuiltinType::OCLImage2dArrayWO:
976 case clang::BuiltinType::OCLImage2dDepthWO:
977 case clang::BuiltinType::OCLImage2dArrayDepthWO:
978 case clang::BuiltinType::OCLImage2dMSAAWO:
979 case clang::BuiltinType::OCLImage2dArrayMSAAWO:
980 case clang::BuiltinType::OCLImage2dMSAADepthWO:
981 case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
982 case clang::BuiltinType::OCLImage3dWO:
983 case clang::BuiltinType::OCLImage1dRW:
984 case clang::BuiltinType::OCLImage1dArrayRW:
985 case clang::BuiltinType::OCLImage1dBufferRW:
986 case clang::BuiltinType::OCLImage2dRW:
987 case clang::BuiltinType::OCLImage2dArrayRW:
988 case clang::BuiltinType::OCLImage2dDepthRW:
989 case clang::BuiltinType::OCLImage2dArrayDepthRW:
990 case clang::BuiltinType::OCLImage2dMSAARW:
991 case clang::BuiltinType::OCLImage2dArrayMSAARW:
992 case clang::BuiltinType::OCLImage2dMSAADepthRW:
993 case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
994 case clang::BuiltinType::OCLImage3dRW:
995 case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload:
996 case clang::BuiltinType::OCLIntelSubgroupAVCImePayload:
997 case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload:
998 case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload:
999 case clang::BuiltinType::OCLIntelSubgroupAVCMceResult:
1000 case clang::BuiltinType::OCLIntelSubgroupAVCImeResult:
1001 case clang::BuiltinType::OCLIntelSubgroupAVCRefResult:
1002 case clang::BuiltinType::OCLIntelSubgroupAVCSicResult:
1003 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout:
1004 case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout:
1005 case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin:
1006 case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin:
1007 case clang::BuiltinType::Void:
1008 case clang::BuiltinType::Bool:
1009 case clang::BuiltinType::Char_U:
1010 case clang::BuiltinType::UChar:
1011 case clang::BuiltinType::WChar_U:
1012 case clang::BuiltinType::Char8:
1013 case clang::BuiltinType::Char16:
1014 case clang::BuiltinType::Char32:
1015 case clang::BuiltinType::UShort:
1016 case clang::BuiltinType::UInt:
1017 case clang::BuiltinType::ULong:
1018 case clang::BuiltinType::ULongLong:
1019 case clang::BuiltinType::UInt128:
1020 case clang::BuiltinType::Char_S:
1021 case clang::BuiltinType::SChar:
1022 case clang::BuiltinType::WChar_S:
1023 case clang::BuiltinType::Short:
1024 case clang::BuiltinType::Int:
1025 case clang::BuiltinType::Long:
1026 case clang::BuiltinType::LongLong:
1027 case clang::BuiltinType::Int128:
1028 case clang::BuiltinType::ShortAccum:
1029 case clang::BuiltinType::Accum:
1030 case clang::BuiltinType::LongAccum:
1031 case clang::BuiltinType::UShortAccum:
1032 case clang::BuiltinType::UAccum:
1033 case clang::BuiltinType::ULongAccum:
1034 case clang::BuiltinType::ShortFract:
1035 case clang::BuiltinType::Fract:
1036 case clang::BuiltinType::LongFract:
1037 case clang::BuiltinType::UShortFract:
1038 case clang::BuiltinType::UFract:
1039 case clang::BuiltinType::ULongFract:
1040 case clang::BuiltinType::SatShortAccum:
1041 case clang::BuiltinType::SatAccum:
1042 case clang::BuiltinType::SatLongAccum:
1043 case clang::BuiltinType::SatUShortAccum:
1044 case clang::BuiltinType::SatUAccum:
1045 case clang::BuiltinType::SatULongAccum:
1046 case clang::BuiltinType::SatShortFract:
1047 case clang::BuiltinType::SatFract:
1048 case clang::BuiltinType::SatLongFract:
1049 case clang::BuiltinType::SatUShortFract:
1050 case clang::BuiltinType::SatUFract:
1051 case clang::BuiltinType::SatULongFract:
1052 case clang::BuiltinType::Half:
1053 case clang::BuiltinType::Float:
1054 case clang::BuiltinType::Double:
1055 case clang::BuiltinType::LongDouble:
1056 case clang::BuiltinType::Float16:
1057 case clang::BuiltinType::Float128:
1058 case clang::BuiltinType::NullPtr:
1059 case clang::BuiltinType::ObjCId:
1060 case clang::BuiltinType::ObjCClass:
1061 case clang::BuiltinType::ObjCSel:
1062 case clang::BuiltinType::OCLSampler:
1063 case clang::BuiltinType::OCLEvent:
1064 case clang::BuiltinType::OCLClkEvent:
1065 case clang::BuiltinType::OCLQueue:
1066 case clang::BuiltinType::OCLReserveID:
1067 case clang::BuiltinType::Dependent:
1068 case clang::BuiltinType::Overload:
1069 case clang::BuiltinType::BoundMember:
1070 case clang::BuiltinType::PseudoObject:
1071 case clang::BuiltinType::UnknownAny:
1072 case clang::BuiltinType::BuiltinFn:
1073 case clang::BuiltinType::ARCUnbridgedCast:
1074 case clang::BuiltinType::OMPArraySection:
1075 break;
1076 }
1077}
1078
1079static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dRO == clang::BuiltinType::OCLImage1dRO, "");
1080static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dArrayRO == clang::BuiltinType::OCLImage1dArrayRO, "");
1081static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dBufferRO == clang::BuiltinType::OCLImage1dBufferRO, "");
1082static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dRO == clang::BuiltinType::OCLImage2dRO, "");
1083static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayRO == clang::BuiltinType::OCLImage2dArrayRO, "");
1084static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dDepthRO == clang::BuiltinType::OCLImage2dDepthRO, "");
1085static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayDepthRO == clang::BuiltinType::OCLImage2dArrayDepthRO, "");
1086static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAARO == clang::BuiltinType::OCLImage2dMSAARO, "");
1087static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAARO == clang::BuiltinType::OCLImage2dArrayMSAARO, "");
1088static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAADepthRO == clang::BuiltinType::OCLImage2dMSAADepthRO, "");
1089static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO == clang::BuiltinType::OCLImage2dArrayMSAADepthRO, "");
1090static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage3dRO == clang::BuiltinType::OCLImage3dRO, "");
1091static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dWO == clang::BuiltinType::OCLImage1dWO, "");
1092static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dArrayWO == clang::BuiltinType::OCLImage1dArrayWO, "");
1093static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dBufferWO == clang::BuiltinType::OCLImage1dBufferWO, "");
1094static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dWO == clang::BuiltinType::OCLImage2dWO, "");
1095static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayWO == clang::BuiltinType::OCLImage2dArrayWO, "");
1096static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dDepthWO == clang::BuiltinType::OCLImage2dDepthWO, "");
1097static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayDepthWO == clang::BuiltinType::OCLImage2dArrayDepthWO, "");
1098static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAAWO == clang::BuiltinType::OCLImage2dMSAAWO, "");
1099static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAAWO == clang::BuiltinType::OCLImage2dArrayMSAAWO, "");
1100static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAADepthWO == clang::BuiltinType::OCLImage2dMSAADepthWO, "");
1101static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO == clang::BuiltinType::OCLImage2dArrayMSAADepthWO, "");
1102static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage3dWO == clang::BuiltinType::OCLImage3dWO, "");
1103static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dRW == clang::BuiltinType::OCLImage1dRW, "");
1104static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dArrayRW == clang::BuiltinType::OCLImage1dArrayRW, "");
1105static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage1dBufferRW == clang::BuiltinType::OCLImage1dBufferRW, "");
1106static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dRW == clang::BuiltinType::OCLImage2dRW, "");
1107static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayRW == clang::BuiltinType::OCLImage2dArrayRW, "");
1108static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dDepthRW == clang::BuiltinType::OCLImage2dDepthRW, "");
1109static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayDepthRW == clang::BuiltinType::OCLImage2dArrayDepthRW, "");
1110static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAARW == clang::BuiltinType::OCLImage2dMSAARW, "");
1111static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAARW == clang::BuiltinType::OCLImage2dArrayMSAARW, "");
1112static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dMSAADepthRW == clang::BuiltinType::OCLImage2dMSAADepthRW, "");
1113static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW == clang::BuiltinType::OCLImage2dArrayMSAADepthRW, "");
1114static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLImage3dRW == clang::BuiltinType::OCLImage3dRW, "");
1115static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload == clang::BuiltinType::OCLIntelSubgroupAVCMcePayload, "");
1116static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload == clang::BuiltinType::OCLIntelSubgroupAVCImePayload, "");
1117static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload == clang::BuiltinType::OCLIntelSubgroupAVCRefPayload, "");
1118static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload == clang::BuiltinType::OCLIntelSubgroupAVCSicPayload, "");
1119static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult == clang::BuiltinType::OCLIntelSubgroupAVCMceResult, "");
1120static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult == clang::BuiltinType::OCLIntelSubgroupAVCImeResult, "");
1121static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult == clang::BuiltinType::OCLIntelSubgroupAVCRefResult, "");
1122static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult == clang::BuiltinType::OCLIntelSubgroupAVCSicResult, "");
1123static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout, "");
1124static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout == clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout, "");
1125static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin, "");
1126static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin == clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin, "");
1127static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeVoid == clang::BuiltinType::Void, "");
1128static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeBool == clang::BuiltinType::Bool, "");
1129static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar_U == clang::BuiltinType::Char_U, "");
1130static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUChar == clang::BuiltinType::UChar, "");
1131static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeWChar_U == clang::BuiltinType::WChar_U, "");
1132static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar8 == clang::BuiltinType::Char8, "");
1133static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar16 == clang::BuiltinType::Char16, "");
1134static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar32 == clang::BuiltinType::Char32, "");
1135static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUShort == clang::BuiltinType::UShort, "");
1136static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUInt == clang::BuiltinType::UInt, "");
1137static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeULong == clang::BuiltinType::ULong, "");
1138static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeULongLong == clang::BuiltinType::ULongLong, "");
1139static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUInt128 == clang::BuiltinType::UInt128, "");
1140static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeChar_S == clang::BuiltinType::Char_S, "");
1141static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSChar == clang::BuiltinType::SChar, "");
1142static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeWChar_S == clang::BuiltinType::WChar_S, "");
1143static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeShort == clang::BuiltinType::Short, "");
1144static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeInt == clang::BuiltinType::Int, "");
1145static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeLong == clang::BuiltinType::Long, "");
1146static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeLongLong == clang::BuiltinType::LongLong, "");
1147static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeInt128 == clang::BuiltinType::Int128, "");
1148static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeShortAccum == clang::BuiltinType::ShortAccum, "");
1149static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeAccum == clang::BuiltinType::Accum, "");
1150static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeLongAccum == clang::BuiltinType::LongAccum, "");
1151static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUShortAccum == clang::BuiltinType::UShortAccum, "");
1152static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUAccum == clang::BuiltinType::UAccum, "");
1153static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeULongAccum == clang::BuiltinType::ULongAccum, "");
1154static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeShortFract == clang::BuiltinType::ShortFract, "");
1155static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeFract == clang::BuiltinType::Fract, "");
1156static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeLongFract == clang::BuiltinType::LongFract, "");
1157static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUShortFract == clang::BuiltinType::UShortFract, "");
1158static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUFract == clang::BuiltinType::UFract, "");
1159static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeULongFract == clang::BuiltinType::ULongFract, "");
1160static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatShortAccum == clang::BuiltinType::SatShortAccum, "");
1161static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatAccum == clang::BuiltinType::SatAccum, "");
1162static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatLongAccum == clang::BuiltinType::SatLongAccum, "");
1163static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatUShortAccum == clang::BuiltinType::SatUShortAccum, "");
1164static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatUAccum == clang::BuiltinType::SatUAccum, "");
1165static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatULongAccum == clang::BuiltinType::SatULongAccum, "");
1166static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatShortFract == clang::BuiltinType::SatShortFract, "");
1167static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatFract == clang::BuiltinType::SatFract, "");
1168static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatLongFract == clang::BuiltinType::SatLongFract, "");
1169static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatUShortFract == clang::BuiltinType::SatUShortFract, "");
1170static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatUFract == clang::BuiltinType::SatUFract, "");
1171static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeSatULongFract == clang::BuiltinType::SatULongFract, "");
1172static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeHalf == clang::BuiltinType::Half, "");
1173static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeFloat == clang::BuiltinType::Float, "");
1174static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeDouble == clang::BuiltinType::Double, "");
1175static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeLongDouble == clang::BuiltinType::LongDouble, "");
1176static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeFloat16 == clang::BuiltinType::Float16, "");
1177static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeFloat128 == clang::BuiltinType::Float128, "");
1178static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeNullPtr == clang::BuiltinType::NullPtr, "");
1179static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeObjCId == clang::BuiltinType::ObjCId, "");
1180static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeObjCClass == clang::BuiltinType::ObjCClass, "");
1181static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeObjCSel == clang::BuiltinType::ObjCSel, "");
1182static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLSampler == clang::BuiltinType::OCLSampler, "");
1183static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLEvent == clang::BuiltinType::OCLEvent, "");
1184static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLClkEvent == clang::BuiltinType::OCLClkEvent, "");
1185static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLQueue == clang::BuiltinType::OCLQueue, "");
1186static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOCLReserveID == clang::BuiltinType::OCLReserveID, "");
1187static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeDependent == clang::BuiltinType::Dependent, "");
1188static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOverload == clang::BuiltinType::Overload, "");
1189static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeBoundMember == clang::BuiltinType::BoundMember, "");
1190static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypePseudoObject == clang::BuiltinType::PseudoObject, "");
1191static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeUnknownAny == clang::BuiltinType::UnknownAny, "");
1192static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeBuiltinFn == clang::BuiltinType::BuiltinFn, "");
1193static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeARCUnbridgedCast == clang::BuiltinType::ARCUnbridgedCast, "");
1194static_assert((clang::BuiltinType::Kind)ZigClangBuiltinTypeOMPArraySection == clang::BuiltinType::OMPArraySection, "");
1195
1196void ZigClang_detect_enum_CallingConv(clang::CallingConv x) {
1197 switch (x) {
1198 case clang::CC_C:
1199 case clang::CC_X86StdCall:
1200 case clang::CC_X86FastCall:
1201 case clang::CC_X86ThisCall:
1202 case clang::CC_X86VectorCall:
1203 case clang::CC_X86Pascal:
1204 case clang::CC_Win64:
1205 case clang::CC_X86_64SysV:
1206 case clang::CC_X86RegCall:
1207 case clang::CC_AAPCS:
1208 case clang::CC_AAPCS_VFP:
1209 case clang::CC_IntelOclBicc:
1210 case clang::CC_SpirFunction:
1211 case clang::CC_OpenCLKernel:
1212 case clang::CC_Swift:
1213 case clang::CC_PreserveMost:
1214 case clang::CC_PreserveAll:
1215 case clang::CC_AArch64VectorCall:
1216 break;
1217 }
1218}
1219
1220static_assert((clang::CallingConv)ZigClangCallingConv_C == clang::CC_C, "");
1221static_assert((clang::CallingConv)ZigClangCallingConv_X86StdCall == clang::CC_X86StdCall, "");
1222static_assert((clang::CallingConv)ZigClangCallingConv_X86FastCall == clang::CC_X86FastCall, "");
1223static_assert((clang::CallingConv)ZigClangCallingConv_X86ThisCall == clang::CC_X86ThisCall, "");
1224static_assert((clang::CallingConv)ZigClangCallingConv_X86VectorCall == clang::CC_X86VectorCall, "");
1225static_assert((clang::CallingConv)ZigClangCallingConv_X86Pascal == clang::CC_X86Pascal, "");
1226static_assert((clang::CallingConv)ZigClangCallingConv_Win64 == clang::CC_Win64, "");
1227static_assert((clang::CallingConv)ZigClangCallingConv_X86_64SysV == clang::CC_X86_64SysV, "");
1228static_assert((clang::CallingConv)ZigClangCallingConv_X86RegCall == clang::CC_X86RegCall, "");
1229static_assert((clang::CallingConv)ZigClangCallingConv_AAPCS == clang::CC_AAPCS, "");
1230static_assert((clang::CallingConv)ZigClangCallingConv_AAPCS_VFP == clang::CC_AAPCS_VFP, "");
1231static_assert((clang::CallingConv)ZigClangCallingConv_IntelOclBicc == clang::CC_IntelOclBicc, "");
1232static_assert((clang::CallingConv)ZigClangCallingConv_SpirFunction == clang::CC_SpirFunction, "");
1233static_assert((clang::CallingConv)ZigClangCallingConv_OpenCLKernel == clang::CC_OpenCLKernel, "");
1234static_assert((clang::CallingConv)ZigClangCallingConv_Swift == clang::CC_Swift, "");
1235static_assert((clang::CallingConv)ZigClangCallingConv_PreserveMost == clang::CC_PreserveMost, "");
1236static_assert((clang::CallingConv)ZigClangCallingConv_PreserveAll == clang::CC_PreserveAll, "");
1237static_assert((clang::CallingConv)ZigClangCallingConv_AArch64VectorCall == clang::CC_AArch64VectorCall, "");
1238
1239void ZigClang_detect_enum_StorageClass(clang::StorageClass x) {
1240 switch (x) {
1241 case clang::SC_None:
1242 case clang::SC_Extern:
1243 case clang::SC_Static:
1244 case clang::SC_PrivateExtern:
1245 case clang::SC_Auto:
1246 case clang::SC_Register:
1247 break;
1248 }
1249}
1250
1251static_assert((clang::StorageClass)ZigClangStorageClass_None == clang::SC_None, "");
1252static_assert((clang::StorageClass)ZigClangStorageClass_Extern == clang::SC_Extern, "");
1253static_assert((clang::StorageClass)ZigClangStorageClass_Static == clang::SC_Static, "");
1254static_assert((clang::StorageClass)ZigClangStorageClass_PrivateExtern == clang::SC_PrivateExtern, "");
1255static_assert((clang::StorageClass)ZigClangStorageClass_Auto == clang::SC_Auto, "");
1256static_assert((clang::StorageClass)ZigClangStorageClass_Register == clang::SC_Register, "");
1257
1258
1401259static_assert(sizeof(ZigClangSourceLocation) == sizeof(clang::SourceLocation), "");
1411260static ZigClangSourceLocation bitcast(clang::SourceLocation src) {
1421261 ZigClangSourceLocation dest;
......@@ -161,6 +1280,26 @@ static clang::QualType bitcast(ZigClangQualType src) {
1611280 return dest;
1621281}
1631282
1283static_assert(sizeof(ZigClangAPValueLValueBase) == sizeof(clang::APValue::LValueBase), "");
1284static ZigClangAPValueLValueBase bitcast(clang::APValue::LValueBase src) {
1285 ZigClangAPValueLValueBase dest;
1286 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangAPValueLValueBase));
1287 return dest;
1288}
1289static clang::APValue::LValueBase bitcast(ZigClangAPValueLValueBase src) {
1290 clang::APValue::LValueBase dest;
1291 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangAPValueLValueBase));
1292 return dest;
1293}
1294
1295static_assert(sizeof(ZigClangCompoundStmt_const_body_iterator) == sizeof(clang::CompoundStmt::const_body_iterator), "");
1296static ZigClangCompoundStmt_const_body_iterator bitcast(clang::CompoundStmt::const_body_iterator src) {
1297 ZigClangCompoundStmt_const_body_iterator dest;
1298 memcpy(&dest, static_cast<void *>(&src), sizeof(ZigClangCompoundStmt_const_body_iterator));
1299 return dest;
1300}
1301
1302
1641303ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *self,
1651304 ZigClangSourceLocation Loc)
1661305{
......@@ -196,6 +1335,10 @@ ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext* sel
1961335 return bitcast(reinterpret_cast<const clang::ASTContext *>(self)->getPointerType(bitcast(T)));
1971336}
1981337
1338unsigned ZigClangASTContext_getTypeAlign(const ZigClangASTContext* self, ZigClangQualType T) {
1339 return reinterpret_cast<const clang::ASTContext *>(self)->getTypeAlign(bitcast(T));
1340}
1341
1991342ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *self) {
2001343 clang::ASTContext *result = &reinterpret_cast<clang::ASTUnit *>(self)->getASTContext();
2011344 return reinterpret_cast<ZigClangASTContext *>(result);
......@@ -212,3 +1355,477 @@ bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *self, void *contex
2121355 return reinterpret_cast<clang::ASTUnit *>(self)->visitLocalTopLevelDecls(context,
2131356 reinterpret_cast<bool (*)(void *, const clang::Decl *)>(Fn));
2141357}
1358
1359const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty) {
1360 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordType *>(record_ty)->getDecl();
1361 return reinterpret_cast<const ZigClangRecordDecl *>(record_decl);
1362}
1363
1364const ZigClangEnumDecl *ZigClangEnumType_getDecl(const ZigClangEnumType *enum_ty) {
1365 const clang::EnumDecl *enum_decl = reinterpret_cast<const clang::EnumType *>(enum_ty)->getDecl();
1366 return reinterpret_cast<const ZigClangEnumDecl *>(enum_decl);
1367}
1368
1369const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl) {
1370 const clang::TagDecl *tag_decl = reinterpret_cast<const clang::RecordDecl*>(record_decl)->getCanonicalDecl();
1371 return reinterpret_cast<const ZigClangTagDecl *>(tag_decl);
1372}
1373
1374const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *enum_decl) {
1375 const clang::TagDecl *tag_decl = reinterpret_cast<const clang::EnumDecl*>(enum_decl)->getCanonicalDecl();
1376 return reinterpret_cast<const ZigClangTagDecl *>(tag_decl);
1377}
1378
1379const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const ZigClangTypedefNameDecl *self) {
1380 const clang::TypedefNameDecl *decl = reinterpret_cast<const clang::TypedefNameDecl*>(self)->getCanonicalDecl();
1381 return reinterpret_cast<const ZigClangTypedefNameDecl *>(decl);
1382}
1383
1384const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
1385 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
1386 const clang::RecordDecl *definition = record_decl->getDefinition();
1387 return reinterpret_cast<const ZigClangRecordDecl *>(definition);
1388}
1389
1390const ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const ZigClangEnumDecl *zig_enum_decl) {
1391 const clang::EnumDecl *enum_decl = reinterpret_cast<const clang::EnumDecl *>(zig_enum_decl);
1392 const clang::EnumDecl *definition = enum_decl->getDefinition();
1393 return reinterpret_cast<const ZigClangEnumDecl *>(definition);
1394}
1395
1396bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl) {
1397 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isUnion();
1398}
1399
1400bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl) {
1401 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isStruct();
1402}
1403
1404bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl) {
1405 return reinterpret_cast<const clang::RecordDecl*>(record_decl)->isAnonymousStructOrUnion();
1406}
1407
1408const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *zig_decl) {
1409 const clang::Decl *decl = reinterpret_cast<const clang::Decl *>(zig_decl);
1410 const clang::NamedDecl *named_decl = static_cast<const clang::NamedDecl *>(decl);
1411 return (const char *)named_decl->getName().bytes_begin();
1412}
1413
1414ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *self) {
1415 auto casted = reinterpret_cast<const clang::Decl *>(self);
1416 return (ZigClangDeclKind)casted->getKind();
1417}
1418
1419const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *self) {
1420 auto casted = reinterpret_cast<const clang::Decl *>(self);
1421 return casted->getDeclKindName();
1422}
1423
1424ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *zig_record_decl) {
1425 const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
1426 return bitcast(record_decl->getLocation());
1427}
1428
1429ZigClangSourceLocation ZigClangEnumDecl_getLocation(const ZigClangEnumDecl *self) {
1430 auto casted = reinterpret_cast<const clang::EnumDecl *>(self);
1431 return bitcast(casted->getLocation());
1432}
1433
1434ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const ZigClangTypedefNameDecl *self) {
1435 auto casted = reinterpret_cast<const clang::TypedefNameDecl *>(self);
1436 return bitcast(casted->getLocation());
1437}
1438
1439ZigClangSourceLocation ZigClangDecl_getLocation(const ZigClangDecl *self) {
1440 auto casted = reinterpret_cast<const clang::Decl *>(self);
1441 return bitcast(casted->getLocation());
1442}
1443
1444bool ZigClangSourceLocation_eq(ZigClangSourceLocation zig_a, ZigClangSourceLocation zig_b) {
1445 clang::SourceLocation a = bitcast(zig_a);
1446 clang::SourceLocation b = bitcast(zig_b);
1447 return a == b;
1448}
1449
1450ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *self) {
1451 return bitcast(reinterpret_cast<const clang::EnumDecl *>(self)->getIntegerType());
1452}
1453
1454struct ZigClangQualType ZigClangFunctionDecl_getType(const struct ZigClangFunctionDecl *self) {
1455 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1456 return bitcast(casted->getType());
1457}
1458
1459struct ZigClangSourceLocation ZigClangFunctionDecl_getLocation(const struct ZigClangFunctionDecl *self) {
1460 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1461 return bitcast(casted->getLocation());
1462}
1463
1464bool ZigClangFunctionDecl_hasBody(const struct ZigClangFunctionDecl *self) {
1465 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1466 return casted->hasBody();
1467}
1468
1469enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *self) {
1470 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1471 return (ZigClangStorageClass)casted->getStorageClass();
1472}
1473
1474const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *self,
1475 unsigned i)
1476{
1477 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1478 const clang::ParmVarDecl *parm_var_decl = casted->getParamDecl(i);
1479 return reinterpret_cast<const ZigClangParmVarDecl *>(parm_var_decl);
1480}
1481
1482const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *self) {
1483 auto casted = reinterpret_cast<const clang::FunctionDecl *>(self);
1484 const clang::Stmt *stmt = casted->getBody();
1485 return reinterpret_cast<const ZigClangStmt *>(stmt);
1486}
1487
1488const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
1489 auto casted = reinterpret_cast<const clang::TypedefType *>(self);
1490 const clang::TypedefNameDecl *name_decl = casted->getDecl();
1491 return reinterpret_cast<const ZigClangTypedefNameDecl *>(name_decl);
1492}
1493
1494ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const ZigClangTypedefNameDecl *self) {
1495 auto casted = reinterpret_cast<const clang::TypedefNameDecl *>(self);
1496 clang::QualType ty = casted->getUnderlyingType();
1497 return bitcast(ty);
1498}
1499
1500ZigClangQualType ZigClangQualType_getCanonicalType(ZigClangQualType self) {
1501 clang::QualType qt = bitcast(self);
1502 return bitcast(qt.getCanonicalType());
1503}
1504
1505const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType self) {
1506 clang::QualType qt = bitcast(self);
1507 const clang::Type *ty = qt.getTypePtr();
1508 return reinterpret_cast<const ZigClangType *>(ty);
1509}
1510
1511void ZigClangQualType_addConst(ZigClangQualType *self) {
1512 reinterpret_cast<clang::QualType *>(self)->addConst();
1513}
1514
1515bool ZigClangQualType_eq(ZigClangQualType zig_t1, ZigClangQualType zig_t2) {
1516 clang::QualType t1 = bitcast(zig_t1);
1517 clang::QualType t2 = bitcast(zig_t2);
1518 if (t1.isConstQualified() != t2.isConstQualified()) {
1519 return false;
1520 }
1521 if (t1.isVolatileQualified() != t2.isVolatileQualified()) {
1522 return false;
1523 }
1524 if (t1.isRestrictQualified() != t2.isRestrictQualified()) {
1525 return false;
1526 }
1527 return t1.getTypePtr() == t2.getTypePtr();
1528}
1529
1530bool ZigClangQualType_isConstQualified(ZigClangQualType self) {
1531 clang::QualType qt = bitcast(self);
1532 return qt.isConstQualified();
1533}
1534
1535bool ZigClangQualType_isVolatileQualified(ZigClangQualType self) {
1536 clang::QualType qt = bitcast(self);
1537 return qt.isVolatileQualified();
1538}
1539
1540bool ZigClangQualType_isRestrictQualified(ZigClangQualType self) {
1541 clang::QualType qt = bitcast(self);
1542 return qt.isRestrictQualified();
1543}
1544
1545ZigClangTypeClass ZigClangType_getTypeClass(const ZigClangType *self) {
1546 auto casted = reinterpret_cast<const clang::Type *>(self);
1547 clang::Type::TypeClass tc = casted->getTypeClass();
1548 return (ZigClangTypeClass)tc;
1549}
1550
1551ZigClangQualType ZigClangType_getPointeeType(const ZigClangType *self) {
1552 auto casted = reinterpret_cast<const clang::Type *>(self);
1553 return bitcast(casted->getPointeeType());
1554}
1555
1556bool ZigClangType_isVoidType(const ZigClangType *self) {
1557 auto casted = reinterpret_cast<const clang::Type *>(self);
1558 return casted->isVoidType();
1559}
1560
1561const char *ZigClangType_getTypeClassName(const ZigClangType *self) {
1562 auto casted = reinterpret_cast<const clang::Type *>(self);
1563 return casted->getTypeClassName();
1564}
1565
1566ZigClangSourceLocation ZigClangStmt_getBeginLoc(const ZigClangStmt *self) {
1567 auto casted = reinterpret_cast<const clang::Stmt *>(self);
1568 return bitcast(casted->getBeginLoc());
1569}
1570
1571bool ZigClangStmt_classof_Expr(const ZigClangStmt *self) {
1572 auto casted = reinterpret_cast<const clang::Stmt *>(self);
1573 return clang::Expr::classof(casted);
1574}
1575
1576ZigClangStmtClass ZigClangStmt_getStmtClass(const ZigClangStmt *self) {
1577 auto casted = reinterpret_cast<const clang::Stmt *>(self);
1578 return (ZigClangStmtClass)casted->getStmtClass();
1579}
1580
1581ZigClangStmtClass ZigClangExpr_getStmtClass(const ZigClangExpr *self) {
1582 auto casted = reinterpret_cast<const clang::Expr *>(self);
1583 return (ZigClangStmtClass)casted->getStmtClass();
1584}
1585
1586ZigClangQualType ZigClangExpr_getType(const ZigClangExpr *self) {
1587 auto casted = reinterpret_cast<const clang::Expr *>(self);
1588 return bitcast(casted->getType());
1589}
1590
1591ZigClangSourceLocation ZigClangExpr_getBeginLoc(const ZigClangExpr *self) {
1592 auto casted = reinterpret_cast<const clang::Expr *>(self);
1593 return bitcast(casted->getBeginLoc());
1594}
1595
1596ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self) {
1597 auto casted = reinterpret_cast<const clang::APValue *>(self);
1598 return (ZigClangAPValueKind)casted->getKind();
1599}
1600
1601const ZigClangAPSInt *ZigClangAPValue_getInt(const ZigClangAPValue *self) {
1602 auto casted = reinterpret_cast<const clang::APValue *>(self);
1603 const llvm::APSInt *result = &casted->getInt();
1604 return reinterpret_cast<const ZigClangAPSInt *>(result);
1605}
1606
1607unsigned ZigClangAPValue_getArrayInitializedElts(const ZigClangAPValue *self) {
1608 auto casted = reinterpret_cast<const clang::APValue *>(self);
1609 return casted->getArrayInitializedElts();
1610}
1611
1612const ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const ZigClangAPValue *self, unsigned i) {
1613 auto casted = reinterpret_cast<const clang::APValue *>(self);
1614 const clang::APValue *result = &casted->getArrayInitializedElt(i);
1615 return reinterpret_cast<const ZigClangAPValue *>(result);
1616}
1617
1618const ZigClangAPValue *ZigClangAPValue_getArrayFiller(const ZigClangAPValue *self) {
1619 auto casted = reinterpret_cast<const clang::APValue *>(self);
1620 const clang::APValue *result = &casted->getArrayFiller();
1621 return reinterpret_cast<const ZigClangAPValue *>(result);
1622}
1623
1624unsigned ZigClangAPValue_getArraySize(const ZigClangAPValue *self) {
1625 auto casted = reinterpret_cast<const clang::APValue *>(self);
1626 return casted->getArraySize();
1627}
1628
1629const ZigClangAPSInt *ZigClangAPSInt_negate(const ZigClangAPSInt *self) {
1630 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1631 llvm::APSInt *result = new llvm::APSInt();
1632 *result = *casted;
1633 *result = -*result;
1634 return reinterpret_cast<const ZigClangAPSInt *>(result);
1635}
1636
1637void ZigClangAPSInt_free(const ZigClangAPSInt *self) {
1638 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1639 delete casted;
1640}
1641
1642bool ZigClangAPSInt_isSigned(const ZigClangAPSInt *self) {
1643 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1644 return casted->isSigned();
1645}
1646
1647bool ZigClangAPSInt_isNegative(const ZigClangAPSInt *self) {
1648 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1649 return casted->isNegative();
1650}
1651
1652const uint64_t *ZigClangAPSInt_getRawData(const ZigClangAPSInt *self) {
1653 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1654 return casted->getRawData();
1655}
1656
1657unsigned ZigClangAPSInt_getNumWords(const ZigClangAPSInt *self) {
1658 auto casted = reinterpret_cast<const llvm::APSInt *>(self);
1659 return casted->getNumWords();
1660}
1661
1662const ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(ZigClangAPValueLValueBase self) {
1663 clang::APValue::LValueBase casted = bitcast(self);
1664 const clang::Expr *expr = casted.dyn_cast<const clang::Expr *>();
1665 return reinterpret_cast<const ZigClangExpr *>(expr);
1666}
1667
1668ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const ZigClangAPValue *self) {
1669 auto casted = reinterpret_cast<const clang::APValue *>(self);
1670 clang::APValue::LValueBase lval_base = casted->getLValueBase();
1671 return bitcast(lval_base);
1672}
1673
1674ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,
1675 struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path)
1676{
1677 clang::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
1678
1679 std::shared_ptr<clang::PCHContainerOperations> pch_container_ops = std::make_shared<clang::PCHContainerOperations>();
1680
1681 bool only_local_decls = true;
1682 bool capture_diagnostics = true;
1683 bool user_files_are_volatile = true;
1684 bool allow_pch_with_compiler_errors = false;
1685 bool single_file_parse = false;
1686 bool for_serialization = false;
1687 std::unique_ptr<clang::ASTUnit> *err_unit = new std::unique_ptr<clang::ASTUnit>();
1688 clang::ASTUnit *ast_unit = clang::ASTUnit::LoadFromCommandLine(
1689 args_begin, args_end,
1690 pch_container_ops, diags, resources_path,
1691 only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete,
1692 false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
1693 single_file_parse, user_files_are_volatile, for_serialization, clang::None, err_unit,
1694 nullptr);
1695
1696 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
1697 if (!ast_unit && !err_unit) {
1698 return nullptr;
1699 }
1700
1701 if (diags->getClient()->getNumErrors() > 0) {
1702 if (ast_unit) {
1703 *err_unit = std::unique_ptr<clang::ASTUnit>(ast_unit);
1704 }
1705
1706 size_t cap = 4;
1707 *errors_len = 0;
1708 *errors_ptr = reinterpret_cast<Stage2ErrorMsg*>(malloc(cap * sizeof(Stage2ErrorMsg)));
1709 if (*errors_ptr == nullptr) {
1710 return nullptr;
1711 }
1712
1713 for (clang::ASTUnit::stored_diag_iterator it = (*err_unit)->stored_diag_begin(),
1714 it_end = (*err_unit)->stored_diag_end();
1715 it != it_end; ++it)
1716 {
1717 switch (it->getLevel()) {
1718 case clang::DiagnosticsEngine::Ignored:
1719 case clang::DiagnosticsEngine::Note:
1720 case clang::DiagnosticsEngine::Remark:
1721 case clang::DiagnosticsEngine::Warning:
1722 continue;
1723 case clang::DiagnosticsEngine::Error:
1724 case clang::DiagnosticsEngine::Fatal:
1725 break;
1726 }
1727 llvm::StringRef msg_str_ref = it->getMessage();
1728 if (*errors_len >= cap) {
1729 cap *= 2;
1730 Stage2ErrorMsg *new_errors = reinterpret_cast<Stage2ErrorMsg *>(
1731 realloc(*errors_ptr, cap * sizeof(Stage2ErrorMsg)));
1732 if (new_errors == nullptr) {
1733 free(*errors_ptr);
1734 *errors_ptr = nullptr;
1735 *errors_len = 0;
1736 return nullptr;
1737 }
1738 *errors_ptr = new_errors;
1739 }
1740 Stage2ErrorMsg *msg = *errors_ptr + *errors_len;
1741 *errors_len += 1;
1742 msg->msg_ptr = (const char *)msg_str_ref.bytes_begin();
1743 msg->msg_len = msg_str_ref.size();
1744
1745 clang::FullSourceLoc fsl = it->getLocation();
1746 if (fsl.hasManager()) {
1747 clang::FileID file_id = fsl.getFileID();
1748 clang::StringRef filename = fsl.getManager().getFilename(fsl);
1749 if (filename.empty()) {
1750 msg->filename_ptr = nullptr;
1751 } else {
1752 msg->filename_ptr = (const char *)filename.bytes_begin();
1753 msg->filename_len = filename.size();
1754 }
1755 msg->source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
1756 msg->line = fsl.getSpellingLineNumber() - 1;
1757 msg->column = fsl.getSpellingColumnNumber() - 1;
1758 msg->offset = fsl.getManager().getFileOffset(fsl);
1759 } else {
1760 // The only known way this gets triggered right now is if you have a lot of errors
1761 // clang emits "too many errors emitted, stopping now"
1762 msg->filename_ptr = nullptr;
1763 msg->source = nullptr;
1764 }
1765 }
1766
1767 if (*errors_len == 0) {
1768 free(*errors_ptr);
1769 *errors_ptr = nullptr;
1770 }
1771
1772 return nullptr;
1773 }
1774
1775 return reinterpret_cast<ZigClangASTUnit *>(ast_unit);
1776}
1777
1778void ZigClangErrorMsg_delete(Stage2ErrorMsg *ptr, size_t len) {
1779 free(ptr);
1780}
1781
1782void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {
1783 delete reinterpret_cast<clang::ASTUnit *>(self);
1784}
1785
1786enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self) {
1787 auto casted = reinterpret_cast<const clang::BuiltinType *>(self);
1788 return (ZigClangBuiltinTypeKind)casted->getKind();
1789}
1790
1791bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunctionType *self) {
1792 auto casted = reinterpret_cast<const clang::FunctionType *>(self);
1793 return casted->getNoReturnAttr();
1794}
1795
1796enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self) {
1797 auto casted = reinterpret_cast<const clang::FunctionType *>(self);
1798 return (ZigClangCallingConv)casted->getCallConv();
1799}
1800
1801struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self) {
1802 auto casted = reinterpret_cast<const clang::FunctionType *>(self);
1803 return bitcast(casted->getReturnType());
1804}
1805
1806bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self) {
1807 auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self);
1808 return casted->isVariadic();
1809}
1810
1811unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self) {
1812 auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self);
1813 return casted->getNumParams();
1814}
1815
1816struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self,
1817 unsigned index)
1818{
1819 auto casted = reinterpret_cast<const clang::FunctionProtoType *>(self);
1820 return bitcast(casted->getParamType(index));
1821}
1822
1823ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self) {
1824 auto casted = reinterpret_cast<const clang::CompoundStmt *>(self);
1825 return bitcast(casted->body_begin());
1826}
1827
1828ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self) {
1829 auto casted = reinterpret_cast<const clang::CompoundStmt *>(self);
1830 return bitcast(casted->body_end());
1831}
src/zig_clang.h+686-115
......@@ -8,14 +8,13 @@
88#ifndef ZIG_ZIG_CLANG_H
99#define ZIG_ZIG_CLANG_H
1010
11#ifdef __cplusplus
12#define ZIG_EXTERN_C extern "C"
13#else
14#define ZIG_EXTERN_C
15#endif
11#include "userland.h"
12#include <inttypes.h>
13#include <stdbool.h>
1614
1715// ATTENTION: If you modify this file, be sure to update the corresponding
18// extern function declarations in the self-hosted compiler.
16// extern function declarations in the self-hosted compiler file
17// src-self-hosted/clang.zig.
1918
2019struct ZigClangSourceLocation {
2120 unsigned ID;
......@@ -25,7 +24,14 @@ struct ZigClangQualType {
2524 void *ptr;
2625};
2726
27struct ZigClangAPValueLValueBase {
28 void *Ptr;
29 unsigned CallIndex;
30 unsigned Version;
31};
32
2833struct ZigClangAPValue;
34struct ZigClangAPSInt;
2935struct ZigClangASTContext;
3036struct ZigClangASTUnit;
3137struct ZigClangArraySubscriptExpr;
......@@ -82,10 +88,10 @@ struct ZigClangSkipFunctionBodiesScope;
8288struct ZigClangSourceManager;
8389struct ZigClangSourceRange;
8490struct ZigClangStmt;
85struct ZigClangStorageClass;
8691struct ZigClangStringLiteral;
8792struct ZigClangStringRef;
8893struct ZigClangSwitchStmt;
94struct ZigClangTagDecl;
8995struct ZigClangType;
9096struct ZigClangTypedefNameDecl;
9197struct ZigClangTypedefType;
......@@ -94,6 +100,9 @@ struct ZigClangUnaryOperator;
94100struct ZigClangValueDecl;
95101struct ZigClangVarDecl;
96102struct ZigClangWhileStmt;
103struct ZigClangFunctionType;
104
105typedef struct ZigClangStmt *const * ZigClangCompoundStmt_const_body_iterator;
97106
98107enum ZigClangBO {
99108 ZigClangBO_PtrMemD,
......@@ -148,112 +157,674 @@ enum ZigClangUO {
148157 ZigClangUO_Coawait,
149158};
150159
151//struct ZigClangCC_AAPCS;
152//struct ZigClangCC_AAPCS_VFP;
153//struct ZigClangCC_C;
154//struct ZigClangCC_IntelOclBicc;
155//struct ZigClangCC_OpenCLKernel;
156//struct ZigClangCC_PreserveAll;
157//struct ZigClangCC_PreserveMost;
158//struct ZigClangCC_SpirFunction;
159//struct ZigClangCC_Swift;
160//struct ZigClangCC_Win64;
161//struct ZigClangCC_X86FastCall;
162//struct ZigClangCC_X86Pascal;
163//struct ZigClangCC_X86RegCall;
164//struct ZigClangCC_X86StdCall;
165//struct ZigClangCC_X86ThisCall;
166//struct ZigClangCC_X86VectorCall;
167//struct ZigClangCC_X86_64SysV;
168
169//struct ZigClangCK_ARCConsumeObject;
170//struct ZigClangCK_ARCExtendBlockObject;
171//struct ZigClangCK_ARCProduceObject;
172//struct ZigClangCK_ARCReclaimReturnedObject;
173//struct ZigClangCK_AddressSpaceConversion;
174//struct ZigClangCK_AnyPointerToBlockPointerCast;
175//struct ZigClangCK_ArrayToPointerDecay;
176//struct ZigClangCK_AtomicToNonAtomic;
177//struct ZigClangCK_BaseToDerived;
178//struct ZigClangCK_BaseToDerivedMemberPointer;
179//struct ZigClangCK_BitCast;
180//struct ZigClangCK_BlockPointerToObjCPointerCast;
181//struct ZigClangCK_BooleanToSignedIntegral;
182//struct ZigClangCK_BuiltinFnToFnPtr;
183//struct ZigClangCK_CPointerToObjCPointerCast;
184//struct ZigClangCK_ConstructorConversion;
185//struct ZigClangCK_CopyAndAutoreleaseBlockObject;
186//struct ZigClangCK_Dependent;
187//struct ZigClangCK_DerivedToBase;
188//struct ZigClangCK_DerivedToBaseMemberPointer;
189//struct ZigClangCK_Dynamic;
190//struct ZigClangCK_FloatingCast;
191//struct ZigClangCK_FloatingComplexCast;
192//struct ZigClangCK_FloatingComplexToBoolean;
193//struct ZigClangCK_FloatingComplexToIntegralComplex;
194//struct ZigClangCK_FloatingComplexToReal;
195//struct ZigClangCK_FloatingRealToComplex;
196//struct ZigClangCK_FloatingToBoolean;
197//struct ZigClangCK_FloatingToIntegral;
198//struct ZigClangCK_FunctionToPointerDecay;
199//struct ZigClangCK_IntToOCLSampler;
200//struct ZigClangCK_IntegralCast;
201//struct ZigClangCK_IntegralComplexCast;
202//struct ZigClangCK_IntegralComplexToBoolean;
203//struct ZigClangCK_IntegralComplexToFloatingComplex;
204//struct ZigClangCK_IntegralComplexToReal;
205//struct ZigClangCK_IntegralRealToComplex;
206//struct ZigClangCK_IntegralToBoolean;
207//struct ZigClangCK_IntegralToFloating;
208//struct ZigClangCK_IntegralToPointer;
209//struct ZigClangCK_LValueBitCast;
210//struct ZigClangCK_LValueToRValue;
211//struct ZigClangCK_MemberPointerToBoolean;
212//struct ZigClangCK_NoOp;
213//struct ZigClangCK_NonAtomicToAtomic;
214//struct ZigClangCK_NullToMemberPointer;
215//struct ZigClangCK_NullToPointer;
216//struct ZigClangCK_ObjCObjectLValueCast;
217//struct ZigClangCK_PointerToBoolean;
218//struct ZigClangCK_PointerToIntegral;
219//struct ZigClangCK_ReinterpretMemberPointer;
220//struct ZigClangCK_ToUnion;
221//struct ZigClangCK_ToVoid;
222//struct ZigClangCK_UncheckedDerivedToBase;
223//struct ZigClangCK_UserDefinedConversion;
224//struct ZigClangCK_VectorSplat;
225//struct ZigClangCK_ZeroToOCLEvent;
226//struct ZigClangCK_ZeroToOCLQueue;
227
228//struct ZigClangETK_Class;
229//struct ZigClangETK_Enum;
230//struct ZigClangETK_Interface;
231//struct ZigClangETK_None;
232//struct ZigClangETK_Struct;
233//struct ZigClangETK_Typename;
234//struct ZigClangETK_Union;
235
236//struct ZigClangSC_None;
237//struct ZigClangSC_PrivateExtern;
238//struct ZigClangSC_Static;
239
240//struct ZigClangTU_Complete;
241
242ZIG_EXTERN_C ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *,
243 ZigClangSourceLocation Loc);
244ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *,
245 ZigClangSourceLocation SpellingLoc);
246ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *,
247 ZigClangSourceLocation Loc);
248ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *,
249 ZigClangSourceLocation Loc);
250ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *,
251 ZigClangSourceLocation SL);
252
253ZIG_EXTERN_C ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext*, ZigClangQualType T);
254
255ZIG_EXTERN_C ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *);
256ZIG_EXTERN_C ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *);
257ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *, void *context,
258 bool (*Fn)(void *context, const ZigClangDecl *decl));
160enum ZigClangTypeClass {
161 ZigClangType_Builtin,
162 ZigClangType_Complex,
163 ZigClangType_Pointer,
164 ZigClangType_BlockPointer,
165 ZigClangType_LValueReference,
166 ZigClangType_RValueReference,
167 ZigClangType_MemberPointer,
168 ZigClangType_ConstantArray,
169 ZigClangType_IncompleteArray,
170 ZigClangType_VariableArray,
171 ZigClangType_DependentSizedArray,
172 ZigClangType_DependentSizedExtVector,
173 ZigClangType_DependentAddressSpace,
174 ZigClangType_Vector,
175 ZigClangType_DependentVector,
176 ZigClangType_ExtVector,
177 ZigClangType_FunctionProto,
178 ZigClangType_FunctionNoProto,
179 ZigClangType_UnresolvedUsing,
180 ZigClangType_Paren,
181 ZigClangType_Typedef,
182 ZigClangType_Adjusted,
183 ZigClangType_Decayed,
184 ZigClangType_TypeOfExpr,
185 ZigClangType_TypeOf,
186 ZigClangType_Decltype,
187 ZigClangType_UnaryTransform,
188 ZigClangType_Record,
189 ZigClangType_Enum,
190 ZigClangType_Elaborated,
191 ZigClangType_Attributed,
192 ZigClangType_TemplateTypeParm,
193 ZigClangType_SubstTemplateTypeParm,
194 ZigClangType_SubstTemplateTypeParmPack,
195 ZigClangType_TemplateSpecialization,
196 ZigClangType_Auto,
197 ZigClangType_DeducedTemplateSpecialization,
198 ZigClangType_InjectedClassName,
199 ZigClangType_DependentName,
200 ZigClangType_DependentTemplateSpecialization,
201 ZigClangType_PackExpansion,
202 ZigClangType_ObjCTypeParam,
203 ZigClangType_ObjCObject,
204 ZigClangType_ObjCInterface,
205 ZigClangType_ObjCObjectPointer,
206 ZigClangType_Pipe,
207 ZigClangType_Atomic,
208};
209
210enum ZigClangStmtClass {
211 ZigClangStmt_NoStmtClass = 0,
212 ZigClangStmt_GCCAsmStmtClass,
213 ZigClangStmt_MSAsmStmtClass,
214 ZigClangStmt_AttributedStmtClass,
215 ZigClangStmt_BreakStmtClass,
216 ZigClangStmt_CXXCatchStmtClass,
217 ZigClangStmt_CXXForRangeStmtClass,
218 ZigClangStmt_CXXTryStmtClass,
219 ZigClangStmt_CapturedStmtClass,
220 ZigClangStmt_CompoundStmtClass,
221 ZigClangStmt_ContinueStmtClass,
222 ZigClangStmt_CoreturnStmtClass,
223 ZigClangStmt_CoroutineBodyStmtClass,
224 ZigClangStmt_DeclStmtClass,
225 ZigClangStmt_DoStmtClass,
226 ZigClangStmt_BinaryConditionalOperatorClass,
227 ZigClangStmt_ConditionalOperatorClass,
228 ZigClangStmt_AddrLabelExprClass,
229 ZigClangStmt_ArrayInitIndexExprClass,
230 ZigClangStmt_ArrayInitLoopExprClass,
231 ZigClangStmt_ArraySubscriptExprClass,
232 ZigClangStmt_ArrayTypeTraitExprClass,
233 ZigClangStmt_AsTypeExprClass,
234 ZigClangStmt_AtomicExprClass,
235 ZigClangStmt_BinaryOperatorClass,
236 ZigClangStmt_CompoundAssignOperatorClass,
237 ZigClangStmt_BlockExprClass,
238 ZigClangStmt_CXXBindTemporaryExprClass,
239 ZigClangStmt_CXXBoolLiteralExprClass,
240 ZigClangStmt_CXXConstructExprClass,
241 ZigClangStmt_CXXTemporaryObjectExprClass,
242 ZigClangStmt_CXXDefaultArgExprClass,
243 ZigClangStmt_CXXDefaultInitExprClass,
244 ZigClangStmt_CXXDeleteExprClass,
245 ZigClangStmt_CXXDependentScopeMemberExprClass,
246 ZigClangStmt_CXXFoldExprClass,
247 ZigClangStmt_CXXInheritedCtorInitExprClass,
248 ZigClangStmt_CXXNewExprClass,
249 ZigClangStmt_CXXNoexceptExprClass,
250 ZigClangStmt_CXXNullPtrLiteralExprClass,
251 ZigClangStmt_CXXPseudoDestructorExprClass,
252 ZigClangStmt_CXXScalarValueInitExprClass,
253 ZigClangStmt_CXXStdInitializerListExprClass,
254 ZigClangStmt_CXXThisExprClass,
255 ZigClangStmt_CXXThrowExprClass,
256 ZigClangStmt_CXXTypeidExprClass,
257 ZigClangStmt_CXXUnresolvedConstructExprClass,
258 ZigClangStmt_CXXUuidofExprClass,
259 ZigClangStmt_CallExprClass,
260 ZigClangStmt_CUDAKernelCallExprClass,
261 ZigClangStmt_CXXMemberCallExprClass,
262 ZigClangStmt_CXXOperatorCallExprClass,
263 ZigClangStmt_UserDefinedLiteralClass,
264 ZigClangStmt_CStyleCastExprClass,
265 ZigClangStmt_CXXFunctionalCastExprClass,
266 ZigClangStmt_CXXConstCastExprClass,
267 ZigClangStmt_CXXDynamicCastExprClass,
268 ZigClangStmt_CXXReinterpretCastExprClass,
269 ZigClangStmt_CXXStaticCastExprClass,
270 ZigClangStmt_ObjCBridgedCastExprClass,
271 ZigClangStmt_ImplicitCastExprClass,
272 ZigClangStmt_CharacterLiteralClass,
273 ZigClangStmt_ChooseExprClass,
274 ZigClangStmt_CompoundLiteralExprClass,
275 ZigClangStmt_ConvertVectorExprClass,
276 ZigClangStmt_CoawaitExprClass,
277 ZigClangStmt_CoyieldExprClass,
278 ZigClangStmt_DeclRefExprClass,
279 ZigClangStmt_DependentCoawaitExprClass,
280 ZigClangStmt_DependentScopeDeclRefExprClass,
281 ZigClangStmt_DesignatedInitExprClass,
282 ZigClangStmt_DesignatedInitUpdateExprClass,
283 ZigClangStmt_ExpressionTraitExprClass,
284 ZigClangStmt_ExtVectorElementExprClass,
285 ZigClangStmt_FixedPointLiteralClass,
286 ZigClangStmt_FloatingLiteralClass,
287 ZigClangStmt_ConstantExprClass,
288 ZigClangStmt_ExprWithCleanupsClass,
289 ZigClangStmt_FunctionParmPackExprClass,
290 ZigClangStmt_GNUNullExprClass,
291 ZigClangStmt_GenericSelectionExprClass,
292 ZigClangStmt_ImaginaryLiteralClass,
293 ZigClangStmt_ImplicitValueInitExprClass,
294 ZigClangStmt_InitListExprClass,
295 ZigClangStmt_IntegerLiteralClass,
296 ZigClangStmt_LambdaExprClass,
297 ZigClangStmt_MSPropertyRefExprClass,
298 ZigClangStmt_MSPropertySubscriptExprClass,
299 ZigClangStmt_MaterializeTemporaryExprClass,
300 ZigClangStmt_MemberExprClass,
301 ZigClangStmt_NoInitExprClass,
302 ZigClangStmt_OMPArraySectionExprClass,
303 ZigClangStmt_ObjCArrayLiteralClass,
304 ZigClangStmt_ObjCAvailabilityCheckExprClass,
305 ZigClangStmt_ObjCBoolLiteralExprClass,
306 ZigClangStmt_ObjCBoxedExprClass,
307 ZigClangStmt_ObjCDictionaryLiteralClass,
308 ZigClangStmt_ObjCEncodeExprClass,
309 ZigClangStmt_ObjCIndirectCopyRestoreExprClass,
310 ZigClangStmt_ObjCIsaExprClass,
311 ZigClangStmt_ObjCIvarRefExprClass,
312 ZigClangStmt_ObjCMessageExprClass,
313 ZigClangStmt_ObjCPropertyRefExprClass,
314 ZigClangStmt_ObjCProtocolExprClass,
315 ZigClangStmt_ObjCSelectorExprClass,
316 ZigClangStmt_ObjCStringLiteralClass,
317 ZigClangStmt_ObjCSubscriptRefExprClass,
318 ZigClangStmt_OffsetOfExprClass,
319 ZigClangStmt_OpaqueValueExprClass,
320 ZigClangStmt_UnresolvedLookupExprClass,
321 ZigClangStmt_UnresolvedMemberExprClass,
322 ZigClangStmt_PackExpansionExprClass,
323 ZigClangStmt_ParenExprClass,
324 ZigClangStmt_ParenListExprClass,
325 ZigClangStmt_PredefinedExprClass,
326 ZigClangStmt_PseudoObjectExprClass,
327 ZigClangStmt_ShuffleVectorExprClass,
328 ZigClangStmt_SizeOfPackExprClass,
329 ZigClangStmt_StmtExprClass,
330 ZigClangStmt_StringLiteralClass,
331 ZigClangStmt_SubstNonTypeTemplateParmExprClass,
332 ZigClangStmt_SubstNonTypeTemplateParmPackExprClass,
333 ZigClangStmt_TypeTraitExprClass,
334 ZigClangStmt_TypoExprClass,
335 ZigClangStmt_UnaryExprOrTypeTraitExprClass,
336 ZigClangStmt_UnaryOperatorClass,
337 ZigClangStmt_VAArgExprClass,
338 ZigClangStmt_ForStmtClass,
339 ZigClangStmt_GotoStmtClass,
340 ZigClangStmt_IfStmtClass,
341 ZigClangStmt_IndirectGotoStmtClass,
342 ZigClangStmt_LabelStmtClass,
343 ZigClangStmt_MSDependentExistsStmtClass,
344 ZigClangStmt_NullStmtClass,
345 ZigClangStmt_OMPAtomicDirectiveClass,
346 ZigClangStmt_OMPBarrierDirectiveClass,
347 ZigClangStmt_OMPCancelDirectiveClass,
348 ZigClangStmt_OMPCancellationPointDirectiveClass,
349 ZigClangStmt_OMPCriticalDirectiveClass,
350 ZigClangStmt_OMPFlushDirectiveClass,
351 ZigClangStmt_OMPDistributeDirectiveClass,
352 ZigClangStmt_OMPDistributeParallelForDirectiveClass,
353 ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass,
354 ZigClangStmt_OMPDistributeSimdDirectiveClass,
355 ZigClangStmt_OMPForDirectiveClass,
356 ZigClangStmt_OMPForSimdDirectiveClass,
357 ZigClangStmt_OMPParallelForDirectiveClass,
358 ZigClangStmt_OMPParallelForSimdDirectiveClass,
359 ZigClangStmt_OMPSimdDirectiveClass,
360 ZigClangStmt_OMPTargetParallelForSimdDirectiveClass,
361 ZigClangStmt_OMPTargetSimdDirectiveClass,
362 ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass,
363 ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass,
364 ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
365 ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass,
366 ZigClangStmt_OMPTaskLoopDirectiveClass,
367 ZigClangStmt_OMPTaskLoopSimdDirectiveClass,
368 ZigClangStmt_OMPTeamsDistributeDirectiveClass,
369 ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass,
370 ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass,
371 ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass,
372 ZigClangStmt_OMPMasterDirectiveClass,
373 ZigClangStmt_OMPOrderedDirectiveClass,
374 ZigClangStmt_OMPParallelDirectiveClass,
375 ZigClangStmt_OMPParallelSectionsDirectiveClass,
376 ZigClangStmt_OMPSectionDirectiveClass,
377 ZigClangStmt_OMPSectionsDirectiveClass,
378 ZigClangStmt_OMPSingleDirectiveClass,
379 ZigClangStmt_OMPTargetDataDirectiveClass,
380 ZigClangStmt_OMPTargetDirectiveClass,
381 ZigClangStmt_OMPTargetEnterDataDirectiveClass,
382 ZigClangStmt_OMPTargetExitDataDirectiveClass,
383 ZigClangStmt_OMPTargetParallelDirectiveClass,
384 ZigClangStmt_OMPTargetParallelForDirectiveClass,
385 ZigClangStmt_OMPTargetTeamsDirectiveClass,
386 ZigClangStmt_OMPTargetUpdateDirectiveClass,
387 ZigClangStmt_OMPTaskDirectiveClass,
388 ZigClangStmt_OMPTaskgroupDirectiveClass,
389 ZigClangStmt_OMPTaskwaitDirectiveClass,
390 ZigClangStmt_OMPTaskyieldDirectiveClass,
391 ZigClangStmt_OMPTeamsDirectiveClass,
392 ZigClangStmt_ObjCAtCatchStmtClass,
393 ZigClangStmt_ObjCAtFinallyStmtClass,
394 ZigClangStmt_ObjCAtSynchronizedStmtClass,
395 ZigClangStmt_ObjCAtThrowStmtClass,
396 ZigClangStmt_ObjCAtTryStmtClass,
397 ZigClangStmt_ObjCAutoreleasePoolStmtClass,
398 ZigClangStmt_ObjCForCollectionStmtClass,
399 ZigClangStmt_ReturnStmtClass,
400 ZigClangStmt_SEHExceptStmtClass,
401 ZigClangStmt_SEHFinallyStmtClass,
402 ZigClangStmt_SEHLeaveStmtClass,
403 ZigClangStmt_SEHTryStmtClass,
404 ZigClangStmt_CaseStmtClass,
405 ZigClangStmt_DefaultStmtClass,
406 ZigClangStmt_SwitchStmtClass,
407 ZigClangStmt_WhileStmtClass,
408};
409
410enum ZigClangCK {
411 ZigClangCK_Dependent,
412 ZigClangCK_BitCast,
413 ZigClangCK_LValueBitCast,
414 ZigClangCK_LValueToRValue,
415 ZigClangCK_NoOp,
416 ZigClangCK_BaseToDerived,
417 ZigClangCK_DerivedToBase,
418 ZigClangCK_UncheckedDerivedToBase,
419 ZigClangCK_Dynamic,
420 ZigClangCK_ToUnion,
421 ZigClangCK_ArrayToPointerDecay,
422 ZigClangCK_FunctionToPointerDecay,
423 ZigClangCK_NullToPointer,
424 ZigClangCK_NullToMemberPointer,
425 ZigClangCK_BaseToDerivedMemberPointer,
426 ZigClangCK_DerivedToBaseMemberPointer,
427 ZigClangCK_MemberPointerToBoolean,
428 ZigClangCK_ReinterpretMemberPointer,
429 ZigClangCK_UserDefinedConversion,
430 ZigClangCK_ConstructorConversion,
431 ZigClangCK_IntegralToPointer,
432 ZigClangCK_PointerToIntegral,
433 ZigClangCK_PointerToBoolean,
434 ZigClangCK_ToVoid,
435 ZigClangCK_VectorSplat,
436 ZigClangCK_IntegralCast,
437 ZigClangCK_IntegralToBoolean,
438 ZigClangCK_IntegralToFloating,
439 ZigClangCK_FixedPointCast,
440 ZigClangCK_FixedPointToBoolean,
441 ZigClangCK_FloatingToIntegral,
442 ZigClangCK_FloatingToBoolean,
443 ZigClangCK_BooleanToSignedIntegral,
444 ZigClangCK_FloatingCast,
445 ZigClangCK_CPointerToObjCPointerCast,
446 ZigClangCK_BlockPointerToObjCPointerCast,
447 ZigClangCK_AnyPointerToBlockPointerCast,
448 ZigClangCK_ObjCObjectLValueCast,
449 ZigClangCK_FloatingRealToComplex,
450 ZigClangCK_FloatingComplexToReal,
451 ZigClangCK_FloatingComplexToBoolean,
452 ZigClangCK_FloatingComplexCast,
453 ZigClangCK_FloatingComplexToIntegralComplex,
454 ZigClangCK_IntegralRealToComplex,
455 ZigClangCK_IntegralComplexToReal,
456 ZigClangCK_IntegralComplexToBoolean,
457 ZigClangCK_IntegralComplexCast,
458 ZigClangCK_IntegralComplexToFloatingComplex,
459 ZigClangCK_ARCProduceObject,
460 ZigClangCK_ARCConsumeObject,
461 ZigClangCK_ARCReclaimReturnedObject,
462 ZigClangCK_ARCExtendBlockObject,
463 ZigClangCK_AtomicToNonAtomic,
464 ZigClangCK_NonAtomicToAtomic,
465 ZigClangCK_CopyAndAutoreleaseBlockObject,
466 ZigClangCK_BuiltinFnToFnPtr,
467 ZigClangCK_ZeroToOCLOpaqueType,
468 ZigClangCK_AddressSpaceConversion,
469 ZigClangCK_IntToOCLSampler,
470};
471
472enum ZigClangAPValueKind {
473 ZigClangAPValueUninitialized,
474 ZigClangAPValueInt,
475 ZigClangAPValueFloat,
476 ZigClangAPValueComplexInt,
477 ZigClangAPValueComplexFloat,
478 ZigClangAPValueLValue,
479 ZigClangAPValueVector,
480 ZigClangAPValueArray,
481 ZigClangAPValueStruct,
482 ZigClangAPValueUnion,
483 ZigClangAPValueMemberPointer,
484 ZigClangAPValueAddrLabelDiff,
485};
486
487enum ZigClangDeclKind {
488 ZigClangDeclAccessSpec,
489 ZigClangDeclBlock,
490 ZigClangDeclCaptured,
491 ZigClangDeclClassScopeFunctionSpecialization,
492 ZigClangDeclEmpty,
493 ZigClangDeclExport,
494 ZigClangDeclExternCContext,
495 ZigClangDeclFileScopeAsm,
496 ZigClangDeclFriend,
497 ZigClangDeclFriendTemplate,
498 ZigClangDeclImport,
499 ZigClangDeclLinkageSpec,
500 ZigClangDeclLabel,
501 ZigClangDeclNamespace,
502 ZigClangDeclNamespaceAlias,
503 ZigClangDeclObjCCompatibleAlias,
504 ZigClangDeclObjCCategory,
505 ZigClangDeclObjCCategoryImpl,
506 ZigClangDeclObjCImplementation,
507 ZigClangDeclObjCInterface,
508 ZigClangDeclObjCProtocol,
509 ZigClangDeclObjCMethod,
510 ZigClangDeclObjCProperty,
511 ZigClangDeclBuiltinTemplate,
512 ZigClangDeclClassTemplate,
513 ZigClangDeclFunctionTemplate,
514 ZigClangDeclTypeAliasTemplate,
515 ZigClangDeclVarTemplate,
516 ZigClangDeclTemplateTemplateParm,
517 ZigClangDeclEnum,
518 ZigClangDeclRecord,
519 ZigClangDeclCXXRecord,
520 ZigClangDeclClassTemplateSpecialization,
521 ZigClangDeclClassTemplatePartialSpecialization,
522 ZigClangDeclTemplateTypeParm,
523 ZigClangDeclObjCTypeParam,
524 ZigClangDeclTypeAlias,
525 ZigClangDeclTypedef,
526 ZigClangDeclUnresolvedUsingTypename,
527 ZigClangDeclUsing,
528 ZigClangDeclUsingDirective,
529 ZigClangDeclUsingPack,
530 ZigClangDeclUsingShadow,
531 ZigClangDeclConstructorUsingShadow,
532 ZigClangDeclBinding,
533 ZigClangDeclField,
534 ZigClangDeclObjCAtDefsField,
535 ZigClangDeclObjCIvar,
536 ZigClangDeclFunction,
537 ZigClangDeclCXXDeductionGuide,
538 ZigClangDeclCXXMethod,
539 ZigClangDeclCXXConstructor,
540 ZigClangDeclCXXConversion,
541 ZigClangDeclCXXDestructor,
542 ZigClangDeclMSProperty,
543 ZigClangDeclNonTypeTemplateParm,
544 ZigClangDeclVar,
545 ZigClangDeclDecomposition,
546 ZigClangDeclImplicitParam,
547 ZigClangDeclOMPCapturedExpr,
548 ZigClangDeclParmVar,
549 ZigClangDeclVarTemplateSpecialization,
550 ZigClangDeclVarTemplatePartialSpecialization,
551 ZigClangDeclEnumConstant,
552 ZigClangDeclIndirectField,
553 ZigClangDeclOMPDeclareReduction,
554 ZigClangDeclUnresolvedUsingValue,
555 ZigClangDeclOMPRequires,
556 ZigClangDeclOMPThreadPrivate,
557 ZigClangDeclObjCPropertyImpl,
558 ZigClangDeclPragmaComment,
559 ZigClangDeclPragmaDetectMismatch,
560 ZigClangDeclStaticAssert,
561 ZigClangDeclTranslationUnit,
562};
563
564enum ZigClangBuiltinTypeKind {
565 ZigClangBuiltinTypeOCLImage1dRO,
566 ZigClangBuiltinTypeOCLImage1dArrayRO,
567 ZigClangBuiltinTypeOCLImage1dBufferRO,
568 ZigClangBuiltinTypeOCLImage2dRO,
569 ZigClangBuiltinTypeOCLImage2dArrayRO,
570 ZigClangBuiltinTypeOCLImage2dDepthRO,
571 ZigClangBuiltinTypeOCLImage2dArrayDepthRO,
572 ZigClangBuiltinTypeOCLImage2dMSAARO,
573 ZigClangBuiltinTypeOCLImage2dArrayMSAARO,
574 ZigClangBuiltinTypeOCLImage2dMSAADepthRO,
575 ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRO,
576 ZigClangBuiltinTypeOCLImage3dRO,
577 ZigClangBuiltinTypeOCLImage1dWO,
578 ZigClangBuiltinTypeOCLImage1dArrayWO,
579 ZigClangBuiltinTypeOCLImage1dBufferWO,
580 ZigClangBuiltinTypeOCLImage2dWO,
581 ZigClangBuiltinTypeOCLImage2dArrayWO,
582 ZigClangBuiltinTypeOCLImage2dDepthWO,
583 ZigClangBuiltinTypeOCLImage2dArrayDepthWO,
584 ZigClangBuiltinTypeOCLImage2dMSAAWO,
585 ZigClangBuiltinTypeOCLImage2dArrayMSAAWO,
586 ZigClangBuiltinTypeOCLImage2dMSAADepthWO,
587 ZigClangBuiltinTypeOCLImage2dArrayMSAADepthWO,
588 ZigClangBuiltinTypeOCLImage3dWO,
589 ZigClangBuiltinTypeOCLImage1dRW,
590 ZigClangBuiltinTypeOCLImage1dArrayRW,
591 ZigClangBuiltinTypeOCLImage1dBufferRW,
592 ZigClangBuiltinTypeOCLImage2dRW,
593 ZigClangBuiltinTypeOCLImage2dArrayRW,
594 ZigClangBuiltinTypeOCLImage2dDepthRW,
595 ZigClangBuiltinTypeOCLImage2dArrayDepthRW,
596 ZigClangBuiltinTypeOCLImage2dMSAARW,
597 ZigClangBuiltinTypeOCLImage2dArrayMSAARW,
598 ZigClangBuiltinTypeOCLImage2dMSAADepthRW,
599 ZigClangBuiltinTypeOCLImage2dArrayMSAADepthRW,
600 ZigClangBuiltinTypeOCLImage3dRW,
601 ZigClangBuiltinTypeOCLIntelSubgroupAVCMcePayload,
602 ZigClangBuiltinTypeOCLIntelSubgroupAVCImePayload,
603 ZigClangBuiltinTypeOCLIntelSubgroupAVCRefPayload,
604 ZigClangBuiltinTypeOCLIntelSubgroupAVCSicPayload,
605 ZigClangBuiltinTypeOCLIntelSubgroupAVCMceResult,
606 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResult,
607 ZigClangBuiltinTypeOCLIntelSubgroupAVCRefResult,
608 ZigClangBuiltinTypeOCLIntelSubgroupAVCSicResult,
609 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultSingleRefStreamout,
610 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeResultDualRefStreamout,
611 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeSingleRefStreamin,
612 ZigClangBuiltinTypeOCLIntelSubgroupAVCImeDualRefStreamin,
613 ZigClangBuiltinTypeVoid,
614 ZigClangBuiltinTypeBool,
615 ZigClangBuiltinTypeChar_U,
616 ZigClangBuiltinTypeUChar,
617 ZigClangBuiltinTypeWChar_U,
618 ZigClangBuiltinTypeChar8,
619 ZigClangBuiltinTypeChar16,
620 ZigClangBuiltinTypeChar32,
621 ZigClangBuiltinTypeUShort,
622 ZigClangBuiltinTypeUInt,
623 ZigClangBuiltinTypeULong,
624 ZigClangBuiltinTypeULongLong,
625 ZigClangBuiltinTypeUInt128,
626 ZigClangBuiltinTypeChar_S,
627 ZigClangBuiltinTypeSChar,
628 ZigClangBuiltinTypeWChar_S,
629 ZigClangBuiltinTypeShort,
630 ZigClangBuiltinTypeInt,
631 ZigClangBuiltinTypeLong,
632 ZigClangBuiltinTypeLongLong,
633 ZigClangBuiltinTypeInt128,
634 ZigClangBuiltinTypeShortAccum,
635 ZigClangBuiltinTypeAccum,
636 ZigClangBuiltinTypeLongAccum,
637 ZigClangBuiltinTypeUShortAccum,
638 ZigClangBuiltinTypeUAccum,
639 ZigClangBuiltinTypeULongAccum,
640 ZigClangBuiltinTypeShortFract,
641 ZigClangBuiltinTypeFract,
642 ZigClangBuiltinTypeLongFract,
643 ZigClangBuiltinTypeUShortFract,
644 ZigClangBuiltinTypeUFract,
645 ZigClangBuiltinTypeULongFract,
646 ZigClangBuiltinTypeSatShortAccum,
647 ZigClangBuiltinTypeSatAccum,
648 ZigClangBuiltinTypeSatLongAccum,
649 ZigClangBuiltinTypeSatUShortAccum,
650 ZigClangBuiltinTypeSatUAccum,
651 ZigClangBuiltinTypeSatULongAccum,
652 ZigClangBuiltinTypeSatShortFract,
653 ZigClangBuiltinTypeSatFract,
654 ZigClangBuiltinTypeSatLongFract,
655 ZigClangBuiltinTypeSatUShortFract,
656 ZigClangBuiltinTypeSatUFract,
657 ZigClangBuiltinTypeSatULongFract,
658 ZigClangBuiltinTypeHalf,
659 ZigClangBuiltinTypeFloat,
660 ZigClangBuiltinTypeDouble,
661 ZigClangBuiltinTypeLongDouble,
662 ZigClangBuiltinTypeFloat16,
663 ZigClangBuiltinTypeFloat128,
664 ZigClangBuiltinTypeNullPtr,
665 ZigClangBuiltinTypeObjCId,
666 ZigClangBuiltinTypeObjCClass,
667 ZigClangBuiltinTypeObjCSel,
668 ZigClangBuiltinTypeOCLSampler,
669 ZigClangBuiltinTypeOCLEvent,
670 ZigClangBuiltinTypeOCLClkEvent,
671 ZigClangBuiltinTypeOCLQueue,
672 ZigClangBuiltinTypeOCLReserveID,
673 ZigClangBuiltinTypeDependent,
674 ZigClangBuiltinTypeOverload,
675 ZigClangBuiltinTypeBoundMember,
676 ZigClangBuiltinTypePseudoObject,
677 ZigClangBuiltinTypeUnknownAny,
678 ZigClangBuiltinTypeBuiltinFn,
679 ZigClangBuiltinTypeARCUnbridgedCast,
680 ZigClangBuiltinTypeOMPArraySection,
681};
682
683enum ZigClangCallingConv {
684 ZigClangCallingConv_C, // __attribute__((cdecl))
685 ZigClangCallingConv_X86StdCall, // __attribute__((stdcall))
686 ZigClangCallingConv_X86FastCall, // __attribute__((fastcall))
687 ZigClangCallingConv_X86ThisCall, // __attribute__((thiscall))
688 ZigClangCallingConv_X86VectorCall, // __attribute__((vectorcall))
689 ZigClangCallingConv_X86Pascal, // __attribute__((pascal))
690 ZigClangCallingConv_Win64, // __attribute__((ms_abi))
691 ZigClangCallingConv_X86_64SysV, // __attribute__((sysv_abi))
692 ZigClangCallingConv_X86RegCall, // __attribute__((regcall))
693 ZigClangCallingConv_AAPCS, // __attribute__((pcs("aapcs")))
694 ZigClangCallingConv_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
695 ZigClangCallingConv_IntelOclBicc, // __attribute__((intel_ocl_bicc))
696 ZigClangCallingConv_SpirFunction, // default for OpenCL functions on SPIR target
697 ZigClangCallingConv_OpenCLKernel, // inferred for OpenCL kernels
698 ZigClangCallingConv_Swift, // __attribute__((swiftcall))
699 ZigClangCallingConv_PreserveMost, // __attribute__((preserve_most))
700 ZigClangCallingConv_PreserveAll, // __attribute__((preserve_all))
701 ZigClangCallingConv_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
702};
703
704enum ZigClangStorageClass {
705 // These are legal on both functions and variables.
706 ZigClangStorageClass_None,
707 ZigClangStorageClass_Extern,
708 ZigClangStorageClass_Static,
709 ZigClangStorageClass_PrivateExtern,
710
711 // These are only legal on variables.
712 ZigClangStorageClass_Auto,
713 ZigClangStorageClass_Register,
714};
715
716ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,
717 struct ZigClangSourceLocation Loc);
718ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *,
719 struct ZigClangSourceLocation SpellingLoc);
720ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const struct ZigClangSourceManager *,
721 struct ZigClangSourceLocation Loc);
722ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const struct ZigClangSourceManager *,
723 struct ZigClangSourceLocation Loc);
724ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct ZigClangSourceManager *,
725 struct ZigClangSourceLocation SL);
726
727ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);
728
729
730// Can return null.
731ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,
732 struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path);
733ZIG_EXTERN_C void ZigClangASTUnit_delete(struct ZigClangASTUnit *);
734ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len);
735
736ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);
737ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *);
738ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context,
739 bool (*Fn)(void *context, const struct ZigClangDecl *decl));
740
741ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty);
742ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struct ZigClangEnumType *record_ty);
743
744ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);
745ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);
746ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
747
748ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
749ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
750
751ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangRecordDecl_getLocation(const struct ZigClangRecordDecl *);
752ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangEnumDecl_getLocation(const struct ZigClangEnumDecl *);
753ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const struct ZigClangTypedefNameDecl *);
754ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangDecl_getLocation(const struct ZigClangDecl *);
755
756ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionDecl_getType(const struct ZigClangFunctionDecl *);
757ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFunctionDecl_getLocation(const struct ZigClangFunctionDecl *);
758ZIG_EXTERN_C bool ZigClangFunctionDecl_hasBody(const struct ZigClangFunctionDecl *);
759ZIG_EXTERN_C enum ZigClangStorageClass ZigClangFunctionDecl_getStorageClass(const struct ZigClangFunctionDecl *);
760ZIG_EXTERN_C const struct ZigClangParmVarDecl *ZigClangFunctionDecl_getParamDecl(const struct ZigClangFunctionDecl *, unsigned i);
761ZIG_EXTERN_C const struct ZigClangStmt *ZigClangFunctionDecl_getBody(const struct ZigClangFunctionDecl *);
762
763ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
764ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
765ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const struct ZigClangRecordDecl *record_decl);
766
767ZIG_EXTERN_C struct ZigClangQualType ZigClangEnumDecl_getIntegerType(const struct ZigClangEnumDecl *);
768
769ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangDecl *decl);
770ZIG_EXTERN_C enum ZigClangDeclKind ZigClangDecl_getKind(const struct ZigClangDecl *decl);
771ZIG_EXTERN_C const char *ZigClangDecl_getDeclKindName(const struct ZigClangDecl *decl);
772
773ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
774
775ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);
776ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const struct ZigClangTypedefNameDecl *);
777
778ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType);
779ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType);
780ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *);
781ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType);
782ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType);
783ZIG_EXTERN_C bool ZigClangQualType_isVolatileQualified(struct ZigClangQualType);
784ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
785
786ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
787ZIG_EXTERN_C struct ZigClangQualType ZigClangType_getPointeeType(const struct ZigClangType *self);
788ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
789ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);
790
791ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangStmt_getBeginLoc(const struct ZigClangStmt *self);
792ZIG_EXTERN_C enum ZigClangStmtClass ZigClangStmt_getStmtClass(const struct ZigClangStmt *self);
793ZIG_EXTERN_C bool ZigClangStmt_classof_Expr(const struct ZigClangStmt *self);
794
795ZIG_EXTERN_C enum ZigClangStmtClass ZigClangExpr_getStmtClass(const struct ZigClangExpr *self);
796ZIG_EXTERN_C struct ZigClangQualType ZigClangExpr_getType(const struct ZigClangExpr *self);
797ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangExpr_getBeginLoc(const struct ZigClangExpr *self);
798
799ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self);
800ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self);
801ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self);
802ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const struct ZigClangAPValue *self, unsigned i);
803ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayFiller(const struct ZigClangAPValue *self);
804ZIG_EXTERN_C unsigned ZigClangAPValue_getArraySize(const struct ZigClangAPValue *self);
805ZIG_EXTERN_C struct ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const struct ZigClangAPValue *self);
806
807ZIG_EXTERN_C bool ZigClangAPSInt_isSigned(const struct ZigClangAPSInt *self);
808ZIG_EXTERN_C bool ZigClangAPSInt_isNegative(const struct ZigClangAPSInt *self);
809ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPSInt_negate(const struct ZigClangAPSInt *self);
810ZIG_EXTERN_C void ZigClangAPSInt_free(const struct ZigClangAPSInt *self);
811ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const struct ZigClangAPSInt *self);
812ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const struct ZigClangAPSInt *self);
813
814ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(struct ZigClangAPValueLValueBase self);
815
816ZIG_EXTERN_C enum ZigClangBuiltinTypeKind ZigClangBuiltinType_getKind(const struct ZigClangBuiltinType *self);
817
818ZIG_EXTERN_C bool ZigClangFunctionType_getNoReturnAttr(const struct ZigClangFunctionType *self);
819ZIG_EXTERN_C enum ZigClangCallingConv ZigClangFunctionType_getCallConv(const struct ZigClangFunctionType *self);
820ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionType_getReturnType(const struct ZigClangFunctionType *self);
821
822ZIG_EXTERN_C bool ZigClangFunctionProtoType_isVariadic(const struct ZigClangFunctionProtoType *self);
823ZIG_EXTERN_C unsigned ZigClangFunctionProtoType_getNumParams(const struct ZigClangFunctionProtoType *self);
824ZIG_EXTERN_C struct ZigClangQualType ZigClangFunctionProtoType_getParamType(const struct ZigClangFunctionProtoType *self, unsigned i);
825
826
827ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_begin(const struct ZigClangCompoundStmt *self);
828ZIG_EXTERN_C ZigClangCompoundStmt_const_body_iterator ZigClangCompoundStmt_body_end(const struct ZigClangCompoundStmt *self);
829
259830#endif
std/array_list.zig+38
......@@ -111,6 +111,17 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
111111 new_item_ptr.* = item;
112112 }
113113
114 pub fn orderedRemove(self: *Self, i: usize) T {
115 const newlen = self.len - 1;
116 if (newlen == i) return self.pop();
117
118 const old_item = self.at(i);
119 for (self.items[i..newlen]) |*b, j| b.* = self.items[i + 1 + j];
120 self.items[newlen] = undefined;
121 self.len = newlen;
122 return old_item;
123 }
124
114125 /// Removes the element at the specified index and returns it.
115126 /// The empty slot is filled from the end of the list.
116127 pub fn swapRemove(self: *Self, i: usize) T {
......@@ -279,6 +290,33 @@ test "std.ArrayList.basic" {
279290 testing.expect(list.pop() == 33);
280291}
281292
293test "std.ArrayList.orderedRemove" {
294 var list = ArrayList(i32).init(debug.global_allocator);
295 defer list.deinit();
296
297 try list.append(1);
298 try list.append(2);
299 try list.append(3);
300 try list.append(4);
301 try list.append(5);
302 try list.append(6);
303 try list.append(7);
304
305 //remove from middle
306 testing.expectEqual(i32(4), list.orderedRemove(3));
307 testing.expectEqual(i32(5), list.at(3));
308 testing.expectEqual(usize(6), list.len);
309
310 //remove from end
311 testing.expectEqual(i32(7), list.orderedRemove(5));
312 testing.expectEqual(usize(5), list.len);
313
314 //remove from front
315 testing.expectEqual(i32(1), list.orderedRemove(0));
316 testing.expectEqual(i32(2), list.at(0));
317 testing.expectEqual(usize(4), list.len);
318}
319
282320test "std.ArrayList.swapRemove" {
283321 var list = ArrayList(i32).init(debug.global_allocator);
284322 defer list.deinit();
std/build.zig+27
......@@ -50,6 +50,8 @@ pub const Builder = struct {
5050 build_root: []const u8,
5151 cache_root: []const u8,
5252 release_mode: ?builtin.Mode,
53 override_std_dir: ?[]const u8,
54 override_lib_dir: ?[]const u8,
5355
5456 pub const CStd = enum {
5557 C89,
......@@ -133,6 +135,8 @@ pub const Builder = struct {
133135 },
134136 .have_install_step = false,
135137 .release_mode = null,
138 .override_std_dir = null,
139 .override_lib_dir = null,
136140 };
137141 self.detectNativeSystemPaths();
138142 self.default_step = self.step("default", "Build the project");
......@@ -937,8 +941,11 @@ pub const LibExeObjStep = struct {
937941 verbose_link: bool,
938942 verbose_cc: bool,
939943 disable_gen_h: bool,
944 bundle_compiler_rt: bool,
945 disable_stack_probing: bool,
940946 c_std: Builder.CStd,
941947 override_std_dir: ?[]const u8,
948 override_lib_dir: ?[]const u8,
942949 main_pkg_path: ?[]const u8,
943950 exec_cmd_args: ?[]const ?[]const u8,
944951 name_prefix: []const u8,
......@@ -1039,11 +1046,14 @@ pub const LibExeObjStep = struct {
10391046 .c_std = Builder.CStd.C99,
10401047 .system_linker_hack = false,
10411048 .override_std_dir = null,
1049 .override_lib_dir = null,
10421050 .main_pkg_path = null,
10431051 .exec_cmd_args = null,
10441052 .name_prefix = "",
10451053 .filter = null,
10461054 .disable_gen_h = false,
1055 .bundle_compiler_rt = false,
1056 .disable_stack_probing = false,
10471057 .output_dir = null,
10481058 .need_system_paths = false,
10491059 .single_threaded = false,
......@@ -1446,6 +1456,12 @@ pub const LibExeObjStep = struct {
14461456 if (self.disable_gen_h) {
14471457 try zig_args.append("--disable-gen-h");
14481458 }
1459 if (self.bundle_compiler_rt) {
1460 try zig_args.append("--bundle-compiler-rt");
1461 }
1462 if (self.disable_stack_probing) {
1463 try zig_args.append("--disable-stack-probing");
1464 }
14491465
14501466 switch (self.target) {
14511467 Target.Native => {},
......@@ -1528,6 +1544,17 @@ pub const LibExeObjStep = struct {
15281544 if (self.override_std_dir) |dir| {
15291545 try zig_args.append("--override-std-dir");
15301546 try zig_args.append(builder.pathFromRoot(dir));
1547 } else if (self.builder.override_std_dir) |dir| {
1548 try zig_args.append("--override-std-dir");
1549 try zig_args.append(builder.pathFromRoot(dir));
1550 }
1551
1552 if (self.override_lib_dir) |dir| {
1553 try zig_args.append("--override-lib-dir");
1554 try zig_args.append(builder.pathFromRoot(dir));
1555 } else if (self.builder.override_lib_dir) |dir| {
1556 try zig_args.append("--override-lib-dir");
1557 try zig_args.append(builder.pathFromRoot(dir));
15311558 }
15321559
15331560 if (self.main_pkg_path) |dir| {
std/c.zig+6
......@@ -12,6 +12,12 @@ pub use switch (builtin.os) {
1212
1313// TODO https://github.com/ziglang/zig/issues/265 on this whole file
1414
15pub const FILE = @OpaqueType();
16pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;
17pub extern "c" fn fclose(stream: *FILE) c_int;
18pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
19pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
20
1521pub extern "c" fn abort() noreturn;
1622pub extern "c" fn exit(code: c_int) noreturn;
1723pub extern "c" fn isatty(fd: c_int) c_int;
std/c/freebsd.zig+27-5
......@@ -42,14 +42,36 @@ pub const pthread_attr_t = extern struct {
4242};
4343
4444pub const msghdr = extern struct {
45 msg_name: *u8,
45 /// optional address
46 msg_name: ?*sockaddr,
47 /// size of address
4648 msg_namelen: socklen_t,
47 msg_iov: *iovec,
49 /// scatter/gather array
50 msg_iov: [*]iovec,
51 /// # elements in msg_iov
4852 msg_iovlen: i32,
49 __pad1: i32,
50 msg_control: *u8,
53 /// ancillary data
54 msg_control: ?*c_void,
55 /// ancillary data buffer len
5156 msg_controllen: socklen_t,
52 __pad2: socklen_t,
57 /// flags on received message
58 msg_flags: i32,
59};
60
61pub const msghdr_const = extern struct {
62 /// optional address
63 msg_name: ?*const sockaddr,
64 /// size of address
65 msg_namelen: socklen_t,
66 /// scatter/gather array
67 msg_iov: [*]iovec_const,
68 /// # elements in msg_iov
69 msg_iovlen: i32,
70 /// ancillary data
71 msg_control: ?*c_void,
72 /// ancillary data buffer len
73 msg_controllen: socklen_t,
74 /// flags on received message
5375 msg_flags: i32,
5476};
5577
std/c/linux.zig+4
......@@ -1,3 +1,4 @@
1const linux = @import("../os/linux.zig");
12pub use @import("../os/linux/errno.zig");
23
34pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
......@@ -11,3 +12,6 @@ pub const pthread_attr_t = extern struct {
1112
1213/// See std.elf for constants for this
1314pub extern fn getauxval(__type: c_ulong) c_ulong;
15
16pub const dl_iterate_phdr_callback = extern fn (info: *linux.dl_phdr_info, size: usize, data: ?*c_void) c_int;
17pub extern fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
std/c/netbsd.zig+27-5
......@@ -42,14 +42,36 @@ pub const pthread_attr_t = extern struct {
4242};
4343
4444pub const msghdr = extern struct {
45 msg_name: *u8,
45 /// optional address
46 msg_name: ?*sockaddr,
47 /// size of address
4648 msg_namelen: socklen_t,
47 msg_iov: *iovec,
49 /// scatter/gather array
50 msg_iov: [*]iovec,
51 /// # elements in msg_iov
4852 msg_iovlen: i32,
49 __pad1: i32,
50 msg_control: *u8,
53 /// ancillary data
54 msg_control: ?*c_void,
55 /// ancillary data buffer len
5156 msg_controllen: socklen_t,
52 __pad2: socklen_t,
57 /// flags on received message
58 msg_flags: i32,
59};
60
61pub const msghdr_const = extern struct {
62 /// optional address
63 msg_name: ?*const sockaddr,
64 /// size of address
65 msg_namelen: socklen_t,
66 /// scatter/gather array
67 msg_iov: [*]iovec_const,
68 /// # elements in msg_iov
69 msg_iovlen: i32,
70 /// ancillary data
71 msg_control: ?*c_void,
72 /// ancillary data buffer len
73 msg_controllen: socklen_t,
74 /// flags on received message
5375 msg_flags: i32,
5476};
5577
std/crypto/chacha20.zig+3-2
......@@ -142,7 +142,7 @@ pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]
142142 assert(in.len >= out.len);
143143 assert(counter +% (in.len >> 6) >= counter);
144144
145 var cursor: u64 = 0;
145 var cursor: usize = 0;
146146 var k: [8]u32 = undefined;
147147 var c: [4]u32 = undefined;
148148
......@@ -161,7 +161,8 @@ pub fn chaCha20With64BitNonce(out: []u8, in: []const u8, counter: u64, key: [32]
161161 c[3] = mem.readIntSliceLittle(u32, nonce[4..8]);
162162
163163 const block_size = (1 << 6);
164 const big_block = (block_size << 32);
164 // The full block size is greater than the address space on a 32bit machine
165 const big_block = if (@sizeOf(usize) > 4) (block_size << 32) else maxInt(usize);
165166
166167 // first partial big block
167168 if (((@intCast(u64, maxInt(u32) - @truncate(u32, counter)) + 1) << 6) < in.len) {
std/debug.zig+344-286
......@@ -13,6 +13,8 @@ const ArrayList = std.ArrayList;
1313const builtin = @import("builtin");
1414const maxInt = std.math.maxInt;
1515
16const leb = @import("debug/leb128.zig");
17
1618pub const FailingAllocator = @import("debug/failing_allocator.zig").FailingAllocator;
1719pub const failing_allocator = &FailingAllocator.init(global_allocator, 0).allocator;
1820
......@@ -214,14 +216,14 @@ pub fn writeStackTrace(
214216 tty_color: bool,
215217) !void {
216218 var frame_index: usize = 0;
217 var frames_left: usize = stack_trace.index;
219 var frames_left: usize = std.math.min(stack_trace.index, stack_trace.instruction_addresses.len);
218220
219221 while (frames_left != 0) : ({
220222 frames_left -= 1;
221223 frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len;
222224 }) {
223225 const return_address = stack_trace.instruction_addresses[frame_index];
224 try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
226 try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color);
225227 }
226228}
227229
......@@ -263,7 +265,7 @@ pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color
263265 }
264266 var it = StackIterator.init(start_addr);
265267 while (it.next()) |return_address| {
266 try printSourceAtAddress(debug_info, out_stream, return_address, tty_color);
268 try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color);
267269 }
268270}
269271
......@@ -376,7 +378,6 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres
376378 // There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)
377379 // from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,
378380 // breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
379
380381 const subsection_end_index = sect_offset + subsect_hdr.Length;
381382
382383 while (line_index < subsection_end_index) {
......@@ -690,9 +691,9 @@ pub fn printSourceAtAddressDwarf(
690691 return;
691692 };
692693 const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name);
693 if (getLineNumberInfoDwarf(debug_info, compile_unit.*, address - 1)) |line_info| {
694 if (getLineNumberInfoDwarf(debug_info, compile_unit.*, address)) |line_info| {
694695 defer line_info.deinit();
695 const symbol_name = "???";
696 const symbol_name = getSymbolNameDwarf(debug_info, address) orelse "???";
696697 try printLineInfo(
697698 out_stream,
698699 line_info,
......@@ -969,6 +970,8 @@ fn findDwarfSectionFromElf(elf_file: *elf.Elf, name: []const u8) !?DwarfInfo.Sec
969970pub fn openDwarfDebugInfo(di: *DwarfInfo, allocator: *mem.Allocator) !void {
970971 di.abbrev_table_list = ArrayList(AbbrevTableHeader).init(allocator);
971972 di.compile_unit_list = ArrayList(CompileUnit).init(allocator);
973 di.func_list = ArrayList(Func).init(allocator);
974 try scanAllFunctions(di);
972975 try scanAllCompileUnits(di);
973976}
974977
......@@ -992,6 +995,7 @@ pub fn openElfDebugInfo(
992995 .debug_ranges = (try findDwarfSectionFromElf(&efile, ".debug_ranges")),
993996 .abbrev_table_list = undefined,
994997 .compile_unit_list = undefined,
998 .func_list = undefined,
995999 };
9961000 try openDwarfDebugInfo(&di, allocator);
9971001 return di;
......@@ -1162,6 +1166,7 @@ pub const DwarfInfo = struct {
11621166 debug_ranges: ?Section,
11631167 abbrev_table_list: ArrayList(AbbrevTableHeader),
11641168 compile_unit_list: ArrayList(CompileUnit),
1169 func_list: ArrayList(Func),
11651170
11661171 pub const Section = struct {
11671172 offset: usize,
......@@ -1178,7 +1183,7 @@ pub const DwarfInfo = struct {
11781183};
11791184
11801185pub const DebugInfo = switch (builtin.os) {
1181 builtin.Os.macosx => struct {
1186 builtin.Os.macosx, builtin.Os.ios => struct {
11821187 symbols: []const MachoSymbol,
11831188 strings: []const u8,
11841189 ofiles: OFileTable,
......@@ -1213,7 +1218,6 @@ const CompileUnit = struct {
12131218 version: u16,
12141219 is_64: bool,
12151220 die: *Die,
1216 index: usize,
12171221 pc_range: ?PcRange,
12181222};
12191223
......@@ -1244,21 +1248,19 @@ const FormValue = union(enum) {
12441248 ExprLoc: []u8,
12451249 Flag: bool,
12461250 SecOffset: u64,
1247 Ref: []u8,
1251 Ref: u64,
12481252 RefAddr: u64,
1249 RefSig8: u64,
12501253 String: []u8,
12511254 StrPtr: u64,
12521255};
12531256
12541257const Constant = struct {
1255 payload: []u8,
1258 payload: u64,
12561259 signed: bool,
12571260
12581261 fn asUnsignedLe(self: *const Constant) !u64 {
1259 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;
12601262 if (self.signed) return error.InvalidDebugInfo;
1261 return mem.readVarInt(u64, self.payload, builtin.Endian.Little);
1263 return self.payload;
12621264 }
12631265};
12641266
......@@ -1304,6 +1306,14 @@ const Die = struct {
13041306 };
13051307 }
13061308
1309 fn getAttrRef(self: *const Die, id: u64) !u64 {
1310 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
1311 return switch (form_value.*) {
1312 FormValue.Ref => |value| value,
1313 else => error.InvalidDebugInfo,
1314 };
1315 }
1316
13071317 fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]u8 {
13081318 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
13091319 return switch (form_value.*) {
......@@ -1443,11 +1453,18 @@ fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, size: usize) !
14431453 return parseFormValueBlockLen(allocator, in_stream, block_len);
14441454}
14451455
1446fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, size: usize) !FormValue {
1456fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, comptime size: i32) !FormValue {
14471457 return FormValue{
14481458 .Const = Constant{
14491459 .signed = signed,
1450 .payload = try readAllocBytes(allocator, in_stream, size),
1460 .payload = switch (size) {
1461 1 => try in_stream.readIntLittle(u8),
1462 2 => try in_stream.readIntLittle(u16),
1463 4 => try in_stream.readIntLittle(u32),
1464 8 => try in_stream.readIntLittle(u64),
1465 -1 => if (signed) @bitCast(u64, try leb.readILEB128(i64, in_stream)) else try leb.readULEB128(u64, in_stream),
1466 else => @compileError("Invalid size"),
1467 },
14511468 },
14521469 };
14531470}
......@@ -1460,14 +1477,17 @@ fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
14601477 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLittle(u32)) else if (@sizeOf(usize) == 8) try in_stream.readIntLittle(u64) else unreachable;
14611478}
14621479
1463fn parseFormValueRefLen(allocator: *mem.Allocator, in_stream: var, size: usize) !FormValue {
1464 const buf = try readAllocBytes(allocator, in_stream, size);
1465 return FormValue{ .Ref = buf };
1466}
1467
1468fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, comptime T: type) !FormValue {
1469 const block_len = try in_stream.readIntLittle(T);
1470 return parseFormValueRefLen(allocator, in_stream, block_len);
1480fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, size: i32) !FormValue {
1481 return FormValue{
1482 .Ref = switch (size) {
1483 1 => try in_stream.readIntLittle(u8),
1484 2 => try in_stream.readIntLittle(u16),
1485 4 => try in_stream.readIntLittle(u32),
1486 8 => try in_stream.readIntLittle(u64),
1487 -1 => try leb.readULEB128(u64, in_stream),
1488 else => unreachable,
1489 },
1490 };
14711491}
14721492
14731493fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64: bool) anyerror!FormValue {
......@@ -1477,7 +1497,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
14771497 DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
14781498 DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
14791499 DW.FORM_block => x: {
1480 const block_len = try readULeb128(in_stream);
1500 const block_len = try leb.readULEB128(usize, in_stream);
14811501 return parseFormValueBlockLen(allocator, in_stream, block_len);
14821502 },
14831503 DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1),
......@@ -1485,12 +1505,11 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
14851505 DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4),
14861506 DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8),
14871507 DW.FORM_udata, DW.FORM_sdata => {
1488 const block_len = try readULeb128(in_stream);
14891508 const signed = form_id == DW.FORM_sdata;
1490 return parseFormValueConstant(allocator, in_stream, signed, block_len);
1509 return parseFormValueConstant(allocator, in_stream, signed, -1);
14911510 },
14921511 DW.FORM_exprloc => {
1493 const size = try readULeb128(in_stream);
1512 const size = try leb.readULEB128(usize, in_stream);
14941513 const buf = try readAllocBytes(allocator, in_stream, size);
14951514 return FormValue{ .ExprLoc = buf };
14961515 },
......@@ -1498,22 +1517,19 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
14981517 DW.FORM_flag_present => FormValue{ .Flag = true },
14991518 DW.FORM_sec_offset => FormValue{ .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
15001519
1501 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),
1502 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),
1503 DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32),
1504 DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64),
1505 DW.FORM_ref_udata => {
1506 const ref_len = try readULeb128(in_stream);
1507 return parseFormValueRefLen(allocator, in_stream, ref_len);
1508 },
1520 DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, 1),
1521 DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, 2),
1522 DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, 4),
1523 DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, 8),
1524 DW.FORM_ref_udata => parseFormValueRef(allocator, in_stream, -1),
15091525
15101526 DW.FORM_ref_addr => FormValue{ .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
1511 DW.FORM_ref_sig8 => FormValue{ .RefSig8 = try in_stream.readIntLittle(u64) },
1527 DW.FORM_ref_sig8 => FormValue{ .Ref = try in_stream.readIntLittle(u64) },
15121528
15131529 DW.FORM_string => FormValue{ .String = try readStringRaw(allocator, in_stream) },
15141530 DW.FORM_strp => FormValue{ .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
15151531 DW.FORM_indirect => {
1516 const child_form_id = try readULeb128(in_stream);
1532 const child_form_id = try leb.readULEB128(u64, in_stream);
15171533 return parseFormValue(allocator, in_stream, child_form_id, is_64);
15181534 },
15191535 else => error.InvalidDebugInfo,
......@@ -1523,19 +1539,19 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64
15231539fn parseAbbrevTable(di: *DwarfInfo) !AbbrevTable {
15241540 var result = AbbrevTable.init(di.allocator());
15251541 while (true) {
1526 const abbrev_code = try readULeb128(di.dwarf_in_stream);
1542 const abbrev_code = try leb.readULEB128(u64, di.dwarf_in_stream);
15271543 if (abbrev_code == 0) return result;
15281544 try result.append(AbbrevTableEntry{
15291545 .abbrev_code = abbrev_code,
1530 .tag_id = try readULeb128(di.dwarf_in_stream),
1546 .tag_id = try leb.readULEB128(u64, di.dwarf_in_stream),
15311547 .has_children = (try di.dwarf_in_stream.readByte()) == DW.CHILDREN_yes,
15321548 .attrs = ArrayList(AbbrevAttr).init(di.allocator()),
15331549 });
15341550 const attrs = &result.items[result.len - 1].attrs;
15351551
15361552 while (true) {
1537 const attr_id = try readULeb128(di.dwarf_in_stream);
1538 const form_id = try readULeb128(di.dwarf_in_stream);
1553 const attr_id = try leb.readULEB128(u64, di.dwarf_in_stream);
1554 const form_id = try leb.readULEB128(u64, di.dwarf_in_stream);
15391555 if (attr_id == 0 and form_id == 0) break;
15401556 try attrs.append(AbbrevAttr{
15411557 .attr_id = attr_id,
......@@ -1568,8 +1584,28 @@ fn getAbbrevTableEntry(abbrev_table: *const AbbrevTable, abbrev_code: u64) ?*con
15681584 return null;
15691585}
15701586
1587fn parseDie1(di: *DwarfInfo, abbrev_table: *const AbbrevTable, is_64: bool) !?Die {
1588 const abbrev_code = try leb.readULEB128(u64, di.dwarf_in_stream);
1589 if (abbrev_code == 0) return null;
1590 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) orelse return error.InvalidDebugInfo;
1591
1592 var result = Die{
1593 .tag_id = table_entry.tag_id,
1594 .has_children = table_entry.has_children,
1595 .attrs = ArrayList(Die.Attr).init(di.allocator()),
1596 };
1597 try result.attrs.resize(table_entry.attrs.len);
1598 for (table_entry.attrs.toSliceConst()) |attr, i| {
1599 result.attrs.items[i] = Die.Attr{
1600 .id = attr.attr_id,
1601 .value = try parseFormValue(di.allocator(), di.dwarf_in_stream, attr.form_id, is_64),
1602 };
1603 }
1604 return result;
1605}
1606
15711607fn parseDie(di: *DwarfInfo, abbrev_table: *const AbbrevTable, is_64: bool) !Die {
1572 const abbrev_code = try readULeb128(di.dwarf_in_stream);
1608 const abbrev_code = try leb.readULEB128(u64, di.dwarf_in_stream);
15731609 const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) orelse return error.InvalidDebugInfo;
15741610
15751611 var result = Die{
......@@ -1682,9 +1718,9 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
16821718 while (true) {
16831719 const file_name = readStringMem(&ptr);
16841720 if (file_name.len == 0) break;
1685 const dir_index = try readULeb128Mem(&ptr);
1686 const mtime = try readULeb128Mem(&ptr);
1687 const len_bytes = try readULeb128Mem(&ptr);
1721 const dir_index = try leb.readULEB128Mem(usize, &ptr);
1722 const mtime = try leb.readULEB128Mem(usize, &ptr);
1723 const len_bytes = try leb.readULEB128Mem(usize, &ptr);
16881724 try file_entries.append(FileEntry{
16891725 .file_name = file_name,
16901726 .dir_index = dir_index,
......@@ -1698,7 +1734,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
16981734 const opcode = readByteMem(&ptr);
16991735
17001736 if (opcode == DW.LNS_extended_op) {
1701 const op_size = try readULeb128Mem(&ptr);
1737 const op_size = try leb.readULEB128Mem(u64, &ptr);
17021738 if (op_size < 1) return error.InvalidDebugInfo;
17031739 var sub_op = readByteMem(&ptr);
17041740 switch (sub_op) {
......@@ -1713,9 +1749,9 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
17131749 },
17141750 DW.LNE_define_file => {
17151751 const file_name = readStringMem(&ptr);
1716 const dir_index = try readULeb128Mem(&ptr);
1717 const mtime = try readULeb128Mem(&ptr);
1718 const len_bytes = try readULeb128Mem(&ptr);
1752 const dir_index = try leb.readULEB128Mem(usize, &ptr);
1753 const mtime = try leb.readULEB128Mem(usize, &ptr);
1754 const len_bytes = try leb.readULEB128Mem(usize, &ptr);
17191755 try file_entries.append(FileEntry{
17201756 .file_name = file_name,
17211757 .dir_index = dir_index,
......@@ -1743,19 +1779,19 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
17431779 prog.basic_block = false;
17441780 },
17451781 DW.LNS_advance_pc => {
1746 const arg = try readULeb128Mem(&ptr);
1782 const arg = try leb.readULEB128Mem(u64, &ptr);
17471783 prog.address += arg * minimum_instruction_length;
17481784 },
17491785 DW.LNS_advance_line => {
1750 const arg = try readILeb128Mem(&ptr);
1786 const arg = try leb.readILEB128Mem(i64, &ptr);
17511787 prog.line += arg;
17521788 },
17531789 DW.LNS_set_file => {
1754 const arg = try readULeb128Mem(&ptr);
1790 const arg = try leb.readULEB128Mem(u64, &ptr);
17551791 prog.file = arg;
17561792 },
17571793 DW.LNS_set_column => {
1758 const arg = try readULeb128Mem(&ptr);
1794 const arg = try leb.readULEB128Mem(u64, &ptr);
17591795 prog.column = arg;
17601796 },
17611797 DW.LNS_negate_stmt => {
......@@ -1787,182 +1823,292 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
17871823
17881824fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo {
17891825 const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir);
1826 const line_info_offset = try compile_unit.die.getAttrSecOffset(DW.AT_stmt_list);
17901827
1791 const debug_line_end = di.debug_line.offset + di.debug_line.size;
1792 var this_offset = di.debug_line.offset;
1793 var this_index: usize = 0;
1828 assert(line_info_offset < di.debug_line.size);
17941829
1795 while (this_offset < debug_line_end) : (this_index += 1) {
1796 try di.dwarf_seekable_stream.seekTo(this_offset);
1830 try di.dwarf_seekable_stream.seekTo(di.debug_line.offset + line_info_offset);
17971831
1798 var is_64: bool = undefined;
1799 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
1800 if (unit_length == 0) return error.MissingDebugInfo;
1801 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
1832 var is_64: bool = undefined;
1833 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
1834 if (unit_length == 0) {
1835 return error.MissingDebugInfo;
1836 }
1837 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
18021838
1803 if (compile_unit.index != this_index) {
1804 this_offset += next_offset;
1805 continue;
1806 }
1839 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
1840 // TODO support 3 and 5
1841 if (version != 2 and version != 4) return error.InvalidDebugInfo;
18071842
1808 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
1809 // TODO support 3 and 5
1810 if (version != 2 and version != 4) return error.InvalidDebugInfo;
1843 const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian);
1844 const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length;
1845
1846 const minimum_instruction_length = try di.dwarf_in_stream.readByte();
1847 if (minimum_instruction_length == 0) return error.InvalidDebugInfo;
1848
1849 if (version >= 4) {
1850 // maximum_operations_per_instruction
1851 _ = try di.dwarf_in_stream.readByte();
1852 }
1853
1854 const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0;
1855 const line_base = try di.dwarf_in_stream.readByteSigned();
1856
1857 const line_range = try di.dwarf_in_stream.readByte();
1858 if (line_range == 0) return error.InvalidDebugInfo;
18111859
1812 const prologue_length = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian);
1813 const prog_start_offset = (try di.dwarf_seekable_stream.getPos()) + prologue_length;
1860 const opcode_base = try di.dwarf_in_stream.readByte();
18141861
1815 const minimum_instruction_length = try di.dwarf_in_stream.readByte();
1816 if (minimum_instruction_length == 0) return error.InvalidDebugInfo;
1862 const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1);
18171863
1818 if (version >= 4) {
1819 // maximum_operations_per_instruction
1820 _ = try di.dwarf_in_stream.readByte();
1864 {
1865 var i: usize = 0;
1866 while (i < opcode_base - 1) : (i += 1) {
1867 standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte();
18211868 }
1869 }
18221870
1823 const default_is_stmt = (try di.dwarf_in_stream.readByte()) != 0;
1824 const line_base = try di.dwarf_in_stream.readByteSigned();
1871 var include_directories = ArrayList([]u8).init(di.allocator());
1872 try include_directories.append(compile_unit_cwd);
1873 while (true) {
1874 const dir = try di.readString();
1875 if (dir.len == 0) break;
1876 try include_directories.append(dir);
1877 }
1878
1879 var file_entries = ArrayList(FileEntry).init(di.allocator());
1880 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address);
18251881
1826 const line_range = try di.dwarf_in_stream.readByte();
1827 if (line_range == 0) return error.InvalidDebugInfo;
1882 while (true) {
1883 const file_name = try di.readString();
1884 if (file_name.len == 0) break;
1885 const dir_index = try leb.readULEB128(usize, di.dwarf_in_stream);
1886 const mtime = try leb.readULEB128(usize, di.dwarf_in_stream);
1887 const len_bytes = try leb.readULEB128(usize, di.dwarf_in_stream);
1888 try file_entries.append(FileEntry{
1889 .file_name = file_name,
1890 .dir_index = dir_index,
1891 .mtime = mtime,
1892 .len_bytes = len_bytes,
1893 });
1894 }
18281895
1829 const opcode_base = try di.dwarf_in_stream.readByte();
1896 try di.dwarf_seekable_stream.seekTo(prog_start_offset);
18301897
1831 const standard_opcode_lengths = try di.allocator().alloc(u8, opcode_base - 1);
1898 while (true) {
1899 const opcode = try di.dwarf_in_stream.readByte();
18321900
1833 {
1834 var i: usize = 0;
1835 while (i < opcode_base - 1) : (i += 1) {
1836 standard_opcode_lengths[i] = try di.dwarf_in_stream.readByte();
1901 if (opcode == DW.LNS_extended_op) {
1902 const op_size = try leb.readULEB128(u64, di.dwarf_in_stream);
1903 if (op_size < 1) return error.InvalidDebugInfo;
1904 var sub_op = try di.dwarf_in_stream.readByte();
1905 switch (sub_op) {
1906 DW.LNE_end_sequence => {
1907 prog.end_sequence = true;
1908 if (try prog.checkLineMatch()) |info| return info;
1909 return error.MissingDebugInfo;
1910 },
1911 DW.LNE_set_address => {
1912 const addr = try di.dwarf_in_stream.readInt(usize, di.endian);
1913 prog.address = addr;
1914 },
1915 DW.LNE_define_file => {
1916 const file_name = try di.readString();
1917 const dir_index = try leb.readULEB128(usize, di.dwarf_in_stream);
1918 const mtime = try leb.readULEB128(usize, di.dwarf_in_stream);
1919 const len_bytes = try leb.readULEB128(usize, di.dwarf_in_stream);
1920 try file_entries.append(FileEntry{
1921 .file_name = file_name,
1922 .dir_index = dir_index,
1923 .mtime = mtime,
1924 .len_bytes = len_bytes,
1925 });
1926 },
1927 else => {
1928 const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo;
1929 try di.dwarf_seekable_stream.seekForward(fwd_amt);
1930 },
1931 }
1932 } else if (opcode >= opcode_base) {
1933 // special opcodes
1934 const adjusted_opcode = opcode - opcode_base;
1935 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
1936 const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);
1937 prog.line += inc_line;
1938 prog.address += inc_addr;
1939 if (try prog.checkLineMatch()) |info| return info;
1940 prog.basic_block = false;
1941 } else {
1942 switch (opcode) {
1943 DW.LNS_copy => {
1944 if (try prog.checkLineMatch()) |info| return info;
1945 prog.basic_block = false;
1946 },
1947 DW.LNS_advance_pc => {
1948 const arg = try leb.readULEB128(u64, di.dwarf_in_stream);
1949 prog.address += arg * minimum_instruction_length;
1950 },
1951 DW.LNS_advance_line => {
1952 const arg = try leb.readILEB128(i64, di.dwarf_in_stream);
1953 prog.line += arg;
1954 },
1955 DW.LNS_set_file => {
1956 const arg = try leb.readULEB128(u64, di.dwarf_in_stream);
1957 prog.file = arg;
1958 },
1959 DW.LNS_set_column => {
1960 const arg = try leb.readULEB128(u64, di.dwarf_in_stream);
1961 prog.column = arg;
1962 },
1963 DW.LNS_negate_stmt => {
1964 prog.is_stmt = !prog.is_stmt;
1965 },
1966 DW.LNS_set_basic_block => {
1967 prog.basic_block = true;
1968 },
1969 DW.LNS_const_add_pc => {
1970 const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range);
1971 prog.address += inc_addr;
1972 },
1973 DW.LNS_fixed_advance_pc => {
1974 const arg = try di.dwarf_in_stream.readInt(u16, di.endian);
1975 prog.address += arg;
1976 },
1977 DW.LNS_set_prologue_end => {},
1978 else => {
1979 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
1980 const len_bytes = standard_opcode_lengths[opcode - 1];
1981 try di.dwarf_seekable_stream.seekForward(len_bytes);
1982 },
18371983 }
18381984 }
1985 }
18391986
1840 var include_directories = ArrayList([]u8).init(di.allocator());
1841 try include_directories.append(compile_unit_cwd);
1842 while (true) {
1843 const dir = try di.readString();
1844 if (dir.len == 0) break;
1845 try include_directories.append(dir);
1846 }
1987 return error.MissingDebugInfo;
1988}
18471989
1848 var file_entries = ArrayList(FileEntry).init(di.allocator());
1849 var prog = LineNumberProgram.init(default_is_stmt, include_directories.toSliceConst(), &file_entries, target_address);
1990const Func = struct {
1991 pc_range: ?PcRange,
1992 name: ?[]u8,
1993};
18501994
1851 while (true) {
1852 const file_name = try di.readString();
1853 if (file_name.len == 0) break;
1854 const dir_index = try readULeb128(di.dwarf_in_stream);
1855 const mtime = try readULeb128(di.dwarf_in_stream);
1856 const len_bytes = try readULeb128(di.dwarf_in_stream);
1857 try file_entries.append(FileEntry{
1858 .file_name = file_name,
1859 .dir_index = dir_index,
1860 .mtime = mtime,
1861 .len_bytes = len_bytes,
1862 });
1995fn getSymbolNameDwarf(di: *DwarfInfo, address: u64) ?[]const u8 {
1996 for (di.func_list.toSliceConst()) |*func| {
1997 if (func.pc_range) |range| {
1998 if (address >= range.start and address < range.end) {
1999 return func.name;
2000 }
18632001 }
2002 }
2003
2004 return null;
2005}
18642006
1865 try di.dwarf_seekable_stream.seekTo(prog_start_offset);
2007fn scanAllFunctions(di: *DwarfInfo) !void {
2008 const debug_info_end = di.debug_info.offset + di.debug_info.size;
2009 var this_unit_offset = di.debug_info.offset;
18662010
1867 while (true) {
1868 const opcode = try di.dwarf_in_stream.readByte();
1869
1870 if (opcode == DW.LNS_extended_op) {
1871 const op_size = try readULeb128(di.dwarf_in_stream);
1872 if (op_size < 1) return error.InvalidDebugInfo;
1873 var sub_op = try di.dwarf_in_stream.readByte();
1874 switch (sub_op) {
1875 DW.LNE_end_sequence => {
1876 prog.end_sequence = true;
1877 if (try prog.checkLineMatch()) |info| return info;
1878 return error.MissingDebugInfo;
1879 },
1880 DW.LNE_set_address => {
1881 const addr = try di.dwarf_in_stream.readInt(usize, di.endian);
1882 prog.address = addr;
1883 },
1884 DW.LNE_define_file => {
1885 const file_name = try di.readString();
1886 const dir_index = try readULeb128(di.dwarf_in_stream);
1887 const mtime = try readULeb128(di.dwarf_in_stream);
1888 const len_bytes = try readULeb128(di.dwarf_in_stream);
1889 try file_entries.append(FileEntry{
1890 .file_name = file_name,
1891 .dir_index = dir_index,
1892 .mtime = mtime,
1893 .len_bytes = len_bytes,
1894 });
1895 },
1896 else => {
1897 const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo;
1898 try di.dwarf_seekable_stream.seekForward(fwd_amt);
1899 },
1900 }
1901 } else if (opcode >= opcode_base) {
1902 // special opcodes
1903 const adjusted_opcode = opcode - opcode_base;
1904 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
1905 const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);
1906 prog.line += inc_line;
1907 prog.address += inc_addr;
1908 if (try prog.checkLineMatch()) |info| return info;
1909 prog.basic_block = false;
1910 } else {
1911 switch (opcode) {
1912 DW.LNS_copy => {
1913 if (try prog.checkLineMatch()) |info| return info;
1914 prog.basic_block = false;
1915 },
1916 DW.LNS_advance_pc => {
1917 const arg = try readULeb128(di.dwarf_in_stream);
1918 prog.address += arg * minimum_instruction_length;
1919 },
1920 DW.LNS_advance_line => {
1921 const arg = try readILeb128(di.dwarf_in_stream);
1922 prog.line += arg;
1923 },
1924 DW.LNS_set_file => {
1925 const arg = try readULeb128(di.dwarf_in_stream);
1926 prog.file = arg;
1927 },
1928 DW.LNS_set_column => {
1929 const arg = try readULeb128(di.dwarf_in_stream);
1930 prog.column = arg;
1931 },
1932 DW.LNS_negate_stmt => {
1933 prog.is_stmt = !prog.is_stmt;
1934 },
1935 DW.LNS_set_basic_block => {
1936 prog.basic_block = true;
1937 },
1938 DW.LNS_const_add_pc => {
1939 const inc_addr = minimum_instruction_length * ((255 - opcode_base) / line_range);
1940 prog.address += inc_addr;
1941 },
1942 DW.LNS_fixed_advance_pc => {
1943 const arg = try di.dwarf_in_stream.readInt(u16, di.endian);
1944 prog.address += arg;
1945 },
1946 DW.LNS_set_prologue_end => {},
1947 else => {
1948 if (opcode - 1 >= standard_opcode_lengths.len) return error.InvalidDebugInfo;
1949 const len_bytes = standard_opcode_lengths[opcode - 1];
1950 try di.dwarf_seekable_stream.seekForward(len_bytes);
1951 },
1952 }
2011 while (this_unit_offset < debug_info_end) {
2012 try di.dwarf_seekable_stream.seekTo(this_unit_offset);
2013
2014 var is_64: bool = undefined;
2015 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
2016 if (unit_length == 0) return;
2017 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
2018
2019 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
2020 if (version < 2 or version > 5) return error.InvalidDebugInfo;
2021
2022 const debug_abbrev_offset = if (is_64) try di.dwarf_in_stream.readInt(u64, di.endian) else try di.dwarf_in_stream.readInt(u32, di.endian);
2023
2024 const address_size = try di.dwarf_in_stream.readByte();
2025 if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
2026
2027 const compile_unit_pos = try di.dwarf_seekable_stream.getPos();
2028 const abbrev_table = try getAbbrevTable(di, debug_abbrev_offset);
2029
2030 try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
2031
2032 const next_unit_pos = this_unit_offset + next_offset;
2033
2034 while ((try di.dwarf_seekable_stream.getPos()) < next_unit_pos) {
2035 const die_obj = (try parseDie1(di, abbrev_table, is_64)) orelse continue;
2036 const after_die_offset = try di.dwarf_seekable_stream.getPos();
2037
2038 switch (die_obj.tag_id) {
2039 DW.TAG_subprogram, DW.TAG_inlined_subroutine, DW.TAG_subroutine, DW.TAG_entry_point => {
2040 const fn_name = x: {
2041 var depth: i32 = 3;
2042 var this_die_obj = die_obj;
2043 // Prenvent endless loops
2044 while (depth > 0) : (depth -= 1) {
2045 if (this_die_obj.getAttr(DW.AT_name)) |_| {
2046 const name = try this_die_obj.getAttrString(di, DW.AT_name);
2047 break :x name;
2048 } else if (this_die_obj.getAttr(DW.AT_abstract_origin)) |ref| {
2049 // Follow the DIE it points to and repeat
2050 const ref_offset = try this_die_obj.getAttrRef(DW.AT_abstract_origin);
2051 if (ref_offset > next_offset) return error.InvalidDebugInfo;
2052 try di.dwarf_seekable_stream.seekTo(this_unit_offset + ref_offset);
2053 this_die_obj = (try parseDie1(di, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;
2054 } else if (this_die_obj.getAttr(DW.AT_specification)) |ref| {
2055 // Follow the DIE it points to and repeat
2056 const ref_offset = try this_die_obj.getAttrRef(DW.AT_specification);
2057 if (ref_offset > next_offset) return error.InvalidDebugInfo;
2058 try di.dwarf_seekable_stream.seekTo(this_unit_offset + ref_offset);
2059 this_die_obj = (try parseDie1(di, abbrev_table, is_64)) orelse return error.InvalidDebugInfo;
2060 } else {
2061 break :x null;
2062 }
2063 }
2064
2065 break :x null;
2066 };
2067
2068 const pc_range = x: {
2069 if (die_obj.getAttrAddr(DW.AT_low_pc)) |low_pc| {
2070 if (die_obj.getAttr(DW.AT_high_pc)) |high_pc_value| {
2071 const pc_end = switch (high_pc_value.*) {
2072 FormValue.Address => |value| value,
2073 FormValue.Const => |value| b: {
2074 const offset = try value.asUnsignedLe();
2075 break :b (low_pc + offset);
2076 },
2077 else => return error.InvalidDebugInfo,
2078 };
2079 break :x PcRange{
2080 .start = low_pc,
2081 .end = pc_end,
2082 };
2083 } else {
2084 break :x null;
2085 }
2086 } else |err| {
2087 if (err != error.MissingDebugInfo) return err;
2088 break :x null;
2089 }
2090 };
2091
2092 try di.func_list.append(Func{
2093 .name = fn_name,
2094 .pc_range = pc_range,
2095 });
2096 },
2097 else => {
2098 continue;
2099 },
19532100 }
2101
2102 try di.dwarf_seekable_stream.seekTo(after_die_offset);
19542103 }
19552104
1956 this_offset += next_offset;
2105 this_unit_offset += next_offset;
19572106 }
1958
1959 return error.MissingDebugInfo;
19602107}
19612108
19622109fn scanAllCompileUnits(di: *DwarfInfo) !void {
19632110 const debug_info_end = di.debug_info.offset + di.debug_info.size;
19642111 var this_unit_offset = di.debug_info.offset;
1965 var cu_index: usize = 0;
19662112
19672113 while (this_unit_offset < debug_info_end) {
19682114 try di.dwarf_seekable_stream.seekTo(this_unit_offset);
......@@ -2019,11 +2165,9 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
20192165 .is_64 = is_64,
20202166 .pc_range = pc_range,
20212167 .die = compile_unit_die,
2022 .index = cu_index,
20232168 });
20242169
20252170 this_unit_offset += next_offset;
2026 cu_index += 1;
20272171 }
20282172}
20292173
......@@ -2098,52 +2242,6 @@ fn readStringMem(ptr: *[*]const u8) []const u8 {
20982242 return result;
20992243}
21002244
2101fn readULeb128Mem(ptr: *[*]const u8) !u64 {
2102 var result: u64 = 0;
2103 var shift: usize = 0;
2104 var i: usize = 0;
2105
2106 while (true) {
2107 const byte = ptr.*[i];
2108 i += 1;
2109
2110 var operand: u64 = undefined;
2111
2112 if (@shlWithOverflow(u64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
2113
2114 result |= operand;
2115
2116 if ((byte & 0b10000000) == 0) {
2117 ptr.* += i;
2118 return result;
2119 }
2120
2121 shift += 7;
2122 }
2123}
2124fn readILeb128Mem(ptr: *[*]const u8) !i64 {
2125 var result: i64 = 0;
2126 var shift: usize = 0;
2127 var i: usize = 0;
2128
2129 while (true) {
2130 const byte = ptr.*[i];
2131 i += 1;
2132
2133 var operand: i64 = undefined;
2134 if (@shlWithOverflow(i64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
2135
2136 result |= operand;
2137 shift += 7;
2138
2139 if ((byte & 0b10000000) == 0) {
2140 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << @intCast(u6, shift));
2141 ptr.* += i;
2142 return result;
2143 }
2144 }
2145}
2146
21472245fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool) !u64 {
21482246 const first_32_bits = try in_stream.readIntLittle(u32);
21492247 is_64.* = (first_32_bits == 0xffffffff);
......@@ -2155,46 +2253,6 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)
21552253 }
21562254}
21572255
2158fn readULeb128(in_stream: var) !u64 {
2159 var result: u64 = 0;
2160 var shift: usize = 0;
2161
2162 while (true) {
2163 const byte = try in_stream.readByte();
2164
2165 var operand: u64 = undefined;
2166
2167 if (@shlWithOverflow(u64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
2168
2169 result |= operand;
2170
2171 if ((byte & 0b10000000) == 0) return result;
2172
2173 shift += 7;
2174 }
2175}
2176
2177fn readILeb128(in_stream: var) !i64 {
2178 var result: i64 = 0;
2179 var shift: usize = 0;
2180
2181 while (true) {
2182 const byte = try in_stream.readByte();
2183
2184 var operand: i64 = undefined;
2185
2186 if (@shlWithOverflow(i64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
2187
2188 result |= operand;
2189 shift += 7;
2190
2191 if ((byte & 0b10000000) == 0) {
2192 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << @intCast(u6, shift));
2193 return result;
2194 }
2195 }
2196}
2197
21982256/// This should only be used in temporary test programs.
21992257pub const global_allocator = &global_fixed_allocator.allocator;
22002258var global_fixed_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(global_allocator_mem[0..]);
std/debug/failing_allocator.zig+13-5
......@@ -10,6 +10,7 @@ pub const FailingAllocator = struct {
1010 internal_allocator: *mem.Allocator,
1111 allocated_bytes: usize,
1212 freed_bytes: usize,
13 allocations: usize,
1314 deallocations: usize,
1415
1516 pub fn init(allocator: *mem.Allocator, fail_index: usize) FailingAllocator {
......@@ -19,6 +20,7 @@ pub const FailingAllocator = struct {
1920 .index = 0,
2021 .allocated_bytes = 0,
2122 .freed_bytes = 0,
23 .allocations = 0,
2224 .deallocations = 0,
2325 .allocator = mem.Allocator{
2426 .reallocFn = realloc,
......@@ -39,19 +41,25 @@ pub const FailingAllocator = struct {
3941 new_size,
4042 new_align,
4143 );
42 if (new_size <= old_mem.len) {
44 if (new_size < old_mem.len) {
4345 self.freed_bytes += old_mem.len - new_size;
44 } else {
46 if (new_size == 0)
47 self.deallocations += 1;
48 } else if (new_size > old_mem.len) {
4549 self.allocated_bytes += new_size - old_mem.len;
50 if (old_mem.len == 0)
51 self.allocations += 1;
4652 }
47 self.deallocations += 1;
4853 self.index += 1;
4954 return result;
5055 }
5156
5257 fn shrink(allocator: *mem.Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
5358 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
54 self.freed_bytes += old_mem.len - new_size;
55 return self.internal_allocator.shrinkFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
59 const r = self.internal_allocator.shrinkFn(self.internal_allocator, old_mem, old_align, new_size, new_align);
60 self.freed_bytes += old_mem.len - r.len;
61 if (new_size == 0)
62 self.deallocations += 1;
63 return r;
5664 }
5765};
std/debug/leb128.zig created+228
......@@ -0,0 +1,228 @@
1const std = @import("std");
2const testing = std.testing;
3
4pub fn readULEB128(comptime T: type, in_stream: var) !T {
5 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
6
7 var result: T = 0;
8 var shift: usize = 0;
9
10 while (true) {
11 const byte = try in_stream.readByte();
12
13 if (shift > T.bit_count)
14 return error.Overflow;
15
16 var operand: T = undefined;
17 if (@shlWithOverflow(T, byte & 0x7f, @intCast(ShiftT, shift), &operand))
18 return error.Overflow;
19
20 result |= operand;
21
22 if ((byte & 0x80) == 0)
23 return result;
24
25 shift += 7;
26 }
27}
28
29pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
30 const ShiftT = @IntType(false, std.math.log2(T.bit_count));
31
32 var result: T = 0;
33 var shift: usize = 0;
34 var i: usize = 0;
35
36 while (true) : (i += 1) {
37 const byte = ptr.*[i];
38
39 if (shift > T.bit_count)
40 return error.Overflow;
41
42 var operand: T = undefined;
43 if (@shlWithOverflow(T, byte & 0x7f, @intCast(ShiftT, shift), &operand))
44 return error.Overflow;
45
46 result |= operand;
47
48 if ((byte & 0x80) == 0) {
49 ptr.* += i;
50 return result;
51 }
52
53 shift += 7;
54 }
55}
56
57pub 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));
60
61 var result: UT = 0;
62 var shift: usize = 0;
63
64 while (true) {
65 const byte = u8(try in_stream.readByte());
66
67 if (shift > T.bit_count)
68 return error.Overflow;
69
70 var operand: UT = undefined;
71 if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
72 if (byte != 0x7f)
73 return error.Overflow;
74 }
75
76 result |= operand;
77
78 shift += 7;
79
80 if ((byte & 0x80) == 0) {
81 if (shift < T.bit_count and (byte & 0x40) != 0) {
82 result |= @bitCast(UT, @intCast(T, -1)) << @intCast(ShiftT, shift);
83 }
84 return @bitCast(T, result);
85 }
86 }
87}
88
89pub 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));
92
93 var result: UT = 0;
94 var shift: usize = 0;
95 var i: usize = 0;
96
97 while (true) : (i += 1) {
98 const byte = ptr.*[i];
99
100 if (shift > T.bit_count)
101 return error.Overflow;
102
103 var operand: UT = undefined;
104 if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
105 if (byte != 0x7f)
106 return error.Overflow;
107 }
108
109 result |= operand;
110
111 shift += 7;
112
113 if ((byte & 0x80) == 0) {
114 if (shift < T.bit_count and (byte & 0x40) != 0) {
115 result |= @bitCast(UT, @intCast(T, -1)) << @intCast(ShiftT, shift);
116 }
117 ptr.* += i;
118 return @bitCast(T, result);
119 }
120 }
121}
122
123fn test_read_stream_ileb128(comptime T: type, encoded: []const u8) !T {
124 var in_stream = std.io.SliceInStream.init(encoded);
125 return try readILEB128(T, &in_stream.stream);
126}
127
128fn test_read_stream_uleb128(comptime T: type, encoded: []const u8) !T {
129 var in_stream = std.io.SliceInStream.init(encoded);
130 return try readULEB128(T, &in_stream.stream);
131}
132
133fn test_read_ileb128(comptime T: type, encoded: []const u8) !T {
134 var in_stream = std.io.SliceInStream.init(encoded);
135 const v1 = readILEB128(T, &in_stream.stream);
136 var in_ptr = encoded.ptr;
137 const v2 = readILEB128Mem(T, &in_ptr);
138 testing.expectEqual(v1, v2);
139 return v1;
140}
141
142fn test_read_uleb128(comptime T: type, encoded: []const u8) !T {
143 var in_stream = std.io.SliceInStream.init(encoded);
144 const v1 = readULEB128(T, &in_stream.stream);
145 var in_ptr = encoded.ptr;
146 const v2 = readULEB128Mem(T, &in_ptr);
147 testing.expectEqual(v1, v2);
148 return v1;
149}
150
151test "deserialize signed LEB128" {
152 // Truncated
153 testing.expectError(error.EndOfStream, test_read_stream_ileb128(i64, "\x80"));
154
155 // Overflow
156 testing.expectError(error.Overflow, test_read_ileb128(i8, "\x80\x80\x40"));
157 testing.expectError(error.Overflow, test_read_ileb128(i16, "\x80\x80\x80\x40"));
158 testing.expectError(error.Overflow, test_read_ileb128(i32, "\x80\x80\x80\x80\x40"));
159 testing.expectError(error.Overflow, test_read_ileb128(i64, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x40"));
160 testing.expectError(error.Overflow, test_read_ileb128(i8, "\xff\x7e"));
161
162 // Decode SLEB128
163 testing.expect((try test_read_ileb128(i64, "\x00")) == 0);
164 testing.expect((try test_read_ileb128(i64, "\x01")) == 1);
165 testing.expect((try test_read_ileb128(i64, "\x3f")) == 63);
166 testing.expect((try test_read_ileb128(i64, "\x40")) == -64);
167 testing.expect((try test_read_ileb128(i64, "\x41")) == -63);
168 testing.expect((try test_read_ileb128(i64, "\x7f")) == -1);
169 testing.expect((try test_read_ileb128(i64, "\x80\x01")) == 128);
170 testing.expect((try test_read_ileb128(i64, "\x81\x01")) == 129);
171 testing.expect((try test_read_ileb128(i64, "\xff\x7e")) == -129);
172 testing.expect((try test_read_ileb128(i64, "\x80\x7f")) == -128);
173 testing.expect((try test_read_ileb128(i64, "\x81\x7f")) == -127);
174 testing.expect((try test_read_ileb128(i64, "\xc0\x00")) == 64);
175 testing.expect((try test_read_ileb128(i64, "\xc7\x9f\x7f")) == -12345);
176 testing.expect((try test_read_ileb128(i8, "\xff\x7f")) == -1);
177 testing.expect((try test_read_ileb128(i16, "\xff\xff\x7f")) == -1);
178 testing.expect((try test_read_ileb128(i32, "\xff\xff\xff\xff\x7f")) == -1);
179 testing.expect((try test_read_ileb128(i32, "\x80\x80\x80\x80\x08")) == -0x80000000);
180 testing.expect((try test_read_ileb128(i64, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01")) == @bitCast(i64, @intCast(u64, 0x8000000000000000)));
181 testing.expect((try test_read_ileb128(i64, "\x80\x80\x80\x80\x80\x80\x80\x80\x40")) == -0x4000000000000000);
182 testing.expect((try test_read_ileb128(i64, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x7f")) == -0x8000000000000000);
183
184 // Decode unnormalized SLEB128 with extra padding bytes.
185 testing.expect((try test_read_ileb128(i64, "\x80\x00")) == 0);
186 testing.expect((try test_read_ileb128(i64, "\x80\x80\x00")) == 0);
187 testing.expect((try test_read_ileb128(i64, "\xff\x00")) == 0x7f);
188 testing.expect((try test_read_ileb128(i64, "\xff\x80\x00")) == 0x7f);
189 testing.expect((try test_read_ileb128(i64, "\x80\x81\x00")) == 0x80);
190 testing.expect((try test_read_ileb128(i64, "\x80\x81\x80\x00")) == 0x80);
191}
192
193test "deserialize unsigned LEB128" {
194 // Truncated
195 testing.expectError(error.EndOfStream, test_read_stream_uleb128(u64, "\x80"));
196
197 // Overflow
198 testing.expectError(error.Overflow, test_read_uleb128(u8, "\x80\x02"));
199 testing.expectError(error.Overflow, test_read_uleb128(u8, "\x80\x80\x40"));
200 testing.expectError(error.Overflow, test_read_uleb128(u16, "\x80\x80\x84"));
201 testing.expectError(error.Overflow, test_read_uleb128(u16, "\x80\x80\x80\x40"));
202 testing.expectError(error.Overflow, test_read_uleb128(u32, "\x80\x80\x80\x80\x90"));
203 testing.expectError(error.Overflow, test_read_uleb128(u32, "\x80\x80\x80\x80\x40"));
204 testing.expectError(error.Overflow, test_read_uleb128(u64, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x40"));
205
206 // Decode ULEB128
207 testing.expect((try test_read_uleb128(u64, "\x00")) == 0);
208 testing.expect((try test_read_uleb128(u64, "\x01")) == 1);
209 testing.expect((try test_read_uleb128(u64, "\x3f")) == 63);
210 testing.expect((try test_read_uleb128(u64, "\x40")) == 64);
211 testing.expect((try test_read_uleb128(u64, "\x7f")) == 0x7f);
212 testing.expect((try test_read_uleb128(u64, "\x80\x01")) == 0x80);
213 testing.expect((try test_read_uleb128(u64, "\x81\x01")) == 0x81);
214 testing.expect((try test_read_uleb128(u64, "\x90\x01")) == 0x90);
215 testing.expect((try test_read_uleb128(u64, "\xff\x01")) == 0xff);
216 testing.expect((try test_read_uleb128(u64, "\x80\x02")) == 0x100);
217 testing.expect((try test_read_uleb128(u64, "\x81\x02")) == 0x101);
218 testing.expect((try test_read_uleb128(u64, "\x80\xc1\x80\x80\x10")) == 4294975616);
219 testing.expect((try test_read_uleb128(u64, "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01")) == 0x8000000000000000);
220
221 // Decode ULEB128 with extra padding bytes
222 testing.expect((try test_read_uleb128(u64, "\x80\x00")) == 0);
223 testing.expect((try test_read_uleb128(u64, "\x80\x80\x00")) == 0);
224 testing.expect((try test_read_uleb128(u64, "\xff\x00")) == 0x7f);
225 testing.expect((try test_read_uleb128(u64, "\xff\x80\x00")) == 0x7f);
226 testing.expect((try test_read_uleb128(u64, "\x80\x81\x00")) == 0x80);
227 testing.expect((try test_read_uleb128(u64, "\x80\x81\x80\x00")) == 0x80);
228}
std/dwarf.zig+4
......@@ -13,6 +13,7 @@ pub const TAG_reference_type = 0x10;
1313pub const TAG_compile_unit = 0x11;
1414pub const TAG_string_type = 0x12;
1515pub const TAG_structure_type = 0x13;
16pub const TAG_subroutine = 0x14;
1617pub const TAG_subroutine_type = 0x15;
1718pub const TAG_typedef = 0x16;
1819pub const TAG_union_type = 0x17;
......@@ -241,6 +242,9 @@ pub const AT_const_expr = 0x6c;
241242pub const AT_enum_class = 0x6d;
242243pub const AT_linkage_name = 0x6e;
243244
245// DWARF 5
246pub const AT_alignment = 0x88;
247
244248pub const AT_lo_user = 0x2000; // Implementation-defined range start.
245249pub const AT_hi_user = 0x3fff; // Implementation-defined range end.
246250
std/dynamic_library.zig+83
......@@ -19,6 +19,89 @@ pub const DynLib = switch (builtin.os) {
1919 else => void,
2020};
2121
22// The link_map structure is not completely specified beside the fields
23// reported below, any libc is free to store additional data in the remaining
24// space.
25// An iterator is provided in order to traverse the linked list in a idiomatic
26// fashion.
27const LinkMap = extern struct {
28 l_addr: usize,
29 l_name: [*]const u8,
30 l_ld: ?*elf.Dyn,
31 l_next: ?*LinkMap,
32 l_prev: ?*LinkMap,
33
34 pub const Iterator = struct {
35 current: ?*LinkMap,
36
37 fn end(self: *Iterator) bool {
38 return self.current == null;
39 }
40
41 fn next(self: *Iterator) ?*LinkMap {
42 if (self.current) |it| {
43 self.current = it.l_next;
44 return it;
45 }
46 return null;
47 }
48 };
49};
50
51const RDebug = extern struct {
52 r_version: i32,
53 r_map: ?*LinkMap,
54 r_brk: usize,
55 r_ldbase: usize,
56};
57
58fn elf_get_va_offset(phdrs: []elf.Phdr) !usize {
59 for (phdrs) |*phdr| {
60 if (phdr.p_type == elf.PT_LOAD) {
61 return @ptrToInt(phdr) - phdr.p_vaddr;
62 }
63 }
64 return error.InvalidExe;
65}
66
67pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
68 const va_offset = try elf_get_va_offset(phdrs);
69
70 const dyn_table = init: {
71 for (phdrs) |*phdr| {
72 if (phdr.p_type == elf.PT_DYNAMIC) {
73 const ptr = @intToPtr([*]elf.Dyn, va_offset + phdr.p_vaddr);
74 break :init ptr[0..phdr.p_memsz / @sizeOf(elf.Dyn)];
75 }
76 }
77 // No PT_DYNAMIC means this is either a statically-linked program or a
78 // badly corrupted one
79 return LinkMap.Iterator{.current = null};
80 };
81
82 const link_map_ptr = init: {
83 for (dyn_table) |*dyn| {
84 switch (dyn.d_tag) {
85 elf.DT_DEBUG => {
86 const r_debug = @intToPtr(*RDebug, dyn.d_un.d_ptr);
87 if (r_debug.r_version != 1) return error.InvalidExe;
88 break :init r_debug.r_map;
89 },
90 elf.DT_PLTGOT => {
91 const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr);
92 // The address to the link_map structure is stored in the
93 // second slot
94 break :init @intToPtr(?*LinkMap, got_table[1]);
95 },
96 else => { }
97 }
98 }
99 return error.InvalidExe;
100 };
101
102 return LinkMap.Iterator{.current = link_map_ptr};
103}
104
22105pub const LinuxDynLib = struct {
23106 elf_lib: ElfLib,
24107 fd: i32,
std/elf.zig+5
......@@ -877,6 +877,11 @@ pub const Phdr = switch (@sizeOf(usize)) {
877877 8 => Elf64_Phdr,
878878 else => @compileError("expected pointer size of 32 or 64"),
879879};
880pub const Dyn = switch (@sizeOf(usize)) {
881 4 => Elf32_Dyn,
882 8 => Elf64_Dyn,
883 else => @compileError("expected pointer size of 32 or 64"),
884};
880885pub const Shdr = switch (@sizeOf(usize)) {
881886 4 => Elf32_Shdr,
882887 8 => Elf64_Shdr,
std/fmt.zig+96-12
......@@ -8,6 +8,8 @@ const builtin = @import("builtin");
88const errol = @import("fmt/errol.zig");
99const lossyCast = std.math.lossyCast;
1010
11pub const default_max_depth = 3;
12
1113/// Renders fmt string with args, calling output with slices of bytes.
1214/// If `output` returns an error, the error is returned from `format` and
1315/// `output` is not called again.
......@@ -49,7 +51,7 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
4951 start_index = i;
5052 },
5153 '}' => {
52 try formatType(args[next_arg], fmt[0..0], context, Errors, output);
54 try formatType(args[next_arg], fmt[0..0], context, Errors, output, default_max_depth);
5355 next_arg += 1;
5456 state = State.Start;
5557 start_index = i + 1;
......@@ -69,7 +71,7 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
6971 State.FormatString => switch (c) {
7072 '}' => {
7173 const s = start_index + 1;
72 try formatType(args[next_arg], fmt[s..i], context, Errors, output);
74 try formatType(args[next_arg], fmt[s..i], context, Errors, output, default_max_depth);
7375 next_arg += 1;
7476 state = State.Start;
7577 start_index = i + 1;
......@@ -108,6 +110,7 @@ pub fn formatType(
108110 context: var,
109111 comptime Errors: type,
110112 output: fn (@typeOf(context), []const u8) Errors!void,
113 max_depth: usize,
111114) Errors!void {
112115 const T = @typeOf(value);
113116 switch (@typeInfo(T)) {
......@@ -122,16 +125,16 @@ pub fn formatType(
122125 },
123126 builtin.TypeId.Optional => {
124127 if (value) |payload| {
125 return formatType(payload, fmt, context, Errors, output);
128 return formatType(payload, fmt, context, Errors, output, max_depth);
126129 } else {
127130 return output(context, "null");
128131 }
129132 },
130133 builtin.TypeId.ErrorUnion => {
131134 if (value) |payload| {
132 return formatType(payload, fmt, context, Errors, output);
135 return formatType(payload, fmt, context, Errors, output, max_depth);
133136 } else |err| {
134 return formatType(err, fmt, context, Errors, output);
137 return formatType(err, fmt, context, Errors, output, max_depth);
135138 }
136139 },
137140 builtin.TypeId.ErrorSet => {
......@@ -164,10 +167,13 @@ pub fn formatType(
164167 switch (comptime @typeId(T)) {
165168 builtin.TypeId.Enum => {
166169 try output(context, ".");
167 try formatType(@tagName(value), "", context, Errors, output);
170 try formatType(@tagName(value), "", context, Errors, output, max_depth);
168171 return;
169172 },
170173 builtin.TypeId.Struct => {
174 if (max_depth == 0) {
175 return output(context, "{ ... }");
176 }
171177 comptime var field_i = 0;
172178 inline while (field_i < @memberCount(T)) : (field_i += 1) {
173179 if (field_i == 0) {
......@@ -177,11 +183,14 @@ pub fn formatType(
177183 }
178184 try output(context, @memberName(T, field_i));
179185 try output(context, " = ");
180 try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output);
186 try formatType(@field(value, @memberName(T, field_i)), "", context, Errors, output, max_depth-1);
181187 }
182188 try output(context, " }");
183189 },
184190 builtin.TypeId.Union => {
191 if (max_depth == 0) {
192 return output(context, "{ ... }");
193 }
185194 const info = @typeInfo(T).Union;
186195 if (info.tag_type) |UnionTagType| {
187196 try output(context, "{ .");
......@@ -189,7 +198,7 @@ pub fn formatType(
189198 try output(context, " = ");
190199 inline for (info.fields) |u_field| {
191200 if (@enumToInt(UnionTagType(value)) == u_field.enum_field.?.value) {
192 try formatType(@field(value, u_field.name), "", context, Errors, output);
201 try formatType(@field(value, u_field.name), "", context, Errors, output, max_depth-1);
193202 }
194203 }
195204 try output(context, " }");
......@@ -210,7 +219,7 @@ pub fn formatType(
210219 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
211220 },
212221 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
213 return formatType(value.*, fmt, context, Errors, output);
222 return formatType(value.*, fmt, context, Errors, output, max_depth);
214223 },
215224 else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
216225 },
......@@ -986,17 +995,17 @@ test "fmt.format" {
986995 {
987996 var buf1: [32]u8 = undefined;
988997 var context = BufPrintContext{ .remaining = buf1[0..] };
989 try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite);
998 try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
990999 var res = buf1[0 .. buf1.len - context.remaining.len];
9911000 testing.expect(mem.eql(u8, res, "1234"));
9921001
9931002 context = BufPrintContext{ .remaining = buf1[0..] };
994 try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite);
1003 try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
9951004 res = buf1[0 .. buf1.len - context.remaining.len];
9961005 testing.expect(mem.eql(u8, res, "a"));
9971006
9981007 context = BufPrintContext{ .remaining = buf1[0..] };
999 try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite);
1008 try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite, default_max_depth);
10001009 res = buf1[0 .. buf1.len - context.remaining.len];
10011010 testing.expect(mem.eql(u8, res, "1100"));
10021011 }
......@@ -1364,6 +1373,20 @@ test "fmt.format" {
13641373
13651374 try testFmt("E.Two", "{}", inst);
13661375 }
1376 //self-referential struct format
1377 {
1378 const S = struct {
1379 const SelfType = @This();
1380 a: ?*SelfType,
1381 };
1382
1383 var inst = S{
1384 .a = null,
1385 };
1386 inst.a = &inst;
1387
1388 try testFmt("S{ .a = S{ .a = S{ .a = S{ ... } } } }", "{}", inst);
1389 }
13671390 //print bytes as hex
13681391 {
13691392 const some_bytes = "\xCA\xFE\xBA\xBE";
......@@ -1449,3 +1472,64 @@ test "fmt.formatIntValue with comptime_int" {
14491472 try formatIntValue(value, "", &buf, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append);
14501473 assert(mem.eql(u8, buf.toSlice(), "123456789123456789"));
14511474}
1475
1476test "fmt.formatType max_depth" {
1477 const Vec2 = struct {
1478 const SelfType = @This();
1479 x: f32,
1480 y: f32,
1481
1482 pub fn format(
1483 self: SelfType,
1484 comptime fmt: []const u8,
1485 context: var,
1486 comptime Errors: type,
1487 output: fn (@typeOf(context), []const u8) Errors!void,
1488 ) Errors!void {
1489 return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y);
1490 }
1491 };
1492 const E = enum {
1493 One,
1494 Two,
1495 Three,
1496 };
1497 const TU = union(enum) {
1498 const SelfType = @This();
1499 float: f32,
1500 int: u32,
1501 ptr: ?*SelfType,
1502 };
1503 const S = struct {
1504 const SelfType = @This();
1505 a: ?*SelfType,
1506 tu: TU,
1507 e: E,
1508 vec: Vec2,
1509 };
1510
1511 var inst = S{
1512 .a = null,
1513 .tu = TU{ .ptr = null },
1514 .e = E.Two,
1515 .vec = Vec2{ .x = 10.2, .y = 2.22 },
1516 };
1517 inst.a = &inst;
1518 inst.tu.ptr = &inst.tu;
1519
1520 var buf0 = try std.Buffer.init(std.debug.global_allocator, "");
1521 try formatType(inst, "", &buf0, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 0);
1522 assert(mem.eql(u8, buf0.toSlice(), "S{ ... }"));
1523
1524 var buf1 = try std.Buffer.init(std.debug.global_allocator, "");
1525 try formatType(inst, "", &buf1, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 1);
1526 assert(mem.eql(u8, buf1.toSlice(), "S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }"));
1527
1528 var buf2 = try std.Buffer.init(std.debug.global_allocator, "");
1529 try formatType(inst, "", &buf2, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 2);
1530 assert(mem.eql(u8, buf2.toSlice(), "S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }"));
1531
1532 var buf3 = try std.Buffer.init(std.debug.global_allocator, "");
1533 try formatType(inst, "", &buf3, @typeOf(std.Buffer.append).ReturnType.ErrorSet, std.Buffer.append, 3);
1534 assert(mem.eql(u8, buf3.toSlice(), "S{ .a = S{ .a = S{ .a = S{ ... }, .tu = TU{ ... }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ ... } }, .e = E.Two, .vec = (10.200,2.220) }, .tu = TU{ .ptr = TU{ .ptr = TU{ ... } } }, .e = E.Two, .vec = (10.200,2.220) }"));
1535}
std/hash_map.zig+71-12
......@@ -118,7 +118,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
118118 };
119119 }
120120 self.incrementModificationCount();
121 try self.ensureCapacity();
121 try self.autoCapacity();
122122 const put_result = self.internalPut(key);
123123 assert(put_result.old_kv == null);
124124 return GetOrPutResult{
......@@ -135,15 +135,37 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
135135 return res.kv;
136136 }
137137
138 fn ensureCapacity(self: *Self) !void {
139 if (self.entries.len == 0) {
140 return self.initCapacity(16);
138 fn optimizedCapacity(expected_count: usize) usize {
139 // ensure that the hash map will be at most 60% full if
140 // expected_count items are put into it
141 var optimized_capacity = expected_count * 5 / 3;
142 // round capacity to the next power of two
143 const pow = math.log2_int_ceil(usize, optimized_capacity);
144 return math.pow(usize, 2, pow);
145 }
146
147 /// Increases capacity so that the hash map will be at most
148 /// 60% full when expected_count items are put into it
149 pub fn ensureCapacity(self: *Self, expected_count: usize) !void {
150 const optimized_capacity = optimizedCapacity(expected_count);
151 return self.ensureCapacityExact(optimized_capacity);
152 }
153
154 /// Sets the capacity to the new capacity if the new
155 /// capacity is greater than the current capacity.
156 /// New capacity must be a power of two.
157 fn ensureCapacityExact(self: *Self, new_capacity: usize) !void {
158 const is_power_of_two = new_capacity & (new_capacity-1) == 0;
159 assert(is_power_of_two);
160
161 if (new_capacity <= self.entries.len) {
162 return;
141163 }
142164
143 // if we get too full (60%), double the capacity
144 if (self.size * 5 >= self.entries.len * 3) {
145 const old_entries = self.entries;
146 try self.initCapacity(self.entries.len * 2);
165 const old_entries = self.entries;
166 try self.initCapacity(new_capacity);
167 self.incrementModificationCount();
168 if (old_entries.len > 0) {
147169 // dump all of the old elements into the new table
148170 for (old_entries) |*old_entry| {
149171 if (old_entry.used) {
......@@ -156,8 +178,13 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
156178
157179 /// Returns the kv pair that was already there.
158180 pub fn put(self: *Self, key: K, value: V) !?KV {
181 try self.autoCapacity();
182 return putAssumeCapacity(self, key, value);
183 }
184
185 pub fn putAssumeCapacity(self: *Self, key: K, value: V) ?KV {
186 assert(self.count() < self.entries.len);
159187 self.incrementModificationCount();
160 try self.ensureCapacity();
161188
162189 const put_result = self.internalPut(key);
163190 put_result.new_entry.kv.value = value;
......@@ -175,7 +202,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
175202 return hm.get(key) != null;
176203 }
177204
178 pub fn remove(hm: *Self, key: K) ?*KV {
205 pub fn remove(hm: *Self, key: K) ?KV {
179206 if (hm.entries.len == 0) return null;
180207 hm.incrementModificationCount();
181208 const start_index = hm.keyToIndex(key);
......@@ -189,13 +216,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
189216
190217 if (!eql(entry.kv.key, key)) continue;
191218
219 const removed_kv = entry.kv;
192220 while (roll_over < hm.entries.len) : (roll_over += 1) {
193221 const next_index = (start_index + roll_over + 1) % hm.entries.len;
194222 const next_entry = &hm.entries[next_index];
195223 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
196224 entry.used = false;
197225 hm.size -= 1;
198 return &entry.kv;
226 return removed_kv;
199227 }
200228 entry.* = next_entry.*;
201229 entry.distance_from_start_index -= 1;
......@@ -226,6 +254,16 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
226254 return other;
227255 }
228256
257 fn autoCapacity(self: *Self) !void {
258 if (self.entries.len == 0) {
259 return self.ensureCapacityExact(16);
260 }
261 // if we get too full (60%), double the capacity
262 if (self.size * 5 >= self.entries.len * 3) {
263 return self.ensureCapacityExact(self.entries.len * 2);
264 }
265 }
266
229267 fn initCapacity(hm: *Self, capacity: usize) !void {
230268 hm.entries = try hm.allocator.alloc(Entry, capacity);
231269 hm.size = 0;
......@@ -371,7 +409,10 @@ test "basic hash map usage" {
371409
372410 testing.expect(map.contains(2));
373411 testing.expect(map.get(2).?.value == 22);
374 _ = map.remove(2);
412
413 const rmv1 = map.remove(2);
414 testing.expect(rmv1.?.key == 2);
415 testing.expect(rmv1.?.value == 22);
375416 testing.expect(map.remove(2) == null);
376417 testing.expect(map.get(2) == null);
377418}
......@@ -423,6 +464,24 @@ test "iterator hash map" {
423464 testing.expect(entry.value == values[0]);
424465}
425466
467test "ensure capacity" {
468 var direct_allocator = std.heap.DirectAllocator.init();
469 defer direct_allocator.deinit();
470
471 var map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);
472 defer map.deinit();
473
474 try map.ensureCapacity(20);
475 const initialCapacity = map.entries.len;
476 testing.expect(initialCapacity >= 20);
477 var i : i32 = 0;
478 while (i < 20) : (i += 1) {
479 testing.expect(map.putAssumeCapacity(i, i+10) == null);
480 }
481 // shouldn't resize from putAssumeCapacity
482 testing.expect(initialCapacity == map.entries.len);
483}
484
426485pub fn getHashPtrAddrFn(comptime K: type) (fn (K) u32) {
427486 return struct {
428487 fn hash(key: K) u32 {
std/heap.zig+405-73
......@@ -34,9 +34,6 @@ fn cShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new
3434/// Thread-safe and lock-free.
3535pub const DirectAllocator = struct {
3636 allocator: Allocator,
37 heap_handle: ?HeapHandle,
38
39 const HeapHandle = if (builtin.os == Os.windows) os.windows.HANDLE else void;
4037
4138 pub fn init() DirectAllocator {
4239 return DirectAllocator{
......@@ -44,21 +41,15 @@ pub const DirectAllocator = struct {
4441 .reallocFn = realloc,
4542 .shrinkFn = shrink,
4643 },
47 .heap_handle = if (builtin.os == Os.windows) null else {},
4844 };
4945 }
5046
51 pub fn deinit(self: *DirectAllocator) void {
52 switch (builtin.os) {
53 Os.windows => if (self.heap_handle) |heap_handle| {
54 _ = os.windows.HeapDestroy(heap_handle);
55 },
56 else => {},
57 }
58 }
47 pub fn deinit(self: *DirectAllocator) void {}
5948
6049 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
6150 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
51 if (n == 0)
52 return (([*]u8)(undefined))[0..0];
6253
6354 switch (builtin.os) {
6455 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
......@@ -68,39 +59,76 @@ pub const DirectAllocator = struct {
6859 if (addr == p.MAP_FAILED) return error.OutOfMemory;
6960 if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n];
7061
71 const aligned_addr = (addr & ~usize(alignment - 1)) + alignment;
72
73 // We can unmap the unused portions of our mmap, but we must only
74 // pass munmap bytes that exist outside our allocated pages or it
75 // will happily eat us too.
76
77 // Since alignment > page_size, we are by definition on a page boundary.
78 const unused_start = addr;
79 const unused_len = aligned_addr - 1 - unused_start;
80
81 const err = p.munmap(unused_start, unused_len);
82 assert(p.getErrno(err) == 0);
62 const aligned_addr = mem.alignForward(addr, alignment);
8363
84 // It is impossible that there is an unoccupied page at the top of our
85 // mmap.
64 // Unmap the extra bytes that were only requested in order to guarantee
65 // that the range of memory we were provided had a proper alignment in
66 // it somewhere. The extra bytes could be at the beginning, or end, or both.
67 const unused_start_len = aligned_addr - addr;
68 if (unused_start_len != 0) {
69 const err = p.munmap(addr, unused_start_len);
70 assert(p.getErrno(err) == 0);
71 }
72 const aligned_end_addr = std.mem.alignForward(aligned_addr + n, os.page_size);
73 const unused_end_len = addr + alloc_size - aligned_end_addr;
74 if (unused_end_len != 0) {
75 const err = p.munmap(aligned_end_addr, unused_end_len);
76 assert(p.getErrno(err) == 0);
77 }
8678
8779 return @intToPtr([*]u8, aligned_addr)[0..n];
8880 },
89 Os.windows => {
90 const amt = n + alignment + @sizeOf(usize);
91 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);
92 const heap_handle = optional_heap_handle orelse blk: {
93 const hh = os.windows.HeapCreate(0, amt, 0) orelse return error.OutOfMemory;
94 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse break :blk hh;
95 _ = os.windows.HeapDestroy(hh);
96 break :blk other_hh.?; // can't be null because of the cmpxchg
97 };
98 const ptr = os.windows.HeapAlloc(heap_handle, 0, amt) orelse return error.OutOfMemory;
99 const root_addr = @ptrToInt(ptr);
100 const adjusted_addr = mem.alignForward(root_addr, alignment);
101 const record_addr = adjusted_addr + n;
102 @intToPtr(*align(1) usize, record_addr).* = root_addr;
103 return @intToPtr([*]u8, adjusted_addr)[0..n];
81 .windows => {
82 const w = os.windows;
83
84 // Although officially it's at least aligned to page boundary,
85 // Windows is known to reserve pages on a 64K boundary. It's
86 // even more likely that the requested alignment is <= 64K than
87 // 4K, so we're just allocating blindly and hoping for the best.
88 // see https://devblogs.microsoft.com/oldnewthing/?p=42223
89 const addr = w.VirtualAlloc(
90 null,
91 n,
92 w.MEM_COMMIT | w.MEM_RESERVE,
93 w.PAGE_READWRITE,
94 ) orelse return error.OutOfMemory;
95
96 // If the allocation is sufficiently aligned, use it.
97 if (@ptrToInt(addr) & (alignment - 1) == 0) {
98 return @ptrCast([*]u8, addr)[0..n];
99 }
100
101 // If it wasn't, actually do an explicitely aligned allocation.
102 if (w.VirtualFree(addr, 0, w.MEM_RELEASE) == 0) unreachable;
103 const alloc_size = n + alignment;
104
105 const final_addr = while (true) {
106 // Reserve a range of memory large enough to find a sufficiently
107 // aligned address.
108 const reserved_addr = w.VirtualAlloc(
109 null,
110 alloc_size,
111 w.MEM_RESERVE,
112 w.PAGE_NOACCESS,
113 ) orelse return error.OutOfMemory;
114 const aligned_addr = mem.alignForward(@ptrToInt(reserved_addr), alignment);
115
116 // Release the reserved pages (not actually used).
117 if (w.VirtualFree(reserved_addr, 0, w.MEM_RELEASE) == 0) unreachable;
118
119 // At this point, it is possible that another thread has
120 // obtained some memory space that will cause the next
121 // VirtualAlloc call to fail. To handle this, we will retry
122 // until it succeeds.
123 if (w.VirtualAlloc(
124 @intToPtr(*c_void, aligned_addr),
125 n,
126 w.MEM_COMMIT | w.MEM_RESERVE,
127 w.PAGE_READWRITE,
128 )) |ptr| break ptr;
129 } else unreachable; // TODO else unreachable should not be necessary
130
131 return @ptrCast([*]u8, final_addr)[0..n];
104132 },
105133 else => @compileError("Unsupported OS"),
106134 }
......@@ -118,13 +146,31 @@ pub const DirectAllocator = struct {
118146 }
119147 return old_mem[0..new_size];
120148 },
121 Os.windows => return realloc(allocator, old_mem, old_align, new_size, new_align) catch {
122 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
123 const old_record_addr = old_adjusted_addr + old_mem.len;
124 const root_addr = @intToPtr(*align(1) usize, old_record_addr).*;
125 const old_ptr = @intToPtr(*c_void, root_addr);
126 const new_record_addr = old_record_addr - new_size + old_mem.len;
127 @intToPtr(*align(1) usize, new_record_addr).* = root_addr;
149 .windows => {
150 const w = os.windows;
151 if (new_size == 0) {
152 // From the docs:
153 // "If the dwFreeType parameter is MEM_RELEASE, this parameter
154 // must be 0 (zero). The function frees the entire region that
155 // is reserved in the initial allocation call to VirtualAlloc."
156 // So we can only use MEM_RELEASE when actually releasing the
157 // whole allocation.
158 if (w.VirtualFree(old_mem.ptr, 0, w.MEM_RELEASE) == 0) unreachable;
159 } else {
160 const base_addr = @ptrToInt(old_mem.ptr);
161 const old_addr_end = base_addr + old_mem.len;
162 const new_addr_end = base_addr + new_size;
163 const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
164 if (old_addr_end > new_addr_end_rounded) {
165 // For shrinking that is not releasing, we will only
166 // decommit the pages not needed anymore.
167 if (w.VirtualFree(
168 @intToPtr(*c_void, new_addr_end_rounded),
169 old_addr_end - new_addr_end_rounded,
170 w.MEM_DECOMMIT,
171 ) == 0) unreachable;
172 }
173 }
128174 return old_mem[0..new_size];
129175 },
130176 else => @compileError("Unsupported OS"),
......@@ -138,36 +184,168 @@ pub const DirectAllocator = struct {
138184 return shrink(allocator, old_mem, old_align, new_size, new_align);
139185 }
140186 const result = try alloc(allocator, new_size, new_align);
141 mem.copy(u8, result, old_mem);
142 _ = os.posix.munmap(@ptrToInt(old_mem.ptr), old_mem.len);
187 if (old_mem.len != 0) {
188 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
189 _ = os.posix.munmap(@ptrToInt(old_mem.ptr), old_mem.len);
190 }
143191 return result;
144192 },
145 Os.windows => {
146 if (old_mem.len == 0) return alloc(allocator, new_size, new_align);
193 .windows => {
194 if (old_mem.len == 0) {
195 return alloc(allocator, new_size, new_align);
196 }
197
198 if (new_size <= old_mem.len and new_align <= old_align) {
199 return shrink(allocator, old_mem, old_align, new_size, new_align);
200 }
201
202 const w = os.windows;
203 const base_addr = @ptrToInt(old_mem.ptr);
204
205 if (new_align > old_align and base_addr & (new_align - 1) != 0) {
206 // Current allocation doesn't satisfy the new alignment.
207 // For now we'll do a new one no matter what, but maybe
208 // there is something smarter to do instead.
209 const result = try alloc(allocator, new_size, new_align);
210 assert(old_mem.len != 0);
211 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
212 if (w.VirtualFree(old_mem.ptr, 0, w.MEM_RELEASE) == 0) unreachable;
147213
148 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
214 return result;
215 }
216
217 const old_addr_end = base_addr + old_mem.len;
218 const old_addr_end_rounded = mem.alignForward(old_addr_end, os.page_size);
219 const new_addr_end = base_addr + new_size;
220 const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
221 if (new_addr_end_rounded == old_addr_end_rounded) {
222 // The reallocation fits in the already allocated pages.
223 return @ptrCast([*]u8, old_mem.ptr)[0..new_size];
224 }
225 assert(new_addr_end_rounded > old_addr_end_rounded);
226
227 // We need to commit new pages.
228 const additional_size = new_addr_end - old_addr_end_rounded;
229 const realloc_addr = w.VirtualAlloc(
230 @intToPtr(*c_void, old_addr_end_rounded),
231 additional_size,
232 w.MEM_COMMIT | w.MEM_RESERVE,
233 w.PAGE_READWRITE,
234 ) orelse {
235 // Committing new pages at the end of the existing allocation
236 // failed, we need to try a new one.
237 const new_alloc_mem = try alloc(allocator, new_size, new_align);
238 @memcpy(new_alloc_mem.ptr, old_mem.ptr, old_mem.len);
239 if (w.VirtualFree(old_mem.ptr, 0, w.MEM_RELEASE) == 0) unreachable;
240
241 return new_alloc_mem;
242 };
243
244 assert(@ptrToInt(realloc_addr) == old_addr_end_rounded);
245 return @ptrCast([*]u8, old_mem.ptr)[0..new_size];
246 },
247 else => @compileError("Unsupported OS"),
248 }
249 }
250};
251
252pub const HeapAllocator = switch (builtin.os) {
253 .windows => struct {
254 allocator: Allocator,
255 heap_handle: ?HeapHandle,
256
257 const HeapHandle = os.windows.HANDLE;
258
259 pub fn init() HeapAllocator {
260 return HeapAllocator{
261 .allocator = Allocator{
262 .reallocFn = realloc,
263 .shrinkFn = shrink,
264 },
265 .heap_handle = null,
266 };
267 }
268
269 pub fn deinit(self: *HeapAllocator) void {
270 if (self.heap_handle) |heap_handle| {
271 _ = os.windows.HeapDestroy(heap_handle);
272 }
273 }
274
275 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
276 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
277 if (n == 0)
278 return (([*]u8)(undefined))[0..0];
279
280 const amt = n + alignment + @sizeOf(usize);
281 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);
282 const heap_handle = optional_heap_handle orelse blk: {
283 const options = if (builtin.single_threaded) os.windows.HEAP_NO_SERIALIZE else 0;
284 const hh = os.windows.HeapCreate(options, amt, 0) orelse return error.OutOfMemory;
285 const other_hh = @cmpxchgStrong(?HeapHandle, &self.heap_handle, null, hh, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse break :blk hh;
286 _ = os.windows.HeapDestroy(hh);
287 break :blk other_hh.?; // can't be null because of the cmpxchg
288 };
289 const ptr = os.windows.HeapAlloc(heap_handle, 0, amt) orelse return error.OutOfMemory;
290 const root_addr = @ptrToInt(ptr);
291 const adjusted_addr = mem.alignForward(root_addr, alignment);
292 const record_addr = adjusted_addr + n;
293 @intToPtr(*align(1) usize, record_addr).* = root_addr;
294 return @intToPtr([*]u8, adjusted_addr)[0..n];
295 }
296
297 fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
298 return realloc(allocator, old_mem, old_align, new_size, new_align) catch {
149299 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
150300 const old_record_addr = old_adjusted_addr + old_mem.len;
151301 const root_addr = @intToPtr(*align(1) usize, old_record_addr).*;
152302 const old_ptr = @intToPtr(*c_void, root_addr);
153 const amt = new_size + new_align + @sizeOf(usize);
154 const new_ptr = os.windows.HeapReAlloc(
155 self.heap_handle.?,
156 0,
157 old_ptr,
158 amt,
159 ) orelse return error.OutOfMemory;
160 const offset = old_adjusted_addr - root_addr;
161 const new_root_addr = @ptrToInt(new_ptr);
162 const new_adjusted_addr = new_root_addr + offset;
163 assert(new_adjusted_addr % new_align == 0);
164 const new_record_addr = new_adjusted_addr + new_size;
165 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;
166 return @intToPtr([*]u8, new_adjusted_addr)[0..new_size];
167 },
168 else => @compileError("Unsupported OS"),
303 const new_record_addr = old_record_addr - new_size + old_mem.len;
304 @intToPtr(*align(1) usize, new_record_addr).* = root_addr;
305 return old_mem[0..new_size];
306 };
169307 }
170 }
308
309 fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
310 if (old_mem.len == 0) return alloc(allocator, new_size, new_align);
311
312 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
313 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
314 const old_record_addr = old_adjusted_addr + old_mem.len;
315 const root_addr = @intToPtr(*align(1) usize, old_record_addr).*;
316 const old_ptr = @intToPtr(*c_void, root_addr);
317
318 if (new_size == 0) {
319 if (os.windows.HeapFree(self.heap_handle.?, 0, old_ptr) == 0) unreachable;
320 return old_mem[0..0];
321 }
322
323 const amt = new_size + new_align + @sizeOf(usize);
324 const new_ptr = os.windows.HeapReAlloc(
325 self.heap_handle.?,
326 0,
327 old_ptr,
328 amt,
329 ) orelse return error.OutOfMemory;
330 const offset = old_adjusted_addr - root_addr;
331 const new_root_addr = @ptrToInt(new_ptr);
332 var new_adjusted_addr = new_root_addr + offset;
333 const offset_is_valid = new_adjusted_addr + new_size + @sizeOf(usize) <= new_root_addr + amt;
334 const offset_is_aligned = new_adjusted_addr % new_align == 0;
335 if (!offset_is_valid or !offset_is_aligned) {
336 // If HeapReAlloc didn't happen to move the memory to the new alignment,
337 // or the memory starting at the old offset would be outside of the new allocation,
338 // then we need to copy the memory to a valid aligned address and use that
339 const new_aligned_addr = mem.alignForward(new_root_addr, new_align);
340 @memcpy(@intToPtr([*]u8, new_aligned_addr), @intToPtr([*]u8, new_adjusted_addr), std.math.min(old_mem.len, new_size));
341 new_adjusted_addr = new_aligned_addr;
342 }
343 const new_record_addr = new_adjusted_addr + new_size;
344 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;
345 return @intToPtr([*]u8, new_adjusted_addr)[0..new_size];
346 }
347 },
348 else => @compileError("Unsupported OS"),
171349};
172350
173351/// This allocator takes an existing allocator, wraps it, and provides an interface
......@@ -250,7 +428,7 @@ pub const ArenaAllocator = struct {
250428 return error.OutOfMemory;
251429 } else {
252430 const result = try alloc(allocator, new_size, new_align);
253 mem.copy(u8, result, old_mem);
431 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
254432 return result;
255433 }
256434 }
......@@ -306,6 +484,103 @@ pub const FixedBufferAllocator = struct {
306484 } else if (new_size <= old_mem.len and new_align <= old_align) {
307485 // We can't do anything with the memory, so tell the client to keep it.
308486 return error.OutOfMemory;
487 } else {
488 const result = try alloc(allocator, new_size, new_align);
489 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
490 return result;
491 }
492 }
493
494 fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
495 return old_mem[0..new_size];
496 }
497};
498
499// FIXME: Exposed LLVM intrinsics is a bug
500// See: https://github.com/ziglang/zig/issues/2291
501extern fn @"llvm.wasm.memory.size.i32"(u32) u32;
502extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32;
503
504pub const wasm_allocator = &wasm_allocator_state.allocator;
505var wasm_allocator_state = WasmAllocator{
506 .allocator = Allocator{
507 .reallocFn = WasmAllocator.realloc,
508 .shrinkFn = WasmAllocator.shrink,
509 },
510 .start_ptr = undefined,
511 .num_pages = 0,
512 .end_index = 0,
513};
514
515const WasmAllocator = struct {
516 allocator: Allocator,
517 start_ptr: [*]u8,
518 num_pages: usize,
519 end_index: usize,
520
521 comptime {
522 if (builtin.arch != .wasm32) {
523 @compileError("WasmAllocator is only available for wasm32 arch");
524 }
525 }
526
527 fn alloc(allocator: *Allocator, size: usize, alignment: u29) ![]u8 {
528 const self = @fieldParentPtr(WasmAllocator, "allocator", allocator);
529
530 const addr = @ptrToInt(self.start_ptr) + self.end_index;
531 const adjusted_addr = mem.alignForward(addr, alignment);
532 const adjusted_index = self.end_index + (adjusted_addr - addr);
533 const new_end_index = adjusted_index + size;
534
535 if (new_end_index > self.num_pages * os.page_size) {
536 const required_memory = new_end_index - (self.num_pages * os.page_size);
537
538 var num_pages: usize = required_memory / os.page_size;
539 if (required_memory % os.page_size != 0) {
540 num_pages += 1;
541 }
542
543 const prev_page = @"llvm.wasm.memory.grow.i32"(0, @intCast(u32, num_pages));
544 if (prev_page == -1) {
545 return error.OutOfMemory;
546 }
547
548 self.num_pages += num_pages;
549 }
550
551 const result = self.start_ptr[adjusted_index..new_end_index];
552 self.end_index = new_end_index;
553
554 return result;
555 }
556
557 // Check if memory is the last "item" and is aligned correctly
558 fn is_last_item(allocator: *Allocator, memory: []u8, alignment: u29) bool {
559 const self = @fieldParentPtr(WasmAllocator, "allocator", allocator);
560 return memory.ptr == self.start_ptr + self.end_index - memory.len and mem.alignForward(@ptrToInt(memory.ptr), alignment) == @ptrToInt(memory.ptr);
561 }
562
563 fn realloc(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
564 const self = @fieldParentPtr(WasmAllocator, "allocator", allocator);
565
566 // Initialize start_ptr at the first realloc
567 if (self.num_pages == 0) {
568 self.start_ptr = @intToPtr([*]u8, @intCast(usize, @"llvm.wasm.memory.size.i32"(0)) * os.page_size);
569 }
570
571 if (is_last_item(allocator, old_mem, new_align)) {
572 const start_index = self.end_index - old_mem.len;
573 const new_end_index = start_index + new_size;
574
575 if (new_end_index > self.num_pages * os.page_size) {
576 _ = try alloc(allocator, new_end_index - self.end_index, new_align);
577 }
578 const result = self.start_ptr[start_index..new_end_index];
579
580 self.end_index = new_end_index;
581 return result;
582 } else if (new_size <= old_mem.len and new_align <= old_align) {
583 return error.OutOfMemory;
309584 } else {
310585 const result = try alloc(allocator, new_size, new_align);
311586 mem.copy(u8, result, old_mem);
......@@ -360,7 +635,7 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
360635 return error.OutOfMemory;
361636 } else {
362637 const result = try alloc(allocator, new_size, new_align);
363 mem.copy(u8, result, old_mem);
638 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
364639 return result;
365640 }
366641 }
......@@ -470,6 +745,31 @@ test "DirectAllocator" {
470745 try testAllocator(allocator);
471746 try testAllocatorAligned(allocator, 16);
472747 try testAllocatorLargeAlignment(allocator);
748 try testAllocatorAlignedShrink(allocator);
749
750 if (builtin.os == .windows) {
751 // Trying really large alignment. As mentionned in the implementation,
752 // VirtualAlloc returns 64K aligned addresses. We want to make sure
753 // DirectAllocator works beyond that, as it's not tested by
754 // `testAllocatorLargeAlignment`.
755 const slice = try allocator.alignedAlloc(u8, 1 << 20, 128);
756 slice[0] = 0x12;
757 slice[127] = 0x34;
758 allocator.free(slice);
759 }
760}
761
762test "HeapAllocator" {
763 if (builtin.os == .windows) {
764 var heap_allocator = HeapAllocator.init();
765 defer heap_allocator.deinit();
766
767 const allocator = &heap_allocator.allocator;
768 try testAllocator(allocator);
769 try testAllocatorAligned(allocator, 16);
770 try testAllocatorLargeAlignment(allocator);
771 try testAllocatorAlignedShrink(allocator);
772 }
473773}
474774
475775test "ArenaAllocator" {
......@@ -482,15 +782,17 @@ test "ArenaAllocator" {
482782 try testAllocator(&arena_allocator.allocator);
483783 try testAllocatorAligned(&arena_allocator.allocator, 16);
484784 try testAllocatorLargeAlignment(&arena_allocator.allocator);
785 try testAllocatorAlignedShrink(&arena_allocator.allocator);
485786}
486787
487var test_fixed_buffer_allocator_memory: [30000 * @sizeOf(usize)]u8 = undefined;
788var test_fixed_buffer_allocator_memory: [80000 * @sizeOf(u64)]u8 = undefined;
488789test "FixedBufferAllocator" {
489790 var fixed_buffer_allocator = FixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]);
490791
491792 try testAllocator(&fixed_buffer_allocator.allocator);
492793 try testAllocatorAligned(&fixed_buffer_allocator.allocator, 16);
493794 try testAllocatorLargeAlignment(&fixed_buffer_allocator.allocator);
795 try testAllocatorAlignedShrink(&fixed_buffer_allocator.allocator);
494796}
495797
496798test "FixedBufferAllocator Reuse memory on realloc" {
......@@ -528,6 +830,7 @@ test "ThreadSafeFixedBufferAllocator" {
528830 try testAllocator(&fixed_buffer_allocator.allocator);
529831 try testAllocatorAligned(&fixed_buffer_allocator.allocator, 16);
530832 try testAllocatorLargeAlignment(&fixed_buffer_allocator.allocator);
833 try testAllocatorAlignedShrink(&fixed_buffer_allocator.allocator);
531834}
532835
533836fn testAllocator(allocator: *mem.Allocator) !void {
......@@ -610,3 +913,32 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
610913
611914 allocator.free(slice);
612915}
916
917fn testAllocatorAlignedShrink(allocator: *mem.Allocator) mem.Allocator.Error!void {
918 var debug_buffer: [1000]u8 = undefined;
919 const debug_allocator = &FixedBufferAllocator.init(&debug_buffer).allocator;
920
921 const alloc_size = os.page_size * 2 + 50;
922 var slice = try allocator.alignedAlloc(u8, 16, alloc_size);
923 defer allocator.free(slice);
924
925 var stuff_to_free = std.ArrayList([]align(16) u8).init(debug_allocator);
926 // On Windows, VirtualAlloc returns addresses aligned to a 64K boundary,
927 // which is 16 pages, hence the 32. This test may require to increase
928 // the size of the allocations feeding the `allocator` parameter if they
929 // fail, because of this high over-alignment we want to have.
930 while (@ptrToInt(slice.ptr) == mem.alignForward(@ptrToInt(slice.ptr), os.page_size * 32)) {
931 try stuff_to_free.append(slice);
932 slice = try allocator.alignedAlloc(u8, 16, alloc_size);
933 }
934 while (stuff_to_free.popOrNull()) |item| {
935 allocator.free(item);
936 }
937 slice[0] = 0x12;
938 slice[60] = 0x34;
939
940 // realloc to a smaller size but with a larger alignment
941 slice = try allocator.alignedRealloc(slice, os.page_size * 32, alloc_size / 2);
942 testing.expect(slice[0] == 0x12);
943 testing.expect(slice[60] == 0x34);
944}
std/io.zig+24-17
......@@ -36,6 +36,7 @@ pub fn getStdIn() GetStdIoErrs!File {
3636}
3737
3838pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;
39pub const COutStream = @import("io/c_out_stream.zig").COutStream;
3940
4041pub fn InStream(comptime ReadError: type) type {
4142 return struct {
......@@ -194,8 +195,8 @@ pub fn InStream(comptime ReadError: type) type {
194195 return mem.readVarInt(ReturnType, bytes, endian);
195196 }
196197
197 pub fn skipBytes(self: *Self, num_bytes: usize) !void {
198 var i: usize = 0;
198 pub fn skipBytes(self: *Self, num_bytes: u64) !void {
199 var i: u64 = 0;
199200 while (i < num_bytes) : (i += 1) {
200201 _ = try self.readByte();
201202 }
......@@ -289,7 +290,7 @@ pub fn readFileAllocAligned(allocator: *mem.Allocator, path: []const u8, comptim
289290 var file = try File.openRead(path);
290291 defer file.close();
291292
292 const size = try file.getEndPos();
293 const size = try math.cast(usize, try file.getEndPos());
293294 const buf = try allocator.alignedAlloc(u8, A, size);
294295 errdefer allocator.free(buf);
295296
......@@ -742,7 +743,7 @@ pub fn CountingOutStream(comptime OutStreamError: type) type {
742743 pub const Error = OutStreamError;
743744
744745 pub stream: Stream,
745 pub bytes_written: usize,
746 pub bytes_written: u64,
746747 child_stream: *Stream,
747748
748749 pub fn init(child_stream: *Stream) Self {
......@@ -1089,8 +1090,11 @@ test "io.readLineSliceFrom" {
10891090}
10901091
10911092pub const Packing = enum {
1092 Byte, /// Pack data to byte alignment
1093 Bit, /// Pack data to bit alignment
1093 /// Pack data to byte alignment
1094 Byte,
1095
1096 /// Pack data to bit alignment
1097 Bit,
10941098};
10951099
10961100/// Creates a deserializer that deserializes types from any stream.
......@@ -1111,10 +1115,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
11111115 pub const Stream = InStream(Error);
11121116
11131117 pub fn init(in_stream: *Stream) Self {
1114 return Self{ .in_stream = switch (packing) {
1115 .Bit => BitInStream(endian, Stream.Error).init(in_stream),
1116 .Byte => in_stream,
1117 } };
1118 return Self{
1119 .in_stream = switch (packing) {
1120 .Bit => BitInStream(endian, Stream.Error).init(in_stream),
1121 .Byte => in_stream,
1122 },
1123 };
11181124 }
11191125
11201126 pub fn alignToByte(self: *Self) void {
......@@ -1281,7 +1287,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
12811287 ptr.* = null;
12821288 return;
12831289 }
1284
1290
12851291 ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe
12861292 const val_ptr = &ptr.*.?;
12871293 try self.deserializeInto(val_ptr);
......@@ -1320,10 +1326,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
13201326 pub const Stream = OutStream(Error);
13211327
13221328 pub fn init(out_stream: *Stream) Self {
1323 return Self{ .out_stream = switch (packing) {
1324 .Bit => BitOutStream(endian, Stream.Error).init(out_stream),
1325 .Byte => out_stream,
1326 } };
1329 return Self{
1330 .out_stream = switch (packing) {
1331 .Bit => BitOutStream(endian, Stream.Error).init(out_stream),
1332 .Byte => out_stream,
1333 },
1334 };
13271335 }
13281336
13291337 /// Flushes any unwritten bits to the stream
......@@ -1447,7 +1455,6 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
14471455
14481456test "import io tests" {
14491457 comptime {
1450 _ = @import("io_test.zig");
1458 _ = @import("io/test.zig");
14511459 }
14521460}
1453
std/io/c_out_stream.zig created+48
......@@ -0,0 +1,48 @@
1const std = @import("../std.zig");
2const OutStream = std.io.OutStream;
3const builtin = @import("builtin");
4const posix = std.os.posix;
5
6/// TODO make std.os.FILE use *FILE when linking libc and this just becomes
7/// std.io.FileOutStream because std.os.File.write would do this when linking
8/// libc.
9pub const COutStream = struct {
10 pub const Error = std.os.File.WriteError;
11 pub const Stream = OutStream(Error);
12
13 stream: Stream,
14 c_file: *std.c.FILE,
15
16 pub fn init(c_file: *std.c.FILE) COutStream {
17 return COutStream{
18 .c_file = c_file,
19 .stream = Stream{ .writeFn = writeFn },
20 };
21 }
22
23 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
24 const self = @fieldParentPtr(COutStream, "stream", out_stream);
25 const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, self.c_file);
26 if (amt_written == bytes.len) return;
27 // TODO errno on windows. should we have a posix layer for windows?
28 if (builtin.os == .windows) {
29 return error.InputOutput;
30 }
31 const errno = std.c._errno().*;
32 switch (errno) {
33 0 => unreachable,
34 posix.EINVAL => unreachable,
35 posix.EFAULT => unreachable,
36 posix.EAGAIN => unreachable, // this is a blocking API
37 posix.EBADF => unreachable, // always a race condition
38 posix.EDESTADDRREQ => unreachable, // connect was never called
39 posix.EDQUOT => return error.DiskQuota,
40 posix.EFBIG => return error.FileTooBig,
41 posix.EIO => return error.InputOutput,
42 posix.ENOSPC => return error.NoSpaceLeft,
43 posix.EPERM => return error.AccessDenied,
44 posix.EPIPE => return error.BrokenPipe,
45 else => return std.os.unexpectedErrorPosix(@intCast(usize, errno)),
46 }
47 }
48};
std/io/seekable_stream.zig+8-8
......@@ -7,25 +7,25 @@ pub fn SeekableStream(comptime SeekErrorType: type, comptime GetSeekPosErrorType
77 pub const SeekError = SeekErrorType;
88 pub const GetSeekPosError = GetSeekPosErrorType;
99
10 seekToFn: fn (self: *Self, pos: usize) SeekError!void,
11 seekForwardFn: fn (self: *Self, pos: isize) SeekError!void,
10 seekToFn: fn (self: *Self, pos: u64) SeekError!void,
11 seekForwardFn: fn (self: *Self, pos: i64) SeekError!void,
1212
13 getPosFn: fn (self: *Self) GetSeekPosError!usize,
14 getEndPosFn: fn (self: *Self) GetSeekPosError!usize,
13 getPosFn: fn (self: *Self) GetSeekPosError!u64,
14 getEndPosFn: fn (self: *Self) GetSeekPosError!u64,
1515
16 pub fn seekTo(self: *Self, pos: usize) SeekError!void {
16 pub fn seekTo(self: *Self, pos: u64) SeekError!void {
1717 return self.seekToFn(self, pos);
1818 }
1919
20 pub fn seekForward(self: *Self, amt: isize) SeekError!void {
20 pub fn seekForward(self: *Self, amt: i64) SeekError!void {
2121 return self.seekForwardFn(self, amt);
2222 }
2323
24 pub fn getEndPos(self: *Self) GetSeekPosError!usize {
24 pub fn getEndPos(self: *Self) GetSeekPosError!u64 {
2525 return self.getEndPosFn(self);
2626 }
2727
28 pub fn getPos(self: *Self) GetSeekPosError!usize {
28 pub fn getPos(self: *Self) GetSeekPosError!u64 {
2929 return self.getPosFn(self);
3030 }
3131 };
std/io/test.zig created+602
......@@ -0,0 +1,602 @@
1const std = @import("../std.zig");
2const io = std.io;
3const meta = std.meta;
4const trait = std.trait;
5const DefaultPrng = std.rand.DefaultPrng;
6const expect = std.testing.expect;
7const expectError = std.testing.expectError;
8const mem = std.mem;
9const os = std.os;
10const builtin = @import("builtin");
11
12test "write a file, read it, then delete it" {
13 var raw_bytes: [200 * 1024]u8 = undefined;
14 var allocator = &std.heap.FixedBufferAllocator.init(raw_bytes[0..]).allocator;
15
16 var data: [1024]u8 = undefined;
17 var prng = DefaultPrng.init(1234);
18 prng.random.bytes(data[0..]);
19 const tmp_file_name = "temp_test_file.txt";
20 {
21 var file = try os.File.openWrite(tmp_file_name);
22 defer file.close();
23
24 var file_out_stream = file.outStream();
25 var buf_stream = io.BufferedOutStream(os.File.WriteError).init(&file_out_stream.stream);
26 const st = &buf_stream.stream;
27 try st.print("begin");
28 try st.write(data[0..]);
29 try st.print("end");
30 try buf_stream.flush();
31 }
32
33 {
34 // make sure openWriteNoClobber doesn't harm the file
35 if (os.File.openWriteNoClobber(tmp_file_name, os.File.default_mode)) |file| {
36 unreachable;
37 } else |err| {
38 std.debug.assert(err == os.File.OpenError.PathAlreadyExists);
39 }
40 }
41
42 {
43 var file = try os.File.openRead(tmp_file_name);
44 defer file.close();
45
46 const file_size = try file.getEndPos();
47 const expected_file_size = "begin".len + data.len + "end".len;
48 expect(file_size == expected_file_size);
49
50 var file_in_stream = file.inStream();
51 var buf_stream = io.BufferedInStream(os.File.ReadError).init(&file_in_stream.stream);
52 const st = &buf_stream.stream;
53 const contents = try st.readAllAlloc(allocator, 2 * 1024);
54 defer allocator.free(contents);
55
56 expect(mem.eql(u8, contents[0.."begin".len], "begin"));
57 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
58 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
59 }
60 try os.deleteFile(tmp_file_name);
61}
62
63test "BufferOutStream" {
64 var bytes: [100]u8 = undefined;
65 var allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
66
67 var buffer = try std.Buffer.initSize(allocator, 0);
68 var buf_stream = &std.io.BufferOutStream.init(&buffer).stream;
69
70 const x: i32 = 42;
71 const y: i32 = 1234;
72 try buf_stream.print("x: {}\ny: {}\n", x, y);
73
74 expect(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
75}
76
77test "SliceInStream" {
78 const bytes = []const u8{ 1, 2, 3, 4, 5, 6, 7 };
79 var ss = io.SliceInStream.init(bytes);
80
81 var dest: [4]u8 = undefined;
82
83 var read = try ss.stream.read(dest[0..4]);
84 expect(read == 4);
85 expect(mem.eql(u8, dest[0..4], bytes[0..4]));
86
87 read = try ss.stream.read(dest[0..4]);
88 expect(read == 3);
89 expect(mem.eql(u8, dest[0..3], bytes[4..7]));
90
91 read = try ss.stream.read(dest[0..4]);
92 expect(read == 0);
93}
94
95test "PeekStream" {
96 const bytes = []const u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
97 var ss = io.SliceInStream.init(bytes);
98 var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);
99
100 var dest: [4]u8 = undefined;
101
102 ps.putBackByte(9);
103 ps.putBackByte(10);
104
105 var read = try ps.stream.read(dest[0..4]);
106 expect(read == 4);
107 expect(dest[0] == 10);
108 expect(dest[1] == 9);
109 expect(mem.eql(u8, dest[2..4], bytes[0..2]));
110
111 read = try ps.stream.read(dest[0..4]);
112 expect(read == 4);
113 expect(mem.eql(u8, dest[0..4], bytes[2..6]));
114
115 read = try ps.stream.read(dest[0..4]);
116 expect(read == 2);
117 expect(mem.eql(u8, dest[0..2], bytes[6..8]));
118
119 ps.putBackByte(11);
120 ps.putBackByte(12);
121
122 read = try ps.stream.read(dest[0..4]);
123 expect(read == 2);
124 expect(dest[0] == 12);
125 expect(dest[1] == 11);
126}
127
128test "SliceOutStream" {
129 var buffer: [10]u8 = undefined;
130 var ss = io.SliceOutStream.init(buffer[0..]);
131
132 try ss.stream.write("Hello");
133 expect(mem.eql(u8, ss.getWritten(), "Hello"));
134
135 try ss.stream.write("world");
136 expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
137
138 expectError(error.OutOfSpace, ss.stream.write("!"));
139 expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
140
141 ss.reset();
142 expect(ss.getWritten().len == 0);
143
144 expectError(error.OutOfSpace, ss.stream.write("Hello world!"));
145 expect(mem.eql(u8, ss.getWritten(), "Hello worl"));
146}
147
148test "BitInStream" {
149 const mem_be = []u8{ 0b11001101, 0b00001011 };
150 const mem_le = []u8{ 0b00011101, 0b10010101 };
151
152 var mem_in_be = io.SliceInStream.init(mem_be[0..]);
153 const InError = io.SliceInStream.Error;
154 var bit_stream_be = io.BitInStream(builtin.Endian.Big, InError).init(&mem_in_be.stream);
155
156 var out_bits: usize = undefined;
157
158 expect(1 == try bit_stream_be.readBits(u2, 1, &out_bits));
159 expect(out_bits == 1);
160 expect(2 == try bit_stream_be.readBits(u5, 2, &out_bits));
161 expect(out_bits == 2);
162 expect(3 == try bit_stream_be.readBits(u128, 3, &out_bits));
163 expect(out_bits == 3);
164 expect(4 == try bit_stream_be.readBits(u8, 4, &out_bits));
165 expect(out_bits == 4);
166 expect(5 == try bit_stream_be.readBits(u9, 5, &out_bits));
167 expect(out_bits == 5);
168 expect(1 == try bit_stream_be.readBits(u1, 1, &out_bits));
169 expect(out_bits == 1);
170
171 mem_in_be.pos = 0;
172 bit_stream_be.bit_count = 0;
173 expect(0b110011010000101 == try bit_stream_be.readBits(u15, 15, &out_bits));
174 expect(out_bits == 15);
175
176 mem_in_be.pos = 0;
177 bit_stream_be.bit_count = 0;
178 expect(0b1100110100001011 == try bit_stream_be.readBits(u16, 16, &out_bits));
179 expect(out_bits == 16);
180
181 _ = try bit_stream_be.readBits(u0, 0, &out_bits);
182
183 expect(0 == try bit_stream_be.readBits(u1, 1, &out_bits));
184 expect(out_bits == 0);
185 expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1));
186
187 var mem_in_le = io.SliceInStream.init(mem_le[0..]);
188 var bit_stream_le = io.BitInStream(builtin.Endian.Little, InError).init(&mem_in_le.stream);
189
190 expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits));
191 expect(out_bits == 1);
192 expect(2 == try bit_stream_le.readBits(u5, 2, &out_bits));
193 expect(out_bits == 2);
194 expect(3 == try bit_stream_le.readBits(u128, 3, &out_bits));
195 expect(out_bits == 3);
196 expect(4 == try bit_stream_le.readBits(u8, 4, &out_bits));
197 expect(out_bits == 4);
198 expect(5 == try bit_stream_le.readBits(u9, 5, &out_bits));
199 expect(out_bits == 5);
200 expect(1 == try bit_stream_le.readBits(u1, 1, &out_bits));
201 expect(out_bits == 1);
202
203 mem_in_le.pos = 0;
204 bit_stream_le.bit_count = 0;
205 expect(0b001010100011101 == try bit_stream_le.readBits(u15, 15, &out_bits));
206 expect(out_bits == 15);
207
208 mem_in_le.pos = 0;
209 bit_stream_le.bit_count = 0;
210 expect(0b1001010100011101 == try bit_stream_le.readBits(u16, 16, &out_bits));
211 expect(out_bits == 16);
212
213 _ = try bit_stream_le.readBits(u0, 0, &out_bits);
214
215 expect(0 == try bit_stream_le.readBits(u1, 1, &out_bits));
216 expect(out_bits == 0);
217 expectError(error.EndOfStream, bit_stream_le.readBitsNoEof(u1, 1));
218}
219
220test "BitOutStream" {
221 var mem_be = []u8{0} ** 2;
222 var mem_le = []u8{0} ** 2;
223
224 var mem_out_be = io.SliceOutStream.init(mem_be[0..]);
225 const OutError = io.SliceOutStream.Error;
226 var bit_stream_be = io.BitOutStream(builtin.Endian.Big, OutError).init(&mem_out_be.stream);
227
228 try bit_stream_be.writeBits(u2(1), 1);
229 try bit_stream_be.writeBits(u5(2), 2);
230 try bit_stream_be.writeBits(u128(3), 3);
231 try bit_stream_be.writeBits(u8(4), 4);
232 try bit_stream_be.writeBits(u9(5), 5);
233 try bit_stream_be.writeBits(u1(1), 1);
234
235 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
236
237 mem_out_be.pos = 0;
238
239 try bit_stream_be.writeBits(u15(0b110011010000101), 15);
240 try bit_stream_be.flushBits();
241 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
242
243 mem_out_be.pos = 0;
244 try bit_stream_be.writeBits(u32(0b110011010000101), 16);
245 expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
246
247 try bit_stream_be.writeBits(u0(0), 0);
248
249 var mem_out_le = io.SliceOutStream.init(mem_le[0..]);
250 var bit_stream_le = io.BitOutStream(builtin.Endian.Little, OutError).init(&mem_out_le.stream);
251
252 try bit_stream_le.writeBits(u2(1), 1);
253 try bit_stream_le.writeBits(u5(2), 2);
254 try bit_stream_le.writeBits(u128(3), 3);
255 try bit_stream_le.writeBits(u8(4), 4);
256 try bit_stream_le.writeBits(u9(5), 5);
257 try bit_stream_le.writeBits(u1(1), 1);
258
259 expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
260
261 mem_out_le.pos = 0;
262 try bit_stream_le.writeBits(u15(0b110011010000101), 15);
263 try bit_stream_le.flushBits();
264 expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
265
266 mem_out_le.pos = 0;
267 try bit_stream_le.writeBits(u32(0b1100110100001011), 16);
268 expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
269
270 try bit_stream_le.writeBits(u0(0), 0);
271}
272
273test "BitStreams with File Stream" {
274 const tmp_file_name = "temp_test_file.txt";
275 {
276 var file = try os.File.openWrite(tmp_file_name);
277 defer file.close();
278
279 var file_out = file.outStream();
280 var file_out_stream = &file_out.stream;
281 const OutError = os.File.WriteError;
282 var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream);
283
284 try bit_stream.writeBits(u2(1), 1);
285 try bit_stream.writeBits(u5(2), 2);
286 try bit_stream.writeBits(u128(3), 3);
287 try bit_stream.writeBits(u8(4), 4);
288 try bit_stream.writeBits(u9(5), 5);
289 try bit_stream.writeBits(u1(1), 1);
290 try bit_stream.flushBits();
291 }
292 {
293 var file = try os.File.openRead(tmp_file_name);
294 defer file.close();
295
296 var file_in = file.inStream();
297 var file_in_stream = &file_in.stream;
298 const InError = os.File.ReadError;
299 var bit_stream = io.BitInStream(builtin.endian, InError).init(file_in_stream);
300
301 var out_bits: usize = undefined;
302
303 expect(1 == try bit_stream.readBits(u2, 1, &out_bits));
304 expect(out_bits == 1);
305 expect(2 == try bit_stream.readBits(u5, 2, &out_bits));
306 expect(out_bits == 2);
307 expect(3 == try bit_stream.readBits(u128, 3, &out_bits));
308 expect(out_bits == 3);
309 expect(4 == try bit_stream.readBits(u8, 4, &out_bits));
310 expect(out_bits == 4);
311 expect(5 == try bit_stream.readBits(u9, 5, &out_bits));
312 expect(out_bits == 5);
313 expect(1 == try bit_stream.readBits(u1, 1, &out_bits));
314 expect(out_bits == 1);
315
316 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
317 }
318 try os.deleteFile(tmp_file_name);
319}
320
321fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
322 //@NOTE: if this test is taking too long, reduce the maximum tested bitsize
323 const max_test_bitsize = 128;
324
325 const total_bytes = comptime blk: {
326 var bytes = 0;
327 comptime var i = 0;
328 while (i <= max_test_bitsize) : (i += 1) bytes += (i / 8) + @boolToInt(i % 8 > 0);
329 break :blk bytes * 2;
330 };
331
332 var data_mem: [total_bytes]u8 = undefined;
333 var out = io.SliceOutStream.init(data_mem[0..]);
334 const OutError = io.SliceOutStream.Error;
335 var out_stream = &out.stream;
336 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
337
338 var in = io.SliceInStream.init(data_mem[0..]);
339 const InError = io.SliceInStream.Error;
340 var in_stream = &in.stream;
341 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
342
343 comptime var i = 0;
344 inline while (i <= max_test_bitsize) : (i += 1) {
345 const U = @IntType(false, i);
346 const S = @IntType(true, i);
347 try serializer.serializeInt(U(i));
348 if (i != 0) try serializer.serializeInt(S(-1)) else try serializer.serialize(S(0));
349 }
350 try serializer.flush();
351
352 i = 0;
353 inline while (i <= max_test_bitsize) : (i += 1) {
354 const U = @IntType(false, i);
355 const S = @IntType(true, i);
356 const x = try deserializer.deserializeInt(U);
357 const y = try deserializer.deserializeInt(S);
358 expect(x == U(i));
359 if (i != 0) expect(y == S(-1)) else expect(y == 0);
360 }
361
362 const u8_bit_count = comptime meta.bitCount(u8);
363 //0 + 1 + 2 + ... n = (n * (n + 1)) / 2
364 //and we have each for unsigned and signed, so * 2
365 const total_bits = (max_test_bitsize * (max_test_bitsize + 1));
366 const extra_packed_byte = @boolToInt(total_bits % u8_bit_count > 0);
367 const total_packed_bytes = (total_bits / u8_bit_count) + extra_packed_byte;
368
369 expect(in.pos == if (packing == .Bit) total_packed_bytes else total_bytes);
370
371 //Verify that empty error set works with serializer.
372 //deserializer is covered by SliceInStream
373 const NullError = io.NullOutStream.Error;
374 var null_out = io.NullOutStream.init();
375 var null_out_stream = &null_out.stream;
376 var null_serializer = io.Serializer(endian, packing, NullError).init(null_out_stream);
377 try null_serializer.serialize(data_mem[0..]);
378 try null_serializer.flush();
379}
380
381test "Serializer/Deserializer Int" {
382 try testIntSerializerDeserializer(.Big, .Byte);
383 try testIntSerializerDeserializer(.Little, .Byte);
384 // TODO these tests are disabled due to tripping an LLVM assertion
385 // https://github.com/ziglang/zig/issues/2019
386 //try testIntSerializerDeserializer(builtin.Endian.Big, true);
387 //try testIntSerializerDeserializer(builtin.Endian.Little, true);
388}
389
390fn testIntSerializerDeserializerInfNaN(
391 comptime endian: builtin.Endian,
392 comptime packing: io.Packing,
393) !void {
394 const mem_size = (16 * 2 + 32 * 2 + 64 * 2 + 128 * 2) / comptime meta.bitCount(u8);
395 var data_mem: [mem_size]u8 = undefined;
396
397 var out = io.SliceOutStream.init(data_mem[0..]);
398 const OutError = io.SliceOutStream.Error;
399 var out_stream = &out.stream;
400 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
401
402 var in = io.SliceInStream.init(data_mem[0..]);
403 const InError = io.SliceInStream.Error;
404 var in_stream = &in.stream;
405 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
406
407 //@TODO: isInf/isNan not currently implemented for f128.
408 try serializer.serialize(std.math.nan(f16));
409 try serializer.serialize(std.math.inf(f16));
410 try serializer.serialize(std.math.nan(f32));
411 try serializer.serialize(std.math.inf(f32));
412 try serializer.serialize(std.math.nan(f64));
413 try serializer.serialize(std.math.inf(f64));
414 //try serializer.serialize(std.math.nan(f128));
415 //try serializer.serialize(std.math.inf(f128));
416 const nan_check_f16 = try deserializer.deserialize(f16);
417 const inf_check_f16 = try deserializer.deserialize(f16);
418 const nan_check_f32 = try deserializer.deserialize(f32);
419 const inf_check_f32 = try deserializer.deserialize(f32);
420 const nan_check_f64 = try deserializer.deserialize(f64);
421 const inf_check_f64 = try deserializer.deserialize(f64);
422 //const nan_check_f128 = try deserializer.deserialize(f128);
423 //const inf_check_f128 = try deserializer.deserialize(f128);
424 expect(std.math.isNan(nan_check_f16));
425 expect(std.math.isInf(inf_check_f16));
426 expect(std.math.isNan(nan_check_f32));
427 expect(std.math.isInf(inf_check_f32));
428 expect(std.math.isNan(nan_check_f64));
429 expect(std.math.isInf(inf_check_f64));
430 //expect(std.math.isNan(nan_check_f128));
431 //expect(std.math.isInf(inf_check_f128));
432}
433
434test "Serializer/Deserializer Int: Inf/NaN" {
435 try testIntSerializerDeserializerInfNaN(.Big, .Byte);
436 try testIntSerializerDeserializerInfNaN(.Little, .Byte);
437 try testIntSerializerDeserializerInfNaN(.Big, .Bit);
438 try testIntSerializerDeserializerInfNaN(.Little, .Bit);
439}
440
441fn testAlternateSerializer(self: var, serializer: var) !void {
442 try serializer.serialize(self.f_f16);
443}
444
445fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
446 const ColorType = enum(u4) {
447 RGB8 = 1,
448 RA16 = 2,
449 R32 = 3,
450 };
451
452 const TagAlign = union(enum(u32)) {
453 A: u8,
454 B: u8,
455 C: u8,
456 };
457
458 const Color = union(ColorType) {
459 RGB8: struct {
460 r: u8,
461 g: u8,
462 b: u8,
463 a: u8,
464 },
465 RA16: struct {
466 r: u16,
467 a: u16,
468 },
469 R32: u32,
470 };
471
472 const PackedStruct = packed struct {
473 f_i3: i3,
474 f_u2: u2,
475 };
476
477 //to test custom serialization
478 const Custom = struct {
479 f_f16: f16,
480 f_unused_u32: u32,
481
482 pub fn deserialize(self: *@This(), deserializer: var) !void {
483 try deserializer.deserializeInto(&self.f_f16);
484 self.f_unused_u32 = 47;
485 }
486
487 pub const serialize = testAlternateSerializer;
488 };
489
490 const MyStruct = struct {
491 f_i3: i3,
492 f_u8: u8,
493 f_tag_align: TagAlign,
494 f_u24: u24,
495 f_i19: i19,
496 f_void: void,
497 f_f32: f32,
498 f_f128: f128,
499 f_packed_0: PackedStruct,
500 f_i7arr: [10]i7,
501 f_of64n: ?f64,
502 f_of64v: ?f64,
503 f_color_type: ColorType,
504 f_packed_1: PackedStruct,
505 f_custom: Custom,
506 f_color: Color,
507 };
508
509 const my_inst = MyStruct{
510 .f_i3 = -1,
511 .f_u8 = 8,
512 .f_tag_align = TagAlign{ .B = 148 },
513 .f_u24 = 24,
514 .f_i19 = 19,
515 .f_void = {},
516 .f_f32 = 32.32,
517 .f_f128 = 128.128,
518 .f_packed_0 = PackedStruct{ .f_i3 = -1, .f_u2 = 2 },
519 .f_i7arr = [10]i7{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
520 .f_of64n = null,
521 .f_of64v = 64.64,
522 .f_color_type = ColorType.R32,
523 .f_packed_1 = PackedStruct{ .f_i3 = 1, .f_u2 = 1 },
524 .f_custom = Custom{ .f_f16 = 38.63, .f_unused_u32 = 47 },
525 .f_color = Color{ .R32 = 123822 },
526 };
527
528 var data_mem: [@sizeOf(MyStruct)]u8 = undefined;
529 var out = io.SliceOutStream.init(data_mem[0..]);
530 const OutError = io.SliceOutStream.Error;
531 var out_stream = &out.stream;
532 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
533
534 var in = io.SliceInStream.init(data_mem[0..]);
535 const InError = io.SliceInStream.Error;
536 var in_stream = &in.stream;
537 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
538
539 try serializer.serialize(my_inst);
540
541 const my_copy = try deserializer.deserialize(MyStruct);
542 expect(meta.eql(my_copy, my_inst));
543}
544
545test "Serializer/Deserializer generic" {
546 try testSerializerDeserializer(builtin.Endian.Big, .Byte);
547 try testSerializerDeserializer(builtin.Endian.Little, .Byte);
548 try testSerializerDeserializer(builtin.Endian.Big, .Bit);
549 try testSerializerDeserializer(builtin.Endian.Little, .Bit);
550}
551
552fn testBadData(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
553 const E = enum(u14) {
554 One = 1,
555 Two = 2,
556 };
557
558 const A = struct {
559 e: E,
560 };
561
562 const C = union(E) {
563 One: u14,
564 Two: f16,
565 };
566
567 var data_mem: [4]u8 = undefined;
568 var out = io.SliceOutStream.init(data_mem[0..]);
569 const OutError = io.SliceOutStream.Error;
570 var out_stream = &out.stream;
571 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
572
573 var in = io.SliceInStream.init(data_mem[0..]);
574 const InError = io.SliceInStream.Error;
575 var in_stream = &in.stream;
576 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
577
578 try serializer.serialize(u14(3));
579 expectError(error.InvalidEnumTag, deserializer.deserialize(A));
580 out.pos = 0;
581 try serializer.serialize(u14(3));
582 try serializer.serialize(u14(88));
583 expectError(error.InvalidEnumTag, deserializer.deserialize(C));
584}
585
586test "Deserializer bad data" {
587 try testBadData(.Big, .Byte);
588 try testBadData(.Little, .Byte);
589 try testBadData(.Big, .Bit);
590 try testBadData(.Little, .Bit);
591}
592
593test "c out stream" {
594 if (!builtin.link_libc) return error.SkipZigTest;
595
596 const filename = c"tmp_io_test_file.txt";
597 const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
598 defer std.os.deleteFileC(filename) catch {};
599
600 const out_stream = &io.COutStream.init(out_file).stream;
601 try out_stream.print("hi: {}\n", i32(123));
602}
std/io_test.zig deleted-591
......@@ -1,591 +0,0 @@
1const std = @import("std.zig");
2const io = std.io;
3const meta = std.meta;
4const trait = std.trait;
5const DefaultPrng = std.rand.DefaultPrng;
6const expect = std.testing.expect;
7const expectError = std.testing.expectError;
8const mem = std.mem;
9const os = std.os;
10const builtin = @import("builtin");
11
12test "write a file, read it, then delete it" {
13 var raw_bytes: [200 * 1024]u8 = undefined;
14 var allocator = &std.heap.FixedBufferAllocator.init(raw_bytes[0..]).allocator;
15
16 var data: [1024]u8 = undefined;
17 var prng = DefaultPrng.init(1234);
18 prng.random.bytes(data[0..]);
19 const tmp_file_name = "temp_test_file.txt";
20 {
21 var file = try os.File.openWrite(tmp_file_name);
22 defer file.close();
23
24 var file_out_stream = file.outStream();
25 var buf_stream = io.BufferedOutStream(os.File.WriteError).init(&file_out_stream.stream);
26 const st = &buf_stream.stream;
27 try st.print("begin");
28 try st.write(data[0..]);
29 try st.print("end");
30 try buf_stream.flush();
31 }
32
33 {
34 // make sure openWriteNoClobber doesn't harm the file
35 if (os.File.openWriteNoClobber(tmp_file_name, os.File.default_mode)) |file| {
36 unreachable;
37 } else |err| {
38 std.debug.assert(err == os.File.OpenError.PathAlreadyExists);
39 }
40 }
41
42 {
43 var file = try os.File.openRead(tmp_file_name);
44 defer file.close();
45
46 const file_size = try file.getEndPos();
47 const expected_file_size = "begin".len + data.len + "end".len;
48 expect(file_size == expected_file_size);
49
50 var file_in_stream = file.inStream();
51 var buf_stream = io.BufferedInStream(os.File.ReadError).init(&file_in_stream.stream);
52 const st = &buf_stream.stream;
53 const contents = try st.readAllAlloc(allocator, 2 * 1024);
54 defer allocator.free(contents);
55
56 expect(mem.eql(u8, contents[0.."begin".len], "begin"));
57 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
58 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
59 }
60 try os.deleteFile(tmp_file_name);
61}
62
63test "BufferOutStream" {
64 var bytes: [100]u8 = undefined;
65 var allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator;
66
67 var buffer = try std.Buffer.initSize(allocator, 0);
68 var buf_stream = &std.io.BufferOutStream.init(&buffer).stream;
69
70 const x: i32 = 42;
71 const y: i32 = 1234;
72 try buf_stream.print("x: {}\ny: {}\n", x, y);
73
74 expect(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
75}
76
77test "SliceInStream" {
78 const bytes = []const u8{ 1, 2, 3, 4, 5, 6, 7 };
79 var ss = io.SliceInStream.init(bytes);
80
81 var dest: [4]u8 = undefined;
82
83 var read = try ss.stream.read(dest[0..4]);
84 expect(read == 4);
85 expect(mem.eql(u8, dest[0..4], bytes[0..4]));
86
87 read = try ss.stream.read(dest[0..4]);
88 expect(read == 3);
89 expect(mem.eql(u8, dest[0..3], bytes[4..7]));
90
91 read = try ss.stream.read(dest[0..4]);
92 expect(read == 0);
93}
94
95test "PeekStream" {
96 const bytes = []const u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
97 var ss = io.SliceInStream.init(bytes);
98 var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);
99
100 var dest: [4]u8 = undefined;
101
102 ps.putBackByte(9);
103 ps.putBackByte(10);
104
105 var read = try ps.stream.read(dest[0..4]);
106 expect(read == 4);
107 expect(dest[0] == 10);
108 expect(dest[1] == 9);
109 expect(mem.eql(u8, dest[2..4], bytes[0..2]));
110
111 read = try ps.stream.read(dest[0..4]);
112 expect(read == 4);
113 expect(mem.eql(u8, dest[0..4], bytes[2..6]));
114
115 read = try ps.stream.read(dest[0..4]);
116 expect(read == 2);
117 expect(mem.eql(u8, dest[0..2], bytes[6..8]));
118
119 ps.putBackByte(11);
120 ps.putBackByte(12);
121
122 read = try ps.stream.read(dest[0..4]);
123 expect(read == 2);
124 expect(dest[0] == 12);
125 expect(dest[1] == 11);
126}
127
128test "SliceOutStream" {
129 var buffer: [10]u8 = undefined;
130 var ss = io.SliceOutStream.init(buffer[0..]);
131
132 try ss.stream.write("Hello");
133 expect(mem.eql(u8, ss.getWritten(), "Hello"));
134
135 try ss.stream.write("world");
136 expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
137
138 expectError(error.OutOfSpace, ss.stream.write("!"));
139 expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
140
141 ss.reset();
142 expect(ss.getWritten().len == 0);
143
144 expectError(error.OutOfSpace, ss.stream.write("Hello world!"));
145 expect(mem.eql(u8, ss.getWritten(), "Hello worl"));
146}
147
148test "BitInStream" {
149 const mem_be = []u8{ 0b11001101, 0b00001011 };
150 const mem_le = []u8{ 0b00011101, 0b10010101 };
151
152 var mem_in_be = io.SliceInStream.init(mem_be[0..]);
153 const InError = io.SliceInStream.Error;
154 var bit_stream_be = io.BitInStream(builtin.Endian.Big, InError).init(&mem_in_be.stream);
155
156 var out_bits: usize = undefined;
157
158 expect(1 == try bit_stream_be.readBits(u2, 1, &out_bits));
159 expect(out_bits == 1);
160 expect(2 == try bit_stream_be.readBits(u5, 2, &out_bits));
161 expect(out_bits == 2);
162 expect(3 == try bit_stream_be.readBits(u128, 3, &out_bits));
163 expect(out_bits == 3);
164 expect(4 == try bit_stream_be.readBits(u8, 4, &out_bits));
165 expect(out_bits == 4);
166 expect(5 == try bit_stream_be.readBits(u9, 5, &out_bits));
167 expect(out_bits == 5);
168 expect(1 == try bit_stream_be.readBits(u1, 1, &out_bits));
169 expect(out_bits == 1);
170
171 mem_in_be.pos = 0;
172 bit_stream_be.bit_count = 0;
173 expect(0b110011010000101 == try bit_stream_be.readBits(u15, 15, &out_bits));
174 expect(out_bits == 15);
175
176 mem_in_be.pos = 0;
177 bit_stream_be.bit_count = 0;
178 expect(0b1100110100001011 == try bit_stream_be.readBits(u16, 16, &out_bits));
179 expect(out_bits == 16);
180
181 _ = try bit_stream_be.readBits(u0, 0, &out_bits);
182
183 expect(0 == try bit_stream_be.readBits(u1, 1, &out_bits));
184 expect(out_bits == 0);
185 expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1));
186
187 var mem_in_le = io.SliceInStream.init(mem_le[0..]);
188 var bit_stream_le = io.BitInStream(builtin.Endian.Little, InError).init(&mem_in_le.stream);
189
190 expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits));
191 expect(out_bits == 1);
192 expect(2 == try bit_stream_le.readBits(u5, 2, &out_bits));
193 expect(out_bits == 2);
194 expect(3 == try bit_stream_le.readBits(u128, 3, &out_bits));
195 expect(out_bits == 3);
196 expect(4 == try bit_stream_le.readBits(u8, 4, &out_bits));
197 expect(out_bits == 4);
198 expect(5 == try bit_stream_le.readBits(u9, 5, &out_bits));
199 expect(out_bits == 5);
200 expect(1 == try bit_stream_le.readBits(u1, 1, &out_bits));
201 expect(out_bits == 1);
202
203 mem_in_le.pos = 0;
204 bit_stream_le.bit_count = 0;
205 expect(0b001010100011101 == try bit_stream_le.readBits(u15, 15, &out_bits));
206 expect(out_bits == 15);
207
208 mem_in_le.pos = 0;
209 bit_stream_le.bit_count = 0;
210 expect(0b1001010100011101 == try bit_stream_le.readBits(u16, 16, &out_bits));
211 expect(out_bits == 16);
212
213 _ = try bit_stream_le.readBits(u0, 0, &out_bits);
214
215 expect(0 == try bit_stream_le.readBits(u1, 1, &out_bits));
216 expect(out_bits == 0);
217 expectError(error.EndOfStream, bit_stream_le.readBitsNoEof(u1, 1));
218}
219
220test "BitOutStream" {
221 var mem_be = []u8{0} ** 2;
222 var mem_le = []u8{0} ** 2;
223
224 var mem_out_be = io.SliceOutStream.init(mem_be[0..]);
225 const OutError = io.SliceOutStream.Error;
226 var bit_stream_be = io.BitOutStream(builtin.Endian.Big, OutError).init(&mem_out_be.stream);
227
228 try bit_stream_be.writeBits(u2(1), 1);
229 try bit_stream_be.writeBits(u5(2), 2);
230 try bit_stream_be.writeBits(u128(3), 3);
231 try bit_stream_be.writeBits(u8(4), 4);
232 try bit_stream_be.writeBits(u9(5), 5);
233 try bit_stream_be.writeBits(u1(1), 1);
234
235 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
236
237 mem_out_be.pos = 0;
238
239 try bit_stream_be.writeBits(u15(0b110011010000101), 15);
240 try bit_stream_be.flushBits();
241 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
242
243 mem_out_be.pos = 0;
244 try bit_stream_be.writeBits(u32(0b110011010000101), 16);
245 expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
246
247 try bit_stream_be.writeBits(u0(0), 0);
248
249 var mem_out_le = io.SliceOutStream.init(mem_le[0..]);
250 var bit_stream_le = io.BitOutStream(builtin.Endian.Little, OutError).init(&mem_out_le.stream);
251
252 try bit_stream_le.writeBits(u2(1), 1);
253 try bit_stream_le.writeBits(u5(2), 2);
254 try bit_stream_le.writeBits(u128(3), 3);
255 try bit_stream_le.writeBits(u8(4), 4);
256 try bit_stream_le.writeBits(u9(5), 5);
257 try bit_stream_le.writeBits(u1(1), 1);
258
259 expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
260
261 mem_out_le.pos = 0;
262 try bit_stream_le.writeBits(u15(0b110011010000101), 15);
263 try bit_stream_le.flushBits();
264 expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
265
266 mem_out_le.pos = 0;
267 try bit_stream_le.writeBits(u32(0b1100110100001011), 16);
268 expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
269
270 try bit_stream_le.writeBits(u0(0), 0);
271}
272
273test "BitStreams with File Stream" {
274 const tmp_file_name = "temp_test_file.txt";
275 {
276 var file = try os.File.openWrite(tmp_file_name);
277 defer file.close();
278
279 var file_out = file.outStream();
280 var file_out_stream = &file_out.stream;
281 const OutError = os.File.WriteError;
282 var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream);
283
284 try bit_stream.writeBits(u2(1), 1);
285 try bit_stream.writeBits(u5(2), 2);
286 try bit_stream.writeBits(u128(3), 3);
287 try bit_stream.writeBits(u8(4), 4);
288 try bit_stream.writeBits(u9(5), 5);
289 try bit_stream.writeBits(u1(1), 1);
290 try bit_stream.flushBits();
291 }
292 {
293 var file = try os.File.openRead(tmp_file_name);
294 defer file.close();
295
296 var file_in = file.inStream();
297 var file_in_stream = &file_in.stream;
298 const InError = os.File.ReadError;
299 var bit_stream = io.BitInStream(builtin.endian, InError).init(file_in_stream);
300
301 var out_bits: usize = undefined;
302
303 expect(1 == try bit_stream.readBits(u2, 1, &out_bits));
304 expect(out_bits == 1);
305 expect(2 == try bit_stream.readBits(u5, 2, &out_bits));
306 expect(out_bits == 2);
307 expect(3 == try bit_stream.readBits(u128, 3, &out_bits));
308 expect(out_bits == 3);
309 expect(4 == try bit_stream.readBits(u8, 4, &out_bits));
310 expect(out_bits == 4);
311 expect(5 == try bit_stream.readBits(u9, 5, &out_bits));
312 expect(out_bits == 5);
313 expect(1 == try bit_stream.readBits(u1, 1, &out_bits));
314 expect(out_bits == 1);
315
316 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
317 }
318 try os.deleteFile(tmp_file_name);
319}
320
321fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
322 //@NOTE: if this test is taking too long, reduce the maximum tested bitsize
323 const max_test_bitsize = 128;
324
325 const total_bytes = comptime blk: {
326 var bytes = 0;
327 comptime var i = 0;
328 while (i <= max_test_bitsize) : (i += 1) bytes += (i / 8) + @boolToInt(i % 8 > 0);
329 break :blk bytes * 2;
330 };
331
332 var data_mem: [total_bytes]u8 = undefined;
333 var out = io.SliceOutStream.init(data_mem[0..]);
334 const OutError = io.SliceOutStream.Error;
335 var out_stream = &out.stream;
336 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
337
338 var in = io.SliceInStream.init(data_mem[0..]);
339 const InError = io.SliceInStream.Error;
340 var in_stream = &in.stream;
341 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
342
343 comptime var i = 0;
344 inline while (i <= max_test_bitsize) : (i += 1) {
345 const U = @IntType(false, i);
346 const S = @IntType(true, i);
347 try serializer.serializeInt(U(i));
348 if (i != 0) try serializer.serializeInt(S(-1)) else try serializer.serialize(S(0));
349 }
350 try serializer.flush();
351
352 i = 0;
353 inline while (i <= max_test_bitsize) : (i += 1) {
354 const U = @IntType(false, i);
355 const S = @IntType(true, i);
356 const x = try deserializer.deserializeInt(U);
357 const y = try deserializer.deserializeInt(S);
358 expect(x == U(i));
359 if (i != 0) expect(y == S(-1)) else expect(y == 0);
360 }
361
362 const u8_bit_count = comptime meta.bitCount(u8);
363 //0 + 1 + 2 + ... n = (n * (n + 1)) / 2
364 //and we have each for unsigned and signed, so * 2
365 const total_bits = (max_test_bitsize * (max_test_bitsize + 1));
366 const extra_packed_byte = @boolToInt(total_bits % u8_bit_count > 0);
367 const total_packed_bytes = (total_bits / u8_bit_count) + extra_packed_byte;
368
369 expect(in.pos == if (packing == .Bit) total_packed_bytes else total_bytes);
370
371 //Verify that empty error set works with serializer.
372 //deserializer is covered by SliceInStream
373 const NullError = io.NullOutStream.Error;
374 var null_out = io.NullOutStream.init();
375 var null_out_stream = &null_out.stream;
376 var null_serializer = io.Serializer(endian, packing, NullError).init(null_out_stream);
377 try null_serializer.serialize(data_mem[0..]);
378 try null_serializer.flush();
379}
380
381test "Serializer/Deserializer Int" {
382 try testIntSerializerDeserializer(.Big, .Byte);
383 try testIntSerializerDeserializer(.Little, .Byte);
384 // TODO these tests are disabled due to tripping an LLVM assertion
385 // https://github.com/ziglang/zig/issues/2019
386 //try testIntSerializerDeserializer(builtin.Endian.Big, true);
387 //try testIntSerializerDeserializer(builtin.Endian.Little, true);
388}
389
390fn testIntSerializerDeserializerInfNaN(
391 comptime endian: builtin.Endian,
392 comptime packing: io.Packing,
393) !void {
394 const mem_size = (16 * 2 + 32 * 2 + 64 * 2 + 128 * 2) / comptime meta.bitCount(u8);
395 var data_mem: [mem_size]u8 = undefined;
396
397 var out = io.SliceOutStream.init(data_mem[0..]);
398 const OutError = io.SliceOutStream.Error;
399 var out_stream = &out.stream;
400 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
401
402 var in = io.SliceInStream.init(data_mem[0..]);
403 const InError = io.SliceInStream.Error;
404 var in_stream = &in.stream;
405 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
406
407 //@TODO: isInf/isNan not currently implemented for f128.
408 try serializer.serialize(std.math.nan(f16));
409 try serializer.serialize(std.math.inf(f16));
410 try serializer.serialize(std.math.nan(f32));
411 try serializer.serialize(std.math.inf(f32));
412 try serializer.serialize(std.math.nan(f64));
413 try serializer.serialize(std.math.inf(f64));
414 //try serializer.serialize(std.math.nan(f128));
415 //try serializer.serialize(std.math.inf(f128));
416 const nan_check_f16 = try deserializer.deserialize(f16);
417 const inf_check_f16 = try deserializer.deserialize(f16);
418 const nan_check_f32 = try deserializer.deserialize(f32);
419 const inf_check_f32 = try deserializer.deserialize(f32);
420 const nan_check_f64 = try deserializer.deserialize(f64);
421 const inf_check_f64 = try deserializer.deserialize(f64);
422 //const nan_check_f128 = try deserializer.deserialize(f128);
423 //const inf_check_f128 = try deserializer.deserialize(f128);
424 expect(std.math.isNan(nan_check_f16));
425 expect(std.math.isInf(inf_check_f16));
426 expect(std.math.isNan(nan_check_f32));
427 expect(std.math.isInf(inf_check_f32));
428 expect(std.math.isNan(nan_check_f64));
429 expect(std.math.isInf(inf_check_f64));
430 //expect(std.math.isNan(nan_check_f128));
431 //expect(std.math.isInf(inf_check_f128));
432}
433
434test "Serializer/Deserializer Int: Inf/NaN" {
435 try testIntSerializerDeserializerInfNaN(.Big, .Byte);
436 try testIntSerializerDeserializerInfNaN(.Little, .Byte);
437 try testIntSerializerDeserializerInfNaN(.Big, .Bit);
438 try testIntSerializerDeserializerInfNaN(.Little, .Bit);
439}
440
441fn testAlternateSerializer(self: var, serializer: var) !void {
442 try serializer.serialize(self.f_f16);
443}
444
445fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
446 const ColorType = enum(u4) {
447 RGB8 = 1,
448 RA16 = 2,
449 R32 = 3,
450 };
451
452 const TagAlign = union(enum(u32)) {
453 A: u8,
454 B: u8,
455 C: u8,
456 };
457
458 const Color = union(ColorType) {
459 RGB8: struct {
460 r: u8,
461 g: u8,
462 b: u8,
463 a: u8,
464 },
465 RA16: struct {
466 r: u16,
467 a: u16,
468 },
469 R32: u32,
470 };
471
472 const PackedStruct = packed struct {
473 f_i3: i3,
474 f_u2: u2,
475 };
476
477 //to test custom serialization
478 const Custom = struct {
479 f_f16: f16,
480 f_unused_u32: u32,
481
482 pub fn deserialize(self: *@This(), deserializer: var) !void {
483 try deserializer.deserializeInto(&self.f_f16);
484 self.f_unused_u32 = 47;
485 }
486
487 pub const serialize = testAlternateSerializer;
488 };
489
490 const MyStruct = struct {
491 f_i3: i3,
492 f_u8: u8,
493 f_tag_align: TagAlign,
494 f_u24: u24,
495 f_i19: i19,
496 f_void: void,
497 f_f32: f32,
498 f_f128: f128,
499 f_packed_0: PackedStruct,
500 f_i7arr: [10]i7,
501 f_of64n: ?f64,
502 f_of64v: ?f64,
503 f_color_type: ColorType,
504 f_packed_1: PackedStruct,
505 f_custom: Custom,
506 f_color: Color,
507 };
508
509 const my_inst = MyStruct{
510 .f_i3 = -1,
511 .f_u8 = 8,
512 .f_tag_align = TagAlign{ .B = 148 },
513 .f_u24 = 24,
514 .f_i19 = 19,
515 .f_void = {},
516 .f_f32 = 32.32,
517 .f_f128 = 128.128,
518 .f_packed_0 = PackedStruct{ .f_i3 = -1, .f_u2 = 2 },
519 .f_i7arr = [10]i7{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
520 .f_of64n = null,
521 .f_of64v = 64.64,
522 .f_color_type = ColorType.R32,
523 .f_packed_1 = PackedStruct{ .f_i3 = 1, .f_u2 = 1 },
524 .f_custom = Custom{ .f_f16 = 38.63, .f_unused_u32 = 47 },
525 .f_color = Color{ .R32 = 123822 },
526 };
527
528 var data_mem: [@sizeOf(MyStruct)]u8 = undefined;
529 var out = io.SliceOutStream.init(data_mem[0..]);
530 const OutError = io.SliceOutStream.Error;
531 var out_stream = &out.stream;
532 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
533
534 var in = io.SliceInStream.init(data_mem[0..]);
535 const InError = io.SliceInStream.Error;
536 var in_stream = &in.stream;
537 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
538
539 try serializer.serialize(my_inst);
540
541 const my_copy = try deserializer.deserialize(MyStruct);
542 expect(meta.eql(my_copy, my_inst));
543}
544
545test "Serializer/Deserializer generic" {
546 try testSerializerDeserializer(builtin.Endian.Big, .Byte);
547 try testSerializerDeserializer(builtin.Endian.Little, .Byte);
548 try testSerializerDeserializer(builtin.Endian.Big, .Bit);
549 try testSerializerDeserializer(builtin.Endian.Little, .Bit);
550}
551
552fn testBadData(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
553 const E = enum(u14) {
554 One = 1,
555 Two = 2,
556 };
557
558 const A = struct {
559 e: E,
560 };
561
562 const C = union(E) {
563 One: u14,
564 Two: f16,
565 };
566
567 var data_mem: [4]u8 = undefined;
568 var out = io.SliceOutStream.init(data_mem[0..]);
569 const OutError = io.SliceOutStream.Error;
570 var out_stream = &out.stream;
571 var serializer = io.Serializer(endian, packing, OutError).init(out_stream);
572
573 var in = io.SliceInStream.init(data_mem[0..]);
574 const InError = io.SliceInStream.Error;
575 var in_stream = &in.stream;
576 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
577
578 try serializer.serialize(u14(3));
579 expectError(error.InvalidEnumTag, deserializer.deserialize(A));
580 out.pos = 0;
581 try serializer.serialize(u14(3));
582 try serializer.serialize(u14(88));
583 expectError(error.InvalidEnumTag, deserializer.deserialize(C));
584}
585
586test "Deserializer bad data" {
587 try testBadData(.Big, .Byte);
588 try testBadData(.Little, .Byte);
589 try testBadData(.Big, .Bit);
590 try testBadData(.Little, .Bit);
591}
std/json.zig+4
......@@ -1400,3 +1400,7 @@ test "json.parser.dynamic" {
14001400 const double = image.Object.get("double").?.value;
14011401 testing.expect(double.Float == 1.3412);
14021402}
1403
1404test "import more json tests" {
1405 _ = @import("json/test.zig");
1406}
std/json/test.zig created+1904
......@@ -0,0 +1,1904 @@
1// RFC 8529 conformance tests.
2//
3// Tests are taken from https://github.com/nst/JSONTestSuite
4// Read also http://seriot.ch/parsing_json.php for a good overview.
5
6const std = @import("../std.zig");
7
8fn ok(comptime s: []const u8) void {
9 std.testing.expect(std.json.validate(s));
10}
11
12fn err(comptime s: []const u8) void {
13 std.testing.expect(!std.json.validate(s));
14}
15
16fn any(comptime s: []const u8) void {
17 std.testing.expect(true);
18}
19
20////////////////////////////////////////////////////////////////////////////////////////////////////
21//
22// Additional tests not part of test JSONTestSuite.
23
24test "y_trailing_comma_after_empty" {
25 ok(
26 \\{"1":[],"2":{},"3":"4"}
27 );
28}
29
30////////////////////////////////////////////////////////////////////////////////////////////////////
31
32test "y_array_arraysWithSpaces" {
33 ok(
34 \\[[] ]
35 );
36}
37
38test "y_array_empty" {
39 ok(
40 \\[]
41 );
42}
43
44test "y_array_empty-string" {
45 ok(
46 \\[""]
47 );
48}
49
50test "y_array_ending_with_newline" {
51 ok(
52 \\["a"]
53 );
54}
55
56test "y_array_false" {
57 ok(
58 \\[false]
59 );
60}
61
62test "y_array_heterogeneous" {
63 ok(
64 \\[null, 1, "1", {}]
65 );
66}
67
68test "y_array_null" {
69 ok(
70 \\[null]
71 );
72}
73
74test "y_array_with_1_and_newline" {
75 ok(
76 \\[1
77 \\]
78 );
79}
80
81test "y_array_with_leading_space" {
82 ok(
83 \\ [1]
84 );
85}
86
87test "y_array_with_several_null" {
88 ok(
89 \\[1,null,null,null,2]
90 );
91}
92
93test "y_array_with_trailing_space" {
94 ok("[2] ");
95}
96
97test "y_number_0e+1" {
98 ok(
99 \\[0e+1]
100 );
101}
102
103test "y_number_0e1" {
104 ok(
105 \\[0e1]
106 );
107}
108
109test "y_number_after_space" {
110 ok(
111 \\[ 4]
112 );
113}
114
115test "y_number_double_close_to_zero" {
116 ok(
117 \\[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]
118 );
119}
120
121test "y_number_int_with_exp" {
122 ok(
123 \\[20e1]
124 );
125}
126
127test "y_number" {
128 ok(
129 \\[123e65]
130 );
131}
132
133test "y_number_minus_zero" {
134 ok(
135 \\[-0]
136 );
137}
138
139test "y_number_negative_int" {
140 ok(
141 \\[-123]
142 );
143}
144
145test "y_number_negative_one" {
146 ok(
147 \\[-1]
148 );
149}
150
151test "y_number_negative_zero" {
152 ok(
153 \\[-0]
154 );
155}
156
157test "y_number_real_capital_e" {
158 ok(
159 \\[1E22]
160 );
161}
162
163test "y_number_real_capital_e_neg_exp" {
164 ok(
165 \\[1E-2]
166 );
167}
168
169test "y_number_real_capital_e_pos_exp" {
170 ok(
171 \\[1E+2]
172 );
173}
174
175test "y_number_real_exponent" {
176 ok(
177 \\[123e45]
178 );
179}
180
181test "y_number_real_fraction_exponent" {
182 ok(
183 \\[123.456e78]
184 );
185}
186
187test "y_number_real_neg_exp" {
188 ok(
189 \\[1e-2]
190 );
191}
192
193test "y_number_real_pos_exponent" {
194 ok(
195 \\[1e+2]
196 );
197}
198
199test "y_number_simple_int" {
200 ok(
201 \\[123]
202 );
203}
204
205test "y_number_simple_real" {
206 ok(
207 \\[123.456789]
208 );
209}
210
211test "y_object_basic" {
212 ok(
213 \\{"asd":"sdf"}
214 );
215}
216
217test "y_object_duplicated_key_and_value" {
218 ok(
219 \\{"a":"b","a":"b"}
220 );
221}
222
223test "y_object_duplicated_key" {
224 ok(
225 \\{"a":"b","a":"c"}
226 );
227}
228
229test "y_object_empty" {
230 ok(
231 \\{}
232 );
233}
234
235test "y_object_empty_key" {
236 ok(
237 \\{"":0}
238 );
239}
240
241test "y_object_escaped_null_in_key" {
242 ok(
243 \\{"foo\u0000bar": 42}
244 );
245}
246
247test "y_object_extreme_numbers" {
248 ok(
249 \\{ "min": -1.0e+28, "max": 1.0e+28 }
250 );
251}
252
253test "y_object" {
254 ok(
255 \\{"asd":"sdf", "dfg":"fgh"}
256 );
257}
258
259test "y_object_long_strings" {
260 ok(
261 \\{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
262 );
263}
264
265test "y_object_simple" {
266 ok(
267 \\{"a":[]}
268 );
269}
270
271test "y_object_string_unicode" {
272 ok(
273 \\{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
274 );
275}
276
277test "y_object_with_newlines" {
278 ok(
279 \\{
280 \\"a": "b"
281 \\}
282 );
283}
284
285test "y_string_1_2_3_bytes_UTF-8_sequences" {
286 ok(
287 \\["\u0060\u012a\u12AB"]
288 );
289}
290
291test "y_string_accepted_surrogate_pair" {
292 ok(
293 \\["\uD801\udc37"]
294 );
295}
296
297test "y_string_accepted_surrogate_pairs" {
298 ok(
299 \\["\ud83d\ude39\ud83d\udc8d"]
300 );
301}
302
303test "y_string_allowed_escapes" {
304 ok(
305 \\["\"\\\/\b\f\n\r\t"]
306 );
307}
308
309test "y_string_backslash_and_u_escaped_zero" {
310 ok(
311 \\["\\u0000"]
312 );
313}
314
315test "y_string_backslash_doublequotes" {
316 ok(
317 \\["\""]
318 );
319}
320
321test "y_string_comments" {
322 ok(
323 \\["a/*b*/c/*d//e"]
324 );
325}
326
327test "y_string_double_escape_a" {
328 ok(
329 \\["\\a"]
330 );
331}
332
333test "y_string_double_escape_n" {
334 ok(
335 \\["\\n"]
336 );
337}
338
339test "y_string_escaped_control_character" {
340 ok(
341 \\["\u0012"]
342 );
343}
344
345test "y_string_escaped_noncharacter" {
346 ok(
347 \\["\uFFFF"]
348 );
349}
350
351test "y_string_in_array" {
352 ok(
353 \\["asd"]
354 );
355}
356
357test "y_string_in_array_with_leading_space" {
358 ok(
359 \\[ "asd"]
360 );
361}
362
363test "y_string_last_surrogates_1_and_2" {
364 ok(
365 \\["\uDBFF\uDFFF"]
366 );
367}
368
369test "y_string_nbsp_uescaped" {
370 ok(
371 \\["new\u00A0line"]
372 );
373}
374
375test "y_string_nonCharacterInUTF-8_U+10FFFF" {
376 ok(
377 \\["􏿿"]
378 );
379}
380
381test "y_string_nonCharacterInUTF-8_U+FFFF" {
382 ok(
383 \\["￿"]
384 );
385}
386
387test "y_string_null_escape" {
388 ok(
389 \\["\u0000"]
390 );
391}
392
393test "y_string_one-byte-utf-8" {
394 ok(
395 \\["\u002c"]
396 );
397}
398
399test "y_string_pi" {
400 ok(
401 \\["π"]
402 );
403}
404
405test "y_string_reservedCharacterInUTF-8_U+1BFFF" {
406 ok(
407 \\["𛿿"]
408 );
409}
410
411test "y_string_simple_ascii" {
412 ok(
413 \\["asd "]
414 );
415}
416
417test "y_string_space" {
418 ok(
419 \\" "
420 );
421}
422
423test "y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF" {
424 ok(
425 \\["\uD834\uDd1e"]
426 );
427}
428
429test "y_string_three-byte-utf-8" {
430 ok(
431 \\["\u0821"]
432 );
433}
434
435test "y_string_two-byte-utf-8" {
436 ok(
437 \\["\u0123"]
438 );
439}
440
441test "y_string_u+2028_line_sep" {
442 ok("[\"\xe2\x80\xa8\"]");
443}
444
445test "y_string_u+2029_par_sep" {
446 ok("[\"\xe2\x80\xa9\"]");
447}
448
449test "y_string_uescaped_newline" {
450 ok(
451 \\["new\u000Aline"]
452 );
453}
454
455test "y_string_uEscape" {
456 ok(
457 \\["\u0061\u30af\u30EA\u30b9"]
458 );
459}
460
461test "y_string_unescaped_char_delete" {
462 ok("[\"\x7f\"]");
463}
464
465test "y_string_unicode_2" {
466 ok(
467 \\["⍂㈴⍂"]
468 );
469}
470
471test "y_string_unicodeEscapedBackslash" {
472 ok(
473 \\["\u005C"]
474 );
475}
476
477test "y_string_unicode_escaped_double_quote" {
478 ok(
479 \\["\u0022"]
480 );
481}
482
483test "y_string_unicode" {
484 ok(
485 \\["\uA66D"]
486 );
487}
488
489test "y_string_unicode_U+10FFFE_nonchar" {
490 ok(
491 \\["\uDBFF\uDFFE"]
492 );
493}
494
495test "y_string_unicode_U+1FFFE_nonchar" {
496 ok(
497 \\["\uD83F\uDFFE"]
498 );
499}
500
501test "y_string_unicode_U+200B_ZERO_WIDTH_SPACE" {
502 ok(
503 \\["\u200B"]
504 );
505}
506
507test "y_string_unicode_U+2064_invisible_plus" {
508 ok(
509 \\["\u2064"]
510 );
511}
512
513test "y_string_unicode_U+FDD0_nonchar" {
514 ok(
515 \\["\uFDD0"]
516 );
517}
518
519test "y_string_unicode_U+FFFE_nonchar" {
520 ok(
521 \\["\uFFFE"]
522 );
523}
524
525test "y_string_utf8" {
526 ok(
527 \\["€𝄞"]
528 );
529}
530
531test "y_string_with_del_character" {
532 ok("[\"a\x7fa\"]");
533}
534
535test "y_structure_lonely_false" {
536 ok(
537 \\false
538 );
539}
540
541test "y_structure_lonely_int" {
542 ok(
543 \\42
544 );
545}
546
547test "y_structure_lonely_negative_real" {
548 ok(
549 \\-0.1
550 );
551}
552
553test "y_structure_lonely_null" {
554 ok(
555 \\null
556 );
557}
558
559test "y_structure_lonely_string" {
560 ok(
561 \\"asd"
562 );
563}
564
565test "y_structure_lonely_true" {
566 ok(
567 \\true
568 );
569}
570
571test "y_structure_string_empty" {
572 ok(
573 \\""
574 );
575}
576
577test "y_structure_trailing_newline" {
578 ok(
579 \\["a"]
580 );
581}
582
583test "y_structure_true_in_array" {
584 ok(
585 \\[true]
586 );
587}
588
589test "y_structure_whitespace_array" {
590 ok(" [] ");
591}
592
593////////////////////////////////////////////////////////////////////////////////////////////////////
594
595test "n_array_1_true_without_comma" {
596 err(
597 \\[1 true]
598 );
599}
600
601test "n_array_a_invalid_utf8" {
602 err(
603 \\[aå]
604 );
605}
606
607test "n_array_colon_instead_of_comma" {
608 err(
609 \\["": 1]
610 );
611}
612
613test "n_array_comma_after_close" {
614 //err(
615 // \\[""],
616 //);
617}
618
619test "n_array_comma_and_number" {
620 err(
621 \\[,1]
622 );
623}
624
625test "n_array_double_comma" {
626 err(
627 \\[1,,2]
628 );
629}
630
631test "n_array_double_extra_comma" {
632 err(
633 \\["x",,]
634 );
635}
636
637test "n_array_extra_close" {
638 err(
639 \\["x"]]
640 );
641}
642
643test "n_array_extra_comma" {
644 //err(
645 // \\["",]
646 //);
647}
648
649test "n_array_incomplete_invalid_value" {
650 err(
651 \\[x
652 );
653}
654
655test "n_array_incomplete" {
656 err(
657 \\["x"
658 );
659}
660
661test "n_array_inner_array_no_comma" {
662 err(
663 \\[3[4]]
664 );
665}
666
667test "n_array_invalid_utf8" {
668 err(
669 \\[ÿ]
670 );
671}
672
673test "n_array_items_separated_by_semicolon" {
674 err(
675 \\[1:2]
676 );
677}
678
679test "n_array_just_comma" {
680 err(
681 \\[,]
682 );
683}
684
685test "n_array_just_minus" {
686 err(
687 \\[-]
688 );
689}
690
691test "n_array_missing_value" {
692 err(
693 \\[ , ""]
694 );
695}
696
697test "n_array_newlines_unclosed" {
698 err(
699 \\["a",
700 \\4
701 \\,1,
702 );
703}
704
705test "n_array_number_and_comma" {
706 err(
707 \\[1,]
708 );
709}
710
711test "n_array_number_and_several_commas" {
712 err(
713 \\[1,,]
714 );
715}
716
717test "n_array_spaces_vertical_tab_formfeed" {
718 err("[\"\x0aa\"\\f]");
719}
720
721test "n_array_star_inside" {
722 err(
723 \\[*]
724 );
725}
726
727test "n_array_unclosed" {
728 err(
729 \\[""
730 );
731}
732
733test "n_array_unclosed_trailing_comma" {
734 err(
735 \\[1,
736 );
737}
738
739test "n_array_unclosed_with_new_lines" {
740 err(
741 \\[1,
742 \\1
743 \\,1
744 );
745}
746
747test "n_array_unclosed_with_object_inside" {
748 err(
749 \\[{}
750 );
751}
752
753test "n_incomplete_false" {
754 err(
755 \\[fals]
756 );
757}
758
759test "n_incomplete_null" {
760 err(
761 \\[nul]
762 );
763}
764
765test "n_incomplete_true" {
766 err(
767 \\[tru]
768 );
769}
770
771test "n_multidigit_number_then_00" {
772 err("123\x00");
773}
774
775test "n_number_0.1.2" {
776 err(
777 \\[0.1.2]
778 );
779}
780
781test "n_number_-01" {
782 err(
783 \\[-01]
784 );
785}
786
787test "n_number_0.3e" {
788 err(
789 \\[0.3e]
790 );
791}
792
793test "n_number_0.3e+" {
794 err(
795 \\[0.3e+]
796 );
797}
798
799test "n_number_0_capital_E" {
800 err(
801 \\[0E]
802 );
803}
804
805test "n_number_0_capital_E+" {
806 err(
807 \\[0E+]
808 );
809}
810
811test "n_number_0.e1" {
812 err(
813 \\[0.e1]
814 );
815}
816
817test "n_number_0e" {
818 err(
819 \\[0e]
820 );
821}
822
823test "n_number_0e+" {
824 err(
825 \\[0e+]
826 );
827}
828
829test "n_number_1_000" {
830 err(
831 \\[1 000.0]
832 );
833}
834
835test "n_number_1.0e-" {
836 err(
837 \\[1.0e-]
838 );
839}
840
841test "n_number_1.0e" {
842 err(
843 \\[1.0e]
844 );
845}
846
847test "n_number_1.0e+" {
848 err(
849 \\[1.0e+]
850 );
851}
852
853test "n_number_-1.0." {
854 err(
855 \\[-1.0.]
856 );
857}
858
859test "n_number_1eE2" {
860 err(
861 \\[1eE2]
862 );
863}
864
865test "n_number_.-1" {
866 err(
867 \\[.-1]
868 );
869}
870
871test "n_number_+1" {
872 err(
873 \\[+1]
874 );
875}
876
877test "n_number_.2e-3" {
878 err(
879 \\[.2e-3]
880 );
881}
882
883test "n_number_2.e-3" {
884 err(
885 \\[2.e-3]
886 );
887}
888
889test "n_number_2.e+3" {
890 err(
891 \\[2.e+3]
892 );
893}
894
895test "n_number_2.e3" {
896 err(
897 \\[2.e3]
898 );
899}
900
901test "n_number_-2." {
902 err(
903 \\[-2.]
904 );
905}
906
907test "n_number_9.e+" {
908 err(
909 \\[9.e+]
910 );
911}
912
913test "n_number_expression" {
914 err(
915 \\[1+2]
916 );
917}
918
919test "n_number_hex_1_digit" {
920 err(
921 \\[0x1]
922 );
923}
924
925test "n_number_hex_2_digits" {
926 err(
927 \\[0x42]
928 );
929}
930
931test "n_number_infinity" {
932 err(
933 \\[Infinity]
934 );
935}
936
937test "n_number_+Inf" {
938 err(
939 \\[+Inf]
940 );
941}
942
943test "n_number_Inf" {
944 err(
945 \\[Inf]
946 );
947}
948
949test "n_number_invalid+-" {
950 err(
951 \\[0e+-1]
952 );
953}
954
955test "n_number_invalid-negative-real" {
956 err(
957 \\[-123.123foo]
958 );
959}
960
961test "n_number_invalid-utf-8-in-bigger-int" {
962 err(
963 \\[123å]
964 );
965}
966
967test "n_number_invalid-utf-8-in-exponent" {
968 err(
969 \\[1e1å]
970 );
971}
972
973test "n_number_invalid-utf-8-in-int" {
974 err(
975 \\[0å]
976 );
977}
978
979test "n_number_++" {
980 err(
981 \\[++1234]
982 );
983}
984
985test "n_number_minus_infinity" {
986 err(
987 \\[-Infinity]
988 );
989}
990
991test "n_number_minus_sign_with_trailing_garbage" {
992 err(
993 \\[-foo]
994 );
995}
996
997test "n_number_minus_space_1" {
998 err(
999 \\[- 1]
1000 );
1001}
1002
1003test "n_number_-NaN" {
1004 err(
1005 \\[-NaN]
1006 );
1007}
1008
1009test "n_number_NaN" {
1010 err(
1011 \\[NaN]
1012 );
1013}
1014
1015test "n_number_neg_int_starting_with_zero" {
1016 err(
1017 \\[-012]
1018 );
1019}
1020
1021test "n_number_neg_real_without_int_part" {
1022 err(
1023 \\[-.123]
1024 );
1025}
1026
1027test "n_number_neg_with_garbage_at_end" {
1028 err(
1029 \\[-1x]
1030 );
1031}
1032
1033test "n_number_real_garbage_after_e" {
1034 err(
1035 \\[1ea]
1036 );
1037}
1038
1039test "n_number_real_with_invalid_utf8_after_e" {
1040 err(
1041 \\[1eå]
1042 );
1043}
1044
1045test "n_number_real_without_fractional_part" {
1046 err(
1047 \\[1.]
1048 );
1049}
1050
1051test "n_number_starting_with_dot" {
1052 err(
1053 \\[.123]
1054 );
1055}
1056
1057test "n_number_U+FF11_fullwidth_digit_one" {
1058 err(
1059 \\[1]
1060 );
1061}
1062
1063test "n_number_with_alpha_char" {
1064 err(
1065 \\[1.8011670033376514H-308]
1066 );
1067}
1068
1069test "n_number_with_alpha" {
1070 err(
1071 \\[1.2a-3]
1072 );
1073}
1074
1075test "n_number_with_leading_zero" {
1076 err(
1077 \\[012]
1078 );
1079}
1080
1081test "n_object_bad_value" {
1082 err(
1083 \\["x", truth]
1084 );
1085}
1086
1087test "n_object_bracket_key" {
1088 err(
1089 \\{[: "x"}
1090 );
1091}
1092
1093test "n_object_comma_instead_of_colon" {
1094 err(
1095 \\{"x", null}
1096 );
1097}
1098
1099test "n_object_double_colon" {
1100 err(
1101 \\{"x"::"b"}
1102 );
1103}
1104
1105test "n_object_emoji" {
1106 err(
1107 \\{🇨🇭}
1108 );
1109}
1110
1111test "n_object_garbage_at_end" {
1112 err(
1113 \\{"a":"a" 123}
1114 );
1115}
1116
1117test "n_object_key_with_single_quotes" {
1118 err(
1119 \\{key: 'value'}
1120 );
1121}
1122
1123test "n_object_lone_continuation_byte_in_key_and_trailing_comma" {
1124 err(
1125 \\{"¹":"0",}
1126 );
1127}
1128
1129test "n_object_missing_colon" {
1130 err(
1131 \\{"a" b}
1132 );
1133}
1134
1135test "n_object_missing_key" {
1136 err(
1137 \\{:"b"}
1138 );
1139}
1140
1141test "n_object_missing_semicolon" {
1142 err(
1143 \\{"a" "b"}
1144 );
1145}
1146
1147test "n_object_missing_value" {
1148 err(
1149 \\{"a":
1150 );
1151}
1152
1153test "n_object_no-colon" {
1154 err(
1155 \\{"a"
1156 );
1157}
1158
1159test "n_object_non_string_key_but_huge_number_instead" {
1160 err(
1161 \\{9999E9999:1}
1162 );
1163}
1164
1165test "n_object_non_string_key" {
1166 err(
1167 \\{1:1}
1168 );
1169}
1170
1171test "n_object_repeated_null_null" {
1172 err(
1173 \\{null:null,null:null}
1174 );
1175}
1176
1177test "n_object_several_trailing_commas" {
1178 err(
1179 \\{"id":0,,,,,}
1180 );
1181}
1182
1183test "n_object_single_quote" {
1184 err(
1185 \\{'a':0}
1186 );
1187}
1188
1189test "n_object_trailing_comma" {
1190 err(
1191 \\{"id":0,}
1192 );
1193}
1194
1195test "n_object_trailing_comment" {
1196 err(
1197 \\{"a":"b"}/**/
1198 );
1199}
1200
1201test "n_object_trailing_comment_open" {
1202 err(
1203 \\{"a":"b"}/**//
1204 );
1205}
1206
1207test "n_object_trailing_comment_slash_open_incomplete" {
1208 err(
1209 \\{"a":"b"}/
1210 );
1211}
1212
1213test "n_object_trailing_comment_slash_open" {
1214 err(
1215 \\{"a":"b"}//
1216 );
1217}
1218
1219test "n_object_two_commas_in_a_row" {
1220 err(
1221 \\{"a":"b",,"c":"d"}
1222 );
1223}
1224
1225test "n_object_unquoted_key" {
1226 err(
1227 \\{a: "b"}
1228 );
1229}
1230
1231test "n_object_unterminated-value" {
1232 err(
1233 \\{"a":"a
1234 );
1235}
1236
1237test "n_object_with_single_string" {
1238 err(
1239 \\{ "foo" : "bar", "a" }
1240 );
1241}
1242
1243test "n_object_with_trailing_garbage" {
1244 err(
1245 \\{"a":"b"}#
1246 );
1247}
1248
1249test "n_single_space" {
1250 err(" ");
1251}
1252
1253test "n_string_1_surrogate_then_escape" {
1254 err(
1255 \\["\uD800\"]
1256 );
1257}
1258
1259test "n_string_1_surrogate_then_escape_u1" {
1260 err(
1261 \\["\uD800\u1"]
1262 );
1263}
1264
1265test "n_string_1_surrogate_then_escape_u1x" {
1266 err(
1267 \\["\uD800\u1x"]
1268 );
1269}
1270
1271test "n_string_1_surrogate_then_escape_u" {
1272 err(
1273 \\["\uD800\u"]
1274 );
1275}
1276
1277test "n_string_accentuated_char_no_quotes" {
1278 err(
1279 \\[é]
1280 );
1281}
1282
1283test "n_string_backslash_00" {
1284 err("[\"\x00\"]");
1285}
1286
1287test "n_string_escaped_backslash_bad" {
1288 err(
1289 \\["\\\"]
1290 );
1291}
1292
1293test "n_string_escaped_ctrl_char_tab" {
1294 err("\x5b\x22\x5c\x09\x22\x5d");
1295}
1296
1297test "n_string_escaped_emoji" {
1298 err("[\"\x5c\xc3\xb0\xc2\x9f\xc2\x8c\xc2\x80\"]");
1299}
1300
1301test "n_string_escape_x" {
1302 err(
1303 \\["\x00"]
1304 );
1305}
1306
1307test "n_string_incomplete_escaped_character" {
1308 err(
1309 \\["\u00A"]
1310 );
1311}
1312
1313test "n_string_incomplete_escape" {
1314 err(
1315 \\["\"]
1316 );
1317}
1318
1319test "n_string_incomplete_surrogate_escape_invalid" {
1320 err(
1321 \\["\uD800\uD800\x"]
1322 );
1323}
1324
1325test "n_string_incomplete_surrogate" {
1326 err(
1327 \\["\uD834\uDd"]
1328 );
1329}
1330
1331test "n_string_invalid_backslash_esc" {
1332 err(
1333 \\["\a"]
1334 );
1335}
1336
1337test "n_string_invalid_unicode_escape" {
1338 err(
1339 \\["\uqqqq"]
1340 );
1341}
1342
1343test "n_string_invalid_utf8_after_escape" {
1344 err("[\"\\\x75\xc3\xa5\"]");
1345}
1346
1347test "n_string_invalid-utf-8-in-escape" {
1348 err(
1349 \\["\uå"]
1350 );
1351}
1352
1353test "n_string_leading_uescaped_thinspace" {
1354 err(
1355 \\[\u0020"asd"]
1356 );
1357}
1358
1359test "n_string_no_quotes_with_bad_escape" {
1360 err(
1361 \\[\n]
1362 );
1363}
1364
1365test "n_string_single_doublequote" {
1366 err(
1367 \\"
1368 );
1369}
1370
1371test "n_string_single_quote" {
1372 err(
1373 \\['single quote']
1374 );
1375}
1376
1377test "n_string_single_string_no_double_quotes" {
1378 err(
1379 \\abc
1380 );
1381}
1382
1383test "n_string_start_escape_unclosed" {
1384 err(
1385 \\["\
1386 );
1387}
1388
1389test "n_string_unescaped_crtl_char" {
1390 err("[\"a\x00a\"]");
1391}
1392
1393test "n_string_unescaped_newline" {
1394 err(
1395 \\["new
1396 \\line"]
1397 );
1398}
1399
1400test "n_string_unescaped_tab" {
1401 err("[\"\t\"]");
1402}
1403
1404test "n_string_unicode_CapitalU" {
1405 err(
1406 \\"\UA66D"
1407 );
1408}
1409
1410test "n_string_with_trailing_garbage" {
1411 err(
1412 \\""x
1413 );
1414}
1415
1416test "n_structure_100000_opening_arrays" {
1417 err("[" ** 100000);
1418}
1419
1420test "n_structure_angle_bracket_." {
1421 err(
1422 \\<.>
1423 );
1424}
1425
1426test "n_structure_angle_bracket_null" {
1427 err(
1428 \\[<null>]
1429 );
1430}
1431
1432test "n_structure_array_trailing_garbage" {
1433 err(
1434 \\[1]x
1435 );
1436}
1437
1438test "n_structure_array_with_extra_array_close" {
1439 err(
1440 \\[1]]
1441 );
1442}
1443
1444test "n_structure_array_with_unclosed_string" {
1445 err(
1446 \\["asd]
1447 );
1448}
1449
1450test "n_structure_ascii-unicode-identifier" {
1451 err(
1452 \\aå
1453 );
1454}
1455
1456test "n_structure_capitalized_True" {
1457 err(
1458 \\[True]
1459 );
1460}
1461
1462test "n_structure_close_unopened_array" {
1463 err(
1464 \\1]
1465 );
1466}
1467
1468test "n_structure_comma_instead_of_closing_brace" {
1469 err(
1470 \\{"x": true,
1471 );
1472}
1473
1474test "n_structure_double_array" {
1475 err(
1476 \\[][]
1477 );
1478}
1479
1480test "n_structure_end_array" {
1481 err(
1482 \\]
1483 );
1484}
1485
1486test "n_structure_incomplete_UTF8_BOM" {
1487 err(
1488 \\ï»{}
1489 );
1490}
1491
1492test "n_structure_lone-invalid-utf-8" {
1493 err(
1494 \\å
1495 );
1496}
1497
1498test "n_structure_lone-open-bracket" {
1499 err(
1500 \\[
1501 );
1502}
1503
1504test "n_structure_no_data" {
1505 err(
1506 \\
1507 );
1508}
1509
1510test "n_structure_null-byte-outside-string" {
1511 err("[\x00]");
1512}
1513
1514test "n_structure_number_with_trailing_garbage" {
1515 err(
1516 \\2@
1517 );
1518}
1519
1520test "n_structure_object_followed_by_closing_object" {
1521 err(
1522 \\{}}
1523 );
1524}
1525
1526test "n_structure_object_unclosed_no_value" {
1527 err(
1528 \\{"":
1529 );
1530}
1531
1532test "n_structure_object_with_comment" {
1533 err(
1534 \\{"a":/*comment*/"b"}
1535 );
1536}
1537
1538test "n_structure_object_with_trailing_garbage" {
1539 err(
1540 \\{"a": true} "x"
1541 );
1542}
1543
1544test "n_structure_open_array_apostrophe" {
1545 err(
1546 \\['
1547 );
1548}
1549
1550test "n_structure_open_array_comma" {
1551 err(
1552 \\[,
1553 );
1554}
1555
1556test "n_structure_open_array_object" {
1557 err("[{\"\":" ** 50000);
1558}
1559
1560test "n_structure_open_array_open_object" {
1561 err(
1562 \\[{
1563 );
1564}
1565
1566test "n_structure_open_array_open_string" {
1567 err(
1568 \\["a
1569 );
1570}
1571
1572test "n_structure_open_array_string" {
1573 err(
1574 \\["a"
1575 );
1576}
1577
1578test "n_structure_open_object_close_array" {
1579 err(
1580 \\{]
1581 );
1582}
1583
1584test "n_structure_open_object_comma" {
1585 err(
1586 \\{,
1587 );
1588}
1589
1590test "n_structure_open_object" {
1591 err(
1592 \\{
1593 );
1594}
1595
1596test "n_structure_open_object_open_array" {
1597 err(
1598 \\{[
1599 );
1600}
1601
1602test "n_structure_open_object_open_string" {
1603 err(
1604 \\{"a
1605 );
1606}
1607
1608test "n_structure_open_object_string_with_apostrophes" {
1609 err(
1610 \\{'a'
1611 );
1612}
1613
1614test "n_structure_open_open" {
1615 err(
1616 \\["\{["\{["\{["\{
1617 );
1618}
1619
1620test "n_structure_single_eacute" {
1621 err(
1622 \\é
1623 );
1624}
1625
1626test "n_structure_single_star" {
1627 err(
1628 \\*
1629 );
1630}
1631
1632test "n_structure_trailing_#" {
1633 err(
1634 \\{"a":"b"}#{}
1635 );
1636}
1637
1638test "n_structure_U+2060_word_joined" {
1639 err(
1640 \\[⁠]
1641 );
1642}
1643
1644test "n_structure_uescaped_LF_before_string" {
1645 err(
1646 \\[\u000A""]
1647 );
1648}
1649
1650test "n_structure_unclosed_array" {
1651 err(
1652 \\[1
1653 );
1654}
1655
1656test "n_structure_unclosed_array_partial_null" {
1657 err(
1658 \\[ false, nul
1659 );
1660}
1661
1662test "n_structure_unclosed_array_unfinished_false" {
1663 err(
1664 \\[ true, fals
1665 );
1666}
1667
1668test "n_structure_unclosed_array_unfinished_true" {
1669 err(
1670 \\[ false, tru
1671 );
1672}
1673
1674test "n_structure_unclosed_object" {
1675 err(
1676 \\{"asd":"asd"
1677 );
1678}
1679
1680test "n_structure_unicode-identifier" {
1681 err(
1682 \\Ã¥
1683 );
1684}
1685
1686test "n_structure_UTF8_BOM_no_data" {
1687 err(
1688 \\
1689 );
1690}
1691
1692test "n_structure_whitespace_formfeed" {
1693 err("[\x0c]");
1694}
1695
1696test "n_structure_whitespace_U+2060_word_joiner" {
1697 err(
1698 \\[⁠]
1699 );
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////////////////////////
1703
1704test "i_number_double_huge_neg_exp" {
1705 any(
1706 \\[123.456e-789]
1707 );
1708}
1709
1710test "i_number_huge_exp" {
1711 any(
1712 \\[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
1713 );
1714}
1715
1716test "i_number_neg_int_huge_exp" {
1717 any(
1718 \\[-1e+9999]
1719 );
1720}
1721
1722test "i_number_pos_double_huge_exp" {
1723 any(
1724 \\[1.5e+9999]
1725 );
1726}
1727
1728test "i_number_real_neg_overflow" {
1729 any(
1730 \\[-123123e100000]
1731 );
1732}
1733
1734test "i_number_real_pos_overflow" {
1735 any(
1736 \\[123123e100000]
1737 );
1738}
1739
1740test "i_number_real_underflow" {
1741 any(
1742 \\[123e-10000000]
1743 );
1744}
1745
1746test "i_number_too_big_neg_int" {
1747 any(
1748 \\[-123123123123123123123123123123]
1749 );
1750}
1751
1752test "i_number_too_big_pos_int" {
1753 any(
1754 \\[100000000000000000000]
1755 );
1756}
1757
1758test "i_number_very_big_negative_int" {
1759 any(
1760 \\[-237462374673276894279832749832423479823246327846]
1761 );
1762}
1763
1764test "i_object_key_lone_2nd_surrogate" {
1765 any(
1766 \\{"\uDFAA":0}
1767 );
1768}
1769
1770test "i_string_1st_surrogate_but_2nd_missing" {
1771 any(
1772 \\["\uDADA"]
1773 );
1774}
1775
1776test "i_string_1st_valid_surrogate_2nd_invalid" {
1777 any(
1778 \\["\uD888\u1234"]
1779 );
1780}
1781
1782test "i_string_incomplete_surrogate_and_escape_valid" {
1783 any(
1784 \\["\uD800\n"]
1785 );
1786}
1787
1788test "i_string_incomplete_surrogate_pair" {
1789 any(
1790 \\["\uDd1ea"]
1791 );
1792}
1793
1794test "i_string_incomplete_surrogates_escape_valid" {
1795 any(
1796 \\["\uD800\uD800\n"]
1797 );
1798}
1799
1800test "i_string_invalid_lonely_surrogate" {
1801 any(
1802 \\["\ud800"]
1803 );
1804}
1805
1806test "i_string_invalid_surrogate" {
1807 any(
1808 \\["\ud800abc"]
1809 );
1810}
1811
1812test "i_string_invalid_utf-8" {
1813 any(
1814 \\["ÿ"]
1815 );
1816}
1817
1818test "i_string_inverted_surrogates_U+1D11E" {
1819 any(
1820 \\["\uDd1e\uD834"]
1821 );
1822}
1823
1824test "i_string_iso_latin_1" {
1825 any(
1826 \\["é"]
1827 );
1828}
1829
1830test "i_string_lone_second_surrogate" {
1831 any(
1832 \\["\uDFAA"]
1833 );
1834}
1835
1836test "i_string_lone_utf8_continuation_byte" {
1837 any(
1838 \\[""]
1839 );
1840}
1841
1842test "i_string_not_in_unicode_range" {
1843 any(
1844 \\["ô¿¿¿"]
1845 );
1846}
1847
1848test "i_string_overlong_sequence_2_bytes" {
1849 any(
1850 \\["À¯"]
1851 );
1852}
1853
1854test "i_string_overlong_sequence_6_bytes" {
1855 any(
1856 \\["üƒ¿¿¿¿"]
1857 );
1858}
1859
1860test "i_string_overlong_sequence_6_bytes_null" {
1861 any(
1862 \\["ü€€€€€"]
1863 );
1864}
1865
1866test "i_string_truncated-utf-8" {
1867 any(
1868 \\["àÿ"]
1869 );
1870}
1871
1872test "i_string_utf16BE_no_BOM" {
1873 any("\x00\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d");
1874}
1875
1876test "i_string_utf16LE_no_BOM" {
1877 any("\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1878}
1879
1880test "i_string_UTF-16LE_with_BOM" {
1881 any("\xc3\xbf\xc3\xbe\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1882}
1883
1884test "i_string_UTF-8_invalid_sequence" {
1885 any(
1886 \\["日шú"]
1887 );
1888}
1889
1890test "i_string_UTF8_surrogate_U+D800" {
1891 any(
1892 \\["í €"]
1893 );
1894}
1895
1896test "i_structure_500_nested_arrays" {
1897 any(("[" ** 500) ++ ("]" ** 500));
1898}
1899
1900test "i_structure_UTF-8_BOM_empty_object" {
1901 any(
1902 \\{}
1903 );
1904}
std/json_test.zig deleted-1904
......@@ -1,1904 +0,0 @@
1// RFC 8529 conformance tests.
2//
3// Tests are taken from https://github.com/nst/JSONTestSuite
4// Read also http://seriot.ch/parsing_json.php for a good overview.
5
6const std = @import("std.zig");
7
8fn ok(comptime s: []const u8) void {
9 std.testing.expect(std.json.validate(s));
10}
11
12fn err(comptime s: []const u8) void {
13 std.testing.expect(!std.json.validate(s));
14}
15
16fn any(comptime s: []const u8) void {
17 std.testing.expect(true);
18}
19
20////////////////////////////////////////////////////////////////////////////////////////////////////
21//
22// Additional tests not part of test JSONTestSuite.
23
24test "json.test.y_trailing_comma_after_empty" {
25 ok(
26 \\{"1":[],"2":{},"3":"4"}
27 );
28}
29
30////////////////////////////////////////////////////////////////////////////////////////////////////
31
32test "json.test.y_array_arraysWithSpaces" {
33 ok(
34 \\[[] ]
35 );
36}
37
38test "json.test.y_array_empty" {
39 ok(
40 \\[]
41 );
42}
43
44test "json.test.y_array_empty-string" {
45 ok(
46 \\[""]
47 );
48}
49
50test "json.test.y_array_ending_with_newline" {
51 ok(
52 \\["a"]
53 );
54}
55
56test "json.test.y_array_false" {
57 ok(
58 \\[false]
59 );
60}
61
62test "json.test.y_array_heterogeneous" {
63 ok(
64 \\[null, 1, "1", {}]
65 );
66}
67
68test "json.test.y_array_null" {
69 ok(
70 \\[null]
71 );
72}
73
74test "json.test.y_array_with_1_and_newline" {
75 ok(
76 \\[1
77 \\]
78 );
79}
80
81test "json.test.y_array_with_leading_space" {
82 ok(
83 \\ [1]
84 );
85}
86
87test "json.test.y_array_with_several_null" {
88 ok(
89 \\[1,null,null,null,2]
90 );
91}
92
93test "json.test.y_array_with_trailing_space" {
94 ok("[2] ");
95}
96
97test "json.test.y_number_0e+1" {
98 ok(
99 \\[0e+1]
100 );
101}
102
103test "json.test.y_number_0e1" {
104 ok(
105 \\[0e1]
106 );
107}
108
109test "json.test.y_number_after_space" {
110 ok(
111 \\[ 4]
112 );
113}
114
115test "json.test.y_number_double_close_to_zero" {
116 ok(
117 \\[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]
118 );
119}
120
121test "json.test.y_number_int_with_exp" {
122 ok(
123 \\[20e1]
124 );
125}
126
127test "json.test.y_number" {
128 ok(
129 \\[123e65]
130 );
131}
132
133test "json.test.y_number_minus_zero" {
134 ok(
135 \\[-0]
136 );
137}
138
139test "json.test.y_number_negative_int" {
140 ok(
141 \\[-123]
142 );
143}
144
145test "json.test.y_number_negative_one" {
146 ok(
147 \\[-1]
148 );
149}
150
151test "json.test.y_number_negative_zero" {
152 ok(
153 \\[-0]
154 );
155}
156
157test "json.test.y_number_real_capital_e" {
158 ok(
159 \\[1E22]
160 );
161}
162
163test "json.test.y_number_real_capital_e_neg_exp" {
164 ok(
165 \\[1E-2]
166 );
167}
168
169test "json.test.y_number_real_capital_e_pos_exp" {
170 ok(
171 \\[1E+2]
172 );
173}
174
175test "json.test.y_number_real_exponent" {
176 ok(
177 \\[123e45]
178 );
179}
180
181test "json.test.y_number_real_fraction_exponent" {
182 ok(
183 \\[123.456e78]
184 );
185}
186
187test "json.test.y_number_real_neg_exp" {
188 ok(
189 \\[1e-2]
190 );
191}
192
193test "json.test.y_number_real_pos_exponent" {
194 ok(
195 \\[1e+2]
196 );
197}
198
199test "json.test.y_number_simple_int" {
200 ok(
201 \\[123]
202 );
203}
204
205test "json.test.y_number_simple_real" {
206 ok(
207 \\[123.456789]
208 );
209}
210
211test "json.test.y_object_basic" {
212 ok(
213 \\{"asd":"sdf"}
214 );
215}
216
217test "json.test.y_object_duplicated_key_and_value" {
218 ok(
219 \\{"a":"b","a":"b"}
220 );
221}
222
223test "json.test.y_object_duplicated_key" {
224 ok(
225 \\{"a":"b","a":"c"}
226 );
227}
228
229test "json.test.y_object_empty" {
230 ok(
231 \\{}
232 );
233}
234
235test "json.test.y_object_empty_key" {
236 ok(
237 \\{"":0}
238 );
239}
240
241test "json.test.y_object_escaped_null_in_key" {
242 ok(
243 \\{"foo\u0000bar": 42}
244 );
245}
246
247test "json.test.y_object_extreme_numbers" {
248 ok(
249 \\{ "min": -1.0e+28, "max": 1.0e+28 }
250 );
251}
252
253test "json.test.y_object" {
254 ok(
255 \\{"asd":"sdf", "dfg":"fgh"}
256 );
257}
258
259test "json.test.y_object_long_strings" {
260 ok(
261 \\{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
262 );
263}
264
265test "json.test.y_object_simple" {
266 ok(
267 \\{"a":[]}
268 );
269}
270
271test "json.test.y_object_string_unicode" {
272 ok(
273 \\{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" }
274 );
275}
276
277test "json.test.y_object_with_newlines" {
278 ok(
279 \\{
280 \\"a": "b"
281 \\}
282 );
283}
284
285test "json.test.y_string_1_2_3_bytes_UTF-8_sequences" {
286 ok(
287 \\["\u0060\u012a\u12AB"]
288 );
289}
290
291test "json.test.y_string_accepted_surrogate_pair" {
292 ok(
293 \\["\uD801\udc37"]
294 );
295}
296
297test "json.test.y_string_accepted_surrogate_pairs" {
298 ok(
299 \\["\ud83d\ude39\ud83d\udc8d"]
300 );
301}
302
303test "json.test.y_string_allowed_escapes" {
304 ok(
305 \\["\"\\\/\b\f\n\r\t"]
306 );
307}
308
309test "json.test.y_string_backslash_and_u_escaped_zero" {
310 ok(
311 \\["\\u0000"]
312 );
313}
314
315test "json.test.y_string_backslash_doublequotes" {
316 ok(
317 \\["\""]
318 );
319}
320
321test "json.test.y_string_comments" {
322 ok(
323 \\["a/*b*/c/*d//e"]
324 );
325}
326
327test "json.test.y_string_double_escape_a" {
328 ok(
329 \\["\\a"]
330 );
331}
332
333test "json.test.y_string_double_escape_n" {
334 ok(
335 \\["\\n"]
336 );
337}
338
339test "json.test.y_string_escaped_control_character" {
340 ok(
341 \\["\u0012"]
342 );
343}
344
345test "json.test.y_string_escaped_noncharacter" {
346 ok(
347 \\["\uFFFF"]
348 );
349}
350
351test "json.test.y_string_in_array" {
352 ok(
353 \\["asd"]
354 );
355}
356
357test "json.test.y_string_in_array_with_leading_space" {
358 ok(
359 \\[ "asd"]
360 );
361}
362
363test "json.test.y_string_last_surrogates_1_and_2" {
364 ok(
365 \\["\uDBFF\uDFFF"]
366 );
367}
368
369test "json.test.y_string_nbsp_uescaped" {
370 ok(
371 \\["new\u00A0line"]
372 );
373}
374
375test "json.test.y_string_nonCharacterInUTF-8_U+10FFFF" {
376 ok(
377 \\["􏿿"]
378 );
379}
380
381test "json.test.y_string_nonCharacterInUTF-8_U+FFFF" {
382 ok(
383 \\["￿"]
384 );
385}
386
387test "json.test.y_string_null_escape" {
388 ok(
389 \\["\u0000"]
390 );
391}
392
393test "json.test.y_string_one-byte-utf-8" {
394 ok(
395 \\["\u002c"]
396 );
397}
398
399test "json.test.y_string_pi" {
400 ok(
401 \\["π"]
402 );
403}
404
405test "json.test.y_string_reservedCharacterInUTF-8_U+1BFFF" {
406 ok(
407 \\["𛿿"]
408 );
409}
410
411test "json.test.y_string_simple_ascii" {
412 ok(
413 \\["asd "]
414 );
415}
416
417test "json.test.y_string_space" {
418 ok(
419 \\" "
420 );
421}
422
423test "json.test.y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF" {
424 ok(
425 \\["\uD834\uDd1e"]
426 );
427}
428
429test "json.test.y_string_three-byte-utf-8" {
430 ok(
431 \\["\u0821"]
432 );
433}
434
435test "json.test.y_string_two-byte-utf-8" {
436 ok(
437 \\["\u0123"]
438 );
439}
440
441test "json.test.y_string_u+2028_line_sep" {
442 ok("[\"\xe2\x80\xa8\"]");
443}
444
445test "json.test.y_string_u+2029_par_sep" {
446 ok("[\"\xe2\x80\xa9\"]");
447}
448
449test "json.test.y_string_uescaped_newline" {
450 ok(
451 \\["new\u000Aline"]
452 );
453}
454
455test "json.test.y_string_uEscape" {
456 ok(
457 \\["\u0061\u30af\u30EA\u30b9"]
458 );
459}
460
461test "json.test.y_string_unescaped_char_delete" {
462 ok("[\"\x7f\"]");
463}
464
465test "json.test.y_string_unicode_2" {
466 ok(
467 \\["⍂㈴⍂"]
468 );
469}
470
471test "json.test.y_string_unicodeEscapedBackslash" {
472 ok(
473 \\["\u005C"]
474 );
475}
476
477test "json.test.y_string_unicode_escaped_double_quote" {
478 ok(
479 \\["\u0022"]
480 );
481}
482
483test "json.test.y_string_unicode" {
484 ok(
485 \\["\uA66D"]
486 );
487}
488
489test "json.test.y_string_unicode_U+10FFFE_nonchar" {
490 ok(
491 \\["\uDBFF\uDFFE"]
492 );
493}
494
495test "json.test.y_string_unicode_U+1FFFE_nonchar" {
496 ok(
497 \\["\uD83F\uDFFE"]
498 );
499}
500
501test "json.test.y_string_unicode_U+200B_ZERO_WIDTH_SPACE" {
502 ok(
503 \\["\u200B"]
504 );
505}
506
507test "json.test.y_string_unicode_U+2064_invisible_plus" {
508 ok(
509 \\["\u2064"]
510 );
511}
512
513test "json.test.y_string_unicode_U+FDD0_nonchar" {
514 ok(
515 \\["\uFDD0"]
516 );
517}
518
519test "json.test.y_string_unicode_U+FFFE_nonchar" {
520 ok(
521 \\["\uFFFE"]
522 );
523}
524
525test "json.test.y_string_utf8" {
526 ok(
527 \\["€𝄞"]
528 );
529}
530
531test "json.test.y_string_with_del_character" {
532 ok("[\"a\x7fa\"]");
533}
534
535test "json.test.y_structure_lonely_false" {
536 ok(
537 \\false
538 );
539}
540
541test "json.test.y_structure_lonely_int" {
542 ok(
543 \\42
544 );
545}
546
547test "json.test.y_structure_lonely_negative_real" {
548 ok(
549 \\-0.1
550 );
551}
552
553test "json.test.y_structure_lonely_null" {
554 ok(
555 \\null
556 );
557}
558
559test "json.test.y_structure_lonely_string" {
560 ok(
561 \\"asd"
562 );
563}
564
565test "json.test.y_structure_lonely_true" {
566 ok(
567 \\true
568 );
569}
570
571test "json.test.y_structure_string_empty" {
572 ok(
573 \\""
574 );
575}
576
577test "json.test.y_structure_trailing_newline" {
578 ok(
579 \\["a"]
580 );
581}
582
583test "json.test.y_structure_true_in_array" {
584 ok(
585 \\[true]
586 );
587}
588
589test "json.test.y_structure_whitespace_array" {
590 ok(" [] ");
591}
592
593////////////////////////////////////////////////////////////////////////////////////////////////////
594
595test "json.test.n_array_1_true_without_comma" {
596 err(
597 \\[1 true]
598 );
599}
600
601test "json.test.n_array_a_invalid_utf8" {
602 err(
603 \\[aå]
604 );
605}
606
607test "json.test.n_array_colon_instead_of_comma" {
608 err(
609 \\["": 1]
610 );
611}
612
613test "json.test.n_array_comma_after_close" {
614 //err(
615 // \\[""],
616 //);
617}
618
619test "json.test.n_array_comma_and_number" {
620 err(
621 \\[,1]
622 );
623}
624
625test "json.test.n_array_double_comma" {
626 err(
627 \\[1,,2]
628 );
629}
630
631test "json.test.n_array_double_extra_comma" {
632 err(
633 \\["x",,]
634 );
635}
636
637test "json.test.n_array_extra_close" {
638 err(
639 \\["x"]]
640 );
641}
642
643test "json.test.n_array_extra_comma" {
644 //err(
645 // \\["",]
646 //);
647}
648
649test "json.test.n_array_incomplete_invalid_value" {
650 err(
651 \\[x
652 );
653}
654
655test "json.test.n_array_incomplete" {
656 err(
657 \\["x"
658 );
659}
660
661test "json.test.n_array_inner_array_no_comma" {
662 err(
663 \\[3[4]]
664 );
665}
666
667test "json.test.n_array_invalid_utf8" {
668 err(
669 \\[ÿ]
670 );
671}
672
673test "json.test.n_array_items_separated_by_semicolon" {
674 err(
675 \\[1:2]
676 );
677}
678
679test "json.test.n_array_just_comma" {
680 err(
681 \\[,]
682 );
683}
684
685test "json.test.n_array_just_minus" {
686 err(
687 \\[-]
688 );
689}
690
691test "json.test.n_array_missing_value" {
692 err(
693 \\[ , ""]
694 );
695}
696
697test "json.test.n_array_newlines_unclosed" {
698 err(
699 \\["a",
700 \\4
701 \\,1,
702 );
703}
704
705test "json.test.n_array_number_and_comma" {
706 err(
707 \\[1,]
708 );
709}
710
711test "json.test.n_array_number_and_several_commas" {
712 err(
713 \\[1,,]
714 );
715}
716
717test "json.test.n_array_spaces_vertical_tab_formfeed" {
718 err("[\"\x0aa\"\\f]");
719}
720
721test "json.test.n_array_star_inside" {
722 err(
723 \\[*]
724 );
725}
726
727test "json.test.n_array_unclosed" {
728 err(
729 \\[""
730 );
731}
732
733test "json.test.n_array_unclosed_trailing_comma" {
734 err(
735 \\[1,
736 );
737}
738
739test "json.test.n_array_unclosed_with_new_lines" {
740 err(
741 \\[1,
742 \\1
743 \\,1
744 );
745}
746
747test "json.test.n_array_unclosed_with_object_inside" {
748 err(
749 \\[{}
750 );
751}
752
753test "json.test.n_incomplete_false" {
754 err(
755 \\[fals]
756 );
757}
758
759test "json.test.n_incomplete_null" {
760 err(
761 \\[nul]
762 );
763}
764
765test "json.test.n_incomplete_true" {
766 err(
767 \\[tru]
768 );
769}
770
771test "json.test.n_multidigit_number_then_00" {
772 err("123\x00");
773}
774
775test "json.test.n_number_0.1.2" {
776 err(
777 \\[0.1.2]
778 );
779}
780
781test "json.test.n_number_-01" {
782 err(
783 \\[-01]
784 );
785}
786
787test "json.test.n_number_0.3e" {
788 err(
789 \\[0.3e]
790 );
791}
792
793test "json.test.n_number_0.3e+" {
794 err(
795 \\[0.3e+]
796 );
797}
798
799test "json.test.n_number_0_capital_E" {
800 err(
801 \\[0E]
802 );
803}
804
805test "json.test.n_number_0_capital_E+" {
806 err(
807 \\[0E+]
808 );
809}
810
811test "json.test.n_number_0.e1" {
812 err(
813 \\[0.e1]
814 );
815}
816
817test "json.test.n_number_0e" {
818 err(
819 \\[0e]
820 );
821}
822
823test "json.test.n_number_0e+" {
824 err(
825 \\[0e+]
826 );
827}
828
829test "json.test.n_number_1_000" {
830 err(
831 \\[1 000.0]
832 );
833}
834
835test "json.test.n_number_1.0e-" {
836 err(
837 \\[1.0e-]
838 );
839}
840
841test "json.test.n_number_1.0e" {
842 err(
843 \\[1.0e]
844 );
845}
846
847test "json.test.n_number_1.0e+" {
848 err(
849 \\[1.0e+]
850 );
851}
852
853test "json.test.n_number_-1.0." {
854 err(
855 \\[-1.0.]
856 );
857}
858
859test "json.test.n_number_1eE2" {
860 err(
861 \\[1eE2]
862 );
863}
864
865test "json.test.n_number_.-1" {
866 err(
867 \\[.-1]
868 );
869}
870
871test "json.test.n_number_+1" {
872 err(
873 \\[+1]
874 );
875}
876
877test "json.test.n_number_.2e-3" {
878 err(
879 \\[.2e-3]
880 );
881}
882
883test "json.test.n_number_2.e-3" {
884 err(
885 \\[2.e-3]
886 );
887}
888
889test "json.test.n_number_2.e+3" {
890 err(
891 \\[2.e+3]
892 );
893}
894
895test "json.test.n_number_2.e3" {
896 err(
897 \\[2.e3]
898 );
899}
900
901test "json.test.n_number_-2." {
902 err(
903 \\[-2.]
904 );
905}
906
907test "json.test.n_number_9.e+" {
908 err(
909 \\[9.e+]
910 );
911}
912
913test "json.test.n_number_expression" {
914 err(
915 \\[1+2]
916 );
917}
918
919test "json.test.n_number_hex_1_digit" {
920 err(
921 \\[0x1]
922 );
923}
924
925test "json.test.n_number_hex_2_digits" {
926 err(
927 \\[0x42]
928 );
929}
930
931test "json.test.n_number_infinity" {
932 err(
933 \\[Infinity]
934 );
935}
936
937test "json.test.n_number_+Inf" {
938 err(
939 \\[+Inf]
940 );
941}
942
943test "json.test.n_number_Inf" {
944 err(
945 \\[Inf]
946 );
947}
948
949test "json.test.n_number_invalid+-" {
950 err(
951 \\[0e+-1]
952 );
953}
954
955test "json.test.n_number_invalid-negative-real" {
956 err(
957 \\[-123.123foo]
958 );
959}
960
961test "json.test.n_number_invalid-utf-8-in-bigger-int" {
962 err(
963 \\[123å]
964 );
965}
966
967test "json.test.n_number_invalid-utf-8-in-exponent" {
968 err(
969 \\[1e1å]
970 );
971}
972
973test "json.test.n_number_invalid-utf-8-in-int" {
974 err(
975 \\[0å]
976 );
977}
978
979test "json.test.n_number_++" {
980 err(
981 \\[++1234]
982 );
983}
984
985test "json.test.n_number_minus_infinity" {
986 err(
987 \\[-Infinity]
988 );
989}
990
991test "json.test.n_number_minus_sign_with_trailing_garbage" {
992 err(
993 \\[-foo]
994 );
995}
996
997test "json.test.n_number_minus_space_1" {
998 err(
999 \\[- 1]
1000 );
1001}
1002
1003test "json.test.n_number_-NaN" {
1004 err(
1005 \\[-NaN]
1006 );
1007}
1008
1009test "json.test.n_number_NaN" {
1010 err(
1011 \\[NaN]
1012 );
1013}
1014
1015test "json.test.n_number_neg_int_starting_with_zero" {
1016 err(
1017 \\[-012]
1018 );
1019}
1020
1021test "json.test.n_number_neg_real_without_int_part" {
1022 err(
1023 \\[-.123]
1024 );
1025}
1026
1027test "json.test.n_number_neg_with_garbage_at_end" {
1028 err(
1029 \\[-1x]
1030 );
1031}
1032
1033test "json.test.n_number_real_garbage_after_e" {
1034 err(
1035 \\[1ea]
1036 );
1037}
1038
1039test "json.test.n_number_real_with_invalid_utf8_after_e" {
1040 err(
1041 \\[1eå]
1042 );
1043}
1044
1045test "json.test.n_number_real_without_fractional_part" {
1046 err(
1047 \\[1.]
1048 );
1049}
1050
1051test "json.test.n_number_starting_with_dot" {
1052 err(
1053 \\[.123]
1054 );
1055}
1056
1057test "json.test.n_number_U+FF11_fullwidth_digit_one" {
1058 err(
1059 \\[1]
1060 );
1061}
1062
1063test "json.test.n_number_with_alpha_char" {
1064 err(
1065 \\[1.8011670033376514H-308]
1066 );
1067}
1068
1069test "json.test.n_number_with_alpha" {
1070 err(
1071 \\[1.2a-3]
1072 );
1073}
1074
1075test "json.test.n_number_with_leading_zero" {
1076 err(
1077 \\[012]
1078 );
1079}
1080
1081test "json.test.n_object_bad_value" {
1082 err(
1083 \\["x", truth]
1084 );
1085}
1086
1087test "json.test.n_object_bracket_key" {
1088 err(
1089 \\{[: "x"}
1090 );
1091}
1092
1093test "json.test.n_object_comma_instead_of_colon" {
1094 err(
1095 \\{"x", null}
1096 );
1097}
1098
1099test "json.test.n_object_double_colon" {
1100 err(
1101 \\{"x"::"b"}
1102 );
1103}
1104
1105test "json.test.n_object_emoji" {
1106 err(
1107 \\{🇨🇭}
1108 );
1109}
1110
1111test "json.test.n_object_garbage_at_end" {
1112 err(
1113 \\{"a":"a" 123}
1114 );
1115}
1116
1117test "json.test.n_object_key_with_single_quotes" {
1118 err(
1119 \\{key: 'value'}
1120 );
1121}
1122
1123test "json.test.n_object_lone_continuation_byte_in_key_and_trailing_comma" {
1124 err(
1125 \\{"¹":"0",}
1126 );
1127}
1128
1129test "json.test.n_object_missing_colon" {
1130 err(
1131 \\{"a" b}
1132 );
1133}
1134
1135test "json.test.n_object_missing_key" {
1136 err(
1137 \\{:"b"}
1138 );
1139}
1140
1141test "json.test.n_object_missing_semicolon" {
1142 err(
1143 \\{"a" "b"}
1144 );
1145}
1146
1147test "json.test.n_object_missing_value" {
1148 err(
1149 \\{"a":
1150 );
1151}
1152
1153test "json.test.n_object_no-colon" {
1154 err(
1155 \\{"a"
1156 );
1157}
1158
1159test "json.test.n_object_non_string_key_but_huge_number_instead" {
1160 err(
1161 \\{9999E9999:1}
1162 );
1163}
1164
1165test "json.test.n_object_non_string_key" {
1166 err(
1167 \\{1:1}
1168 );
1169}
1170
1171test "json.test.n_object_repeated_null_null" {
1172 err(
1173 \\{null:null,null:null}
1174 );
1175}
1176
1177test "json.test.n_object_several_trailing_commas" {
1178 err(
1179 \\{"id":0,,,,,}
1180 );
1181}
1182
1183test "json.test.n_object_single_quote" {
1184 err(
1185 \\{'a':0}
1186 );
1187}
1188
1189test "json.test.n_object_trailing_comma" {
1190 err(
1191 \\{"id":0,}
1192 );
1193}
1194
1195test "json.test.n_object_trailing_comment" {
1196 err(
1197 \\{"a":"b"}/**/
1198 );
1199}
1200
1201test "json.test.n_object_trailing_comment_open" {
1202 err(
1203 \\{"a":"b"}/**//
1204 );
1205}
1206
1207test "json.test.n_object_trailing_comment_slash_open_incomplete" {
1208 err(
1209 \\{"a":"b"}/
1210 );
1211}
1212
1213test "json.test.n_object_trailing_comment_slash_open" {
1214 err(
1215 \\{"a":"b"}//
1216 );
1217}
1218
1219test "json.test.n_object_two_commas_in_a_row" {
1220 err(
1221 \\{"a":"b",,"c":"d"}
1222 );
1223}
1224
1225test "json.test.n_object_unquoted_key" {
1226 err(
1227 \\{a: "b"}
1228 );
1229}
1230
1231test "json.test.n_object_unterminated-value" {
1232 err(
1233 \\{"a":"a
1234 );
1235}
1236
1237test "json.test.n_object_with_single_string" {
1238 err(
1239 \\{ "foo" : "bar", "a" }
1240 );
1241}
1242
1243test "json.test.n_object_with_trailing_garbage" {
1244 err(
1245 \\{"a":"b"}#
1246 );
1247}
1248
1249test "json.test.n_single_space" {
1250 err(" ");
1251}
1252
1253test "json.test.n_string_1_surrogate_then_escape" {
1254 err(
1255 \\["\uD800\"]
1256 );
1257}
1258
1259test "json.test.n_string_1_surrogate_then_escape_u1" {
1260 err(
1261 \\["\uD800\u1"]
1262 );
1263}
1264
1265test "json.test.n_string_1_surrogate_then_escape_u1x" {
1266 err(
1267 \\["\uD800\u1x"]
1268 );
1269}
1270
1271test "json.test.n_string_1_surrogate_then_escape_u" {
1272 err(
1273 \\["\uD800\u"]
1274 );
1275}
1276
1277test "json.test.n_string_accentuated_char_no_quotes" {
1278 err(
1279 \\[é]
1280 );
1281}
1282
1283test "json.test.n_string_backslash_00" {
1284 err("[\"\x00\"]");
1285}
1286
1287test "json.test.n_string_escaped_backslash_bad" {
1288 err(
1289 \\["\\\"]
1290 );
1291}
1292
1293test "json.test.n_string_escaped_ctrl_char_tab" {
1294 err("\x5b\x22\x5c\x09\x22\x5d");
1295}
1296
1297test "json.test.n_string_escaped_emoji" {
1298 err("[\"\x5c\xc3\xb0\xc2\x9f\xc2\x8c\xc2\x80\"]");
1299}
1300
1301test "json.test.n_string_escape_x" {
1302 err(
1303 \\["\x00"]
1304 );
1305}
1306
1307test "json.test.n_string_incomplete_escaped_character" {
1308 err(
1309 \\["\u00A"]
1310 );
1311}
1312
1313test "json.test.n_string_incomplete_escape" {
1314 err(
1315 \\["\"]
1316 );
1317}
1318
1319test "json.test.n_string_incomplete_surrogate_escape_invalid" {
1320 err(
1321 \\["\uD800\uD800\x"]
1322 );
1323}
1324
1325test "json.test.n_string_incomplete_surrogate" {
1326 err(
1327 \\["\uD834\uDd"]
1328 );
1329}
1330
1331test "json.test.n_string_invalid_backslash_esc" {
1332 err(
1333 \\["\a"]
1334 );
1335}
1336
1337test "json.test.n_string_invalid_unicode_escape" {
1338 err(
1339 \\["\uqqqq"]
1340 );
1341}
1342
1343test "json.test.n_string_invalid_utf8_after_escape" {
1344 err("[\"\\\x75\xc3\xa5\"]");
1345}
1346
1347test "json.test.n_string_invalid-utf-8-in-escape" {
1348 err(
1349 \\["\uå"]
1350 );
1351}
1352
1353test "json.test.n_string_leading_uescaped_thinspace" {
1354 err(
1355 \\[\u0020"asd"]
1356 );
1357}
1358
1359test "json.test.n_string_no_quotes_with_bad_escape" {
1360 err(
1361 \\[\n]
1362 );
1363}
1364
1365test "json.test.n_string_single_doublequote" {
1366 err(
1367 \\"
1368 );
1369}
1370
1371test "json.test.n_string_single_quote" {
1372 err(
1373 \\['single quote']
1374 );
1375}
1376
1377test "json.test.n_string_single_string_no_double_quotes" {
1378 err(
1379 \\abc
1380 );
1381}
1382
1383test "json.test.n_string_start_escape_unclosed" {
1384 err(
1385 \\["\
1386 );
1387}
1388
1389test "json.test.n_string_unescaped_crtl_char" {
1390 err("[\"a\x00a\"]");
1391}
1392
1393test "json.test.n_string_unescaped_newline" {
1394 err(
1395 \\["new
1396 \\line"]
1397 );
1398}
1399
1400test "json.test.n_string_unescaped_tab" {
1401 err("[\"\t\"]");
1402}
1403
1404test "json.test.n_string_unicode_CapitalU" {
1405 err(
1406 \\"\UA66D"
1407 );
1408}
1409
1410test "json.test.n_string_with_trailing_garbage" {
1411 err(
1412 \\""x
1413 );
1414}
1415
1416test "json.test.n_structure_100000_opening_arrays" {
1417 err("[" ** 100000);
1418}
1419
1420test "json.test.n_structure_angle_bracket_." {
1421 err(
1422 \\<.>
1423 );
1424}
1425
1426test "json.test.n_structure_angle_bracket_null" {
1427 err(
1428 \\[<null>]
1429 );
1430}
1431
1432test "json.test.n_structure_array_trailing_garbage" {
1433 err(
1434 \\[1]x
1435 );
1436}
1437
1438test "json.test.n_structure_array_with_extra_array_close" {
1439 err(
1440 \\[1]]
1441 );
1442}
1443
1444test "json.test.n_structure_array_with_unclosed_string" {
1445 err(
1446 \\["asd]
1447 );
1448}
1449
1450test "json.test.n_structure_ascii-unicode-identifier" {
1451 err(
1452 \\aå
1453 );
1454}
1455
1456test "json.test.n_structure_capitalized_True" {
1457 err(
1458 \\[True]
1459 );
1460}
1461
1462test "json.test.n_structure_close_unopened_array" {
1463 err(
1464 \\1]
1465 );
1466}
1467
1468test "json.test.n_structure_comma_instead_of_closing_brace" {
1469 err(
1470 \\{"x": true,
1471 );
1472}
1473
1474test "json.test.n_structure_double_array" {
1475 err(
1476 \\[][]
1477 );
1478}
1479
1480test "json.test.n_structure_end_array" {
1481 err(
1482 \\]
1483 );
1484}
1485
1486test "json.test.n_structure_incomplete_UTF8_BOM" {
1487 err(
1488 \\ï»{}
1489 );
1490}
1491
1492test "json.test.n_structure_lone-invalid-utf-8" {
1493 err(
1494 \\å
1495 );
1496}
1497
1498test "json.test.n_structure_lone-open-bracket" {
1499 err(
1500 \\[
1501 );
1502}
1503
1504test "json.test.n_structure_no_data" {
1505 err(
1506 \\
1507 );
1508}
1509
1510test "json.test.n_structure_null-byte-outside-string" {
1511 err("[\x00]");
1512}
1513
1514test "json.test.n_structure_number_with_trailing_garbage" {
1515 err(
1516 \\2@
1517 );
1518}
1519
1520test "json.test.n_structure_object_followed_by_closing_object" {
1521 err(
1522 \\{}}
1523 );
1524}
1525
1526test "json.test.n_structure_object_unclosed_no_value" {
1527 err(
1528 \\{"":
1529 );
1530}
1531
1532test "json.test.n_structure_object_with_comment" {
1533 err(
1534 \\{"a":/*comment*/"b"}
1535 );
1536}
1537
1538test "json.test.n_structure_object_with_trailing_garbage" {
1539 err(
1540 \\{"a": true} "x"
1541 );
1542}
1543
1544test "json.test.n_structure_open_array_apostrophe" {
1545 err(
1546 \\['
1547 );
1548}
1549
1550test "json.test.n_structure_open_array_comma" {
1551 err(
1552 \\[,
1553 );
1554}
1555
1556test "json.test.n_structure_open_array_object" {
1557 err("[{\"\":" ** 50000);
1558}
1559
1560test "json.test.n_structure_open_array_open_object" {
1561 err(
1562 \\[{
1563 );
1564}
1565
1566test "json.test.n_structure_open_array_open_string" {
1567 err(
1568 \\["a
1569 );
1570}
1571
1572test "json.test.n_structure_open_array_string" {
1573 err(
1574 \\["a"
1575 );
1576}
1577
1578test "json.test.n_structure_open_object_close_array" {
1579 err(
1580 \\{]
1581 );
1582}
1583
1584test "json.test.n_structure_open_object_comma" {
1585 err(
1586 \\{,
1587 );
1588}
1589
1590test "json.test.n_structure_open_object" {
1591 err(
1592 \\{
1593 );
1594}
1595
1596test "json.test.n_structure_open_object_open_array" {
1597 err(
1598 \\{[
1599 );
1600}
1601
1602test "json.test.n_structure_open_object_open_string" {
1603 err(
1604 \\{"a
1605 );
1606}
1607
1608test "json.test.n_structure_open_object_string_with_apostrophes" {
1609 err(
1610 \\{'a'
1611 );
1612}
1613
1614test "json.test.n_structure_open_open" {
1615 err(
1616 \\["\{["\{["\{["\{
1617 );
1618}
1619
1620test "json.test.n_structure_single_eacute" {
1621 err(
1622 \\é
1623 );
1624}
1625
1626test "json.test.n_structure_single_star" {
1627 err(
1628 \\*
1629 );
1630}
1631
1632test "json.test.n_structure_trailing_#" {
1633 err(
1634 \\{"a":"b"}#{}
1635 );
1636}
1637
1638test "json.test.n_structure_U+2060_word_joined" {
1639 err(
1640 \\[⁠]
1641 );
1642}
1643
1644test "json.test.n_structure_uescaped_LF_before_string" {
1645 err(
1646 \\[\u000A""]
1647 );
1648}
1649
1650test "json.test.n_structure_unclosed_array" {
1651 err(
1652 \\[1
1653 );
1654}
1655
1656test "json.test.n_structure_unclosed_array_partial_null" {
1657 err(
1658 \\[ false, nul
1659 );
1660}
1661
1662test "json.test.n_structure_unclosed_array_unfinished_false" {
1663 err(
1664 \\[ true, fals
1665 );
1666}
1667
1668test "json.test.n_structure_unclosed_array_unfinished_true" {
1669 err(
1670 \\[ false, tru
1671 );
1672}
1673
1674test "json.test.n_structure_unclosed_object" {
1675 err(
1676 \\{"asd":"asd"
1677 );
1678}
1679
1680test "json.test.n_structure_unicode-identifier" {
1681 err(
1682 \\Ã¥
1683 );
1684}
1685
1686test "json.test.n_structure_UTF8_BOM_no_data" {
1687 err(
1688 \\
1689 );
1690}
1691
1692test "json.test.n_structure_whitespace_formfeed" {
1693 err("[\x0c]");
1694}
1695
1696test "json.test.n_structure_whitespace_U+2060_word_joiner" {
1697 err(
1698 \\[⁠]
1699 );
1700}
1701
1702////////////////////////////////////////////////////////////////////////////////////////////////////
1703
1704test "json.test.i_number_double_huge_neg_exp" {
1705 any(
1706 \\[123.456e-789]
1707 );
1708}
1709
1710test "json.test.i_number_huge_exp" {
1711 any(
1712 \\[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
1713 );
1714}
1715
1716test "json.test.i_number_neg_int_huge_exp" {
1717 any(
1718 \\[-1e+9999]
1719 );
1720}
1721
1722test "json.test.i_number_pos_double_huge_exp" {
1723 any(
1724 \\[1.5e+9999]
1725 );
1726}
1727
1728test "json.test.i_number_real_neg_overflow" {
1729 any(
1730 \\[-123123e100000]
1731 );
1732}
1733
1734test "json.test.i_number_real_pos_overflow" {
1735 any(
1736 \\[123123e100000]
1737 );
1738}
1739
1740test "json.test.i_number_real_underflow" {
1741 any(
1742 \\[123e-10000000]
1743 );
1744}
1745
1746test "json.test.i_number_too_big_neg_int" {
1747 any(
1748 \\[-123123123123123123123123123123]
1749 );
1750}
1751
1752test "json.test.i_number_too_big_pos_int" {
1753 any(
1754 \\[100000000000000000000]
1755 );
1756}
1757
1758test "json.test.i_number_very_big_negative_int" {
1759 any(
1760 \\[-237462374673276894279832749832423479823246327846]
1761 );
1762}
1763
1764test "json.test.i_object_key_lone_2nd_surrogate" {
1765 any(
1766 \\{"\uDFAA":0}
1767 );
1768}
1769
1770test "json.test.i_string_1st_surrogate_but_2nd_missing" {
1771 any(
1772 \\["\uDADA"]
1773 );
1774}
1775
1776test "json.test.i_string_1st_valid_surrogate_2nd_invalid" {
1777 any(
1778 \\["\uD888\u1234"]
1779 );
1780}
1781
1782test "json.test.i_string_incomplete_surrogate_and_escape_valid" {
1783 any(
1784 \\["\uD800\n"]
1785 );
1786}
1787
1788test "json.test.i_string_incomplete_surrogate_pair" {
1789 any(
1790 \\["\uDd1ea"]
1791 );
1792}
1793
1794test "json.test.i_string_incomplete_surrogates_escape_valid" {
1795 any(
1796 \\["\uD800\uD800\n"]
1797 );
1798}
1799
1800test "json.test.i_string_invalid_lonely_surrogate" {
1801 any(
1802 \\["\ud800"]
1803 );
1804}
1805
1806test "json.test.i_string_invalid_surrogate" {
1807 any(
1808 \\["\ud800abc"]
1809 );
1810}
1811
1812test "json.test.i_string_invalid_utf-8" {
1813 any(
1814 \\["ÿ"]
1815 );
1816}
1817
1818test "json.test.i_string_inverted_surrogates_U+1D11E" {
1819 any(
1820 \\["\uDd1e\uD834"]
1821 );
1822}
1823
1824test "json.test.i_string_iso_latin_1" {
1825 any(
1826 \\["é"]
1827 );
1828}
1829
1830test "json.test.i_string_lone_second_surrogate" {
1831 any(
1832 \\["\uDFAA"]
1833 );
1834}
1835
1836test "json.test.i_string_lone_utf8_continuation_byte" {
1837 any(
1838 \\[""]
1839 );
1840}
1841
1842test "json.test.i_string_not_in_unicode_range" {
1843 any(
1844 \\["ô¿¿¿"]
1845 );
1846}
1847
1848test "json.test.i_string_overlong_sequence_2_bytes" {
1849 any(
1850 \\["À¯"]
1851 );
1852}
1853
1854test "json.test.i_string_overlong_sequence_6_bytes" {
1855 any(
1856 \\["üƒ¿¿¿¿"]
1857 );
1858}
1859
1860test "json.test.i_string_overlong_sequence_6_bytes_null" {
1861 any(
1862 \\["ü€€€€€"]
1863 );
1864}
1865
1866test "json.test.i_string_truncated-utf-8" {
1867 any(
1868 \\["àÿ"]
1869 );
1870}
1871
1872test "json.test.i_string_utf16BE_no_BOM" {
1873 any("\x00\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d");
1874}
1875
1876test "json.test.i_string_utf16LE_no_BOM" {
1877 any("\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1878}
1879
1880test "json.test.i_string_UTF-16LE_with_BOM" {
1881 any("\xc3\xbf\xc3\xbe\x5b\x00\x22\x00\xc3\xa9\x00\x22\x00\x5d\x00");
1882}
1883
1884test "json.test.i_string_UTF-8_invalid_sequence" {
1885 any(
1886 \\["日шú"]
1887 );
1888}
1889
1890test "json.test.i_string_UTF8_surrogate_U+D800" {
1891 any(
1892 \\["í €"]
1893 );
1894}
1895
1896test "json.test.i_structure_500_nested_arrays" {
1897 any(("[" ** 500) ++ ("]" ** 500));
1898}
1899
1900test "json.test.i_structure_UTF-8_BOM_empty_object" {
1901 any(
1902 \\{}
1903 );
1904}
std/math/acos.zig+8-2
......@@ -1,11 +1,17 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - acos(x) = nan if x < -1 or x > 1
4// https://git.musl-libc.org/cgit/musl/tree/src/math/acosf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/acos.c
46
57const std = @import("../std.zig");
68const math = std.math;
79const expect = std.testing.expect;
810
11/// Returns the arc-cosine of x.
12///
13/// Special cases:
14/// - acos(x) = nan if x < -1 or x > 1
915pub fn acos(x: var) @typeOf(x) {
1016 const T = @typeOf(x);
1117 return switch (T) {
std/math/acosh.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - acosh(x) = snan if x < 1
4// - acosh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/acoshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/acosh.c
56
67const builtin = @import("builtin");
78const std = @import("../std.zig");
89const math = std.math;
910const expect = std.testing.expect;
1011
12/// Returns the hyperbolic arc-cosine of x.
13///
14/// Special cases:
15/// - acosh(x) = snan if x < 1
16/// - acosh(nan) = nan
1117pub fn acosh(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/asin.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - asin(+-0) = +-0
4// - asin(x) = nan if x < -1 or x > 1
4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/asin.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns the arc-sin of x.
12///
13/// Special Cases:
14/// - asin(+-0) = +-0
15/// - asin(x) = nan if x < -1 or x > 1
1016pub fn asin(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/asinh.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - asinh(+-0) = +-0
4// - asinh(+-inf) = +-inf
5// - asinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/asinh.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the hyperbolic arc-sin of x.
13///
14/// Special Cases:
15/// - asinh(+-0) = +-0
16/// - asinh(+-inf) = +-inf
17/// - asinh(nan) = nan
1218pub fn asinh(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/atan.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - atan(+-0) = +-0
4// - atan(+-inf) = +-pi/2
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atanf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atan.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns the arc-tangent of x.
12///
13/// Special Cases:
14/// - atan(+-0) = +-0
15/// - atan(+-inf) = +-pi/2
1016pub fn atan(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/atan2.zig+24-18
......@@ -1,27 +1,33 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// atan2(y, nan) = nan
4// atan2(nan, x) = nan
5// atan2(+0, x>=0) = +0
6// atan2(-0, x>=0) = -0
7// atan2(+0, x<=-0) = +pi
8// atan2(-0, x<=-0) = -pi
9// atan2(y>0, 0) = +pi/2
10// atan2(y<0, 0) = -pi/2
11// atan2(+inf, +inf) = +pi/4
12// atan2(-inf, +inf) = -pi/4
13// atan2(+inf, -inf) = 3pi/4
14// atan2(-inf, -inf) = -3pi/4
15// atan2(y, +inf) = 0
16// atan2(y>0, -inf) = +pi
17// atan2(y<0, -inf) = -pi
18// atan2(+inf, x) = +pi/2
19// atan2(-inf, x) = -pi/2
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atan2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atan2.c
206
217const std = @import("../std.zig");
228const math = std.math;
239const expect = std.testing.expect;
2410
11/// Returns the arc-tangent of y/x.
12///
13/// Special Cases:
14/// - atan2(y, nan) = nan
15/// - atan2(nan, x) = nan
16/// - atan2(+0, x>=0) = +0
17/// - atan2(-0, x>=0) = -0
18/// - atan2(+0, x<=-0) = +pi
19/// - atan2(-0, x<=-0) = -pi
20/// - atan2(y>0, 0) = +pi/2
21/// - atan2(y<0, 0) = -pi/2
22/// - atan2(+inf, +inf) = +pi/4
23/// - atan2(-inf, +inf) = -pi/4
24/// - atan2(+inf, -inf) = 3pi/4
25/// - atan2(-inf, -inf) = -3pi/4
26/// - atan2(y, +inf) = 0
27/// - atan2(y>0, -inf) = +pi
28/// - atan2(y<0, -inf) = -pi
29/// - atan2(+inf, x) = +pi/2
30/// - atan2(-inf, x) = -pi/2
2531pub fn atan2(comptime T: type, y: T, x: T) T {
2632 return switch (T) {
2733 f32 => atan2_32(y, x),
std/math/atanh.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - atanh(+-1) = +-inf with signal
4// - atanh(x) = nan if |x| > 1 with signal
5// - atanh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/atanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/atanh.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the hyperbolic arc-tangent of x.
13///
14/// Special Cases:
15/// - atanh(+-1) = +-inf with signal
16/// - atanh(x) = nan if |x| > 1 with signal
17/// - atanh(nan) = nan
1218pub fn atanh(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/big.zig+2
......@@ -1,5 +1,7 @@
11pub use @import("big/int.zig");
2pub use @import("big/rational.zig");
23
34test "math.big" {
45 _ = @import("big/int.zig");
6 _ = @import("big/rational.zig");
57}
std/math/big/int.zig+504-282
......@@ -21,78 +21,160 @@ comptime {
2121 debug.assert(Limb.is_signed == false);
2222}
2323
24/// An arbitrary-precision big integer.
25///
26/// Memory is allocated by an Int as needed to ensure operations never overflow. The range of an
27/// Int is bounded only by available memory.
2428pub const Int = struct {
25 allocator: *Allocator,
26 positive: bool,
27 // - little-endian ordered
28 // - len >= 1 always
29 // - zero value -> len == 1 with limbs[0] == 0
29 const sign_bit: usize = 1 << (usize.bit_count - 1);
30
31 /// Default number of limbs to allocate on creation of an Int.
32 pub const default_capacity = 4;
33
34 /// Allocator used by the Int when requesting memory.
35 allocator: ?*Allocator,
36
37 /// Raw digits. These are:
38 ///
39 /// * Little-endian ordered
40 /// * limbs.len >= 1
41 /// * Zero is represent as Int.len() == 1 with limbs[0] == 0.
42 ///
43 /// Accessing limbs directly should be avoided.
3044 limbs: []Limb,
31 len: usize,
3245
33 const default_capacity = 4;
46 /// High bit is the sign bit. If set, Int is negative, else Int is positive.
47 /// The remaining bits represent the number of limbs used by Int.
48 metadata: usize,
3449
50 /// Creates a new Int. default_capacity limbs will be allocated immediately.
51 /// Int will be zeroed.
3552 pub fn init(allocator: *Allocator) !Int {
3653 return try Int.initCapacity(allocator, default_capacity);
3754 }
3855
56 /// Creates a new Int. Int will be set to `value`.
57 ///
58 /// This is identical to an `init`, followed by a `set`.
3959 pub fn initSet(allocator: *Allocator, value: var) !Int {
4060 var s = try Int.init(allocator);
4161 try s.set(value);
4262 return s;
4363 }
4464
65 /// Creates a new Int with a specific capacity. If capacity < default_capacity then the
66 /// default capacity will be used instead.
4567 pub fn initCapacity(allocator: *Allocator, capacity: usize) !Int {
4668 return Int{
4769 .allocator = allocator,
48 .positive = true,
70 .metadata = 1,
4971 .limbs = block: {
5072 var limbs = try allocator.alloc(Limb, math.max(default_capacity, capacity));
5173 limbs[0] = 0;
5274 break :block limbs;
5375 },
54 .len = 1,
5576 };
5677 }
5778
79 /// Returns the number of limbs currently in use.
80 pub fn len(self: Int) usize {
81 return self.metadata & ~sign_bit;
82 }
83
84 /// Returns whether an Int is positive.
85 pub fn isPositive(self: Int) bool {
86 return self.metadata & sign_bit == 0;
87 }
88
89 /// Sets the sign of an Int.
90 pub fn setSign(self: *Int, positive: bool) void {
91 if (positive) {
92 self.metadata &= ~sign_bit;
93 } else {
94 self.metadata |= sign_bit;
95 }
96 }
97
98 /// Sets the length of an Int.
99 ///
100 /// If setLen is used, then the Int must be normalized to suit.
101 pub fn setLen(self: *Int, new_len: usize) void {
102 self.metadata &= sign_bit;
103 self.metadata |= new_len;
104 }
105
106 /// Returns an Int backed by a fixed set of limb values.
107 /// This is read-only and cannot be used as a result argument. If the Int tries to allocate
108 /// memory a runtime panic will occur.
109 pub fn initFixed(limbs: []const Limb) Int {
110 var self = Int{
111 .allocator = null,
112 .metadata = limbs.len,
113 // Cast away the const, invalid use to pass as a pointer argument.
114 .limbs = @intToPtr([*]Limb, @ptrToInt(limbs.ptr))[0..limbs.len],
115 };
116
117 self.normalize(limbs.len);
118 return self;
119 }
120
121 /// Ensures an Int has enough space allocated for capacity limbs. If the Int does not have
122 /// sufficient capacity, the exact amount will be allocated. This occurs even if the requested
123 /// capacity is only greater than the current capacity by one limb.
58124 pub fn ensureCapacity(self: *Int, capacity: usize) !void {
125 self.assertWritable();
59126 if (capacity <= self.limbs.len) {
60127 return;
61128 }
62129
63 self.limbs = try self.allocator.realloc(self.limbs, capacity);
130 self.limbs = try self.allocator.?.realloc(self.limbs, capacity);
64131 }
65132
133 fn assertWritable(self: Int) void {
134 if (self.allocator == null) {
135 @panic("provided Int value is read-only but must be writable");
136 }
137 }
138
139 /// Frees all memory associated with an Int.
66140 pub fn deinit(self: *Int) void {
67 self.allocator.free(self.limbs);
141 self.assertWritable();
142 self.allocator.?.free(self.limbs);
68143 self.* = undefined;
69144 }
70145
146 /// Clones an Int and returns a new Int with the same value. The new Int is a deep copy and
147 /// can be modified separately from the original.
71148 pub fn clone(other: Int) !Int {
149 other.assertWritable();
72150 return Int{
73151 .allocator = other.allocator,
74 .positive = other.positive,
152 .metadata = other.metadata,
75153 .limbs = block: {
76 var limbs = try other.allocator.alloc(Limb, other.len);
77 mem.copy(Limb, limbs[0..], other.limbs[0..other.len]);
154 var limbs = try other.allocator.?.alloc(Limb, other.len());
155 mem.copy(Limb, limbs[0..], other.limbs[0..other.len()]);
78156 break :block limbs;
79157 },
80 .len = other.len,
81158 };
82159 }
83160
161 /// Copies the value of an Int to an existing Int so that they both have the same value.
162 /// Extra memory will be allocated if the receiver does not have enough capacity.
84163 pub fn copy(self: *Int, other: Int) !void {
85 if (self == &other) {
164 self.assertWritable();
165 if (self.limbs.ptr == other.limbs.ptr) {
86166 return;
87167 }
88168
89 self.positive = other.positive;
90 try self.ensureCapacity(other.len);
91 mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len]);
92 self.len = other.len;
169 try self.ensureCapacity(other.len());
170 mem.copy(Limb, self.limbs[0..], other.limbs[0..other.len()]);
171 self.metadata = other.metadata;
93172 }
94173
174 /// Efficiently swap an Int with another. This swaps the limb pointers and a full copy is not
175 /// performed. The address of the limbs field will not be the same after this function.
95176 pub fn swap(self: *Int, other: *Int) void {
177 self.assertWritable();
96178 mem.swap(Int, self, other);
97179 }
98180
......@@ -103,45 +185,49 @@ pub const Int = struct {
103185 debug.warn("\n");
104186 }
105187
106 pub fn negate(r: *Int) void {
107 r.positive = !r.positive;
188 /// Negate the sign of an Int.
189 pub fn negate(self: *Int) void {
190 self.metadata ^= sign_bit;
108191 }
109192
110 pub fn abs(r: *Int) void {
111 r.positive = true;
193 /// Make an Int positive.
194 pub fn abs(self: *Int) void {
195 self.metadata &= ~sign_bit;
112196 }
113197
114 pub fn isOdd(r: Int) bool {
115 return r.limbs[0] & 1 != 0;
198 /// Returns true if an Int is odd.
199 pub fn isOdd(self: Int) bool {
200 return self.limbs[0] & 1 != 0;
116201 }
117202
118 pub fn isEven(r: Int) bool {
119 return !r.isOdd();
203 /// Returns true if an Int is even.
204 pub fn isEven(self: Int) bool {
205 return !self.isOdd();
120206 }
121207
122 // Returns the number of bits required to represent the absolute value of self.
208 /// Returns the number of bits required to represent the absolute value an Int.
123209 fn bitCountAbs(self: Int) usize {
124 return (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
210 return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1]));
125211 }
126212
127 // Returns the number of bits required to represent the integer in twos-complement form.
128 //
129 // If the integer is negative the value returned is the number of bits needed by a signed
130 // integer to represent the value. If positive the value is the number of bits for an
131 // unsigned integer. Any unsigned integer will fit in the signed integer with bitcount
132 // one greater than the returned value.
133 //
134 // e.g. -127 returns 8 as it will fit in an i8. 127 returns 7 since it fits in a u7.
213 /// Returns the number of bits required to represent the integer in twos-complement form.
214 ///
215 /// If the integer is negative the value returned is the number of bits needed by a signed
216 /// integer to represent the value. If positive the value is the number of bits for an
217 /// unsigned integer. Any unsigned integer will fit in the signed integer with bitcount
218 /// one greater than the returned value.
219 ///
220 /// e.g. -127 returns 8 as it will fit in an i8. 127 returns 7 since it fits in a u7.
135221 fn bitCountTwosComp(self: Int) usize {
136222 var bits = self.bitCountAbs();
137223
138224 // If the entire value has only one bit set (e.g. 0b100000000) then the negation in twos
139225 // complement requires one less bit.
140 if (!self.positive) block: {
226 if (!self.isPositive()) block: {
141227 bits += 1;
142228
143 if (@popCount(self.limbs[self.len - 1]) == 1) {
144 for (self.limbs[0 .. self.len - 1]) |limb| {
229 if (@popCount(self.limbs[self.len() - 1]) == 1) {
230 for (self.limbs[0 .. self.len() - 1]) |limb| {
145231 if (@popCount(limb) != 0) {
146232 break :block;
147233 }
......@@ -154,31 +240,34 @@ pub const Int = struct {
154240 return bits;
155241 }
156242
157 pub fn fitsInTwosComp(self: Int, is_signed: bool, bit_count: usize) bool {
243 fn fitsInTwosComp(self: Int, is_signed: bool, bit_count: usize) bool {
158244 if (self.eqZero()) {
159245 return true;
160246 }
161 if (!is_signed and !self.positive) {
247 if (!is_signed and !self.isPositive()) {
162248 return false;
163249 }
164250
165 const req_bits = self.bitCountTwosComp() + @boolToInt(self.positive and is_signed);
251 const req_bits = self.bitCountTwosComp() + @boolToInt(self.isPositive() and is_signed);
166252 return bit_count >= req_bits;
167253 }
168254
255 /// Returns whether self can fit into an integer of the requested type.
169256 pub fn fits(self: Int, comptime T: type) bool {
170257 return self.fitsInTwosComp(T.is_signed, T.bit_count);
171258 }
172259
173 // Returns the approximate size of the integer in the given base. Negative values accommodate for
174 // the minus sign. This is used for determining the number of characters needed to print the
175 // value. It is inexact and will exceed the given value by 1-2 digits.
260 /// Returns the approximate size of the integer in the given base. Negative values accommodate for
261 /// the minus sign. This is used for determining the number of characters needed to print the
262 /// value. It is inexact and may exceed the given value by ~1-2 bytes.
176263 pub fn sizeInBase(self: Int, base: usize) usize {
177 const bit_count = usize(@boolToInt(!self.positive)) + self.bitCountAbs();
264 const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs();
178265 return (bit_count / math.log2(base)) + 1;
179266 }
180267
268 /// Sets an Int to value. Value must be an primitive integer type.
181269 pub fn set(self: *Int, value: var) Allocator.Error!void {
270 self.assertWritable();
182271 const T = @typeOf(value);
183272
184273 switch (@typeInfo(T)) {
......@@ -186,19 +275,19 @@ pub const Int = struct {
186275 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
187276
188277 try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb));
189 self.positive = value >= 0;
190 self.len = 0;
278 self.metadata = 0;
279 self.setSign(value >= 0);
191280
192281 var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);
193282
194283 if (info.bits <= Limb.bit_count) {
195284 self.limbs[0] = Limb(w_value);
196 self.len = 1;
285 self.metadata += 1;
197286 } else {
198287 var i: usize = 0;
199288 while (w_value != 0) : (i += 1) {
200289 self.limbs[i] = @truncate(Limb, w_value);
201 self.len += 1;
290 self.metadata += 1;
202291
203292 // TODO: shift == 64 at compile-time fails. Fails on u128 limbs.
204293 w_value >>= Limb.bit_count / 2;
......@@ -212,8 +301,8 @@ pub const Int = struct {
212301 const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1;
213302 try self.ensureCapacity(req_limbs);
214303
215 self.positive = value >= 0;
216 self.len = req_limbs;
304 self.metadata = req_limbs;
305 self.setSign(value >= 0);
217306
218307 if (w_value <= maxInt(Limb)) {
219308 self.limbs[0] = w_value;
......@@ -240,6 +329,9 @@ pub const Int = struct {
240329 TargetTooSmall,
241330 };
242331
332 /// Convert self to type T.
333 ///
334 /// Returns an error if self cannot be narrowed into the requested type without truncation.
243335 pub fn to(self: Int, comptime T: type) ConvertError!T {
244336 switch (@typeId(T)) {
245337 TypeId.Int => {
......@@ -254,17 +346,17 @@ pub const Int = struct {
254346 if (@sizeOf(UT) <= @sizeOf(Limb)) {
255347 r = @intCast(UT, self.limbs[0]);
256348 } else {
257 for (self.limbs[0..self.len]) |_, ri| {
258 const limb = self.limbs[self.len - ri - 1];
349 for (self.limbs[0..self.len()]) |_, ri| {
350 const limb = self.limbs[self.len() - ri - 1];
259351 r <<= Limb.bit_count;
260352 r |= limb;
261353 }
262354 }
263355
264356 if (!T.is_signed) {
265 return if (self.positive) @intCast(T, r) else error.NegativeIntoUnsigned;
357 return if (self.isPositive()) @intCast(T, r) else error.NegativeIntoUnsigned;
266358 } else {
267 if (self.positive) {
359 if (self.isPositive()) {
268360 return @intCast(T, r);
269361 } else {
270362 if (math.cast(T, r)) |ok| {
......@@ -303,7 +395,15 @@ pub const Int = struct {
303395 };
304396 }
305397
398 /// Set self from the string representation `value`.
399 ///
400 /// value must contain only digits <= `base`. Base prefixes are not allowed (e.g. 0x43 should
401 /// simply be 43).
402 ///
403 /// Returns an error if memory could not be allocated or `value` has invalid digits for the
404 /// requested base.
306405 pub fn setString(self: *Int, base: u8, value: []const u8) !void {
406 self.assertWritable();
307407 if (base < 2 or base > 16) {
308408 return error.InvalidBase;
309409 }
......@@ -315,27 +415,22 @@ pub const Int = struct {
315415 i += 1;
316416 }
317417
318 // TODO values less than limb size should guarantee non allocating
319 var base_buffer: [512]u8 = undefined;
320 const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator;
321 const base_ap = try Int.initSet(base_al, base);
322
323 var d_buffer: [512]u8 = undefined;
324 var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]);
325 const d_al = &d_fba.allocator;
326
418 const ap_base = Int.initFixed(([]Limb{base})[0..]);
327419 try self.set(0);
420
328421 for (value[i..]) |ch| {
329422 const d = try charToDigit(ch, base);
330 d_fba.end_index = 0;
331 const d_ap = try Int.initSet(d_al, d);
332423
333 try self.mul(self.*, base_ap);
334 try self.add(self.*, d_ap);
424 const ap_d = Int.initFixed(([]Limb{d})[0..]);
425
426 try self.mul(self.*, ap_base);
427 try self.add(self.*, ap_d);
335428 }
336 self.positive = positive;
429 self.setSign(positive);
337430 }
338431
432 /// Converts self to a string in the requested base. Memory is allocated from the provided
433 /// allocator and not the one present in self.
339434 /// TODO make this call format instead of the other way around
340435 pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 {
341436 if (base < 2 or base > 16) {
......@@ -355,7 +450,7 @@ pub const Int = struct {
355450 if (base & (base - 1) == 0) {
356451 const base_shift = math.log2_int(Limb, base);
357452
358 for (self.limbs[0..self.len]) |limb| {
453 for (self.limbs[0..self.len()]) |limb| {
359454 var shift: usize = 0;
360455 while (shift < Limb.bit_count) : (shift += base_shift) {
361456 const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1));
......@@ -382,11 +477,11 @@ pub const Int = struct {
382477 }
383478
384479 var q = try self.clone();
385 q.positive = true;
480 q.abs();
386481 var r = try Int.init(allocator);
387482 var b = try Int.initSet(allocator, limb_base);
388483
389 while (q.len >= 2) {
484 while (q.len() >= 2) {
390485 try Int.divTrunc(&q, &r, q, b);
391486
392487 var r_word = r.limbs[0];
......@@ -399,7 +494,7 @@ pub const Int = struct {
399494 }
400495
401496 {
402 debug.assert(q.len == 1);
497 debug.assert(q.len() == 1);
403498
404499 var r_word = q.limbs[0];
405500 while (r_word != 0) {
......@@ -410,7 +505,7 @@ pub const Int = struct {
410505 }
411506 }
412507
413 if (!self.positive) {
508 if (!self.isPositive()) {
414509 try digits.append('-');
415510 }
416511
......@@ -419,7 +514,7 @@ pub const Int = struct {
419514 return s;
420515 }
421516
422 /// for the std lib format function
517 /// To allow `std.fmt.printf` to work with Int.
423518 /// TODO make this non-allocating
424519 pub fn format(
425520 self: Int,
......@@ -428,22 +523,24 @@ pub const Int = struct {
428523 comptime FmtError: type,
429524 output: fn (@typeOf(context), []const u8) FmtError!void,
430525 ) FmtError!void {
526 self.assertWritable();
431527 // TODO look at fmt and support other bases
432 const str = self.toString(self.allocator, 10) catch @panic("TODO make this non allocating");
433 defer self.allocator.free(str);
528 // TODO support read-only fixed integers
529 const str = self.toString(self.allocator.?, 10) catch @panic("TODO make this non allocating");
530 defer self.allocator.?.free(str);
434531 return output(context, str);
435532 }
436533
437 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
534 /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
438535 pub fn cmpAbs(a: Int, b: Int) i8 {
439 if (a.len < b.len) {
536 if (a.len() < b.len()) {
440537 return -1;
441538 }
442 if (a.len > b.len) {
539 if (a.len() > b.len()) {
443540 return 1;
444541 }
445542
446 var i: usize = a.len - 1;
543 var i: usize = a.len() - 1;
447544 while (i != 0) : (i -= 1) {
448545 if (a.limbs[i] != b.limbs[i]) {
449546 break;
......@@ -459,53 +556,37 @@ pub const Int = struct {
459556 }
460557 }
461558
462 // returns -1, 0, 1 if a < b, a == b or a > b respectively.
559 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
463560 pub fn cmp(a: Int, b: Int) i8 {
464 if (a.positive != b.positive) {
465 return if (a.positive) i8(1) else -1;
561 if (a.isPositive() != b.isPositive()) {
562 return if (a.isPositive()) i8(1) else -1;
466563 } else {
467564 const r = cmpAbs(a, b);
468 return if (a.positive) r else -r;
565 return if (a.isPositive()) r else -r;
469566 }
470567 }
471568
472 // if a == 0
569 /// Returns true if a == 0.
473570 pub fn eqZero(a: Int) bool {
474 return a.len == 1 and a.limbs[0] == 0;
571 return a.len() == 1 and a.limbs[0] == 0;
475572 }
476573
477 // if |a| == |b|
574 /// Returns true if |a| == |b|.
478575 pub fn eqAbs(a: Int, b: Int) bool {
479576 return cmpAbs(a, b) == 0;
480577 }
481578
482 // if a == b
579 /// Returns true if a == b.
483580 pub fn eq(a: Int, b: Int) bool {
484581 return cmp(a, b) == 0;
485582 }
486583
487 // Normalize for a possible single carry digit.
488 //
489 // [1, 2, 3, 4, 0] -> [1, 2, 3, 4]
490 // [1, 2, 3, 4, 5] -> [1, 2, 3, 4, 5]
491 // [0] -> [0]
492 fn norm1(r: *Int, length: usize) void {
493 debug.assert(length > 0);
494 debug.assert(length <= r.limbs.len);
495
496 if (r.limbs[length - 1] == 0) {
497 r.len = if (length > 1) length - 1 else 1;
498 } else {
499 r.len = length;
500 }
501 }
502
503584 // Normalize a possible sequence of leading zeros.
504585 //
505586 // [1, 2, 3, 4, 0] -> [1, 2, 3, 4]
506587 // [1, 2, 0, 0, 0] -> [1, 2]
507588 // [0, 0, 0, 0, 0] -> [0]
508 fn normN(r: *Int, length: usize) void {
589 fn normalize(r: *Int, length: usize) void {
509590 debug.assert(length > 0);
510591 debug.assert(length <= r.limbs.len);
511592
......@@ -517,11 +598,25 @@ pub const Int = struct {
517598 }
518599
519600 // Handle zero
520 r.len = if (j != 0) j else 1;
601 r.setLen(if (j != 0) j else 1);
521602 }
522603
523 // r = a + b
604 // Cannot be used as a result argument to any function.
605 fn readOnlyPositive(a: Int) Int {
606 return Int{
607 .allocator = null,
608 .metadata = a.len(),
609 .limbs = a.limbs,
610 };
611 }
612
613 /// r = a + b
614 ///
615 /// r, a and b may be aliases.
616 ///
617 /// Returns an error if memory could not be allocated.
524618 pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
619 r.assertWritable();
525620 if (a.eqZero()) {
526621 try r.copy(b);
527622 return;
......@@ -530,38 +625,26 @@ pub const Int = struct {
530625 return;
531626 }
532627
533 if (a.positive != b.positive) {
534 if (a.positive) {
628 if (a.isPositive() != b.isPositive()) {
629 if (a.isPositive()) {
535630 // (a) + (-b) => a - b
536 const bp = Int{
537 .allocator = undefined,
538 .positive = true,
539 .limbs = b.limbs,
540 .len = b.len,
541 };
542 try r.sub(a, bp);
631 try r.sub(a, readOnlyPositive(b));
543632 } else {
544633 // (-a) + (b) => b - a
545 const ap = Int{
546 .allocator = undefined,
547 .positive = true,
548 .limbs = a.limbs,
549 .len = a.len,
550 };
551 try r.sub(b, ap);
634 try r.sub(b, readOnlyPositive(a));
552635 }
553636 } else {
554 if (a.len >= b.len) {
555 try r.ensureCapacity(a.len + 1);
556 lladd(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
557 r.norm1(a.len + 1);
637 if (a.len() >= b.len()) {
638 try r.ensureCapacity(a.len() + 1);
639 lladd(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
640 r.normalize(a.len() + 1);
558641 } else {
559 try r.ensureCapacity(b.len + 1);
560 lladd(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
561 r.norm1(b.len + 1);
642 try r.ensureCapacity(b.len() + 1);
643 lladd(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
644 r.normalize(b.len() + 1);
562645 }
563646
564 r.positive = a.positive;
647 r.setSign(a.isPositive());
565648 }
566649 }
567650
......@@ -589,55 +672,48 @@ pub const Int = struct {
589672 r[i] = carry;
590673 }
591674
592 // r = a - b
675 /// r = a - b
676 ///
677 /// r, a and b may be aliases.
678 ///
679 /// Returns an error if memory could not be allocated.
593680 pub fn sub(r: *Int, a: Int, b: Int) !void {
594 if (a.positive != b.positive) {
595 if (a.positive) {
681 r.assertWritable();
682 if (a.isPositive() != b.isPositive()) {
683 if (a.isPositive()) {
596684 // (a) - (-b) => a + b
597 const bp = Int{
598 .allocator = undefined,
599 .positive = true,
600 .limbs = b.limbs,
601 .len = b.len,
602 };
603 try r.add(a, bp);
685 try r.add(a, readOnlyPositive(b));
604686 } else {
605687 // (-a) - (b) => -(a + b)
606 const ap = Int{
607 .allocator = undefined,
608 .positive = true,
609 .limbs = a.limbs,
610 .len = a.len,
611 };
612 try r.add(ap, b);
613 r.positive = false;
688 try r.add(readOnlyPositive(a), b);
689 r.setSign(false);
614690 }
615691 } else {
616 if (a.positive) {
692 if (a.isPositive()) {
617693 // (a) - (b) => a - b
618694 if (a.cmp(b) >= 0) {
619 try r.ensureCapacity(a.len + 1);
620 llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
621 r.normN(a.len);
622 r.positive = true;
695 try r.ensureCapacity(a.len() + 1);
696 llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
697 r.normalize(a.len());
698 r.setSign(true);
623699 } else {
624 try r.ensureCapacity(b.len + 1);
625 llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
626 r.normN(b.len);
627 r.positive = false;
700 try r.ensureCapacity(b.len() + 1);
701 llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
702 r.normalize(b.len());
703 r.setSign(false);
628704 }
629705 } else {
630706 // (-a) - (-b) => -(a - b)
631707 if (a.cmp(b) < 0) {
632 try r.ensureCapacity(a.len + 1);
633 llsub(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
634 r.normN(a.len);
635 r.positive = false;
708 try r.ensureCapacity(a.len() + 1);
709 llsub(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
710 r.normalize(a.len());
711 r.setSign(false);
636712 } else {
637 try r.ensureCapacity(b.len + 1);
638 llsub(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
639 r.normN(b.len);
640 r.positive = true;
713 try r.ensureCapacity(b.len() + 1);
714 llsub(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
715 r.normalize(b.len());
716 r.setSign(true);
641717 }
642718 }
643719 }
......@@ -667,16 +743,20 @@ pub const Int = struct {
667743 debug.assert(borrow == 0);
668744 }
669745
670 // rma = a * b
671 //
672 // For greatest efficiency, ensure rma does not alias a or b.
746 /// rma = a * b
747 ///
748 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
749 ///
750 /// Returns an error if memory could not be allocated.
673751 pub fn mul(rma: *Int, a: Int, b: Int) !void {
752 rma.assertWritable();
753
674754 var r = rma;
675755 var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr;
676756
677757 var sr: Int = undefined;
678758 if (aliased) {
679 sr = try Int.initCapacity(rma.allocator, a.len + b.len);
759 sr = try Int.initCapacity(rma.allocator.?, a.len() + b.len());
680760 r = &sr;
681761 aliased = true;
682762 }
......@@ -685,16 +765,16 @@ pub const Int = struct {
685765 r.deinit();
686766 };
687767
688 try r.ensureCapacity(a.len + b.len);
768 try r.ensureCapacity(a.len() + b.len());
689769
690 if (a.len >= b.len) {
691 llmul(r.limbs, a.limbs[0..a.len], b.limbs[0..b.len]);
770 if (a.len() >= b.len()) {
771 llmul(r.limbs, a.limbs[0..a.len()], b.limbs[0..b.len()]);
692772 } else {
693 llmul(r.limbs, b.limbs[0..b.len], a.limbs[0..a.len]);
773 llmul(r.limbs, b.limbs[0..b.len()], a.limbs[0..a.len()]);
694774 }
695775
696 r.positive = a.positive == b.positive;
697 r.normN(a.len + b.len);
776 r.normalize(a.len() + b.len());
777 r.setSign(a.isPositive() == b.isPositive());
698778 }
699779
700780 // a + b * c + *carry, sets carry to the overflow bits
......@@ -740,29 +820,34 @@ pub const Int = struct {
740820 }
741821 }
742822
823 /// q = a / b (rem r)
824 ///
825 /// a / b are floored (rounded towards 0).
743826 pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void {
744827 try div(q, r, a, b);
745828
746829 // Trunc -> Floor.
747 if (!q.positive) {
748 // TODO values less than limb size should guarantee non allocating
749 var one_buffer: [512]u8 = undefined;
750 const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator;
751 const one_ap = try Int.initSet(one_al, 1);
752
753 try q.sub(q.*, one_ap);
754 try r.add(q.*, one_ap);
830 if (!q.isPositive()) {
831 const one = Int.initFixed(([]Limb{1})[0..]);
832 try q.sub(q.*, one);
833 try r.add(q.*, one);
755834 }
756 r.positive = b.positive;
835 r.setSign(b.isPositive());
757836 }
758837
838 /// q = a / b (rem r)
839 ///
840 /// a / b are truncated (rounded towards -inf).
759841 pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
760842 try div(q, r, a, b);
761 r.positive = a.positive;
843 r.setSign(a.isPositive());
762844 }
763845
764846 // Truncates by default.
765847 fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void {
848 quo.assertWritable();
849 rem.assertWritable();
850
766851 if (b.eqZero()) {
767852 @panic("division by zero");
768853 }
......@@ -773,36 +858,67 @@ pub const Int = struct {
773858 if (a.cmpAbs(b) < 0) {
774859 // quo may alias a so handle rem first
775860 try rem.copy(a);
776 rem.positive = a.positive == b.positive;
861 rem.setSign(a.isPositive() == b.isPositive());
777862
778 quo.positive = true;
779 quo.len = 1;
863 quo.metadata = 1;
780864 quo.limbs[0] = 0;
781865 return;
782866 }
783867
784 if (b.len == 1) {
785 try quo.ensureCapacity(a.len);
868 // Handle trailing zero-words of divisor/dividend. These are not handled in the following
869 // algorithms.
870 const a_zero_limb_count = blk: {
871 var i: usize = 0;
872 while (i < a.len()) : (i += 1) {
873 if (a.limbs[i] != 0) break;
874 }
875 break :blk i;
876 };
877 const b_zero_limb_count = blk: {
878 var i: usize = 0;
879 while (i < b.len()) : (i += 1) {
880 if (b.limbs[i] != 0) break;
881 }
882 break :blk i;
883 };
786884
787 lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[0..a.len], b.limbs[0]);
788 quo.norm1(a.len);
789 quo.positive = a.positive == b.positive;
885 const ab_zero_limb_count = std.math.min(a_zero_limb_count, b_zero_limb_count);
790886
791 rem.len = 1;
792 rem.positive = true;
887 if (b.len() - ab_zero_limb_count == 1) {
888 try quo.ensureCapacity(a.len());
889
890 lldiv1(quo.limbs[0..], &rem.limbs[0], a.limbs[ab_zero_limb_count..a.len()], b.limbs[b.len() - 1]);
891 quo.normalize(a.len() - ab_zero_limb_count);
892 quo.setSign(a.isPositive() == b.isPositive());
893
894 rem.metadata = 1;
793895 } else {
794896 // x and y are modified during division
795 var x = try a.clone();
897 var x = try Int.initCapacity(quo.allocator.?, a.len());
796898 defer x.deinit();
899 try x.copy(a);
797900
798 var y = try b.clone();
901 var y = try Int.initCapacity(quo.allocator.?, b.len());
799902 defer y.deinit();
903 try y.copy(b);
800904
801905 // x may grow one limb during normalization
802 try quo.ensureCapacity(a.len + y.len);
803 try divN(quo.allocator, quo, rem, &x, &y);
906 try quo.ensureCapacity(a.len() + y.len());
907
908 // Shrink x, y such that the trailing zero limbs shared between are removed.
909 if (ab_zero_limb_count != 0) {
910 std.mem.copy(Limb, x.limbs[0..], x.limbs[ab_zero_limb_count..]);
911 std.mem.copy(Limb, y.limbs[0..], y.limbs[ab_zero_limb_count..]);
912 x.metadata -= ab_zero_limb_count;
913 y.metadata -= ab_zero_limb_count;
914 }
804915
805 quo.positive = a.positive == b.positive;
916 try divN(quo.allocator.?, quo, rem, &x, &y);
917 quo.setSign(a.isPositive() == b.isPositive());
918 }
919
920 if (ab_zero_limb_count != 0) {
921 try rem.shiftLeft(rem.*, ab_zero_limb_count * Limb.bit_count);
806922 }
807923 }
808924
......@@ -837,25 +953,28 @@ pub const Int = struct {
837953 //
838954 // x = qy + r where 0 <= r < y
839955 fn divN(allocator: *Allocator, q: *Int, r: *Int, x: *Int, y: *Int) !void {
840 debug.assert(y.len >= 2);
841 debug.assert(x.len >= y.len);
842 debug.assert(q.limbs.len >= x.len + y.len - 1);
956 debug.assert(y.len() >= 2);
957 debug.assert(x.len() >= y.len());
958 debug.assert(q.limbs.len >= x.len() + y.len() - 1);
843959 debug.assert(default_capacity >= 3); // see 3.2
844960
845961 var tmp = try Int.init(allocator);
846962 defer tmp.deinit();
847963
848 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)
849 const norm_shift = @clz(y.limbs[y.len - 1]);
964 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even
965 var norm_shift = @clz(y.limbs[y.len() - 1]);
966 if (norm_shift == 0 and y.isOdd()) {
967 norm_shift = Limb.bit_count;
968 }
850969 try x.shiftLeft(x.*, norm_shift);
851970 try y.shiftLeft(y.*, norm_shift);
852971
853 const n = x.len - 1;
854 const t = y.len - 1;
972 const n = x.len() - 1;
973 const t = y.len() - 1;
855974
856975 // 1.
857 q.len = n - t + 1;
858 mem.set(Limb, q.limbs[0..q.len], 0);
976 q.metadata = n - t + 1;
977 mem.set(Limb, q.limbs[0..q.len()], 0);
859978
860979 // 2.
861980 try tmp.shiftLeft(y.*, Limb.bit_count * (n - t));
......@@ -880,7 +999,7 @@ pub const Int = struct {
880999 tmp.limbs[0] = if (i >= 2) x.limbs[i - 2] else 0;
8811000 tmp.limbs[1] = if (i >= 1) x.limbs[i - 1] else 0;
8821001 tmp.limbs[2] = x.limbs[i];
883 tmp.normN(3);
1002 tmp.normalize(3);
8841003
8851004 while (true) {
8861005 // 2x1 limb multiplication unrolled against single-limb q[i-t-1]
......@@ -888,7 +1007,7 @@ pub const Int = struct {
8881007 r.limbs[0] = addMulLimbWithCarry(0, if (t >= 1) y.limbs[t - 1] else 0, q.limbs[i - t - 1], &carry);
8891008 r.limbs[1] = addMulLimbWithCarry(0, y.limbs[t], q.limbs[i - t - 1], &carry);
8901009 r.limbs[2] = carry;
891 r.normN(3);
1010 r.normalize(3);
8921011
8931012 if (r.cmpAbs(tmp) <= 0) {
8941013 break;
......@@ -903,7 +1022,7 @@ pub const Int = struct {
9031022 try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1));
9041023 try x.sub(x.*, tmp);
9051024
906 if (!x.positive) {
1025 if (!x.isPositive()) {
9071026 try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1));
9081027 try x.add(x.*, tmp);
9091028 q.limbs[i - t - 1] -= 1;
......@@ -911,18 +1030,20 @@ pub const Int = struct {
9111030 }
9121031
9131032 // Denormalize
914 q.normN(q.len);
1033 q.normalize(q.len());
9151034
9161035 try r.shiftRight(x.*, norm_shift);
917 r.normN(r.len);
1036 r.normalize(r.len());
9181037 }
9191038
920 // r = a << shift, in other words, r = a * 2^shift
1039 /// r = a << shift, in other words, r = a * 2^shift
9211040 pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
922 try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);
923 llshl(r.limbs[0..], a.limbs[0..a.len], shift);
924 r.norm1(a.len + (shift / Limb.bit_count) + 1);
925 r.positive = a.positive;
1041 r.assertWritable();
1042
1043 try r.ensureCapacity(a.len() + (shift / Limb.bit_count) + 1);
1044 llshl(r.limbs[0..], a.limbs[0..a.len()], shift);
1045 r.normalize(a.len() + (shift / Limb.bit_count) + 1);
1046 r.setSign(a.isPositive());
9261047 }
9271048
9281049 fn llshl(r: []Limb, a: []const Limb, shift: usize) void {
......@@ -948,19 +1069,20 @@ pub const Int = struct {
9481069 mem.set(Limb, r[0 .. limb_shift - 1], 0);
9491070 }
9501071
951 // r = a >> shift
1072 /// r = a >> shift
9521073 pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
953 if (a.len <= shift / Limb.bit_count) {
954 r.len = 1;
1074 r.assertWritable();
1075
1076 if (a.len() <= shift / Limb.bit_count) {
1077 r.metadata = 1;
9551078 r.limbs[0] = 0;
956 r.positive = true;
9571079 return;
9581080 }
9591081
960 try r.ensureCapacity(a.len - (shift / Limb.bit_count));
961 const r_len = llshr(r.limbs[0..], a.limbs[0..a.len], shift);
962 r.len = a.len - (shift / Limb.bit_count);
963 r.positive = a.positive;
1082 try r.ensureCapacity(a.len() - (shift / Limb.bit_count));
1083 const r_len = llshr(r.limbs[0..], a.limbs[0..a.len()], shift);
1084 r.metadata = a.len() - (shift / Limb.bit_count);
1085 r.setSign(a.isPositive());
9641086 }
9651087
9661088 fn llshr(r: []Limb, a: []const Limb, shift: usize) void {
......@@ -983,16 +1105,20 @@ pub const Int = struct {
9831105 }
9841106 }
9851107
986 // r = a | b
1108 /// r = a | b
1109 ///
1110 /// a and b are zero-extended to the longer of a or b.
9871111 pub fn bitOr(r: *Int, a: Int, b: Int) !void {
988 if (a.len > b.len) {
989 try r.ensureCapacity(a.len);
990 llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
991 r.len = a.len;
1112 r.assertWritable();
1113
1114 if (a.len() > b.len()) {
1115 try r.ensureCapacity(a.len());
1116 llor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
1117 r.setLen(a.len());
9921118 } else {
993 try r.ensureCapacity(b.len);
994 llor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
995 r.len = b.len;
1119 try r.ensureCapacity(b.len());
1120 llor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
1121 r.setLen(b.len());
9961122 }
9971123 }
9981124
......@@ -1010,16 +1136,18 @@ pub const Int = struct {
10101136 }
10111137 }
10121138
1013 // r = a & b
1139 /// r = a & b
10141140 pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
1015 if (a.len > b.len) {
1016 try r.ensureCapacity(b.len);
1017 lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
1018 r.normN(b.len);
1141 r.assertWritable();
1142
1143 if (a.len() > b.len()) {
1144 try r.ensureCapacity(b.len());
1145 lland(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
1146 r.normalize(b.len());
10191147 } else {
1020 try r.ensureCapacity(a.len);
1021 lland(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
1022 r.normN(a.len);
1148 try r.ensureCapacity(a.len());
1149 lland(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
1150 r.normalize(a.len());
10231151 }
10241152 }
10251153
......@@ -1034,16 +1162,18 @@ pub const Int = struct {
10341162 }
10351163 }
10361164
1037 // r = a ^ b
1165 /// r = a ^ b
10381166 pub fn bitXor(r: *Int, a: Int, b: Int) !void {
1039 if (a.len > b.len) {
1040 try r.ensureCapacity(a.len);
1041 llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
1042 r.normN(a.len);
1167 r.assertWritable();
1168
1169 if (a.len() > b.len()) {
1170 try r.ensureCapacity(a.len());
1171 llxor(r.limbs[0..], a.limbs[0..a.len()], b.limbs[0..b.len()]);
1172 r.normalize(a.len());
10431173 } else {
1044 try r.ensureCapacity(b.len);
1045 llxor(r.limbs[0..], b.limbs[0..b.len], a.limbs[0..a.len]);
1046 r.normN(b.len);
1174 try r.ensureCapacity(b.len());
1175 llxor(r.limbs[0..], b.limbs[0..b.len()], a.limbs[0..a.len()]);
1176 r.normalize(b.len());
10471177 }
10481178 }
10491179
......@@ -1067,7 +1197,9 @@ pub const Int = struct {
10671197// They will still run on larger than this and should pass, but the multi-limb code-paths
10681198// may be untested in some cases.
10691199
1070const al = debug.global_allocator;
1200var buffer: [64 * 8192]u8 = undefined;
1201var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
1202const al = &fixed.allocator;
10711203
10721204test "big.int comptime_int set" {
10731205 comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
......@@ -1088,14 +1220,14 @@ test "big.int comptime_int set negative" {
10881220 var a = try Int.initSet(al, -10);
10891221
10901222 testing.expect(a.limbs[0] == 10);
1091 testing.expect(a.positive == false);
1223 testing.expect(a.isPositive() == false);
10921224}
10931225
10941226test "big.int int set unaligned small" {
10951227 var a = try Int.initSet(al, u7(45));
10961228
10971229 testing.expect(a.limbs[0] == 45);
1098 testing.expect(a.positive == true);
1230 testing.expect(a.isPositive() == true);
10991231}
11001232
11011233test "big.int comptime_int to" {
......@@ -1116,7 +1248,7 @@ test "big.int to target too small error" {
11161248 testing.expectError(error.TargetTooSmall, a.to(u8));
11171249}
11181250
1119test "big.int norm1" {
1251test "big.int normalize" {
11201252 var a = try Int.init(al);
11211253 try a.ensureCapacity(8);
11221254
......@@ -1124,26 +1256,26 @@ test "big.int norm1" {
11241256 a.limbs[1] = 2;
11251257 a.limbs[2] = 3;
11261258 a.limbs[3] = 0;
1127 a.norm1(4);
1128 testing.expect(a.len == 3);
1259 a.normalize(4);
1260 testing.expect(a.len() == 3);
11291261
11301262 a.limbs[0] = 1;
11311263 a.limbs[1] = 2;
11321264 a.limbs[2] = 3;
1133 a.norm1(3);
1134 testing.expect(a.len == 3);
1265 a.normalize(3);
1266 testing.expect(a.len() == 3);
11351267
11361268 a.limbs[0] = 0;
11371269 a.limbs[1] = 0;
1138 a.norm1(2);
1139 testing.expect(a.len == 1);
1270 a.normalize(2);
1271 testing.expect(a.len() == 1);
11401272
11411273 a.limbs[0] = 0;
1142 a.norm1(1);
1143 testing.expect(a.len == 1);
1274 a.normalize(1);
1275 testing.expect(a.len() == 1);
11441276}
11451277
1146test "big.int normN" {
1278test "big.int normalize multi" {
11471279 var a = try Int.init(al);
11481280 try a.ensureCapacity(8);
11491281
......@@ -1151,25 +1283,25 @@ test "big.int normN" {
11511283 a.limbs[1] = 2;
11521284 a.limbs[2] = 0;
11531285 a.limbs[3] = 0;
1154 a.normN(4);
1155 testing.expect(a.len == 2);
1286 a.normalize(4);
1287 testing.expect(a.len() == 2);
11561288
11571289 a.limbs[0] = 1;
11581290 a.limbs[1] = 2;
11591291 a.limbs[2] = 3;
1160 a.normN(3);
1161 testing.expect(a.len == 3);
1292 a.normalize(3);
1293 testing.expect(a.len() == 3);
11621294
11631295 a.limbs[0] = 0;
11641296 a.limbs[1] = 0;
11651297 a.limbs[2] = 0;
11661298 a.limbs[3] = 0;
1167 a.normN(4);
1168 testing.expect(a.len == 1);
1299 a.normalize(4);
1300 testing.expect(a.len() == 1);
11691301
11701302 a.limbs[0] = 0;
1171 a.normN(1);
1172 testing.expect(a.len == 1);
1303 a.normalize(1);
1304 testing.expect(a.len() == 1);
11731305}
11741306
11751307test "big.int parity" {
......@@ -1204,7 +1336,7 @@ test "big.int bitcount + sizeInBase" {
12041336 try a.shiftLeft(a, 5000);
12051337 testing.expect(a.bitCountAbs() == 5032);
12061338 testing.expect(a.sizeInBase(2) >= 5032);
1207 a.positive = false;
1339 a.setSign(false);
12081340
12091341 testing.expect(a.bitCountAbs() == 5032);
12101342 testing.expect(a.sizeInBase(2) >= 5033);
......@@ -1216,10 +1348,8 @@ test "big.int bitcount/to" {
12161348 try a.set(0);
12171349 testing.expect(a.bitCountTwosComp() == 0);
12181350
1219 // TODO: stack smashing
1220 // testing.expect((try a.to(u0)) == 0);
1221 // TODO: sigsegv
1222 // testing.expect((try a.to(i0)) == 0);
1351 testing.expect((try a.to(u0)) == 0);
1352 testing.expect((try a.to(i0)) == 0);
12231353
12241354 try a.set(-1);
12251355 testing.expect(a.bitCountTwosComp() == 1);
......@@ -1980,6 +2110,98 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
19802110 testing.expect((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
19812111}
19822112
2113test "big.int div multi-single zero-limb trailing" {
2114 var a = try Int.initSet(al, 0x60000000000000000000000000000000000000000000000000000000000000000);
2115 var b = try Int.initSet(al, 0x10000000000000000);
2116
2117 var q = try Int.init(al);
2118 var r = try Int.init(al);
2119 try Int.divTrunc(&q, &r, a, b);
2120
2121 var expected = try Int.initSet(al, 0x6000000000000000000000000000000000000000000000000);
2122 testing.expect(q.eq(expected));
2123 testing.expect(r.eqZero());
2124}
2125
2126test "big.int div multi-multi zero-limb trailing (with rem)" {
2127 var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
2128 var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
2129
2130 var q = try Int.init(al);
2131 var r = try Int.init(al);
2132 try Int.divTrunc(&q, &r, a, b);
2133
2134 testing.expect((try q.to(u128)) == 0x10000000000000000);
2135
2136 const rs = try r.toString(al, 16);
2137 testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000"));
2138}
2139
2140test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
2141 var a = try Int.initSet(al, 0x8666666655555555888888877777777611111111111111110000000000000000);
2142 var b = try Int.initSet(al, 0x8666666655555555444444443333333300000000000000000000000000000000);
2143
2144 var q = try Int.init(al);
2145 var r = try Int.init(al);
2146 try Int.divTrunc(&q, &r, a, b);
2147
2148 testing.expect((try q.to(u128)) == 0x1);
2149
2150 const rs = try r.toString(al, 16);
2151 testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000"));
2152}
2153
2154test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
2155 var a = try Int.initSet(al, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
2156 var b = try Int.initSet(al, 0x866666665555555544444444333333330000000000000000);
2157
2158 var q = try Int.init(al);
2159 var r = try Int.init(al);
2160 try Int.divTrunc(&q, &r, a, b);
2161
2162 const qs = try q.toString(al, 16);
2163 testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f"));
2164
2165 const rs = try r.toString(al, 16);
2166 testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000"));
2167}
2168
2169test "big.int div multi-multi fuzz case #1" {
2170 var a = try Int.init(al);
2171 var b = try Int.init(al);
2172
2173 try a.setString(16, "ffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
2174 try b.setString(16, "3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000000000000000000007fffffffffff");
2175
2176 var q = try Int.init(al);
2177 var r = try Int.init(al);
2178 try Int.divTrunc(&q, &r, a, b);
2179
2180 const qs = try q.toString(al, 16);
2181 testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1"));
2182
2183 const rs = try r.toString(al, 16);
2184 testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1"));
2185}
2186
2187test "big.int div multi-multi fuzz case #2" {
2188 var a = try Int.init(al);
2189 var b = try Int.init(al);
2190
2191 try a.setString(16, "3ffffffffe00000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000001fffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffc000000000000000000000000000000000000000000000000000000000000000");
2192 try b.setString(16, "ffc0000000000000000000000000000000000000000000000000");
2193
2194 var q = try Int.init(al);
2195 var r = try Int.init(al);
2196 try Int.divTrunc(&q, &r, a, b);
2197
2198 const qs = try q.toString(al, 16);
2199 testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4"));
2200
2201 const rs = try r.toString(al, 16);
2202 testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000"));
2203}
2204
19832205test "big.int shift-right single" {
19842206 var a = try Int.initSet(al, 0xffff0000);
19852207 try a.shiftRight(a, 16);
std/math/big/rational.zig created+938
......@@ -0,0 +1,938 @@
1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const debug = std.debug;
4const math = std.math;
5const mem = std.mem;
6const testing = std.testing;
7const Allocator = mem.Allocator;
8const ArrayList = std.ArrayList;
9
10const TypeId = builtin.TypeId;
11
12const bn = @import("int.zig");
13const Limb = bn.Limb;
14const DoubleLimb = bn.DoubleLimb;
15const Int = bn.Int;
16
17/// An arbitrary-precision rational number.
18///
19/// Memory is allocated as needed for operations to ensure full precision is kept. The precision
20/// of a Rational is only bounded by memory.
21///
22/// Rational's are always normalized. That is, for a Rational r = p/q where p and q are integers,
23/// gcd(p, q) = 1 always.
24pub const Rational = struct {
25 /// Numerator. Determines the sign of the Rational.
26 p: Int,
27
28 /// Denominator. Sign is ignored.
29 q: Int,
30
31 /// Create a new Rational. A small amount of memory will be allocated on initialization.
32 /// This will be 2 * Int.default_capacity.
33 pub fn init(a: *Allocator) !Rational {
34 return Rational{
35 .p = try Int.init(a),
36 .q = try Int.initSet(a, 1),
37 };
38 }
39
40 /// Frees all memory associated with a Rational.
41 pub fn deinit(self: *Rational) void {
42 self.p.deinit();
43 self.q.deinit();
44 }
45
46 /// Set a Rational from a primitive integer type.
47 pub fn setInt(self: *Rational, a: var) !void {
48 try self.p.set(a);
49 try self.q.set(1);
50 }
51
52 /// Set a Rational from a string of the form `A/B` where A and B are base-10 integers.
53 pub fn setFloatString(self: *Rational, str: []const u8) !void {
54 // TODO: Accept a/b fractions and exponent form
55 if (str.len == 0) {
56 return error.InvalidFloatString;
57 }
58
59 const State = enum {
60 Integer,
61 Fractional,
62 };
63
64 var state = State.Integer;
65 var point: ?usize = null;
66
67 var start: usize = 0;
68 if (str[0] == '-') {
69 start += 1;
70 }
71
72 for (str) |c, i| {
73 switch (state) {
74 State.Integer => {
75 switch (c) {
76 '.' => {
77 state = State.Fractional;
78 point = i;
79 },
80 '0'...'9' => {
81 // okay
82 },
83 else => {
84 return error.InvalidFloatString;
85 },
86 }
87 },
88 State.Fractional => {
89 switch (c) {
90 '0'...'9' => {
91 // okay
92 },
93 else => {
94 return error.InvalidFloatString;
95 },
96 }
97 },
98 }
99 }
100
101 // TODO: batch the multiplies by 10
102 if (point) |i| {
103 try self.p.setString(10, str[0..i]);
104
105 const base = Int.initFixed(([]Limb{10})[0..]);
106
107 var j: usize = start;
108 while (j < str.len - i - 1) : (j += 1) {
109 try self.p.mul(self.p, base);
110 }
111
112 try self.q.setString(10, str[i + 1 ..]);
113 try self.p.add(self.p, self.q);
114
115 try self.q.set(1);
116 var k: usize = i + 1;
117 while (k < str.len) : (k += 1) {
118 try self.q.mul(self.q, base);
119 }
120
121 try self.reduce();
122 } else {
123 try self.p.setString(10, str[0..]);
124 try self.q.set(1);
125 }
126 }
127
128 /// Set a Rational from a floating-point value. The rational will have enough precision to
129 /// completely represent the provided float.
130 pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {
131 // Translated from golang.go/src/math/big/rat.go.
132 debug.assert(@typeId(T) == builtin.TypeId.Float);
133
134 const UnsignedIntType = @IntType(false, T.bit_count);
135 const f_bits = @bitCast(UnsignedIntType, f);
136
137 const exponent_bits = math.floatExponentBits(T);
138 const exponent_bias = (1 << (exponent_bits - 1)) - 1;
139 const mantissa_bits = math.floatMantissaBits(T);
140
141 const exponent_mask = (1 << exponent_bits) - 1;
142 const mantissa_mask = (1 << mantissa_bits) - 1;
143
144 var exponent = @intCast(i16, (f_bits >> mantissa_bits) & exponent_mask);
145 var mantissa = f_bits & mantissa_mask;
146
147 switch (exponent) {
148 exponent_mask => {
149 return error.NonFiniteFloat;
150 },
151 0 => {
152 // denormal
153 exponent -= exponent_bias - 1;
154 },
155 else => {
156 // normal
157 mantissa |= 1 << mantissa_bits;
158 exponent -= exponent_bias;
159 },
160 }
161
162 var shift: i16 = mantissa_bits - exponent;
163
164 // factor out powers of two early from rational
165 while (mantissa & 1 == 0 and shift > 0) {
166 mantissa >>= 1;
167 shift -= 1;
168 }
169
170 try self.p.set(mantissa);
171 self.p.setSign(f >= 0);
172
173 try self.q.set(1);
174 if (shift >= 0) {
175 try self.q.shiftLeft(self.q, @intCast(usize, shift));
176 } else {
177 try self.p.shiftLeft(self.p, @intCast(usize, -shift));
178 }
179
180 try self.reduce();
181 }
182
183 /// Return a floating-point value that is the closest value to a Rational.
184 ///
185 /// The result may not be exact if the Rational is too precise or too large for the
186 /// target type.
187 pub fn toFloat(self: Rational, comptime T: type) !T {
188 // Translated from golang.go/src/math/big/rat.go.
189 // TODO: Indicate whether the result is not exact.
190 debug.assert(@typeId(T) == builtin.TypeId.Float);
191
192 const fsize = T.bit_count;
193 const BitReprType = @IntType(false, T.bit_count);
194
195 const msize = math.floatMantissaBits(T);
196 const msize1 = msize + 1;
197 const msize2 = msize1 + 1;
198
199 const esize = math.floatExponentBits(T);
200 const ebias = (1 << (esize - 1)) - 1;
201 const emin = 1 - ebias;
202 const emax = ebias;
203
204 if (self.p.eqZero()) {
205 return 0;
206 }
207
208 // 1. left-shift a or sub so that a/b is in [1 << msize1, 1 << (msize2 + 1)]
209 var exp = @intCast(isize, self.p.bitCountTwosComp()) - @intCast(isize, self.q.bitCountTwosComp());
210
211 var a2 = try self.p.clone();
212 defer a2.deinit();
213
214 var b2 = try self.q.clone();
215 defer b2.deinit();
216
217 const shift = msize2 - exp;
218 if (shift >= 0) {
219 try a2.shiftLeft(a2, @intCast(usize, shift));
220 } else {
221 try b2.shiftLeft(b2, @intCast(usize, -shift));
222 }
223
224 // 2. compute quotient and remainder
225 var q = try Int.init(self.p.allocator.?);
226 defer q.deinit();
227
228 // unused
229 var r = try Int.init(self.p.allocator.?);
230 defer r.deinit();
231
232 try Int.divTrunc(&q, &r, a2, b2);
233
234 var mantissa = extractLowBits(q, BitReprType);
235 var have_rem = r.len() > 0;
236
237 // 3. q didn't fit in msize2 bits, redo division b2 << 1
238 if (mantissa >> msize2 == 1) {
239 if (mantissa & 1 == 1) {
240 have_rem = true;
241 }
242 mantissa >>= 1;
243 exp += 1;
244 }
245 if (mantissa >> msize1 != 1) {
246 // NOTE: This can be hit if the limb size is small (u8/16).
247 @panic("unexpected bits in result");
248 }
249
250 // 4. Rounding
251 if (emin - msize <= exp and exp <= emin) {
252 // denormal
253 const shift1 = @intCast(math.Log2Int(BitReprType), emin - (exp - 1));
254 const lost_bits = mantissa & ((@intCast(BitReprType, 1) << shift1) - 1);
255 have_rem = have_rem or lost_bits != 0;
256 mantissa >>= shift1;
257 exp = 2 - ebias;
258 }
259
260 // round q using round-half-to-even
261 var exact = !have_rem;
262 if (mantissa & 1 != 0) {
263 exact = false;
264 if (have_rem or (mantissa & 2 != 0)) {
265 mantissa += 1;
266 if (mantissa >= 1 << msize2) {
267 // 11...1 => 100...0
268 mantissa >>= 1;
269 exp += 1;
270 }
271 }
272 }
273 mantissa >>= 1;
274
275 const f = math.scalbn(@intToFloat(T, mantissa), @intCast(i32, exp - msize1));
276 if (math.isInf(f)) {
277 exact = false;
278 }
279
280 return if (self.p.isPositive()) f else -f;
281 }
282
283 /// Set a rational from an integer ratio.
284 pub fn setRatio(self: *Rational, p: var, q: var) !void {
285 try self.p.set(p);
286 try self.q.set(q);
287
288 self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0);
289 self.q.setSign(true);
290
291 try self.reduce();
292
293 if (self.q.eqZero()) {
294 @panic("cannot set rational with denominator = 0");
295 }
296 }
297
298 /// Set a Rational directly from an Int.
299 pub fn copyInt(self: *Rational, a: Int) !void {
300 try self.p.copy(a);
301 try self.q.set(1);
302 }
303
304 /// Set a Rational directly from a ratio of two Int's.
305 pub fn copyRatio(self: *Rational, a: Int, b: Int) !void {
306 try self.p.copy(a);
307 try self.q.copy(b);
308
309 self.p.setSign(@boolToInt(self.p.isPositive()) ^ @boolToInt(self.q.isPositive()) == 0);
310 self.q.setSign(true);
311
312 try self.reduce();
313 }
314
315 /// Make a Rational positive.
316 pub fn abs(r: *Rational) void {
317 r.p.abs();
318 }
319
320 /// Negate the sign of a Rational.
321 pub fn negate(r: *Rational) void {
322 r.p.negate();
323 }
324
325 /// Efficiently swap a Rational with another. This swaps the limb pointers and a full copy is not
326 /// performed. The address of the limbs field will not be the same after this function.
327 pub fn swap(r: *Rational, other: *Rational) void {
328 r.p.swap(&other.p);
329 r.q.swap(&other.q);
330 }
331
332 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
333 pub fn cmp(a: Rational, b: Rational) !i8 {
334 return cmpInternal(a, b, true);
335 }
336
337 /// Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
338 pub fn cmpAbs(a: Rational, b: Rational) !i8 {
339 return cmpInternal(a, b, false);
340 }
341
342 // p/q > x/y iff p*y > x*q
343 fn cmpInternal(a: Rational, b: Rational, is_abs: bool) !i8 {
344 // TODO: Would a div compare algorithm of sorts be viable and quicker? Can we avoid
345 // the memory allocations here?
346 var q = try Int.init(a.p.allocator.?);
347 defer q.deinit();
348
349 var p = try Int.init(b.p.allocator.?);
350 defer p.deinit();
351
352 try q.mul(a.p, b.q);
353 try p.mul(b.p, a.q);
354
355 return if (is_abs) q.cmpAbs(p) else q.cmp(p);
356 }
357
358 /// rma = a + b.
359 ///
360 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
361 ///
362 /// Returns an error if memory could not be allocated.
363 pub fn add(rma: *Rational, a: Rational, b: Rational) !void {
364 var r = rma;
365 var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
366
367 var sr: Rational = undefined;
368 if (aliased) {
369 sr = try Rational.init(rma.p.allocator.?);
370 r = &sr;
371 aliased = true;
372 }
373 defer if (aliased) {
374 rma.swap(r);
375 r.deinit();
376 };
377
378 try r.p.mul(a.p, b.q);
379 try r.q.mul(b.p, a.q);
380 try r.p.add(r.p, r.q);
381
382 try r.q.mul(a.q, b.q);
383 try r.reduce();
384 }
385
386 /// rma = a - b.
387 ///
388 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
389 ///
390 /// Returns an error if memory could not be allocated.
391 pub fn sub(rma: *Rational, a: Rational, b: Rational) !void {
392 var r = rma;
393 var aliased = rma.p.limbs.ptr == a.p.limbs.ptr or rma.p.limbs.ptr == b.p.limbs.ptr;
394
395 var sr: Rational = undefined;
396 if (aliased) {
397 sr = try Rational.init(rma.p.allocator.?);
398 r = &sr;
399 aliased = true;
400 }
401 defer if (aliased) {
402 rma.swap(r);
403 r.deinit();
404 };
405
406 try r.p.mul(a.p, b.q);
407 try r.q.mul(b.p, a.q);
408 try r.p.sub(r.p, r.q);
409
410 try r.q.mul(a.q, b.q);
411 try r.reduce();
412 }
413
414 /// rma = a * b.
415 ///
416 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
417 ///
418 /// Returns an error if memory could not be allocated.
419 pub fn mul(r: *Rational, a: Rational, b: Rational) !void {
420 try r.p.mul(a.p, b.p);
421 try r.q.mul(a.q, b.q);
422 try r.reduce();
423 }
424
425 /// rma = a / b.
426 ///
427 /// rma, a and b may be aliases. However, it is more efficient if rma does not alias a or b.
428 ///
429 /// Returns an error if memory could not be allocated.
430 pub fn div(r: *Rational, a: Rational, b: Rational) !void {
431 if (b.p.eqZero()) {
432 @panic("division by zero");
433 }
434
435 try r.p.mul(a.p, b.q);
436 try r.q.mul(b.p, a.q);
437 try r.reduce();
438 }
439
440 /// Invert the numerator and denominator fields of a Rational. p/q => q/p.
441 pub fn invert(r: *Rational) void {
442 Int.swap(&r.p, &r.q);
443 }
444
445 // reduce r/q such that gcd(r, q) = 1
446 fn reduce(r: *Rational) !void {
447 var a = try Int.init(r.p.allocator.?);
448 defer a.deinit();
449
450 const sign = r.p.isPositive();
451 r.p.abs();
452 try gcd(&a, r.p, r.q);
453 r.p.setSign(sign);
454
455 const one = Int.initFixed(([]Limb{1})[0..]);
456 if (a.cmp(one) != 0) {
457 var unused = try Int.init(r.p.allocator.?);
458 defer unused.deinit();
459
460 // TODO: divexact would be useful here
461 // TODO: don't copy r.q for div
462 try Int.divTrunc(&r.p, &unused, r.p, a);
463 try Int.divTrunc(&r.q, &unused, r.q, a);
464 }
465 }
466};
467
468const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count);
469
470fn gcd(rma: *Int, x: Int, y: Int) !void {
471 rma.assertWritable();
472 var r = rma;
473 var aliased = rma.limbs.ptr == x.limbs.ptr or rma.limbs.ptr == y.limbs.ptr;
474
475 var sr: Int = undefined;
476 if (aliased) {
477 sr = try Int.initCapacity(rma.allocator.?, math.max(x.len(), y.len()));
478 r = &sr;
479 aliased = true;
480 }
481 defer if (aliased) {
482 rma.swap(r);
483 r.deinit();
484 };
485
486 try gcdLehmer(r, x, y);
487}
488
489// Storage must live for the lifetime of the returned value
490fn FixedIntFromSignedDoubleLimb(A: SignedDoubleLimb, storage: []Limb) Int {
491 std.debug.assert(storage.len >= 2);
492
493 var A_is_positive = A >= 0;
494 const Au = @intCast(DoubleLimb, if (A < 0) -A else A);
495 storage[0] = @truncate(Limb, Au);
496 storage[1] = @truncate(Limb, Au >> Limb.bit_count);
497 var Ap = Int.initFixed(storage[0..2]);
498 Ap.setSign(A_is_positive);
499 return Ap;
500}
501
502fn gcdLehmer(r: *Int, xa: Int, ya: Int) !void {
503 var x = try xa.clone();
504 x.abs();
505 defer x.deinit();
506
507 var y = try ya.clone();
508 y.abs();
509 defer y.deinit();
510
511 if (x.cmp(y) < 0) {
512 x.swap(&y);
513 }
514
515 var T = try Int.init(r.allocator.?);
516 defer T.deinit();
517
518 while (y.len() > 1) {
519 debug.assert(x.isPositive() and y.isPositive());
520 debug.assert(x.len() >= y.len());
521
522 var xh: SignedDoubleLimb = x.limbs[x.len() - 1];
523 var yh: SignedDoubleLimb = if (x.len() > y.len()) 0 else y.limbs[x.len() - 1];
524
525 var A: SignedDoubleLimb = 1;
526 var B: SignedDoubleLimb = 0;
527 var C: SignedDoubleLimb = 0;
528 var D: SignedDoubleLimb = 1;
529
530 while (yh + C != 0 and yh + D != 0) {
531 const q = @divFloor(xh + A, yh + C);
532 const qp = @divFloor(xh + B, yh + D);
533 if (q != qp) {
534 break;
535 }
536
537 var t = A - q * C;
538 A = C;
539 C = t;
540 t = B - q * D;
541 B = D;
542 D = t;
543
544 t = xh - q * yh;
545 xh = yh;
546 yh = t;
547 }
548
549 if (B == 0) {
550 // T = x % y, r is unused
551 try Int.divTrunc(r, &T, x, y);
552 debug.assert(T.isPositive());
553
554 x.swap(&y);
555 y.swap(&T);
556 } else {
557 var storage: [8]Limb = undefined;
558 const Ap = FixedIntFromSignedDoubleLimb(A, storage[0..2]);
559 const Bp = FixedIntFromSignedDoubleLimb(B, storage[2..4]);
560 const Cp = FixedIntFromSignedDoubleLimb(C, storage[4..6]);
561 const Dp = FixedIntFromSignedDoubleLimb(D, storage[6..8]);
562
563 // T = Ax + By
564 try r.mul(x, Ap);
565 try T.mul(y, Bp);
566 try T.add(r.*, T);
567
568 // u = Cx + Dy, r as u
569 try x.mul(x, Cp);
570 try r.mul(y, Dp);
571 try r.add(x, r.*);
572
573 x.swap(&T);
574 y.swap(r);
575 }
576 }
577
578 // euclidean algorithm
579 debug.assert(x.cmp(y) >= 0);
580
581 while (!y.eqZero()) {
582 try Int.divTrunc(&T, r, x, y);
583 x.swap(&y);
584 y.swap(r);
585 }
586
587 r.swap(&x);
588}
589
590var buffer: [64 * 8192]u8 = undefined;
591var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
592var al = &fixed.allocator;
593
594test "big.rational gcd non-one small" {
595 var a = try Int.initSet(al, 17);
596 var b = try Int.initSet(al, 97);
597 var r = try Int.init(al);
598
599 try gcd(&r, a, b);
600
601 testing.expect((try r.to(u32)) == 1);
602}
603
604test "big.rational gcd non-one small" {
605 var a = try Int.initSet(al, 4864);
606 var b = try Int.initSet(al, 3458);
607 var r = try Int.init(al);
608
609 try gcd(&r, a, b);
610
611 testing.expect((try r.to(u32)) == 38);
612}
613
614test "big.rational gcd non-one large" {
615 var a = try Int.initSet(al, 0xffffffffffffffff);
616 var b = try Int.initSet(al, 0xffffffffffffffff7777);
617 var r = try Int.init(al);
618
619 try gcd(&r, a, b);
620
621 testing.expect((try r.to(u32)) == 4369);
622}
623
624test "big.rational gcd large multi-limb result" {
625 var a = try Int.initSet(al, 0x12345678123456781234567812345678123456781234567812345678);
626 var b = try Int.initSet(al, 0x12345671234567123456712345671234567123456712345671234567);
627 var r = try Int.init(al);
628
629 try gcd(&r, a, b);
630
631 testing.expect((try r.to(u256)) == 0xf000000ff00000fff0000ffff000fffff00ffffff1);
632}
633
634test "big.rational gcd one large" {
635 var a = try Int.initSet(al, 1897056385327307);
636 var b = try Int.initSet(al, 2251799813685248);
637 var r = try Int.init(al);
638
639 try gcd(&r, a, b);
640
641 testing.expect((try r.to(u64)) == 1);
642}
643
644fn extractLowBits(a: Int, comptime T: type) T {
645 testing.expect(@typeId(T) == builtin.TypeId.Int);
646
647 if (T.bit_count <= Limb.bit_count) {
648 return @truncate(T, a.limbs[0]);
649 } else {
650 var r: T = 0;
651 comptime var i: usize = 0;
652
653 // Remainder is always 0 since if T.bit_count >= Limb.bit_count -> Limb | T and both
654 // are powers of two.
655 inline while (i < T.bit_count / Limb.bit_count) : (i += 1) {
656 r |= math.shl(T, a.limbs[i], i * Limb.bit_count);
657 }
658
659 return r;
660 }
661}
662
663test "big.rational extractLowBits" {
664 var a = try Int.initSet(al, 0x11112222333344441234567887654321);
665
666 const a1 = extractLowBits(a, u8);
667 testing.expect(a1 == 0x21);
668
669 const a2 = extractLowBits(a, u16);
670 testing.expect(a2 == 0x4321);
671
672 const a3 = extractLowBits(a, u32);
673 testing.expect(a3 == 0x87654321);
674
675 const a4 = extractLowBits(a, u64);
676 testing.expect(a4 == 0x1234567887654321);
677
678 const a5 = extractLowBits(a, u128);
679 testing.expect(a5 == 0x11112222333344441234567887654321);
680}
681
682test "big.rational set" {
683 var a = try Rational.init(al);
684
685 try a.setInt(5);
686 testing.expect((try a.p.to(u32)) == 5);
687 testing.expect((try a.q.to(u32)) == 1);
688
689 try a.setRatio(7, 3);
690 testing.expect((try a.p.to(u32)) == 7);
691 testing.expect((try a.q.to(u32)) == 3);
692
693 try a.setRatio(9, 3);
694 testing.expect((try a.p.to(i32)) == 3);
695 testing.expect((try a.q.to(i32)) == 1);
696
697 try a.setRatio(-9, 3);
698 testing.expect((try a.p.to(i32)) == -3);
699 testing.expect((try a.q.to(i32)) == 1);
700
701 try a.setRatio(9, -3);
702 testing.expect((try a.p.to(i32)) == -3);
703 testing.expect((try a.q.to(i32)) == 1);
704
705 try a.setRatio(-9, -3);
706 testing.expect((try a.p.to(i32)) == 3);
707 testing.expect((try a.q.to(i32)) == 1);
708}
709
710test "big.rational setFloat" {
711 var a = try Rational.init(al);
712
713 try a.setFloat(f64, 2.5);
714 testing.expect((try a.p.to(i32)) == 5);
715 testing.expect((try a.q.to(i32)) == 2);
716
717 try a.setFloat(f32, -2.5);
718 testing.expect((try a.p.to(i32)) == -5);
719 testing.expect((try a.q.to(i32)) == 2);
720
721 try a.setFloat(f32, 3.141593);
722
723 // = 3.14159297943115234375
724 testing.expect((try a.p.to(u32)) == 3294199);
725 testing.expect((try a.q.to(u32)) == 1048576);
726
727 try a.setFloat(f64, 72.141593120712409172417410926841290461290467124);
728
729 // = 72.1415931207124145885245525278151035308837890625
730 testing.expect((try a.p.to(u128)) == 5076513310880537);
731 testing.expect((try a.q.to(u128)) == 70368744177664);
732}
733
734test "big.rational setFloatString" {
735 var a = try Rational.init(al);
736
737 try a.setFloatString("72.14159312071241458852455252781510353");
738
739 // = 72.1415931207124145885245525278151035308837890625
740 testing.expect((try a.p.to(u128)) == 7214159312071241458852455252781510353);
741 testing.expect((try a.q.to(u128)) == 100000000000000000000000000000000000);
742}
743
744test "big.rational toFloat" {
745 var a = try Rational.init(al);
746
747 // = 3.14159297943115234375
748 try a.setRatio(3294199, 1048576);
749 testing.expect((try a.toFloat(f64)) == 3.14159297943115234375);
750
751 // = 72.1415931207124145885245525278151035308837890625
752 try a.setRatio(5076513310880537, 70368744177664);
753 testing.expect((try a.toFloat(f64)) == 72.141593120712409172417410926841290461290467124);
754}
755
756test "big.rational set/to Float round-trip" {
757 var a = try Rational.init(al);
758 var prng = std.rand.DefaultPrng.init(0x5EED);
759 var i: usize = 0;
760 while (i < 512) : (i += 1) {
761 const r = prng.random.float(f64);
762 try a.setFloat(f64, r);
763 testing.expect((try a.toFloat(f64)) == r);
764 }
765}
766
767test "big.rational copy" {
768 var a = try Rational.init(al);
769
770 const b = try Int.initSet(al, 5);
771
772 try a.copyInt(b);
773 testing.expect((try a.p.to(u32)) == 5);
774 testing.expect((try a.q.to(u32)) == 1);
775
776 const c = try Int.initSet(al, 7);
777 const d = try Int.initSet(al, 3);
778
779 try a.copyRatio(c, d);
780 testing.expect((try a.p.to(u32)) == 7);
781 testing.expect((try a.q.to(u32)) == 3);
782
783 const e = try Int.initSet(al, 9);
784 const f = try Int.initSet(al, 3);
785
786 try a.copyRatio(e, f);
787 testing.expect((try a.p.to(u32)) == 3);
788 testing.expect((try a.q.to(u32)) == 1);
789}
790
791test "big.rational negate" {
792 var a = try Rational.init(al);
793
794 try a.setInt(-50);
795 testing.expect((try a.p.to(i32)) == -50);
796 testing.expect((try a.q.to(i32)) == 1);
797
798 a.negate();
799 testing.expect((try a.p.to(i32)) == 50);
800 testing.expect((try a.q.to(i32)) == 1);
801
802 a.negate();
803 testing.expect((try a.p.to(i32)) == -50);
804 testing.expect((try a.q.to(i32)) == 1);
805}
806
807test "big.rational abs" {
808 var a = try Rational.init(al);
809
810 try a.setInt(-50);
811 testing.expect((try a.p.to(i32)) == -50);
812 testing.expect((try a.q.to(i32)) == 1);
813
814 a.abs();
815 testing.expect((try a.p.to(i32)) == 50);
816 testing.expect((try a.q.to(i32)) == 1);
817
818 a.abs();
819 testing.expect((try a.p.to(i32)) == 50);
820 testing.expect((try a.q.to(i32)) == 1);
821}
822
823test "big.rational swap" {
824 var a = try Rational.init(al);
825 var b = try Rational.init(al);
826
827 try a.setRatio(50, 23);
828 try b.setRatio(17, 3);
829
830 testing.expect((try a.p.to(u32)) == 50);
831 testing.expect((try a.q.to(u32)) == 23);
832
833 testing.expect((try b.p.to(u32)) == 17);
834 testing.expect((try b.q.to(u32)) == 3);
835
836 a.swap(&b);
837
838 testing.expect((try a.p.to(u32)) == 17);
839 testing.expect((try a.q.to(u32)) == 3);
840
841 testing.expect((try b.p.to(u32)) == 50);
842 testing.expect((try b.q.to(u32)) == 23);
843}
844
845test "big.rational cmp" {
846 var a = try Rational.init(al);
847 var b = try Rational.init(al);
848
849 try a.setRatio(500, 231);
850 try b.setRatio(18903, 8584);
851 testing.expect((try a.cmp(b)) < 0);
852
853 try a.setRatio(890, 10);
854 try b.setRatio(89, 1);
855 testing.expect((try a.cmp(b)) == 0);
856}
857
858test "big.rational add single-limb" {
859 var a = try Rational.init(al);
860 var b = try Rational.init(al);
861
862 try a.setRatio(500, 231);
863 try b.setRatio(18903, 8584);
864 testing.expect((try a.cmp(b)) < 0);
865
866 try a.setRatio(890, 10);
867 try b.setRatio(89, 1);
868 testing.expect((try a.cmp(b)) == 0);
869}
870
871test "big.rational add" {
872 var a = try Rational.init(al);
873 var b = try Rational.init(al);
874 var r = try Rational.init(al);
875
876 try a.setRatio(78923, 23341);
877 try b.setRatio(123097, 12441414);
878 try a.add(a, b);
879
880 try r.setRatio(984786924199, 290395044174);
881 testing.expect((try a.cmp(r)) == 0);
882}
883
884test "big.rational sub" {
885 var a = try Rational.init(al);
886 var b = try Rational.init(al);
887 var r = try Rational.init(al);
888
889 try a.setRatio(78923, 23341);
890 try b.setRatio(123097, 12441414);
891 try a.sub(a, b);
892
893 try r.setRatio(979040510045, 290395044174);
894 testing.expect((try a.cmp(r)) == 0);
895}
896
897test "big.rational mul" {
898 var a = try Rational.init(al);
899 var b = try Rational.init(al);
900 var r = try Rational.init(al);
901
902 try a.setRatio(78923, 23341);
903 try b.setRatio(123097, 12441414);
904 try a.mul(a, b);
905
906 try r.setRatio(571481443, 17082061422);
907 testing.expect((try a.cmp(r)) == 0);
908}
909
910test "big.rational div" {
911 var a = try Rational.init(al);
912 var b = try Rational.init(al);
913 var r = try Rational.init(al);
914
915 try a.setRatio(78923, 23341);
916 try b.setRatio(123097, 12441414);
917 try a.div(a, b);
918
919 try r.setRatio(75531824394, 221015929);
920 testing.expect((try a.cmp(r)) == 0);
921}
922
923test "big.rational div" {
924 var a = try Rational.init(al);
925 var r = try Rational.init(al);
926
927 try a.setRatio(78923, 23341);
928 a.invert();
929
930 try r.setRatio(23341, 78923);
931 testing.expect((try a.cmp(r)) == 0);
932
933 try a.setRatio(-78923, 23341);
934 a.invert();
935
936 try r.setRatio(-23341, 78923);
937 testing.expect((try a.cmp(r)) == 0);
938}
std/math/cbrt.zig+10-4
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - cbrt(+-0) = +-0
4// - cbrt(+-inf) = +-inf
5// - cbrt(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/cbrtf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/cbrt.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010
11/// Returns the cube root of x.
12///
13/// Special Cases:
14/// - cbrt(+-0) = +-0
15/// - cbrt(+-inf) = +-inf
16/// - cbrt(nan) = nan
1117pub fn cbrt(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/ceil.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ceil(+-0) = +-0
4// - ceil(+-inf) = +-inf
5// - ceil(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ceil.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
99const math = std.math;
1010const expect = std.testing.expect;
1111
12/// Returns the least integer value greater than of equal to x.
13///
14/// Special Cases:
15/// - ceil(+-0) = +-0
16/// - ceil(+-inf) = +-inf
17/// - ceil(nan) = nan
1218pub fn ceil(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/complex.zig+12
......@@ -23,13 +23,18 @@ pub const sqrt = @import("complex/sqrt.zig").sqrt;
2323pub const tanh = @import("complex/tanh.zig").tanh;
2424pub const tan = @import("complex/tan.zig").tan;
2525
26/// A complex number consisting of a real an imaginary part. T must be a floating-point value.
2627pub fn Complex(comptime T: type) type {
2728 return struct {
2829 const Self = @This();
2930
31 /// Real part.
3032 re: T,
33
34 /// Imaginary part.
3135 im: T,
3236
37 /// Create a new Complex number from the given real and imaginary parts.
3338 pub fn new(re: T, im: T) Self {
3439 return Self{
3540 .re = re,
......@@ -37,6 +42,7 @@ pub fn Complex(comptime T: type) type {
3742 };
3843 }
3944
45 /// Returns the sum of two complex numbers.
4046 pub fn add(self: Self, other: Self) Self {
4147 return Self{
4248 .re = self.re + other.re,
......@@ -44,6 +50,7 @@ pub fn Complex(comptime T: type) type {
4450 };
4551 }
4652
53 /// Returns the subtraction of two complex numbers.
4754 pub fn sub(self: Self, other: Self) Self {
4855 return Self{
4956 .re = self.re - other.re,
......@@ -51,6 +58,7 @@ pub fn Complex(comptime T: type) type {
5158 };
5259 }
5360
61 /// Returns the product of two complex numbers.
5462 pub fn mul(self: Self, other: Self) Self {
5563 return Self{
5664 .re = self.re * other.re - self.im * other.im,
......@@ -58,6 +66,7 @@ pub fn Complex(comptime T: type) type {
5866 };
5967 }
6068
69 /// Returns the quotient of two complex numbers.
6170 pub fn div(self: Self, other: Self) Self {
6271 const re_num = self.re * other.re + self.im * other.im;
6372 const im_num = self.im * other.re - self.re * other.im;
......@@ -69,6 +78,7 @@ pub fn Complex(comptime T: type) type {
6978 };
7079 }
7180
81 /// Returns the complex conjugate of a number.
7282 pub fn conjugate(self: Self) Self {
7383 return Self{
7484 .re = self.re,
......@@ -76,6 +86,7 @@ pub fn Complex(comptime T: type) type {
7686 };
7787 }
7888
89 /// Returns the reciprocal of a complex number.
7990 pub fn reciprocal(self: Self) Self {
8091 const m = self.re * self.re + self.im * self.im;
8192 return Self{
......@@ -84,6 +95,7 @@ pub fn Complex(comptime T: type) type {
8495 };
8596 }
8697
98 /// Returns the magnitude of a complex number.
8799 pub fn magnitude(self: Self) T {
88100 return math.sqrt(self.re * self.re + self.im * self.im);
89101 }
std/math/complex/abs.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the absolute value (modulus) of z.
78pub fn abs(z: var) @typeOf(z.re) {
89 const T = @typeOf(z.re);
910 return math.hypot(T, z.re, z.im);
std/math/complex/acos.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the arc-cosine of z.
78pub fn acos(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = cmath.asin(z);
std/math/complex/acosh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-cosine of z.
78pub fn acosh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = cmath.acos(z);
std/math/complex/arg.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the angular component (in radians) of z.
78pub fn arg(z: var) @typeOf(z.re) {
89 const T = @typeOf(z.re);
910 return math.atan2(T, z.im, z.re);
std/math/complex/asin.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7// Returns the arc-sine of z.
78pub fn asin(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const x = z.re;
std/math/complex/asinh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-sine of z.
78pub fn asinh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/atan.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/catanf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/catan.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the arc-tangent of z.
714pub fn atan(z: var) @typeOf(z) {
815 const T = @typeOf(z.re);
916 return switch (T) {
std/math/complex/atanh.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the hyperbolic arc-tangent of z.
78pub fn atanh(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/conj.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the complex conjugate of z.
78pub fn conj(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 return Complex(T).new(z.re, -z.im);
std/math/complex/cos.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the cosine of z.
78pub fn cos(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const p = Complex(T).new(-z.im, z.re);
std/math/complex/cosh.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/ccoshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/ccosh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns the hyperbolic arc-cosine of z.
916pub fn cosh(z: var) Complex(@typeOf(z.re)) {
1017 const T = @typeOf(z.re);
1118 return switch (T) {
std/math/complex/exp.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/cexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/cexp.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns e raised to the power of z (e^z).
916pub fn exp(z: var) @typeOf(z) {
1017 const T = @typeOf(z.re);
1118
std/math/complex/ldexp.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/__cexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/__cexp.c
6
17const std = @import("../../std.zig");
28const debug = std.debug;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns exp(z) scaled to avoid overflow.
714pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) {
815 const T = @typeOf(z.re);
916
std/math/complex/log.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the natural logarithm of z.
78pub fn log(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const r = cmath.abs(z);
std/math/complex/pow.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns z raised to the complex power of c.
78pub fn pow(comptime T: type, z: T, c: T) T {
89 const p = cmath.log(z);
910 const q = c.mul(p);
std/math/complex/proj.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the projection of z onto the riemann sphere.
78pub fn proj(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910
std/math/complex/sin.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the sine of z.
78pub fn sin(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const p = Complex(T).new(-z.im, z.re);
std/math/complex/sinh.zig+7
......@@ -1,3 +1,9 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/csinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/csinh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
......@@ -6,6 +12,7 @@ const Complex = cmath.Complex;
612
713const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
814
15/// Returns the hyperbolic sine of z.
916pub fn sinh(z: var) @typeOf(z) {
1017 const T = @typeOf(z.re);
1118 return switch (T) {
std/math/complex/sqrt.zig+8
......@@ -1,9 +1,17 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/csqrtf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/csqrt.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the square root of z. The real and imaginary parts of the result have the same sign
14/// as the imaginary part of z.
715pub fn sqrt(z: var) @typeOf(z) {
816 const T = @typeOf(z.re);
917
std/math/complex/tan.zig+1
......@@ -4,6 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7/// Returns the tanget of z.
78pub fn tan(z: var) Complex(@typeOf(z.re)) {
89 const T = @typeOf(z.re);
910 const q = Complex(T).new(-z.im, z.re);
std/math/complex/tanh.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/complex/ctanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/complex/ctanh.c
6
17const std = @import("../../std.zig");
28const testing = std.testing;
39const math = std.math;
410const cmath = math.complex;
511const Complex = cmath.Complex;
612
13/// Returns the hyperbolic tangent of z.
714pub fn tanh(z: var) @typeOf(z) {
815 const T = @typeOf(z.re);
916 return switch (T) {
std/math/copysign.zig+7
......@@ -1,8 +1,15 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/copysignf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/copysign.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const expect = std.testing.expect;
410const maxInt = std.math.maxInt;
511
12/// Returns a value with the magnitude of x and the sign of y.
613pub fn copysign(comptime T: type, x: T, y: T) T {
714 return switch (T) {
815 f16 => copysign16(x, y),
std/math/cos.zig+46-100
......@@ -1,18 +1,23 @@
1// Special Cases:
1// Ported from go, which is licensed under a BSD-3 license.
2// https://golang.org/LICENSE
23//
3// - cos(+-inf) = nan
4// - cos(nan) = nan
4// https://golang.org/src/math/sin.go
55
66const builtin = @import("builtin");
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010
11/// Returns the cosine of the radian value x.
12///
13/// Special Cases:
14/// - cos(+-inf) = nan
15/// - cos(nan) = nan
1116pub fn cos(x: var) @typeOf(x) {
1217 const T = @typeOf(x);
1318 return switch (T) {
14 f32 => cos32(x),
15 f64 => cos64(x),
19 f32 => cos_(f32, x),
20 f64 => cos_(f64, x),
1621 else => @compileError("cos not implemented for " ++ @typeName(T)),
1722 };
1823}
......@@ -33,78 +38,24 @@ const C3 = 2.48015872888517045348E-5;
3338const C4 = -1.38888888888730564116E-3;
3439const C5 = 4.16666666666665929218E-2;
3540
36// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
37//
38// This may have slight differences on some edge cases and may need to replaced if so.
39fn cos32(x_: f32) f32 {
40 const pi4a = 7.85398125648498535156e-1;
41 const pi4b = 3.77489470793079817668E-8;
42 const pi4c = 2.69515142907905952645E-15;
43 const m4pi = 1.273239544735162542821171882678754627704620361328125;
44
45 var x = x_;
46 if (math.isNan(x) or math.isInf(x)) {
47 return math.nan(f32);
48 }
49
50 var sign = false;
51 if (x < 0) {
52 x = -x;
53 }
54
55 var y = math.floor(x * m4pi);
56 var j = @floatToInt(i64, y);
41const pi4a = 7.85398125648498535156e-1;
42const pi4b = 3.77489470793079817668E-8;
43const pi4c = 2.69515142907905952645E-15;
44const m4pi = 1.273239544735162542821171882678754627704620361328125;
5745
58 if (j & 1 == 1) {
59 j += 1;
60 y += 1;
61 }
62
63 j &= 7;
64 if (j > 3) {
65 j -= 4;
66 sign = !sign;
67 }
68 if (j > 1) {
69 sign = !sign;
70 }
71
72 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
73 const w = z * z;
74
75 const r = r: {
76 if (j == 1 or j == 2) {
77 break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
78 } else {
79 break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
80 }
81 };
82
83 if (sign) {
84 return -r;
85 } else {
86 return r;
87 }
88}
89
90fn cos64(x_: f64) f64 {
91 const pi4a = 7.85398125648498535156e-1;
92 const pi4b = 3.77489470793079817668E-8;
93 const pi4c = 2.69515142907905952645E-15;
94 const m4pi = 1.273239544735162542821171882678754627704620361328125;
46fn cos_(comptime T: type, x_: T) T {
47 const I = @IntType(true, T.bit_count);
9548
9649 var x = x_;
9750 if (math.isNan(x) or math.isInf(x)) {
98 return math.nan(f64);
51 return math.nan(T);
9952 }
10053
10154 var sign = false;
102 if (x < 0) {
103 x = -x;
104 }
55 x = math.fabs(x);
10556
10657 var y = math.floor(x * m4pi);
107 var j = @floatToInt(i64, y);
58 var j = @floatToInt(I, y);
10859
10960 if (j & 1 == 1) {
11061 j += 1;
......@@ -123,56 +74,51 @@ fn cos64(x_: f64) f64 {
12374 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
12475 const w = z * z;
12576
126 const r = r: {
127 if (j == 1 or j == 2) {
128 break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
129 } else {
130 break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
131 }
132 };
77 const r = if (j == 1 or j == 2)
78 z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))))
79 else
80 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
13381
134 if (sign) {
135 return -r;
136 } else {
137 return r;
138 }
82 return if (sign) -r else r;
13983}
14084
14185test "math.cos" {
142 expect(cos(f32(0.0)) == cos32(0.0));
143 expect(cos(f64(0.0)) == cos64(0.0));
86 expect(cos(f32(0.0)) == cos_(f32, 0.0));
87 expect(cos(f64(0.0)) == cos_(f64, 0.0));
14488}
14589
14690test "math.cos32" {
14791 const epsilon = 0.000001;
14892
149 expect(math.approxEq(f32, cos32(0.0), 1.0, epsilon));
150 expect(math.approxEq(f32, cos32(0.2), 0.980067, epsilon));
151 expect(math.approxEq(f32, cos32(0.8923), 0.627623, epsilon));
152 expect(math.approxEq(f32, cos32(1.5), 0.070737, epsilon));
153 expect(math.approxEq(f32, cos32(37.45), 0.969132, epsilon));
154 expect(math.approxEq(f32, cos32(89.123), 0.400798, epsilon));
93 expect(math.approxEq(f32, cos_(f32, 0.0), 1.0, epsilon));
94 expect(math.approxEq(f32, cos_(f32, 0.2), 0.980067, epsilon));
95 expect(math.approxEq(f32, cos_(f32, 0.8923), 0.627623, epsilon));
96 expect(math.approxEq(f32, cos_(f32, 1.5), 0.070737, epsilon));
97 expect(math.approxEq(f32, cos_(f32, -1.5), 0.070737, epsilon));
98 expect(math.approxEq(f32, cos_(f32, 37.45), 0.969132, epsilon));
99 expect(math.approxEq(f32, cos_(f32, 89.123), 0.400798, epsilon));
155100}
156101
157102test "math.cos64" {
158103 const epsilon = 0.000001;
159104
160 expect(math.approxEq(f64, cos64(0.0), 1.0, epsilon));
161 expect(math.approxEq(f64, cos64(0.2), 0.980067, epsilon));
162 expect(math.approxEq(f64, cos64(0.8923), 0.627623, epsilon));
163 expect(math.approxEq(f64, cos64(1.5), 0.070737, epsilon));
164 expect(math.approxEq(f64, cos64(37.45), 0.969132, epsilon));
165 expect(math.approxEq(f64, cos64(89.123), 0.40080, epsilon));
105 expect(math.approxEq(f64, cos_(f64, 0.0), 1.0, epsilon));
106 expect(math.approxEq(f64, cos_(f64, 0.2), 0.980067, epsilon));
107 expect(math.approxEq(f64, cos_(f64, 0.8923), 0.627623, epsilon));
108 expect(math.approxEq(f64, cos_(f64, 1.5), 0.070737, epsilon));
109 expect(math.approxEq(f64, cos_(f64, -1.5), 0.070737, epsilon));
110 expect(math.approxEq(f64, cos_(f64, 37.45), 0.969132, epsilon));
111 expect(math.approxEq(f64, cos_(f64, 89.123), 0.40080, epsilon));
166112}
167113
168114test "math.cos32.special" {
169 expect(math.isNan(cos32(math.inf(f32))));
170 expect(math.isNan(cos32(-math.inf(f32))));
171 expect(math.isNan(cos32(math.nan(f32))));
115 expect(math.isNan(cos_(f32, math.inf(f32))));
116 expect(math.isNan(cos_(f32, -math.inf(f32))));
117 expect(math.isNan(cos_(f32, math.nan(f32))));
172118}
173119
174120test "math.cos64.special" {
175 expect(math.isNan(cos64(math.inf(f64))));
176 expect(math.isNan(cos64(-math.inf(f64))));
177 expect(math.isNan(cos64(math.nan(f64))));
121 expect(math.isNan(cos_(f64, math.inf(f64))));
122 expect(math.isNan(cos_(f64, -math.inf(f64))));
123 expect(math.isNan(cos_(f64, math.nan(f64))));
178124}
std/math/cosh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - cosh(+-0) = 1
4// - cosh(+-inf) = +inf
5// - cosh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/coshf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/cosh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expo2 = @import("expo2.zig").expo2;
1111const expect = std.testing.expect;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic cosine of x.
15///
16/// Special Cases:
17/// - cosh(+-0) = 1
18/// - cosh(+-inf) = +inf
19/// - cosh(nan) = nan
1420pub fn cosh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/exp.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - exp(+inf) = +inf
4// - exp(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/expf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const assert = std.debug.assert;
910const builtin = @import("builtin");
1011
12/// Returns e raised to the power of x (e^x).
13///
14/// Special Cases:
15/// - exp(+inf) = +inf
16/// - exp(nan) = nan
1117pub fn exp(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/exp2.zig+9-3
......@@ -1,12 +1,18 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - exp2(+inf) = +inf
4// - exp2(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910
11/// Returns 2 raised to the power of x (2^x).
12///
13/// Special Cases:
14/// - exp2(+inf) = +inf
15/// - exp2(nan) = nan
1016pub fn exp2(x: var) @typeOf(x) {
1117 const T = @typeOf(x);
1218 return switch (T) {
std/math/expm1.zig+13-4
......@@ -1,14 +1,23 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - expm1(+inf) = +inf
4// - expm1(-inf) = -1
5// - expm1(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/expmf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/expm.c
6
7// TODO: Updated recently.
68
79const builtin = @import("builtin");
810const std = @import("../std.zig");
911const math = std.math;
1012const expect = std.testing.expect;
1113
14/// Returns e raised to the power of x, minus 1 (e^x - 1). This is more accurate than exp(e, x) - 1
15/// when x is near 0.
16///
17/// Special Cases:
18/// - expm1(+inf) = +inf
19/// - expm1(-inf) = -1
20/// - expm1(nan) = nan
1221pub fn expm1(x: var) @typeOf(x) {
1322 const T = @typeOf(x);
1423 return switch (T) {
std/math/expo2.zig+7
......@@ -1,5 +1,12 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/__expo2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/__expo2.c
6
17const math = @import("../math.zig");
28
9/// Returns exp(x) / 2 for x >= log(maxFloat(T)).
310pub fn expo2(x: var) @typeOf(x) {
411 const T = @typeOf(x);
512 return switch (T) {
std/math/fabs.zig+9-3
......@@ -1,13 +1,19 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - fabs(+-inf) = +inf
4// - fabs(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/fabsf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/fabs.c
56
67const std = @import("../std.zig");
78const math = std.math;
89const expect = std.testing.expect;
910const maxInt = std.math.maxInt;
1011
12/// Returns the absolute value of x.
13///
14/// Special Cases:
15/// - fabs(+-inf) = +inf
16/// - fabs(nan) = nan
1117pub fn fabs(x: var) @typeOf(x) {
1218 const T = @typeOf(x);
1319 return switch (T) {
std/math/floor.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - floor(+-0) = +-0
4// - floor(+-inf) = +-inf
5// - floor(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/floorf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/floor.c
66
77const builtin = @import("builtin");
88const expect = std.testing.expect;
99const std = @import("../std.zig");
1010const math = std.math;
1111
12/// Returns the greatest integer value less than or equal to x.
13///
14/// Special Cases:
15/// - floor(+-0) = +-0
16/// - floor(+-inf) = +-inf
17/// - floor(nan) = nan
1218pub fn floor(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/fma.zig+9-1
......@@ -1,7 +1,14 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/fmaf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/fma.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const expect = std.testing.expect;
410
11/// Returns x * y + z with a single rounding error.
512pub fn fma(comptime T: type, x: T, y: T, z: T) T {
613 return switch (T) {
714 f32 => fma32(x, y, z),
......@@ -16,7 +23,7 @@ fn fma32(x: f32, y: f32, z: f32) f32 {
1623 const u = @bitCast(u64, xy_z);
1724 const e = (u >> 52) & 0x7FF;
1825
19 if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) {
26 if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or (xy_z - xy == z and xy_z - z == xy)) {
2027 return @floatCast(f32, xy_z);
2128 } else {
2229 // TODO: Handle inexact case with double-rounding
......@@ -24,6 +31,7 @@ fn fma32(x: f32, y: f32, z: f32) f32 {
2431 }
2532}
2633
34// NOTE: Upstream fma.c has been rewritten completely to raise fp exceptions more accurately.
2735fn fma64(x: f64, y: f64, z: f64) f64 {
2836 if (!math.isFinite(x) or !math.isFinite(y)) {
2937 return x * y + z;
std/math/frexp.zig+11-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - frexp(+-0) = +-0, 0
4// - frexp(+-inf) = +-inf, 0
5// - frexp(nan) = nan, undefined
4// https://git.musl-libc.org/cgit/musl/tree/src/math/frexpf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/frexp.c
66
77const std = @import("../std.zig");
88const math = std.math;
......@@ -17,6 +17,13 @@ fn frexp_result(comptime T: type) type {
1717pub const frexp32_result = frexp_result(f32);
1818pub const frexp64_result = frexp_result(f64);
1919
20/// Breaks x into a normalized fraction and an integral power of two.
21/// f == frac * 2^exp, with |frac| in the interval [0.5, 1).
22///
23/// Special Cases:
24/// - frexp(+-0) = +-0, 0
25/// - frexp(+-inf) = +-inf, 0
26/// - frexp(nan) = nan, undefined
2027pub fn frexp(x: var) frexp_result(@typeOf(x)) {
2128 const T = @typeOf(x);
2229 return switch (T) {
std/math/hypot.zig+11-5
......@@ -1,15 +1,21 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - hypot(+-inf, y) = +inf
4// - hypot(x, +-inf) = +inf
5// - hypot(nan, y) = nan
6// - hypot(x, nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/hypotf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/hypot.c
76
87const std = @import("../std.zig");
98const math = std.math;
109const expect = std.testing.expect;
1110const maxInt = std.math.maxInt;
1211
12/// Returns sqrt(x * x + y * y), avoiding unncessary overflow and underflow.
13///
14/// Special Cases:
15/// - hypot(+-inf, y) = +inf
16/// - hypot(x, +-inf) = +inf
17/// - hypot(nan, y) = nan
18/// - hypot(x, nan) = nan
1319pub fn hypot(comptime T: type, x: T, y: T) T {
1420 return switch (T) {
1521 f32 => hypot32(x, y),
std/math/ilogb.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ilogb(+-inf) = maxInt(i32)
4// - ilogb(0) = maxInt(i32)
5// - ilogb(nan) = maxInt(i32)
4// https://git.musl-libc.org/cgit/musl/tree/src/math/ilogbf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ilogb.c
66
77const std = @import("../std.zig");
88const math = std.math;
......@@ -10,6 +10,12 @@ const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111const minInt = std.math.minInt;
1212
13/// Returns the binary exponent of x as an integer.
14///
15/// Special Cases:
16/// - ilogb(+-inf) = maxInt(i32)
17/// - ilogb(0) = maxInt(i32)
18/// - ilogb(nan) = maxInt(i32)
1319pub fn ilogb(x: var) i32 {
1420 const T = @typeOf(x);
1521 return switch (T) {
std/math/inf.zig+1
......@@ -1,6 +1,7 @@
11const std = @import("../std.zig");
22const math = std.math;
33
4/// Returns value inf for the type T.
45pub fn inf(comptime T: type) T {
56 return switch (T) {
67 f16 => math.inf_f16,
std/math/isfinite.zig+1
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is a finite value.
67pub fn isFinite(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
std/math/isinf.zig+3
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is an infinity, ignoring sign.
67pub fn isInf(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
......@@ -28,6 +29,7 @@ pub fn isInf(x: var) bool {
2829 }
2930}
3031
32/// Returns whether x is an infinity with a positive sign.
3133pub fn isPositiveInf(x: var) bool {
3234 const T = @typeOf(x);
3335 switch (T) {
......@@ -49,6 +51,7 @@ pub fn isPositiveInf(x: var) bool {
4951 }
5052}
5153
54/// Returns whether x is an infinity with a negative sign.
5255pub fn isNegativeInf(x: var) bool {
5356 const T = @typeOf(x);
5457 switch (T) {
std/math/isnan.zig+4-2
......@@ -3,13 +3,15 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6/// Returns whether x is a nan.
67pub fn isNan(x: var) bool {
78 return x != x;
89}
910
10/// Note: A signalling nan is identical to a standard nan right now but may have a different bit
11/// representation in the future when required.
11/// Returns whether x is a signalling nan.
1212pub fn isSignalNan(x: var) bool {
13 // Note: A signalling nan is identical to a standard nan right now but may have a different bit
14 // representation in the future when required.
1315 return isNan(x);
1416}
1517
std/math/isnormal.zig+1
......@@ -3,6 +3,7 @@ const math = std.math;
33const expect = std.testing.expect;
44const maxInt = std.math.maxInt;
55
6// Returns whether x has a normalized representation (i.e. integer part of mantissa is 1).
67pub fn isNormal(x: var) bool {
78 const T = @typeOf(x);
89 switch (T) {
std/math/ln.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - ln(+inf) = +inf
4// - ln(0) = -inf
5// - ln(x) = nan if x < 0
6// - ln(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/lnf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/ln.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -11,6 +10,13 @@ const expect = std.testing.expect;
1110const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312
13/// Returns the natural logarithm of x.
14///
15/// Special Cases:
16/// - ln(+inf) = +inf
17/// - ln(0) = -inf
18/// - ln(x) = nan if x < 0
19/// - ln(nan) = nan
1420pub fn ln(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 switch (@typeId(T)) {
std/math/log.zig+7
......@@ -1,9 +1,16 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/logf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const builtin = @import("builtin");
410const TypeId = builtin.TypeId;
511const expect = std.testing.expect;
612
13/// Returns the logarithm of x for the provided base.
714pub fn log(comptime T: type, base: T, x: T) T {
815 if (base == 2) {
916 return math.log2(x);
std/math/log10.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log10(+inf) = +inf
4// - log10(0) = -inf
5// - log10(x) = nan if x < 0
6// - log10(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log10f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log10.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -12,6 +11,13 @@ const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312const maxInt = std.math.maxInt;
1413
14/// Returns the base-10 logarithm of x.
15///
16/// Special Cases:
17/// - log10(+inf) = +inf
18/// - log10(0) = -inf
19/// - log10(x) = nan if x < 0
20/// - log10(nan) = nan
1521pub fn log10(x: var) @typeOf(x) {
1622 const T = @typeOf(x);
1723 switch (@typeId(T)) {
std/math/log1p.zig+12-6
......@@ -1,16 +1,22 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log1p(+inf) = +inf
4// - log1p(+-0) = +-0
5// - log1p(-1) = -inf
6// - log1p(x) = nan if x < -1
7// - log1p(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log1pf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log1p.c
86
97const builtin = @import("builtin");
108const std = @import("../std.zig");
119const math = std.math;
1210const expect = std.testing.expect;
1311
12/// Returns the natural logarithm of 1 + x with greater accuracy when x is near zero.
13///
14/// Special Cases:
15/// - log1p(+inf) = +inf
16/// - log1p(+-0) = +-0
17/// - log1p(-1) = -inf
18/// - log1p(x) = nan if x < -1
19/// - log1p(nan) = nan
1420pub fn log1p(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/log2.zig+11-5
......@@ -1,9 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - log2(+inf) = +inf
4// - log2(0) = -inf
5// - log2(x) = nan if x < 0
6// - log2(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/log2f.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c
76
87const std = @import("../std.zig");
98const math = std.math;
......@@ -12,6 +11,13 @@ const builtin = @import("builtin");
1211const TypeId = builtin.TypeId;
1312const maxInt = std.math.maxInt;
1413
14/// Returns the base-2 logarithm of x.
15///
16/// Special Cases:
17/// - log2(+inf) = +inf
18/// - log2(0) = -inf
19/// - log2(x) = nan if x < 0
20/// - log2(nan) = nan
1521pub fn log2(x: var) @typeOf(x) {
1622 const T = @typeOf(x);
1723 switch (@typeId(T)) {
std/math/modf.zig+10-3
......@@ -1,7 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - modf(+-inf) = +-inf, nan
4// - modf(nan) = nan, nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/modff.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/modf.c
56
67const std = @import("../std.zig");
78const math = std.math;
......@@ -17,6 +18,12 @@ fn modf_result(comptime T: type) type {
1718pub const modf32_result = modf_result(f32);
1819pub const modf64_result = modf_result(f64);
1920
21/// Returns the integer and fractional floating-point numbers that sum to x. The sign of each
22/// result is the same as the sign of x.
23///
24/// Special Cases:
25/// - modf(+-inf) = +-inf, nan
26/// - modf(nan) = nan, nan
2027pub fn modf(x: var) modf_result(@typeOf(x)) {
2128 const T = @typeOf(x);
2229 return switch (T) {
std/math/nan.zig+4-2
......@@ -1,5 +1,6 @@
11const math = @import("../math.zig");
22
3/// Returns the nan representation for type T.
34pub fn nan(comptime T: type) T {
45 return switch (T) {
56 f16 => math.nan_f16,
......@@ -10,9 +11,10 @@ pub fn nan(comptime T: type) T {
1011 };
1112}
1213
13// Note: A signalling nan is identical to a standard right now by may have a different bit
14// representation in the future when required.
14/// Returns the signalling nan representation for type T.
1515pub fn snan(comptime T: type) T {
16 // Note: A signalling nan is identical to a standard right now by may have a different bit
17 // representation in the future when required.
1618 return switch (T) {
1719 f16 => @bitCast(f16, math.nan_u16),
1820 f32 => @bitCast(f32, math.nan_u32),
std/math/pow.zig+57-39
......@@ -1,32 +1,36 @@
1// Special Cases:
1// Ported from go, which is licensed under a BSD-3 license.
2// https://golang.org/LICENSE
23//
3// pow(x, +-0) = 1 for any x
4// pow(1, y) = 1 for any y
5// pow(x, 1) = x for any x
6// pow(nan, y) = nan
7// pow(x, nan) = nan
8// pow(+-0, y) = +-inf for y an odd integer < 0
9// pow(+-0, -inf) = +inf
10// pow(+-0, +inf) = +0
11// pow(+-0, y) = +inf for finite y < 0 and not an odd integer
12// pow(+-0, y) = +-0 for y an odd integer > 0
13// pow(+-0, y) = +0 for finite y > 0 and not an odd integer
14// pow(-1, +-inf) = 1
15// pow(x, +inf) = +inf for |x| > 1
16// pow(x, -inf) = +0 for |x| > 1
17// pow(x, +inf) = +0 for |x| < 1
18// pow(x, -inf) = +inf for |x| < 1
19// pow(+inf, y) = +inf for y > 0
20// pow(+inf, y) = +0 for y < 0
21// pow(-inf, y) = pow(-0, -y)
22// pow(x, y) = nan for finite x < 0 and finite non-integer y
4// https://golang.org/src/math/pow.go
235
246const builtin = @import("builtin");
257const std = @import("../std.zig");
268const math = std.math;
279const expect = std.testing.expect;
2810
29// This implementation is taken from the go stlib, musl is a bit more complex.
11/// Returns x raised to the power of y (x^y).
12///
13/// Special Cases:
14/// - pow(x, +-0) = 1 for any x
15/// - pow(1, y) = 1 for any y
16/// - pow(x, 1) = x for any x
17/// - pow(nan, y) = nan
18/// - pow(x, nan) = nan
19/// - pow(+-0, y) = +-inf for y an odd integer < 0
20/// - pow(+-0, -inf) = +inf
21/// - pow(+-0, +inf) = +0
22/// - pow(+-0, y) = +inf for finite y < 0 and not an odd integer
23/// - pow(+-0, y) = +-0 for y an odd integer > 0
24/// - pow(+-0, y) = +0 for finite y > 0 and not an odd integer
25/// - pow(-1, +-inf) = 1
26/// - pow(x, +inf) = +inf for |x| > 1
27/// - pow(x, -inf) = +0 for |x| > 1
28/// - pow(x, +inf) = +0 for |x| < 1
29/// - pow(x, -inf) = +inf for |x| < 1
30/// - pow(+inf, y) = +inf for y > 0
31/// - pow(+inf, y) = +0 for y < 0
32/// - pow(-inf, y) = pow(-0, -y)
33/// - pow(x, y) = nan for finite x < 0 and finite non-integer y
3034pub fn pow(comptime T: type, x: T, y: T) T {
3135 if (@typeInfo(T) == builtin.TypeId.Int) {
3236 return math.powi(T, x, y) catch unreachable;
......@@ -53,15 +57,6 @@ pub fn pow(comptime T: type, x: T, y: T) T {
5357 return x;
5458 }
5559
56 // special case sqrt
57 if (y == 0.5) {
58 return math.sqrt(x);
59 }
60
61 if (y == -0.5) {
62 return 1 / math.sqrt(x);
63 }
64
6560 if (x == 0) {
6661 if (y < 0) {
6762 // pow(+-0, y) = +- 0 for y an odd integer
......@@ -112,14 +107,16 @@ pub fn pow(comptime T: type, x: T, y: T) T {
112107 }
113108 }
114109
115 var ay = y;
116 var flip = false;
117 if (ay < 0) {
118 ay = -ay;
119 flip = true;
110 // special case sqrt
111 if (y == 0.5) {
112 return math.sqrt(x);
113 }
114
115 if (y == -0.5) {
116 return 1 / math.sqrt(x);
120117 }
121118
122 const r1 = math.modf(ay);
119 const r1 = math.modf(math.fabs(y));
123120 var yi = r1.ipart;
124121 var yf = r1.fpart;
125122
......@@ -148,8 +145,18 @@ pub fn pow(comptime T: type, x: T, y: T) T {
148145 var xe = r2.exponent;
149146 var x1 = r2.significand;
150147
151 var i = @floatToInt(i32, yi);
148 var i = @floatToInt(@IntType(true, T.bit_count), yi);
152149 while (i != 0) : (i >>= 1) {
150 const overflow_shift = math.floatExponentBits(T) + 1;
151 if (xe < -(1 << overflow_shift) or (1 << overflow_shift) < xe) {
152 // catch xe before it overflows the left shift below
153 // Since i != 0 it has at least one bit still set, so ae will accumulate xe
154 // on at least one more iteration, ae += xe is a lower bound on ae
155 // the lower bound on ae exceeds the size of a float exp
156 // so the final call to Ldexp will produce under/overflow (0/Inf)
157 ae += xe;
158 break;
159 }
153160 if (i & 1 == 1) {
154161 a1 *= x1;
155162 ae += xe;
......@@ -163,7 +170,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
163170 }
164171
165172 // a *= a1 * 2^ae
166 if (flip) {
173 if (y < 0) {
167174 a1 = 1 / a1;
168175 ae = -ae;
169176 }
......@@ -202,6 +209,9 @@ test "math.pow.special" {
202209 expect(pow(f32, 45, 1.0) == 45);
203210 expect(pow(f32, -45, 1.0) == -45);
204211 expect(math.isNan(pow(f32, math.nan(f32), 5.0)));
212 expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5)));
213 expect(math.isPositiveInf(pow(f32, -0, -0.5)));
214 expect(pow(f32, -0, 0.5) == 0);
205215 expect(math.isNan(pow(f32, 5.0, math.nan(f32))));
206216 expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));
207217 //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?
......@@ -232,3 +242,11 @@ test "math.pow.special" {
232242 expect(math.isNan(pow(f32, -1.0, 1.2)));
233243 expect(math.isNan(pow(f32, -12.4, 78.5)));
234244}
245
246test "math.pow.overflow" {
247 expect(math.isPositiveInf(pow(f64, 2, 1 << 32)));
248 expect(pow(f64, 2, -(1 << 32)) == 0);
249 expect(math.isNegativeInf(pow(f64, -2, (1 << 32) + 1)));
250 expect(pow(f64, 0.5, 1 << 45) == 0);
251 expect(math.isPositiveInf(pow(f64, 0.5, -(1 << 45))));
252}
std/math/powi.zig+13-9
......@@ -1,12 +1,7 @@
1// Special Cases:
1// Based on Rust, which is licensed under the MIT license.
2// https://github.com/rust-lang/rust/blob/360432f1e8794de58cd94f34c9c17ad65871e5b5/LICENSE-MIT
23//
3// powi(x, +-0) = 1 for any x
4// powi(0, y) = 0 for any y
5// powi(1, y) = 1 for any y
6// powi(-1, y) = -1 for for y an odd integer
7// powi(-1, y) = 1 for for y an even integer
8// powi(x, y) = Overflow for for y >= @sizeOf(x) - 1 y > 0
9// powi(x, y) = Underflow for for y > @sizeOf(x) - 1 y < 0
4// https://github.com/rust-lang/rust/blob/360432f1e8794de58cd94f34c9c17ad65871e5b5/src/libcore/num/mod.rs#L3423
105
116const builtin = @import("builtin");
127const std = @import("../std.zig");
......@@ -14,7 +9,16 @@ const math = std.math;
149const assert = std.debug.assert;
1510const testing = std.testing;
1611
17// This implementation is based on that from the rust stlib
12/// Returns the power of x raised by the integer y (x^y).
13///
14/// Special Cases:
15/// - powi(x, +-0) = 1 for any x
16/// - powi(0, y) = 0 for any y
17/// - powi(1, y) = 1 for any y
18/// - powi(-1, y) = -1 for y an odd integer
19/// - powi(-1, y) = 1 for y an even integer
20/// - powi(x, y) = Overflow for y >= @sizeOf(x) - 1 or y > 0
21/// - powi(x, y) = Underflow for y > @sizeOf(x) - 1 or y < 0
1822pub fn powi(comptime T: type, x: T, y: T) (error{
1923 Overflow,
2024 Underflow,
std/math/round.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - round(+-0) = +-0
4// - round(+-inf) = +-inf
5// - round(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/roundf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/round.c
66
77const builtin = @import("builtin");
88const expect = std.testing.expect;
99const std = @import("../std.zig");
1010const math = std.math;
1111
12/// Returns x rounded to the nearest integer, rounding half away from zero.
13///
14/// Special Cases:
15/// - round(+-0) = +-0
16/// - round(+-inf) = +-inf
17/// - round(nan) = nan
1218pub fn round(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/math/scalbn.zig+7
......@@ -1,7 +1,14 @@
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
3//
4// https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c
6
17const std = @import("../std.zig");
28const math = std.math;
39const expect = std.testing.expect;
410
11/// Returns x * 2^n.
512pub fn scalbn(x: var, n: i32) @typeOf(x) {
613 const T = @typeOf(x);
714 return switch (T) {
std/math/signbit.zig+1
......@@ -2,6 +2,7 @@ const std = @import("../std.zig");
22const math = std.math;
33const expect = std.testing.expect;
44
5/// Returns whether x is negative or negative 0.
56pub fn signbit(x: var) bool {
67 const T = @typeOf(x);
78 return switch (T) {
std/math/sin.zig+52-108
......@@ -1,19 +1,24 @@
1// Special Cases:
1// Ported from go, which is licensed under a BSD-3 license.
2// https://golang.org/LICENSE
23//
3// - sin(+-0) = +-0
4// - sin(+-inf) = nan
5// - sin(nan) = nan
4// https://golang.org/src/math/sin.go
65
76const builtin = @import("builtin");
87const std = @import("../std.zig");
98const math = std.math;
109const expect = std.testing.expect;
1110
11/// Returns the sine of the radian value x.
12///
13/// Special Cases:
14/// - sin(+-0) = +-0
15/// - sin(+-inf) = nan
16/// - sin(nan) = nan
1217pub fn sin(x: var) @typeOf(x) {
1318 const T = @typeOf(x);
1419 return switch (T) {
15 f32 => sin32(x),
16 f64 => sin64(x),
20 f32 => sin_(T, x),
21 f64 => sin_(T, x),
1722 else => @compileError("sin not implemented for " ++ @typeName(T)),
1823 };
1924}
......@@ -34,83 +39,27 @@ const C3 = 2.48015872888517045348E-5;
3439const C4 = -1.38888888888730564116E-3;
3540const C5 = 4.16666666666665929218E-2;
3641
37// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
38//
39// This may have slight differences on some edge cases and may need to replaced if so.
40fn sin32(x_: f32) f32 {
41 const pi4a = 7.85398125648498535156e-1;
42 const pi4b = 3.77489470793079817668E-8;
43 const pi4c = 2.69515142907905952645E-15;
44 const m4pi = 1.273239544735162542821171882678754627704620361328125;
45
46 var x = x_;
47 if (x == 0 or math.isNan(x)) {
48 return x;
49 }
50 if (math.isInf(x)) {
51 return math.nan(f32);
52 }
53
54 var sign = false;
55 if (x < 0) {
56 x = -x;
57 sign = true;
58 }
59
60 var y = math.floor(x * m4pi);
61 var j = @floatToInt(i64, y);
62
63 if (j & 1 == 1) {
64 j += 1;
65 y += 1;
66 }
42const pi4a = 7.85398125648498535156e-1;
43const pi4b = 3.77489470793079817668E-8;
44const pi4c = 2.69515142907905952645E-15;
45const m4pi = 1.273239544735162542821171882678754627704620361328125;
6746
68 j &= 7;
69 if (j > 3) {
70 j -= 4;
71 sign = !sign;
72 }
73
74 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
75 const w = z * z;
76
77 const r = r: {
78 if (j == 1 or j == 2) {
79 break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
80 } else {
81 break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
82 }
83 };
84
85 if (sign) {
86 return -r;
87 } else {
88 return r;
89 }
90}
91
92fn sin64(x_: f64) f64 {
93 const pi4a = 7.85398125648498535156e-1;
94 const pi4b = 3.77489470793079817668E-8;
95 const pi4c = 2.69515142907905952645E-15;
96 const m4pi = 1.273239544735162542821171882678754627704620361328125;
47fn sin_(comptime T: type, x_: T) T {
48 const I = @IntType(true, T.bit_count);
9749
9850 var x = x_;
9951 if (x == 0 or math.isNan(x)) {
10052 return x;
10153 }
10254 if (math.isInf(x)) {
103 return math.nan(f64);
55 return math.nan(T);
10456 }
10557
106 var sign = false;
107 if (x < 0) {
108 x = -x;
109 sign = true;
110 }
58 var sign = x < 0;
59 x = math.fabs(x);
11160
11261 var y = math.floor(x * m4pi);
113 var j = @floatToInt(i64, y);
62 var j = @floatToInt(I, y);
11463
11564 if (j & 1 == 1) {
11665 j += 1;
......@@ -126,61 +75,56 @@ fn sin64(x_: f64) f64 {
12675 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
12776 const w = z * z;
12877
129 const r = r: {
130 if (j == 1 or j == 2) {
131 break :r 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))));
132 } else {
133 break :r z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
134 }
135 };
78 const r = if (j == 1 or j == 2)
79 1.0 - 0.5 * w + w * w * (C5 + w * (C4 + w * (C3 + w * (C2 + w * (C1 + w * C0)))))
80 else
81 z + z * w * (S5 + w * (S4 + w * (S3 + w * (S2 + w * (S1 + w * S0)))));
13682
137 if (sign) {
138 return -r;
139 } else {
140 return r;
141 }
83 return if (sign) -r else r;
14284}
14385
14486test "math.sin" {
145 expect(sin(f32(0.0)) == sin32(0.0));
146 expect(sin(f64(0.0)) == sin64(0.0));
87 expect(sin(f32(0.0)) == sin_(f32, 0.0));
88 expect(sin(f64(0.0)) == sin_(f64, 0.0));
14789 expect(comptime (math.sin(f64(2))) == math.sin(f64(2)));
14890}
14991
15092test "math.sin32" {
15193 const epsilon = 0.000001;
15294
153 expect(math.approxEq(f32, sin32(0.0), 0.0, epsilon));
154 expect(math.approxEq(f32, sin32(0.2), 0.198669, epsilon));
155 expect(math.approxEq(f32, sin32(0.8923), 0.778517, epsilon));
156 expect(math.approxEq(f32, sin32(1.5), 0.997495, epsilon));
157 expect(math.approxEq(f32, sin32(37.45), -0.246544, epsilon));
158 expect(math.approxEq(f32, sin32(89.123), 0.916166, epsilon));
95 expect(math.approxEq(f32, sin_(f32, 0.0), 0.0, epsilon));
96 expect(math.approxEq(f32, sin_(f32, 0.2), 0.198669, epsilon));
97 expect(math.approxEq(f32, sin_(f32, 0.8923), 0.778517, epsilon));
98 expect(math.approxEq(f32, sin_(f32, 1.5), 0.997495, epsilon));
99 expect(math.approxEq(f32, sin_(f32, -1.5), -0.997495, epsilon));
100 expect(math.approxEq(f32, sin_(f32, 37.45), -0.246544, epsilon));
101 expect(math.approxEq(f32, sin_(f32, 89.123), 0.916166, epsilon));
159102}
160103
161104test "math.sin64" {
162105 const epsilon = 0.000001;
163106
164 expect(math.approxEq(f64, sin64(0.0), 0.0, epsilon));
165 expect(math.approxEq(f64, sin64(0.2), 0.198669, epsilon));
166 expect(math.approxEq(f64, sin64(0.8923), 0.778517, epsilon));
167 expect(math.approxEq(f64, sin64(1.5), 0.997495, epsilon));
168 expect(math.approxEq(f64, sin64(37.45), -0.246543, epsilon));
169 expect(math.approxEq(f64, sin64(89.123), 0.916166, epsilon));
107 expect(math.approxEq(f64, sin_(f64, 0.0), 0.0, epsilon));
108 expect(math.approxEq(f64, sin_(f64, 0.2), 0.198669, epsilon));
109 expect(math.approxEq(f64, sin_(f64, 0.8923), 0.778517, epsilon));
110 expect(math.approxEq(f64, sin_(f64, 1.5), 0.997495, epsilon));
111 expect(math.approxEq(f64, sin_(f64, -1.5), -0.997495, epsilon));
112 expect(math.approxEq(f64, sin_(f64, 37.45), -0.246543, epsilon));
113 expect(math.approxEq(f64, sin_(f64, 89.123), 0.916166, epsilon));
170114}
171115
172116test "math.sin32.special" {
173 expect(sin32(0.0) == 0.0);
174 expect(sin32(-0.0) == -0.0);
175 expect(math.isNan(sin32(math.inf(f32))));
176 expect(math.isNan(sin32(-math.inf(f32))));
177 expect(math.isNan(sin32(math.nan(f32))));
117 expect(sin_(f32, 0.0) == 0.0);
118 expect(sin_(f32, -0.0) == -0.0);
119 expect(math.isNan(sin_(f32, math.inf(f32))));
120 expect(math.isNan(sin_(f32, -math.inf(f32))));
121 expect(math.isNan(sin_(f32, math.nan(f32))));
178122}
179123
180124test "math.sin64.special" {
181 expect(sin64(0.0) == 0.0);
182 expect(sin64(-0.0) == -0.0);
183 expect(math.isNan(sin64(math.inf(f64))));
184 expect(math.isNan(sin64(-math.inf(f64))));
185 expect(math.isNan(sin64(math.nan(f64))));
125 expect(sin_(f64, 0.0) == 0.0);
126 expect(sin_(f64, -0.0) == -0.0);
127 expect(math.isNan(sin_(f64, math.inf(f64))));
128 expect(math.isNan(sin_(f64, -math.inf(f64))));
129 expect(math.isNan(sin_(f64, math.nan(f64))));
186130}
std/math/sinh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - sinh(+-0) = +-0
4// - sinh(+-inf) = +-inf
5// - sinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/sinhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/sinh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expect = std.testing.expect;
1111const expo2 = @import("expo2.zig").expo2;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic sine of x.
15///
16/// Special Cases:
17/// - sinh(+-0) = +-0
18/// - sinh(+-inf) = +-inf
19/// - sinh(nan) = nan
1420pub fn sinh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/sqrt.zig+7-7
......@@ -1,10 +1,3 @@
1// Special Cases:
2//
3// - sqrt(+inf) = +inf
4// - sqrt(+-0) = +-0
5// - sqrt(x) = nan if x < 0
6// - sqrt(nan) = nan
7
81const std = @import("../std.zig");
92const math = std.math;
103const expect = std.testing.expect;
......@@ -12,6 +5,13 @@ const builtin = @import("builtin");
125const TypeId = builtin.TypeId;
136const maxInt = std.math.maxInt;
147
8/// Returns the square root of x.
9///
10/// Special Cases:
11/// - sqrt(+inf) = +inf
12/// - sqrt(+-0) = +-0
13/// - sqrt(x) = nan if x < 0
14/// - sqrt(nan) = nan
1515pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
1616 const T = @typeOf(x);
1717 switch (@typeId(T)) {
std/math/tan.zig+50-104
......@@ -1,19 +1,24 @@
1// Special Cases:
1// Ported from go, which is licensed under a BSD-3 license.
2// https://golang.org/LICENSE
23//
3// - tan(+-0) = +-0
4// - tan(+-inf) = nan
5// - tan(nan) = nan
4// https://golang.org/src/math/tan.go
65
76const builtin = @import("builtin");
87const std = @import("../std.zig");
98const math = std.math;
109const expect = std.testing.expect;
1110
11/// Returns the tangent of the radian value x.
12///
13/// Special Cases:
14/// - tan(+-0) = +-0
15/// - tan(+-inf) = nan
16/// - tan(nan) = nan
1217pub fn tan(x: var) @typeOf(x) {
1318 const T = @typeOf(x);
1419 return switch (T) {
15 f32 => tan32(x),
16 f64 => tan64(x),
20 f32 => tan_(f32, x),
21 f64 => tan_(f64, x),
1722 else => @compileError("tan not implemented for " ++ @typeName(T)),
1823 };
1924}
......@@ -27,80 +32,27 @@ const Tq2 = -1.32089234440210967447E6;
2732const Tq3 = 2.50083801823357915839E7;
2833const Tq4 = -5.38695755929454629881E7;
2934
30// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
31//
32// This may have slight differences on some edge cases and may need to replaced if so.
33fn tan32(x_: f32) f32 {
34 const pi4a = 7.85398125648498535156e-1;
35 const pi4b = 3.77489470793079817668E-8;
36 const pi4c = 2.69515142907905952645E-15;
37 const m4pi = 1.273239544735162542821171882678754627704620361328125;
38
39 var x = x_;
40 if (x == 0 or math.isNan(x)) {
41 return x;
42 }
43 if (math.isInf(x)) {
44 return math.nan(f32);
45 }
46
47 var sign = false;
48 if (x < 0) {
49 x = -x;
50 sign = true;
51 }
52
53 var y = math.floor(x * m4pi);
54 var j = @floatToInt(i64, y);
55
56 if (j & 1 == 1) {
57 j += 1;
58 y += 1;
59 }
60
61 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
62 const w = z * z;
63
64 var r = r: {
65 if (w > 1e-14) {
66 break :r z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4));
67 } else {
68 break :r z;
69 }
70 };
71
72 if (j & 2 == 2) {
73 r = -1 / r;
74 }
75 if (sign) {
76 r = -r;
77 }
78
79 return r;
80}
35const pi4a = 7.85398125648498535156e-1;
36const pi4b = 3.77489470793079817668E-8;
37const pi4c = 2.69515142907905952645E-15;
38const m4pi = 1.273239544735162542821171882678754627704620361328125;
8139
82fn tan64(x_: f64) f64 {
83 const pi4a = 7.85398125648498535156e-1;
84 const pi4b = 3.77489470793079817668E-8;
85 const pi4c = 2.69515142907905952645E-15;
86 const m4pi = 1.273239544735162542821171882678754627704620361328125;
40fn tan_(comptime T: type, x_: T) T {
41 const I = @IntType(true, T.bit_count);
8742
8843 var x = x_;
8944 if (x == 0 or math.isNan(x)) {
9045 return x;
9146 }
9247 if (math.isInf(x)) {
93 return math.nan(f64);
48 return math.nan(T);
9449 }
9550
96 var sign = false;
97 if (x < 0) {
98 x = -x;
99 sign = true;
100 }
51 var sign = x < 0;
52 x = math.fabs(x);
10153
10254 var y = math.floor(x * m4pi);
103 var j = @floatToInt(i64, y);
55 var j = @floatToInt(I, y);
10456
10557 if (j & 1 == 1) {
10658 j += 1;
......@@ -110,63 +62,57 @@ fn tan64(x_: f64) f64 {
11062 const z = ((x - y * pi4a) - y * pi4b) - y * pi4c;
11163 const w = z * z;
11264
113 var r = r: {
114 if (w > 1e-14) {
115 break :r z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4));
116 } else {
117 break :r z;
118 }
119 };
65 var r = if (w > 1e-14)
66 z + z * (w * ((Tp0 * w + Tp1) * w + Tp2) / ((((w + Tq1) * w + Tq2) * w + Tq3) * w + Tq4))
67 else
68 z;
12069
12170 if (j & 2 == 2) {
12271 r = -1 / r;
12372 }
124 if (sign) {
125 r = -r;
126 }
12773
128 return r;
74 return if (sign) -r else r;
12975}
13076
13177test "math.tan" {
132 expect(tan(f32(0.0)) == tan32(0.0));
133 expect(tan(f64(0.0)) == tan64(0.0));
78 expect(tan(f32(0.0)) == tan_(f32, 0.0));
79 expect(tan(f64(0.0)) == tan_(f64, 0.0));
13480}
13581
13682test "math.tan32" {
13783 const epsilon = 0.000001;
13884
139 expect(math.approxEq(f32, tan32(0.0), 0.0, epsilon));
140 expect(math.approxEq(f32, tan32(0.2), 0.202710, epsilon));
141 expect(math.approxEq(f32, tan32(0.8923), 1.240422, epsilon));
142 expect(math.approxEq(f32, tan32(1.5), 14.101420, epsilon));
143 expect(math.approxEq(f32, tan32(37.45), -0.254397, epsilon));
144 expect(math.approxEq(f32, tan32(89.123), 2.285852, epsilon));
85 expect(math.approxEq(f32, tan_(f32, 0.0), 0.0, epsilon));
86 expect(math.approxEq(f32, tan_(f32, 0.2), 0.202710, epsilon));
87 expect(math.approxEq(f32, tan_(f32, 0.8923), 1.240422, epsilon));
88 expect(math.approxEq(f32, tan_(f32, 1.5), 14.101420, epsilon));
89 expect(math.approxEq(f32, tan_(f32, 37.45), -0.254397, epsilon));
90 expect(math.approxEq(f32, tan_(f32, 89.123), 2.285852, epsilon));
14591}
14692
14793test "math.tan64" {
14894 const epsilon = 0.000001;
14995
150 expect(math.approxEq(f64, tan64(0.0), 0.0, epsilon));
151 expect(math.approxEq(f64, tan64(0.2), 0.202710, epsilon));
152 expect(math.approxEq(f64, tan64(0.8923), 1.240422, epsilon));
153 expect(math.approxEq(f64, tan64(1.5), 14.101420, epsilon));
154 expect(math.approxEq(f64, tan64(37.45), -0.254397, epsilon));
155 expect(math.approxEq(f64, tan64(89.123), 2.2858376, epsilon));
96 expect(math.approxEq(f64, tan_(f64, 0.0), 0.0, epsilon));
97 expect(math.approxEq(f64, tan_(f64, 0.2), 0.202710, epsilon));
98 expect(math.approxEq(f64, tan_(f64, 0.8923), 1.240422, epsilon));
99 expect(math.approxEq(f64, tan_(f64, 1.5), 14.101420, epsilon));
100 expect(math.approxEq(f64, tan_(f64, 37.45), -0.254397, epsilon));
101 expect(math.approxEq(f64, tan_(f64, 89.123), 2.2858376, epsilon));
156102}
157103
158104test "math.tan32.special" {
159 expect(tan32(0.0) == 0.0);
160 expect(tan32(-0.0) == -0.0);
161 expect(math.isNan(tan32(math.inf(f32))));
162 expect(math.isNan(tan32(-math.inf(f32))));
163 expect(math.isNan(tan32(math.nan(f32))));
105 expect(tan_(f32, 0.0) == 0.0);
106 expect(tan_(f32, -0.0) == -0.0);
107 expect(math.isNan(tan_(f32, math.inf(f32))));
108 expect(math.isNan(tan_(f32, -math.inf(f32))));
109 expect(math.isNan(tan_(f32, math.nan(f32))));
164110}
165111
166112test "math.tan64.special" {
167 expect(tan64(0.0) == 0.0);
168 expect(tan64(-0.0) == -0.0);
169 expect(math.isNan(tan64(math.inf(f64))));
170 expect(math.isNan(tan64(-math.inf(f64))));
171 expect(math.isNan(tan64(math.nan(f64))));
113 expect(tan_(f64, 0.0) == 0.0);
114 expect(tan_(f64, -0.0) == -0.0);
115 expect(math.isNan(tan_(f64, math.inf(f64))));
116 expect(math.isNan(tan_(f64, -math.inf(f64))));
117 expect(math.isNan(tan_(f64, math.nan(f64))));
172118}
std/math/tanh.zig+10-4
......@@ -1,8 +1,8 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - sinh(+-0) = +-0
4// - sinh(+-inf) = +-1
5// - sinh(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/tanhf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/tanh.c
66
77const builtin = @import("builtin");
88const std = @import("../std.zig");
......@@ -11,6 +11,12 @@ const expect = std.testing.expect;
1111const expo2 = @import("expo2.zig").expo2;
1212const maxInt = std.math.maxInt;
1313
14/// Returns the hyperbolic tangent of x.
15///
16/// Special Cases:
17/// - sinh(+-0) = +-0
18/// - sinh(+-inf) = +-1
19/// - sinh(nan) = nan
1420pub fn tanh(x: var) @typeOf(x) {
1521 const T = @typeOf(x);
1622 return switch (T) {
std/math/trunc.zig+10-4
......@@ -1,14 +1,20 @@
1// Special Cases:
1// Ported from musl, which is licensed under the MIT license:
2// https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
23//
3// - trunc(+-0) = +-0
4// - trunc(+-inf) = +-inf
5// - trunc(nan) = nan
4// https://git.musl-libc.org/cgit/musl/tree/src/math/truncf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/trunc.c
66
77const std = @import("../std.zig");
88const math = std.math;
99const expect = std.testing.expect;
1010const maxInt = std.math.maxInt;
1111
12/// Returns the integer value of x.
13///
14/// Special Cases:
15/// - trunc(+-0) = +-0
16/// - trunc(+-inf) = +-inf
17/// - trunc(nan) = nan
1218pub fn trunc(x: var) @typeOf(x) {
1319 const T = @typeOf(x);
1420 return switch (T) {
std/mem.zig+23-29
......@@ -34,39 +34,39 @@ pub const Allocator = struct {
3434 /// The returned slice must have its pointer aligned at least to `new_alignment` bytes.
3535 reallocFn: fn (
3636 self: *Allocator,
37 // Guaranteed to be the same as what was returned from most recent call to
38 // `reallocFn` or `shrinkFn`.
39 // If `old_mem.len == 0` then this is a new allocation and `new_byte_count`
40 // is guaranteed to be >= 1.
37 /// Guaranteed to be the same as what was returned from most recent call to
38 /// `reallocFn` or `shrinkFn`.
39 /// If `old_mem.len == 0` then this is a new allocation and `new_byte_count`
40 /// is guaranteed to be >= 1.
4141 old_mem: []u8,
42 // If `old_mem.len == 0` then this is `undefined`, otherwise:
43 // Guaranteed to be the same as what was returned from most recent call to
44 // `reallocFn` or `shrinkFn`.
45 // Guaranteed to be >= 1.
46 // Guaranteed to be a power of 2.
42 /// If `old_mem.len == 0` then this is `undefined`, otherwise:
43 /// Guaranteed to be the same as what was returned from most recent call to
44 /// `reallocFn` or `shrinkFn`.
45 /// Guaranteed to be >= 1.
46 /// Guaranteed to be a power of 2.
4747 old_alignment: u29,
48 // If `new_byte_count` is 0 then this is a free and it is guaranteed that
49 // `old_mem.len != 0`.
48 /// If `new_byte_count` is 0 then this is a free and it is guaranteed that
49 /// `old_mem.len != 0`.
5050 new_byte_count: usize,
51 // Guaranteed to be >= 1.
52 // Guaranteed to be a power of 2.
53 // Returned slice's pointer must have this alignment.
51 /// Guaranteed to be >= 1.
52 /// Guaranteed to be a power of 2.
53 /// Returned slice's pointer must have this alignment.
5454 new_alignment: u29,
5555 ) Error![]u8,
5656
5757 /// This function deallocates memory. It must succeed.
5858 shrinkFn: fn (
5959 self: *Allocator,
60 // Guaranteed to be the same as what was returned from most recent call to
61 // `reallocFn` or `shrinkFn`.
60 /// Guaranteed to be the same as what was returned from most recent call to
61 /// `reallocFn` or `shrinkFn`.
6262 old_mem: []u8,
63 // Guaranteed to be the same as what was returned from most recent call to
64 // `reallocFn` or `shrinkFn`.
63 /// Guaranteed to be the same as what was returned from most recent call to
64 /// `reallocFn` or `shrinkFn`.
6565 old_alignment: u29,
66 // Guaranteed to be less than or equal to `old_mem.len`.
66 /// Guaranteed to be less than or equal to `old_mem.len`.
6767 new_byte_count: usize,
68 // If `new_byte_count == 0` then this is `undefined`, otherwise:
69 // Guaranteed to be less than or equal to `old_alignment`.
68 /// If `new_byte_count == 0` then this is `undefined`, otherwise:
69 /// Guaranteed to be less than or equal to `old_alignment`.
7070 new_alignment: u29,
7171 ) []u8,
7272
......@@ -104,10 +104,7 @@ pub const Allocator = struct {
104104 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
105105 const byte_slice = try self.reallocFn(self, ([*]u8)(undefined)[0..0], undefined, byte_count, alignment);
106106 assert(byte_slice.len == byte_count);
107 // This loop gets optimized out in ReleaseFast mode
108 for (byte_slice) |*byte| {
109 byte.* = undefined;
110 }
107 @memset(byte_slice.ptr, undefined, byte_slice.len);
111108 return @bytesToSlice(T, @alignCast(alignment, byte_slice));
112109 }
113110
......@@ -153,10 +150,7 @@ pub const Allocator = struct {
153150 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
154151 assert(byte_slice.len == byte_count);
155152 if (new_n > old_mem.len) {
156 // This loop gets optimized out in ReleaseFast mode
157 for (byte_slice[old_byte_slice.len..]) |*byte| {
158 byte.* = undefined;
159 }
153 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);
160154 }
161155 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));
162156 }
std/os.zig+104-14
......@@ -23,6 +23,7 @@ test "std.os" {
2323 _ = @import("os/time.zig");
2424 _ = @import("os/windows.zig");
2525 _ = @import("os/uefi.zig");
26 _ = @import("os/wasi.zig");
2627 _ = @import("os/get_app_data_dir.zig");
2728}
2829
......@@ -33,6 +34,7 @@ pub const freebsd = @import("os/freebsd.zig");
3334pub const netbsd = @import("os/netbsd.zig");
3435pub const zen = @import("os/zen.zig");
3536pub const uefi = @import("os/uefi.zig");
37pub const wasi = @import("os/wasi.zig");
3638
3739pub const posix = switch (builtin.os) {
3840 Os.linux => linux,
......@@ -40,6 +42,7 @@ pub const posix = switch (builtin.os) {
4042 Os.freebsd => freebsd,
4143 Os.netbsd => netbsd,
4244 Os.zen => zen,
45 Os.wasi => wasi,
4346 else => @compileError("Unsupported OS"),
4447};
4548
......@@ -50,7 +53,11 @@ pub const path = @import("os/path.zig");
5053pub const File = @import("os/file.zig").File;
5154pub const time = @import("os/time.zig");
5255
53pub const page_size = 4 * 1024;
56pub const page_size = switch (builtin.arch) {
57 .wasm32, .wasm64 => 64 * 1024,
58 else => 4 * 1024,
59};
60
5461pub const MAX_PATH_BYTES = switch (builtin.os) {
5562 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => posix.PATH_MAX,
5663 // Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
......@@ -139,6 +146,12 @@ pub fn getRandomBytes(buf: []u8) !void {
139146 };
140147 }
141148 },
149 Os.wasi => {
150 const random_get_result = os.wasi.random_get(buf.ptr, buf.len);
151 if (random_get_result != os.wasi.ESUCCESS) {
152 return error.Unknown;
153 }
154 },
142155 Os.zen => {
143156 const randomness = []u8{ 42, 1, 7, 12, 22, 17, 99, 16, 26, 87, 41, 45 };
144157 var i: usize = 0;
......@@ -198,6 +211,12 @@ pub fn abort() noreturn {
198211 }
199212 windows.ExitProcess(3);
200213 },
214 Os.wasi => {
215 _ = wasi.proc_raise(wasi.SIGABRT);
216 // TODO: Is SIGKILL even necessary?
217 _ = wasi.proc_raise(wasi.SIGKILL);
218 while (true) {}
219 },
201220 Os.uefi => {
202221 // TODO there's gotta be a better thing to do here than loop forever
203222 while (true) {}
......@@ -226,6 +245,9 @@ pub fn exit(status: u8) noreturn {
226245 Os.windows => {
227246 windows.ExitProcess(status);
228247 },
248 Os.wasi => {
249 wasi.proc_exit(status);
250 },
229251 else => @compileError("Unsupported OS"),
230252 }
231253}
......@@ -749,6 +771,37 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
749771
750772 try result.setMove(key, value);
751773 }
774 } else if (builtin.os == Os.wasi) {
775 var environ_count: usize = undefined;
776 var environ_buf_size: usize = undefined;
777
778 const environ_sizes_get_ret = std.os.wasi.environ_sizes_get(&environ_count, &environ_buf_size);
779 if (environ_sizes_get_ret != os.wasi.ESUCCESS) {
780 return unexpectedErrorPosix(environ_sizes_get_ret);
781 }
782
783 // TODO: Verify that the documentation is incorrect
784 // https://github.com/WebAssembly/WASI/issues/27
785 var environ = try allocator.alloc(?[*]u8, environ_count + 1);
786 defer allocator.free(environ);
787 var environ_buf = try std.heap.wasm_allocator.alloc(u8, environ_buf_size);
788 defer allocator.free(environ_buf);
789
790 const environ_get_ret = std.os.wasi.environ_get(environ.ptr, environ_buf.ptr);
791 if (environ_get_ret != os.wasi.ESUCCESS) {
792 return unexpectedErrorPosix(environ_get_ret);
793 }
794
795 for (environ) |env| {
796 if (env) |ptr| {
797 const pair = mem.toSlice(u8, ptr);
798 var parts = mem.separate(pair, "=");
799 const key = parts.next().?;
800 const value = parts.next().?;
801 try result.set(key, value);
802 }
803 }
804 return result;
752805 } else {
753806 for (posix_environ_raw) |ptr| {
754807 var line_i: usize = 0;
......@@ -1083,13 +1136,14 @@ pub fn copyFile(source_path: []const u8, dest_path: []const u8) !void {
10831136 defer in_file.close();
10841137
10851138 const mode = try in_file.mode();
1139 const in_stream = &in_file.inStream().stream;
10861140
10871141 var atomic_file = try AtomicFile.init(dest_path, mode);
10881142 defer atomic_file.deinit();
10891143
10901144 var buf: [page_size]u8 = undefined;
10911145 while (true) {
1092 const amt = try in_file.readFull(buf[0..]);
1146 const amt = try in_stream.readFull(buf[0..]);
10931147 try atomic_file.file.write(buf[0..amt]);
10941148 if (amt != buf.len) {
10951149 return atomic_file.finish();
......@@ -2127,6 +2181,11 @@ pub const ArgIterator = struct {
21272181 inner: InnerType,
21282182
21292183 pub fn init() ArgIterator {
2184 if (builtin.os == Os.wasi) {
2185 // TODO: Figure out a compatible interface accomodating WASI
2186 @compileError("ArgIterator is not yet supported in WASI. Use argsAlloc and argsFree instead.");
2187 }
2188
21302189 return ArgIterator{ .inner = InnerType.init() };
21312190 }
21322191
......@@ -2159,6 +2218,34 @@ pub fn args() ArgIterator {
21592218
21602219/// Caller must call argsFree on result.
21612220pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
2221 if (builtin.os == Os.wasi) {
2222 var count: usize = undefined;
2223 var buf_size: usize = undefined;
2224
2225 const args_sizes_get_ret = os.wasi.args_sizes_get(&count, &buf_size);
2226 if (args_sizes_get_ret != os.wasi.ESUCCESS) {
2227 return unexpectedErrorPosix(args_sizes_get_ret);
2228 }
2229
2230 var argv = try allocator.alloc([*]u8, count);
2231 defer allocator.free(argv);
2232
2233 var argv_buf = try allocator.alloc(u8, buf_size);
2234 const args_get_ret = os.wasi.args_get(argv.ptr, argv_buf.ptr);
2235 if (args_get_ret != os.wasi.ESUCCESS) {
2236 return unexpectedErrorPosix(args_get_ret);
2237 }
2238
2239 var result_slice = try allocator.alloc([]u8, count);
2240
2241 var i: usize = 0;
2242 while (i < count) : (i += 1) {
2243 result_slice[i] = mem.toSlice(u8, argv[i]);
2244 }
2245
2246 return result_slice;
2247 }
2248
21622249 // TODO refactor to only make 1 allocation.
21632250 var it = args();
21642251 var contents = try Buffer.initSize(allocator, 0);
......@@ -2196,6 +2283,16 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
21962283}
21972284
21982285pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {
2286 if (builtin.os == Os.wasi) {
2287 const last_item = args_alloc[args_alloc.len - 1];
2288 const last_byte_addr = @ptrToInt(last_item.ptr) + last_item.len + 1; // null terminated
2289 const first_item_ptr = args_alloc[0].ptr;
2290 const len = last_byte_addr - @ptrToInt(first_item_ptr);
2291 allocator.free(first_item_ptr[0..len]);
2292
2293 return allocator.free(args_alloc);
2294 }
2295
21992296 var total_bytes: usize = 0;
22002297 for (args_alloc) |arg| {
22012298 total_bytes += @sizeOf([]u8) + arg.len;
......@@ -3030,9 +3127,6 @@ pub const SpawnThreadError = error{
30303127 Unexpected,
30313128};
30323129
3033pub var linux_tls_phdr: ?*std.elf.Phdr = null;
3034pub var linux_tls_img_src: [*]const u8 = undefined; // defined if linux_tls_phdr is
3035
30363130/// caller must call wait on the returned thread
30373131/// fn startFn(@typeOf(context)) T
30383132/// where T is u8, noreturn, void, or !void
......@@ -3142,12 +3236,10 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
31423236 }
31433237 // Finally, the Thread Local Storage, if any.
31443238 if (!Thread.use_pthreads) {
3145 if (linux_tls_phdr) |tls_phdr| {
3146 l = mem.alignForward(l, tls_phdr.p_align);
3239 if (linux.tls.tls_image) |tls_img| {
3240 l = mem.alignForward(l, @alignOf(usize));
31473241 tls_start_offset = l;
3148 l += tls_phdr.p_memsz;
3149 // the fs register address
3150 l += @sizeOf(usize);
3242 l += tls_img.alloc_size;
31513243 }
31523244 }
31533245 break :blk l;
......@@ -3188,10 +3280,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
31883280 posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID |
31893281 posix.CLONE_DETACHED;
31903282 var newtls: usize = undefined;
3191 if (linux_tls_phdr) |tls_phdr| {
3192 @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), linux_tls_img_src, tls_phdr.p_filesz);
3193 newtls = mmap_addr + mmap_len - @sizeOf(usize);
3194 @intToPtr(*usize, newtls).* = newtls;
3283 if (linux.tls.tls_image) |tls_img| {
3284 newtls = linux.tls.copyTLS(mmap_addr + tls_start_offset);
31953285 flags |= posix.CLONE_SETTLS;
31963286 }
31973287 const rc = posix.clone(MainFuncs.linuxThreadMain, mmap_addr + stack_end_offset, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);
std/os/darwin.zig+1-1
......@@ -812,7 +812,7 @@ pub fn sigaction(sig: u5, noalias act: *const Sigaction, noalias oact: ?*Sigacti
812812 .sa_mask = act.mask,
813813 };
814814 var coact: c.Sigaction = undefined;
815 const result = errnoWrap(c.sigaction(sig, *cact, *coact));
815 const result = errnoWrap(c.sigaction(sig, &cact, &coact));
816816 if (result != 0) {
817817 return result;
818818 }
std/os/file.zig+12-16
......@@ -235,7 +235,7 @@ pub const File = struct {
235235 Unexpected,
236236 };
237237
238 pub fn seekForward(self: File, amount: isize) SeekError!void {
238 pub fn seekForward(self: File, amount: i64) SeekError!void {
239239 switch (builtin.os) {
240240 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
241241 const result = posix.lseek(self.handle, amount, posix.SEEK_CUR);
......@@ -266,7 +266,7 @@ pub const File = struct {
266266 }
267267 }
268268
269 pub fn seekTo(self: File, pos: usize) SeekError!void {
269 pub fn seekTo(self: File, pos: u64) SeekError!void {
270270 switch (builtin.os) {
271271 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
272272 const ipos = try math.cast(isize, pos);
......@@ -301,13 +301,12 @@ pub const File = struct {
301301 }
302302
303303 pub const GetSeekPosError = error{
304 Overflow,
305304 SystemResources,
306305 Unseekable,
307306 Unexpected,
308307 };
309308
310 pub fn getPos(self: File) GetSeekPosError!usize {
309 pub fn getPos(self: File) GetSeekPosError!u64 {
311310 switch (builtin.os) {
312311 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
313312 const result = posix.lseek(self.handle, 0, posix.SEEK_CUR);
......@@ -324,7 +323,7 @@ pub const File = struct {
324323 else => os.unexpectedErrorPosix(err),
325324 };
326325 }
327 return result;
326 return u64(result);
328327 },
329328 Os.windows => {
330329 var pos: windows.LARGE_INTEGER = undefined;
......@@ -336,17 +335,16 @@ pub const File = struct {
336335 };
337336 }
338337
339 assert(pos >= 0);
340 return math.cast(usize, pos);
338 return @intCast(u64, pos);
341339 },
342340 else => @compileError("unsupported OS"),
343341 }
344342 }
345343
346 pub fn getEndPos(self: File) GetSeekPosError!usize {
344 pub fn getEndPos(self: File) GetSeekPosError!u64 {
347345 if (is_posix) {
348346 const stat = try os.posixFStat(self.handle);
349 return @intCast(usize, stat.size);
347 return @intCast(u64, stat.size);
350348 } else if (is_windows) {
351349 var file_size: windows.LARGE_INTEGER = undefined;
352350 if (windows.GetFileSizeEx(self.handle, &file_size) == 0) {
......@@ -355,9 +353,7 @@ pub const File = struct {
355353 else => os.unexpectedErrorWindows(err),
356354 };
357355 }
358 if (file_size < 0)
359 return error.Overflow;
360 return math.cast(usize, @intCast(u64, file_size));
356 return @intCast(u64, file_size);
361357 } else {
362358 @compileError("TODO support getEndPos on this OS");
363359 }
......@@ -492,22 +488,22 @@ pub const File = struct {
492488
493489 pub const Stream = io.SeekableStream(SeekError, GetSeekPosError);
494490
495 pub fn seekToFn(seekable_stream: *Stream, pos: usize) SeekError!void {
491 pub fn seekToFn(seekable_stream: *Stream, pos: u64) SeekError!void {
496492 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
497493 return self.file.seekTo(pos);
498494 }
499495
500 pub fn seekForwardFn(seekable_stream: *Stream, amt: isize) SeekError!void {
496 pub fn seekForwardFn(seekable_stream: *Stream, amt: i64) SeekError!void {
501497 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
502498 return self.file.seekForward(amt);
503499 }
504500
505 pub fn getEndPosFn(seekable_stream: *Stream) GetSeekPosError!usize {
501 pub fn getEndPosFn(seekable_stream: *Stream) GetSeekPosError!u64 {
506502 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
507503 return self.file.getEndPos();
508504 }
509505
510 pub fn getPosFn(seekable_stream: *Stream) GetSeekPosError!usize {
506 pub fn getPosFn(seekable_stream: *Stream) GetSeekPosError!u64 {
511507 const self = @fieldParentPtr(SeekableStream, "stream", seekable_stream);
512508 return self.file.getPos();
513509 }
std/os/linux.zig+150-16
......@@ -2,7 +2,10 @@ const std = @import("../std.zig");
22const assert = std.debug.assert;
33const builtin = @import("builtin");
44const maxInt = std.math.maxInt;
5const elf = std.elf;
6pub const tls = @import("linux/tls.zig");
57const vdso = @import("linux/vdso.zig");
8const dl = @import("../dynamic_library.zig");
69pub use switch (builtin.arch) {
710 builtin.Arch.x86_64 => @import("linux/x86_64.zig"),
811 builtin.Arch.i386 => @import("linux/i386.zig"),
......@@ -12,6 +15,7 @@ pub use switch (builtin.arch) {
1215pub use @import("linux/errno.zig");
1316
1417pub const PATH_MAX = 4096;
18pub const IOV_MAX = 1024;
1519
1620pub const STDIN_FILENO = 0;
1721pub const STDOUT_FILENO = 1;
......@@ -955,10 +959,13 @@ pub fn waitpid(pid: i32, status: *i32, options: i32) usize {
955959 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
956960}
957961
962var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
963
958964pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
959965 if (VDSO_CGT_SYM.len != 0) {
960 const f = @atomicLoad(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, builtin.AtomicOrder.Unordered);
961 if (@ptrToInt(f) != 0) {
966 const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered);
967 if (ptr) |fn_ptr| {
968 const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
962969 const rc = f(clk_id, tp);
963970 switch (rc) {
964971 0, @bitCast(usize, isize(-EINVAL)) => return rc,
......@@ -968,13 +975,18 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
968975 }
969976 return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));
970977}
971var vdso_clock_gettime = init_vdso_clock_gettime;
978
972979extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
973 const addr = vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM);
974 var f = @intToPtr(@typeOf(init_vdso_clock_gettime), addr);
975 _ = @cmpxchgStrong(@typeOf(init_vdso_clock_gettime), &vdso_clock_gettime, init_vdso_clock_gettime, f, builtin.AtomicOrder.Monotonic, builtin.AtomicOrder.Monotonic);
976 if (@ptrToInt(f) == 0) return @bitCast(usize, isize(-ENOSYS));
977 return f(clk, ts);
980 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
981 // Note that we may not have a VDSO at all, update the stub address anyway
982 // so that clock_gettime will fall back on the good old (and slow) syscall
983 _ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);
984 // Call into the VDSO if available
985 if (ptr) |fn_ptr| {
986 const f = @ptrCast(@typeOf(clock_gettime), fn_ptr);
987 return f(clk, ts);
988 }
989 return @bitCast(usize, isize(-ENOSYS));
978990}
979991
980992pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
......@@ -1100,8 +1112,8 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
11001112
11011113const NSIG = 65;
11021114const sigset_t = [128 / @sizeOf(usize)]usize;
1103const all_mask = []usize{maxInt(usize)};
1104const app_mask = []usize{0xfffffffc7fffffff};
1115const all_mask = []u32{ 0xffffffff, 0xffffffff };
1116const app_mask = []u32{ 0xfffffffc, 0x7fffffff };
11051117
11061118const k_sigaction = extern struct {
11071119 handler: extern fn (i32) void,
......@@ -1193,6 +1205,16 @@ pub const iovec_const = extern struct {
11931205 iov_len: usize,
11941206};
11951207
1208pub const mmsghdr = extern struct {
1209 msg_hdr: msghdr,
1210 msg_len: u32,
1211};
1212
1213pub const mmsghdr_const = extern struct {
1214 msg_hdr: msghdr_const,
1215 msg_len: u32,
1216};
1217
11961218pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
11971219 return syscall3(SYS_getsockname, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));
11981220}
......@@ -1213,10 +1235,50 @@ pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noal
12131235 return syscall5(SYS_getsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
12141236}
12151237
1216pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize {
1238pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {
12171239 return syscall3(SYS_sendmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);
12181240}
12191241
1242pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize {
1243 if (@typeInfo(usize).Int.bits > @typeInfo(@typeOf(mmsghdr(undefined).msg_len)).Int.bits) {
1244 // workaround kernel brokenness:
1245 // if adding up all iov_len overflows a i32 then split into multiple calls
1246 // see https://www.openwall.com/lists/musl/2014/06/07/5
1247 const kvlen = if (vlen > IOV_MAX) IOV_MAX else vlen; // matches kernel
1248 var next_unsent: usize = 0;
1249 for (msgvec[0..kvlen]) |*msg, i| {
1250 var size: i32 = 0;
1251 const msg_iovlen = @intCast(usize, msg.msg_hdr.msg_iovlen); // kernel side this is treated as unsigned
1252 for (msg.msg_hdr.msg_iov[0..msg_iovlen]) |iov, j| {
1253 if (iov.iov_len > std.math.maxInt(i32) or @addWithOverflow(i32, size, @intCast(i32, iov.iov_len), &size)) {
1254 // batch-send all messages up to the current message
1255 if (next_unsent < i) {
1256 const batch_size = i - next_unsent;
1257 const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
1258 if (getErrno(r) != 0) return next_unsent;
1259 if (r < batch_size) return next_unsent + r;
1260 }
1261 // send current message as own packet
1262 const r = sendmsg(fd, &msg.msg_hdr, flags);
1263 if (getErrno(r) != 0) return r;
1264 // Linux limits the total bytes sent by sendmsg to INT_MAX, so this cast is safe.
1265 msg.msg_len = @intCast(u32, r);
1266 next_unsent = i + 1;
1267 break;
1268 }
1269 }
1270 }
1271 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG_EOR)
1272 const batch_size = kvlen - next_unsent;
1273 const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
1274 if (getErrno(r) != 0) return r;
1275 return next_unsent + r;
1276 }
1277 return kvlen;
1278 }
1279 return syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(msgvec), vlen, flags);
1280}
1281
12201282pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
12211283 return syscall3(SYS_connect, @bitCast(usize, isize(fd)), @ptrToInt(addr), len);
12221284}
......@@ -1339,17 +1401,25 @@ pub fn sched_getaffinity(pid: i32, set: []usize) usize {
13391401 return syscall3(SYS_sched_getaffinity, @bitCast(usize, isize(pid)), set.len * @sizeOf(usize), @ptrToInt(set.ptr));
13401402}
13411403
1342pub const epoll_data = packed union {
1404pub const epoll_data = extern union {
13431405 ptr: usize,
13441406 fd: i32,
13451407 @"u32": u32,
13461408 @"u64": u64,
13471409};
13481410
1349pub const epoll_event = packed struct {
1350 events: u32,
1351 data: epoll_data,
1352};
1411// On x86_64 the structure is packed so that it matches the definition of its
1412// 32bit counterpart
1413pub const epoll_event = if (builtin.arch != .x86_64)
1414 extern struct {
1415 events: u32,
1416 data: epoll_data,
1417 }
1418else
1419 packed struct {
1420 events: u32,
1421 data: epoll_data,
1422 };
13531423
13541424pub fn epoll_create() usize {
13551425 return epoll_create1(0);
......@@ -1534,6 +1604,70 @@ pub const dirent64 = extern struct {
15341604 d_name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
15351605};
15361606
1607pub const dl_phdr_info = extern struct {
1608 dlpi_addr: usize,
1609 dlpi_name: ?[*]const u8,
1610 dlpi_phdr: [*]elf.Phdr,
1611 dlpi_phnum: u16,
1612};
1613
1614// XXX: This should be weak
1615extern const __ehdr_start: elf.Ehdr = undefined;
1616
1617pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize {
1618 if (builtin.link_libc) {
1619 return std.c.dl_iterate_phdr(@ptrCast(std.c.dl_iterate_phdr_callback, callback), @ptrCast(?*c_void, data));
1620 }
1621
1622 const elf_base = @ptrToInt(&__ehdr_start);
1623 const n_phdr = __ehdr_start.e_phnum;
1624 const phdrs = (@intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff))[0..n_phdr];
1625
1626 var it = dl.linkmap_iterator(phdrs) catch return 0;
1627
1628 // The executable has no dynamic link segment, create a single entry for
1629 // the whole ELF image
1630 if (it.end()) {
1631 var info = dl_phdr_info{
1632 .dlpi_addr = elf_base,
1633 .dlpi_name = c"/proc/self/exe",
1634 .dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff),
1635 .dlpi_phnum = __ehdr_start.e_phnum,
1636 };
1637
1638 return callback(&info, @sizeOf(dl_phdr_info), data);
1639 }
1640
1641 // Last return value from the callback function
1642 var last_r: isize = 0;
1643 while (it.next()) |entry| {
1644 var dlpi_phdr: usize = undefined;
1645 var dlpi_phnum: u16 = undefined;
1646
1647 if (entry.l_addr != 0) {
1648 const elf_header = @intToPtr(*elf.Ehdr, entry.l_addr);
1649 dlpi_phdr = entry.l_addr + elf_header.e_phoff;
1650 dlpi_phnum = elf_header.e_phnum;
1651 } else {
1652 // This is the running ELF image
1653 dlpi_phdr = elf_base + __ehdr_start.e_phoff;
1654 dlpi_phnum = __ehdr_start.e_phnum;
1655 }
1656
1657 var info = dl_phdr_info{
1658 .dlpi_addr = entry.l_addr,
1659 .dlpi_name = entry.l_name,
1660 .dlpi_phdr = @intToPtr([*]elf.Phdr, dlpi_phdr),
1661 .dlpi_phnum = dlpi_phnum,
1662 };
1663
1664 last_r = callback(&info, @sizeOf(dl_phdr_info), data);
1665 if (last_r != 0) break;
1666 }
1667
1668 return last_r;
1669}
1670
15371671test "import" {
15381672 if (builtin.os == builtin.Os.linux) {
15391673 _ = @import("linux/test.zig");
std/os/linux/arm64.zig+16-3
......@@ -2,6 +2,7 @@ const std = @import("../../std.zig");
22const linux = std.os.linux;
33const socklen_t = linux.socklen_t;
44const iovec = linux.iovec;
5const iovec_const = linux.iovec_const;
56
67pub const SYS_io_setup = 0;
78pub const SYS_io_destroy = 1;
......@@ -415,12 +416,24 @@ pub fn syscall6(
415416pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
416417
417418pub const msghdr = extern struct {
418 msg_name: *u8,
419 msg_name: ?*sockaddr,
419420 msg_namelen: socklen_t,
420 msg_iov: *iovec,
421 msg_iov: [*]iovec,
421422 msg_iovlen: i32,
422423 __pad1: i32,
423 msg_control: *u8,
424 msg_control: ?*c_void,
425 msg_controllen: socklen_t,
426 __pad2: socklen_t,
427 msg_flags: i32,
428};
429
430pub const msghdr_const = extern struct {
431 msg_name: ?*const sockaddr,
432 msg_namelen: socklen_t,
433 msg_iov: [*]iovec_const,
434 msg_iovlen: i32,
435 __pad1: i32,
436 msg_control: ?*c_void,
424437 msg_controllen: socklen_t,
425438 __pad2: socklen_t,
426439 msg_flags: i32,
std/os/linux/test.zig+41
......@@ -1,6 +1,8 @@
11const std = @import("../../std.zig");
22const builtin = @import("builtin");
33const linux = std.os.linux;
4const mem = std.mem;
5const elf = std.elf;
46const expect = std.testing.expect;
57
68test "getpid" {
......@@ -42,3 +44,42 @@ test "timer" {
4244 // TODO implicit cast from *[N]T to [*]T
4345 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
4446}
47
48export fn iter_fn(info: *linux.dl_phdr_info, size: usize, data: ?*usize) i32 {
49 var counter = data.?;
50 // Count how many libraries are loaded
51 counter.* += usize(1);
52
53 // The image should contain at least a PT_LOAD segment
54 if (info.dlpi_phnum < 1) return -1;
55
56 // Quick & dirty validation of the phdr pointers, make sure we're not
57 // pointing to some random gibberish
58 var i: usize = 0;
59 var found_load = false;
60 while (i < info.dlpi_phnum) : (i += 1) {
61 const phdr = info.dlpi_phdr[i];
62
63 if (phdr.p_type != elf.PT_LOAD) continue;
64
65 // Find the ELF header
66 const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset);
67 // Validate the magic
68 if (!mem.eql(u8, elf_header.e_ident[0..], "\x7fELF")) return -1;
69 // Consistency check
70 if (elf_header.e_phnum != info.dlpi_phnum) return -1;
71
72 found_load = true;
73 break;
74 }
75
76 if (!found_load) return -1;
77
78 return 42;
79}
80
81test "dl_iterate_phdr" {
82 var counter: usize = 0;
83 expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
84 expect(counter != 0);
85}
std/os/linux/tls.zig created+247
......@@ -0,0 +1,247 @@
1const std = @import("std");
2const mem = std.mem;
3const posix = std.os.posix;
4const elf = std.elf;
5const builtin = @import("builtin");
6const assert = std.debug.assert;
7
8// This file implements the two TLS variants [1] used by ELF-based systems.
9//
10// The variant I has the following layout in memory:
11// -------------------------------------------------------
12// | DTV | Zig | DTV | Alignment | TLS |
13// | storage | thread data | pointer | | block |
14// ------------------------^------------------------------
15// `-- The thread pointer register points here
16//
17// In this case we allocate additional space for our control structure that's
18// placed _before_ the DTV pointer together with the DTV.
19//
20// NOTE: Some systems such as power64 or mips use this variant with a twist: the
21// alignment is not present and the tp and DTV addresses are offset by a
22// constant.
23//
24// On the other hand the variant II has the following layout in memory:
25// ---------------------------------------
26// | TLS | TCB | Zig | DTV |
27// | block | | thread data | storage |
28// --------^------------------------------
29// `-- The thread pointer register points here
30//
31// The structure of the TCB is not defined by the ABI so we reserve enough space
32// for a single pointer as some architectures such as i386 and x86_64 need a
33// pointer to the TCB block itself at the address pointed by the tp.
34//
35// In this case the control structure and DTV are placed one after another right
36// after the TLS block data.
37//
38// At the moment the DTV is very simple since we only support static TLS, all we
39// need is a two word vector to hold the number of entries (1) and the address
40// of the first TLS block.
41//
42// [1] https://www.akkadia.org/drepper/tls.pdf
43
44const TLSVariant = enum {
45 VariantI,
46 VariantII,
47};
48
49const tls_variant = switch (builtin.arch) {
50 .arm, .armeb, .aarch64, .aarch64_be => TLSVariant.VariantI,
51 .x86_64, .i386 => TLSVariant.VariantII,
52 else => @compileError("undefined tls_variant for this architecture"),
53};
54
55// Controls how many bytes are reserved for the Thread Control Block
56const tls_tcb_size = switch (builtin.arch) {
57 // ARM EABI mandates enough space for two pointers: the first one points to
58 // the DTV while the second one is unspecified but reserved
59 .arm, .armeb, .aarch64, .aarch64_be => 2 * @sizeOf(usize),
60 .i386, .x86_64 => @sizeOf(usize),
61 else => 0,
62};
63
64// Controls if the TCB should be aligned according to the TLS segment p_align
65const tls_tcb_align_size = switch (builtin.arch) {
66 .arm, .armeb, .aarch64, .aarch64_be => true,
67 else => false,
68};
69
70// Check if the architecture-specific parameters look correct
71comptime {
72 if (tls_tcb_align_size and tls_variant != TLSVariant.VariantI) {
73 @compileError("tls_tcb_align_size is only meaningful for variant I TLS");
74 }
75}
76
77// Some architectures add some offset to the tp and dtv addresses in order to
78// make the generated code more efficient
79
80const tls_tp_offset = switch (builtin.arch) {
81 else => 0,
82};
83
84const tls_dtv_offset = switch (builtin.arch) {
85 else => 0,
86};
87
88// Per-thread storage for Zig's use
89const CustomData = packed struct {
90};
91
92// Dynamic Thread Vector
93const DTV = packed struct {
94 entries: usize,
95 tls_block: [1]usize,
96};
97
98// Holds all the information about the process TLS image
99const TLSImage = struct {
100 data_src: []u8,
101 alloc_size: usize,
102 tcb_offset: usize,
103 dtv_offset: usize,
104 data_offset: usize,
105};
106
107pub var tls_image: ?TLSImage = null;
108
109pub fn setThreadPointer(addr: usize) void {
110 switch (builtin.arch) {
111 .x86_64 => {
112 const rc = std.os.linux.syscall2(std.os.linux.SYS_arch_prctl,
113 std.os.linux.ARCH_SET_FS, addr);
114 assert(rc == 0);
115 },
116 .aarch64 => {
117 asm volatile (
118 \\ msr tpidr_el0, %[addr]
119 : : [addr] "r" (addr)
120 );
121 },
122 else => @compileError("Unsupported architecture"),
123 }
124}
125
126pub fn initTLS() void {
127 var tls_phdr: ?*elf.Phdr = null;
128 var img_base: usize = 0;
129
130 const auxv = std.os.linux_elf_aux_maybe.?;
131 var at_phent: usize = undefined;
132 var at_phnum: usize = undefined;
133 var at_phdr: usize = undefined;
134
135 var i: usize = 0;
136 while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
137 switch (auxv[i].a_type) {
138 elf.AT_PHENT => at_phent = auxv[i].a_un.a_val,
139 elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
140 elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
141 else => continue,
142 }
143 }
144
145 // Sanity check
146 assert(at_phent == @sizeOf(elf.Phdr));
147
148 // Search the TLS section
149 const phdrs = (@intToPtr([*]elf.Phdr, at_phdr))[0..at_phnum];
150
151 for (phdrs) |*phdr| {
152 switch (phdr.p_type) {
153 elf.PT_PHDR => img_base = at_phdr - phdr.p_vaddr,
154 elf.PT_TLS => tls_phdr = phdr,
155 else => continue,
156 }
157 }
158
159 if (tls_phdr) |phdr| {
160 // Offsets into the allocated TLS area
161 var tcb_offset: usize = undefined;
162 var dtv_offset: usize = undefined;
163 var data_offset: usize = undefined;
164 var thread_data_offset: usize = undefined;
165 // Compute the total size of the ABI-specific data plus our own control
166 // structures
167 const alloc_size = switch (tls_variant) {
168 .VariantI => blk: {
169 var l: usize = 0;
170 dtv_offset = l;
171 l += @sizeOf(DTV);
172 thread_data_offset = l;
173 l += @sizeOf(CustomData);
174 l = mem.alignForward(l, phdr.p_align);
175 tcb_offset = l;
176 if (tls_tcb_align_size) {
177 l += mem.alignForward(tls_tcb_size, phdr.p_align);
178 } else {
179 l += tls_tcb_size;
180 }
181 data_offset = l;
182 l += phdr.p_memsz;
183 break :blk l;
184 },
185 .VariantII => blk: {
186 var l: usize = 0;
187 data_offset = l;
188 l += phdr.p_memsz;
189 l = mem.alignForward(l, phdr.p_align);
190 tcb_offset = l;
191 l += tls_tcb_size;
192 thread_data_offset = l;
193 l += @sizeOf(CustomData);
194 dtv_offset = l;
195 l += @sizeOf(DTV);
196 break :blk l;
197 }
198 };
199
200 tls_image = TLSImage{
201 .data_src = @intToPtr([*]u8, phdr.p_vaddr + img_base)[0..phdr.p_filesz],
202 .alloc_size = alloc_size,
203 .tcb_offset = tcb_offset,
204 .dtv_offset = dtv_offset,
205 .data_offset = data_offset,
206 };
207 }
208}
209
210pub fn copyTLS(addr: usize) usize {
211 const tls_img = tls_image.?;
212
213 // Be paranoid, clear the area we're going to use
214 @memset(@intToPtr([*]u8, addr), 0, tls_img.alloc_size);
215 // Prepare the DTV
216 const dtv = @intToPtr(*DTV, addr + tls_img.dtv_offset);
217 dtv.entries = 1;
218 dtv.tls_block[0] = addr + tls_img.data_offset + tls_dtv_offset;
219 // Set-up the TCB
220 const tcb_ptr = @intToPtr(*usize, addr + tls_img.tcb_offset);
221 if (tls_variant == TLSVariant.VariantI) {
222 tcb_ptr.* = addr + tls_img.dtv_offset;
223 } else {
224 tcb_ptr.* = addr + tls_img.tcb_offset;
225 }
226 // Copy the data
227 @memcpy(@intToPtr([*]u8, addr + tls_img.data_offset), tls_img.data_src.ptr, tls_img.data_src.len);
228
229 // Return the corrected (if needed) value for the tp register
230 return addr + tls_img.tcb_offset + tls_tp_offset;
231}
232
233var main_thread_tls_buffer: [256]u8 align(32) = undefined;
234
235pub fn allocateTLS(size: usize) usize {
236 // Small TLS allocation, use our local buffer
237 if (size < main_thread_tls_buffer.len) {
238 return @ptrToInt(&main_thread_tls_buffer);
239 }
240
241 const addr = posix.mmap(null, size, posix.PROT_READ | posix.PROT_WRITE,
242 posix.MAP_PRIVATE | posix.MAP_ANONYMOUS, -1, 0);
243
244 if (posix.getErrno(addr) != 0) @panic("out of memory");
245
246 return addr;
247}
std/os/linux/x86_64.zig+22-3
......@@ -1,7 +1,9 @@
11const std = @import("../../std.zig");
22const linux = std.os.linux;
3const sockaddr = linux.sockaddr;
34const socklen_t = linux.socklen_t;
45const iovec = linux.iovec;
6const iovec_const = linux.iovec_const;
57
68pub const SYS_read = 0;
79pub const SYS_write = 1;
......@@ -386,6 +388,11 @@ pub const VDSO_CGT_VER = "LINUX_2.6";
386388pub const VDSO_GETCPU_SYM = "__vdso_getcpu";
387389pub const VDSO_GETCPU_VER = "LINUX_2.6";
388390
391pub const ARCH_SET_GS = 0x1001;
392pub const ARCH_SET_FS = 0x1002;
393pub const ARCH_GET_FS = 0x1003;
394pub const ARCH_GET_GS = 0x1004;
395
389396pub fn syscall0(number: usize) usize {
390397 return asm volatile ("syscall"
391398 : [ret] "={rax}" (-> usize)
......@@ -483,12 +490,24 @@ pub nakedcc fn restore_rt() void {
483490}
484491
485492pub const msghdr = extern struct {
486 msg_name: *u8,
493 msg_name: ?*sockaddr,
494 msg_namelen: socklen_t,
495 msg_iov: [*]iovec,
496 msg_iovlen: i32,
497 __pad1: i32,
498 msg_control: ?*c_void,
499 msg_controllen: socklen_t,
500 __pad2: socklen_t,
501 msg_flags: i32,
502};
503
504pub const msghdr_const = extern struct {
505 msg_name: ?*const sockaddr,
487506 msg_namelen: socklen_t,
488 msg_iov: *iovec,
507 msg_iov: [*]iovec_const,
489508 msg_iovlen: i32,
490509 __pad1: i32,
491 msg_control: *u8,
510 msg_control: ?*c_void,
492511 msg_controllen: socklen_t,
493512 __pad2: socklen_t,
494513 msg_flags: i32,
std/os/time.zig+23-7
......@@ -3,41 +3,44 @@ const builtin = @import("builtin");
33const Os = builtin.Os;
44const debug = std.debug;
55const testing = std.testing;
6const math = std.math;
67
78const windows = std.os.windows;
89const linux = std.os.linux;
910const darwin = std.os.darwin;
11const wasi = std.os.wasi;
1012const posix = std.os.posix;
1113
1214pub const epoch = @import("epoch.zig");
1315
14/// Sleep for the specified duration
16/// Spurious wakeups are possible and no precision of timing is guaranteed.
1517pub fn sleep(nanoseconds: u64) void {
1618 switch (builtin.os) {
1719 Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => {
1820 const s = nanoseconds / ns_per_s;
1921 const ns = nanoseconds % ns_per_s;
20 posixSleep(@intCast(u63, s), @intCast(u63, ns));
22 posixSleep(s, ns);
2123 },
2224 Os.windows => {
2325 const ns_per_ms = ns_per_s / ms_per_s;
2426 const milliseconds = nanoseconds / ns_per_ms;
25 windows.Sleep(@intCast(windows.DWORD, milliseconds));
27 const ms_that_will_fit = std.math.cast(windows.DWORD, milliseconds) catch std.math.maxInt(windows.DWORD);
28 windows.Sleep(ms_that_will_fit);
2629 },
2730 else => @compileError("Unsupported OS"),
2831 }
2932}
3033
31pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
34/// Spurious wakeups are possible and no precision of timing is guaranteed.
35pub fn posixSleep(seconds: u64, nanoseconds: u64) void {
3236 var req = posix.timespec{
33 .tv_sec = seconds,
34 .tv_nsec = nanoseconds,
37 .tv_sec = std.math.cast(isize, seconds) catch std.math.maxInt(isize),
38 .tv_nsec = std.math.cast(isize, nanoseconds) catch std.math.maxInt(isize),
3539 };
3640 var rem: posix.timespec = undefined;
3741 while (true) {
3842 const ret_val = posix.nanosleep(&req, &rem);
3943 const err = posix.getErrno(ret_val);
40 if (err == 0) return;
4144 switch (err) {
4245 posix.EFAULT => unreachable,
4346 posix.EINVAL => {
......@@ -49,6 +52,7 @@ pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
4952 req = rem;
5053 continue;
5154 },
55 // This prong handles success as well as unexpected errors.
5256 else => return,
5357 }
5458 }
......@@ -64,9 +68,21 @@ pub const milliTimestamp = switch (builtin.os) {
6468 Os.windows => milliTimestampWindows,
6569 Os.linux, Os.freebsd, Os.netbsd => milliTimestampPosix,
6670 Os.macosx, Os.ios => milliTimestampDarwin,
71 Os.wasi => milliTimestampWasi,
6772 else => @compileError("Unsupported OS"),
6873};
6974
75fn milliTimestampWasi() u64 {
76 var ns: wasi.timestamp_t = undefined;
77
78 // TODO: Verify that precision is ignored
79 const err = wasi.clock_time_get(wasi.CLOCK_REALTIME, 1, &ns);
80 debug.assert(err == wasi.ESUCCESS);
81
82 const ns_per_ms = 1000;
83 return @divFloor(ns, ns_per_ms);
84}
85
7086fn milliTimestampWindows() u64 {
7187 //FileTime has a granularity of 100 nanoseconds
7288 // and uses the NTFS/Windows epoch
std/os/wasi.zig created+42
......@@ -0,0 +1,42 @@
1pub use @import("wasi/core.zig");
2
3pub const STDIN_FILENO = 0;
4pub const STDOUT_FILENO = 1;
5pub const STDERR_FILENO = 2;
6
7pub fn getErrno(r: usize) usize {
8 const signed_r = @bitCast(isize, r);
9 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
10}
11
12pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
13 var nwritten: usize = undefined;
14
15 const ciovs = ciovec_t{
16 .buf = buf,
17 .buf_len = count,
18 };
19
20 const err = fd_write(@bitCast(fd_t, isize(fd)), &ciovs, 1, &nwritten);
21 if (err == ESUCCESS) {
22 return nwritten;
23 } else {
24 return @bitCast(usize, -isize(err));
25 }
26}
27
28pub fn read(fd: i32, buf: [*]u8, nbyte: usize) usize {
29 var nread: usize = undefined;
30
31 const iovs = iovec_t{
32 .buf = buf,
33 .buf_len = nbyte,
34 };
35
36 const err = fd_read(@bitCast(fd_t, isize(fd)), &iovs, 1, &nread);
37 if (err == ESUCCESS) {
38 return nread;
39 } else {
40 return @bitCast(usize, -isize(err));
41 }
42}
std/os/wasi/core.zig created+374
......@@ -0,0 +1,374 @@
1// Based on https://github.com/CraneStation/wasi-sysroot/blob/wasi/libc-bottom-half/headers/public/wasi/core.h
2// and https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md
3
4pub const advice_t = u8;
5pub const ADVICE_NORMAL: advice_t = 0;
6pub const ADVICE_SEQUENTIAL: advice_t = 1;
7pub const ADVICE_RANDOM: advice_t = 2;
8pub const ADVICE_WILLNEED: advice_t = 3;
9pub const ADVICE_DONTNEED: advice_t = 4;
10pub const ADVICE_NOREUSE: advice_t = 5;
11
12pub const ciovec_t = extern struct {
13 buf: [*]const u8,
14 buf_len: usize,
15};
16
17pub const clockid_t = u32;
18pub const CLOCK_REALTIME: clockid_t = 0;
19pub const CLOCK_MONOTONIC: clockid_t = 1;
20pub const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2;
21pub const CLOCK_THREAD_CPUTIME_ID: clockid_t = 3;
22
23pub const device_t = u64;
24
25pub const dircookie_t = u64;
26pub const DIRCOOKIE_START: dircookie_t = 0;
27
28pub const dirent_t = extern struct {
29 d_next: dircookie_t,
30 d_ino: inode_t,
31 d_namlen: u32,
32 d_type: filetype_t,
33};
34
35pub const errno_t = u16;
36pub const ESUCCESS: errno_t = 0;
37pub const E2BIG: errno_t = 1;
38pub const EACCES: errno_t = 2;
39pub const EADDRINUSE: errno_t = 3;
40pub const EADDRNOTAVAIL: errno_t = 4;
41pub const EAFNOSUPPORT: errno_t = 5;
42pub const EAGAIN: errno_t = 6;
43pub const EALREADY: errno_t = 7;
44pub const EBADF: errno_t = 8;
45pub const EBADMSG: errno_t = 9;
46pub const EBUSY: errno_t = 10;
47pub const ECANCELED: errno_t = 11;
48pub const ECHILD: errno_t = 12;
49pub const ECONNABORTED: errno_t = 13;
50pub const ECONNREFUSED: errno_t = 14;
51pub const ECONNRESET: errno_t = 15;
52pub const EDEADLK: errno_t = 16;
53pub const EDESTADDRREQ: errno_t = 17;
54pub const EDOM: errno_t = 18;
55pub const EDQUOT: errno_t = 19;
56pub const EEXIST: errno_t = 20;
57pub const EFAULT: errno_t = 21;
58pub const EFBIG: errno_t = 22;
59pub const EHOSTUNREACH: errno_t = 23;
60pub const EIDRM: errno_t = 24;
61pub const EILSEQ: errno_t = 25;
62pub const EINPROGRESS: errno_t = 26;
63pub const EINTR: errno_t = 27;
64pub const EINVAL: errno_t = 28;
65pub const EIO: errno_t = 29;
66pub const EISCONN: errno_t = 30;
67pub const EISDIR: errno_t = 31;
68pub const ELOOP: errno_t = 32;
69pub const EMFILE: errno_t = 33;
70pub const EMLINK: errno_t = 34;
71pub const EMSGSIZE: errno_t = 35;
72pub const EMULTIHOP: errno_t = 36;
73pub const ENAMETOOLONG: errno_t = 37;
74pub const ENETDOWN: errno_t = 38;
75pub const ENETRESET: errno_t = 39;
76pub const ENETUNREACH: errno_t = 40;
77pub const ENFILE: errno_t = 41;
78pub const ENOBUFS: errno_t = 42;
79pub const ENODEV: errno_t = 43;
80pub const ENOENT: errno_t = 44;
81pub const ENOEXEC: errno_t = 45;
82pub const ENOLCK: errno_t = 46;
83pub const ENOLINK: errno_t = 47;
84pub const ENOMEM: errno_t = 48;
85pub const ENOMSG: errno_t = 49;
86pub const ENOPROTOOPT: errno_t = 50;
87pub const ENOSPC: errno_t = 51;
88pub const ENOSYS: errno_t = 52;
89pub const ENOTCONN: errno_t = 53;
90pub const ENOTDIR: errno_t = 54;
91pub const ENOTEMPTY: errno_t = 55;
92pub const ENOTRECOVERABLE: errno_t = 56;
93pub const ENOTSOCK: errno_t = 57;
94pub const ENOTSUP: errno_t = 58;
95pub const ENOTTY: errno_t = 59;
96pub const ENXIO: errno_t = 60;
97pub const EOVERFLOW: errno_t = 61;
98pub const EOWNERDEAD: errno_t = 62;
99pub const EPERM: errno_t = 63;
100pub const EPIPE: errno_t = 64;
101pub const EPROTO: errno_t = 65;
102pub const EPROTONOSUPPORT: errno_t = 66;
103pub const EPROTOTYPE: errno_t = 67;
104pub const ERANGE: errno_t = 68;
105pub const EROFS: errno_t = 69;
106pub const ESPIPE: errno_t = 70;
107pub const ESRCH: errno_t = 71;
108pub const ESTALE: errno_t = 72;
109pub const ETIMEDOUT: errno_t = 73;
110pub const ETXTBSY: errno_t = 74;
111pub const EXDEV: errno_t = 75;
112pub const ENOTCAPABLE: errno_t = 76;
113
114pub const event_t = extern struct {
115 userdata: userdata_t,
116 @"error": errno_t,
117 @"type": eventtype_t,
118 u: extern union {
119 fd_readwrite: extern struct {
120 nbytes: filesize_t,
121 flags: eventrwflags_t,
122 },
123 },
124};
125
126pub const eventrwflags_t = u16;
127pub const EVENT_FD_READWRITE_HANGUP: eventrwflags_t = 0x0001;
128
129pub const eventtype_t = u8;
130pub const EVENTTYPE_CLOCK: eventtype_t = 0;
131pub const EVENTTYPE_FD_READ: eventtype_t = 1;
132pub const EVENTTYPE_FD_WRITE: eventtype_t = 2;
133
134pub const exitcode_t = u32;
135
136pub const fd_t = u32;
137
138pub const fdflags_t = u16;
139pub const FDFLAG_APPEND: fdflags_t = 0x0001;
140pub const FDFLAG_DSYNC: fdflags_t = 0x0002;
141pub const FDFLAG_NONBLOCK: fdflags_t = 0x0004;
142pub const FDFLAG_RSYNC: fdflags_t = 0x0008;
143pub const FDFLAG_SYNC: fdflags_t = 0x0010;
144
145const fdstat_t = extern struct {
146 fs_filetype: filetype_t,
147 fs_flags: fdflags_t,
148 fs_rights_base: rights_t,
149 fs_rights_inheriting: rights_t,
150};
151
152pub const filedelta_t = i64;
153
154pub const filesize_t = u64;
155
156pub const filestat_t = extern struct {
157 st_dev: device_t,
158 st_ino: inode_t,
159 st_filetype: filetype_t,
160 st_nlink: linkcount_t,
161 st_size: filesize_t,
162 st_atim: timestamp_t,
163 st_mtim: timestamp_t,
164 st_ctim: timestamp_t,
165};
166
167pub const filetype_t = u8;
168pub const FILETYPE_UNKNOWN: filetype_t = 0;
169pub const FILETYPE_BLOCK_DEVICE: filetype_t = 1;
170pub const FILETYPE_CHARACTER_DEVICE: filetype_t = 2;
171pub const FILETYPE_DIRECTORY: filetype_t = 3;
172pub const FILETYPE_REGULAR_FILE: filetype_t = 4;
173pub const FILETYPE_SOCKET_DGRAM: filetype_t = 5;
174pub const FILETYPE_SOCKET_STREAM: filetype_t = 6;
175pub const FILETYPE_SYMBOLIC_LINK: filetype_t = 7;
176
177pub const fstflags_t = u16;
178pub const FILESTAT_SET_ATIM: fstflags_t = 0x0001;
179pub const FILESTAT_SET_ATIM_NOW: fstflags_t = 0x0002;
180pub const FILESTAT_SET_MTIM: fstflags_t = 0x0004;
181pub const FILESTAT_SET_MTIM_NOW: fstflags_t = 0x0008;
182
183pub const inode_t = u64;
184
185pub const iovec_t = extern struct {
186 buf: [*]u8,
187 buf_len: usize,
188};
189
190pub const linkcount_t = u32;
191
192pub const lookupflags_t = u32;
193pub const LOOKUP_SYMLINK_FOLLOW: lookupflags_t = 0x00000001;
194
195pub const oflags_t = u16;
196pub const O_CREAT: oflags_t = 0x0001;
197pub const O_DIRECTORY: oflags_t = 0x0002;
198pub const O_EXCL: oflags_t = 0x0004;
199pub const O_TRUNC: oflags_t = 0x0008;
200
201pub const preopentype_t = u8;
202pub const PREOPENTYPE_DIR: preopentype_t = 0;
203
204pub const prestat_t = extern struct {
205 pr_type: preopentype_t,
206 u: extern union {
207 dir: extern struct {
208 pr_name_len: usize,
209 },
210 },
211};
212
213pub const riflags_t = u16;
214pub const SOCK_RECV_PEEK: riflags_t = 0x0001;
215pub const SOCK_RECV_WAITALL: riflags_t = 0x0002;
216
217pub const rights_t = u64;
218pub const RIGHT_FD_DATASYNC: rights_t = 0x0000000000000001;
219pub const RIGHT_FD_READ: rights_t = 0x0000000000000002;
220pub const RIGHT_FD_SEEK: rights_t = 0x0000000000000004;
221pub const RIGHT_FD_FDSTAT_SET_FLAGS: rights_t = 0x0000000000000008;
222pub const RIGHT_FD_SYNC: rights_t = 0x0000000000000010;
223pub const RIGHT_FD_TELL: rights_t = 0x0000000000000020;
224pub const RIGHT_FD_WRITE: rights_t = 0x0000000000000040;
225pub const RIGHT_FD_ADVISE: rights_t = 0x0000000000000080;
226pub const RIGHT_FD_ALLOCATE: rights_t = 0x0000000000000100;
227pub const RIGHT_PATH_CREATE_DIRECTORY: rights_t = 0x0000000000000200;
228pub const RIGHT_PATH_CREATE_FILE: rights_t = 0x0000000000000400;
229pub const RIGHT_PATH_LINK_SOURCE: rights_t = 0x0000000000000800;
230pub const RIGHT_PATH_LINK_TARGET: rights_t = 0x0000000000001000;
231pub const RIGHT_PATH_OPEN: rights_t = 0x0000000000002000;
232pub const RIGHT_FD_READDIR: rights_t = 0x0000000000004000;
233pub const RIGHT_PATH_READLINK: rights_t = 0x0000000000008000;
234pub const RIGHT_PATH_RENAME_SOURCE: rights_t = 0x0000000000010000;
235pub const RIGHT_PATH_RENAME_TARGET: rights_t = 0x0000000000020000;
236pub const RIGHT_PATH_FILESTAT_GET: rights_t = 0x0000000000040000;
237pub const RIGHT_PATH_FILESTAT_SET_SIZE: rights_t = 0x0000000000080000;
238pub const RIGHT_PATH_FILESTAT_SET_TIMES: rights_t = 0x0000000000100000;
239pub const RIGHT_FD_FILESTAT_GET: rights_t = 0x0000000000200000;
240pub const RIGHT_FD_FILESTAT_SET_SIZE: rights_t = 0x0000000000400000;
241pub const RIGHT_FD_FILESTAT_SET_TIMES: rights_t = 0x0000000000800000;
242pub const RIGHT_PATH_SYMLINK: rights_t = 0x0000000001000000;
243pub const RIGHT_PATH_REMOVE_DIRECTORY: rights_t = 0x0000000002000000;
244pub const RIGHT_PATH_UNLINK_FILE: rights_t = 0x0000000004000000;
245pub const RIGHT_POLL_FD_READWRITE: rights_t = 0x0000000008000000;
246pub const RIGHT_SOCK_SHUTDOWN: rights_t = 0x0000000010000000;
247
248pub const roflags_t = u16;
249pub const SOCK_RECV_DATA_TRUNCATED: roflags_t = 0x0001;
250
251pub const sdflags_t = u8;
252pub const SHUT_RD: sdflags_t = 0x01;
253pub const SHUT_WR: sdflags_t = 0x02;
254
255pub const siflags_t = u16;
256
257pub const signal_t = u8;
258pub const SIGHUP: signal_t = 1;
259pub const SIGINT: signal_t = 2;
260pub const SIGQUIT: signal_t = 3;
261pub const SIGILL: signal_t = 4;
262pub const SIGTRAP: signal_t = 5;
263pub const SIGABRT: signal_t = 6;
264pub const SIGBUS: signal_t = 7;
265pub const SIGFPE: signal_t = 8;
266pub const SIGKILL: signal_t = 9;
267pub const SIGUSR1: signal_t = 10;
268pub const SIGSEGV: signal_t = 11;
269pub const SIGUSR2: signal_t = 12;
270pub const SIGPIPE: signal_t = 13;
271pub const SIGALRM: signal_t = 14;
272pub const SIGTERM: signal_t = 15;
273pub const SIGCHLD: signal_t = 16;
274pub const SIGCONT: signal_t = 17;
275pub const SIGSTOP: signal_t = 18;
276pub const SIGTSTP: signal_t = 19;
277pub const SIGTTIN: signal_t = 20;
278pub const SIGTTOU: signal_t = 21;
279pub const SIGURG: signal_t = 22;
280pub const SIGXCPU: signal_t = 23;
281pub const SIGXFSZ: signal_t = 24;
282pub const SIGVTALRM: signal_t = 25;
283pub const SIGPROF: signal_t = 26;
284pub const SIGWINCH: signal_t = 27;
285pub const SIGPOLL: signal_t = 28;
286pub const SIGPWR: signal_t = 29;
287pub const SIGSYS: signal_t = 30;
288
289pub const subclockflags_t = u16;
290pub const SUBSCRIPTION_CLOCK_ABSTIME: subclockflags_t = 0x0001;
291
292pub const subscription_t = extern struct {
293 userdata: userdata_t,
294 @"type": eventtype_t,
295 u: extern union {
296 clock: extern struct {
297 identifier: userdata_t,
298 clock_id: clockid_t,
299 timeout: timestamp_t,
300 precision: timestamp_t,
301 flags: subclockflags_t,
302 },
303 fd_readwrite: extern struct {
304 fd: fd_t,
305 },
306 },
307};
308
309pub const timestamp_t = u64;
310
311pub const userdata_t = u64;
312
313pub const whence_t = u8;
314pub const WHENCE_CUR: whence_t = 0;
315pub const WHENCE_END: whence_t = 1;
316pub const WHENCE_SET: whence_t = 2;
317
318pub extern "wasi_unstable" fn args_get(argv: [*][*]u8, argv_buf: [*]u8) errno_t;
319pub extern "wasi_unstable" fn args_sizes_get(argc: *usize, argv_buf_size: *usize) errno_t;
320
321pub extern "wasi_unstable" fn clock_res_get(clock_id: clockid_t, resolution: *timestamp_t) errno_t;
322pub extern "wasi_unstable" fn clock_time_get(clock_id: clockid_t, precision: timestamp_t, timestamp: *timestamp_t) errno_t;
323
324pub extern "wasi_unstable" fn environ_get(environ: [*]?[*]u8, environ_buf: [*]u8) errno_t;
325pub extern "wasi_unstable" fn environ_sizes_get(environ_count: *usize, environ_buf_size: *usize) errno_t;
326
327pub extern "wasi_unstable" fn fd_advise(fd: fd_t, offset: filesize_t, len: filesize_t, advice: advice_t) errno_t;
328pub extern "wasi_unstable" fn fd_allocate(fd: fd_t, offset: filesize_t, len: filesize_t) errno_t;
329pub extern "wasi_unstable" fn fd_close(fd: fd_t) errno_t;
330pub extern "wasi_unstable" fn fd_datasync(fd: fd_t) errno_t;
331pub extern "wasi_unstable" fn fd_pread(fd: fd_t, iovs: *const iovec_t, iovs_len: usize, offset: filesize_t, nread: *usize) errno_t;
332pub extern "wasi_unstable" fn fd_pwrite(fd: fd_t, iovs: *const ciovec_t, iovs_len: usize, offset: filesize_t, nwritten: *usize) errno_t;
333pub extern "wasi_unstable" fn fd_read(fd: fd_t, iovs: *const iovec_t, iovs_len: usize, nread: *usize) errno_t;
334pub extern "wasi_unstable" fn fd_readdir(fd: fd_t, buf: [*]u8, buf_len: usize, cookie: dircookie_t, bufused: *usize) errno_t;
335pub extern "wasi_unstable" fn fd_renumber(from: fd_t, to: fd_t) errno_t;
336pub extern "wasi_unstable" fn fd_seek(fd: fd_t, offset: filedelta_t, whence: whence_t, newoffset: *filesize_t) errno_t;
337pub extern "wasi_unstable" fn fd_sync(fd: fd_t) errno_t;
338pub extern "wasi_unstable" fn fd_tell(fd: fd_t, newoffset: *filesize_t) errno_t;
339pub extern "wasi_unstable" fn fd_write(fd: fd_t, iovs: *const ciovec_t, iovs_len: usize, nwritten: *usize) errno_t;
340
341pub extern "wasi_unstable" fn fd_fdstat_get(fd: fd_t, buf: *fdstat_t) errno_t;
342pub extern "wasi_unstable" fn fd_fdstat_set_flags(fd: fd_t, flags: fdflags_t) errno_t;
343pub extern "wasi_unstable" fn fd_fdstat_set_rights(fd: fd_t, fs_rights_base: rights_t, fs_rights_inheriting: rights_t) errno_t;
344
345pub extern "wasi_unstable" fn fd_filestat_get(fd: fd_t, buf: *filestat_t) errno_t;
346pub extern "wasi_unstable" fn fd_filestat_set_size(fd: fd_t, st_size: filesize_t) errno_t;
347pub extern "wasi_unstable" fn fd_filestat_set_times(fd: fd_t, st_atim: timestamp_t, st_mtim: timestamp_t, fstflags: fstflags_t) errno_t;
348
349pub extern "wasi_unstable" fn fd_prestat_get(fd: fd_t, buf: *prestat_t) errno_t;
350pub extern "wasi_unstable" fn fd_prestat_dir_name(fd: fd_t, path: [*]u8, path_len: usize) errno_t;
351
352pub extern "wasi_unstable" fn path_create_directory(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
353pub extern "wasi_unstable" fn path_filestat_get(fd: fd_t, flags: lookupflags_t, path: [*]const u8, path_len: usize, buf: *filestat_t) errno_t;
354pub extern "wasi_unstable" fn path_filestat_set_times(fd: fd_t, flags: lookupflags_t, path: [*]const u8, path_len: usize, st_atim: timestamp_t, st_mtim: timestamp_t, fstflags: fstflags_t) errno_t;
355pub extern "wasi_unstable" fn path_link(old_fd: fd_t, old_flags: lookupflags_t, old_path: [*]const u8, old_path_len: usize, new_fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
356pub extern "wasi_unstable" fn path_open(dirfd: fd_t, dirflags: lookupflags_t, path: [*]const u8, path_len: usize, oflags: oflags_t, fs_rights_base: rights_t, fs_rights_inheriting: rights_t, fs_flags: fdflags_t, fd: *fd_t) errno_t;
357pub extern "wasi_unstable" fn path_readlink(fd: fd_t, path: [*]const u8, path_len: usize, buf: [*]u8, buf_len: usize, bufused: *usize) errno_t;
358pub extern "wasi_unstable" fn path_remove_directory(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
359pub extern "wasi_unstable" fn path_rename(old_fd: fd_t, old_path: [*]const u8, old_path_len: usize, new_fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
360pub extern "wasi_unstable" fn path_symlink(old_path: [*]const u8, old_path_len: usize, fd: fd_t, new_path: [*]const u8, new_path_len: usize) errno_t;
361pub extern "wasi_unstable" fn path_unlink_file(fd: fd_t, path: [*]const u8, path_len: usize) errno_t;
362
363pub extern "wasi_unstable" fn poll_oneoff(in: *const subscription_t, out: *event_t, nsubscriptions: usize, nevents: *usize) errno_t;
364
365pub extern "wasi_unstable" fn proc_exit(rval: exitcode_t) noreturn;
366pub extern "wasi_unstable" fn proc_raise(sig: signal_t) errno_t;
367
368pub extern "wasi_unstable" fn random_get(buf: [*]u8, buf_len: usize) errno_t;
369
370pub extern "wasi_unstable" fn sched_yield() errno_t;
371
372pub extern "wasi_unstable" fn sock_recv(sock: fd_t, ri_data: *const iovec_t, ri_data_len: usize, ri_flags: riflags_t, ro_datalen: *usize, ro_flags: *roflags_t) errno_t;
373pub extern "wasi_unstable" fn sock_send(sock: fd_t, si_data: *const ciovec_t, si_data_len: usize, si_flags: siflags_t, so_datalen: *usize) errno_t;
374pub extern "wasi_unstable" fn sock_shutdown(sock: fd_t, how: sdflags_t) errno_t;
std/os/windows.zig+31
......@@ -239,6 +239,37 @@ pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
239239pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
240240pub const HEAP_NO_SERIALIZE = 0x00000001;
241241
242// AllocationType values
243pub const MEM_COMMIT = 0x1000;
244pub const MEM_RESERVE = 0x2000;
245pub const MEM_RESET = 0x80000;
246pub const MEM_RESET_UNDO = 0x1000000;
247pub const MEM_LARGE_PAGES = 0x20000000;
248pub const MEM_PHYSICAL = 0x400000;
249pub const MEM_TOP_DOWN = 0x100000;
250pub const MEM_WRITE_WATCH = 0x200000;
251
252// Protect values
253pub const PAGE_EXECUTE = 0x10;
254pub const PAGE_EXECUTE_READ = 0x20;
255pub const PAGE_EXECUTE_READWRITE = 0x40;
256pub const PAGE_EXECUTE_WRITECOPY = 0x80;
257pub const PAGE_NOACCESS = 0x01;
258pub const PAGE_READONLY = 0x02;
259pub const PAGE_READWRITE = 0x04;
260pub const PAGE_WRITECOPY = 0x08;
261pub const PAGE_TARGETS_INVALID = 0x40000000;
262pub const PAGE_TARGETS_NO_UPDATE = 0x40000000; // Same as PAGE_TARGETS_INVALID
263pub const PAGE_GUARD = 0x100;
264pub const PAGE_NOCACHE = 0x200;
265pub const PAGE_WRITECOMBINE = 0x400;
266
267// FreeType values
268pub const MEM_COALESCE_PLACEHOLDERS = 0x1;
269pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
270pub const MEM_DECOMMIT = 0x4000;
271pub const MEM_RELEASE = 0x8000;
272
242273pub const PTHREAD_START_ROUTINE = extern fn (LPVOID) DWORD;
243274pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
244275
std/os/windows/kernel32.zig+3
......@@ -116,6 +116,9 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem
116116
117117pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL;
118118
119pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID;
120pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL;
121
119122pub extern "kernel32" stdcallcc fn MoveFileExW(
120123 lpExistingFileName: [*]const u16,
121124 lpNewFileName: [*]const u16,
std/packed_int_array.zig created+649
......@@ -0,0 +1,649 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const debug = std.debug;
4const testing = std.testing;
5
6pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
7 //The general technique employed here is to cast bytes in the array to a container
8 // integer (having bits % 8 == 0) large enough to contain the number of bits we want,
9 // then we can retrieve or store the new value with a relative minimum of masking
10 // and shifting. In this worst case, this means that we'll need an integer that's
11 // actually 1 byte larger than the minimum required to store the bits, because it
12 // is possible that the bits start at the end of the first byte, continue through
13 // zero or more, then end in the beginning of the last. But, if we try to access
14 // a value in the very last byte of memory with that integer size, that extra byte
15 // will be out of bounds. Depending on the circumstances of the memory, that might
16 // mean the OS fatally kills the program. Thus, we use a larger container (MaxIo)
17 // most of the time, but a smaller container (MinIo) when touching the last byte
18 // of the memory.
19 const int_bits = comptime std.meta.bitCount(Int);
20
21 //in the best case, this is the number of bytes we need to touch
22 // to read or write a value, as bits
23 const min_io_bits = ((int_bits + 7) / 8) * 8;
24
25 //in the worst case, this is the number of bytes we need to touch
26 // to read or write a value, as bits
27 const max_io_bits = switch (int_bits) {
28 0 => 0,
29 1 => 8,
30 2...9 => 16,
31 10...65535 => ((int_bits / 8) + 2) * 8,
32 else => unreachable,
33 };
34
35 //we bitcast the desired Int type to an unsigned version of itself
36 // to avoid issues with shifting signed ints.
37 const UnInt = @IntType(false, int_bits);
38
39 //The maximum container int type
40 const MinIo = @IntType(false, min_io_bits);
41
42 //The minimum container int type
43 const MaxIo = @IntType(false, max_io_bits);
44
45 return struct {
46 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {
47 if (int_bits == 0) return 0;
48
49 const bit_index = (index * int_bits) + bit_offset;
50 const max_end_byte = (bit_index + max_io_bits) / 8;
51
52 //Using the larger container size will potentially read out of bounds
53 if (max_end_byte > bytes.len) return getBits(bytes, MinIo, bit_index);
54 return getBits(bytes, MaxIo, bit_index);
55 }
56
57 fn getBits(bytes: []const u8, comptime Container: type, bit_index: usize) Int {
58 const container_bits = comptime std.meta.bitCount(Container);
59 const Shift = std.math.Log2Int(Container);
60
61 const start_byte = bit_index / 8;
62 const head_keep_bits = bit_index - (start_byte * 8);
63 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
64
65 //read bytes as container
66 const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]);
67 var value = value_ptr.*;
68
69 if (endian != builtin.endian) value = @bswap(Container, value);
70
71 switch (endian) {
72 .Big => {
73 value <<= @intCast(Shift, head_keep_bits);
74 value >>= @intCast(Shift, head_keep_bits);
75 value >>= @intCast(Shift, tail_keep_bits);
76 },
77 .Little => {
78 value <<= @intCast(Shift, tail_keep_bits);
79 value >>= @intCast(Shift, tail_keep_bits);
80 value >>= @intCast(Shift, head_keep_bits);
81 },
82 }
83
84 return @bitCast(Int, @truncate(UnInt, value));
85 }
86
87 pub fn set(bytes: []u8, index: usize, bit_offset: u3, int: Int) void {
88 if (int_bits == 0) return;
89
90 const bit_index = (index * int_bits) + bit_offset;
91 const max_end_byte = (bit_index + max_io_bits) / 8;
92
93 //Using the larger container size will potentially write out of bounds
94 if (max_end_byte > bytes.len) return setBits(bytes, MinIo, bit_index, int);
95 setBits(bytes, MaxIo, bit_index, int);
96 }
97
98 fn setBits(bytes: []u8, comptime Container: type, bit_index: usize, int: Int) void {
99 const container_bits = comptime std.meta.bitCount(Container);
100 const Shift = std.math.Log2Int(Container);
101
102 const start_byte = bit_index / 8;
103 const head_keep_bits = bit_index - (start_byte * 8);
104 const tail_keep_bits = container_bits - (int_bits + head_keep_bits);
105 const keep_shift = switch (endian) {
106 .Big => @intCast(Shift, tail_keep_bits),
107 .Little => @intCast(Shift, head_keep_bits),
108 };
109
110 //position the bits where they need to be in the container
111 const value = @intCast(Container, @bitCast(UnInt, int)) << keep_shift;
112
113 //read existing bytes
114 const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);
115 var target = target_ptr.*;
116
117 if (endian != builtin.endian) target = @bswap(Container, target);
118
119 //zero the bits we want to replace in the existing bytes
120 const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift;
121 const mask = ~inv_mask;
122 target &= mask;
123
124 //merge the new value
125 target |= value;
126
127 if (endian != builtin.endian) target = @bswap(Container, target);
128
129 //save it back
130 target_ptr.* = target;
131 }
132
133 fn slice(bytes: []u8, bit_offset: u3, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
134 debug.assert(end >= start);
135
136 const length = end - start;
137 const bit_index = (start * int_bits) + bit_offset;
138 const start_byte = bit_index / 8;
139 const end_byte = (bit_index + (length * int_bits) + 7) / 8;
140 const new_bytes = bytes[start_byte..end_byte];
141
142 if (length == 0) return PackedIntSliceEndian(Int, endian).init(new_bytes[0..0], 0);
143
144 var new_slice = PackedIntSliceEndian(Int, endian).init(new_bytes, length);
145 new_slice.bit_offset = @intCast(u3, (bit_index - (start_byte * 8)));
146 return new_slice;
147 }
148
149 fn sliceCast(bytes: []u8, comptime NewInt: type, comptime new_endian: builtin.Endian, bit_offset: u3, old_len: usize) PackedIntSliceEndian(NewInt, new_endian) {
150 const new_int_bits = comptime std.meta.bitCount(NewInt);
151 const New = PackedIntSliceEndian(NewInt, new_endian);
152
153 const total_bits = (old_len * int_bits);
154 const new_int_count = total_bits / new_int_bits;
155
156 debug.assert(total_bits == new_int_count * new_int_bits);
157
158 var new = New.init(bytes, new_int_count);
159 new.bit_offset = bit_offset;
160
161 return new;
162 }
163 };
164}
165
166///Creates a bit-packed array of integers of type Int. Bits
167/// are packed using native endianess and without storing any meta
168/// data. PackedIntArray(i3, 8) will occupy exactly 3 bytes of memory.
169pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type {
170 return PackedIntArrayEndian(Int, builtin.endian, int_count);
171}
172
173///Creates a bit-packed array of integers of type Int. Bits
174/// are packed using specified endianess and without storing any meta
175/// data.
176pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, comptime int_count: usize) type {
177 const int_bits = comptime std.meta.bitCount(Int);
178 const total_bits = int_bits * int_count;
179 const total_bytes = (total_bits + 7) / 8;
180
181 const Io = PackedIntIo(Int, endian);
182
183 return struct {
184 const Self = @This();
185
186 bytes: [total_bytes]u8,
187
188 ///Returns the number of elements in the packed array
189 pub fn len(self: Self) usize {
190 return int_count;
191 }
192
193 ///Initialize a packed array using an unpacked array
194 /// or, more likely, an array literal.
195 pub fn init(ints: [int_count]Int) Self {
196 var self = Self(undefined);
197 for (ints) |int, i| self.set(i, int);
198 return self;
199 }
200
201 ///Return the Int stored at index
202 pub fn get(self: Self, index: usize) Int {
203 debug.assert(index < int_count);
204 return Io.get(self.bytes, index, 0);
205 }
206
207 ///Copy int into the array at index
208 pub fn set(self: *Self, index: usize, int: Int) void {
209 debug.assert(index < int_count);
210 return Io.set(&self.bytes, index, 0, int);
211 }
212
213 ///Create a PackedIntSlice of the array from given start to given end
214 pub fn slice(self: *Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
215 debug.assert(start < int_count);
216 debug.assert(end <= int_count);
217 return Io.slice(&self.bytes, 0, start, end);
218 }
219
220 ///Create a PackedIntSlice of the array using NewInt as the bit width integer.
221 /// NewInt's bit width must fit evenly within the array's Int's total bits.
222 pub fn sliceCast(self: *Self, comptime NewInt: type) PackedIntSlice(NewInt) {
223 return self.sliceCastEndian(NewInt, endian);
224 }
225
226 ///Create a PackedIntSlice of the array using NewInt as the bit width integer
227 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within
228 /// the array's Int's total bits.
229 pub fn sliceCastEndian(self: *Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) {
230 return Io.sliceCast(&self.bytes, NewInt, new_endian, 0, int_count);
231 }
232 };
233}
234
235///Uses a slice as a bit-packed block of int_count integers of type Int.
236/// Bits are packed using native endianess and without storing any meta
237/// data.
238pub fn PackedIntSlice(comptime Int: type) type {
239 return PackedIntSliceEndian(Int, builtin.endian);
240}
241
242///Uses a slice as a bit-packed block of int_count integers of type Int.
243/// Bits are packed using specified endianess and without storing any meta
244/// data.
245pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: builtin.Endian) type {
246 const int_bits = comptime std.meta.bitCount(Int);
247 const Io = PackedIntIo(Int, endian);
248
249 return struct {
250 const Self = @This();
251
252 bytes: []u8,
253 int_count: usize,
254 bit_offset: u3,
255
256 ///Returns the number of elements in the packed slice
257 pub fn len(self: Self) usize {
258 return self.int_count;
259 }
260
261 ///Calculates the number of bytes required to store a desired count
262 /// of Ints
263 pub fn bytesRequired(int_count: usize) usize {
264 const total_bits = int_bits * int_count;
265 const total_bytes = (total_bits + 7) / 8;
266 return total_bytes;
267 }
268
269 ///Initialize a packed slice using the memory at bytes, with int_count
270 /// elements. bytes must be large enough to accomodate the requested
271 /// count.
272 pub fn init(bytes: []u8, int_count: usize) Self {
273 debug.assert(bytes.len >= bytesRequired(int_count));
274
275 return Self{
276 .bytes = bytes,
277 .int_count = int_count,
278 .bit_offset = 0,
279 };
280 }
281
282 ///Return the Int stored at index
283 pub fn get(self: Self, index: usize) Int {
284 debug.assert(index < self.int_count);
285 return Io.get(self.bytes, index, self.bit_offset);
286 }
287
288 ///Copy int into the array at index
289 pub fn set(self: *Self, index: usize, int: Int) void {
290 debug.assert(index < self.int_count);
291 return Io.set(self.bytes, index, self.bit_offset, int);
292 }
293
294 ///Create a PackedIntSlice of this slice from given start to given end
295 pub fn slice(self: Self, start: usize, end: usize) PackedIntSliceEndian(Int, endian) {
296 debug.assert(start < self.int_count);
297 debug.assert(end <= self.int_count);
298 return Io.slice(self.bytes, self.bit_offset, start, end);
299 }
300
301 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer.
302 /// NewInt's bit width must fit evenly within this slice's Int's total bits.
303 pub fn sliceCast(self: Self, comptime NewInt: type) PackedIntSliceEndian(NewInt, endian) {
304 return self.sliceCastEndian(NewInt, endian);
305 }
306
307 ///Create a PackedIntSlice of this slice using NewInt as the bit width integer
308 /// and new_endian as the new endianess. NewInt's bit width must fit evenly within
309 /// this slice's Int's total bits.
310 pub fn sliceCastEndian(self: Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) {
311 return Io.sliceCast(self.bytes, NewInt, new_endian, self.bit_offset, self.int_count);
312 }
313 };
314}
315
316test "PackedIntArray" {
317 @setEvalBranchQuota(10000);
318 const max_bits = 256;
319 const int_count = 19;
320
321 comptime var bits = 0;
322 inline while (bits <= 256) : (bits += 1) {
323 //alternate unsigned and signed
324 const even = bits % 2 == 0;
325 const I = @IntType(even, bits);
326
327 const PackedArray = PackedIntArray(I, int_count);
328 const expected_bytes = ((bits * int_count) + 7) / 8;
329 testing.expect(@sizeOf(PackedArray) == expected_bytes);
330
331 var data = PackedArray(undefined);
332
333 //write values, counting up
334 var i = usize(0);
335 var count = I(0);
336 while (i < data.len()) : (i += 1) {
337 data.set(i, count);
338 if (bits > 0) count +%= 1;
339 }
340
341 //read and verify values
342 i = 0;
343 count = 0;
344 while (i < data.len()) : (i += 1) {
345 const val = data.get(i);
346 testing.expect(val == count);
347 if (bits > 0) count +%= 1;
348 }
349 }
350}
351
352test "PackedIntArray init" {
353 const PackedArray = PackedIntArray(u3, 8);
354 var packed_array = PackedArray.init([]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });
355 var i = usize(0);
356 while (i < packed_array.len()) : (i += 1) testing.expect(packed_array.get(i) == i);
357}
358
359test "PackedIntSlice" {
360 @setEvalBranchQuota(10000);
361 const max_bits = 256;
362 const int_count = 19;
363 const total_bits = max_bits * int_count;
364 const total_bytes = (total_bits + 7) / 8;
365
366 var buffer: [total_bytes]u8 = undefined;
367
368 comptime var bits = 0;
369 inline while (bits <= 256) : (bits += 1) {
370 //alternate unsigned and signed
371 const even = bits % 2 == 0;
372 const I = @IntType(even, bits);
373 const P = PackedIntSlice(I);
374
375 var data = P.init(&buffer, int_count);
376
377 //write values, counting up
378 var i = usize(0);
379 var count = I(0);
380 while (i < data.len()) : (i += 1) {
381 data.set(i, count);
382 if (bits > 0) count +%= 1;
383 }
384
385 //read and verify values
386 i = 0;
387 count = 0;
388 while (i < data.len()) : (i += 1) {
389 const val = data.get(i);
390 testing.expect(val == count);
391 if (bits > 0) count +%= 1;
392 }
393 }
394}
395
396test "PackedIntSlice of PackedInt(Array/Slice)" {
397 const max_bits = 16;
398 const int_count = 19;
399
400 comptime var bits = 0;
401 inline while (bits <= max_bits) : (bits += 1) {
402 const Int = @IntType(false, bits);
403
404 const PackedArray = PackedIntArray(Int, int_count);
405 var packed_array = PackedArray(undefined);
406
407 const limit = (1 << bits);
408
409 var i = usize(0);
410 while (i < packed_array.len()) : (i += 1) {
411 packed_array.set(i, @intCast(Int, i % limit));
412 }
413
414 //slice of array
415 var packed_slice = packed_array.slice(2, 5);
416 testing.expect(packed_slice.len() == 3);
417 const ps_bit_count = (bits * packed_slice.len()) + packed_slice.bit_offset;
418 const ps_expected_bytes = (ps_bit_count + 7) / 8;
419 testing.expect(packed_slice.bytes.len == ps_expected_bytes);
420 testing.expect(packed_slice.get(0) == 2 % limit);
421 testing.expect(packed_slice.get(1) == 3 % limit);
422 testing.expect(packed_slice.get(2) == 4 % limit);
423 packed_slice.set(1, 7 % limit);
424 testing.expect(packed_slice.get(1) == 7 % limit);
425
426 //write through slice
427 testing.expect(packed_array.get(3) == 7 % limit);
428
429 //slice of a slice
430 const packed_slice_two = packed_slice.slice(0, 3);
431 testing.expect(packed_slice_two.len() == 3);
432 const ps2_bit_count = (bits * packed_slice_two.len()) + packed_slice_two.bit_offset;
433 const ps2_expected_bytes = (ps2_bit_count + 7) / 8;
434 testing.expect(packed_slice_two.bytes.len == ps2_expected_bytes);
435 testing.expect(packed_slice_two.get(1) == 7 % limit);
436 testing.expect(packed_slice_two.get(2) == 4 % limit);
437
438 //size one case
439 const packed_slice_three = packed_slice_two.slice(1, 2);
440 testing.expect(packed_slice_three.len() == 1);
441 const ps3_bit_count = (bits * packed_slice_three.len()) + packed_slice_three.bit_offset;
442 const ps3_expected_bytes = (ps3_bit_count + 7) / 8;
443 testing.expect(packed_slice_three.bytes.len == ps3_expected_bytes);
444 testing.expect(packed_slice_three.get(0) == 7 % limit);
445
446 //empty slice case
447 const packed_slice_empty = packed_slice.slice(0, 0);
448 testing.expect(packed_slice_empty.len() == 0);
449 testing.expect(packed_slice_empty.bytes.len == 0);
450
451 //slicing at byte boundaries
452 const packed_slice_edge = packed_array.slice(8, 16);
453 testing.expect(packed_slice_edge.len() == 8);
454 const pse_bit_count = (bits * packed_slice_edge.len()) + packed_slice_edge.bit_offset;
455 const pse_expected_bytes = (pse_bit_count + 7) / 8;
456 testing.expect(packed_slice_edge.bytes.len == pse_expected_bytes);
457 testing.expect(packed_slice_edge.bit_offset == 0);
458 }
459}
460
461test "PackedIntSlice accumulating bit offsets" {
462 //bit_offset is u3, so standard debugging asserts should catch
463 // anything
464 {
465 const PackedArray = PackedIntArray(u3, 16);
466 var packed_array = PackedArray(undefined);
467
468 var packed_slice = packed_array.slice(0, packed_array.len());
469 var i = usize(0);
470 while (i < packed_array.len() - 1) : (i += 1) {
471 packed_slice = packed_slice.slice(1, packed_slice.len());
472 }
473 }
474 {
475 const PackedArray = PackedIntArray(u11, 88);
476 var packed_array = PackedArray(undefined);
477
478 var packed_slice = packed_array.slice(0, packed_array.len());
479 var i = usize(0);
480 while (i < packed_array.len() - 1) : (i += 1) {
481 packed_slice = packed_slice.slice(1, packed_slice.len());
482 }
483 }
484}
485
486//@NOTE: As I do not have a big endian system to test this on,
487// big endian values were not tested
488test "PackedInt(Array/Slice) sliceCast" {
489 const PackedArray = PackedIntArray(u1, 16);
490 var packed_array = PackedArray.init([]u1{ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 });
491 const packed_slice_cast_2 = packed_array.sliceCast(u2);
492 const packed_slice_cast_4 = packed_slice_cast_2.sliceCast(u4);
493 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);
494 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);
495
496 var i = usize(0);
497 while (i < packed_slice_cast_2.len()) : (i += 1) {
498 const val = switch (builtin.endian) {
499 .Big => 0b01,
500 .Little => 0b10,
501 };
502 testing.expect(packed_slice_cast_2.get(i) == val);
503 }
504 i = 0;
505 while (i < packed_slice_cast_4.len()) : (i += 1) {
506 const val = switch (builtin.endian) {
507 .Big => 0b0101,
508 .Little => 0b1010,
509 };
510 testing.expect(packed_slice_cast_4.get(i) == val);
511 }
512 i = 0;
513 while (i < packed_slice_cast_9.len()) : (i += 1) {
514 const val = 0b010101010;
515 testing.expect(packed_slice_cast_9.get(i) == val);
516 packed_slice_cast_9.set(i, 0b111000111);
517 }
518 i = 0;
519 while (i < packed_slice_cast_3.len()) : (i += 1) {
520 const val = switch (builtin.endian) {
521 .Big => if (i % 2 == 0) u3(0b111) else u3(0b000),
522 .Little => if (i % 2 == 0) u3(0b111) else u3(0b000),
523 };
524 testing.expect(packed_slice_cast_3.get(i) == val);
525 }
526}
527
528test "PackedInt(Array/Slice)Endian" {
529 {
530 const PackedArrayBe = PackedIntArrayEndian(u4, .Big, 8);
531 var packed_array_be = PackedArrayBe.init([]u4{
532 0,
533 1,
534 2,
535 3,
536 4,
537 5,
538 6,
539 7,
540 });
541 testing.expect(packed_array_be.bytes[0] == 0b00000001);
542 testing.expect(packed_array_be.bytes[1] == 0b00100011);
543
544 var i = usize(0);
545 while (i < packed_array_be.len()) : (i += 1) {
546 testing.expect(packed_array_be.get(i) == i);
547 }
548
549 var packed_slice_le = packed_array_be.sliceCastEndian(u4, .Little);
550 i = 0;
551 while (i < packed_slice_le.len()) : (i += 1) {
552 const val = if (i % 2 == 0) i + 1 else i - 1;
553 testing.expect(packed_slice_le.get(i) == val);
554 }
555
556 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u4, .Little);
557 i = 0;
558 while (i < packed_slice_le_shift.len()) : (i += 1) {
559 const val = if (i % 2 == 0) i else i + 2;
560 testing.expect(packed_slice_le_shift.get(i) == val);
561 }
562 }
563
564 {
565 const PackedArrayBe = PackedIntArrayEndian(u11, .Big, 8);
566 var packed_array_be = PackedArrayBe.init([]u11{
567 0,
568 1,
569 2,
570 3,
571 4,
572 5,
573 6,
574 7,
575 });
576 testing.expect(packed_array_be.bytes[0] == 0b00000000);
577 testing.expect(packed_array_be.bytes[1] == 0b00000000);
578 testing.expect(packed_array_be.bytes[2] == 0b00000100);
579 testing.expect(packed_array_be.bytes[3] == 0b00000001);
580 testing.expect(packed_array_be.bytes[4] == 0b00000000);
581
582 var i = usize(0);
583 while (i < packed_array_be.len()) : (i += 1) {
584 testing.expect(packed_array_be.get(i) == i);
585 }
586
587 var packed_slice_le = packed_array_be.sliceCastEndian(u11, .Little);
588 testing.expect(packed_slice_le.get(0) == 0b00000000000);
589 testing.expect(packed_slice_le.get(1) == 0b00010000000);
590 testing.expect(packed_slice_le.get(2) == 0b00000000100);
591 testing.expect(packed_slice_le.get(3) == 0b00000000000);
592 testing.expect(packed_slice_le.get(4) == 0b00010000011);
593 testing.expect(packed_slice_le.get(5) == 0b00000000010);
594 testing.expect(packed_slice_le.get(6) == 0b10000010000);
595 testing.expect(packed_slice_le.get(7) == 0b00000111001);
596
597 var packed_slice_le_shift = packed_array_be.slice(1, 5).sliceCastEndian(u11, .Little);
598 testing.expect(packed_slice_le_shift.get(0) == 0b00010000000);
599 testing.expect(packed_slice_le_shift.get(1) == 0b00000000100);
600 testing.expect(packed_slice_le_shift.get(2) == 0b00000000000);
601 testing.expect(packed_slice_le_shift.get(3) == 0b00010000011);
602 }
603}
604
605//@NOTE: Need to manually update this list as more posix os's get
606// added to DirectAllocator. Windows can be added too when DirectAllocator
607// switches to VirtualAlloc.
608
609//These tests prove we aren't accidentally accessing memory past
610// the end of the array/slice by placing it at the end of a page
611// and reading the last element. The assumption is that the page
612// after this one is not mapped and will cause a segfault if we
613// don't account for the bounds.
614test "PackedIntArray at end of available memory" {
615 switch (builtin.os) {
616 .linux, .macosx, .ios, .freebsd, .netbsd => {},
617 else => return,
618 }
619 const PackedArray = PackedIntArray(u3, 8);
620
621 const Padded = struct {
622 _: [std.os.page_size - @sizeOf(PackedArray)]u8,
623 p: PackedArray,
624 };
625
626 var da = std.heap.DirectAllocator.init();
627 const allocator = &da.allocator;
628
629 var pad = try allocator.create(Padded);
630 defer allocator.destroy(pad);
631 pad.p.set(7, std.math.maxInt(u3));
632}
633
634test "PackedIntSlice at end of available memory" {
635 switch (builtin.os) {
636 .linux, .macosx, .ios, .freebsd, .netbsd => {},
637 else => return,
638 }
639 const PackedSlice = PackedIntSlice(u11);
640
641 var da = std.heap.DirectAllocator.init();
642 const allocator = &da.allocator;
643
644 var page = try allocator.alloc(u8, std.os.page_size);
645 defer allocator.free(page);
646
647 var p = PackedSlice.init(page[std.os.page_size - 2 ..], 1);
648 p.set(0, std.math.maxInt(u11));
649}
std/pdb.zig+7-6
......@@ -588,7 +588,7 @@ const SuperBlock = packed struct {
588588
589589const MsfStream = struct {
590590 in_file: os.File,
591 pos: usize,
591 pos: u64,
592592 blocks: []u32,
593593 block_size: u32,
594594
......@@ -598,7 +598,7 @@ const MsfStream = struct {
598598 pub const Error = @typeOf(read).ReturnType.ErrorSet;
599599 pub const Stream = io.InStream(Error);
600600
601 fn init(block_size: u32, block_count: u32, pos: usize, file: os.File, allocator: *mem.Allocator) !MsfStream {
601 fn init(block_size: u32, block_count: u32, pos: u64, file: os.File, allocator: *mem.Allocator) !MsfStream {
602602 var stream = MsfStream{
603603 .in_file = file,
604604 .pos = 0,
......@@ -660,23 +660,24 @@ const MsfStream = struct {
660660 return size;
661661 }
662662
663 fn seekForward(self: *MsfStream, len: usize) !void {
663 // XXX: The `len` parameter should be signed
664 fn seekForward(self: *MsfStream, len: u64) !void {
664665 self.pos += len;
665666 if (self.pos >= self.blocks.len * self.block_size)
666667 return error.EOF;
667668 }
668669
669 fn seekTo(self: *MsfStream, len: usize) !void {
670 fn seekTo(self: *MsfStream, len: u64) !void {
670671 self.pos = len;
671672 if (self.pos >= self.blocks.len * self.block_size)
672673 return error.EOF;
673674 }
674675
675 fn getSize(self: *const MsfStream) usize {
676 fn getSize(self: *const MsfStream) u64 {
676677 return self.blocks.len * self.block_size;
677678 }
678679
679 fn getFilePos(self: MsfStream) usize {
680 fn getFilePos(self: MsfStream) u64 {
680681 const block_id = self.pos / self.block_size;
681682 const block = self.blocks[block_id];
682683 const offset = self.pos % self.block_size;
std/rand.zig+2-2
......@@ -768,10 +768,10 @@ pub const Isaac64 = struct {
768768 const x = self.m[base + m1];
769769 self.a = mix +% self.m[base + m2];
770770
771 const y = self.a +% self.b +% self.m[(x >> 3) % self.m.len];
771 const y = self.a +% self.b +% self.m[@intCast(usize, (x >> 3) % self.m.len)];
772772 self.m[base + m1] = y;
773773
774 self.b = x +% self.m[(y >> 11) % self.m.len];
774 self.b = x +% self.m[@intCast(usize, (y >> 11) % self.m.len)];
775775 self.r[self.r.len - 1 - base - m1] = self.b;
776776 }
777777
std/special/bootstrap.zig+13-61
......@@ -20,6 +20,10 @@ comptime {
2020}
2121
2222nakedcc fn _start() noreturn {
23 if (builtin.os == builtin.Os.wasi) {
24 std.os.wasi.proc_exit(callMain());
25 }
26
2327 switch (builtin.arch) {
2428 builtin.Arch.x86_64 => {
2529 argc_ptr = asm ("lea (%%rsp), %[argc]"
......@@ -63,24 +67,19 @@ fn posixCallMainAndExit() noreturn {
6367 var envp_count: usize = 0;
6468 while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
6569 const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
70
6671 if (builtin.os == builtin.Os.linux) {
67 // Scan auxiliary vector.
72 // Find the beginning of the auxiliary vector
6873 const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
6974 std.os.linux_elf_aux_maybe = auxv;
70 var i: usize = 0;
71 var at_phdr: usize = 0;
72 var at_phnum: usize = 0;
73 var at_phent: usize = 0;
74 while (auxv[i].a_un.a_val != 0) : (i += 1) {
75 switch (auxv[i].a_type) {
76 std.elf.AT_PAGESZ => assert(auxv[i].a_un.a_val == std.os.page_size),
77 std.elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
78 std.elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
79 std.elf.AT_PHENT => at_phent = auxv[i].a_un.a_val,
80 else => {},
81 }
75 // Initialize the TLS area
76 std.os.linux.tls.initTLS();
77
78 if (std.os.linux.tls.tls_image) |tls_img| {
79 const tls_addr = std.os.linux.tls.allocateTLS(tls_img.alloc_size);
80 const tp = std.os.linux.tls.copyTLS(tls_addr);
81 std.os.linux.tls.setThreadPointer(tp);
8282 }
83 if (!builtin.single_threaded) linuxInitializeThreadLocalStorage(at_phdr, at_phnum, at_phent);
8483 }
8584
8685 std.os.posix.exit(callMainWithArgs(argc, argv, envp));
......@@ -136,50 +135,3 @@ inline fn callMain() u8 {
136135
137136const main_thread_tls_align = 32;
138137var main_thread_tls_bytes: [64]u8 align(main_thread_tls_align) = [1]u8{0} ** 64;
139
140fn linuxInitializeThreadLocalStorage(at_phdr: usize, at_phnum: usize, at_phent: usize) void {
141 var phdr_addr = at_phdr;
142 var n = at_phnum;
143 var base: usize = 0;
144 while (n != 0) : ({
145 n -= 1;
146 phdr_addr += at_phent;
147 }) {
148 const phdr = @intToPtr(*std.elf.Phdr, phdr_addr);
149 // TODO look for PT_DYNAMIC when we have https://github.com/ziglang/zig/issues/1917
150 switch (phdr.p_type) {
151 std.elf.PT_PHDR => base = at_phdr - phdr.p_vaddr,
152 std.elf.PT_TLS => std.os.linux_tls_phdr = phdr,
153 else => continue,
154 }
155 }
156 const tls_phdr = std.os.linux_tls_phdr orelse return;
157 std.os.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
158 const end_addr = @ptrToInt(&main_thread_tls_bytes) + tls_phdr.p_memsz;
159 const max_end_addr = @ptrToInt(&main_thread_tls_bytes) + main_thread_tls_bytes.len;
160 assert(max_end_addr >= end_addr + @sizeOf(usize)); // not enough preallocated Thread Local Storage
161 assert(main_thread_tls_align >= tls_phdr.p_align); // preallocated Thread Local Storage not aligned enough
162 @memcpy(&main_thread_tls_bytes, std.os.linux_tls_img_src, tls_phdr.p_filesz);
163 const end_ptr = @intToPtr(*usize, end_addr);
164 end_ptr.* = end_addr;
165 linuxSetThreadArea(end_addr);
166}
167
168fn linuxSetThreadArea(addr: usize) void {
169 switch (builtin.arch) {
170 builtin.Arch.x86_64 => {
171 const ARCH_SET_FS = 0x1002;
172 const rc = std.os.linux.syscall2(std.os.linux.SYS_arch_prctl, ARCH_SET_FS, addr);
173 // acrh_prctl is documented to never fail
174 assert(rc == 0);
175 },
176 builtin.Arch.aarch64 => {
177 asm volatile (
178 \\ msr tpidr_el0,x0
179 \\ mov w0,#0
180 \\ ret
181 );
182 },
183 else => @compileError("Unsupported architecture"),
184 }
185}
std/special/build_runner.zig+21-9
......@@ -94,6 +94,16 @@ pub fn main() !void {
9494 return usageAndErr(&builder, false, try stderr_stream);
9595 });
9696 builder.addSearchPrefix(search_prefix);
97 } else if (mem.eql(u8, arg, "--override-std-dir")) {
98 builder.override_std_dir = try unwrapArg(arg_it.next(allocator) orelse {
99 warn("Expected argument after --override-std-dir\n\n");
100 return usageAndErr(&builder, false, try stderr_stream);
101 });
102 } else if (mem.eql(u8, arg, "--override-lib-dir")) {
103 builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse {
104 warn("Expected argument after --override-lib-dir\n\n");
105 return usageAndErr(&builder, false, try stderr_stream);
106 });
97107 } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
98108 builder.verbose_tokenize = true;
99109 } else if (mem.eql(u8, arg, "--verbose-ast")) {
......@@ -187,15 +197,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
187197 try out_stream.write(
188198 \\
189199 \\Advanced Options:
190 \\ --build-file [file] Override path to build.zig
191 \\ --cache-dir [path] Override path to zig cache directory
192 \\ --verbose-tokenize Enable compiler debug output for tokenization
193 \\ --verbose-ast Enable compiler debug output for parsing into an AST
194 \\ --verbose-link Enable compiler debug output for linking
195 \\ --verbose-ir Enable compiler debug output for Zig IR
196 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
197 \\ --verbose-cimport Enable compiler debug output for C imports
198 \\ --verbose-cc Enable compiler debug output for C compilation
200 \\ --build-file [file] Override path to build.zig
201 \\ --cache-dir [path] Override path to zig cache directory
202 \\ --override-std-dir [arg] Override path to Zig standard library
203 \\ --override-lib-dir [arg] Override path to Zig lib directory
204 \\ --verbose-tokenize Enable compiler debug output for tokenization
205 \\ --verbose-ast Enable compiler debug output for parsing into an AST
206 \\ --verbose-link Enable compiler debug output for linking
207 \\ --verbose-ir Enable compiler debug output for Zig IR
208 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
209 \\ --verbose-cimport Enable compiler debug output for C imports
210 \\ --verbose-cc Enable compiler debug output for C compilation
199211 \\
200212 );
201213}
std/special/compiler_rt.zig+538-149
......@@ -5,20 +5,47 @@ comptime {
55 const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
66 const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
77
8 switch (builtin.arch) {
9 .i386, .x86_64 => @export("__zig_probe_stack", @import("compiler_rt/stack_probe.zig").zig_probe_stack, linkage),
10 else => {},
11 }
12
13 @export("__lesf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);
14 @export("__ledf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage);
815 @export("__letf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
16
17 @export("__gesf2", @import("compiler_rt/comparesf2.zig").__gesf2, linkage);
18 @export("__gedf2", @import("compiler_rt/comparedf2.zig").__gedf2, linkage);
919 @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage);
1020
1121 if (!is_test) {
1222 // only create these aliases when not testing
23 @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);
24 @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage);
1325 @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
26
27 @export("__eqsf2", @import("compiler_rt/comparesf2.zig").__eqsf2, linkage);
28 @export("__eqdf2", @import("compiler_rt/comparedf2.zig").__eqdf2, linkage);
1429 @export("__eqtf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
30
31 @export("__ltsf2", @import("compiler_rt/comparesf2.zig").__ltsf2, linkage);
32 @export("__ltdf2", @import("compiler_rt/comparedf2.zig").__ltdf2, linkage);
1533 @export("__lttf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
34
35 @export("__nesf2", @import("compiler_rt/comparesf2.zig").__nesf2, linkage);
36 @export("__nedf2", @import("compiler_rt/comparedf2.zig").__nedf2, linkage);
1637 @export("__netf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
38
39 @export("__gtsf2", @import("compiler_rt/comparesf2.zig").__gtsf2, linkage);
40 @export("__gtdf2", @import("compiler_rt/comparedf2.zig").__gtdf2, linkage);
1741 @export("__gttf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage);
42
1843 @export("__gnu_h2f_ieee", @import("compiler_rt/extendXfYf2.zig").__extendhfsf2, linkage);
1944 @export("__gnu_f2h_ieee", @import("compiler_rt/truncXfYf2.zig").__truncsfhf2, linkage);
2045 }
2146
47 @export("__unordsf2", @import("compiler_rt/comparesf2.zig").__unordsf2, linkage);
48 @export("__unorddf2", @import("compiler_rt/comparedf2.zig").__unorddf2, linkage);
2249 @export("__unordtf2", @import("compiler_rt/comparetf2.zig").__unordtf2, linkage);
2350
2451 @export("__addsf3", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
......@@ -35,6 +62,17 @@ comptime {
3562 @export("__divsf3", @import("compiler_rt/divsf3.zig").__divsf3, linkage);
3663 @export("__divdf3", @import("compiler_rt/divdf3.zig").__divdf3, linkage);
3764
65 @export("__ashlti3", @import("compiler_rt/ashlti3.zig").__ashlti3, linkage);
66 @export("__lshrti3", @import("compiler_rt/lshrti3.zig").__lshrti3, linkage);
67 @export("__ashrti3", @import("compiler_rt/ashrti3.zig").__ashrti3, linkage);
68
69 @export("__floatsidf", @import("compiler_rt/floatsiXf.zig").__floatsidf, linkage);
70 @export("__floatsisf", @import("compiler_rt/floatsiXf.zig").__floatsisf, linkage);
71 @export("__floatdidf", @import("compiler_rt/floatdidf.zig").__floatdidf, linkage);
72 @export("__floatsitf", @import("compiler_rt/floatsiXf.zig").__floatsitf, linkage);
73 @export("__floatunsidf", @import("compiler_rt/floatunsidf.zig").__floatunsidf, linkage);
74 @export("__floatundidf", @import("compiler_rt/floatundidf.zig").__floatundidf, linkage);
75
3876 @export("__floattitf", @import("compiler_rt/floattitf.zig").__floattitf, linkage);
3977 @export("__floattidf", @import("compiler_rt/floattidf.zig").__floattidf, linkage);
4078 @export("__floattisf", @import("compiler_rt/floattisf.zig").__floattisf, linkage);
......@@ -55,6 +93,10 @@ comptime {
5593 @export("__trunctfdf2", @import("compiler_rt/truncXfYf2.zig").__trunctfdf2, linkage);
5694 @export("__trunctfsf2", @import("compiler_rt/truncXfYf2.zig").__trunctfsf2, linkage);
5795
96 @export("__truncdfsf2", @import("compiler_rt/truncXfYf2.zig").__truncdfsf2, linkage);
97
98 @export("__extendsfdf2", @import("compiler_rt/extendXfYf2.zig").__extendsfdf2, linkage);
99
58100 @export("__fixunssfsi", @import("compiler_rt/fixunssfsi.zig").__fixunssfsi, linkage);
59101 @export("__fixunssfdi", @import("compiler_rt/fixunssfdi.zig").__fixunssfdi, linkage);
60102 @export("__fixunssfti", @import("compiler_rt/fixunssfti.zig").__fixunssfti, linkage);
......@@ -80,18 +122,33 @@ comptime {
80122 @export("__udivmoddi4", @import("compiler_rt/udivmoddi4.zig").__udivmoddi4, linkage);
81123 @export("__popcountdi2", @import("compiler_rt/popcountdi2.zig").__popcountdi2, linkage);
82124
125 @export("__divmoddi4", __divmoddi4, linkage);
126 @export("__divsi3", __divsi3, linkage);
127 @export("__divdi3", __divdi3, linkage);
83128 @export("__udivsi3", __udivsi3, linkage);
84129 @export("__udivdi3", __udivdi3, linkage);
130 @export("__modsi3", __modsi3, linkage);
131 @export("__moddi3", __moddi3, linkage);
132 @export("__umodsi3", __umodsi3, linkage);
85133 @export("__umoddi3", __umoddi3, linkage);
134 @export("__divmodsi4", __divmodsi4, linkage);
86135 @export("__udivmodsi4", __udivmodsi4, linkage);
87136
88137 @export("__negsf2", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
89138 @export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
90139
91140 if (is_arm_arch and !is_arm_64) {
141 @export("__aeabi_unwind_cpp_pr0", __aeabi_unwind_cpp_pr0, strong_linkage);
142 @export("__aeabi_unwind_cpp_pr1", __aeabi_unwind_cpp_pr1, linkage);
143 @export("__aeabi_unwind_cpp_pr2", __aeabi_unwind_cpp_pr2, linkage);
144
145 @export("__aeabi_ldivmod", __aeabi_ldivmod, linkage);
92146 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
93 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
147
148 @export("__aeabi_idiv", __divsi3, linkage);
149 @export("__aeabi_idivmod", __aeabi_idivmod, linkage);
94150 @export("__aeabi_uidiv", __udivsi3, linkage);
151 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
95152
96153 @export("__aeabi_memcpy", __aeabi_memcpy, linkage);
97154 @export("__aeabi_memcpy4", __aeabi_memcpy, linkage);
......@@ -113,6 +170,12 @@ comptime {
113170 @export("__aeabi_memcmp4", __aeabi_memcmp, linkage);
114171 @export("__aeabi_memcmp8", __aeabi_memcmp, linkage);
115172
173 @export("__aeabi_f2d", @import("compiler_rt/extendXfYf2.zig").__extendsfdf2, linkage);
174 @export("__aeabi_i2d", @import("compiler_rt/floatsiXf.zig").__floatsidf, linkage);
175 @export("__aeabi_l2d", @import("compiler_rt/floatdidf.zig").__floatdidf, linkage);
176 @export("__aeabi_ui2d", @import("compiler_rt/floatunsidf.zig").__floatunsidf, linkage);
177 @export("__aeabi_ul2d", @import("compiler_rt/floatundidf.zig").__floatundidf, linkage);
178
116179 @export("__aeabi_fneg", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
117180 @export("__aeabi_dneg", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
118181
......@@ -132,6 +195,9 @@ comptime {
132195 @export("__aeabi_h2f", @import("compiler_rt/extendXfYf2.zig").__extendhfsf2, linkage);
133196 @export("__aeabi_f2h", @import("compiler_rt/truncXfYf2.zig").__truncsfhf2, linkage);
134197
198 @export("__aeabi_i2f", @import("compiler_rt/floatsiXf.zig").__floatsisf, linkage);
199 @export("__aeabi_d2f", @import("compiler_rt/truncXfYf2.zig").__truncdfsf2, linkage);
200
135201 @export("__aeabi_fadd", @import("compiler_rt/addXf3.zig").__addsf3, linkage);
136202 @export("__aeabi_dadd", @import("compiler_rt/addXf3.zig").__adddf3, linkage);
137203 @export("__aeabi_fsub", @import("compiler_rt/addXf3.zig").__subsf3, linkage);
......@@ -144,26 +210,41 @@ comptime {
144210
145211 @export("__aeabi_fdiv", @import("compiler_rt/divsf3.zig").__divsf3, linkage);
146212 @export("__aeabi_ddiv", @import("compiler_rt/divdf3.zig").__divdf3, linkage);
213
214 @export("__aeabi_fcmpeq", @import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpeq, linkage);
215 @export("__aeabi_fcmplt", @import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmplt, linkage);
216 @export("__aeabi_fcmple", @import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmple, linkage);
217 @export("__aeabi_fcmpge", @import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpge, linkage);
218 @export("__aeabi_fcmpgt", @import("compiler_rt/arm/aeabi_fcmp.zig").__aeabi_fcmpgt, linkage);
219 @export("__aeabi_fcmpun", @import("compiler_rt/comparesf2.zig").__unordsf2, linkage);
220
221 @export("__aeabi_dcmpeq", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpeq, linkage);
222 @export("__aeabi_dcmplt", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmplt, linkage);
223 @export("__aeabi_dcmple", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmple, linkage);
224 @export("__aeabi_dcmpge", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpge, linkage);
225 @export("__aeabi_dcmpgt", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpgt, linkage);
226 @export("__aeabi_dcmpun", @import("compiler_rt/comparedf2.zig").__unorddf2, linkage);
147227 }
148228 if (builtin.os == builtin.Os.windows) {
229 if (!builtin.link_libc) {
230 @export("_chkstk", @import("compiler_rt/stack_probe.zig")._chkstk, strong_linkage);
231 @export("__chkstk", @import("compiler_rt/stack_probe.zig").__chkstk, strong_linkage);
232 @export("___chkstk", @import("compiler_rt/stack_probe.zig").___chkstk, strong_linkage);
233 @export("__chkstk_ms", @import("compiler_rt/stack_probe.zig").__chkstk_ms, strong_linkage);
234 @export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage);
235 }
236
149237 switch (builtin.arch) {
150238 builtin.Arch.i386 => {
151 if (!builtin.link_libc) {
152 @export("_chkstk", _chkstk, strong_linkage);
153 @export("__chkstk_ms", __chkstk_ms, linkage);
154 }
155239 @export("_aulldiv", @import("compiler_rt/aulldiv.zig")._aulldiv, strong_linkage);
156240 @export("_aullrem", @import("compiler_rt/aullrem.zig")._aullrem, strong_linkage);
157241 },
158242 builtin.Arch.x86_64 => {
159 if (!builtin.link_libc) {
160 @export("__chkstk", __chkstk, strong_linkage);
161 @export("___chkstk_ms", ___chkstk_ms, linkage);
162 }
243 // The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI
244 // that LLVM expects compiler-rt to have.
163245 @export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage);
164246 @export("__modti3", @import("compiler_rt/modti3.zig").__modti3_windows_x86_64, linkage);
165247 @export("__multi3", @import("compiler_rt/multi3.zig").__multi3_windows_x86_64, linkage);
166 @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4_windows_x86_64, linkage);
167248 @export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3_windows_x86_64, linkage);
168249 @export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4_windows_x86_64, linkage);
169250 @export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3_windows_x86_64, linkage);
......@@ -174,11 +255,12 @@ comptime {
174255 @export("__divti3", @import("compiler_rt/divti3.zig").__divti3, linkage);
175256 @export("__modti3", @import("compiler_rt/modti3.zig").__modti3, linkage);
176257 @export("__multi3", @import("compiler_rt/multi3.zig").__multi3, linkage);
177 @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage);
178258 @export("__udivti3", @import("compiler_rt/udivti3.zig").__udivti3, linkage);
179259 @export("__udivmodti4", @import("compiler_rt/udivmodti4.zig").__udivmodti4, linkage);
180260 @export("__umodti3", @import("compiler_rt/umodti3.zig").__umodti3, linkage);
181261 }
262 @export("__muloti4", @import("compiler_rt/muloti4.zig").__muloti4, linkage);
263 @export("__mulodi4", @import("compiler_rt/mulodi4.zig").__mulodi4, linkage);
182264}
183265
184266const std = @import("std");
......@@ -198,15 +280,49 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
198280 }
199281}
200282
201pub fn setXmm0(comptime T: type, value: T) void {
202 comptime assert(builtin.arch == builtin.Arch.x86_64);
203 const aligned_value: T align(16) = value;
204 asm volatile (
205 \\movaps (%[ptr]), %%xmm0
206 :
207 : [ptr] "r" (&aligned_value)
208 : "xmm0"
209 );
283extern fn __aeabi_unwind_cpp_pr0() void {
284 unreachable;
285}
286extern fn __aeabi_unwind_cpp_pr1() void {
287 unreachable;
288}
289extern fn __aeabi_unwind_cpp_pr2() void {
290 unreachable;
291}
292
293extern fn __divmoddi4(a: i64, b: i64, rem: *i64) i64 {
294 @setRuntimeSafety(is_test);
295
296 const d = __divdi3(a, b);
297 rem.* = a -% (d *% b);
298 return d;
299}
300
301extern fn __divdi3(a: i64, b: i64) i64 {
302 @setRuntimeSafety(is_test);
303
304 // Set aside the sign of the quotient.
305 const sign = @bitCast(u64, (a ^ b) >> 63);
306 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
307 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
308 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
309 // Unsigned division
310 const res = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), null);
311 // Apply sign of quotient to result and return.
312 return @bitCast(i64, (res ^ sign) -% sign);
313}
314
315extern fn __moddi3(a: i64, b: i64) i64 {
316 @setRuntimeSafety(is_test);
317
318 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
319 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
320 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
321 // Unsigned division
322 var r: u64 = undefined;
323 _ = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), &r);
324 // Apply the sign of the dividend and return.
325 return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63);
210326}
211327
212328extern fn __udivdi3(a: u64, b: u64) u64 {
......@@ -222,14 +338,35 @@ extern fn __umoddi3(a: u64, b: u64) u64 {
222338 return r;
223339}
224340
225const AeabiUlDivModResult = extern struct {
226 quot: u64,
227 rem: u64,
228};
229extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult {
341extern fn __aeabi_uidivmod(n: u32, d: u32) extern struct{q: u32, r: u32} {
342 @setRuntimeSafety(is_test);
343
344 var result: @typeOf(__aeabi_uidivmod).ReturnType = undefined;
345 result.q = __udivmodsi4(n, d, &result.r);
346 return result;
347}
348
349extern fn __aeabi_uldivmod(n: u64, d: u64) extern struct{q: u64, r: u64} {
350 @setRuntimeSafety(is_test);
351
352 var result: @typeOf(__aeabi_uldivmod).ReturnType = undefined;
353 result.q = __udivmoddi4(n, d, &result.r);
354 return result;
355}
356
357extern fn __aeabi_idivmod(n: i32, d: i32) extern struct{q: i32, r: i32} {
358 @setRuntimeSafety(is_test);
359
360 var result: @typeOf(__aeabi_idivmod).ReturnType = undefined;
361 result.q = __divmodsi4(n, d, &result.r);
362 return result;
363}
364
365extern fn __aeabi_ldivmod(n: i64, d: i64) extern struct{q: i64, r:i64} {
230366 @setRuntimeSafety(is_test);
231 var result: AeabiUlDivModResult = undefined;
232 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
367
368 var result: @typeOf(__aeabi_ldivmod).ReturnType = undefined;
369 result.q = __divmoddi4(n, d, &result.r);
233370 return result;
234371}
235372
......@@ -253,29 +390,74 @@ const is_arm_arch = switch (builtin.arch) {
253390
254391const is_arm_32 = is_arm_arch and !is_arm_64;
255392
256const use_thumb_1 = is_arm_32 and switch (builtin.arch.arm) {
257 builtin.Arch.Arm32.v6,
258 builtin.Arch.Arm32.v6m,
259 builtin.Arch.Arm32.v6k,
260 builtin.Arch.Arm32.v6t2,
261 => true,
262 else => false,
263};
393const use_thumb_1 = usesThumb1(builtin.arch);
394
395fn usesThumb1(arch: builtin.Arch) bool {
396 return switch (arch) {
397 .arm => switch (arch.arm) {
398 .v6m => true,
399 else => false,
400 },
401 .armeb => switch (arch.armeb) {
402 .v6m => true,
403 else => false,
404 },
405 .thumb => switch (arch.thumb) {
406 .v5,
407 .v5te,
408 .v4t,
409 .v6,
410 .v6m,
411 .v6k,
412 => true,
413 else => false,
414 },
415 .thumbeb => switch (arch.thumbeb) {
416 .v5,
417 .v5te,
418 .v4t,
419 .v6,
420 .v6m,
421 .v6k,
422 => true,
423 else => false,
424 },
425 else => false,
426 };
427}
264428
265nakedcc fn __aeabi_uidivmod() void {
266 @setRuntimeSafety(false);
267 asm volatile (
268 \\ push { lr }
269 \\ sub sp, sp, #4
270 \\ mov r2, sp
271 \\ bl __udivmodsi4
272 \\ ldr r1, [sp]
273 \\ add sp, sp, #4
274 \\ pop { pc }
275 :
276 :
277 : "r2", "r1"
278 );
429test "usesThumb1" {
430 testing.expect(usesThumb1(builtin.Arch{ .arm = .v6m }));
431 testing.expect(!usesThumb1(builtin.Arch{ .arm = .v5 }));
432 //etc.
433
434 testing.expect(usesThumb1(builtin.Arch{ .armeb = .v6m }));
435 testing.expect(!usesThumb1(builtin.Arch{ .armeb = .v5 }));
436 //etc.
437
438 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5 }));
439 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v5te }));
440 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v4t }));
441 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6 }));
442 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6k }));
443 testing.expect(usesThumb1(builtin.Arch{ .thumb = .v6m }));
444 testing.expect(!usesThumb1(builtin.Arch{ .thumb = .v6t2 }));
445 //etc.
446
447 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5 }));
448 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v5te }));
449 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v4t }));
450 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6 }));
451 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6k }));
452 testing.expect(usesThumb1(builtin.Arch{ .thumbeb = .v6m }));
453 testing.expect(!usesThumb1(builtin.Arch{ .thumbeb = .v6t2 }));
454 //etc.
455
456 testing.expect(!usesThumb1(builtin.Arch{ .aarch64 = .v8 }));
457 testing.expect(!usesThumb1(builtin.Arch{ .aarch64_be = .v8 }));
458 testing.expect(!usesThumb1(builtin.Arch.x86_64));
459 testing.expect(!usesThumb1(builtin.Arch.riscv32));
460 //etc.
279461}
280462
281463nakedcc fn __aeabi_memcpy() noreturn {
......@@ -368,107 +550,12 @@ nakedcc fn __aeabi_memcmp() noreturn {
368550 unreachable;
369551}
370552
371// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
372// then decrement %esp by %eax. Preserves all registers except %esp and flags.
373// This routine is windows specific
374// http://msdn.microsoft.com/en-us/library/ms648426.aspx
375nakedcc fn _chkstk() align(4) void {
376 @setRuntimeSafety(false);
377
378 asm volatile (
379 \\ push %%ecx
380 \\ push %%eax
381 \\ cmp $0x1000,%%eax
382 \\ lea 12(%%esp),%%ecx
383 \\ jb 1f
384 \\ 2:
385 \\ sub $0x1000,%%ecx
386 \\ test %%ecx,(%%ecx)
387 \\ sub $0x1000,%%eax
388 \\ cmp $0x1000,%%eax
389 \\ ja 2b
390 \\ 1:
391 \\ sub %%eax,%%ecx
392 \\ test %%ecx,(%%ecx)
393 \\ pop %%eax
394 \\ pop %%ecx
395 \\ ret
396 );
397}
398
399nakedcc fn __chkstk() align(4) void {
400 @setRuntimeSafety(false);
401
402 asm volatile (
403 \\ push %%rcx
404 \\ push %%rax
405 \\ cmp $0x1000,%%rax
406 \\ lea 24(%%rsp),%%rcx
407 \\ jb 1f
408 \\2:
409 \\ sub $0x1000,%%rcx
410 \\ test %%rcx,(%%rcx)
411 \\ sub $0x1000,%%rax
412 \\ cmp $0x1000,%%rax
413 \\ ja 2b
414 \\1:
415 \\ sub %%rax,%%rcx
416 \\ test %%rcx,(%%rcx)
417 \\ pop %%rax
418 \\ pop %%rcx
419 \\ ret
420 );
421}
422
423// _chkstk routine
424// This routine is windows specific
425// http://msdn.microsoft.com/en-us/library/ms648426.aspx
426nakedcc fn __chkstk_ms() align(4) void {
427 @setRuntimeSafety(false);
428
429 asm volatile (
430 \\ push %%ecx
431 \\ push %%eax
432 \\ cmp $0x1000,%%eax
433 \\ lea 12(%%esp),%%ecx
434 \\ jb 1f
435 \\ 2:
436 \\ sub $0x1000,%%ecx
437 \\ test %%ecx,(%%ecx)
438 \\ sub $0x1000,%%eax
439 \\ cmp $0x1000,%%eax
440 \\ ja 2b
441 \\ 1:
442 \\ sub %%eax,%%ecx
443 \\ test %%ecx,(%%ecx)
444 \\ pop %%eax
445 \\ pop %%ecx
446 \\ ret
447 );
448}
449
450nakedcc fn ___chkstk_ms() align(4) void {
451 @setRuntimeSafety(false);
553extern fn __divmodsi4(a: i32, b: i32, rem: *i32) i32 {
554 @setRuntimeSafety(is_test);
452555
453 asm volatile (
454 \\ push %%rcx
455 \\ push %%rax
456 \\ cmp $0x1000,%%rax
457 \\ lea 24(%%rsp),%%rcx
458 \\ jb 1f
459 \\2:
460 \\ sub $0x1000,%%rcx
461 \\ test %%rcx,(%%rcx)
462 \\ sub $0x1000,%%rax
463 \\ cmp $0x1000,%%rax
464 \\ ja 2b
465 \\1:
466 \\ sub %%rax,%%rcx
467 \\ test %%rcx,(%%rcx)
468 \\ pop %%rax
469 \\ pop %%rcx
470 \\ ret
471 );
556 const d = __divsi3(a, b);
557 rem.* = a -% (d * b);
558 return d;
472559}
473560
474561extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 {
......@@ -479,6 +566,20 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 {
479566 return d;
480567}
481568
569extern fn __divsi3(n: i32, d: i32) i32 {
570 @setRuntimeSafety(is_test);
571
572 // Set aside the sign of the quotient.
573 const sign = @bitCast(u32, (n ^ d) >> 31);
574 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
575 const abs_n = (n ^ (n >> 31)) -% (n >> 31);
576 const abs_d = (d ^ (d >> 31)) -% (d >> 31);
577 // abs(a) / abs(b)
578 const res = @bitCast(u32, abs_n) / @bitCast(u32, abs_d);
579 // Apply sign of quotient to result and return.
580 return @bitCast(i32, (res ^ sign) -% sign);
581}
582
482583extern fn __udivsi3(n: u32, d: u32) u32 {
483584 @setRuntimeSafety(is_test);
484585
......@@ -520,6 +621,18 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
520621 return q;
521622}
522623
624extern fn __modsi3(n: i32, d: i32) i32 {
625 @setRuntimeSafety(is_test);
626
627 return n -% __divsi3(n, d) *% d;
628}
629
630extern fn __umodsi3(n: u32, d: u32) u32 {
631 @setRuntimeSafety(is_test);
632
633 return n -% __udivsi3(n, d) *% d;
634}
635
523636test "test_umoddi3" {
524637 test_one_umoddi3(0, 1, 0);
525638 test_one_umoddi3(2, 1, 0);
......@@ -1206,3 +1319,279 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
12061319 const q: u32 = __udivsi3(a, b);
12071320 testing.expect(q == expected_q);
12081321}
1322
1323test "test_divsi3" {
1324 const cases = [][3]i32{
1325 []i32{ 0, 1, 0 },
1326 []i32{ 0, -1, 0 },
1327 []i32{ 2, 1, 2 },
1328 []i32{ 2, -1, -2 },
1329 []i32{ -2, 1, -2 },
1330 []i32{ -2, -1, 2 },
1331
1332 []i32{ @bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000)) },
1333 []i32{ @bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000)) },
1334 []i32{ @bitCast(i32, u32(0x80000000)), -2, 0x40000000 },
1335 []i32{ @bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000)) },
1336 };
1337
1338 for (cases) |case| {
1339 test_one_divsi3(case[0], case[1], case[2]);
1340 }
1341}
1342
1343fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void {
1344 const q: i32 = __divsi3(a, b);
1345 testing.expect(q == expected_q);
1346}
1347
1348test "test_divmodsi4" {
1349 const cases = [][4]i32{
1350 []i32{ 0, 1, 0, 0 },
1351 []i32{ 0, -1, 0, 0 },
1352 []i32{ 2, 1, 2, 0 },
1353 []i32{ 2, -1, -2, 0 },
1354 []i32{ -2, 1, -2, 0 },
1355 []i32{ -2, -1, 2, 0 },
1356 []i32{ 7, 5, 1, 2 },
1357 []i32{ -7, 5, -1, -2 },
1358 []i32{ 19, 5, 3, 4 },
1359 []i32{ 19, -5, -3, 4 },
1360
1361 []i32{ @bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0 },
1362 []i32{ @bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1 },
1363 };
1364
1365 for (cases) |case| {
1366 test_one_divmodsi4(case[0], case[1], case[2], case[3]);
1367 }
1368}
1369
1370fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) void {
1371 var r: i32 = undefined;
1372 const q: i32 = __divmodsi4(a, b, &r);
1373 testing.expect(q == expected_q and r == expected_r);
1374}
1375
1376test "test_divdi3" {
1377 const cases = [][3]i64{
1378 []i64{ 0, 1, 0 },
1379 []i64{ 0, -1, 0 },
1380 []i64{ 2, 1, 2 },
1381 []i64{ 2, -1, -2 },
1382 []i64{ -2, 1, -2 },
1383 []i64{ -2, -1, 2 },
1384
1385 []i64{ @bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)) },
1386 []i64{ @bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)) },
1387 []i64{ @bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000 },
1388 []i64{ @bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000)) },
1389 };
1390
1391 for (cases) |case| {
1392 test_one_divdi3(case[0], case[1], case[2]);
1393 }
1394}
1395
1396fn test_one_divdi3(a: i64, b: i64, expected_q: i64) void {
1397 const q: i64 = __divdi3(a, b);
1398 testing.expect(q == expected_q);
1399}
1400
1401test "test_moddi3" {
1402 const cases = [][3]i64{
1403 []i64{ 0, 1, 0 },
1404 []i64{ 0, -1, 0 },
1405 []i64{ 5, 3, 2 },
1406 []i64{ 5, -3, 2 },
1407 []i64{ -5, 3, -2 },
1408 []i64{ -5, -3, -2 },
1409
1410 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0 },
1411 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0 },
1412 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0 },
1413 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0 },
1414 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2 },
1415 []i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2 },
1416 };
1417
1418 for (cases) |case| {
1419 test_one_moddi3(case[0], case[1], case[2]);
1420 }
1421}
1422
1423fn test_one_moddi3(a: i64, b: i64, expected_r: i64) void {
1424 const r: i64 = __moddi3(a, b);
1425 testing.expect(r == expected_r);
1426}
1427
1428test "test_modsi3" {
1429 const cases = [][3]i32{
1430 []i32{ 0, 1, 0 },
1431 []i32{ 0, -1, 0 },
1432 []i32{ 5, 3, 2 },
1433 []i32{ 5, -3, 2 },
1434 []i32{ -5, 3, -2 },
1435 []i32{ -5, -3, -2 },
1436 []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 },
1437 []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 },
1438 []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 },
1439 []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 },
1440 []i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 },
1441 };
1442
1443 for (cases) |case| {
1444 test_one_modsi3(case[0], case[1], case[2]);
1445 }
1446}
1447
1448fn test_one_modsi3(a: i32, b: i32, expected_r: i32) void {
1449 const r: i32 = __modsi3(a, b);
1450 testing.expect(r == expected_r);
1451}
1452
1453test "test_umodsi3" {
1454 const cases = [][3]u32{
1455 []u32{ 0x00000000, 0x00000001, 0x00000000 },
1456 []u32{ 0x00000000, 0x00000002, 0x00000000 },
1457 []u32{ 0x00000000, 0x00000003, 0x00000000 },
1458 []u32{ 0x00000000, 0x00000010, 0x00000000 },
1459 []u32{ 0x00000000, 0x078644FA, 0x00000000 },
1460 []u32{ 0x00000000, 0x0747AE14, 0x00000000 },
1461 []u32{ 0x00000000, 0x7FFFFFFF, 0x00000000 },
1462 []u32{ 0x00000000, 0x80000000, 0x00000000 },
1463 []u32{ 0x00000000, 0xFFFFFFFD, 0x00000000 },
1464 []u32{ 0x00000000, 0xFFFFFFFE, 0x00000000 },
1465 []u32{ 0x00000000, 0xFFFFFFFF, 0x00000000 },
1466 []u32{ 0x00000001, 0x00000001, 0x00000000 },
1467 []u32{ 0x00000001, 0x00000002, 0x00000001 },
1468 []u32{ 0x00000001, 0x00000003, 0x00000001 },
1469 []u32{ 0x00000001, 0x00000010, 0x00000001 },
1470 []u32{ 0x00000001, 0x078644FA, 0x00000001 },
1471 []u32{ 0x00000001, 0x0747AE14, 0x00000001 },
1472 []u32{ 0x00000001, 0x7FFFFFFF, 0x00000001 },
1473 []u32{ 0x00000001, 0x80000000, 0x00000001 },
1474 []u32{ 0x00000001, 0xFFFFFFFD, 0x00000001 },
1475 []u32{ 0x00000001, 0xFFFFFFFE, 0x00000001 },
1476 []u32{ 0x00000001, 0xFFFFFFFF, 0x00000001 },
1477 []u32{ 0x00000002, 0x00000001, 0x00000000 },
1478 []u32{ 0x00000002, 0x00000002, 0x00000000 },
1479 []u32{ 0x00000002, 0x00000003, 0x00000002 },
1480 []u32{ 0x00000002, 0x00000010, 0x00000002 },
1481 []u32{ 0x00000002, 0x078644FA, 0x00000002 },
1482 []u32{ 0x00000002, 0x0747AE14, 0x00000002 },
1483 []u32{ 0x00000002, 0x7FFFFFFF, 0x00000002 },
1484 []u32{ 0x00000002, 0x80000000, 0x00000002 },
1485 []u32{ 0x00000002, 0xFFFFFFFD, 0x00000002 },
1486 []u32{ 0x00000002, 0xFFFFFFFE, 0x00000002 },
1487 []u32{ 0x00000002, 0xFFFFFFFF, 0x00000002 },
1488 []u32{ 0x00000003, 0x00000001, 0x00000000 },
1489 []u32{ 0x00000003, 0x00000002, 0x00000001 },
1490 []u32{ 0x00000003, 0x00000003, 0x00000000 },
1491 []u32{ 0x00000003, 0x00000010, 0x00000003 },
1492 []u32{ 0x00000003, 0x078644FA, 0x00000003 },
1493 []u32{ 0x00000003, 0x0747AE14, 0x00000003 },
1494 []u32{ 0x00000003, 0x7FFFFFFF, 0x00000003 },
1495 []u32{ 0x00000003, 0x80000000, 0x00000003 },
1496 []u32{ 0x00000003, 0xFFFFFFFD, 0x00000003 },
1497 []u32{ 0x00000003, 0xFFFFFFFE, 0x00000003 },
1498 []u32{ 0x00000003, 0xFFFFFFFF, 0x00000003 },
1499 []u32{ 0x00000010, 0x00000001, 0x00000000 },
1500 []u32{ 0x00000010, 0x00000002, 0x00000000 },
1501 []u32{ 0x00000010, 0x00000003, 0x00000001 },
1502 []u32{ 0x00000010, 0x00000010, 0x00000000 },
1503 []u32{ 0x00000010, 0x078644FA, 0x00000010 },
1504 []u32{ 0x00000010, 0x0747AE14, 0x00000010 },
1505 []u32{ 0x00000010, 0x7FFFFFFF, 0x00000010 },
1506 []u32{ 0x00000010, 0x80000000, 0x00000010 },
1507 []u32{ 0x00000010, 0xFFFFFFFD, 0x00000010 },
1508 []u32{ 0x00000010, 0xFFFFFFFE, 0x00000010 },
1509 []u32{ 0x00000010, 0xFFFFFFFF, 0x00000010 },
1510 []u32{ 0x078644FA, 0x00000001, 0x00000000 },
1511 []u32{ 0x078644FA, 0x00000002, 0x00000000 },
1512 []u32{ 0x078644FA, 0x00000003, 0x00000000 },
1513 []u32{ 0x078644FA, 0x00000010, 0x0000000A },
1514 []u32{ 0x078644FA, 0x078644FA, 0x00000000 },
1515 []u32{ 0x078644FA, 0x0747AE14, 0x003E96E6 },
1516 []u32{ 0x078644FA, 0x7FFFFFFF, 0x078644FA },
1517 []u32{ 0x078644FA, 0x80000000, 0x078644FA },
1518 []u32{ 0x078644FA, 0xFFFFFFFD, 0x078644FA },
1519 []u32{ 0x078644FA, 0xFFFFFFFE, 0x078644FA },
1520 []u32{ 0x078644FA, 0xFFFFFFFF, 0x078644FA },
1521 []u32{ 0x0747AE14, 0x00000001, 0x00000000 },
1522 []u32{ 0x0747AE14, 0x00000002, 0x00000000 },
1523 []u32{ 0x0747AE14, 0x00000003, 0x00000002 },
1524 []u32{ 0x0747AE14, 0x00000010, 0x00000004 },
1525 []u32{ 0x0747AE14, 0x078644FA, 0x0747AE14 },
1526 []u32{ 0x0747AE14, 0x0747AE14, 0x00000000 },
1527 []u32{ 0x0747AE14, 0x7FFFFFFF, 0x0747AE14 },
1528 []u32{ 0x0747AE14, 0x80000000, 0x0747AE14 },
1529 []u32{ 0x0747AE14, 0xFFFFFFFD, 0x0747AE14 },
1530 []u32{ 0x0747AE14, 0xFFFFFFFE, 0x0747AE14 },
1531 []u32{ 0x0747AE14, 0xFFFFFFFF, 0x0747AE14 },
1532 []u32{ 0x7FFFFFFF, 0x00000001, 0x00000000 },
1533 []u32{ 0x7FFFFFFF, 0x00000002, 0x00000001 },
1534 []u32{ 0x7FFFFFFF, 0x00000003, 0x00000001 },
1535 []u32{ 0x7FFFFFFF, 0x00000010, 0x0000000F },
1536 []u32{ 0x7FFFFFFF, 0x078644FA, 0x00156B65 },
1537 []u32{ 0x7FFFFFFF, 0x0747AE14, 0x043D70AB },
1538 []u32{ 0x7FFFFFFF, 0x7FFFFFFF, 0x00000000 },
1539 []u32{ 0x7FFFFFFF, 0x80000000, 0x7FFFFFFF },
1540 []u32{ 0x7FFFFFFF, 0xFFFFFFFD, 0x7FFFFFFF },
1541 []u32{ 0x7FFFFFFF, 0xFFFFFFFE, 0x7FFFFFFF },
1542 []u32{ 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF },
1543 []u32{ 0x80000000, 0x00000001, 0x00000000 },
1544 []u32{ 0x80000000, 0x00000002, 0x00000000 },
1545 []u32{ 0x80000000, 0x00000003, 0x00000002 },
1546 []u32{ 0x80000000, 0x00000010, 0x00000000 },
1547 []u32{ 0x80000000, 0x078644FA, 0x00156B66 },
1548 []u32{ 0x80000000, 0x0747AE14, 0x043D70AC },
1549 []u32{ 0x80000000, 0x7FFFFFFF, 0x00000001 },
1550 []u32{ 0x80000000, 0x80000000, 0x00000000 },
1551 []u32{ 0x80000000, 0xFFFFFFFD, 0x80000000 },
1552 []u32{ 0x80000000, 0xFFFFFFFE, 0x80000000 },
1553 []u32{ 0x80000000, 0xFFFFFFFF, 0x80000000 },
1554 []u32{ 0xFFFFFFFD, 0x00000001, 0x00000000 },
1555 []u32{ 0xFFFFFFFD, 0x00000002, 0x00000001 },
1556 []u32{ 0xFFFFFFFD, 0x00000003, 0x00000001 },
1557 []u32{ 0xFFFFFFFD, 0x00000010, 0x0000000D },
1558 []u32{ 0xFFFFFFFD, 0x078644FA, 0x002AD6C9 },
1559 []u32{ 0xFFFFFFFD, 0x0747AE14, 0x01333341 },
1560 []u32{ 0xFFFFFFFD, 0x7FFFFFFF, 0x7FFFFFFE },
1561 []u32{ 0xFFFFFFFD, 0x80000000, 0x7FFFFFFD },
1562 []u32{ 0xFFFFFFFD, 0xFFFFFFFD, 0x00000000 },
1563 []u32{ 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFD },
1564 []u32{ 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFD },
1565 []u32{ 0xFFFFFFFE, 0x00000001, 0x00000000 },
1566 []u32{ 0xFFFFFFFE, 0x00000002, 0x00000000 },
1567 []u32{ 0xFFFFFFFE, 0x00000003, 0x00000002 },
1568 []u32{ 0xFFFFFFFE, 0x00000010, 0x0000000E },
1569 []u32{ 0xFFFFFFFE, 0x078644FA, 0x002AD6CA },
1570 []u32{ 0xFFFFFFFE, 0x0747AE14, 0x01333342 },
1571 []u32{ 0xFFFFFFFE, 0x7FFFFFFF, 0x00000000 },
1572 []u32{ 0xFFFFFFFE, 0x80000000, 0x7FFFFFFE },
1573 []u32{ 0xFFFFFFFE, 0xFFFFFFFD, 0x00000001 },
1574 []u32{ 0xFFFFFFFE, 0xFFFFFFFE, 0x00000000 },
1575 []u32{ 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFE },
1576 []u32{ 0xFFFFFFFF, 0x00000001, 0x00000000 },
1577 []u32{ 0xFFFFFFFF, 0x00000002, 0x00000001 },
1578 []u32{ 0xFFFFFFFF, 0x00000003, 0x00000000 },
1579 []u32{ 0xFFFFFFFF, 0x00000010, 0x0000000F },
1580 []u32{ 0xFFFFFFFF, 0x078644FA, 0x002AD6CB },
1581 []u32{ 0xFFFFFFFF, 0x0747AE14, 0x01333343 },
1582 []u32{ 0xFFFFFFFF, 0x7FFFFFFF, 0x00000001 },
1583 []u32{ 0xFFFFFFFF, 0x80000000, 0x7FFFFFFF },
1584 []u32{ 0xFFFFFFFF, 0xFFFFFFFD, 0x00000002 },
1585 []u32{ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001 },
1586 []u32{ 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000 },
1587 };
1588
1589 for (cases) |case| {
1590 test_one_umodsi3(case[0], case[1], case[2]);
1591 }
1592}
1593
1594fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
1595 const r: u32 = __umodsi3(a, b);
1596 testing.expect(r == expected_r);
1597}
std/special/compiler_rt/addXf3.zig+2-2
......@@ -78,8 +78,8 @@ fn addXf3(comptime T: type, a: T, b: T) T {
7878 const infRep = @bitCast(Z, std.math.inf(T));
7979
8080 // Detect if a or b is zero, infinity, or NaN.
81 if (aAbs - Z(1) >= infRep - Z(1) or
82 bAbs - Z(1) >= infRep - Z(1))
81 if (aAbs -% Z(1) >= infRep - Z(1) or
82 bAbs -% Z(1) >= infRep - Z(1))
8383 {
8484 // NaN + anything = qNaN
8585 if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);
std/special/compiler_rt/arm/aeabi_dcmp.zig created+108
......@@ -0,0 +1,108 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/arm/aeabi_dcmp.S
4
5const compiler_rt_armhf_target = false; // TODO
6
7const ConditionalOperator = enum {
8 Eq,
9 Lt,
10 Le,
11 Ge,
12 Gt,
13};
14
15pub nakedcc fn __aeabi_dcmpeq() noreturn {
16 @setRuntimeSafety(false);
17 aeabi_dcmp(.Eq);
18 unreachable;
19}
20
21pub nakedcc fn __aeabi_dcmplt() noreturn {
22 @setRuntimeSafety(false);
23 aeabi_dcmp(.Lt);
24 unreachable;
25}
26
27pub nakedcc fn __aeabi_dcmple() noreturn {
28 @setRuntimeSafety(false);
29 aeabi_dcmp(.Le);
30 unreachable;
31}
32
33pub nakedcc fn __aeabi_dcmpge() noreturn {
34 @setRuntimeSafety(false);
35 aeabi_dcmp(.Ge);
36 unreachable;
37}
38
39pub nakedcc fn __aeabi_dcmpgt() noreturn {
40 @setRuntimeSafety(false);
41 aeabi_dcmp(.Gt);
42 unreachable;
43}
44
45inline fn convert_dcmp_args_to_df2_args() void {
46 asm volatile (
47 \\ vmov d0, r0, r1
48 \\ vmov d1, r2, r3
49 );
50}
51
52inline fn aeabi_dcmp(comptime cond: ConditionalOperator) void {
53 @setRuntimeSafety(false);
54 asm volatile (
55 \\ push { r4, lr }
56 );
57
58 if (compiler_rt_armhf_target) {
59 convert_dcmp_args_to_df2_args();
60 }
61
62 switch (cond) {
63 .Eq => asm volatile (
64 \\ bl __eqdf2
65 \\ cmp r0, #0
66 \\ beq 1f
67 \\ movs r0, #0
68 \\ pop { r4, pc }
69 \\ 1:
70 ),
71 .Lt => asm volatile (
72 \\ bl __ltdf2
73 \\ cmp r0, #0
74 \\ blt 1f
75 \\ movs r0, #0
76 \\ pop { r4, pc }
77 \\ 1:
78 ),
79 .Le => asm volatile (
80 \\ bl __ledf2
81 \\ cmp r0, #0
82 \\ ble 1f
83 \\ movs r0, #0
84 \\ pop { r4, pc }
85 \\ 1:
86 ),
87 .Ge => asm volatile (
88 \\ bl __ltdf2
89 \\ cmp r0, #0
90 \\ bge 1f
91 \\ movs r0, #0
92 \\ pop { r4, pc }
93 \\ 1:
94 ),
95 .Gt => asm volatile (
96 \\ bl __gtdf2
97 \\ cmp r0, #0
98 \\ bgt 1f
99 \\ movs r0, #0
100 \\ pop { r4, pc }
101 \\ 1:
102 ),
103 }
104 asm volatile (
105 \\ movs r0, #1
106 \\ pop { r4, pc }
107 );
108}
std/special/compiler_rt/arm/aeabi_fcmp.zig created+108
......@@ -0,0 +1,108 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/arm/aeabi_fcmp.S
4
5const compiler_rt_armhf_target = false; // TODO
6
7const ConditionalOperator = enum {
8 Eq,
9 Lt,
10 Le,
11 Ge,
12 Gt,
13};
14
15pub nakedcc fn __aeabi_fcmpeq() noreturn {
16 @setRuntimeSafety(false);
17 aeabi_fcmp(.Eq);
18 unreachable;
19}
20
21pub nakedcc fn __aeabi_fcmplt() noreturn {
22 @setRuntimeSafety(false);
23 aeabi_fcmp(.Lt);
24 unreachable;
25}
26
27pub nakedcc fn __aeabi_fcmple() noreturn {
28 @setRuntimeSafety(false);
29 aeabi_fcmp(.Le);
30 unreachable;
31}
32
33pub nakedcc fn __aeabi_fcmpge() noreturn {
34 @setRuntimeSafety(false);
35 aeabi_fcmp(.Ge);
36 unreachable;
37}
38
39pub nakedcc fn __aeabi_fcmpgt() noreturn {
40 @setRuntimeSafety(false);
41 aeabi_fcmp(.Gt);
42 unreachable;
43}
44
45inline fn convert_fcmp_args_to_sf2_args() void {
46 asm volatile (
47 \\ vmov s0, r0
48 \\ vmov s1, r1
49 );
50}
51
52inline fn aeabi_fcmp(comptime cond: ConditionalOperator) void {
53 @setRuntimeSafety(false);
54 asm volatile (
55 \\ push { r4, lr }
56 );
57
58 if (compiler_rt_armhf_target) {
59 convert_fcmp_args_to_sf2_args();
60 }
61
62 switch (cond) {
63 .Eq => asm volatile (
64 \\ bl __eqsf2
65 \\ cmp r0, #0
66 \\ beq 1f
67 \\ movs r0, #0
68 \\ pop { r4, pc }
69 \\ 1:
70 ),
71 .Lt => asm volatile (
72 \\ bl __ltsf2
73 \\ cmp r0, #0
74 \\ blt 1f
75 \\ movs r0, #0
76 \\ pop { r4, pc }
77 \\ 1:
78 ),
79 .Le => asm volatile (
80 \\ bl __lesf2
81 \\ cmp r0, #0
82 \\ ble 1f
83 \\ movs r0, #0
84 \\ pop { r4, pc }
85 \\ 1:
86 ),
87 .Ge => asm volatile (
88 \\ bl __ltsf2
89 \\ cmp r0, #0
90 \\ bge 1f
91 \\ movs r0, #0
92 \\ pop { r4, pc }
93 \\ 1:
94 ),
95 .Gt => asm volatile (
96 \\ bl __gtsf2
97 \\ cmp r0, #0
98 \\ bgt 1f
99 \\ movs r0, #0
100 \\ pop { r4, pc }
101 \\ 1:
102 ),
103 }
104 asm volatile (
105 \\ movs r0, #1
106 \\ pop { r4, pc }
107 );
108}
std/special/compiler_rt/ashlti3.zig created+41
......@@ -0,0 +1,41 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3
4pub extern fn __ashlti3(a: i128, b: i32) i128 {
5 var input = twords{ .all = a };
6 var result: twords = undefined;
7
8 if (b > 63) {
9 // 64 <= b < 128
10 result.s.low = 0;
11 result.s.high = input.s.low << @intCast(u6, b - 64);
12 } else {
13 // 0 <= b < 64
14 if (b == 0) return a;
15 result.s.low = input.s.low << @intCast(u6, b);
16 result.s.high = input.s.low >> @intCast(u6, 64 - b);
17 result.s.high |= input.s.high << @intCast(u6, b);
18 }
19
20 return result.all;
21}
22
23const twords = extern union {
24 all: i128,
25 s: S,
26
27 const S = if (builtin.endian == builtin.Endian.Little)
28 struct {
29 low: u64,
30 high: u64,
31 }
32 else
33 struct {
34 high: u64,
35 low: u64,
36 };
37};
38
39test "import ashlti3" {
40 _ = @import("ashlti3_test.zig");
41}
std/special/compiler_rt/ashlti3_test.zig created+46
......@@ -0,0 +1,46 @@
1const __ashlti3 = @import("ashlti3.zig").__ashlti3;
2const testing = @import("std").testing;
3
4fn test__ashlti3(a: i128, b: i32, expected: i128) void {
5 const x = __ashlti3(a, b);
6 testing.expect(x == expected);
7}
8
9test "ashlti3" {
10 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 0, @bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)));
11 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 1, @bitCast(i128, @intCast(u128, 0xFDB97530ECA8642BFDB97530ECA8642A)));
12 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 2, @bitCast(i128, @intCast(u128, 0xFB72EA61D950C857FB72EA61D950C854)));
13 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 3, @bitCast(i128, @intCast(u128, 0xF6E5D4C3B2A190AFF6E5D4C3B2A190A8)));
14 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 4, @bitCast(i128, @intCast(u128, 0xEDCBA9876543215FEDCBA98765432150)));
15 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 28, @bitCast(i128, @intCast(u128, 0x876543215FEDCBA98765432150000000)));
16 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 29, @bitCast(i128, @intCast(u128, 0x0ECA8642BFDB97530ECA8642A0000000)));
17 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 30, @bitCast(i128, @intCast(u128, 0x1D950C857FB72EA61D950C8540000000)));
18 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 31, @bitCast(i128, @intCast(u128, 0x3B2A190AFF6E5D4C3B2A190A80000000)));
19 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 32, @bitCast(i128, @intCast(u128, 0x76543215FEDCBA987654321500000000)));
20 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 33, @bitCast(i128, @intCast(u128, 0xECA8642BFDB97530ECA8642A00000000)));
21 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 34, @bitCast(i128, @intCast(u128, 0xD950C857FB72EA61D950C85400000000)));
22 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 35, @bitCast(i128, @intCast(u128, 0xB2A190AFF6E5D4C3B2A190A800000000)));
23 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 36, @bitCast(i128, @intCast(u128, 0x6543215FEDCBA9876543215000000000)));
24 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 60, @bitCast(i128, @intCast(u128, 0x5FEDCBA9876543215000000000000000)));
25 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 61, @bitCast(i128, @intCast(u128, 0xBFDB97530ECA8642A000000000000000)));
26 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 62, @bitCast(i128, @intCast(u128, 0x7FB72EA61D950C854000000000000000)));
27 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 63, @bitCast(i128, @intCast(u128, 0xFF6E5D4C3B2A190A8000000000000000)));
28 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 64, @bitCast(i128, @intCast(u128, 0xFEDCBA98765432150000000000000000)));
29 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 65, @bitCast(i128, @intCast(u128, 0xFDB97530ECA8642A0000000000000000)));
30 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 66, @bitCast(i128, @intCast(u128, 0xFB72EA61D950C8540000000000000000)));
31 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 67, @bitCast(i128, @intCast(u128, 0xF6E5D4C3B2A190A80000000000000000)));
32 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 68, @bitCast(i128, @intCast(u128, 0xEDCBA987654321500000000000000000)));
33 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 92, @bitCast(i128, @intCast(u128, 0x87654321500000000000000000000000)));
34 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 93, @bitCast(i128, @intCast(u128, 0x0ECA8642A00000000000000000000000)));
35 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 94, @bitCast(i128, @intCast(u128, 0x1D950C85400000000000000000000000)));
36 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 95, @bitCast(i128, @intCast(u128, 0x3B2A190A800000000000000000000000)));
37 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 96, @bitCast(i128, @intCast(u128, 0x76543215000000000000000000000000)));
38 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 97, @bitCast(i128, @intCast(u128, 0xECA8642A000000000000000000000000)));
39 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 98, @bitCast(i128, @intCast(u128, 0xD950C854000000000000000000000000)));
40 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 99, @bitCast(i128, @intCast(u128, 0xB2A190A8000000000000000000000000)));
41 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 100, @bitCast(i128, @intCast(u128, 0x65432150000000000000000000000000)));
42 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 124, @bitCast(i128, @intCast(u128, 0x50000000000000000000000000000000)));
43 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 125, @bitCast(i128, @intCast(u128, 0xA0000000000000000000000000000000)));
44 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 126, @bitCast(i128, @intCast(u128, 0x40000000000000000000000000000000)));
45 test__ashlti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 127, @bitCast(i128, @intCast(u128, 0x80000000000000000000000000000000)));
46}
std/special/compiler_rt/ashrti3.zig created+42
......@@ -0,0 +1,42 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3
4pub extern fn __ashrti3(a: i128, b: i32) i128 {
5 var input = twords{ .all = a };
6 var result: twords = undefined;
7
8 if (b > 63) {
9 // 64 <= b < 128
10 result.s.low = input.s.high >> @intCast(u6, b - 64);
11 result.s.high = input.s.high >> 63;
12 } else {
13 // 0 <= b < 64
14 if (b == 0) return a;
15 result.s.low = input.s.high << @intCast(u6, 64 - b);
16 // Avoid sign-extension here
17 result.s.low |= @bitCast(i64, @bitCast(u64, input.s.low) >> @intCast(u6, b));
18 result.s.high = input.s.high >> @intCast(u6, b);
19 }
20
21 return result.all;
22}
23
24const twords = extern union {
25 all: i128,
26 s: S,
27
28 const S = if (builtin.endian == builtin.Endian.Little)
29 struct {
30 low: i64,
31 high: i64,
32 }
33 else
34 struct {
35 high: i64,
36 low: i64,
37 };
38};
39
40test "import ashrti3" {
41 _ = @import("ashrti3_test.zig");
42}
std/special/compiler_rt/ashrti3_test.zig created+58
......@@ -0,0 +1,58 @@
1const __ashrti3 = @import("ashrti3.zig").__ashrti3;
2const testing = @import("std").testing;
3
4fn test__ashrti3(a: i128, b: i32, expected: i128) void {
5 const x = __ashrti3(a, b);
6 // @import("std").debug.warn("got 0x{x}\nexp 0x{x}\n", @truncate(u64,
7// @bitCast(u128, x) >> 64), @truncate(u64, @bitCast(u128, expected)) >> 64);
8 testing.expect(x == expected);
9}
10
11test "ashrti3" {
12 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 0, @bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)));
13 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 1, @bitCast(i128, @intCast(u128, 0xFF6E5D4C3B2A190AFF6E5D4C3B2A190A)));
14 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 2, @bitCast(i128, @intCast(u128, 0xFFB72EA61D950C857FB72EA61D950C85)));
15 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 3, @bitCast(i128, @intCast(u128, 0xFFDB97530ECA8642BFDB97530ECA8642)));
16 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 4, @bitCast(i128, @intCast(u128, 0xFFEDCBA9876543215FEDCBA987654321)));
17
18 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 28, @bitCast(i128, @intCast(u128, 0xFFFFFFFFEDCBA9876543215FEDCBA987)));
19 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 29, @bitCast(i128, @intCast(u128, 0xFFFFFFFFF6E5D4C3B2A190AFF6E5D4C3)));
20 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 30, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFB72EA61D950C857FB72EA61)));
21 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 31, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFDB97530ECA8642BFDB97530)));
22
23 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 32, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFEDCBA9876543215FEDCBA98)));
24
25 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 33, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFF6E5D4C3B2A190AFF6E5D4C)));
26 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 34, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFB72EA61D950C857FB72EA6)));
27 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 35, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFDB97530ECA8642BFDB9753)));
28 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 36, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFEDCBA9876543215FEDCBA9)));
29
30 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 60, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFEDCBA9876543215F)));
31 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 61, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFF6E5D4C3B2A190AF)));
32 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 62, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFB72EA61D950C857)));
33 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 63, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFDB97530ECA8642B)));
34
35 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 64, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFEDCBA9876543215)));
36
37 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 65, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFF6E5D4C3B2A190A)));
38 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 66, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFB72EA61D950C85)));
39 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 67, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFDB97530ECA8642)));
40 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 68, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFEDCBA987654321)));
41
42 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 92, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFEDCBA987)));
43 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 93, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFF6E5D4C3)));
44 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 94, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFB72EA61)));
45 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 95, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFDB97530)));
46
47 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 96, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFEDCBA98)));
48
49 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 97, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFF6E5D4C)));
50 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 98, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFB72EA6)));
51 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 99, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFDB9753)));
52 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 100, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFEDCBA9)));
53
54 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 124, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)));
55 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 125, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)));
56 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 126, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)));
57 test__ashrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 127, @bitCast(i128, @intCast(u128, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)));
58}
std/special/compiler_rt/comparedf2.zig created+122
......@@ -0,0 +1,122 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparedf2.c
4
5const std = @import("std");
6const builtin = @import("builtin");
7const is_test = builtin.is_test;
8
9const fp_t = f64;
10const rep_t = u64;
11const srep_t = i64;
12
13const typeWidth = rep_t.bit_count;
14const significandBits = std.math.floatMantissaBits(fp_t);
15const exponentBits = std.math.floatExponentBits(fp_t);
16const signBit = (rep_t(1) << (significandBits + exponentBits));
17const absMask = signBit - 1;
18const implicitBit = rep_t(1) << significandBits;
19const significandMask = implicitBit - 1;
20const exponentMask = absMask ^ significandMask;
21const infRep = @bitCast(rep_t, std.math.inf(fp_t));
22
23// TODO https://github.com/ziglang/zig/issues/641
24// and then make the return types of some of these functions the enum instead of c_int
25const LE_LESS = c_int(-1);
26const LE_EQUAL = c_int(0);
27const LE_GREATER = c_int(1);
28const LE_UNORDERED = c_int(1);
29
30pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {
31 @setRuntimeSafety(is_test);
32 const aInt: srep_t = @bitCast(srep_t, a);
33 const bInt: srep_t = @bitCast(srep_t, b);
34 const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask;
35 const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask;
36
37 // If either a or b is NaN, they are unordered.
38 if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED;
39
40 // If a and b are both zeros, they are equal.
41 if ((aAbs | bAbs) == 0) return LE_EQUAL;
42
43 // If at least one of a and b is positive, we get the same result comparing
44 // a and b as signed integers as we would with a fp_ting-point compare.
45 if ((aInt & bInt) >= 0) {
46 if (aInt < bInt) {
47 return LE_LESS;
48 } else if (aInt == bInt) {
49 return LE_EQUAL;
50 } else return LE_GREATER;
51 }
52
53 // Otherwise, both are negative, so we need to flip the sense of the
54 // comparison to get the correct result. (This assumes a twos- or ones-
55 // complement integer representation; if integers are represented in a
56 // sign-magnitude representation, then this flip is incorrect).
57 else {
58 if (aInt > bInt) {
59 return LE_LESS;
60 } else if (aInt == bInt) {
61 return LE_EQUAL;
62 } else return LE_GREATER;
63 }
64}
65
66// TODO https://github.com/ziglang/zig/issues/641
67// and then make the return types of some of these functions the enum instead of c_int
68const GE_LESS = c_int(-1);
69const GE_EQUAL = c_int(0);
70const GE_GREATER = c_int(1);
71const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
72
73pub extern fn __gedf2(a: fp_t, b: fp_t) c_int {
74 @setRuntimeSafety(is_test);
75 const aInt: srep_t = @bitCast(srep_t, a);
76 const bInt: srep_t = @bitCast(srep_t, b);
77 const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask;
78 const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask;
79
80 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
81 if ((aAbs | bAbs) == 0) return GE_EQUAL;
82 if ((aInt & bInt) >= 0) {
83 if (aInt < bInt) {
84 return GE_LESS;
85 } else if (aInt == bInt) {
86 return GE_EQUAL;
87 } else return GE_GREATER;
88 } else {
89 if (aInt > bInt) {
90 return GE_LESS;
91 } else if (aInt == bInt) {
92 return GE_EQUAL;
93 } else return GE_GREATER;
94 }
95}
96
97pub extern fn __unorddf2(a: fp_t, b: fp_t) c_int {
98 @setRuntimeSafety(is_test);
99 const aAbs: rep_t = @bitCast(rep_t, a) & absMask;
100 const bAbs: rep_t = @bitCast(rep_t, b) & absMask;
101 return @boolToInt(aAbs > infRep or bAbs > infRep);
102}
103
104pub extern fn __eqdf2(a: fp_t, b: fp_t) c_int {
105 return __ledf2(a, b);
106}
107
108pub extern fn __ltdf2(a: fp_t, b: fp_t) c_int {
109 return __ledf2(a, b);
110}
111
112pub extern fn __nedf2(a: fp_t, b: fp_t) c_int {
113 return __ledf2(a, b);
114}
115
116pub extern fn __gtdf2(a: fp_t, b: fp_t) c_int {
117 return __gedf2(a, b);
118}
119
120test "import comparedf2" {
121 _ = @import("comparedf2_test.zig");
122}
std/special/compiler_rt/comparedf2_test.zig created+101
......@@ -0,0 +1,101 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/comparedf2_test.c
4
5const std = @import("std");
6const builtin = @import("builtin");
7const is_test = builtin.is_test;
8
9const comparedf2 = @import("comparedf2.zig");
10
11const TestVector = struct {
12 a: f64,
13 b: f64,
14 eqReference: c_int,
15 geReference: c_int,
16 gtReference: c_int,
17 leReference: c_int,
18 ltReference: c_int,
19 neReference: c_int,
20 unReference: c_int,
21};
22
23fn test__cmpdf2(vector: TestVector) bool {
24 if (comparedf2.__eqdf2(vector.a, vector.b) != vector.eqReference) {
25 return false;
26 }
27 if (comparedf2.__gedf2(vector.a, vector.b) != vector.geReference) {
28 return false;
29 }
30 if (comparedf2.__gtdf2(vector.a, vector.b) != vector.gtReference) {
31 return false;
32 }
33 if (comparedf2.__ledf2(vector.a, vector.b) != vector.leReference) {
34 return false;
35 }
36 if (comparedf2.__ltdf2(vector.a, vector.b) != vector.ltReference) {
37 return false;
38 }
39 if (comparedf2.__nedf2(vector.a, vector.b) != vector.neReference) {
40 return false;
41 }
42 if (comparedf2.__unorddf2(vector.a, vector.b) != vector.unReference) {
43 return false;
44 }
45 return true;
46}
47
48const arguments = []f64{
49 std.math.nan(f64),
50 -std.math.inf(f64),
51 -0x1.fffffffffffffp1023,
52 -0x1.0000000000001p0 - 0x1.0000000000000p0,
53 -0x1.fffffffffffffp-1,
54 -0x1.0000000000000p-1022,
55 -0x0.fffffffffffffp-1022,
56 -0x0.0000000000001p-1022,
57 -0.0,
58 0.0,
59 0x0.0000000000001p-1022,
60 0x0.fffffffffffffp-1022,
61 0x1.0000000000000p-1022,
62 0x1.fffffffffffffp-1,
63 0x1.0000000000000p0,
64 0x1.0000000000001p0,
65 0x1.fffffffffffffp1023,
66 std.math.inf(f64),
67};
68
69fn generateVector(comptime a: f64, comptime b: f64) TestVector {
70 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
71 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
72 const unResult = if (a != a or b != b) 1 else 0;
73 return TestVector{
74 .a = a,
75 .b = b,
76 .eqReference = leResult,
77 .geReference = geResult,
78 .gtReference = geResult,
79 .leReference = leResult,
80 .ltReference = leResult,
81 .neReference = leResult,
82 .unReference = unResult,
83 };
84}
85
86const test_vectors = init: {
87 @setEvalBranchQuota(10000);
88 var vectors: [arguments.len * arguments.len]TestVector = undefined;
89 for (arguments[0..]) |arg_i, i| {
90 for (arguments[0..]) |arg_j, j| {
91 vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j);
92 }
93 }
94 break :init vectors;
95};
96
97test "compare f64" {
98 for (test_vectors) |vector, i| {
99 std.testing.expect(test__cmpdf2(vector));
100 }
101}
std/special/compiler_rt/comparesf2.zig created+122
......@@ -0,0 +1,122 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/lib/builtins/comparesf2.c
4
5const std = @import("std");
6const builtin = @import("builtin");
7const is_test = builtin.is_test;
8
9const fp_t = f32;
10const rep_t = u32;
11const srep_t = i32;
12
13const typeWidth = rep_t.bit_count;
14const significandBits = std.math.floatMantissaBits(fp_t);
15const exponentBits = std.math.floatExponentBits(fp_t);
16const signBit = (rep_t(1) << (significandBits + exponentBits));
17const absMask = signBit - 1;
18const implicitBit = rep_t(1) << significandBits;
19const significandMask = implicitBit - 1;
20const exponentMask = absMask ^ significandMask;
21const infRep = @bitCast(rep_t, std.math.inf(fp_t));
22
23// TODO https://github.com/ziglang/zig/issues/641
24// and then make the return types of some of these functions the enum instead of c_int
25const LE_LESS = c_int(-1);
26const LE_EQUAL = c_int(0);
27const LE_GREATER = c_int(1);
28const LE_UNORDERED = c_int(1);
29
30pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {
31 @setRuntimeSafety(is_test);
32 const aInt: srep_t = @bitCast(srep_t, a);
33 const bInt: srep_t = @bitCast(srep_t, b);
34 const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask;
35 const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask;
36
37 // If either a or b is NaN, they are unordered.
38 if (aAbs > infRep or bAbs > infRep) return LE_UNORDERED;
39
40 // If a and b are both zeros, they are equal.
41 if ((aAbs | bAbs) == 0) return LE_EQUAL;
42
43 // If at least one of a and b is positive, we get the same result comparing
44 // a and b as signed integers as we would with a fp_ting-point compare.
45 if ((aInt & bInt) >= 0) {
46 if (aInt < bInt) {
47 return LE_LESS;
48 } else if (aInt == bInt) {
49 return LE_EQUAL;
50 } else return LE_GREATER;
51 }
52
53 // Otherwise, both are negative, so we need to flip the sense of the
54 // comparison to get the correct result. (This assumes a twos- or ones-
55 // complement integer representation; if integers are represented in a
56 // sign-magnitude representation, then this flip is incorrect).
57 else {
58 if (aInt > bInt) {
59 return LE_LESS;
60 } else if (aInt == bInt) {
61 return LE_EQUAL;
62 } else return LE_GREATER;
63 }
64}
65
66// TODO https://github.com/ziglang/zig/issues/641
67// and then make the return types of some of these functions the enum instead of c_int
68const GE_LESS = c_int(-1);
69const GE_EQUAL = c_int(0);
70const GE_GREATER = c_int(1);
71const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
72
73pub extern fn __gesf2(a: fp_t, b: fp_t) c_int {
74 @setRuntimeSafety(is_test);
75 const aInt: srep_t = @bitCast(srep_t, a);
76 const bInt: srep_t = @bitCast(srep_t, b);
77 const aAbs: rep_t = @bitCast(rep_t, aInt) & absMask;
78 const bAbs: rep_t = @bitCast(rep_t, bInt) & absMask;
79
80 if (aAbs > infRep or bAbs > infRep) return GE_UNORDERED;
81 if ((aAbs | bAbs) == 0) return GE_EQUAL;
82 if ((aInt & bInt) >= 0) {
83 if (aInt < bInt) {
84 return GE_LESS;
85 } else if (aInt == bInt) {
86 return GE_EQUAL;
87 } else return GE_GREATER;
88 } else {
89 if (aInt > bInt) {
90 return GE_LESS;
91 } else if (aInt == bInt) {
92 return GE_EQUAL;
93 } else return GE_GREATER;
94 }
95}
96
97pub extern fn __unordsf2(a: fp_t, b: fp_t) c_int {
98 @setRuntimeSafety(is_test);
99 const aAbs: rep_t = @bitCast(rep_t, a) & absMask;
100 const bAbs: rep_t = @bitCast(rep_t, b) & absMask;
101 return @boolToInt(aAbs > infRep or bAbs > infRep);
102}
103
104pub extern fn __eqsf2(a: fp_t, b: fp_t) c_int {
105 return __lesf2(a, b);
106}
107
108pub extern fn __ltsf2(a: fp_t, b: fp_t) c_int {
109 return __lesf2(a, b);
110}
111
112pub extern fn __nesf2(a: fp_t, b: fp_t) c_int {
113 return __lesf2(a, b);
114}
115
116pub extern fn __gtsf2(a: fp_t, b: fp_t) c_int {
117 return __gesf2(a, b);
118}
119
120test "import comparesf2" {
121 _ = @import("comparesf2_test.zig");
122}
std/special/compiler_rt/comparesf2_test.zig created+101
......@@ -0,0 +1,101 @@
1// Ported from:
2//
3// https://github.com/llvm/llvm-project/commit/d674d96bc56c0f377879d01c9d8dfdaaa7859cdb/compiler-rt/test/builtins/Unit/comparesf2_test.c
4
5const std = @import("std");
6const builtin = @import("builtin");
7const is_test = builtin.is_test;
8
9const comparesf2 = @import("comparesf2.zig");
10
11const TestVector = struct {
12 a: f32,
13 b: f32,
14 eqReference: c_int,
15 geReference: c_int,
16 gtReference: c_int,
17 leReference: c_int,
18 ltReference: c_int,
19 neReference: c_int,
20 unReference: c_int,
21};
22
23fn test__cmpsf2(vector: TestVector) bool {
24 if (comparesf2.__eqsf2(vector.a, vector.b) != vector.eqReference) {
25 return false;
26 }
27 if (comparesf2.__gesf2(vector.a, vector.b) != vector.geReference) {
28 return false;
29 }
30 if (comparesf2.__gtsf2(vector.a, vector.b) != vector.gtReference) {
31 return false;
32 }
33 if (comparesf2.__lesf2(vector.a, vector.b) != vector.leReference) {
34 return false;
35 }
36 if (comparesf2.__ltsf2(vector.a, vector.b) != vector.ltReference) {
37 return false;
38 }
39 if (comparesf2.__nesf2(vector.a, vector.b) != vector.neReference) {
40 return false;
41 }
42 if (comparesf2.__unordsf2(vector.a, vector.b) != vector.unReference) {
43 return false;
44 }
45 return true;
46}
47
48const arguments = []f32{
49 std.math.nan(f32),
50 -std.math.inf(f32),
51 -0x1.fffffep127,
52 -0x1.000002p0 - 0x1.000000p0,
53 -0x1.fffffep-1,
54 -0x1.000000p-126,
55 -0x0.fffffep-126,
56 -0x0.000002p-126,
57 -0.0,
58 0.0,
59 0x0.000002p-126,
60 0x0.fffffep-126,
61 0x1.000000p-126,
62 0x1.fffffep-1,
63 0x1.000000p0,
64 0x1.000002p0,
65 0x1.fffffep127,
66 std.math.inf(f32),
67};
68
69fn generateVector(comptime a: f32, comptime b: f32) TestVector {
70 const leResult = if (a < b) -1 else if (a == b) 0 else 1;
71 const geResult = if (a > b) 1 else if (a == b) 0 else -1;
72 const unResult = if (a != a or b != b) 1 else 0;
73 return TestVector{
74 .a = a,
75 .b = b,
76 .eqReference = leResult,
77 .geReference = geResult,
78 .gtReference = geResult,
79 .leReference = leResult,
80 .ltReference = leResult,
81 .neReference = leResult,
82 .unReference = unResult,
83 };
84}
85
86const test_vectors = init: {
87 @setEvalBranchQuota(10000);
88 var vectors: [arguments.len * arguments.len]TestVector = undefined;
89 for (arguments[0..]) |arg_i, i| {
90 for (arguments[0..]) |arg_j, j| {
91 vectors[(i * arguments.len) + j] = generateVector(arg_i, arg_j);
92 }
93 }
94 break :init vectors;
95};
96
97test "compare f32" {
98 for (test_vectors) |vector, i| {
99 std.testing.expect(test__cmpsf2(vector));
100 }
101}
std/special/compiler_rt/divti3.zig+3-3
......@@ -16,9 +16,9 @@ pub extern fn __divti3(a: i128, b: i128) i128 {
1616 return (@bitCast(i128, r) ^ s) -% s;
1717}
1818
19pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void {
20 @setRuntimeSafety(builtin.is_test);
21 compiler_rt.setXmm0(i128, __divti3(a.*, b.*));
19const v128 = @Vector(2, u64);
20pub extern fn __divti3_windows_x86_64(a: v128, b: v128) v128 {
21 return @bitCast(v128, @inlineCall(__divti3, @bitCast(i128, a), @bitCast(i128, b)));
2222}
2323
2424test "import divti3" {
std/special/compiler_rt/extendXfYf2.zig+10-4
......@@ -2,21 +2,27 @@ const std = @import("std");
22const builtin = @import("builtin");
33const is_test = builtin.is_test;
44
5pub extern fn __extendsfdf2(a: f32) f64 {
6 return @inlineCall(extendXfYf2, f64, f32, @bitCast(u32, a));
7}
8
59pub extern fn __extenddftf2(a: f64) f128 {
6 return extendXfYf2(f128, f64, a);
10 return @inlineCall(extendXfYf2, f128, f64, @bitCast(u64, a));
711}
812
913pub extern fn __extendsftf2(a: f32) f128 {
10 return extendXfYf2(f128, f32, a);
14 return @inlineCall(extendXfYf2, f128, f32, @bitCast(u32, a));
1115}
1216
1317pub extern fn __extendhfsf2(a: u16) f32 {
14 return extendXfYf2(f32, f16, @bitCast(f16, a));
18 return @inlineCall(extendXfYf2, f32, f16, a);
1519}
1620
1721const CHAR_BIT = 8;
1822
19inline fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
23fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @typeInfo(src_t).Float.bits)) dst_t {
24 @setRuntimeSafety(builtin.is_test);
25
2026 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);
2127 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);
2228 const srcSigBits = std.math.floatMantissaBits(src_t);
std/special/compiler_rt/floatdidf.zig created+22
......@@ -0,0 +1,22 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4const twop52: f64 = 0x1.0p52;
5const twop32: f64 = 0x1.0p32;
6
7pub extern fn __floatdidf(a: i64) f64 {
8 @setRuntimeSafety(builtin.is_test);
9
10 if (a == 0) return 0;
11
12 var low = @bitCast(i64, twop52);
13 const high = @intToFloat(f64, @truncate(i32, a >> 32)) * twop32;
14
15 low |= @bitCast(i64, a & 0xFFFFFFFF);
16
17 return (high - twop52) + @bitCast(f64, low);
18}
19
20test "import floatdidf" {
21 _ = @import("floatdidf_test.zig");
22}
std/special/compiler_rt/floatdidf_test.zig created+53
......@@ -0,0 +1,53 @@
1const __floatdidf = @import("floatdidf.zig").__floatdidf;
2const testing = @import("std").testing;
3
4fn test__floatdidf(a: i64, expected: f64) void {
5 const r = __floatdidf(a);
6 testing.expect(r == expected);
7}
8
9test "floatdidf" {
10 test__floatdidf(0, 0.0);
11 test__floatdidf(1, 1.0);
12 test__floatdidf(2, 2.0);
13 test__floatdidf(20, 20.0);
14 test__floatdidf(-1, -1.0);
15 test__floatdidf(-2, -2.0);
16 test__floatdidf(-20, -20.0);
17 test__floatdidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
18 test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
19 test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
20 test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
21 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
22 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000800)), -0x1.FFFFFFFFFFFFEp+62);
23 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
24 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000001000)), -0x1.FFFFFFFFFFFFCp+62);
25 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000000)), -0x1.000000p+63);
26 test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000001)), -0x1.000000p+63);
27 test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
28 test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
29 test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
30 test__floatdidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
31 test__floatdidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
32 test__floatdidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
33 test__floatdidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
34 test__floatdidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
35 test__floatdidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
36 test__floatdidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
37 test__floatdidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
38 test__floatdidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
39 test__floatdidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
40 test__floatdidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
41 test__floatdidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
42 test__floatdidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
43 test__floatdidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
44 test__floatdidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
45 test__floatdidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
46 test__floatdidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
47 test__floatdidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
48 test__floatdidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
49 test__floatdidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
50 test__floatdidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
51 test__floatdidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
52 test__floatdidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
53}
std/special/compiler_rt/floatsiXf.zig created+109
......@@ -0,0 +1,109 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const maxInt = std.math.maxInt;
4
5fn floatsiXf(comptime T: type, a: i32) T {
6 @setRuntimeSafety(builtin.is_test);
7
8 const Z = @IntType(false, T.bit_count);
9 const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
10
11 if (a == 0) {
12 return T(0.0);
13 }
14
15 const significandBits = std.math.floatMantissaBits(T);
16 const exponentBits = std.math.floatExponentBits(T);
17 const exponentBias = ((1 << exponentBits - 1) - 1);
18
19 const implicitBit = Z(1) << significandBits;
20 const signBit = Z(1 << Z.bit_count - 1);
21
22 const sign = a >> 31;
23 // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).
24 const abs_a = (a ^ sign) -% sign;
25 // The exponent is the width of abs(a)
26 const exp = Z(31 - @clz(abs_a));
27
28 const sign_bit = if (sign < 0) signBit else 0;
29
30 var mantissa: Z = undefined;
31 // Shift a into the significand field and clear the implicit bit.
32 if (exp <= significandBits) {
33 // No rounding needed
34 const shift = @intCast(S, significandBits - exp);
35 mantissa = @intCast(Z, @bitCast(u32, abs_a)) << shift ^ implicitBit;
36 } else {
37 const shift = @intCast(S, exp - significandBits);
38 // Round to the nearest number after truncation
39 mantissa = @intCast(Z, @bitCast(u32, abs_a)) >> shift ^ implicitBit;
40 // Align to the left and check if the truncated part is halfway over
41 const round = @bitCast(u32, abs_a) << @intCast(u5, 31 - shift);
42 mantissa += @boolToInt(round > 0x80000000);
43 // Tie to even
44 mantissa += mantissa & 1;
45 }
46
47 // Use the addition instead of a or since we may have a carry from the
48 // mantissa to the exponent
49 var result = mantissa;
50 result += (exp + exponentBias) << significandBits;
51 result += sign_bit;
52
53 return @bitCast(T, result);
54}
55
56pub extern fn __floatsisf(arg: i32) f32 {
57 @setRuntimeSafety(builtin.is_test);
58 return @inlineCall(floatsiXf, f32, arg);
59}
60
61pub extern fn __floatsidf(arg: i32) f64 {
62 @setRuntimeSafety(builtin.is_test);
63 return @inlineCall(floatsiXf, f64, arg);
64}
65
66pub extern fn __floatsitf(arg: i32) f128 {
67 @setRuntimeSafety(builtin.is_test);
68 return @inlineCall(floatsiXf, f128, arg);
69}
70
71fn test_one_floatsitf(a: i32, expected: u128) void {
72 const r = __floatsitf(a);
73 std.testing.expect(@bitCast(u128, r) == expected);
74}
75
76fn test_one_floatsidf(a: i32, expected: u64) void {
77 const r = __floatsidf(a);
78 std.testing.expect(@bitCast(u64, r) == expected);
79}
80
81fn test_one_floatsisf(a: i32, expected: u32) void {
82 const r = __floatsisf(a);
83 std.testing.expect(@bitCast(u32, r) == expected);
84}
85
86test "floatsidf" {
87 test_one_floatsidf(0, 0x0000000000000000);
88 test_one_floatsidf(1, 0x3ff0000000000000);
89 test_one_floatsidf(-1, 0xbff0000000000000);
90 test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);
91 test_one_floatsidf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xc1e0000000000000);
92}
93
94test "floatsisf" {
95 test_one_floatsisf(0, 0x00000000);
96 test_one_floatsisf(1, 0x3f800000);
97 test_one_floatsisf(-1, 0xbf800000);
98 test_one_floatsisf(0x7FFFFFFF, 0x4f000000);
99 test_one_floatsisf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xcf000000);
100}
101
102test "floatsitf" {
103 test_one_floatsitf(0, 0);
104 test_one_floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
105 test_one_floatsitf(0x12345678, 0x401b2345678000000000000000000000);
106 test_one_floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
107 test_one_floatsitf(@bitCast(i32, @intCast(u32, 0xffffffff)), 0xbfff0000000000000000000000000000);
108 test_one_floatsitf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xc01e0000000000000000000000000000);
109}
std/special/compiler_rt/floatundidf.zig created+24
......@@ -0,0 +1,24 @@
1const builtin = @import("builtin");
2const std = @import("std");
3
4const twop52: f64 = 0x1.0p52;
5const twop84: f64 = 0x1.0p84;
6const twop84_plus_twop52: f64 = 0x1.00000001p84;
7
8pub extern fn __floatundidf(a: u64) f64 {
9 @setRuntimeSafety(builtin.is_test);
10
11 if (a == 0) return 0;
12
13 var high = @bitCast(u64, twop84);
14 var low = @bitCast(u64, twop52);
15
16 high |= a >> 32;
17 low |= a & 0xFFFFFFFF;
18
19 return (@bitCast(f64, high) - twop84_plus_twop52) + @bitCast(f64, low);
20}
21
22test "import floatundidf" {
23 _ = @import("floatundidf_test.zig");
24}
std/special/compiler_rt/floatundidf_test.zig created+50
......@@ -0,0 +1,50 @@
1const __floatundidf = @import("floatundidf.zig").__floatundidf;
2const testing = @import("std").testing;
3
4fn test__floatundidf(a: u64, expected: f64) void {
5 const r = __floatundidf(a);
6 testing.expect(r == expected);
7}
8
9test "floatundidf" {
10 test__floatundidf(0, 0.0);
11 test__floatundidf(1, 1.0);
12 test__floatundidf(2, 2.0);
13 test__floatundidf(20, 20.0);
14 test__floatundidf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
15 test__floatundidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
16 test__floatundidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
17 test__floatundidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
18 test__floatundidf(0x8000008000000000, 0x1.000001p+63);
19 test__floatundidf(0x8000000000000800, 0x1.0000000000001p+63);
20 test__floatundidf(0x8000010000000000, 0x1.000002p+63);
21 test__floatundidf(0x8000000000001000, 0x1.0000000000002p+63);
22 test__floatundidf(0x8000000000000000, 0x1p+63);
23 test__floatundidf(0x8000000000000001, 0x1p+63);
24 test__floatundidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
25 test__floatundidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
26 test__floatundidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
27 test__floatundidf(0x0007FB72EBFFFFFF, 0x1.FEDCBAFFFFFFCp+50);
28 test__floatundidf(0x0007FB72EC000000, 0x1.FEDCBBp+50);
29 test__floatundidf(0x0007FB72E8000001, 0x1.FEDCBA0000004p+50);
30 test__floatundidf(0x0007FB72E6000000, 0x1.FEDCB98p+50);
31 test__floatundidf(0x0007FB72E7000000, 0x1.FEDCB9Cp+50);
32 test__floatundidf(0x0007FB72E7FFFFFF, 0x1.FEDCB9FFFFFFCp+50);
33 test__floatundidf(0x0007FB72E4000001, 0x1.FEDCB90000004p+50);
34 test__floatundidf(0x0007FB72E4000000, 0x1.FEDCB9p+50);
35 test__floatundidf(0x023479FD0E092DC0, 0x1.1A3CFE870496Ep+57);
36 test__floatundidf(0x023479FD0E092DA1, 0x1.1A3CFE870496Dp+57);
37 test__floatundidf(0x023479FD0E092DB0, 0x1.1A3CFE870496Ep+57);
38 test__floatundidf(0x023479FD0E092DB8, 0x1.1A3CFE870496Ep+57);
39 test__floatundidf(0x023479FD0E092DB6, 0x1.1A3CFE870496Ep+57);
40 test__floatundidf(0x023479FD0E092DBF, 0x1.1A3CFE870496Ep+57);
41 test__floatundidf(0x023479FD0E092DC1, 0x1.1A3CFE870496Ep+57);
42 test__floatundidf(0x023479FD0E092DC7, 0x1.1A3CFE870496Ep+57);
43 test__floatundidf(0x023479FD0E092DC8, 0x1.1A3CFE870496Ep+57);
44 test__floatundidf(0x023479FD0E092DCF, 0x1.1A3CFE870496Ep+57);
45 test__floatundidf(0x023479FD0E092DD0, 0x1.1A3CFE870496Ep+57);
46 test__floatundidf(0x023479FD0E092DD1, 0x1.1A3CFE870496Fp+57);
47 test__floatundidf(0x023479FD0E092DD8, 0x1.1A3CFE870496Fp+57);
48 test__floatundidf(0x023479FD0E092DDF, 0x1.1A3CFE870496Fp+57);
49 test__floatundidf(0x023479FD0E092DE0, 0x1.1A3CFE870496Fp+57);
50}
std/special/compiler_rt/floatunsidf.zig created+33
......@@ -0,0 +1,33 @@
1const builtin = @import("builtin");
2const std = @import("std");
3const maxInt = std.math.maxInt;
4
5const implicitBit = u64(1) << 52;
6
7pub extern fn __floatunsidf(arg: u32) f64 {
8 @setRuntimeSafety(builtin.is_test);
9
10 if (arg == 0) return 0.0;
11
12 // The exponent is the width of abs(a)
13 const exp = u64(31) - @clz(arg);
14 // Shift a into the significand field and clear the implicit bit
15 const shift = @intCast(u6, 52 - exp);
16 const mant = u64(arg) << shift ^ implicitBit;
17
18 return @bitCast(f64, mant | (exp + 1023) << 52);
19}
20
21fn test_one_floatunsidf(a: u32, expected: u64) void {
22 const r = __floatunsidf(a);
23 std.testing.expect(@bitCast(u64, r) == expected);
24}
25
26test "floatsidf" {
27 // Test the produced bit pattern
28 test_one_floatunsidf(0, 0x0000000000000000);
29 test_one_floatunsidf(1, 0x3ff0000000000000);
30 test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);
31 test_one_floatunsidf(@intCast(u32, 0x80000000), 0x41e0000000000000);
32 test_one_floatunsidf(@intCast(u32, 0xFFFFFFFF), 0x41efffffffe00000);
33}
std/special/compiler_rt/lshrti3.zig created+41
......@@ -0,0 +1,41 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3
4pub extern fn __lshrti3(a: i128, b: i32) i128 {
5 var input = twords{ .all = a };
6 var result: twords = undefined;
7
8 if (b > 63) {
9 // 64 <= b < 128
10 result.s.low = input.s.high >> @intCast(u6, b - 64);
11 result.s.high = 0;
12 } else {
13 // 0 <= b < 64
14 if (b == 0) return a;
15 result.s.low = input.s.high << @intCast(u6, 64 - b);
16 result.s.low |= input.s.low >> @intCast(u6, b);
17 result.s.high = input.s.high >> @intCast(u6, b);
18 }
19
20 return result.all;
21}
22
23const twords = extern union {
24 all: i128,
25 s: S,
26
27 const S = if (builtin.endian == builtin.Endian.Little)
28 struct {
29 low: u64,
30 high: u64,
31 }
32 else
33 struct {
34 high: u64,
35 low: u64,
36 };
37};
38
39test "import lshrti3" {
40 _ = @import("lshrti3_test.zig");
41}
std/special/compiler_rt/lshrti3_test.zig created+46
......@@ -0,0 +1,46 @@
1const __lshrti3 = @import("lshrti3.zig").__lshrti3;
2const testing = @import("std").testing;
3
4fn test__lshrti3(a: i128, b: i32, expected: i128) void {
5 const x = __lshrti3(a, b);
6 testing.expect(x == expected);
7}
8
9test "lshrti3" {
10 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 0, @bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)));
11 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 1, @bitCast(i128, @intCast(u128, 0x7F6E5D4C3B2A190AFF6E5D4C3B2A190A)));
12 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 2, @bitCast(i128, @intCast(u128, 0x3FB72EA61D950C857FB72EA61D950C85)));
13 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 3, @bitCast(i128, @intCast(u128, 0x1FDB97530ECA8642BFDB97530ECA8642)));
14 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 4, @bitCast(i128, @intCast(u128, 0x0FEDCBA9876543215FEDCBA987654321)));
15 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 28, @bitCast(i128, @intCast(u128, 0x0000000FEDCBA9876543215FEDCBA987)));
16 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 29, @bitCast(i128, @intCast(u128, 0x00000007F6E5D4C3B2A190AFF6E5D4C3)));
17 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 30, @bitCast(i128, @intCast(u128, 0x00000003FB72EA61D950C857FB72EA61)));
18 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 31, @bitCast(i128, @intCast(u128, 0x00000001FDB97530ECA8642BFDB97530)));
19 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 32, @bitCast(i128, @intCast(u128, 0x00000000FEDCBA9876543215FEDCBA98)));
20 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 33, @bitCast(i128, @intCast(u128, 0x000000007F6E5D4C3B2A190AFF6E5D4C)));
21 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 34, @bitCast(i128, @intCast(u128, 0x000000003FB72EA61D950C857FB72EA6)));
22 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 35, @bitCast(i128, @intCast(u128, 0x000000001FDB97530ECA8642BFDB9753)));
23 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 36, @bitCast(i128, @intCast(u128, 0x000000000FEDCBA9876543215FEDCBA9)));
24 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 60, @bitCast(i128, @intCast(u128, 0x000000000000000FEDCBA9876543215F)));
25 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 61, @bitCast(i128, @intCast(u128, 0x0000000000000007F6E5D4C3B2A190AF)));
26 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 62, @bitCast(i128, @intCast(u128, 0x0000000000000003FB72EA61D950C857)));
27 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 63, @bitCast(i128, @intCast(u128, 0x0000000000000001FDB97530ECA8642B)));
28 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 64, @bitCast(i128, @intCast(u128, 0x0000000000000000FEDCBA9876543215)));
29 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 65, @bitCast(i128, @intCast(u128, 0x00000000000000007F6E5D4C3B2A190A)));
30 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 66, @bitCast(i128, @intCast(u128, 0x00000000000000003FB72EA61D950C85)));
31 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 67, @bitCast(i128, @intCast(u128, 0x00000000000000001FDB97530ECA8642)));
32 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 68, @bitCast(i128, @intCast(u128, 0x00000000000000000FEDCBA987654321)));
33 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 92, @bitCast(i128, @intCast(u128, 0x00000000000000000000000FEDCBA987)));
34 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 93, @bitCast(i128, @intCast(u128, 0x000000000000000000000007F6E5D4C3)));
35 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 94, @bitCast(i128, @intCast(u128, 0x000000000000000000000003FB72EA61)));
36 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 95, @bitCast(i128, @intCast(u128, 0x000000000000000000000001FDB97530)));
37 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 96, @bitCast(i128, @intCast(u128, 0x000000000000000000000000FEDCBA98)));
38 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 97, @bitCast(i128, @intCast(u128, 0x0000000000000000000000007F6E5D4C)));
39 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 98, @bitCast(i128, @intCast(u128, 0x0000000000000000000000003FB72EA6)));
40 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 99, @bitCast(i128, @intCast(u128, 0x0000000000000000000000001FDB9753)));
41 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 100, @bitCast(i128, @intCast(u128, 0x0000000000000000000000000FEDCBA9)));
42 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 124, @bitCast(i128, @intCast(u128, 0x0000000000000000000000000000000F)));
43 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 125, @bitCast(i128, @intCast(u128, 0x00000000000000000000000000000007)));
44 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 126, @bitCast(i128, @intCast(u128, 0x00000000000000000000000000000003)));
45 test__lshrti3(@bitCast(i128, @intCast(u128, 0xFEDCBA9876543215FEDCBA9876543215)), 127, @bitCast(i128, @intCast(u128, 0x00000000000000000000000000000001)));
46}
std/special/compiler_rt/modti3.zig+3-3
......@@ -20,9 +20,9 @@ pub extern fn __modti3(a: i128, b: i128) i128 {
2020 return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1
2121}
2222
23pub extern fn __modti3_windows_x86_64(a: *const i128, b: *const i128) void {
24 @setRuntimeSafety(builtin.is_test);
25 compiler_rt.setXmm0(i128, __modti3(a.*, b.*));
23const v128 = @Vector(2, u64);
24pub extern fn __modti3_windows_x86_64(a: v128, b: v128) v128 {
25 return @bitCast(v128, @inlineCall(__modti3, @bitCast(i128, a), @bitCast(i128, b)));
2626}
2727
2828test "import modti3" {
std/special/compiler_rt/mulodi4.zig created+44
......@@ -0,0 +1,44 @@
1const builtin = @import("builtin");
2const compiler_rt = @import("../compiler_rt.zig");
3const maxInt = std.math.maxInt;
4const minInt = std.math.minInt;
5
6pub extern fn __mulodi4(a: i64, b: i64, overflow: *c_int) i64 {
7 @setRuntimeSafety(builtin.is_test);
8
9 const min = @bitCast(i64, u64(1 << (i64.bit_count - 1)));
10 const max = ~min;
11
12 overflow.* = 0;
13 const result = a *% b;
14
15 // Edge cases
16 if (a == min) {
17 if (b != 0 and b != 1) overflow.* = 1;
18 return result;
19 }
20 if (b == min) {
21 if (a != 0 and a != 1) overflow.* = 1;
22 return result;
23 }
24
25 // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
26 const abs_a = (a ^ (a >> 63)) -% (a >> 63);
27 const abs_b = (b ^ (b >> 63)) -% (b >> 63);
28
29 // Unitary magnitude, cannot have overflow
30 if (abs_a < 2 or abs_b < 2) return result;
31
32 // Compare the signs of the operands
33 if ((a ^ b) >> 63 != 0) {
34 if (abs_a > @divTrunc(max, abs_b)) overflow.* = 1;
35 } else {
36 if (abs_a > @divTrunc(min, -abs_b)) overflow.* = 1;
37 }
38
39 return result;
40}
41
42test "import mulodi4" {
43 _ = @import("mulodi4_test.zig");
44}
std/special/compiler_rt/mulodi4_test.zig created+85
......@@ -0,0 +1,85 @@
1const __mulodi4 = @import("mulodi4.zig").__mulodi4;
2const testing = @import("std").testing;
3
4fn test__mulodi4(a: i64, b: i64, expected: i64, expected_overflow: c_int) void {
5 var overflow: c_int = undefined;
6 const x = __mulodi4(a, b, &overflow);
7 testing.expect(overflow == expected_overflow and (expected_overflow != 0 or x == expected));
8}
9
10test "mulodi4" {
11 test__mulodi4(0, 0, 0, 0);
12 test__mulodi4(0, 1, 0, 0);
13 test__mulodi4(1, 0, 0, 0);
14 test__mulodi4(0, 10, 0, 0);
15 test__mulodi4(10, 0, 0, 0);
16 test__mulodi4(0, 81985529216486895, 0, 0);
17 test__mulodi4(81985529216486895, 0, 0, 0);
18
19 test__mulodi4(0, -1, 0, 0);
20 test__mulodi4(-1, 0, 0, 0);
21 test__mulodi4(0, -10, 0, 0);
22 test__mulodi4(-10, 0, 0, 0);
23 test__mulodi4(0, -81985529216486895, 0, 0);
24 test__mulodi4(-81985529216486895, 0, 0, 0);
25
26 test__mulodi4(1, 1, 1, 0);
27 test__mulodi4(1, 10, 10, 0);
28 test__mulodi4(10, 1, 10, 0);
29 test__mulodi4(1, 81985529216486895, 81985529216486895, 0);
30 test__mulodi4(81985529216486895, 1, 81985529216486895, 0);
31
32 test__mulodi4(1, -1, -1, 0);
33 test__mulodi4(1, -10, -10, 0);
34 test__mulodi4(-10, 1, -10, 0);
35 test__mulodi4(1, -81985529216486895, -81985529216486895, 0);
36 test__mulodi4(-81985529216486895, 1, -81985529216486895, 0);
37
38 test__mulodi4(3037000499, 3037000499, 9223372030926249001, 0);
39 test__mulodi4(-3037000499, 3037000499, -9223372030926249001, 0);
40 test__mulodi4(3037000499, -3037000499, -9223372030926249001, 0);
41 test__mulodi4(-3037000499, -3037000499, 9223372030926249001, 0);
42
43 test__mulodi4(4398046511103, 2097152, 9223372036852678656, 0);
44 test__mulodi4(-4398046511103, 2097152, -9223372036852678656, 0);
45 test__mulodi4(4398046511103, -2097152, -9223372036852678656, 0);
46 test__mulodi4(-4398046511103, -2097152, 9223372036852678656, 0);
47
48 test__mulodi4(2097152, 4398046511103, 9223372036852678656, 0);
49 test__mulodi4(-2097152, 4398046511103, -9223372036852678656, 0);
50 test__mulodi4(2097152, -4398046511103, -9223372036852678656, 0);
51 test__mulodi4(-2097152, -4398046511103, 9223372036852678656, 0);
52
53 test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1);
54 test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);
55 test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, u64(0x8000000000000001)), 0);
56 test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 0);
57 test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0);
58 test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0);
59 test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);
60 test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);
61 test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, u64(0x8000000000000001)), 1);
62 test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 1);
63
64 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -2, @bitCast(i64, u64(0x8000000000000000)), 1);
65 test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
66 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)), 1);
67 test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
68 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 0, 0, 0);
69 test__mulodi4(0, @bitCast(i64, u64(0x8000000000000000)), 0, 0);
70 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)), 0);
71 test__mulodi4(1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 0);
72 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);
73 test__mulodi4(2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);
74
75 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -2, @bitCast(i64, u64(0x8000000000000001)), 1);
76 test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 1);
77 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);
78 test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);
79 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 0, 0, 0);
80 test__mulodi4(0, @bitCast(i64, u64(0x8000000000000001)), 0, 0);
81 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 1, @bitCast(i64, u64(0x8000000000000001)), 0);
82 test__mulodi4(1, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 0);
83 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);
84 test__mulodi4(2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000000)), 1);
85}
std/special/compiler_rt/muloti4.zig+2-8
......@@ -1,4 +1,3 @@
1const udivmod = @import("udivmod.zig").udivmod;
21const builtin = @import("builtin");
32const compiler_rt = @import("../compiler_rt.zig");
43
......@@ -33,11 +32,11 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
3332 }
3433
3534 if (sa == sb) {
36 if (abs_a > @divFloor(max, abs_b)) {
35 if (abs_a > @divTrunc(max, abs_b)) {
3736 overflow.* = 1;
3837 }
3938 } else {
40 if (abs_a > @divFloor(min, -abs_b)) {
39 if (abs_a > @divTrunc(min, -abs_b)) {
4140 overflow.* = 1;
4241 }
4342 }
......@@ -45,11 +44,6 @@ pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
4544 return r;
4645}
4746
48pub extern fn __muloti4_windows_x86_64(a: *const i128, b: *const i128, overflow: *c_int) void {
49 @setRuntimeSafety(builtin.is_test);
50 compiler_rt.setXmm0(i128, __muloti4(a.*, b.*, overflow));
51}
52
5347test "import muloti4" {
5448 _ = @import("muloti4_test.zig");
5549}
std/special/compiler_rt/multi3.zig+3-3
......@@ -14,9 +14,9 @@ pub extern fn __multi3(a: i128, b: i128) i128 {
1414 return r.all;
1515}
1616
17pub extern fn __multi3_windows_x86_64(a: *const i128, b: *const i128) void {
18 @setRuntimeSafety(builtin.is_test);
19 compiler_rt.setXmm0(i128, __multi3(a.*, b.*));
17const v128 = @Vector(2, u64);
18pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 {
19 return @bitCast(v128, @inlineCall(__multi3, @bitCast(i128, a), @bitCast(i128, b)));
2020}
2121
2222fn __mulddi3(a: u64, b: u64) i128 {
std/special/compiler_rt/stack_probe.zig created+206
......@@ -0,0 +1,206 @@
1const builtin = @import("builtin");
2
3// Zig's own stack-probe routine (available only on x86 and x86_64)
4pub nakedcc fn zig_probe_stack() void {
5 @setRuntimeSafety(false);
6
7 // Versions of the Linux kernel before 5.1 treat any access below SP as
8 // invalid so let's update it on the go, otherwise we'll get a segfault
9 // instead of triggering the stack growth.
10
11 switch (builtin.arch) {
12 .x86_64 => {
13 // %rax = probe length, %rsp = stack pointer
14 asm volatile (
15 \\ push %%rcx
16 \\ mov %%rax, %%rcx
17 \\ cmp $0x1000,%%rcx
18 \\ jb 2f
19 \\ 1:
20 \\ sub $0x1000,%%rsp
21 \\ orl $0,16(%%rsp)
22 \\ sub $0x1000,%%rcx
23 \\ cmp $0x1000,%%rcx
24 \\ ja 1b
25 \\ 2:
26 \\ sub %%rcx, %%rsp
27 \\ orl $0,16(%%rsp)
28 \\ add %%rax,%%rsp
29 \\ pop %%rcx
30 \\ ret
31 );
32 },
33 .i386 => {
34 // %eax = probe length, %esp = stack pointer
35 asm volatile (
36 \\ push %%ecx
37 \\ mov %%eax, %%ecx
38 \\ cmp $0x1000,%%ecx
39 \\ jb 2f
40 \\ 1:
41 \\ sub $0x1000,%%esp
42 \\ orl $0,8(%%esp)
43 \\ sub $0x1000,%%ecx
44 \\ cmp $0x1000,%%ecx
45 \\ ja 1b
46 \\ 2:
47 \\ sub %%ecx, %%esp
48 \\ orl $0,8(%%esp)
49 \\ add %%eax,%%esp
50 \\ pop %%ecx
51 \\ ret
52 );
53 },
54 else => { }
55 }
56
57 unreachable;
58}
59
60fn win_probe_stack_only() void {
61 @setRuntimeSafety(false);
62
63 switch (builtin.arch) {
64 .x86_64 => {
65 asm volatile (
66 \\ push %%rcx
67 \\ push %%rax
68 \\ cmp $0x1000,%%rax
69 \\ lea 24(%%rsp),%%rcx
70 \\ jb 1f
71 \\ 2:
72 \\ sub $0x1000,%%rcx
73 \\ test %%rcx,(%%rcx)
74 \\ sub $0x1000,%%rax
75 \\ cmp $0x1000,%%rax
76 \\ ja 2b
77 \\ 1:
78 \\ sub %%rax,%%rcx
79 \\ test %%rcx,(%%rcx)
80 \\ pop %%rax
81 \\ pop %%rcx
82 \\ ret
83 );
84 },
85 .i386 => {
86 asm volatile (
87 \\ push %%ecx
88 \\ push %%eax
89 \\ cmp $0x1000,%%eax
90 \\ lea 12(%%esp),%%ecx
91 \\ jb 1f
92 \\ 2:
93 \\ sub $0x1000,%%ecx
94 \\ test %%ecx,(%%ecx)
95 \\ sub $0x1000,%%eax
96 \\ cmp $0x1000,%%eax
97 \\ ja 2b
98 \\ 1:
99 \\ sub %%eax,%%ecx
100 \\ test %%ecx,(%%ecx)
101 \\ pop %%eax
102 \\ pop %%ecx
103 \\ ret
104 );
105 },
106 else => { }
107 }
108
109 unreachable;
110}
111
112fn win_probe_stack_adjust_sp() void {
113 @setRuntimeSafety(false);
114
115 switch (builtin.arch) {
116 .x86_64 => {
117 asm volatile (
118 \\ push %%rcx
119 \\ cmp $0x1000,%%rax
120 \\ lea 16(%%rsp),%%rcx
121 \\ jb 1f
122 \\ 2:
123 \\ sub $0x1000,%%rcx
124 \\ test %%rcx,(%%rcx)
125 \\ sub $0x1000,%%rax
126 \\ cmp $0x1000,%%rax
127 \\ ja 2b
128 \\ 1:
129 \\ sub %%rax,%%rcx
130 \\ test %%rcx,(%%rcx)
131 \\
132 \\ lea 8(%%rsp),%%rax
133 \\ mov %%rcx,%%rsp
134 \\ mov -8(%%rax),%%rcx
135 \\ push (%%rax)
136 \\ sub %%rsp,%%rax
137 \\ ret
138 );
139 },
140 .i386 => {
141 asm volatile (
142 \\ push %%ecx
143 \\ cmp $0x1000,%%eax
144 \\ lea 8(%%esp),%%ecx
145 \\ jb 1f
146 \\ 2:
147 \\ sub $0x1000,%%ecx
148 \\ test %%ecx,(%%ecx)
149 \\ sub $0x1000,%%eax
150 \\ cmp $0x1000,%%eax
151 \\ ja 2b
152 \\ 1:
153 \\ sub %%eax,%%ecx
154 \\ test %%ecx,(%%ecx)
155 \\
156 \\ lea 4(%%esp),%%eax
157 \\ mov %%ecx,%%esp
158 \\ mov -4(%%eax),%%ecx
159 \\ push (%%eax)
160 \\ sub %%esp,%%eax
161 \\ ret
162 );
163 },
164 else => { },
165 }
166
167 unreachable;
168}
169
170// Windows has a multitude of stack-probing functions with similar names and
171// slightly different behaviours: some behave as alloca() and update the stack
172// pointer after probing the stack, other do not.
173//
174// Function name | Adjusts the SP? |
175// | x86 | x86_64 |
176// ----------------------------------------
177// _chkstk (_alloca) | yes | yes |
178// __chkstk | yes | no |
179// __chkstk_ms | no | no |
180// ___chkstk (__alloca) | yes | yes |
181// ___chkstk_ms | no | no |
182
183pub nakedcc fn _chkstk() void {
184 @setRuntimeSafety(false);
185 @inlineCall(win_probe_stack_adjust_sp);
186}
187pub nakedcc fn __chkstk() void {
188 @setRuntimeSafety(false);
189 switch (builtin.arch) {
190 .i386 => @inlineCall(win_probe_stack_adjust_sp),
191 .x86_64 => @inlineCall(win_probe_stack_only),
192 else => unreachable
193 }
194}
195pub nakedcc fn ___chkstk() void {
196 @setRuntimeSafety(false);
197 @inlineCall(win_probe_stack_adjust_sp);
198}
199pub nakedcc fn __chkstk_ms() void {
200 @setRuntimeSafety(false);
201 @inlineCall(win_probe_stack_only);
202}
203pub nakedcc fn ___chkstk_ms() void {
204 @setRuntimeSafety(false);
205 @inlineCall(win_probe_stack_only);
206}
std/special/compiler_rt/truncXfYf2.zig+4
......@@ -16,6 +16,10 @@ pub extern fn __trunctfdf2(a: f128) f64 {
1616 return truncXfYf2(f64, f128, a);
1717}
1818
19pub extern fn __truncdfsf2(a: f64) f32 {
20 return truncXfYf2(f32, f64, a);
21}
22
1923inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
2024 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);
2125 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);
std/special/compiler_rt/truncXfYf2_test.zig+37
......@@ -200,3 +200,40 @@ test "trunctfdf2" {
200200 test__trunctfdf2(0x1.2f34dd5f437e849b4baab754cdefp+4534, 0x7ff0000000000000);
201201 test__trunctfdf2(0x1.edcbff8ad76ab5bf46463233214fp-435, 0x24cedcbff8ad76ab);
202202}
203
204const __truncdfsf2 = @import("truncXfYf2.zig").__truncdfsf2;
205
206fn test__truncdfsf2(a: f64, expected: u32) void {
207 const x = __truncdfsf2(a);
208
209 const rep = @bitCast(u32, x);
210 if (rep == expected) {
211 return;
212 }
213 // test other possible NaN representation(signal NaN)
214 else if (expected == 0x7fc00000) {
215 if ((rep & 0x7f800000) == 0x7f800000 and (rep & 0x7fffff) > 0) {
216 return;
217 }
218 }
219
220 @import("std").debug.warn("got 0x{x} wanted 0x{x}\n", rep, expected);
221
222 @panic("__trunctfsf2 test failure");
223}
224
225test "truncdfsf2" {
226 // nan & qnan
227 test__truncdfsf2(@bitCast(f64, u64(0x7ff8000000000000)), 0x7fc00000);
228 test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000001)), 0x7fc00000);
229 // inf
230 test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000000)), 0x7f800000);
231 test__truncdfsf2(@bitCast(f64, u64(0xfff0000000000000)), 0xff800000);
232
233 test__truncdfsf2(0.0, 0x0);
234 test__truncdfsf2(1.0, 0x3f800000);
235 test__truncdfsf2(-1.0, 0xbf800000);
236
237 // huge number becomes inf
238 test__truncdfsf2(340282366920938463463374607431768211456.0, 0x7f800000);
239}
std/special/compiler_rt/udivmodti4.zig+3-2
......@@ -7,9 +7,10 @@ pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?*u128) u128 {
77 return udivmod(u128, a, b, maybe_rem);
88}
99
10pub extern fn __udivmodti4_windows_x86_64(a: *const u128, b: *const u128, maybe_rem: ?*u128) void {
10const v128 = @Vector(2, u64);
11pub extern fn __udivmodti4_windows_x86_64(a: v128, b: v128, maybe_rem: ?*u128) v128 {
1112 @setRuntimeSafety(builtin.is_test);
12 compiler_rt.setXmm0(u128, udivmod(u128, a.*, b.*, maybe_rem));
13 return @bitCast(v128, udivmod(u128, @bitCast(u128, a), @bitCast(u128, b), maybe_rem));
1314}
1415
1516test "import udivmodti4" {
std/special/compiler_rt/udivti3.zig+3-2
......@@ -6,7 +6,8 @@ pub extern fn __udivti3(a: u128, b: u128) u128 {
66 return udivmodti4.__udivmodti4(a, b, null);
77}
88
9pub extern fn __udivti3_windows_x86_64(a: *const u128, b: *const u128) void {
9const v128 = @Vector(2, u64);
10pub extern fn __udivti3_windows_x86_64(a: v128, b: v128) v128 {
1011 @setRuntimeSafety(builtin.is_test);
11 udivmodti4.__udivmodti4_windows_x86_64(a, b, null);
12 return udivmodti4.__udivmodti4_windows_x86_64(a, b, null);
1213}
std/special/compiler_rt/umodti3.zig+3-3
......@@ -9,7 +9,7 @@ pub extern fn __umodti3(a: u128, b: u128) u128 {
99 return r;
1010}
1111
12pub extern fn __umodti3_windows_x86_64(a: *const u128, b: *const u128) void {
13 @setRuntimeSafety(builtin.is_test);
14 compiler_rt.setXmm0(u128, __umodti3(a.*, b.*));
12const v128 = @Vector(2, u64);
13pub extern fn __umodti3_windows_x86_64(a: v128, b: v128) v128 {
14 return @bitCast(v128, @inlineCall(__umodti3, @bitCast(u128, a), @bitCast(u128, b)));
1515}
std/special/fmt_runner.zig deleted-260
......@@ -1,260 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3
4const os = std.os;
5const io = std.io;
6const mem = std.mem;
7const Allocator = mem.Allocator;
8const ArrayList = std.ArrayList;
9const Buffer = std.Buffer;
10const ast = std.zig.ast;
11
12const arg = @import("fmt/arg.zig");
13const self_hosted_main = @import("fmt/main.zig");
14const Args = arg.Args;
15const Flag = arg.Flag;
16const errmsg = @import("fmt/errmsg.zig");
17
18var stderr_file: os.File = undefined;
19var stderr: *io.OutStream(os.File.WriteError) = undefined;
20var stdout: *io.OutStream(os.File.WriteError) = undefined;
21
22// This brings `zig fmt` to stage 1.
23pub fn main() !void {
24 // Here we use an ArenaAllocator backed by a DirectAllocator because `zig fmt` is a short-lived,
25 // one shot program. We don't need to waste time freeing memory and finding places to squish
26 // bytes into. So we free everything all at once at the very end.
27 var direct_allocator = std.heap.DirectAllocator.init();
28 var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
29 const allocator = &arena.allocator;
30
31 var stdout_file = try std.io.getStdOut();
32 var stdout_out_stream = stdout_file.outStream();
33 stdout = &stdout_out_stream.stream;
34
35 stderr_file = try std.io.getStdErr();
36 var stderr_out_stream = stderr_file.outStream();
37 stderr = &stderr_out_stream.stream;
38 const args = try std.os.argsAlloc(allocator);
39
40 var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[1..]);
41 defer flags.deinit();
42
43 if (flags.present("help")) {
44 try stdout.write(self_hosted_main.usage_fmt);
45 os.exit(0);
46 }
47
48 const color = blk: {
49 if (flags.single("color")) |color_flag| {
50 if (mem.eql(u8, color_flag, "auto")) {
51 break :blk errmsg.Color.Auto;
52 } else if (mem.eql(u8, color_flag, "on")) {
53 break :blk errmsg.Color.On;
54 } else if (mem.eql(u8, color_flag, "off")) {
55 break :blk errmsg.Color.Off;
56 } else unreachable;
57 } else {
58 break :blk errmsg.Color.Auto;
59 }
60 };
61
62 if (flags.present("stdin")) {
63 if (flags.positionals.len != 0) {
64 try stderr.write("cannot use --stdin with positional arguments\n");
65 os.exit(1);
66 }
67
68 var stdin_file = try io.getStdIn();
69 var stdin = stdin_file.inStream();
70
71 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
72 defer allocator.free(source_code);
73
74 var tree = std.zig.parse(allocator, source_code) catch |err| {
75 try stderr.print("error parsing stdin: {}\n", err);
76 os.exit(1);
77 };
78 defer tree.deinit();
79
80 var error_it = tree.errors.iterator(0);
81 while (error_it.next()) |parse_error| {
82 try printErrMsgToFile(allocator, parse_error, &tree, "<stdin>", stderr_file, color);
83 }
84 if (tree.errors.len != 0) {
85 os.exit(1);
86 }
87 if (flags.present("check")) {
88 const anything_changed = try std.zig.render(allocator, io.null_out_stream, &tree);
89 const code = if (anything_changed) u8(1) else u8(0);
90 os.exit(code);
91 }
92
93 _ = try std.zig.render(allocator, stdout, &tree);
94 return;
95 }
96
97 if (flags.positionals.len == 0) {
98 try stderr.write("expected at least one source file argument\n");
99 os.exit(1);
100 }
101
102 var fmt = Fmt{
103 .seen = Fmt.SeenMap.init(allocator),
104 .any_error = false,
105 .color = color,
106 .allocator = allocator,
107 };
108
109 const check_mode = flags.present("check");
110
111 for (flags.positionals.toSliceConst()) |file_path| {
112 try fmtPath(&fmt, file_path, check_mode);
113 }
114 if (fmt.any_error) {
115 os.exit(1);
116 }
117}
118
119const FmtError = error{
120 SystemResources,
121 OperationAborted,
122 IoPending,
123 BrokenPipe,
124 Unexpected,
125 WouldBlock,
126 FileClosed,
127 DestinationAddressRequired,
128 DiskQuota,
129 FileTooBig,
130 InputOutput,
131 NoSpaceLeft,
132 AccessDenied,
133 OutOfMemory,
134 RenameAcrossMountPoints,
135 ReadOnlyFileSystem,
136 LinkQuotaExceeded,
137 FileBusy,
138} || os.File.OpenError;
139
140fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
141 const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
142 defer fmt.allocator.free(file_path);
143
144 if (try fmt.seen.put(file_path, {})) |_| return;
145
146 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
147 error.IsDir, error.AccessDenied => {
148 // TODO make event based (and dir.next())
149 var dir = try std.os.Dir.open(fmt.allocator, file_path);
150 defer dir.close();
151
152 while (try dir.next()) |entry| {
153 if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
154 const full_path = try os.path.join(fmt.allocator, [][]const u8{ file_path, entry.name });
155 try fmtPath(fmt, full_path, check_mode);
156 }
157 }
158 return;
159 },
160 else => {
161 // TODO lock stderr printing
162 try stderr.print("unable to open '{}': {}\n", file_path, err);
163 fmt.any_error = true;
164 return;
165 },
166 };
167 defer fmt.allocator.free(source_code);
168
169 var tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
170 try stderr.print("error parsing file '{}': {}\n", file_path, err);
171 fmt.any_error = true;
172 return;
173 };
174 defer tree.deinit();
175
176 var error_it = tree.errors.iterator(0);
177 while (error_it.next()) |parse_error| {
178 try printErrMsgToFile(fmt.allocator, parse_error, &tree, file_path, stderr_file, fmt.color);
179 }
180 if (tree.errors.len != 0) {
181 fmt.any_error = true;
182 return;
183 }
184
185 if (check_mode) {
186 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, &tree);
187 if (anything_changed) {
188 try stderr.print("{}\n", file_path);
189 fmt.any_error = true;
190 }
191 } else {
192 // TODO make this evented
193 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
194 defer baf.destroy();
195
196 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), &tree);
197 if (anything_changed) {
198 try stderr.print("{}\n", file_path);
199 try baf.finish();
200 }
201 }
202}
203
204const Fmt = struct {
205 seen: SeenMap,
206 any_error: bool,
207 color: errmsg.Color,
208 allocator: *mem.Allocator,
209
210 const SeenMap = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
211};
212
213fn printErrMsgToFile(allocator: *mem.Allocator, parse_error: *const ast.Error, tree: *ast.Tree,
214 path: []const u8, file: os.File, color: errmsg.Color,) !void
215{
216 const color_on = switch (color) {
217 errmsg.Color.Auto => file.isTty(),
218 errmsg.Color.On => true,
219 errmsg.Color.Off => false,
220 };
221 const lok_token = parse_error.loc();
222 const span = errmsg.Span{
223 .first = lok_token,
224 .last = lok_token,
225 };
226
227 const first_token = tree.tokens.at(span.first);
228 const last_token = tree.tokens.at(span.last);
229 const start_loc = tree.tokenLocationPtr(0, first_token);
230 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
231
232 var text_buf = try std.Buffer.initSize(allocator, 0);
233 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
234 try parse_error.render(&tree.tokens, out_stream);
235 const text = text_buf.toOwnedSlice();
236
237 const stream = &file.outStream().stream;
238 if (!color_on) {
239 try stream.print(
240 "{}:{}:{}: error: {}\n",
241 path,
242 start_loc.line + 1,
243 start_loc.column + 1,
244 text,
245 );
246 return;
247 }
248
249 try stream.print(
250 "{}:{}:{}: error: {}\n{}\n",
251 path,
252 start_loc.line + 1,
253 start_loc.column + 1,
254 text,
255 tree.source[start_loc.line_start..start_loc.line_end],
256 );
257 try stream.writeByteNTimes(' ', start_loc.column);
258 try stream.writeByteNTimes('~', last_token.end - first_token.start);
259 try stream.write("\n");
260}
std/special/panic.zig+6-1
......@@ -9,10 +9,15 @@ const std = @import("std");
99pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
1010 @setCold(true);
1111 switch (builtin.os) {
12 // TODO: fix panic in zen.
12 // TODO: fix panic in zen
1313 builtin.Os.freestanding, builtin.Os.zen => {
1414 while (true) {}
1515 },
16 builtin.Os.wasi => {
17 std.debug.warn("{}", msg);
18 _ = std.os.wasi.proc_raise(std.os.wasi.SIGABRT);
19 unreachable;
20 },
1621 builtin.Os.uefi => {
1722 // TODO look into using the debug info and logging helpful messages
1823 std.os.abort();
std/special/test_runner.zig+1-1
......@@ -8,7 +8,7 @@ pub fn main() !void {
88 var ok_count: usize = 0;
99 var skip_count: usize = 0;
1010 for (test_fn_list) |test_fn, i| {
11 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
11 warn("{}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
1212
1313 if (test_fn.func()) |_| {
1414 ok_count += 1;
std/std.zig+7
......@@ -9,6 +9,10 @@ pub const DynLib = @import("dynamic_library.zig").DynLib;
99pub const HashMap = @import("hash_map.zig").HashMap;
1010pub const LinkedList = @import("linked_list.zig").LinkedList;
1111pub const Mutex = @import("mutex.zig").Mutex;
12pub const PackedIntArrayEndian = @import("packed_int_array.zig").PackedIntArrayEndian;
13pub const PackedIntArray = @import("packed_int_array.zig").PackedIntArray;
14pub const PackedIntSliceEndian = @import("packed_int_array.zig").PackedIntSliceEndian;
15pub const PackedIntSlice = @import("packed_int_array.zig").PackedIntSlice;
1216pub const PriorityQueue = @import("priority_queue.zig").PriorityQueue;
1317pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
1418pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
......@@ -87,6 +91,7 @@ test "std" {
8791 _ = @import("net.zig");
8892 _ = @import("os.zig");
8993 _ = @import("pdb.zig");
94 _ = @import("packed_int_array.zig");
9095 _ = @import("priority_queue.zig");
9196 _ = @import("rand.zig");
9297 _ = @import("sort.zig");
......@@ -94,4 +99,6 @@ test "std" {
9499 _ = @import("unicode.zig");
95100 _ = @import("valgrind.zig");
96101 _ = @import("zig.zig");
102
103 _ = @import("debug/leb128.zig");
97104}
std/zig/ast.zig+5-4
......@@ -18,7 +18,11 @@ pub const Tree = struct {
1818 pub const ErrorList = SegmentedList(Error, 0);
1919
2020 pub fn deinit(self: *Tree) void {
21 self.arena_allocator.deinit();
21 // Here we copy the arena allocator into stack memory, because
22 // otherwise it would destroy itself while it was still working.
23 var arena_allocator = self.arena_allocator;
24 arena_allocator.deinit();
25 // self is destroyed
2226 }
2327
2428 pub fn renderError(self: *Tree, parse_error: *Error, stream: var) !void {
......@@ -551,7 +555,6 @@ pub const Node = struct {
551555 doc_comments: ?*DocComment,
552556 decls: DeclList,
553557 eof_token: TokenIndex,
554 shebang: ?TokenIndex,
555558
556559 pub const DeclList = SegmentedList(*Node, 4);
557560
......@@ -563,7 +566,6 @@ pub const Node = struct {
563566 }
564567
565568 pub fn firstToken(self: *const Root) TokenIndex {
566 if (self.shebang) |shebang| return shebang;
567569 return if (self.decls.len == 0) self.eof_token else (self.decls.at(0).*).firstToken();
568570 }
569571
......@@ -2307,7 +2309,6 @@ test "iterate" {
23072309 .doc_comments = null,
23082310 .decls = Node.Root.DeclList.init(std.debug.global_allocator),
23092311 .eof_token = 0,
2310 .shebang = null,
23112312 };
23122313 var base = &root.base;
23132314 testing.expect(base.iterate(0) == null);
std/zig/parse.zig+179-159
......@@ -9,7 +9,7 @@ const Error = ast.Error;
99
1010/// Result should be freed with tree.deinit() when there are
1111/// no more references to any of the tokens or nodes.
12pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
12pub fn parse(allocator: *mem.Allocator, source: []const u8) !*ast.Tree {
1313 var tree_arena = std.heap.ArenaAllocator.init(allocator);
1414 errdefer tree_arena.deinit();
1515
......@@ -22,12 +22,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
2222 .base = ast.Node{ .id = ast.Node.Id.Root },
2323 .decls = ast.Node.Root.DeclList.init(arena),
2424 .doc_comments = null,
25 .shebang = null,
2625 // initialized when we get the eof token
2726 .eof_token = undefined,
2827 };
2928
30 var tree = ast.Tree{
29 const tree = try arena.create(ast.Tree);
30 tree.* = ast.Tree{
3131 .source = source,
3232 .root_node = root_node,
3333 .arena_allocator = tree_arena,
......@@ -43,15 +43,6 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
4343 }
4444 var tok_it = tree.tokens.iterator(0);
4545
46 // skip over shebang line
47 shebang: {
48 const shebang_tok_index = tok_it.index;
49 const shebang_tok_ptr = tok_it.peek() orelse break :shebang;
50 if (shebang_tok_ptr.id != Token.Id.ShebangLine) break :shebang;
51 root_node.shebang = shebang_tok_index;
52 _ = tok_it.next();
53 }
54
5546 // skip over line comments at the top of the file
5647 while (true) {
5748 const next_tok = tok_it.peek() orelse break;
......@@ -67,9 +58,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
6758
6859 switch (state) {
6960 State.TopLevel => {
70 const comments = try eatDocComments(arena, &tok_it, &tree);
61 const comments = try eatDocComments(arena, &tok_it, tree);
7162
72 const token = nextToken(&tok_it, &tree);
63 const token = nextToken(&tok_it, tree);
7364 const token_index = token.index;
7465 const token_ptr = token.ptr;
7566 switch (token_ptr.id) {
......@@ -150,7 +141,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
150141 continue;
151142 },
152143 else => {
153 prevToken(&tok_it, &tree);
144 prevToken(&tok_it, tree);
154145 stack.append(State.TopLevel) catch unreachable;
155146 try stack.append(State{
156147 .TopLevelExtern = TopLevelDeclCtx{
......@@ -166,7 +157,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
166157 }
167158 },
168159 State.TopLevelExtern => |ctx| {
169 const token = nextToken(&tok_it, &tree);
160 const token = nextToken(&tok_it, tree);
170161 const token_index = token.index;
171162 const token_ptr = token.ptr;
172163 switch (token_ptr.id) {
......@@ -201,7 +192,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
201192 continue;
202193 },
203194 else => {
204 prevToken(&tok_it, &tree);
195 prevToken(&tok_it, tree);
205196 stack.append(State{ .TopLevelDecl = ctx }) catch unreachable;
206197 continue;
207198 },
......@@ -209,11 +200,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
209200 },
210201 State.TopLevelLibname => |ctx| {
211202 const lib_name = blk: {
212 const lib_name_token = nextToken(&tok_it, &tree);
203 const lib_name_token = nextToken(&tok_it, tree);
213204 const lib_name_token_index = lib_name_token.index;
214205 const lib_name_token_ptr = lib_name_token.ptr;
215 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, &tree)) orelse {
216 prevToken(&tok_it, &tree);
206 break :blk (try parseStringLiteral(arena, &tok_it, lib_name_token_ptr, lib_name_token_index, tree)) orelse {
207 prevToken(&tok_it, tree);
217208 break :blk null;
218209 };
219210 };
......@@ -230,7 +221,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
230221 continue;
231222 },
232223 State.ThreadLocal => |ctx| {
233 const token = nextToken(&tok_it, &tree);
224 const token = nextToken(&tok_it, tree);
234225 const token_index = token.index;
235226 const token_ptr = token.ptr;
236227 switch (token_ptr.id) {
......@@ -256,7 +247,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
256247 }
257248 },
258249 State.TopLevelDecl => |ctx| {
259 const token = nextToken(&tok_it, &tree);
250 const token = nextToken(&tok_it, tree);
260251 const token_index = token.index;
261252 const token_ptr = token.ptr;
262253 switch (token_ptr.id) {
......@@ -397,7 +388,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
397388 }
398389 },
399390 State.TopLevelExternOrField => |ctx| {
400 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {
391 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |identifier| {
401392 const node = try arena.create(ast.Node.StructField);
402393 node.* = ast.Node.StructField{
403394 .base = ast.Node{ .id = ast.Node.Id.StructField },
......@@ -434,11 +425,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
434425 },
435426
436427 State.FieldInitValue => |ctx| {
437 const eq_tok = nextToken(&tok_it, &tree);
428 const eq_tok = nextToken(&tok_it, tree);
438429 const eq_tok_index = eq_tok.index;
439430 const eq_tok_ptr = eq_tok.ptr;
440431 if (eq_tok_ptr.id != Token.Id.Equal) {
441 prevToken(&tok_it, &tree);
432 prevToken(&tok_it, tree);
442433 continue;
443434 }
444435 stack.append(State{ .Expression = ctx }) catch unreachable;
......@@ -446,7 +437,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
446437 },
447438
448439 State.ContainerKind => |ctx| {
449 const token = nextToken(&tok_it, &tree);
440 const token = nextToken(&tok_it, tree);
450441 const token_index = token.index;
451442 const token_ptr = token.ptr;
452443 const node = try arena.create(ast.Node.ContainerDecl);
......@@ -479,7 +470,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
479470 },
480471
481472 State.ContainerInitArgStart => |container_decl| {
482 if (eatToken(&tok_it, &tree, Token.Id.LParen) == null) {
473 if (eatToken(&tok_it, tree, Token.Id.LParen) == null) {
483474 continue;
484475 }
485476
......@@ -489,24 +480,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
489480 },
490481
491482 State.ContainerInitArg => |container_decl| {
492 const init_arg_token = nextToken(&tok_it, &tree);
483 const init_arg_token = nextToken(&tok_it, tree);
493484 const init_arg_token_index = init_arg_token.index;
494485 const init_arg_token_ptr = init_arg_token.ptr;
495486 switch (init_arg_token_ptr.id) {
496487 Token.Id.Keyword_enum => {
497488 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Enum = null };
498 const lparen_tok = nextToken(&tok_it, &tree);
489 const lparen_tok = nextToken(&tok_it, tree);
499490 const lparen_tok_index = lparen_tok.index;
500491 const lparen_tok_ptr = lparen_tok.ptr;
501492 if (lparen_tok_ptr.id == Token.Id.LParen) {
502493 try stack.append(State{ .ExpectToken = Token.Id.RParen });
503494 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &container_decl.init_arg_expr.Enum } });
504495 } else {
505 prevToken(&tok_it, &tree);
496 prevToken(&tok_it, tree);
506497 }
507498 },
508499 else => {
509 prevToken(&tok_it, &tree);
500 prevToken(&tok_it, tree);
510501 container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg{ .Type = undefined };
511502 stack.append(State{ .Expression = OptionalCtx{ .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
512503 },
......@@ -515,8 +506,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
515506 },
516507
517508 State.ContainerDecl => |container_decl| {
518 const comments = try eatDocComments(arena, &tok_it, &tree);
519 const token = nextToken(&tok_it, &tree);
509 const comments = try eatDocComments(arena, &tok_it, tree);
510 const token = nextToken(&tok_it, tree);
520511 const token_index = token.index;
521512 const token_ptr = token.ptr;
522513 switch (token_ptr.id) {
......@@ -629,6 +620,35 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
629620 });
630621 continue;
631622 },
623 Token.Id.Keyword_comptime => {
624 const block = try arena.create(ast.Node.Block);
625 block.* = ast.Node.Block{
626 .base = ast.Node{ .id = ast.Node.Id.Block },
627 .label = null,
628 .lbrace = undefined,
629 .statements = ast.Node.Block.StatementList.init(arena),
630 .rbrace = undefined,
631 };
632
633 const node = try arena.create(ast.Node.Comptime);
634 node.* = ast.Node.Comptime{
635 .base = ast.Node{ .id = ast.Node.Id.Comptime },
636 .comptime_token = token_index,
637 .expr = &block.base,
638 .doc_comments = comments,
639 };
640 try container_decl.fields_and_decls.push(&node.base);
641
642 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
643 try stack.append(State{ .Block = block });
644 try stack.append(State{
645 .ExpectTokenSave = ExpectTokenSave{
646 .id = Token.Id.LBrace,
647 .ptr = &block.lbrace,
648 },
649 });
650 continue;
651 },
632652 Token.Id.RBrace => {
633653 if (comments != null) {
634654 ((try tree.errors.addOne())).* = Error{ .UnattachedDocComment = Error.UnattachedDocComment{ .token = token_index } };
......@@ -638,7 +658,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
638658 continue;
639659 },
640660 else => {
641 prevToken(&tok_it, &tree);
661 prevToken(&tok_it, tree);
642662 stack.append(State{ .ContainerDecl = container_decl }) catch unreachable;
643663 try stack.append(State{
644664 .TopLevelExtern = TopLevelDeclCtx{
......@@ -690,7 +710,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
690710 State.VarDeclAlign => |var_decl| {
691711 try stack.append(State{ .VarDeclSection = var_decl });
692712
693 const next_token = nextToken(&tok_it, &tree);
713 const next_token = nextToken(&tok_it, tree);
694714 const next_token_index = next_token.index;
695715 const next_token_ptr = next_token.ptr;
696716 if (next_token_ptr.id == Token.Id.Keyword_align) {
......@@ -700,13 +720,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
700720 continue;
701721 }
702722
703 prevToken(&tok_it, &tree);
723 prevToken(&tok_it, tree);
704724 continue;
705725 },
706726 State.VarDeclSection => |var_decl| {
707727 try stack.append(State{ .VarDeclEq = var_decl });
708728
709 const next_token = nextToken(&tok_it, &tree);
729 const next_token = nextToken(&tok_it, tree);
710730 const next_token_index = next_token.index;
711731 const next_token_ptr = next_token.ptr;
712732 if (next_token_ptr.id == Token.Id.Keyword_linksection) {
......@@ -716,11 +736,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
716736 continue;
717737 }
718738
719 prevToken(&tok_it, &tree);
739 prevToken(&tok_it, tree);
720740 continue;
721741 },
722742 State.VarDeclEq => |var_decl| {
723 const token = nextToken(&tok_it, &tree);
743 const token = nextToken(&tok_it, tree);
724744 const token_index = token.index;
725745 const token_ptr = token.ptr;
726746 switch (token_ptr.id) {
......@@ -742,7 +762,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
742762 },
743763
744764 State.VarDeclSemiColon => |var_decl| {
745 const semicolon_token = nextToken(&tok_it, &tree);
765 const semicolon_token = nextToken(&tok_it, tree);
746766
747767 if (semicolon_token.ptr.id != Token.Id.Semicolon) {
748768 ((try tree.errors.addOne())).* = Error{
......@@ -756,18 +776,18 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
756776
757777 var_decl.semicolon_token = semicolon_token.index;
758778
759 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {
779 if (eatToken(&tok_it, tree, Token.Id.DocComment)) |doc_comment_token| {
760780 const loc = tree.tokenLocation(semicolon_token.ptr.end, doc_comment_token);
761781 if (loc.line == 0) {
762782 try pushDocComment(arena, doc_comment_token, &var_decl.doc_comments);
763783 } else {
764 prevToken(&tok_it, &tree);
784 prevToken(&tok_it, tree);
765785 }
766786 }
767787 },
768788
769789 State.FnDef => |fn_proto| {
770 const token = nextToken(&tok_it, &tree);
790 const token = nextToken(&tok_it, tree);
771791 const token_index = token.index;
772792 const token_ptr = token.ptr;
773793 switch (token_ptr.id) {
......@@ -796,7 +816,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
796816 try stack.append(State{ .ParamDecl = fn_proto });
797817 try stack.append(State{ .ExpectToken = Token.Id.LParen });
798818
799 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |name_token| {
819 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |name_token| {
800820 fn_proto.name_token = name_token;
801821 }
802822 continue;
......@@ -804,7 +824,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
804824 State.FnProtoAlign => |fn_proto| {
805825 stack.append(State{ .FnProtoSection = fn_proto }) catch unreachable;
806826
807 if (eatToken(&tok_it, &tree, Token.Id.Keyword_align)) |align_token| {
827 if (eatToken(&tok_it, tree, Token.Id.Keyword_align)) |align_token| {
808828 try stack.append(State{ .ExpectToken = Token.Id.RParen });
809829 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.align_expr } });
810830 try stack.append(State{ .ExpectToken = Token.Id.LParen });
......@@ -814,7 +834,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
814834 State.FnProtoSection => |fn_proto| {
815835 stack.append(State{ .FnProtoReturnType = fn_proto }) catch unreachable;
816836
817 if (eatToken(&tok_it, &tree, Token.Id.Keyword_linksection)) |align_token| {
837 if (eatToken(&tok_it, tree, Token.Id.Keyword_linksection)) |align_token| {
818838 try stack.append(State{ .ExpectToken = Token.Id.RParen });
819839 try stack.append(State{ .Expression = OptionalCtx{ .RequiredNull = &fn_proto.section_expr } });
820840 try stack.append(State{ .ExpectToken = Token.Id.LParen });
......@@ -822,7 +842,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
822842 continue;
823843 },
824844 State.FnProtoReturnType => |fn_proto| {
825 const token = nextToken(&tok_it, &tree);
845 const token = nextToken(&tok_it, tree);
826846 const token_index = token.index;
827847 const token_ptr = token.ptr;
828848 switch (token_ptr.id) {
......@@ -845,7 +865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
845865 }
846866 }
847867
848 prevToken(&tok_it, &tree);
868 prevToken(&tok_it, tree);
849869 fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = undefined };
850870 stack.append(State{ .TypeExprBegin = OptionalCtx{ .Required = &fn_proto.return_type.Explicit } }) catch unreachable;
851871 continue;
......@@ -854,8 +874,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
854874 },
855875
856876 State.ParamDecl => |fn_proto| {
857 const comments = try eatDocComments(arena, &tok_it, &tree);
858 if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {
877 const comments = try eatDocComments(arena, &tok_it, tree);
878 if (eatToken(&tok_it, tree, Token.Id.RParen)) |_| {
859879 continue;
860880 }
861881 const param_decl = try arena.create(ast.Node.ParamDecl);
......@@ -881,9 +901,9 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
881901 continue;
882902 },
883903 State.ParamDeclAliasOrComptime => |param_decl| {
884 if (eatToken(&tok_it, &tree, Token.Id.Keyword_comptime)) |comptime_token| {
904 if (eatToken(&tok_it, tree, Token.Id.Keyword_comptime)) |comptime_token| {
885905 param_decl.comptime_token = comptime_token;
886 } else if (eatToken(&tok_it, &tree, Token.Id.Keyword_noalias)) |noalias_token| {
906 } else if (eatToken(&tok_it, tree, Token.Id.Keyword_noalias)) |noalias_token| {
887907 param_decl.noalias_token = noalias_token;
888908 }
889909 continue;
......@@ -891,20 +911,20 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
891911 State.ParamDeclName => |param_decl| {
892912 // TODO: Here, we eat two tokens in one state. This means that we can't have
893913 // comments between these two tokens.
894 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| {
895 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {
914 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |ident_token| {
915 if (eatToken(&tok_it, tree, Token.Id.Colon)) |_| {
896916 param_decl.name_token = ident_token;
897917 } else {
898 prevToken(&tok_it, &tree);
918 prevToken(&tok_it, tree);
899919 }
900920 }
901921 continue;
902922 },
903923 State.ParamDeclEnd => |ctx| {
904 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
924 if (eatToken(&tok_it, tree, Token.Id.Ellipsis3)) |ellipsis3| {
905925 ctx.param_decl.var_args_token = ellipsis3;
906926
907 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {
927 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RParen)) {
908928 ExpectCommaOrEndResult.end_token => |t| {
909929 if (t == null) {
910930 stack.append(State{ .ExpectToken = Token.Id.RParen }) catch unreachable;
......@@ -924,7 +944,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
924944 continue;
925945 },
926946 State.ParamDeclComma => |fn_proto| {
927 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RParen)) {
947 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RParen)) {
928948 ExpectCommaOrEndResult.end_token => |t| {
929949 if (t == null) {
930950 stack.append(State{ .ParamDecl = fn_proto }) catch unreachable;
......@@ -939,7 +959,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
939959 },
940960
941961 State.MaybeLabeledExpression => |ctx| {
942 if (eatToken(&tok_it, &tree, Token.Id.Colon)) |_| {
962 if (eatToken(&tok_it, tree, Token.Id.Colon)) |_| {
943963 stack.append(State{
944964 .LabeledExpression = LabelCtx{
945965 .label = ctx.label,
......@@ -953,7 +973,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
953973 continue;
954974 },
955975 State.LabeledExpression => |ctx| {
956 const token = nextToken(&tok_it, &tree);
976 const token = nextToken(&tok_it, tree);
957977 const token_index = token.index;
958978 const token_ptr = token.ptr;
959979 switch (token_ptr.id) {
......@@ -1008,13 +1028,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
10081028 return tree;
10091029 }
10101030
1011 prevToken(&tok_it, &tree);
1031 prevToken(&tok_it, tree);
10121032 continue;
10131033 },
10141034 }
10151035 },
10161036 State.Inline => |ctx| {
1017 const token = nextToken(&tok_it, &tree);
1037 const token = nextToken(&tok_it, tree);
10181038 const token_index = token.index;
10191039 const token_ptr = token.ptr;
10201040 switch (token_ptr.id) {
......@@ -1046,7 +1066,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
10461066 return tree;
10471067 }
10481068
1049 prevToken(&tok_it, &tree);
1069 prevToken(&tok_it, tree);
10501070 continue;
10511071 },
10521072 }
......@@ -1103,7 +1123,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
11031123 continue;
11041124 },
11051125 State.Else => |dest| {
1106 if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
1126 if (eatToken(&tok_it, tree, Token.Id.Keyword_else)) |else_token| {
11071127 const node = try arena.create(ast.Node.Else);
11081128 node.* = ast.Node.Else{
11091129 .base = ast.Node{ .id = ast.Node.Id.Else },
......@@ -1122,7 +1142,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
11221142 },
11231143
11241144 State.Block => |block| {
1125 const token = nextToken(&tok_it, &tree);
1145 const token = nextToken(&tok_it, tree);
11261146 const token_index = token.index;
11271147 const token_ptr = token.ptr;
11281148 switch (token_ptr.id) {
......@@ -1131,7 +1151,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
11311151 continue;
11321152 },
11331153 else => {
1134 prevToken(&tok_it, &tree);
1154 prevToken(&tok_it, tree);
11351155 stack.append(State{ .Block = block }) catch unreachable;
11361156
11371157 try stack.append(State{ .Statement = block });
......@@ -1140,7 +1160,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
11401160 }
11411161 },
11421162 State.Statement => |block| {
1143 const token = nextToken(&tok_it, &tree);
1163 const token = nextToken(&tok_it, tree);
11441164 const token_index = token.index;
11451165 const token_ptr = token.ptr;
11461166 switch (token_ptr.id) {
......@@ -1197,7 +1217,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
11971217 continue;
11981218 },
11991219 else => {
1200 prevToken(&tok_it, &tree);
1220 prevToken(&tok_it, tree);
12011221 const statement = try block.statements.addOne();
12021222 try stack.append(State{ .Semicolon = statement });
12031223 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
......@@ -1206,7 +1226,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
12061226 }
12071227 },
12081228 State.ComptimeStatement => |ctx| {
1209 const token = nextToken(&tok_it, &tree);
1229 const token = nextToken(&tok_it, tree);
12101230 const token_index = token.index;
12111231 const token_ptr = token.ptr;
12121232 switch (token_ptr.id) {
......@@ -1226,8 +1246,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
12261246 continue;
12271247 },
12281248 else => {
1229 prevToken(&tok_it, &tree);
1230 prevToken(&tok_it, &tree);
1249 prevToken(&tok_it, tree);
1250 prevToken(&tok_it, tree);
12311251 const statement = try ctx.block.statements.addOne();
12321252 try stack.append(State{ .Semicolon = statement });
12331253 try stack.append(State{ .Expression = OptionalCtx{ .Required = statement } });
......@@ -1245,11 +1265,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
12451265 },
12461266
12471267 State.AsmOutputItems => |items| {
1248 const lbracket = nextToken(&tok_it, &tree);
1268 const lbracket = nextToken(&tok_it, tree);
12491269 const lbracket_index = lbracket.index;
12501270 const lbracket_ptr = lbracket.ptr;
12511271 if (lbracket_ptr.id != Token.Id.LBracket) {
1252 prevToken(&tok_it, &tree);
1272 prevToken(&tok_it, tree);
12531273 continue;
12541274 }
12551275
......@@ -1280,7 +1300,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
12801300 continue;
12811301 },
12821302 State.AsmOutputReturnOrType => |node| {
1283 const token = nextToken(&tok_it, &tree);
1303 const token = nextToken(&tok_it, tree);
12841304 const token_index = token.index;
12851305 const token_ptr = token.ptr;
12861306 switch (token_ptr.id) {
......@@ -1300,11 +1320,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
13001320 }
13011321 },
13021322 State.AsmInputItems => |items| {
1303 const lbracket = nextToken(&tok_it, &tree);
1323 const lbracket = nextToken(&tok_it, tree);
13041324 const lbracket_index = lbracket.index;
13051325 const lbracket_ptr = lbracket.ptr;
13061326 if (lbracket_ptr.id != Token.Id.LBracket) {
1307 prevToken(&tok_it, &tree);
1327 prevToken(&tok_it, tree);
13081328 continue;
13091329 }
13101330
......@@ -1335,16 +1355,16 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
13351355 continue;
13361356 },
13371357 State.AsmClobberItems => |items| {
1338 while (eatToken(&tok_it, &tree, Token.Id.StringLiteral)) |strlit| {
1358 while (eatToken(&tok_it, tree, Token.Id.StringLiteral)) |strlit| {
13391359 try items.push(strlit);
1340 if (eatToken(&tok_it, &tree, Token.Id.Comma) == null)
1360 if (eatToken(&tok_it, tree, Token.Id.Comma) == null)
13411361 break;
13421362 }
13431363 continue;
13441364 },
13451365
13461366 State.ExprListItemOrEnd => |list_state| {
1347 if (eatToken(&tok_it, &tree, list_state.end)) |token_index| {
1367 if (eatToken(&tok_it, tree, list_state.end)) |token_index| {
13481368 (list_state.ptr).* = token_index;
13491369 continue;
13501370 }
......@@ -1354,7 +1374,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
13541374 continue;
13551375 },
13561376 State.ExprListCommaOrEnd => |list_state| {
1357 switch (expectCommaOrEnd(&tok_it, &tree, list_state.end)) {
1377 switch (expectCommaOrEnd(&tok_it, tree, list_state.end)) {
13581378 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
13591379 (list_state.ptr).* = end;
13601380 continue;
......@@ -1369,7 +1389,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
13691389 }
13701390 },
13711391 State.FieldInitListItemOrEnd => |list_state| {
1372 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1392 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
13731393 (list_state.ptr).* = rbrace;
13741394 continue;
13751395 }
......@@ -1401,7 +1421,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
14011421 continue;
14021422 },
14031423 State.FieldInitListCommaOrEnd => |list_state| {
1404 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1424 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
14051425 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
14061426 (list_state.ptr).* = end;
14071427 continue;
......@@ -1416,17 +1436,17 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
14161436 }
14171437 },
14181438 State.FieldListCommaOrEnd => |field_ctx| {
1419 const end_token = nextToken(&tok_it, &tree);
1439 const end_token = nextToken(&tok_it, tree);
14201440 const end_token_index = end_token.index;
14211441 const end_token_ptr = end_token.ptr;
14221442 switch (end_token_ptr.id) {
14231443 Token.Id.Comma => {
1424 if (eatToken(&tok_it, &tree, Token.Id.DocComment)) |doc_comment_token| {
1444 if (eatToken(&tok_it, tree, Token.Id.DocComment)) |doc_comment_token| {
14251445 const loc = tree.tokenLocation(end_token_ptr.end, doc_comment_token);
14261446 if (loc.line == 0) {
14271447 try pushDocComment(arena, doc_comment_token, field_ctx.doc_comments);
14281448 } else {
1429 prevToken(&tok_it, &tree);
1449 prevToken(&tok_it, tree);
14301450 }
14311451 }
14321452
......@@ -1449,7 +1469,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
14491469 }
14501470 },
14511471 State.ErrorTagListItemOrEnd => |list_state| {
1452 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1472 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
14531473 (list_state.ptr).* = rbrace;
14541474 continue;
14551475 }
......@@ -1461,7 +1481,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
14611481 continue;
14621482 },
14631483 State.ErrorTagListCommaOrEnd => |list_state| {
1464 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1484 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
14651485 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
14661486 (list_state.ptr).* = end;
14671487 continue;
......@@ -1476,12 +1496,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
14761496 }
14771497 },
14781498 State.SwitchCaseOrEnd => |list_state| {
1479 if (eatToken(&tok_it, &tree, Token.Id.RBrace)) |rbrace| {
1499 if (eatToken(&tok_it, tree, Token.Id.RBrace)) |rbrace| {
14801500 (list_state.ptr).* = rbrace;
14811501 continue;
14821502 }
14831503
1484 const comments = try eatDocComments(arena, &tok_it, &tree);
1504 const comments = try eatDocComments(arena, &tok_it, tree);
14851505 const node = try arena.create(ast.Node.SwitchCase);
14861506 node.* = ast.Node.SwitchCase{
14871507 .base = ast.Node{ .id = ast.Node.Id.SwitchCase },
......@@ -1500,7 +1520,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15001520 },
15011521
15021522 State.SwitchCaseCommaOrEnd => |list_state| {
1503 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.RBrace)) {
1523 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.RBrace)) {
15041524 ExpectCommaOrEndResult.end_token => |maybe_end| if (maybe_end) |end| {
15051525 (list_state.ptr).* = end;
15061526 continue;
......@@ -1516,7 +1536,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15161536 },
15171537
15181538 State.SwitchCaseFirstItem => |switch_case| {
1519 const token = nextToken(&tok_it, &tree);
1539 const token = nextToken(&tok_it, tree);
15201540 const token_index = token.index;
15211541 const token_ptr = token.ptr;
15221542 if (token_ptr.id == Token.Id.Keyword_else) {
......@@ -1535,26 +1555,26 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15351555 });
15361556 continue;
15371557 } else {
1538 prevToken(&tok_it, &tree);
1558 prevToken(&tok_it, tree);
15391559 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
15401560 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
15411561 continue;
15421562 }
15431563 },
15441564 State.SwitchCaseItemOrEnd => |switch_case| {
1545 const token = nextToken(&tok_it, &tree);
1565 const token = nextToken(&tok_it, tree);
15461566 if (token.ptr.id == Token.Id.EqualAngleBracketRight) {
15471567 switch_case.arrow_token = token.index;
15481568 continue;
15491569 } else {
1550 prevToken(&tok_it, &tree);
1570 prevToken(&tok_it, tree);
15511571 stack.append(State{ .SwitchCaseItemCommaOrEnd = switch_case }) catch unreachable;
15521572 try stack.append(State{ .RangeExpressionBegin = OptionalCtx{ .Required = try switch_case.items.addOne() } });
15531573 continue;
15541574 }
15551575 },
15561576 State.SwitchCaseItemCommaOrEnd => |switch_case| {
1557 switch (expectCommaOrEnd(&tok_it, &tree, Token.Id.EqualAngleBracketRight)) {
1577 switch (expectCommaOrEnd(&tok_it, tree, Token.Id.EqualAngleBracketRight)) {
15581578 ExpectCommaOrEndResult.end_token => |end_token| {
15591579 if (end_token) |t| {
15601580 switch_case.arrow_token = t;
......@@ -1572,14 +1592,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15721592 },
15731593
15741594 State.SuspendBody => |suspend_node| {
1575 const token = nextToken(&tok_it, &tree);
1595 const token = nextToken(&tok_it, tree);
15761596 switch (token.ptr.id) {
15771597 Token.Id.Semicolon => {
1578 prevToken(&tok_it, &tree);
1598 prevToken(&tok_it, tree);
15791599 continue;
15801600 },
15811601 Token.Id.LBrace => {
1582 prevToken(&tok_it, &tree);
1602 prevToken(&tok_it, tree);
15831603 try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .RequiredNull = &suspend_node.body } });
15841604 continue;
15851605 },
......@@ -1589,7 +1609,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
15891609 }
15901610 },
15911611 State.AsyncAllocator => |async_node| {
1592 if (eatToken(&tok_it, &tree, Token.Id.AngleBracketLeft) == null) {
1612 if (eatToken(&tok_it, tree, Token.Id.AngleBracketLeft) == null) {
15931613 continue;
15941614 }
15951615
......@@ -1630,7 +1650,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
16301650 },
16311651
16321652 State.ExternType => |ctx| {
1633 if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {
1653 if (eatToken(&tok_it, tree, Token.Id.Keyword_fn)) |fn_token| {
16341654 const fn_proto = try arena.create(ast.Node.FnProto);
16351655 fn_proto.* = ast.Node.FnProto{
16361656 .base = ast.Node{ .id = ast.Node.Id.FnProto },
......@@ -1663,7 +1683,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
16631683 continue;
16641684 },
16651685 State.SliceOrArrayAccess => |node| {
1666 const token = nextToken(&tok_it, &tree);
1686 const token = nextToken(&tok_it, tree);
16671687 const token_index = token.index;
16681688 const token_ptr = token.ptr;
16691689 switch (token_ptr.id) {
......@@ -1696,7 +1716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
16961716 }
16971717 },
16981718 State.SliceOrArrayType => |node| {
1699 if (eatToken(&tok_it, &tree, Token.Id.RBracket)) |_| {
1719 if (eatToken(&tok_it, tree, Token.Id.RBracket)) |_| {
17001720 node.op = ast.Node.PrefixOp.Op{
17011721 .SliceType = ast.Node.PrefixOp.PtrInfo{
17021722 .align_info = null,
......@@ -1718,7 +1738,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
17181738 },
17191739
17201740 State.PtrTypeModifiers => |addr_of_info| {
1721 const token = nextToken(&tok_it, &tree);
1741 const token = nextToken(&tok_it, tree);
17221742 const token_index = token.index;
17231743 const token_ptr = token.ptr;
17241744 switch (token_ptr.id) {
......@@ -1768,14 +1788,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
17681788 continue;
17691789 },
17701790 else => {
1771 prevToken(&tok_it, &tree);
1791 prevToken(&tok_it, tree);
17721792 continue;
17731793 },
17741794 }
17751795 },
17761796
17771797 State.AlignBitRange => |align_info| {
1778 const token = nextToken(&tok_it, &tree);
1798 const token = nextToken(&tok_it, tree);
17791799 switch (token.ptr.id) {
17801800 Token.Id.Colon => {
17811801 align_info.bit_range = ast.Node.PrefixOp.PtrInfo.Align.BitRange(undefined);
......@@ -1798,7 +1818,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
17981818 },
17991819
18001820 State.Payload => |opt_ctx| {
1801 const token = nextToken(&tok_it, &tree);
1821 const token = nextToken(&tok_it, tree);
18021822 const token_index = token.index;
18031823 const token_ptr = token.ptr;
18041824 if (token_ptr.id != Token.Id.Pipe) {
......@@ -1812,7 +1832,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
18121832 return tree;
18131833 }
18141834
1815 prevToken(&tok_it, &tree);
1835 prevToken(&tok_it, tree);
18161836 continue;
18171837 }
18181838
......@@ -1835,7 +1855,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
18351855 continue;
18361856 },
18371857 State.PointerPayload => |opt_ctx| {
1838 const token = nextToken(&tok_it, &tree);
1858 const token = nextToken(&tok_it, tree);
18391859 const token_index = token.index;
18401860 const token_ptr = token.ptr;
18411861 if (token_ptr.id != Token.Id.Pipe) {
......@@ -1849,7 +1869,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
18491869 return tree;
18501870 }
18511871
1852 prevToken(&tok_it, &tree);
1872 prevToken(&tok_it, tree);
18531873 continue;
18541874 }
18551875
......@@ -1879,7 +1899,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
18791899 continue;
18801900 },
18811901 State.PointerIndexPayload => |opt_ctx| {
1882 const token = nextToken(&tok_it, &tree);
1902 const token = nextToken(&tok_it, tree);
18831903 const token_index = token.index;
18841904 const token_ptr = token.ptr;
18851905 if (token_ptr.id != Token.Id.Pipe) {
......@@ -1893,7 +1913,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
18931913 return tree;
18941914 }
18951915
1896 prevToken(&tok_it, &tree);
1916 prevToken(&tok_it, tree);
18971917 continue;
18981918 }
18991919
......@@ -1927,7 +1947,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
19271947 },
19281948
19291949 State.Expression => |opt_ctx| {
1930 const token = nextToken(&tok_it, &tree);
1950 const token = nextToken(&tok_it, tree);
19311951 const token_index = token.index;
19321952 const token_ptr = token.ptr;
19331953 switch (token_ptr.id) {
......@@ -1981,7 +2001,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
19812001 },
19822002 else => {
19832003 if (!try parseBlockExpr(&stack, arena, opt_ctx, token_ptr.*, token_index)) {
1984 prevToken(&tok_it, &tree);
2004 prevToken(&tok_it, tree);
19852005 stack.append(State{ .UnwrapExpressionBegin = opt_ctx }) catch unreachable;
19862006 }
19872007 continue;
......@@ -1996,7 +2016,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
19962016 State.RangeExpressionEnd => |opt_ctx| {
19972017 const lhs = opt_ctx.get() orelse continue;
19982018
1999 if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
2019 if (eatToken(&tok_it, tree, Token.Id.Ellipsis3)) |ellipsis3| {
20002020 const node = try arena.create(ast.Node.InfixOp);
20012021 node.* = ast.Node.InfixOp{
20022022 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2019,7 +2039,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
20192039 State.AssignmentExpressionEnd => |opt_ctx| {
20202040 const lhs = opt_ctx.get() orelse continue;
20212041
2022 const token = nextToken(&tok_it, &tree);
2042 const token = nextToken(&tok_it, tree);
20232043 const token_index = token.index;
20242044 const token_ptr = token.ptr;
20252045 if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
......@@ -2036,7 +2056,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
20362056 try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
20372057 continue;
20382058 } else {
2039 prevToken(&tok_it, &tree);
2059 prevToken(&tok_it, tree);
20402060 continue;
20412061 }
20422062 },
......@@ -2050,7 +2070,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
20502070 State.UnwrapExpressionEnd => |opt_ctx| {
20512071 const lhs = opt_ctx.get() orelse continue;
20522072
2053 const token = nextToken(&tok_it, &tree);
2073 const token = nextToken(&tok_it, tree);
20542074 const token_index = token.index;
20552075 const token_ptr = token.ptr;
20562076 if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
......@@ -2072,7 +2092,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
20722092 }
20732093 continue;
20742094 } else {
2075 prevToken(&tok_it, &tree);
2095 prevToken(&tok_it, tree);
20762096 continue;
20772097 }
20782098 },
......@@ -2086,7 +2106,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
20862106 State.BoolOrExpressionEnd => |opt_ctx| {
20872107 const lhs = opt_ctx.get() orelse continue;
20882108
2089 if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
2109 if (eatToken(&tok_it, tree, Token.Id.Keyword_or)) |or_token| {
20902110 const node = try arena.create(ast.Node.InfixOp);
20912111 node.* = ast.Node.InfixOp{
20922112 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2111,7 +2131,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
21112131 State.BoolAndExpressionEnd => |opt_ctx| {
21122132 const lhs = opt_ctx.get() orelse continue;
21132133
2114 if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
2134 if (eatToken(&tok_it, tree, Token.Id.Keyword_and)) |and_token| {
21152135 const node = try arena.create(ast.Node.InfixOp);
21162136 node.* = ast.Node.InfixOp{
21172137 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2136,7 +2156,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
21362156 State.ComparisonExpressionEnd => |opt_ctx| {
21372157 const lhs = opt_ctx.get() orelse continue;
21382158
2139 const token = nextToken(&tok_it, &tree);
2159 const token = nextToken(&tok_it, tree);
21402160 const token_index = token.index;
21412161 const token_ptr = token.ptr;
21422162 if (tokenIdToComparison(token_ptr.id)) |comp_id| {
......@@ -2153,7 +2173,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
21532173 try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
21542174 continue;
21552175 } else {
2156 prevToken(&tok_it, &tree);
2176 prevToken(&tok_it, tree);
21572177 continue;
21582178 }
21592179 },
......@@ -2167,7 +2187,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
21672187 State.BinaryOrExpressionEnd => |opt_ctx| {
21682188 const lhs = opt_ctx.get() orelse continue;
21692189
2170 if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
2190 if (eatToken(&tok_it, tree, Token.Id.Pipe)) |pipe| {
21712191 const node = try arena.create(ast.Node.InfixOp);
21722192 node.* = ast.Node.InfixOp{
21732193 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2192,7 +2212,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
21922212 State.BinaryXorExpressionEnd => |opt_ctx| {
21932213 const lhs = opt_ctx.get() orelse continue;
21942214
2195 if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
2215 if (eatToken(&tok_it, tree, Token.Id.Caret)) |caret| {
21962216 const node = try arena.create(ast.Node.InfixOp);
21972217 node.* = ast.Node.InfixOp{
21982218 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2217,7 +2237,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
22172237 State.BinaryAndExpressionEnd => |opt_ctx| {
22182238 const lhs = opt_ctx.get() orelse continue;
22192239
2220 if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
2240 if (eatToken(&tok_it, tree, Token.Id.Ampersand)) |ampersand| {
22212241 const node = try arena.create(ast.Node.InfixOp);
22222242 node.* = ast.Node.InfixOp{
22232243 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2242,7 +2262,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
22422262 State.BitShiftExpressionEnd => |opt_ctx| {
22432263 const lhs = opt_ctx.get() orelse continue;
22442264
2245 const token = nextToken(&tok_it, &tree);
2265 const token = nextToken(&tok_it, tree);
22462266 const token_index = token.index;
22472267 const token_ptr = token.ptr;
22482268 if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
......@@ -2259,7 +2279,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
22592279 try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
22602280 continue;
22612281 } else {
2262 prevToken(&tok_it, &tree);
2282 prevToken(&tok_it, tree);
22632283 continue;
22642284 }
22652285 },
......@@ -2273,7 +2293,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
22732293 State.AdditionExpressionEnd => |opt_ctx| {
22742294 const lhs = opt_ctx.get() orelse continue;
22752295
2276 const token = nextToken(&tok_it, &tree);
2296 const token = nextToken(&tok_it, tree);
22772297 const token_index = token.index;
22782298 const token_ptr = token.ptr;
22792299 if (tokenIdToAddition(token_ptr.id)) |add_id| {
......@@ -2290,7 +2310,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
22902310 try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
22912311 continue;
22922312 } else {
2293 prevToken(&tok_it, &tree);
2313 prevToken(&tok_it, tree);
22942314 continue;
22952315 }
22962316 },
......@@ -2304,7 +2324,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
23042324 State.MultiplyExpressionEnd => |opt_ctx| {
23052325 const lhs = opt_ctx.get() orelse continue;
23062326
2307 const token = nextToken(&tok_it, &tree);
2327 const token = nextToken(&tok_it, tree);
23082328 const token_index = token.index;
23092329 const token_ptr = token.ptr;
23102330 if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
......@@ -2321,7 +2341,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
23212341 try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
23222342 continue;
23232343 } else {
2324 prevToken(&tok_it, &tree);
2344 prevToken(&tok_it, tree);
23252345 continue;
23262346 }
23272347 },
......@@ -2386,7 +2406,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
23862406 State.TypeExprEnd => |opt_ctx| {
23872407 const lhs = opt_ctx.get() orelse continue;
23882408
2389 if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
2409 if (eatToken(&tok_it, tree, Token.Id.Bang)) |bang| {
23902410 const node = try arena.create(ast.Node.InfixOp);
23912411 node.* = ast.Node.InfixOp{
23922412 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2403,7 +2423,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
24032423 },
24042424
24052425 State.PrefixOpExpression => |opt_ctx| {
2406 const token = nextToken(&tok_it, &tree);
2426 const token = nextToken(&tok_it, tree);
24072427 const token_index = token.index;
24082428 const token_ptr = token.ptr;
24092429 if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
......@@ -2435,14 +2455,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
24352455 }
24362456 continue;
24372457 } else {
2438 prevToken(&tok_it, &tree);
2458 prevToken(&tok_it, tree);
24392459 stack.append(State{ .SuffixOpExpressionBegin = opt_ctx }) catch unreachable;
24402460 continue;
24412461 }
24422462 },
24432463
24442464 State.SuffixOpExpressionBegin => |opt_ctx| {
2445 if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
2465 if (eatToken(&tok_it, tree, Token.Id.Keyword_async)) |async_token| {
24462466 const async_node = try arena.create(ast.Node.AsyncAttribute);
24472467 async_node.* = ast.Node.AsyncAttribute{
24482468 .base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
......@@ -2470,7 +2490,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
24702490 State.SuffixOpExpressionEnd => |opt_ctx| {
24712491 const lhs = opt_ctx.get() orelse continue;
24722492
2473 const token = nextToken(&tok_it, &tree);
2493 const token = nextToken(&tok_it, tree);
24742494 const token_index = token.index;
24752495 const token_ptr = token.ptr;
24762496 switch (token_ptr.id) {
......@@ -2515,7 +2535,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
25152535 continue;
25162536 },
25172537 Token.Id.Period => {
2518 if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {
2538 if (eatToken(&tok_it, tree, Token.Id.Asterisk)) |asterisk_token| {
25192539 const node = try arena.create(ast.Node.SuffixOp);
25202540 node.* = ast.Node.SuffixOp{
25212541 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
......@@ -2527,7 +2547,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
25272547 stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
25282548 continue;
25292549 }
2530 if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {
2550 if (eatToken(&tok_it, tree, Token.Id.QuestionMark)) |question_token| {
25312551 const node = try arena.create(ast.Node.SuffixOp);
25322552 node.* = ast.Node.SuffixOp{
25332553 .base = ast.Node{ .id = ast.Node.Id.SuffixOp },
......@@ -2554,21 +2574,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
25542574 continue;
25552575 },
25562576 else => {
2557 prevToken(&tok_it, &tree);
2577 prevToken(&tok_it, tree);
25582578 continue;
25592579 },
25602580 }
25612581 },
25622582
25632583 State.PrimaryExpression => |opt_ctx| {
2564 const token = nextToken(&tok_it, &tree);
2584 const token = nextToken(&tok_it, tree);
25652585 switch (token.ptr.id) {
25662586 Token.Id.IntegerLiteral => {
25672587 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.IntegerLiteral, token.index);
25682588 continue;
25692589 },
25702590 Token.Id.Period => {
2571 const name_token = nextToken(&tok_it, &tree);
2591 const name_token = nextToken(&tok_it, tree);
25722592 if (name_token.ptr.id != Token.Id.Identifier) {
25732593 ((try tree.errors.addOne())).* = Error{
25742594 .ExpectedToken = Error.ExpectedToken{
......@@ -2624,11 +2644,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
26242644 .result = null,
26252645 };
26262646 opt_ctx.store(&node.base);
2627 const next_token = nextToken(&tok_it, &tree);
2647 const next_token = nextToken(&tok_it, tree);
26282648 const next_token_index = next_token.index;
26292649 const next_token_ptr = next_token.ptr;
26302650 if (next_token_ptr.id != Token.Id.Arrow) {
2631 prevToken(&tok_it, &tree);
2651 prevToken(&tok_it, tree);
26322652 continue;
26332653 }
26342654 node.result = ast.Node.PromiseType.Result{
......@@ -2640,7 +2660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
26402660 continue;
26412661 },
26422662 Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
2643 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token.ptr, token.index, &tree)) orelse unreachable);
2663 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token.ptr, token.index, tree)) orelse unreachable);
26442664 continue;
26452665 },
26462666 Token.Id.LParen => {
......@@ -2728,7 +2748,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
27282748 continue;
27292749 },
27302750 Token.Id.Keyword_struct, Token.Id.Keyword_union, Token.Id.Keyword_enum => {
2731 prevToken(&tok_it, &tree);
2751 prevToken(&tok_it, tree);
27322752 stack.append(State{
27332753 .ContainerKind = ContainerKindCtx{
27342754 .opt_ctx = opt_ctx,
......@@ -2845,7 +2865,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
28452865 },
28462866 else => {
28472867 if (!try parseBlockExpr(&stack, arena, opt_ctx, token.ptr.*, token.index)) {
2848 prevToken(&tok_it, &tree);
2868 prevToken(&tok_it, tree);
28492869 if (opt_ctx != OptionalCtx.Optional) {
28502870 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token.index } };
28512871 return tree;
......@@ -2857,7 +2877,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
28572877 },
28582878
28592879 State.ErrorTypeOrSetDecl => |ctx| {
2860 if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {
2880 if (eatToken(&tok_it, tree, Token.Id.LBrace) == null) {
28612881 const node = try arena.create(ast.Node.InfixOp);
28622882 node.* = ast.Node.InfixOp{
28632883 .base = ast.Node{ .id = ast.Node.Id.InfixOp },
......@@ -2895,11 +2915,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
28952915 continue;
28962916 },
28972917 State.StringLiteral => |opt_ctx| {
2898 const token = nextToken(&tok_it, &tree);
2918 const token = nextToken(&tok_it, tree);
28992919 const token_index = token.index;
29002920 const token_ptr = token.ptr;
2901 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index, &tree)) orelse {
2902 prevToken(&tok_it, &tree);
2921 opt_ctx.store((try parseStringLiteral(arena, &tok_it, token_ptr, token_index, tree)) orelse {
2922 prevToken(&tok_it, tree);
29032923 if (opt_ctx != OptionalCtx.Optional) {
29042924 ((try tree.errors.addOne())).* = Error{ .ExpectedPrimaryExpr = Error.ExpectedPrimaryExpr{ .token = token_index } };
29052925 return tree;
......@@ -2910,13 +2930,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29102930 },
29112931
29122932 State.Identifier => |opt_ctx| {
2913 if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |ident_token| {
2933 if (eatToken(&tok_it, tree, Token.Id.Identifier)) |ident_token| {
29142934 _ = try createToCtxLiteral(arena, opt_ctx, ast.Node.Identifier, ident_token);
29152935 continue;
29162936 }
29172937
29182938 if (opt_ctx != OptionalCtx.Optional) {
2919 const token = nextToken(&tok_it, &tree);
2939 const token = nextToken(&tok_it, tree);
29202940 const token_index = token.index;
29212941 const token_ptr = token.ptr;
29222942 ((try tree.errors.addOne())).* = Error{
......@@ -2930,8 +2950,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29302950 },
29312951
29322952 State.ErrorTag => |node_ptr| {
2933 const comments = try eatDocComments(arena, &tok_it, &tree);
2934 const ident_token = nextToken(&tok_it, &tree);
2953 const comments = try eatDocComments(arena, &tok_it, tree);
2954 const ident_token = nextToken(&tok_it, tree);
29352955 const ident_token_index = ident_token.index;
29362956 const ident_token_ptr = ident_token.ptr;
29372957 if (ident_token_ptr.id != Token.Id.Identifier) {
......@@ -2955,7 +2975,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29552975 },
29562976
29572977 State.ExpectToken => |token_id| {
2958 const token = nextToken(&tok_it, &tree);
2978 const token = nextToken(&tok_it, tree);
29592979 const token_index = token.index;
29602980 const token_ptr = token.ptr;
29612981 if (token_ptr.id != token_id) {
......@@ -2970,7 +2990,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29702990 continue;
29712991 },
29722992 State.ExpectTokenSave => |expect_token_save| {
2973 const token = nextToken(&tok_it, &tree);
2993 const token = nextToken(&tok_it, tree);
29742994 const token_index = token.index;
29752995 const token_ptr = token.ptr;
29762996 if (token_ptr.id != expect_token_save.id) {
......@@ -2986,7 +3006,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29863006 continue;
29873007 },
29883008 State.IfToken => |token_id| {
2989 if (eatToken(&tok_it, &tree, token_id)) |_| {
3009 if (eatToken(&tok_it, tree, token_id)) |_| {
29903010 continue;
29913011 }
29923012
......@@ -2994,7 +3014,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
29943014 continue;
29953015 },
29963016 State.IfTokenSave => |if_token_save| {
2997 if (eatToken(&tok_it, &tree, if_token_save.id)) |token_index| {
3017 if (eatToken(&tok_it, tree, if_token_save.id)) |token_index| {
29983018 (if_token_save.ptr).* = token_index;
29993019 continue;
30003020 }
......@@ -3003,7 +3023,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
30033023 continue;
30043024 },
30053025 State.OptionalTokenSave => |optional_token_save| {
3006 if (eatToken(&tok_it, &tree, optional_token_save.id)) |token_index| {
3026 if (eatToken(&tok_it, tree, optional_token_save.id)) |token_index| {
30073027 (optional_token_save.ptr).* = token_index;
30083028 continue;
30093029 }
std/zig/parser_test.zig+18-18
......@@ -1,10 +1,3 @@
1test "temporary trivial example" {
2 try testCanonical(
3 \\const x = true;
4 \\
5 );
6}
7
81test "zig fmt: allowzero pointer" {
92 try testCanonical(
103 \\const T = [*]allowzero const u8;
......@@ -57,14 +50,6 @@ test "zig fmt: linksection" {
5750 );
5851}
5952
60test "zig fmt: shebang line" {
61 try testCanonical(
62 \\#!/usr/bin/env zig
63 \\pub fn main() void {}
64 \\
65 );
66}
67
6853test "zig fmt: correctly move doc comments on struct fields" {
6954 try testTransform(
7055 \\pub const section_64 = extern struct {
......@@ -2125,6 +2110,21 @@ test "zig fmt: error return" {
21252110 );
21262111}
21272112
2113test "zig fmt: comptime block in container" {
2114 try testCanonical(
2115 \\pub fn container() type {
2116 \\ return struct {
2117 \\ comptime {
2118 \\ if (false) {
2119 \\ unreachable;
2120 \\ }
2121 \\ }
2122 \\ };
2123 \\}
2124 \\
2125 );
2126}
2127
21282128const std = @import("std");
21292129const mem = std.mem;
21302130const warn = std.debug.warn;
......@@ -2137,7 +2137,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
21372137 var stderr_file = try io.getStdErr();
21382138 var stderr = &stderr_file.outStream().stream;
21392139
2140 var tree = try std.zig.parse2(allocator, source);
2140 const tree = try std.zig.parse(allocator, source);
21412141 defer tree.deinit();
21422142
21432143 var error_it = tree.errors.iterator(0);
......@@ -2170,7 +2170,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
21702170 errdefer buffer.deinit();
21712171
21722172 var buffer_out_stream = io.BufferOutStream.init(&buffer);
2173 anything_changed.* = try std.zig.render(allocator, &buffer_out_stream.stream, &tree);
2173 anything_changed.* = try std.zig.render(allocator, &buffer_out_stream.stream, tree);
21742174 return buffer.toOwnedSlice();
21752175}
21762176
......@@ -2215,7 +2215,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
22152215 needed_alloc_count,
22162216 failing_allocator.allocated_bytes,
22172217 failing_allocator.freed_bytes,
2218 failing_allocator.index,
2218 failing_allocator.allocations,
22192219 failing_allocator.deallocations,
22202220 );
22212221 return error.MemoryLeakDetected;
std/zig/render.zig+1-6
......@@ -73,11 +73,6 @@ fn renderRoot(
7373) (@typeOf(stream).Child.Error || Error)!void {
7474 var tok_it = tree.tokens.iterator(0);
7575
76 // render the shebang line
77 if (tree.root_node.shebang) |shebang| {
78 try stream.write(tree.tokenSlice(shebang));
79 }
80
8176 // render all the line comments at the beginning of the file
8277 while (tok_it.next()) |token| {
8378 if (token.id != Token.Id.LineComment) break;
......@@ -753,7 +748,7 @@ fn renderExpression(
753748 counting_stream.bytes_written = 0;
754749 var dummy_col: usize = 0;
755750 try renderExpression(allocator, &counting_stream.stream, tree, 0, &dummy_col, expr.*, Space.None);
756 const width = counting_stream.bytes_written;
751 const width = @intCast(usize, counting_stream.bytes_written);
757752 const col = i % row_size;
758753 column_widths[col] = std.math.max(column_widths[col], width);
759754 expr_widths[i] = width;
test/compile_errors.zig+80-33
......@@ -2,6 +2,64 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "peer cast then implicit cast const pointer to mutable C pointer",
7 \\export fn func() void {
8 \\ var strValue: [*c]u8 = undefined;
9 \\ strValue = strValue orelse c"";
10 \\}
11 ,
12 "tmp.zig:3:32: error: cast discards const qualifier",
13 );
14
15 cases.add(
16 "overflow in enum value allocation",
17 \\const Moo = enum(u8) {
18 \\ Last = 255,
19 \\ Over,
20 \\};
21 \\pub fn main() void {
22 \\ var y = Moo.Last;
23 \\}
24 ,
25 "tmp.zig:3:5: error: enumeration value 256 too large for type 'u8'",
26 );
27
28 cases.add(
29 "attempt to cast enum literal to error",
30 \\export fn entry() void {
31 \\ switch (error.Hi) {
32 \\ .Hi => {},
33 \\ }
34 \\}
35 ,
36 "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'",
37 );
38
39 cases.add(
40 "@sizeOf bad type",
41 \\export fn entry() void {
42 \\ _ = @sizeOf(@typeOf(null));
43 \\}
44 ,
45 "tmp.zig:2:17: error: no size available for type '(null)'",
46 );
47
48 cases.add(
49 "Generic function where return type is self-referenced",
50 \\fn Foo(comptime T: type) Foo(T) {
51 \\ return struct{ x: T };
52 \\}
53 \\export fn entry() void {
54 \\ const t = Foo(u32) {
55 \\ .x = 1
56 \\ };
57 \\}
58 ,
59 "tmp.zig:1:29: error: evaluation exceeded 1000 backwards branches",
60 "tmp.zig:1:29: note: called from here",
61 );
62
563 cases.add(
664 "@ptrToInt 0 to non optional pointer",
765 \\export fn entry() void {
......@@ -552,15 +610,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
552610 "tmp.zig:1:13: error: threadlocal variable cannot be constant",
553611 );
554612
555 cases.add(
556 "threadlocal qualifier on local variable",
557 \\export fn entry() void {
558 \\ threadlocal var x: i32 = 1234;
559 \\}
560 ,
561 "tmp.zig:2:5: error: function-local variable 'x' cannot be threadlocal",
562 );
563
564613 cases.add(
565614 "@bitCast same size but bit count mismatch",
566615 \\export fn entry(byte: u8) void {
......@@ -839,7 +888,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
839888 \\ _ = &x == null;
840889 \\}
841890 ,
842 "tmp.zig:3:12: error: only optionals (not '*i32') can compare to null",
891 "tmp.zig:3:12: error: comparison of '*i32' with null",
843892 );
844893
845894 cases.add(
......@@ -5347,8 +5396,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53475396 "tmp.zig:12:20: note: referenced here",
53485397 );
53495398
5350 cases.add(
5351 "specify enum tag type that is too small",
5399 cases.add("specify enum tag type that is too small",
53525400 \\const Small = enum (u2) {
53535401 \\ One,
53545402 \\ Two,
......@@ -5360,9 +5408,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53605408 \\export fn entry() void {
53615409 \\ var x = Small.One;
53625410 \\}
5363 ,
5364 "tmp.zig:1:21: error: 'u2' too small to hold all bits; must be at least 'u3'",
5365 );
5411 , "tmp.zig:6:5: error: enumeration value 4 too large for type 'u2'");
53665412
53675413 cases.add(
53685414 "specify non-integer enum tag type",
......@@ -5412,22 +5458,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54125458 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",
54135459 );
54145460
5415 cases.add(
5416 "non unsigned integer enum tag type",
5417 \\const Small = enum(i2) {
5418 \\ One,
5419 \\ Two,
5420 \\ Three,
5421 \\ Four,
5422 \\};
5423 \\
5424 \\export fn entry() void {
5425 \\ var y = Small.Two;
5426 \\}
5427 ,
5428 "tmp.zig:1:20: error: expected unsigned integer, found 'i2'",
5429 );
5430
54315461 cases.add(
54325462 "struct fields with value assignments",
54335463 \\const MultipleChoice = struct {
......@@ -5486,8 +5516,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54865516 \\ var x = MultipleChoice.C;
54875517 \\}
54885518 ,
5489 "tmp.zig:6:9: error: enum tag value 60 already taken",
5490 "tmp.zig:4:9: note: other occurrence here",
5519 "tmp.zig:6:5: error: enum tag value 60 already taken",
5520 "tmp.zig:4:5: note: other occurrence here",
54915521 );
54925522
54935523 cases.add(
......@@ -5892,4 +5922,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
58925922 ,
58935923 "tmp.zig:3:23: error: expected type '[]u32', found '*const u32'",
58945924 );
5925
5926 cases.add(
5927 "for loop body expression ignored",
5928 \\fn returns() usize {
5929 \\ return 2;
5930 \\}
5931 \\export fn f1() void {
5932 \\ for ("hello") |_| returns();
5933 \\}
5934 \\export fn f2() void {
5935 \\ var x: anyerror!i32 = error.Bad;
5936 \\ for ("hello") |_| returns() else unreachable;
5937 \\}
5938 ,
5939 "tmp.zig:5:30: error: expression value is ignored",
5940 "tmp.zig:9:30: error: expression value is ignored",
5941 );
58955942}
test/runtime_safety.zig+20
......@@ -1,6 +1,26 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompareOutputContext) void {
4 cases.addRuntimeSafety(".? operator on null pointer",
5 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\pub fn main() void {
9 \\ var ptr: ?*i32 = null;
10 \\ var b = ptr.?;
11 \\}
12 );
13
14 cases.addRuntimeSafety(".? operator on C pointer",
15 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
16 \\ @import("std").os.exit(126);
17 \\}
18 \\pub fn main() void {
19 \\ var ptr: [*c]i32 = null;
20 \\ var b = ptr.?;
21 \\}
22 );
23
424 cases.addRuntimeSafety("@ptrToInt address zero to non-optional pointer",
525 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
626 \\ @import("std").os.exit(126);
test/stage1/behavior.zig+3
......@@ -20,9 +20,12 @@ comptime {
2020 _ = @import("behavior/bugs/1442.zig");
2121 _ = @import("behavior/bugs/1486.zig");
2222 _ = @import("behavior/bugs/1500.zig");
23 _ = @import("behavior/bugs/1607.zig");
2324 _ = @import("behavior/bugs/1851.zig");
2425 _ = @import("behavior/bugs/1914.zig");
2526 _ = @import("behavior/bugs/2006.zig");
27 _ = @import("behavior/bugs/2114.zig");
28 _ = @import("behavior/bugs/2346.zig");
2629 _ = @import("behavior/bugs/394.zig");
2730 _ = @import("behavior/bugs/421.zig");
2831 _ = @import("behavior/bugs/529.zig");
test/stage1/behavior/bit_shifting.zig+10
......@@ -86,3 +86,13 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c
8686 expect(table.get(@intCast(Key, i)) == node);
8787 }
8888}
89
90// #2225
91test "comptime shr of BigInt" {
92 comptime {
93 var n0 = 0xdeadbeef0000000000000000;
94 std.debug.assert(n0 >> 64 == 0xdeadbeef);
95 var n1 = 17908056155735594659;
96 std.debug.assert(n1 >> 64 == 0);
97 }
98}
test/stage1/behavior/bugs/1607.zig created+15
......@@ -0,0 +1,15 @@
1const std = @import("std");
2const testing = std.testing;
3
4const a = []u8{ 1, 2, 3 };
5
6fn checkAddress(s: []const u8) void {
7 for (s) |*i, j| {
8 testing.expect(i == &a[j]);
9 }
10}
11
12test "slices pointing at the same address as global array." {
13 checkAddress(a);
14 comptime checkAddress(a);
15}
test/stage1/behavior/bugs/2114.zig created+19
......@@ -0,0 +1,19 @@
1const std = @import("std");
2const expect = std.testing.expect;
3const math = std.math;
4
5fn ctz(x: var) usize {
6 return @ctz(x);
7}
8
9test "fixed" {
10 testClz();
11 comptime testClz();
12}
13
14fn testClz() void {
15 expect(ctz(u128(0x40000000000000000000000000000000)) == 126);
16 expect(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1)) == u128(0x80000000000000000000000000000000));
17 expect(ctz(u128(0x80000000000000000000000000000000)) == 127);
18 expect(ctz(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1))) == 127);
19}
test/stage1/behavior/bugs/2346.zig created+6
......@@ -0,0 +1,6 @@
1test "fixed" {
2 const a: *void = undefined;
3 const b: *[1]void = a;
4 const c: *[0]u8 = undefined;
5 const d: []u8 = c;
6}
test/stage1/behavior/enum.zig+39
......@@ -923,3 +923,42 @@ test "peer type resolution with enum literal" {
923923 expect(Items.two == .two);
924924 expect(.two == Items.two);
925925}
926
927test "enum literal in array literal" {
928 const Items = enum {
929 one,
930 two,
931 };
932
933 const array = []Items {
934 .one,
935 .two,
936 };
937
938 expect(array[0] == .one);
939 expect(array[1] == .two);
940}
941
942test "signed integer as enum tag" {
943 const SignedEnum = enum(i2) {
944 A0 = -1,
945 A1 = 0,
946 A2 = 1,
947 };
948
949 expect(@enumToInt(SignedEnum.A0) == -1);
950 expect(@enumToInt(SignedEnum.A1) == 0);
951 expect(@enumToInt(SignedEnum.A2) == 1);
952}
953
954test "enum value allocation" {
955 const LargeEnum = enum(u32) {
956 A0 = 0x80000000,
957 A1,
958 A2,
959 };
960
961 expect(@enumToInt(LargeEnum.A0) == 0x80000000);
962 expect(@enumToInt(LargeEnum.A1) == 0x80000001);
963 expect(@enumToInt(LargeEnum.A2) == 0x80000002);
964}
test/stage1/behavior/math.zig+7
......@@ -632,3 +632,10 @@ fn testNanEqNan(comptime F: type) void {
632632 expect(!(nan1 < nan2));
633633 expect(!(nan1 <= nan2));
634634}
635
636test "128-bit multiplication" {
637 var a: i128 = 3;
638 var b: i128 = 2;
639 var c = a * b;
640 expect(c == 6);
641}
test/stage1/behavior/pointers.zig+50
......@@ -150,3 +150,53 @@ test "allowzero pointer and slice" {
150150 expect(@typeInfo(@typeOf(ptr)).Pointer.is_allowzero);
151151 expect(@typeInfo(@typeOf(slice)).Pointer.is_allowzero);
152152}
153
154test "assign null directly to C pointer and test null equality" {
155 var x: [*c]i32 = null;
156 expect(x == null);
157 expect(null == x);
158 expect(!(x != null));
159 expect(!(null != x));
160 if (x) |same_x| {
161 @panic("fail");
162 }
163 var otherx: i32 = undefined;
164 expect((x orelse &otherx) == &otherx);
165
166 const y: [*c]i32 = null;
167 comptime expect(y == null);
168 comptime expect(null == y);
169 comptime expect(!(y != null));
170 comptime expect(!(null != y));
171 if (y) |same_y| @panic("fail");
172 const othery: i32 = undefined;
173 comptime expect((y orelse &othery) == &othery);
174
175 var n: i32 = 1234;
176 var x1: [*c]i32 = &n;
177 expect(!(x1 == null));
178 expect(!(null == x1));
179 expect(x1 != null);
180 expect(null != x1);
181 expect(x1.?.* == 1234);
182 if (x1) |same_x1| {
183 expect(same_x1.* == 1234);
184 } else {
185 @panic("fail");
186 }
187 expect((x1 orelse &otherx) == x1);
188
189 const nc: i32 = 1234;
190 const y1: [*c]const i32 = &nc;
191 comptime expect(!(y1 == null));
192 comptime expect(!(null == y1));
193 comptime expect(y1 != null);
194 comptime expect(null != y1);
195 comptime expect(y1.?.* == 1234);
196 if (y1) |same_y1| {
197 expect(same_y1.* == 1234);
198 } else {
199 @compileError("fail");
200 }
201 comptime expect((y1 orelse &othery) == y1);
202}
test/stage1/behavior/sizeof_and_typeof.zig+7
......@@ -67,3 +67,10 @@ test "@bitOffsetOf" {
6767 expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
6868 expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
6969}
70
71test "@sizeOf on compile-time types" {
72 expect(@sizeOf(comptime_int) == 0);
73 expect(@sizeOf(comptime_float) == 0);
74 expect(@sizeOf(@typeOf(.hi)) == 0);
75 expect(@sizeOf(@typeOf(type)) == 0);
76}
test/stage1/behavior/struct.zig+20-2
......@@ -2,8 +2,7 @@ const std = @import("std");
22const expect = std.testing.expect;
33const expectEqualSlices = std.testing.expectEqualSlices;
44const builtin = @import("builtin");
5const maxInt = std.math.maxInt;
6
5const maxInt = std.math.maxInt;
76const StructWithNoFields = struct {
87 fn add(a: i32, b: i32) i32 {
98 return a + b;
......@@ -505,3 +504,22 @@ test "packed struct with u0 field access" {
505504 var s = S{ .f0 = 0 };
506505 comptime expect(s.f0 == 0);
507506}
507
508const S0 = struct{
509 bar: S1,
510
511 pub const S1 = struct{
512 value: u8,
513 };
514
515 fn init() @This() {
516 return S0{ .bar = S1{ .value = 123 } };
517 }
518};
519
520var g_foo: S0 = S0.init();
521
522test "access to global struct fields" {
523 g_foo.bar.value = 42;
524 expect(g_foo.bar.value == 42);
525}
test/stage1/behavior/syntax.zig+8
......@@ -1,6 +1,14 @@
11// Test trailing comma syntax
22// zig fmt: off
33
4extern var a: c_int;
5extern "c" var b: c_int;
6export var c: c_int = 0;
7threadlocal var d: c_int;
8extern threadlocal var e: c_int;
9extern "c" threadlocal var f: c_int;
10export threadlocal var g: c_int = 0;
11
412const struct_trailing_comma = struct { x: i32, y: i32, };
513const struct_no_comma = struct { x: i32, y: i32 };
614const struct_fn_no_comma = struct { fn m() void {} y: i32 };
test/stage1/behavior/union.zig+37
......@@ -365,3 +365,40 @@ test "@enumToInt works on unions" {
365365 expect(@enumToInt(b) == 1);
366366 expect(@enumToInt(c) == 2);
367367}
368
369const Attribute = union(enum) {
370 A: bool,
371 B: u8,
372};
373
374fn setAttribute(attr: Attribute) void {}
375
376fn Setter(attr: Attribute) type {
377 return struct{
378 fn set() void {
379 setAttribute(attr);
380 }
381 };
382}
383
384test "comptime union field value equality" {
385 const a0 = Setter(Attribute{ .A = false });
386 const a1 = Setter(Attribute{ .A = true });
387 const a2 = Setter(Attribute{ .A = false });
388
389 const b0 = Setter(Attribute{ .B = 5 });
390 const b1 = Setter(Attribute{ .B = 9 });
391 const b2 = Setter(Attribute{ .B = 5 });
392
393 expect(a0 == a0);
394 expect(a1 == a1);
395 expect(a0 == a2);
396
397 expect(b0 == b0);
398 expect(b1 == b1);
399 expect(b0 == b2);
400
401 expect(a0 != b0);
402 expect(a0 != a1);
403 expect(b0 != b1);
404}
test/tests.zig+34-2
......@@ -903,6 +903,7 @@ pub const TranslateCContext = struct {
903903 sources: ArrayList(SourceFile),
904904 expected_lines: ArrayList([]const u8),
905905 allow_warnings: bool,
906 stage2: bool,
906907
907908 const SourceFile = struct {
908909 filename: []const u8,
......@@ -955,7 +956,8 @@ pub const TranslateCContext = struct {
955956 var zig_args = ArrayList([]const u8).init(b.allocator);
956957 zig_args.append(b.zig_exe) catch unreachable;
957958
958 zig_args.append("translate-c") catch unreachable;
959 const translate_c_cmd = if (self.case.stage2) "translate-c-2" else "translate-c";
960 zig_args.append(translate_c_cmd) catch unreachable;
959961 zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
960962
961963 warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
......@@ -1052,6 +1054,7 @@ pub const TranslateCContext = struct {
10521054 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
10531055 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
10541056 .allow_warnings = allow_warnings,
1057 .stage2 = false,
10551058 };
10561059
10571060 tc.addSourceFile(filename, source);
......@@ -1072,6 +1075,34 @@ pub const TranslateCContext = struct {
10721075 self.addCase(tc);
10731076 }
10741077
1078 pub fn add_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
1079 for ([]bool{ false, true }) |stage2| {
1080 const tc = self.create(false, "source.h", name, source, expected_lines);
1081 tc.stage2 = stage2;
1082 self.addCase(tc);
1083 }
1084 }
1085
1086 pub fn addC_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
1087 for ([]bool{ false, true }) |stage2| {
1088 const tc = self.create(false, "source.c", name, source, expected_lines);
1089 tc.stage2 = stage2;
1090 self.addCase(tc);
1091 }
1092 }
1093
1094 pub fn add_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
1095 const tc = self.create(false, "source.h", name, source, expected_lines);
1096 tc.stage2 = true;
1097 self.addCase(tc);
1098 }
1099
1100 pub fn addC_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
1101 const tc = self.create(false, "source.c", name, source, expected_lines);
1102 tc.stage2 = true;
1103 self.addCase(tc);
1104 }
1105
10751106 pub fn addAllowWarnings(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
10761107 const tc = self.create(true, "source.h", name, source, expected_lines);
10771108 self.addCase(tc);
......@@ -1080,7 +1111,8 @@ pub const TranslateCContext = struct {
10801111 pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
10811112 const b = self.b;
10821113
1083 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
1114 const translate_c_cmd = if (case.stage2) "translate-c-2" else "translate-c";
1115 const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {}", translate_c_cmd, case.name) catch unreachable;
10841116 if (self.test_filter) |filter| {
10851117 if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
10861118 }
test/translate_c.zig+167-48
......@@ -1,7 +1,66 @@
11const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
4// add_both - test for stage1 and stage2, in #include mode
5// add - test stage1 only, in #include mode
6// add_2 - test stage2 only, in #include mode
7// addC_both - test for stage1 and stage2, in -c mode
8// addC - test stage1 only, in -c mode
9// addC_2 - test stage2 only, in -c mode
10
411pub fn addCases(cases: *tests.TranslateCContext) void {
12 /////////////// Cases that pass for both stage1/stage2 ////////////////
13 cases.add_both("simple function prototypes",
14 \\void __attribute__((noreturn)) foo(void);
15 \\int bar(void);
16 ,
17 \\pub extern fn foo() noreturn;
18 \\pub extern fn bar() c_int;
19 );
20
21 /////////////// Cases that pass for only stage2 ////////////////
22 cases.add_2("Parameterless function prototypes",
23 \\void a() {}
24 \\void b(void) {}
25 \\void c();
26 \\void d(void);
27 ,
28 \\pub export fn a() void {}
29 \\pub export fn b() void {}
30 \\pub extern fn c(...) void;
31 \\pub extern fn d() void;
32 );
33
34 cases.add_2("simple function definition",
35 \\void foo(void) {}
36 \\static void bar(void) {}
37 ,
38 \\pub export fn foo() void {}
39 \\pub extern fn bar() void {}
40 );
41
42 /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
43
44 cases.add("macro with left shift",
45 \\#define REDISMODULE_READ (1<<0)
46 ,
47 \\pub const REDISMODULE_READ = 1 << 0;
48 );
49
50 cases.add("casting pointers to ints and ints to pointers",
51 \\void foo(void);
52 \\void bar(void) {
53 \\ void *func_ptr = foo;
54 \\ void (*typed_func_ptr)(void) = (void (*)(void)) (unsigned long) func_ptr;
55 \\}
56 ,
57 \\pub extern fn foo() void;
58 \\pub fn bar() void {
59 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
60 \\ var typed_func_ptr: ?extern fn() void = @intToPtr(?extern fn() void, c_ulong(@ptrToInt(func_ptr)));
61 \\}
62 );
63
564 if (builtin.os != builtin.Os.windows) {
665 // Windows treats this as an enum with type c_int
766 cases.add("big negative enum init values when C ABI supports long long enums",
......@@ -72,7 +131,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
72131 \\ _ = c"void foo(void)";
73132 \\}
74133 );
75
134
76135 cases.add("ignore result",
77136 \\void foo() {
78137 \\ int a;
......@@ -648,11 +707,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
648707 ,
649708 \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
650709 \\ if ((a != 0) and (b != 0)) return 0;
651 \\ if ((b != 0) and (c != 0)) return 1;
652 \\ if ((a != 0) and (c != 0)) return 2;
710 \\ if ((b != 0) and (c != null)) return 1;
711 \\ if ((a != 0) and (c != null)) return 2;
653712 \\ if ((a != 0) or (b != 0)) return 3;
654 \\ if ((b != 0) or (c != 0)) return 4;
655 \\ if ((a != 0) or (c != 0)) return 5;
713 \\ if ((b != 0) or (c != null)) return 4;
714 \\ if ((a != 0) or (c != null)) return 5;
656715 \\ return 6;
657716 \\}
658717 );
......@@ -832,7 +891,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
832891 \\}
833892 ,
834893 \\pub export fn foo() [*c]c_int {
835 \\ return 0;
894 \\ return null;
836895 \\}
837896 );
838897
......@@ -1334,7 +1393,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13341393 \\}
13351394 ,
13361395 \\fn ptrcast(a: [*c]c_int) [*c]f32 {
1337 \\ return @ptrCast([*c]f32, a);
1396 \\ return @ptrCast([*c]f32, @alignCast(@alignOf(f32), a));
13381397 \\}
13391398 );
13401399
......@@ -1360,7 +1419,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13601419 \\ return !(a == 0);
13611420 \\ return !(a != 0);
13621421 \\ return !(b != 0);
1363 \\ return !(c != 0);
1422 \\ return !(c != null);
13641423 \\}
13651424 );
13661425
......@@ -1417,7 +1476,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14171476 \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
14181477 \\ if (a != 0) return 0;
14191478 \\ if (b != 0) return 1;
1420 \\ if (c != 0) return 2;
1479 \\ if (c != null) return 2;
14211480 \\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;
14221481 \\ return 4;
14231482 \\}
......@@ -1434,7 +1493,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14341493 \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
14351494 \\ while (a != 0) return 0;
14361495 \\ while (b != 0) return 1;
1437 \\ while (c != 0) return 2;
1496 \\ while (c != null) return 2;
14381497 \\ return 3;
14391498 \\}
14401499 );
......@@ -1450,7 +1509,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14501509 \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
14511510 \\ while (a != 0) return 0;
14521511 \\ while (b != 0) return 1;
1453 \\ while (c != 0) return 2;
1512 \\ while (c != null) return 2;
14541513 \\ return 3;
14551514 \\}
14561515 );
......@@ -1497,14 +1556,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
14971556 \\}
14981557 );
14991558
1500 cases.addC("Parameterless function prototypes",
1501 \\void foo() {}
1502 \\void bar(void) {}
1503 ,
1504 \\pub export fn foo() void {}
1505 \\pub export fn bar() void {}
1506 );
1507
15081559 cases.addC(
15091560 "u integer suffix after 0 (zero) in macro definition",
15101561 "#define ZERO 0U",
......@@ -1553,33 +1604,101 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15531604 "pub const NOT_ZERO = ~c_uint(0);",
15541605 );
15551606
1556 // cases.add("empty array with initializer",
1557 // "int a[4] = {};"
1558 // ,
1559 // "pub var a: [4]c_int = [1]c_int{0} ** 4;"
1560 // );
1561
1562 // cases.add("array with initialization",
1563 // "int a[4] = {1, 2, 3, 4};"
1564 // ,
1565 // "pub var a: [4]c_int = [4]c_int{1, 2, 3, 4};"
1566 // );
1567
1568 // cases.add("array with incomplete initialization",
1569 // "int a[4] = {3, 4};"
1570 // ,
1571 // "pub var a: [4]c_int = [2]c_int{3, 4} ++ ([1]c_int{0} ** 2);"
1572 // );
1573
1574 // cases.add("2D array with initialization",
1575 // "int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };"
1576 // ,
1577 // "pub var a: [3][3]c_int = [3][3]c_int{[3]c_int{1, 2, 3}, [3]c_int{4, 5, 6}, [3]c_int{7, 8, 9}};"
1578 // );
1579
1580 // cases.add("2D array with incomplete initialization",
1581 // "int a[3][3] = { {1, 2}, {4, 5, 6} };"
1582 // ,
1583 // "pub var a: [3][3]c_int = [2][3]c_int{[2]c_int{1, 2} ++ [1]c_int{0}, [3]c_int{4, 5, 6}} ++ [1][3]c_int{[1]c_int{0} ** 3};"
1584 // );
1607 cases.addC("implicit casts",
1608 \\#include <stdbool.h>
1609 \\
1610 \\void fn_int(int x);
1611 \\void fn_f32(float x);
1612 \\void fn_f64(double x);
1613 \\void fn_char(char x);
1614 \\void fn_bool(bool x);
1615 \\void fn_ptr(void *x);
1616 \\
1617 \\void call(int q) {
1618 \\ fn_int(3.0f);
1619 \\ fn_int(3.0);
1620 \\ fn_int(3.0L);
1621 \\ fn_int('ABCD');
1622 \\ fn_f32(3);
1623 \\ fn_f64(3);
1624 \\ fn_char('3');
1625 \\ fn_char('\x1');
1626 \\ fn_char(0);
1627 \\ fn_f32(3.0f);
1628 \\ fn_f64(3.0);
1629 \\ fn_bool(123);
1630 \\ fn_bool(0);
1631 \\ fn_bool(&fn_int);
1632 \\ fn_int(&fn_int);
1633 \\ fn_ptr(42);
1634 \\}
1635 ,
1636 \\pub extern fn fn_int(x: c_int) void;
1637 \\pub extern fn fn_f32(x: f32) void;
1638 \\pub extern fn fn_f64(x: f64) void;
1639 \\pub extern fn fn_char(x: u8) void;
1640 \\pub extern fn fn_bool(x: bool) void;
1641 \\pub extern fn fn_ptr(x: ?*c_void) void;
1642 \\pub export fn call(q: c_int) void {
1643 \\ fn_int(@floatToInt(c_int, 3.000000));
1644 \\ fn_int(@floatToInt(c_int, 3.000000));
1645 \\ fn_int(@floatToInt(c_int, 3.000000));
1646 \\ fn_int(1094861636);
1647 \\ fn_f32(@intToFloat(f32, 3));
1648 \\ fn_f64(@intToFloat(f64, 3));
1649 \\ fn_char(u8('3'));
1650 \\ fn_char(u8('\x01'));
1651 \\ fn_char(u8(0));
1652 \\ fn_f32(3.000000);
1653 \\ fn_f64(3.000000);
1654 \\ fn_bool(true);
1655 \\ fn_bool(false);
1656 \\ fn_bool(@ptrToInt(&fn_int) != 0);
1657 \\ fn_int(@intCast(c_int, @ptrToInt(&fn_int)));
1658 \\ fn_ptr(@intToPtr(?*c_void, 42));
1659 \\}
1660 );
1661
1662 cases.addC("pointer conversion with different alignment",
1663 \\void test_ptr_cast() {
1664 \\ void *p;
1665 \\ {
1666 \\ char *to_char = (char *)p;
1667 \\ short *to_short = (short *)p;
1668 \\ int *to_int = (int *)p;
1669 \\ long long *to_longlong = (long long *)p;
1670 \\ }
1671 \\ {
1672 \\ char *to_char = p;
1673 \\ short *to_short = p;
1674 \\ int *to_int = p;
1675 \\ long long *to_longlong = p;
1676 \\ }
1677 \\}
1678 ,
1679 \\pub export fn test_ptr_cast() void {
1680 \\ var p: ?*c_void = undefined;
1681 \\ {
1682 \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p));
1683 \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p));
1684 \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p));
1685 \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p));
1686 \\ }
1687 \\ {
1688 \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p));
1689 \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p));
1690 \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p));
1691 \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p));
1692 \\ }
1693 \\}
1694 );
1695
1696 /////////////// Cases for only stage1 because stage2 behavior is better ////////////////
1697 cases.addC("Parameterless function prototypes",
1698 \\void foo() {}
1699 \\void bar(void) {}
1700 ,
1701 \\pub export fn foo() void {}
1702 \\pub export fn bar() void {}
1703 );
15851704}