authorgravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-08 16:23:27-07:00
committergravatar for codroid@gmail.comhryx <codroid@gmail.com> 2019-06-08 16:23:27-07:00
logad0f0562d8103d65bd36eb12ead899f375bda3e0
tree97adb8031a0647becf1a8b638494d8a79264c9c3
parented5b8335b564cc4372b12e1c1a1b459aa348a90d
parent720ed74413f086a93f5ed66159300d8dd48e8034
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'master' into translate-c-userland


114 files changed, 3742 insertions(+), 1014 deletions(-)

.github/FUNDING.yml created+2
...@@ -0,0 +1,2 @@
1github: [andrewrk]
2patreon: andrewrk
CMakeLists.txt+8
...@@ -630,9 +630,11 @@ set(ZIG_STD_FILES...@@ -630,9 +630,11 @@ set(ZIG_STD_FILES
630 "os/windows/bits.zig"630 "os/windows/bits.zig"
631 "os/windows/error.zig"631 "os/windows/error.zig"
632 "os/windows/kernel32.zig"632 "os/windows/kernel32.zig"
633 "os/windows/lang.zig"
633 "os/windows/ntdll.zig"634 "os/windows/ntdll.zig"
634 "os/windows/ole32.zig"635 "os/windows/ole32.zig"
635 "os/windows/shell32.zig"636 "os/windows/shell32.zig"
637 "os/windows/sublang.zig"
636 "os/zen.zig"638 "os/zen.zig"
637 "packed_int_array.zig"639 "packed_int_array.zig"
638 "pdb.zig"640 "pdb.zig"
...@@ -6066,6 +6068,8 @@ set(ZIG_LIBC_FILES...@@ -6066,6 +6068,8 @@ set(ZIG_LIBC_FILES
6066 "include/x86_64-linux-musl/bits/stat.h"6068 "include/x86_64-linux-musl/bits/stat.h"
6067 "include/x86_64-linux-musl/bits/syscall.h"6069 "include/x86_64-linux-musl/bits/syscall.h"
6068 "include/x86_64-linux-musl/bits/user.h"6070 "include/x86_64-linux-musl/bits/user.h"
6071 "include/wasm32-freestanding-musl/bits/alltypes.h"
6072 "include/wasm32-freestanding-musl/errno.h"
6069 "musl/arch/aarch64/atomic_arch.h"6073 "musl/arch/aarch64/atomic_arch.h"
6070 "musl/arch/aarch64/bits/alltypes.h.in"6074 "musl/arch/aarch64/bits/alltypes.h.in"
6071 "musl/arch/aarch64/bits/endian.h"6075 "musl/arch/aarch64/bits/endian.h"
...@@ -6726,9 +6730,13 @@ add_custom_command(...@@ -6726,9 +6730,13 @@ add_custom_command(
6726 "-Doutput-dir=${CMAKE_BINARY_DIR}"6730 "-Doutput-dir=${CMAKE_BINARY_DIR}"
6727 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"6731 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
6728 DEPENDS6732 DEPENDS
6733 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
6729 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"6734 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
6730 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"6735 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
6731 "${CMAKE_SOURCE_DIR}/build.zig"6736 "${CMAKE_SOURCE_DIR}/build.zig"
6737 "${CMAKE_SOURCE_DIR}/std/zig/parse.zig"
6738 "${CMAKE_SOURCE_DIR}/std/zig/render.zig"
6739 "${CMAKE_SOURCE_DIR}/std/zig/tokenizer.zig"
6732)6740)
6733add_custom_target(userland_target DEPENDS "${LIBUSERLAND}")6741add_custom_target(userland_target DEPENDS "${LIBUSERLAND}")
6734add_executable(zig "${ZIG_MAIN_SRC}")6742add_executable(zig "${ZIG_MAIN_SRC}")
CONTRIBUTING.md created+91
...@@ -0,0 +1,91 @@
1## Contributing
2
3### Start a Project Using Zig
4
5One of the best ways you can contribute to Zig is to start using it for a
6personal project. Here are some great examples:
7
8 * [Oxid](https://github.com/dbandstra/oxid) - arcade style game
9 * [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games
10 * [trOS](https://github.com/sjdh02/trOS) - tiny aarch64 baremetal OS thingy
11
12Without fail, these projects lead to discovering bugs and helping flesh out use
13cases, which lead to further design iterations of Zig. Importantly, each issue
14found this way comes with real world motivations, so it is easy to explain
15your reasoning behind proposals and feature requests.
16
17Ideally, such a project will help you to learn new skills and add something
18to your personal portfolio at the same time.
19
20### Spread the Word
21
22Another way to contribute is to write about Zig, or speak about Zig at a
23conference, or do either of those things for your project which uses Zig.
24Here are some examples:
25
26 * [Iterative Replacement of C with Zig](http://tiehuis.github.io/blog/zig1.html)
27 * [The Right Tool for the Right Job: Redis Modules & Zig](https://www.youtube.com/watch?v=eCHM8-_poZY)
28
29Zig is a brand new language, with no advertising budget. Word of mouth is the
30only way people find out about the project, and the more people hear about it,
31the more people will use it, and the better chance we have to take over the
32world.
33
34### Finding Contributor Friendly Issues
35
36Please note that issues labeled
37[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal)
38but do not also have the
39[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted)
40label are still under consideration, and efforts to implement such a proposal
41have a high risk of being wasted. If you are interested in a proposal which is
42still under consideration, please express your interest in the issue tracker,
43providing extra insights and considerations that others have not yet expressed.
44The most highly regarded argument in such a discussion is a real world use case.
45
46The issue label
47[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22)
48exists to help contributors find issues that are "limited in scope and/or
49knowledge of Zig internals."
50
51### Editing Source Code
52
53First, build the Stage 1 compiler as described in [the Building section](#building).
54
55When making changes to the standard library, be sure to edit the files in the
56`std` directory and not the installed copy in the build directory. If you add a
57new file to the standard library, you must also add the file path in
58CMakeLists.txt.
59
60To test changes, do the following from the build directory:
61
621. Run `make install` (on POSIX) or
63 `msbuild -p:Configuration=Release INSTALL.vcxproj` (on Windows).
642. `bin/zig build --build-file ../build.zig test` (on POSIX) or
65 `bin\zig.exe build --build-file ..\build.zig test` (on Windows).
66
67That runs the whole test suite, which does a lot of extra testing that you
68likely won't always need, and can take upwards of 2 hours. This is what the
69CI server runs when you make a pull request.
70
71To save time, you can add the `--help` option to the `zig build` command and
72see what options are available. One of the most helpful ones is
73`-Dskip-release`. Adding this option to the command in step 2 above will take
74the time down from around 2 hours to about 6 minutes, and this is a good
75enough amount of testing before making a pull request.
76
77Another example is choosing a different set of things to test. For example,
78`test-std` instead of `test` will only run the standard library tests, and
79not the other ones. Combining this suggestion with the previous one, you could
80do this:
81
82`bin/zig build --build-file ../build.zig test-std -Dskip-release` (on POSIX) or
83`bin\zig.exe build --build-file ..\build.zig test-std -Dskip-release` (on Windows).
84
85This will run only the standard library tests, in debug mode only, for all
86targets (it will cross-compile the tests for non-native targets but not run
87them).
88
89When making changes to the compiler source code, the most helpful test step to
90run is `test-behavior`. When editing documentation it is `docs`. You can find
91this information and more in the `--help` menu.
README.md+1-92
...@@ -8,6 +8,7 @@ Zig is an open-source programming language designed for **robustness**,...@@ -8,6 +8,7 @@ Zig is an open-source programming language designed for **robustness**,
8 * [Introduction](https://ziglang.org/#Introduction)8 * [Introduction](https://ziglang.org/#Introduction)
9 * [Download & Documentation](https://ziglang.org/download)9 * [Download & Documentation](https://ziglang.org/download)
10 * [Community](https://github.com/ziglang/zig/wiki/Community)10 * [Community](https://github.com/ziglang/zig/wiki/Community)
11 * [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md)
1112
12## Building from Source13## Building from Source
1314
...@@ -96,95 +97,3 @@ use stage 1....@@ -96,95 +97,3 @@ use stage 1.
96```97```
97./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast98./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
98```99```
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.
ci/azure/linux_script+1-1
...@@ -28,7 +28,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then...@@ -28,7 +28,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
28 docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm8-1 -j2 $BUILD_SOURCEVERSION28 docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm8-1 -j2 $BUILD_SOURCEVERSION
29 TARBALL="$(ls $ARTIFACTSDIR)"29 TARBALL="$(ls $ARTIFACTSDIR)"
30 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"30 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
31 s3cmd put -P "$ARTIFACTSDIR/$TARBALL" s3://ziglang.org/builds/31 s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$ARTIFACTSDIR/$TARBALL" s3://ziglang.org/builds/
3232
33 SHASUM=$(sha256sum $ARTIFACTSDIR/$TARBALL | cut '-d ' -f1)33 SHASUM=$(sha256sum $ARTIFACTSDIR/$TARBALL | cut '-d ' -f1)
34 BYTESIZE=$(wc -c < $ARTIFACTSDIR/$TARBALL)34 BYTESIZE=$(wc -c < $ARTIFACTSDIR/$TARBALL)
ci/azure/macos_script+3-3
...@@ -6,7 +6,7 @@ set -e...@@ -6,7 +6,7 @@ set -e
6brew install s3cmd gcc@86brew install s3cmd gcc@8
77
8ZIGDIR="$(pwd)"8ZIGDIR="$(pwd)"
9CACHE_BASENAME="llvm+clang-8.0.0-macos-x86_64-gcc8-release-static"9CACHE_BASENAME="llvm+clang-8.0.0-macos-x86_64-gcc8-release"
10PREFIX="$HOME/$CACHE_BASENAME"10PREFIX="$HOME/$CACHE_BASENAME"
11TMPDIR="$HOME/tmpz"11TMPDIR="$HOME/tmpz"
12JOBS="-j2"12JOBS="-j2"
...@@ -62,7 +62,7 @@ else...@@ -62,7 +62,7 @@ else
62 cd $HOME62 cd $HOME
63 tar cfJ "$CACHE_BASENAME.tar.xz" "$CACHE_BASENAME"63 tar cfJ "$CACHE_BASENAME.tar.xz" "$CACHE_BASENAME"
64 cp "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"64 cp "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
65 s3cmd put -P "$CACHE_BASENAME.tar.xz" "s3://ziglang.org/builds/$CACHE_BASENAME.tar.xz"65 s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$CACHE_BASENAME.tar.xz" "s3://ziglang.org/builds/$CACHE_BASENAME.tar.xz"
66fi66fi
6767
68cd $ZIGDIR68cd $ZIGDIR
...@@ -85,7 +85,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then...@@ -85,7 +85,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
85 tar cfJ "$TARBALL" "$DIRNAME"85 tar cfJ "$TARBALL" "$DIRNAME"
8686
87 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"87 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
88 s3cmd put -P "$TARBALL" s3://ziglang.org/builds/88 s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/
8989
90 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)90 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
91 BYTESIZE=$(wc -c < $TARBALL)91 BYTESIZE=$(wc -c < $TARBALL)
ci/azure/pipelines.yml+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1jobs:1jobs:
2- job: BuildMacOS2- job: BuildMacOS
3 pool:3 pool:
4 vmImage: 'macOS 10.13'4 vmImage: 'macOS 10.14'
55
6 timeoutInMinutes: 3606 timeoutInMinutes: 360
77
ci/azure/update_download_page+1-1
...@@ -35,7 +35,7 @@ env...@@ -35,7 +35,7 @@ env
35"../$ZIG" run update-download-page.zig35"../$ZIG" run update-download-page.zig
3636
37mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"37mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
38s3cmd put -P "../$SRC_TARBALL" s3://ziglang.org/builds/38s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "../$SRC_TARBALL" s3://ziglang.org/builds/
39s3cmd put -P "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate"39s3cmd put -P "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
40s3cmd put -P www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate"40s3cmd put -P www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
41s3cmd put -P www/download/index.json s3://ziglang.org/download/index.json --add-header="Cache-Control: max-age=0, must-revalidate"41s3cmd put -P www/download/index.json s3://ziglang.org/download/index.json --add-header="Cache-Control: max-age=0, must-revalidate"
ci/azure/windows_upload+1-1
...@@ -19,7 +19,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then...@@ -19,7 +19,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
19 7z a "$TARBALL" "$DIRNAME"19 7z a "$TARBALL" "$DIRNAME"
2020
21 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"21 mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
22 s3cmd put -P "$TARBALL" s3://ziglang.org/builds/22 s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/
2323
24 SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1)24 SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1)
25 BYTESIZE=$(wc -c < $TARBALL)25 BYTESIZE=$(wc -c < $TARBALL)
ci/srht/freebsd_script+1-1
...@@ -36,7 +36,7 @@ if [ -f ~/.s3cfg ]; then...@@ -36,7 +36,7 @@ if [ -f ~/.s3cfg ]; then
36 mv release "$DIRNAME"36 mv release "$DIRNAME"
37 tar cfJ "$TARBALL" "$DIRNAME"37 tar cfJ "$TARBALL" "$DIRNAME"
3838
39 s3cmd put -P "$TARBALL" s3://ziglang.org/builds/39 s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/
4040
41 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)41 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
42 BYTESIZE=$(wc -c < $TARBALL)42 BYTESIZE=$(wc -c < $TARBALL)
doc/docgen.zig+1-1
...@@ -788,7 +788,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -788,7 +788,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
788 std.zig.Token.Id.Keyword_try,788 std.zig.Token.Id.Keyword_try,
789 std.zig.Token.Id.Keyword_union,789 std.zig.Token.Id.Keyword_union,
790 std.zig.Token.Id.Keyword_unreachable,790 std.zig.Token.Id.Keyword_unreachable,
791 std.zig.Token.Id.Keyword_use,791 std.zig.Token.Id.Keyword_usingnamespace,
792 std.zig.Token.Id.Keyword_var,792 std.zig.Token.Id.Keyword_var,
793 std.zig.Token.Id.Keyword_volatile,793 std.zig.Token.Id.Keyword_volatile,
794 std.zig.Token.Id.Keyword_allowzero,794 std.zig.Token.Id.Keyword_allowzero,
doc/langref.html.in+61-12
...@@ -2026,9 +2026,9 @@ fn foo(bytes: []u8) u32 {...@@ -2026,9 +2026,9 @@ fn foo(bytes: []u8) u32 {
2026 {#header_open|allowzero#}2026 {#header_open|allowzero#}
2027 <p>2027 <p>
2028 This pointer attribute allows a pointer to have address zero. This is only ever needed on the2028 This pointer attribute allows a pointer to have address zero. This is only ever needed on the
2029 freestanding OS target, where the address zero is mappable. In this code example, if the pointer2029 freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use
2030 did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a2030 {#link|Optional Pointers#} instead. In this code example, if the pointer did not have the
2031 {#link|Pointer Cast Invalid Null#} panic:2031 {#syntax#}allowzero{#endsyntax#} attribute, this would be a {#link|Pointer Cast Invalid Null#} panic:
2032 </p>2032 </p>
2033 {#code_begin|test|allowzero#}2033 {#code_begin|test|allowzero#}
2034const std = @import("std");2034const std = @import("std");
...@@ -2263,6 +2263,28 @@ test "linked list" {...@@ -2263,6 +2263,28 @@ test "linked list" {
2263}2263}
2264 {#code_end#}2264 {#code_end#}
22652265
2266 {#header_open|Default Field Values#}
2267 <p>
2268 Each struct field may have an expression indicating the default field value. Such expressions
2269 are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:
2270 </p>
2271 {#code_begin|test#}
2272const Foo = struct {
2273 a: i32 = 1234,
2274 b: i32,
2275};
2276
2277test "default struct initialization fields" {
2278 const x = Foo{
2279 .b = 5,
2280 };
2281 if (x.a + x.b != 1239) {
2282 @compileError("it's even comptime known!");
2283 }
2284}
2285 {#code_end#}
2286 {#header_close#}
2287
2266 {#header_open|extern struct#}2288 {#header_open|extern struct#}
2267 <p>An {#syntax#}extern struct{#endsyntax#} has in-memory layout guaranteed to match the2289 <p>An {#syntax#}extern struct{#endsyntax#} has in-memory layout guaranteed to match the
2268 C ABI for the target.</p>2290 C ABI for the target.</p>
...@@ -3271,6 +3293,7 @@ test "for else" {...@@ -3271,6 +3293,7 @@ test "for else" {
3271 var items = []?i32 { 3, 4, null, 5 };3293 var items = []?i32 { 3, 4, null, 5 };
32723294
3273 // For loops can also be used as expressions.3295 // For loops can also be used as expressions.
3296 // Similar to while loops, when you break from a for loop, the else branch is not evaluated.
3274 var sum: i32 = 0;3297 var sum: i32 = 0;
3275 const result = for (items) |value| {3298 const result = for (items) |value| {
3276 if (value == null) {3299 if (value == null) {
...@@ -7545,7 +7568,7 @@ pub const TypeInfo = union(TypeId) {...@@ -7545,7 +7568,7 @@ pub const TypeInfo = union(TypeId) {
7545 pub const Struct = struct {7568 pub const Struct = struct {
7546 layout: ContainerLayout,7569 layout: ContainerLayout,
7547 fields: []StructField,7570 fields: []StructField,
7548 defs: []Definition,7571 decls: []Declaration,
7549 };7572 };
75507573
7551 pub const Optional = struct {7574 pub const Optional = struct {
...@@ -7573,7 +7596,7 @@ pub const TypeInfo = union(TypeId) {...@@ -7573,7 +7596,7 @@ pub const TypeInfo = union(TypeId) {
7573 layout: ContainerLayout,7596 layout: ContainerLayout,
7574 tag_type: type,7597 tag_type: type,
7575 fields: []EnumField,7598 fields: []EnumField,
7576 defs: []Definition,7599 decls: []Declaration,
7577 };7600 };
75787601
7579 pub const UnionField = struct {7602 pub const UnionField = struct {
...@@ -7586,7 +7609,7 @@ pub const TypeInfo = union(TypeId) {...@@ -7586,7 +7609,7 @@ pub const TypeInfo = union(TypeId) {
7586 layout: ContainerLayout,7609 layout: ContainerLayout,
7587 tag_type: ?type,7610 tag_type: ?type,
7588 fields: []UnionField,7611 fields: []UnionField,
7589 defs: []Definition,7612 decls: []Declaration,
7590 };7613 };
75917614
7592 pub const CallingConvention = enum {7615 pub const CallingConvention = enum {
...@@ -7622,7 +7645,7 @@ pub const TypeInfo = union(TypeId) {...@@ -7622,7 +7645,7 @@ pub const TypeInfo = union(TypeId) {
7622 child: type,7645 child: type,
7623 };7646 };
76247647
7625 pub const Definition = struct {7648 pub const Declaration = struct {
7626 name: []const u8,7649 name: []const u8,
7627 is_pub: bool,7650 is_pub: bool,
7628 data: Data,7651 data: Data,
...@@ -7630,9 +7653,9 @@ pub const TypeInfo = union(TypeId) {...@@ -7630,9 +7653,9 @@ pub const TypeInfo = union(TypeId) {
7630 pub const Data = union(enum) {7653 pub const Data = union(enum) {
7631 Type: type,7654 Type: type,
7632 Var: type,7655 Var: type,
7633 Fn: FnDef,7656 Fn: FnDecl,
76347657
7635 pub const FnDef = struct {7658 pub const FnDecl = struct {
7636 fn_type: type,7659 fn_type: type,
7637 inline_type: Inline,7660 inline_type: Inline,
7638 calling_convention: CallingConvention,7661 calling_convention: CallingConvention,
...@@ -8466,6 +8489,8 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {...@@ -8466,6 +8489,8 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
8466 </li>8489 </li>
8467 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely8490 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
8468 the right choice, at least for your main allocator.</li>8491 the right choice, at least for your main allocator.</li>
8492 <li>Are you building for WebAssembly? In this case, {#syntax#}std.heap.wasm_allocator{#endsyntax#} is likely
8493 the right choice for your main allocator as it uses WebAssembly's memory instructions.</li>
8469 <li>8494 <li>
8470 Is the maximum number of bytes that you will need bounded by a number known at8495 Is the maximum number of bytes that you will need bounded by a number known at
8471 {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or8496 {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or
...@@ -8996,8 +9021,12 @@ all your base are belong to us</code></pre>...@@ -8996,8 +9021,12 @@ all your base are belong to us</code></pre>
8996 {#header_close#}9021 {#header_close#}
8997 {#header_close#}9022 {#header_close#}
8998 {#header_open|WebAssembly#}9023 {#header_open|WebAssembly#}
9024 <p>Zig supports building for WebAssembly out of the box. There is also a specialized {#syntax#}std.heap.wasm_allocator{#endsyntax#}
9025 memory allocator for WebAssembly environments.</p>
8999 {#header_open|Freestanding#}9026 {#header_open|Freestanding#}
9000 {#code_begin|lib|wasm#}9027 <p>For host environments like the web browser and nodejs, build as a library using the freestanding OS target.
9028 Here's an example of running Zig code compiled to WebAssembly with nodejs.</p>
9029 {#code_begin|lib|math#}
9001 {#target_wasm#}9030 {#target_wasm#}
9002extern fn print(i32) void;9031extern fn print(i32) void;
90039032
...@@ -9006,7 +9035,22 @@ export fn add(a: i32, b: i32) void {...@@ -9006,7 +9035,22 @@ export fn add(a: i32, b: i32) void {
9006}9035}
9007 {#code_end#}9036 {#code_end#}
9008 {#header_close#}9037 {#header_close#}
9038 <p class="file">test.js</p>
9039 <pre><code>const fs = require('fs');
9040const source = fs.readFileSync("./math.wasm");
9041const typedArray = new Uint8Array(source);
9042
9043WebAssembly.instantiate(typedArray, {
9044 env: {
9045 print: (result) =&gt; { console.log(`The result is ${result}`); }
9046 }}).then(result =&gt; {
9047 const add = result.instance.exports.add;
9048 add(1, 2);
9049});</code></pre>
9050 <pre><code>$ node test.js
9051The result is 3</code></pre>
9009 {#header_open|WASI#}9052 {#header_open|WASI#}
9053 <p>Zig's support for WebAssembly System Interface (WASI) is under active development. Example of using the standard library and reading command line arguments:</p>
9010 {#code_begin|exe|wasi#}9054 {#code_begin|exe|wasi#}
9011 {#target_wasi#}9055 {#target_wasi#}
9012const std = @import("std");9056const std = @import("std");
...@@ -9020,6 +9064,10 @@ pub fn main() !void {...@@ -9020,6 +9064,10 @@ pub fn main() !void {
9020 }9064 }
9021}9065}
9022 {#code_end#}9066 {#code_end#}
9067 <pre><code>$ wasmer run wasi.wasm 123 hello
90680: wasi.wasm
90691: 123
90702: hello</code></pre>
9023 {#header_close#}9071 {#header_close#}
9024 {#header_close#}9072 {#header_close#}
9025 {#header_open|Targets#}9073 {#header_open|Targets#}
...@@ -9260,6 +9308,7 @@ Available libcs:...@@ -9260,6 +9308,7 @@ Available libcs:
9260 s390x-linux-musl9308 s390x-linux-musl
9261 sparc-linux-gnu9309 sparc-linux-gnu
9262 sparcv9-linux-gnu9310 sparcv9-linux-gnu
9311 wasm32-freestanding-musl
9263 x86_64-linux-gnu9312 x86_64-linux-gnu
9264 x86_64-linux-gnux329313 x86_64-linux-gnux32
9265 x86_64-linux-musl</code></pre>9314 x86_64-linux-musl</code></pre>
...@@ -9892,7 +9941,7 @@ KEYWORD_try &lt;- 'try' end_of_word...@@ -9892,7 +9941,7 @@ KEYWORD_try &lt;- 'try' end_of_word
9892KEYWORD_undefined &lt;- 'undefined' end_of_word9941KEYWORD_undefined &lt;- 'undefined' end_of_word
9893KEYWORD_union &lt;- 'union' end_of_word9942KEYWORD_union &lt;- 'union' end_of_word
9894KEYWORD_unreachable &lt;- 'unreachable' end_of_word9943KEYWORD_unreachable &lt;- 'unreachable' end_of_word
9895KEYWORD_use &lt;- 'use' end_of_word9944KEYWORD_usingnamespace &lt;- 'usingnamespace' end_of_word
9896KEYWORD_var &lt;- 'var' end_of_word9945KEYWORD_var &lt;- 'var' end_of_word
9897KEYWORD_volatile &lt;- 'volatile' end_of_word9946KEYWORD_volatile &lt;- 'volatile' end_of_word
9898KEYWORD_while &lt;- 'while' end_of_word9947KEYWORD_while &lt;- 'while' end_of_word
...@@ -9909,7 +9958,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_anyerror...@@ -9909,7 +9958,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_anyerror
9909 / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend9958 / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
9910 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try9959 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
9911 / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable9960 / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable
9912 / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>9961 / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>
9913 {#header_close#}9962 {#header_close#}
9914 {#header_open|Zen#}9963 {#header_open|Zen#}
9915 <ul>9964 <ul>
libc/include/wasm32-freestanding-musl/bits/alltypes.h created+385
...@@ -0,0 +1,385 @@
1#define _Addr long
2#define _Int64 long long
3#define _Reg long
4
5#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
6typedef __builtin_va_list va_list;
7#define __DEFINED_va_list
8#endif
9
10#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
11typedef __builtin_va_list __isoc_va_list;
12#define __DEFINED___isoc_va_list
13#endif
14
15
16#ifndef __cplusplus
17#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
18typedef int wchar_t;
19#define __DEFINED_wchar_t
20#endif
21
22#endif
23
24#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
25typedef float float_t;
26#define __DEFINED_float_t
27#endif
28
29#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
30typedef double double_t;
31#define __DEFINED_double_t
32#endif
33
34
35#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
36typedef struct { long long __ll; long double __ld; } max_align_t;
37#define __DEFINED_max_align_t
38#endif
39
40
41#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
42typedef long time_t;
43#define __DEFINED_time_t
44#endif
45
46#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
47typedef long suseconds_t;
48#define __DEFINED_suseconds_t
49#endif
50
51
52#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
53typedef struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t;
54#define __DEFINED_pthread_attr_t
55#endif
56
57#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
58typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
59#define __DEFINED_pthread_mutex_t
60#endif
61
62#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
63typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
64#define __DEFINED_mtx_t
65#endif
66
67#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
68typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
69#define __DEFINED_pthread_cond_t
70#endif
71
72#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
73typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
74#define __DEFINED_cnd_t
75#endif
76
77#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
78typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
79#define __DEFINED_pthread_rwlock_t
80#endif
81
82#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
83typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
84#define __DEFINED_pthread_barrier_t
85#endif
86
87#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
88typedef unsigned _Addr size_t;
89#define __DEFINED_size_t
90#endif
91
92#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
93typedef unsigned _Addr uintptr_t;
94#define __DEFINED_uintptr_t
95#endif
96
97#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
98typedef _Addr ptrdiff_t;
99#define __DEFINED_ptrdiff_t
100#endif
101
102#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
103typedef _Addr ssize_t;
104#define __DEFINED_ssize_t
105#endif
106
107#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
108typedef _Addr intptr_t;
109#define __DEFINED_intptr_t
110#endif
111
112#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
113typedef _Addr regoff_t;
114#define __DEFINED_regoff_t
115#endif
116
117#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
118typedef _Reg register_t;
119#define __DEFINED_register_t
120#endif
121
122
123#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
124typedef signed char int8_t;
125#define __DEFINED_int8_t
126#endif
127
128#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
129typedef signed short int16_t;
130#define __DEFINED_int16_t
131#endif
132
133#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
134typedef signed int int32_t;
135#define __DEFINED_int32_t
136#endif
137
138#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
139typedef signed _Int64 int64_t;
140#define __DEFINED_int64_t
141#endif
142
143#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
144typedef signed _Int64 intmax_t;
145#define __DEFINED_intmax_t
146#endif
147
148#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
149typedef unsigned char uint8_t;
150#define __DEFINED_uint8_t
151#endif
152
153#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
154typedef unsigned short uint16_t;
155#define __DEFINED_uint16_t
156#endif
157
158#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
159typedef unsigned int uint32_t;
160#define __DEFINED_uint32_t
161#endif
162
163#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
164typedef unsigned _Int64 uint64_t;
165#define __DEFINED_uint64_t
166#endif
167
168#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t)
169typedef unsigned _Int64 u_int64_t;
170#define __DEFINED_u_int64_t
171#endif
172
173#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
174typedef unsigned _Int64 uintmax_t;
175#define __DEFINED_uintmax_t
176#endif
177
178
179#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
180typedef unsigned mode_t;
181#define __DEFINED_mode_t
182#endif
183
184#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
185typedef unsigned _Reg nlink_t;
186#define __DEFINED_nlink_t
187#endif
188
189#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
190typedef _Int64 off_t;
191#define __DEFINED_off_t
192#endif
193
194#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
195typedef unsigned _Int64 ino_t;
196#define __DEFINED_ino_t
197#endif
198
199#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
200typedef unsigned _Int64 dev_t;
201#define __DEFINED_dev_t
202#endif
203
204#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
205typedef long blksize_t;
206#define __DEFINED_blksize_t
207#endif
208
209#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
210typedef _Int64 blkcnt_t;
211#define __DEFINED_blkcnt_t
212#endif
213
214#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
215typedef unsigned _Int64 fsblkcnt_t;
216#define __DEFINED_fsblkcnt_t
217#endif
218
219#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
220typedef unsigned _Int64 fsfilcnt_t;
221#define __DEFINED_fsfilcnt_t
222#endif
223
224
225#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
226typedef unsigned wint_t;
227#define __DEFINED_wint_t
228#endif
229
230#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
231typedef unsigned long wctype_t;
232#define __DEFINED_wctype_t
233#endif
234
235
236#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
237typedef void * timer_t;
238#define __DEFINED_timer_t
239#endif
240
241#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
242typedef int clockid_t;
243#define __DEFINED_clockid_t
244#endif
245
246#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
247typedef long clock_t;
248#define __DEFINED_clock_t
249#endif
250
251#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
252struct timeval { time_t tv_sec; suseconds_t tv_usec; };
253#define __DEFINED_struct_timeval
254#endif
255
256#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
257struct timespec { time_t tv_sec; long tv_nsec; };
258#define __DEFINED_struct_timespec
259#endif
260
261
262#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
263typedef int pid_t;
264#define __DEFINED_pid_t
265#endif
266
267#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
268typedef unsigned id_t;
269#define __DEFINED_id_t
270#endif
271
272#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
273typedef unsigned uid_t;
274#define __DEFINED_uid_t
275#endif
276
277#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
278typedef unsigned gid_t;
279#define __DEFINED_gid_t
280#endif
281
282#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
283typedef int key_t;
284#define __DEFINED_key_t
285#endif
286
287#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
288typedef unsigned useconds_t;
289#define __DEFINED_useconds_t
290#endif
291
292
293#ifdef __cplusplus
294#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
295typedef unsigned long pthread_t;
296#define __DEFINED_pthread_t
297#endif
298
299#else
300#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
301typedef struct __pthread * pthread_t;
302#define __DEFINED_pthread_t
303#endif
304
305#endif
306#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
307typedef int pthread_once_t;
308#define __DEFINED_pthread_once_t
309#endif
310
311#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
312typedef unsigned pthread_key_t;
313#define __DEFINED_pthread_key_t
314#endif
315
316#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
317typedef int pthread_spinlock_t;
318#define __DEFINED_pthread_spinlock_t
319#endif
320
321#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
322typedef struct { unsigned __attr; } pthread_mutexattr_t;
323#define __DEFINED_pthread_mutexattr_t
324#endif
325
326#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
327typedef struct { unsigned __attr; } pthread_condattr_t;
328#define __DEFINED_pthread_condattr_t
329#endif
330
331#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
332typedef struct { unsigned __attr; } pthread_barrierattr_t;
333#define __DEFINED_pthread_barrierattr_t
334#endif
335
336#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
337typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t;
338#define __DEFINED_pthread_rwlockattr_t
339#endif
340
341
342#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
343typedef struct _IO_FILE FILE;
344#define __DEFINED_FILE
345#endif
346
347
348#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
349typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
350#define __DEFINED_mbstate_t
351#endif
352
353
354#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
355typedef struct __locale_struct * locale_t;
356#define __DEFINED_locale_t
357#endif
358
359
360#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
361typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
362#define __DEFINED_sigset_t
363#endif
364
365
366#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
367struct iovec { void *iov_base; size_t iov_len; };
368#define __DEFINED_struct_iovec
369#endif
370
371
372#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
373typedef unsigned socklen_t;
374#define __DEFINED_socklen_t
375#endif
376
377#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
378typedef unsigned short sa_family_t;
379#define __DEFINED_sa_family_t
380#endif
381
382
383#undef _Addr
384#undef _Int64
385#undef _Reg
libc/include/wasm32-freestanding-musl/errno.h created+24
...@@ -0,0 +1,24 @@
1#ifndef _ERRNO_H
2#define _ERRNO_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#ifdef WASM_THREAD_MODEL_SINGLE
9extern int errno;
10#else
11#ifdef __cplusplus
12extern thread_local int errno;
13#else
14extern _Thread_local int errno;
15#endif
16#endif
17
18#define errno errno
19
20#ifdef __cplusplus
21}
22#endif
23
24#endif
src-self-hosted/c.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1pub use @cImport({1pub usingnamespace @cImport({
2 @cDefine("__STDC_CONSTANT_MACROS", "");2 @cDefine("__STDC_CONSTANT_MACROS", "");
3 @cDefine("__STDC_LIMIT_MACROS", "");3 @cDefine("__STDC_LIMIT_MACROS", "");
4 @cInclude("inttypes.h");4 @cInclude("inttypes.h");
src-self-hosted/clang.zig+209-213
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1pub const struct_ZigClangAPValue = @OpaqueType();1pub const struct_ZigClangAPValue = @OpaqueType();
2pub const struct_ZigClangAPSInt = @OpaqueType();2pub const struct_ZigClangAPSInt = @OpaqueType();
3pub const struct_ZigClangAPFloat = @OpaqueType();
3pub const struct_ZigClangASTContext = @OpaqueType();4pub const struct_ZigClangASTContext = @OpaqueType();
4pub const struct_ZigClangASTUnit = @OpaqueType();5pub const struct_ZigClangASTUnit = @OpaqueType();
5pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();6pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();
...@@ -12,7 +13,7 @@ pub const struct_ZigClangCStyleCastExpr = @OpaqueType();...@@ -12,7 +13,7 @@ pub const struct_ZigClangCStyleCastExpr = @OpaqueType();
12pub const struct_ZigClangCallExpr = @OpaqueType();13pub const struct_ZigClangCallExpr = @OpaqueType();
13pub const struct_ZigClangCaseStmt = @OpaqueType();14pub const struct_ZigClangCaseStmt = @OpaqueType();
14pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();15pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
15pub const ZigClangCompoundStmt = @OpaqueType();16pub const struct_ZigClangCompoundStmt = @OpaqueType();
16pub const struct_ZigClangConditionalOperator = @OpaqueType();17pub const struct_ZigClangConditionalOperator = @OpaqueType();
17pub const struct_ZigClangConstantArrayType = @OpaqueType();18pub const struct_ZigClangConstantArrayType = @OpaqueType();
18pub const struct_ZigClangContinueStmt = @OpaqueType();19pub const struct_ZigClangContinueStmt = @OpaqueType();
...@@ -33,7 +34,7 @@ pub const struct_ZigClangFieldDecl = @OpaqueType();...@@ -33,7 +34,7 @@ pub const struct_ZigClangFieldDecl = @OpaqueType();
33pub const struct_ZigClangFileID = @OpaqueType();34pub const struct_ZigClangFileID = @OpaqueType();
34pub const struct_ZigClangForStmt = @OpaqueType();35pub const struct_ZigClangForStmt = @OpaqueType();
35pub const struct_ZigClangFullSourceLoc = @OpaqueType();36pub const struct_ZigClangFullSourceLoc = @OpaqueType();
36pub const ZigClangFunctionDecl = @OpaqueType();37pub const struct_ZigClangFunctionDecl = @OpaqueType();
37pub const struct_ZigClangFunctionProtoType = @OpaqueType();38pub const struct_ZigClangFunctionProtoType = @OpaqueType();
38pub const struct_ZigClangIfStmt = @OpaqueType();39pub const struct_ZigClangIfStmt = @OpaqueType();
39pub const struct_ZigClangImplicitCastExpr = @OpaqueType();40pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
...@@ -68,7 +69,8 @@ pub const struct_ZigClangUnaryOperator = @OpaqueType();...@@ -68,7 +69,8 @@ pub const struct_ZigClangUnaryOperator = @OpaqueType();
68pub const struct_ZigClangValueDecl = @OpaqueType();69pub const struct_ZigClangValueDecl = @OpaqueType();
69pub const struct_ZigClangVarDecl = @OpaqueType();70pub const struct_ZigClangVarDecl = @OpaqueType();
70pub const struct_ZigClangWhileStmt = @OpaqueType();71pub const struct_ZigClangWhileStmt = @OpaqueType();
71pub const ZigClangFunctionType = @OpaqueType();72pub const struct_ZigClangFunctionType = @OpaqueType();
73pub const struct_ZigClangPredefinedExpr = @OpaqueType();
7274
73pub const ZigClangBO = extern enum {75pub const ZigClangBO = extern enum {
74 PtrMemD,76 PtrMemD,
...@@ -450,188 +452,6 @@ pub const ZigClangAPValueKind = extern enum {...@@ -450,188 +452,6 @@ pub const ZigClangAPValueKind = extern enum {
450 AddrLabelDiff,452 AddrLabelDiff,
451};453};
452454
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_getTypeClass(self: struct_ZigClangQualType) ZigClangTypeClass;
483pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;
484pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void;
485pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
486pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) bool;
487pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool;
488pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool;
489pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
490pub extern fn ZigClangType_getPointeeType(self: ?*const struct_ZigClangType) struct_ZigClangQualType;
491pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
492pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
493pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
494pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
495pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
496pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
497pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
498pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
499pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
500pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
501pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
502pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
503pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
504pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
505pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
506pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
507pub extern fn ZigClangAPSInt_isNegative(self: ?*const struct_ZigClangAPSInt) bool;
508pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const struct_ZigClangAPSInt;
509pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
510pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
511pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
512pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
513pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void;
514
515pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType;
516pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation;
517pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
518pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
519pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
520pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
521
522pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
523
524pub extern fn ZigClangFunctionType_getNoReturnAttr(self: *const ZigClangFunctionType) bool;
525pub extern fn ZigClangFunctionType_getCallConv(self: *const ZigClangFunctionType) ZigClangCallingConv;
526pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionType) ZigClangQualType;
527
528pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
529pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
530pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
531
532pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
533pub const ZigClangQualType = struct_ZigClangQualType;
534pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
535pub const ZigClangAPValue = struct_ZigClangAPValue;
536pub const ZigClangAPSInt = struct_ZigClangAPSInt;
537pub const ZigClangASTContext = struct_ZigClangASTContext;
538pub const ZigClangASTUnit = struct_ZigClangASTUnit;
539pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr;
540pub const ZigClangArrayType = struct_ZigClangArrayType;
541pub const ZigClangAttributedType = struct_ZigClangAttributedType;
542pub const ZigClangBinaryOperator = struct_ZigClangBinaryOperator;
543pub const ZigClangBreakStmt = struct_ZigClangBreakStmt;
544pub const ZigClangBuiltinType = struct_ZigClangBuiltinType;
545pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr;
546pub const ZigClangCallExpr = struct_ZigClangCallExpr;
547pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
548pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
549pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
550pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
551pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
552pub const ZigClangDecayedType = struct_ZigClangDecayedType;
553pub const ZigClangDecl = struct_ZigClangDecl;
554pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr;
555pub const ZigClangDeclStmt = struct_ZigClangDeclStmt;
556pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt;
557pub const ZigClangDiagnosticOptions = struct_ZigClangDiagnosticOptions;
558pub const ZigClangDiagnosticsEngine = struct_ZigClangDiagnosticsEngine;
559pub const ZigClangDoStmt = struct_ZigClangDoStmt;
560pub const ZigClangElaboratedType = struct_ZigClangElaboratedType;
561pub const ZigClangEnumConstantDecl = struct_ZigClangEnumConstantDecl;
562pub const ZigClangEnumDecl = struct_ZigClangEnumDecl;
563pub const ZigClangEnumType = struct_ZigClangEnumType;
564pub const ZigClangExpr = struct_ZigClangExpr;
565pub const ZigClangFieldDecl = struct_ZigClangFieldDecl;
566pub const ZigClangFileID = struct_ZigClangFileID;
567pub const ZigClangForStmt = struct_ZigClangForStmt;
568pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc;
569pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType;
570pub const ZigClangIfStmt = struct_ZigClangIfStmt;
571pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
572pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
573pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
574pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
575pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
576pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
577pub const ZigClangNone = struct_ZigClangNone;
578pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
579pub const ZigClangParenExpr = struct_ZigClangParenExpr;
580pub const ZigClangParenType = struct_ZigClangParenType;
581pub const ZigClangParmVarDecl = struct_ZigClangParmVarDecl;
582pub const ZigClangPointerType = struct_ZigClangPointerType;
583pub const ZigClangPreprocessedEntity = struct_ZigClangPreprocessedEntity;
584pub const ZigClangRecordDecl = struct_ZigClangRecordDecl;
585pub const ZigClangRecordType = struct_ZigClangRecordType;
586pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
587pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
588pub const ZigClangSourceManager = struct_ZigClangSourceManager;
589pub const ZigClangSourceRange = struct_ZigClangSourceRange;
590pub const ZigClangStmt = struct_ZigClangStmt;
591pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
592pub const ZigClangStringRef = struct_ZigClangStringRef;
593pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
594pub const ZigClangTagDecl = struct_ZigClangTagDecl;
595pub const ZigClangType = struct_ZigClangType;
596pub const ZigClangTypedefNameDecl = struct_ZigClangTypedefNameDecl;
597pub const ZigClangTypedefType = struct_ZigClangTypedefType;
598pub const ZigClangUnaryExprOrTypeTraitExpr = struct_ZigClangUnaryExprOrTypeTraitExpr;
599pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator;
600pub const ZigClangValueDecl = struct_ZigClangValueDecl;
601pub const ZigClangVarDecl = struct_ZigClangVarDecl;
602pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
603
604pub const struct_ZigClangSourceLocation = extern struct {
605 ID: c_uint,
606};
607
608pub const Stage2ErrorMsg = extern struct {
609 filename_ptr: ?[*]const u8,
610 filename_len: usize,
611 msg_ptr: [*]const u8,
612 msg_len: usize,
613 // valid until the ASTUnit is freed
614 source: ?[*]const u8,
615 // 0 based
616 line: c_uint,
617 // 0 based
618 column: c_uint,
619 // byte offset into source
620 offset: c_uint,
621};
622pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void;
623
624pub extern fn ZigClangLoadFromCommandLine(
625 args_begin: [*]?[*]const u8,
626 args_end: [*]?[*]const u8,
627 errors_ptr: *[*]Stage2ErrorMsg,
628 errors_len: *usize,
629 resources_path: [*c]const u8,
630) ?*ZigClangASTUnit;
631
632pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
633pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*]const u8;
634
635pub const ZigClangDeclKind = extern enum {455pub const ZigClangDeclKind = extern enum {
636 AccessSpec,456 AccessSpec,
637 Block,457 Block,
...@@ -709,10 +529,6 @@ pub const ZigClangDeclKind = extern enum {...@@ -709,10 +529,6 @@ pub const ZigClangDeclKind = extern enum {
709 TranslationUnit,529 TranslationUnit,
710};530};
711531
712pub const struct_ZigClangQualType = extern struct {
713 ptr: ?*c_void,
714};
715
716pub const ZigClangBuiltinTypeKind = extern enum {532pub const ZigClangBuiltinTypeKind = extern enum {
717 OCLImage1dRO,533 OCLImage1dRO,
718 OCLImage1dArrayRO,534 OCLImage1dArrayRO,
...@@ -862,39 +678,219 @@ pub const ZigClangStorageClass = extern enum {...@@ -862,39 +678,219 @@ pub const ZigClangStorageClass = extern enum {
862 Register,678 Register,
863};679};
864680
865pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt;681pub const ZigClangAPFloat_roundingMode = extern enum {
682 NearestTiesToEven,
683 TowardPositive,
684 TowardNegative,
685 TowardZero,
686 NearestTiesToAway,
687};
866688
867pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;689pub const ZigClangStringLiteral_StringKind = extern enum {
868pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;690 Ascii,
691 Wide,
692 UTF8,
693 UTF16,
694 UTF32,
695};
696
697pub extern fn ZigClangSourceManager_getSpellingLoc(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation;
698pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8;
699pub extern fn ZigClangSourceManager_getSpellingLineNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
700pub extern fn ZigClangSourceManager_getSpellingColumnNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
701pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8;
702pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
703pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
704pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
705pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
706pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl;
707pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl;
708pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
709pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
710pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
711pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
712pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
713pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
714pub extern fn ZigClangEnumDecl_getLocation(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation;
715pub extern fn ZigClangTypedefNameDecl_getLocation(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation;
716pub extern fn ZigClangDecl_getLocation(self: *const ZigClangDecl) ZigClangSourceLocation;
717pub extern fn ZigClangRecordDecl_isUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
718pub extern fn ZigClangRecordDecl_isStruct(record_decl: ?*const struct_ZigClangRecordDecl) bool;
719pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
720pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
721pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
722pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
723pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
724pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
725pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType;
726pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType;
727pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void;
728pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
729pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) bool;
730pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool;
731pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool;
732pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass;
733pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
734pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8;
735pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
736pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
737pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
738pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) ZigClangStmtClass;
739pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
740pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
741pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) ZigClangAPValueKind;
742pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
743pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
744pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
745pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
746pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
747pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
748pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
749pub extern fn ZigClangAPSInt_isNegative(self: ?*const struct_ZigClangAPSInt) bool;
750pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const struct_ZigClangAPSInt;
751pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
752pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
753pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
754pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
755pub extern fn ZigClangASTUnit_delete(self: ?*struct_ZigClangASTUnit) void;
756
757pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType;
758pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation;
759pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
760pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
761pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
762pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
869763
870pub const ZigClangDeclStmt_const_decl_iterator = [*c]const *struct_ZigClangDecl;764pub extern fn ZigClangBuiltinType_getKind(self: *const struct_ZigClangBuiltinType) ZigClangBuiltinTypeKind;
871765
872pub extern fn ZigClangDeclStmt_decl_begin(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;766pub extern fn ZigClangFunctionType_getNoReturnAttr(self: *const ZigClangFunctionType) bool;
873pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;767pub extern fn ZigClangFunctionType_getCallConv(self: *const ZigClangFunctionType) ZigClangCallingConv;
768pub extern fn ZigClangFunctionType_getReturnType(self: *const ZigClangFunctionType) ZigClangQualType;
874769
875pub extern fn ZigClangVarDecl_getType(self: ?*const struct_ZigClangVarDecl) struct_ZigClangQualType;770pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
876pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;771pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
877pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;772pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
878pub const ZigClangVarDecl_TLSKind = extern enum {773
879 None,774pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
880 Static,775pub const ZigClangQualType = struct_ZigClangQualType;
881 Dynamic,776pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
777pub const ZigClangAPValue = struct_ZigClangAPValue;
778pub const ZigClangAPSInt = struct_ZigClangAPSInt;
779pub const ZigClangAPFloat = struct_ZigClangAPFloat;
780pub const ZigClangASTContext = struct_ZigClangASTContext;
781pub const ZigClangASTUnit = struct_ZigClangASTUnit;
782pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr;
783pub const ZigClangArrayType = struct_ZigClangArrayType;
784pub const ZigClangAttributedType = struct_ZigClangAttributedType;
785pub const ZigClangBinaryOperator = struct_ZigClangBinaryOperator;
786pub const ZigClangBreakStmt = struct_ZigClangBreakStmt;
787pub const ZigClangBuiltinType = struct_ZigClangBuiltinType;
788pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr;
789pub const ZigClangCallExpr = struct_ZigClangCallExpr;
790pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
791pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
792pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
793pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
794pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
795pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
796pub const ZigClangDecayedType = struct_ZigClangDecayedType;
797pub const ZigClangDecl = struct_ZigClangDecl;
798pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr;
799pub const ZigClangDeclStmt = struct_ZigClangDeclStmt;
800pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt;
801pub const ZigClangDiagnosticOptions = struct_ZigClangDiagnosticOptions;
802pub const ZigClangDiagnosticsEngine = struct_ZigClangDiagnosticsEngine;
803pub const ZigClangDoStmt = struct_ZigClangDoStmt;
804pub const ZigClangElaboratedType = struct_ZigClangElaboratedType;
805pub const ZigClangEnumConstantDecl = struct_ZigClangEnumConstantDecl;
806pub const ZigClangEnumDecl = struct_ZigClangEnumDecl;
807pub const ZigClangEnumType = struct_ZigClangEnumType;
808pub const ZigClangExpr = struct_ZigClangExpr;
809pub const ZigClangFieldDecl = struct_ZigClangFieldDecl;
810pub const ZigClangFileID = struct_ZigClangFileID;
811pub const ZigClangForStmt = struct_ZigClangForStmt;
812pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc;
813pub const ZigClangFunctionDecl = struct_ZigClangFunctionDecl;
814pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType;
815pub const ZigClangIfStmt = struct_ZigClangIfStmt;
816pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
817pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
818pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
819pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
820pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
821pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
822pub const ZigClangNone = struct_ZigClangNone;
823pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
824pub const ZigClangParenExpr = struct_ZigClangParenExpr;
825pub const ZigClangParenType = struct_ZigClangParenType;
826pub const ZigClangParmVarDecl = struct_ZigClangParmVarDecl;
827pub const ZigClangPointerType = struct_ZigClangPointerType;
828pub const ZigClangPreprocessedEntity = struct_ZigClangPreprocessedEntity;
829pub const ZigClangRecordDecl = struct_ZigClangRecordDecl;
830pub const ZigClangRecordType = struct_ZigClangRecordType;
831pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
832pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
833pub const ZigClangSourceManager = struct_ZigClangSourceManager;
834pub const ZigClangSourceRange = struct_ZigClangSourceRange;
835pub const ZigClangStmt = struct_ZigClangStmt;
836pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
837pub const ZigClangStringRef = struct_ZigClangStringRef;
838pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
839pub const ZigClangTagDecl = struct_ZigClangTagDecl;
840pub const ZigClangType = struct_ZigClangType;
841pub const ZigClangTypedefNameDecl = struct_ZigClangTypedefNameDecl;
842pub const ZigClangTypedefType = struct_ZigClangTypedefType;
843pub const ZigClangUnaryExprOrTypeTraitExpr = struct_ZigClangUnaryExprOrTypeTraitExpr;
844pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator;
845pub const ZigClangValueDecl = struct_ZigClangValueDecl;
846pub const ZigClangVarDecl = struct_ZigClangVarDecl;
847pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
848pub const ZigClangFunctionType = struct_ZigClangFunctionType;
849pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr;
850
851pub const struct_ZigClangSourceLocation = extern struct {
852 ID: c_uint,
853};
854
855pub const Stage2ErrorMsg = extern struct {
856 filename_ptr: ?[*]const u8,
857 filename_len: usize,
858 msg_ptr: [*]const u8,
859 msg_len: usize,
860 // valid until the ASTUnit is freed
861 source: ?[*]const u8,
862 // 0 based
863 line: c_uint,
864 // 0 based
865 column: c_uint,
866 // byte offset into source
867 offset: c_uint,
882};868};
883869
884pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation;870pub const struct_ZigClangQualType = extern struct {
885pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK;871 ptr: ?*c_void,
886pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;872};
887873
888pub extern fn ZigClangArrayType_getElementType(*const ZigClangArrayType) ZigClangQualType;874pub const struct_ZigClangAPValueLValueBase = extern struct {
875 Ptr: ?*c_void,
876 CallIndex: c_uint,
877 Version: c_uint,
878};
889879
890pub extern fn ZigClangDeclRefExpr_getDecl(*const ZigClangDeclRefExpr) *const ZigClangValueDecl;880pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void;
891881
892pub extern fn ZigClangParenType_getInnerType(*const ZigClangParenType) ZigClangQualType;882pub extern fn ZigClangLoadFromCommandLine(
883 args_begin: [*]?[*]const u8,
884 args_end: [*]?[*]const u8,
885 errors_ptr: *[*]Stage2ErrorMsg,
886 errors_len: *usize,
887 resources_path: [*c]const u8,
888) ?*ZigClangASTUnit;
893889
894pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType) ZigClangQualType;890pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
891pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*]const u8;
895892
896pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType;893pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt;
897894
898pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation;895pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
899pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;896pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
900pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;
src-self-hosted/dep_tokenizer.zig created+1055
...@@ -0,0 +1,1055 @@
1const std = @import("std");
2const testing = std.testing;
3
4pub const Tokenizer = struct {
5 arena: std.heap.ArenaAllocator,
6 index: usize,
7 bytes: []const u8,
8 error_text: []const u8,
9 state: State,
10
11 pub fn init(allocator: *std.mem.Allocator, bytes: []const u8) Tokenizer {
12 return Tokenizer{
13 .arena = std.heap.ArenaAllocator.init(allocator),
14 .index = 0,
15 .bytes = bytes,
16 .error_text = "",
17 .state = State{ .lhs = {} },
18 };
19 }
20
21 pub fn deinit(self: *Tokenizer) void {
22 self.arena.deinit();
23 }
24
25 pub fn next(self: *Tokenizer) Error!?Token {
26 while (self.index < self.bytes.len) {
27 const char = self.bytes[self.index];
28 while (true) {
29 switch (self.state) {
30 .lhs => switch (char) {
31 '\t', '\n', '\r', ' ' => {
32 // silently ignore whitespace
33 break; // advance
34 },
35 else => {
36 self.state = State{ .target = try std.Buffer.initSize(&self.arena.allocator, 0) };
37 },
38 },
39 .target => |*target| switch (char) {
40 '\t', '\n', '\r', ' ' => {
41 return self.errorIllegalChar(self.index, char, "invalid target");
42 },
43 '$' => {
44 self.state = State{ .target_dollar_sign = target.* };
45 break; // advance
46 },
47 '\\' => {
48 self.state = State{ .target_reverse_solidus = target.* };
49 break; // advance
50 },
51 ':' => {
52 self.state = State{ .target_colon = target.* };
53 break; // advance
54 },
55 else => {
56 try target.appendByte(char);
57 break; // advance
58 },
59 },
60 .target_reverse_solidus => |*target| switch (char) {
61 '\t', '\n', '\r' => {
62 return self.errorIllegalChar(self.index, char, "bad target escape");
63 },
64 ' ', '#', '\\' => {
65 try target.appendByte(char);
66 self.state = State{ .target = target.* };
67 break; // advance
68 },
69 '$' => {
70 try target.append(self.bytes[self.index - 1 .. self.index]);
71 self.state = State{ .target_dollar_sign = target.* };
72 break; // advance
73 },
74 else => {
75 try target.append(self.bytes[self.index - 1 .. self.index + 1]);
76 self.state = State{ .target = target.* };
77 break; // advance
78 },
79 },
80 .target_dollar_sign => |*target| switch (char) {
81 '$' => {
82 try target.appendByte(char);
83 self.state = State{ .target = target.* };
84 break; // advance
85 },
86 else => {
87 return self.errorIllegalChar(self.index, char, "expecting '$'");
88 },
89 },
90 .target_colon => |*target| switch (char) {
91 '\n', '\r' => {
92 const bytes = target.toSlice();
93 if (bytes.len != 0) {
94 self.state = State{ .lhs = {} };
95 return Token{ .id = .target, .bytes = bytes };
96 }
97 // silently ignore null target
98 self.state = State{ .lhs = {} };
99 continue;
100 },
101 '\\' => {
102 self.state = State{ .target_colon_reverse_solidus = target.* };
103 break; // advance
104 },
105 else => {
106 const bytes = target.toSlice();
107 if (bytes.len != 0) {
108 self.state = State{ .rhs = {} };
109 return Token{ .id = .target, .bytes = bytes };
110 }
111 // silently ignore null target
112 self.state = State{ .lhs = {} };
113 continue;
114 },
115 },
116 .target_colon_reverse_solidus => |*target| switch (char) {
117 '\n', '\r' => {
118 const bytes = target.toSlice();
119 if (bytes.len != 0) {
120 self.state = State{ .lhs = {} };
121 return Token{ .id = .target, .bytes = bytes };
122 }
123 // silently ignore null target
124 self.state = State{ .lhs = {} };
125 continue;
126 },
127 else => {
128 try target.append(self.bytes[self.index - 2 .. self.index + 1]);
129 self.state = State{ .target = target.* };
130 break;
131 },
132 },
133 .rhs => switch (char) {
134 '\t', ' ' => {
135 // silently ignore horizontal whitespace
136 break; // advance
137 },
138 '\n', '\r' => {
139 self.state = State{ .lhs = {} };
140 continue;
141 },
142 '\\' => {
143 self.state = State{ .rhs_continuation = {} };
144 break; // advance
145 },
146 '"' => {
147 self.state = State{ .prereq_quote = try std.Buffer.initSize(&self.arena.allocator, 0) };
148 break; // advance
149 },
150 else => {
151 self.state = State{ .prereq = try std.Buffer.initSize(&self.arena.allocator, 0) };
152 },
153 },
154 .rhs_continuation => switch (char) {
155 '\n' => {
156 self.state = State{ .rhs = {} };
157 break; // advance
158 },
159 '\r' => {
160 self.state = State{ .rhs_continuation_linefeed = {} };
161 break; // advance
162 },
163 else => {
164 return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line");
165 },
166 },
167 .rhs_continuation_linefeed => switch (char) {
168 '\n' => {
169 self.state = State{ .rhs = {} };
170 break; // advance
171 },
172 else => {
173 return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line");
174 },
175 },
176 .prereq_quote => |*prereq| switch (char) {
177 '"' => {
178 const bytes = prereq.toSlice();
179 self.index += 1;
180 self.state = State{ .rhs = {} };
181 return Token{ .id = .prereq, .bytes = bytes };
182 },
183 else => {
184 try prereq.appendByte(char);
185 break; // advance
186 },
187 },
188 .prereq => |*prereq| switch (char) {
189 '\t', ' ' => {
190 const bytes = prereq.toSlice();
191 self.state = State{ .rhs = {} };
192 return Token{ .id = .prereq, .bytes = bytes };
193 },
194 '\n', '\r' => {
195 const bytes = prereq.toSlice();
196 self.state = State{ .lhs = {} };
197 return Token{ .id = .prereq, .bytes = bytes };
198 },
199 '\\' => {
200 self.state = State{ .prereq_continuation = prereq.* };
201 break; // advance
202 },
203 else => {
204 try prereq.appendByte(char);
205 break; // advance
206 },
207 },
208 .prereq_continuation => |*prereq| switch (char) {
209 '\n' => {
210 const bytes = prereq.toSlice();
211 self.index += 1;
212 self.state = State{ .rhs = {} };
213 return Token{ .id = .prereq, .bytes = bytes };
214 },
215 '\r' => {
216 self.state = State{ .prereq_continuation_linefeed = prereq.* };
217 break; // advance
218 },
219 else => {
220 // not continuation
221 try prereq.append(self.bytes[self.index - 1 .. self.index + 1]);
222 self.state = State{ .prereq = prereq.* };
223 break; // advance
224 },
225 },
226 .prereq_continuation_linefeed => |prereq| switch (char) {
227 '\n' => {
228 const bytes = prereq.toSlice();
229 self.index += 1;
230 self.state = State{ .rhs = {} };
231 return Token{ .id = .prereq, .bytes = bytes };
232 },
233 else => {
234 return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line");
235 },
236 },
237 }
238 }
239 self.index += 1;
240 }
241
242 // eof, handle maybe incomplete token
243 if (self.index == 0) return null;
244 const idx = self.index - 1;
245 switch (self.state) {
246 .lhs,
247 .rhs,
248 .rhs_continuation,
249 .rhs_continuation_linefeed,
250 => {},
251 .target => |target| {
252 return self.errorPosition(idx, target.toSlice(), "incomplete target");
253 },
254 .target_reverse_solidus,
255 .target_dollar_sign,
256 => {
257 const index = self.index - 1;
258 return self.errorIllegalChar(idx, self.bytes[idx], "incomplete escape");
259 },
260 .target_colon => |target| {
261 const bytes = target.toSlice();
262 if (bytes.len != 0) {
263 self.index += 1;
264 self.state = State{ .rhs = {} };
265 return Token{ .id = .target, .bytes = bytes };
266 }
267 // silently ignore null target
268 self.state = State{ .lhs = {} };
269 },
270 .target_colon_reverse_solidus => |target| {
271 const bytes = target.toSlice();
272 if (bytes.len != 0) {
273 self.index += 1;
274 self.state = State{ .rhs = {} };
275 return Token{ .id = .target, .bytes = bytes };
276 }
277 // silently ignore null target
278 self.state = State{ .lhs = {} };
279 },
280 .prereq_quote => |prereq| {
281 return self.errorPosition(idx, prereq.toSlice(), "incomplete quoted prerequisite");
282 },
283 .prereq => |prereq| {
284 const bytes = prereq.toSlice();
285 self.state = State{ .lhs = {} };
286 return Token{ .id = .prereq, .bytes = bytes };
287 },
288 .prereq_continuation => |prereq| {
289 const bytes = prereq.toSlice();
290 self.state = State{ .lhs = {} };
291 return Token{ .id = .prereq, .bytes = bytes };
292 },
293 .prereq_continuation_linefeed => |prereq| {
294 const bytes = prereq.toSlice();
295 self.state = State{ .lhs = {} };
296 return Token{ .id = .prereq, .bytes = bytes };
297 },
298 }
299 return null;
300 }
301
302 fn errorf(self: *Tokenizer, comptime fmt: []const u8, args: ...) Error {
303 self.error_text = (try std.Buffer.allocPrint(&self.arena.allocator, fmt, args)).toSlice();
304 return Error.InvalidInput;
305 }
306
307 fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: ...) Error {
308 var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);
309 std.fmt.format(&buffer, anyerror, std.Buffer.append, fmt, args) catch {};
310 try buffer.append(" '");
311 var out = makeOutput(std.Buffer.append, &buffer);
312 try printCharValues(&out, bytes);
313 try buffer.append("'");
314 std.fmt.format(&buffer, anyerror, std.Buffer.append, " at position {}", position - (bytes.len - 1)) catch {};
315 self.error_text = buffer.toSlice();
316 return Error.InvalidInput;
317 }
318
319 fn errorIllegalChar(self: *Tokenizer, position: usize, char: u8, comptime fmt: []const u8, args: ...) Error {
320 var buffer = try std.Buffer.initSize(&self.arena.allocator, 0);
321 try buffer.append("illegal char ");
322 var out = makeOutput(std.Buffer.append, &buffer);
323 try printUnderstandableChar(&out, char);
324 std.fmt.format(&buffer, anyerror, std.Buffer.append, " at position {}", position) catch {};
325 if (fmt.len != 0) std.fmt.format(&buffer, anyerror, std.Buffer.append, ": " ++ fmt, args) catch {};
326 self.error_text = buffer.toSlice();
327 return Error.InvalidInput;
328 }
329
330 const Error = error{
331 OutOfMemory,
332 InvalidInput,
333 };
334
335 const State = union(enum) {
336 lhs: void,
337 target: std.Buffer,
338 target_reverse_solidus: std.Buffer,
339 target_dollar_sign: std.Buffer,
340 target_colon: std.Buffer,
341 target_colon_reverse_solidus: std.Buffer,
342 rhs: void,
343 rhs_continuation: void,
344 rhs_continuation_linefeed: void,
345 prereq_quote: std.Buffer,
346 prereq: std.Buffer,
347 prereq_continuation: std.Buffer,
348 prereq_continuation_linefeed: std.Buffer,
349 };
350
351 const Token = struct {
352 id: ID,
353 bytes: []const u8,
354
355 const ID = enum {
356 target,
357 prereq,
358 };
359 };
360};
361
362test "empty file" {
363 try depTokenizer("", "");
364}
365
366test "empty whitespace" {
367 try depTokenizer("\n", "");
368 try depTokenizer("\r", "");
369 try depTokenizer("\r\n", "");
370 try depTokenizer(" ", "");
371}
372
373test "empty colon" {
374 try depTokenizer(":", "");
375 try depTokenizer("\n:", "");
376 try depTokenizer("\r:", "");
377 try depTokenizer("\r\n:", "");
378 try depTokenizer(" :", "");
379}
380
381test "empty target" {
382 try depTokenizer("foo.o:", "target = {foo.o}");
383 try depTokenizer(
384 \\foo.o:
385 \\bar.o:
386 \\abcd.o:
387 ,
388 \\target = {foo.o}
389 \\target = {bar.o}
390 \\target = {abcd.o}
391 );
392}
393
394test "whitespace empty target" {
395 try depTokenizer("\nfoo.o:", "target = {foo.o}");
396 try depTokenizer("\rfoo.o:", "target = {foo.o}");
397 try depTokenizer("\r\nfoo.o:", "target = {foo.o}");
398 try depTokenizer(" foo.o:", "target = {foo.o}");
399}
400
401test "escape empty target" {
402 try depTokenizer("\\ foo.o:", "target = { foo.o}");
403 try depTokenizer("\\#foo.o:", "target = {#foo.o}");
404 try depTokenizer("\\\\foo.o:", "target = {\\foo.o}");
405 try depTokenizer("$$foo.o:", "target = {$foo.o}");
406}
407
408test "empty target linefeeds" {
409 try depTokenizer("\n", "");
410 try depTokenizer("\r\n", "");
411
412 const expect = "target = {foo.o}";
413 try depTokenizer(
414 \\foo.o:
415 , expect);
416 try depTokenizer(
417 \\foo.o:
418 \\
419 , expect);
420 try depTokenizer(
421 \\foo.o:
422 , expect);
423 try depTokenizer(
424 \\foo.o:
425 \\
426 , expect);
427}
428
429test "empty target linefeeds + continuations" {
430 const expect = "target = {foo.o}";
431 try depTokenizer(
432 \\foo.o:\
433 , expect);
434 try depTokenizer(
435 \\foo.o:\
436 \\
437 , expect);
438 try depTokenizer(
439 \\foo.o:\
440 , expect);
441 try depTokenizer(
442 \\foo.o:\
443 \\
444 , expect);
445}
446
447test "empty target linefeeds + hspace + continuations" {
448 const expect = "target = {foo.o}";
449 try depTokenizer(
450 \\foo.o: \
451 , expect);
452 try depTokenizer(
453 \\foo.o: \
454 \\
455 , expect);
456 try depTokenizer(
457 \\foo.o: \
458 , expect);
459 try depTokenizer(
460 \\foo.o: \
461 \\
462 , expect);
463}
464
465test "prereq" {
466 const expect =
467 \\target = {foo.o}
468 \\prereq = {foo.c}
469 ;
470 try depTokenizer("foo.o: foo.c", expect);
471 try depTokenizer(
472 \\foo.o: \
473 \\foo.c
474 , expect);
475 try depTokenizer(
476 \\foo.o: \
477 \\ foo.c
478 , expect);
479 try depTokenizer(
480 \\foo.o: \
481 \\ foo.c
482 , expect);
483}
484
485test "prereq continuation" {
486 const expect =
487 \\target = {foo.o}
488 \\prereq = {foo.h}
489 \\prereq = {bar.h}
490 ;
491 try depTokenizer(
492 \\foo.o: foo.h\
493 \\bar.h
494 , expect);
495 try depTokenizer(
496 \\foo.o: foo.h\
497 \\bar.h
498 , expect);
499}
500
501test "multiple prereqs" {
502 const expect =
503 \\target = {foo.o}
504 \\prereq = {foo.c}
505 \\prereq = {foo.h}
506 \\prereq = {bar.h}
507 ;
508 try depTokenizer("foo.o: foo.c foo.h bar.h", expect);
509 try depTokenizer(
510 \\foo.o: \
511 \\foo.c foo.h bar.h
512 , expect);
513 try depTokenizer(
514 \\foo.o: foo.c foo.h bar.h\
515 , expect);
516 try depTokenizer(
517 \\foo.o: foo.c foo.h bar.h\
518 \\
519 , expect);
520 try depTokenizer(
521 \\foo.o: \
522 \\foo.c \
523 \\ foo.h\
524 \\bar.h
525 \\
526 , expect);
527 try depTokenizer(
528 \\foo.o: \
529 \\foo.c \
530 \\ foo.h\
531 \\bar.h\
532 \\
533 , expect);
534 try depTokenizer(
535 \\foo.o: \
536 \\foo.c \
537 \\ foo.h\
538 \\bar.h\
539 , expect);
540}
541
542test "multiple targets and prereqs" {
543 try depTokenizer(
544 \\foo.o: foo.c
545 \\bar.o: bar.c a.h b.h c.h
546 \\abc.o: abc.c \
547 \\ one.h two.h \
548 \\ three.h four.h
549 ,
550 \\target = {foo.o}
551 \\prereq = {foo.c}
552 \\target = {bar.o}
553 \\prereq = {bar.c}
554 \\prereq = {a.h}
555 \\prereq = {b.h}
556 \\prereq = {c.h}
557 \\target = {abc.o}
558 \\prereq = {abc.c}
559 \\prereq = {one.h}
560 \\prereq = {two.h}
561 \\prereq = {three.h}
562 \\prereq = {four.h}
563 );
564 try depTokenizer(
565 \\ascii.o: ascii.c
566 \\base64.o: base64.c stdio.h
567 \\elf.o: elf.c a.h b.h c.h
568 \\macho.o: \
569 \\ macho.c\
570 \\ a.h b.h c.h
571 ,
572 \\target = {ascii.o}
573 \\prereq = {ascii.c}
574 \\target = {base64.o}
575 \\prereq = {base64.c}
576 \\prereq = {stdio.h}
577 \\target = {elf.o}
578 \\prereq = {elf.c}
579 \\prereq = {a.h}
580 \\prereq = {b.h}
581 \\prereq = {c.h}
582 \\target = {macho.o}
583 \\prereq = {macho.c}
584 \\prereq = {a.h}
585 \\prereq = {b.h}
586 \\prereq = {c.h}
587 );
588 try depTokenizer(
589 \\a$$scii.o: ascii.c
590 \\\\base64.o: "\base64.c" "s t#dio.h"
591 \\e\\lf.o: "e\lf.c" "a.h$$" "$$b.h c.h$$"
592 \\macho.o: \
593 \\ "macho!.c" \
594 \\ a.h b.h c.h
595 ,
596 \\target = {a$scii.o}
597 \\prereq = {ascii.c}
598 \\target = {\base64.o}
599 \\prereq = {\base64.c}
600 \\prereq = {s t#dio.h}
601 \\target = {e\lf.o}
602 \\prereq = {e\lf.c}
603 \\prereq = {a.h$$}
604 \\prereq = {$$b.h c.h$$}
605 \\target = {macho.o}
606 \\prereq = {macho!.c}
607 \\prereq = {a.h}
608 \\prereq = {b.h}
609 \\prereq = {c.h}
610 );
611}
612
613test "windows quoted prereqs" {
614 try depTokenizer(
615 \\c:\foo.o: "C:\Program Files (x86)\Microsoft Visual Studio\foo.c"
616 \\c:\foo2.o: "C:\Program Files (x86)\Microsoft Visual Studio\foo2.c" \
617 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo1.h" \
618 \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo2.h"
619 ,
620 \\target = {c:\foo.o}
621 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo.c}
622 \\target = {c:\foo2.o}
623 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.c}
624 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo1.h}
625 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.h}
626 );
627}
628
629test "windows mixed prereqs" {
630 try depTokenizer(
631 \\cimport.o: \
632 \\ C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h \
633 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h" \
634 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h" \
635 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h" \
636 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h" \
637 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h" \
638 \\ C:\msys64\opt\zig\lib\zig\include\vadefs.h \
639 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h" \
640 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h" \
641 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h" \
642 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h" \
643 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h" \
644 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h" \
645 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h" \
646 \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h" \
647 \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h"
648 ,
649 \\target = {cimport.o}
650 \\prereq = {C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h}
651 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h}
652 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h}
653 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h}
654 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h}
655 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h}
656 \\prereq = {C:\msys64\opt\zig\lib\zig\include\vadefs.h}
657 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h}
658 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h}
659 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h}
660 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h}
661 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h}
662 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h}
663 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h}
664 \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h}
665 \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h}
666 );
667}
668
669test "funky targets" {
670 try depTokenizer(
671 \\C:\Users\anon\foo.o:
672 \\C:\Users\anon\foo\ .o:
673 \\C:\Users\anon\foo\#.o:
674 \\C:\Users\anon\foo$$.o:
675 \\C:\Users\anon\\\ foo.o:
676 \\C:\Users\anon\\#foo.o:
677 \\C:\Users\anon\$$foo.o:
678 \\C:\Users\anon\\\ \ \ \ \ foo.o:
679 ,
680 \\target = {C:\Users\anon\foo.o}
681 \\target = {C:\Users\anon\foo .o}
682 \\target = {C:\Users\anon\foo#.o}
683 \\target = {C:\Users\anon\foo$.o}
684 \\target = {C:\Users\anon\ foo.o}
685 \\target = {C:\Users\anon\#foo.o}
686 \\target = {C:\Users\anon\$foo.o}
687 \\target = {C:\Users\anon\ foo.o}
688 );
689}
690
691test "error incomplete escape - reverse_solidus" {
692 try depTokenizer("\\",
693 \\ERROR: illegal char '\' at position 0: incomplete escape
694 );
695 try depTokenizer("\t\\",
696 \\ERROR: illegal char '\' at position 1: incomplete escape
697 );
698 try depTokenizer("\n\\",
699 \\ERROR: illegal char '\' at position 1: incomplete escape
700 );
701 try depTokenizer("\r\\",
702 \\ERROR: illegal char '\' at position 1: incomplete escape
703 );
704 try depTokenizer("\r\n\\",
705 \\ERROR: illegal char '\' at position 2: incomplete escape
706 );
707 try depTokenizer(" \\",
708 \\ERROR: illegal char '\' at position 1: incomplete escape
709 );
710}
711
712test "error incomplete escape - dollar_sign" {
713 try depTokenizer("$",
714 \\ERROR: illegal char '$' at position 0: incomplete escape
715 );
716 try depTokenizer("\t$",
717 \\ERROR: illegal char '$' at position 1: incomplete escape
718 );
719 try depTokenizer("\n$",
720 \\ERROR: illegal char '$' at position 1: incomplete escape
721 );
722 try depTokenizer("\r$",
723 \\ERROR: illegal char '$' at position 1: incomplete escape
724 );
725 try depTokenizer("\r\n$",
726 \\ERROR: illegal char '$' at position 2: incomplete escape
727 );
728 try depTokenizer(" $",
729 \\ERROR: illegal char '$' at position 1: incomplete escape
730 );
731}
732
733test "error incomplete target" {
734 try depTokenizer("foo.o",
735 \\ERROR: incomplete target 'foo.o' at position 0
736 );
737 try depTokenizer("\tfoo.o",
738 \\ERROR: incomplete target 'foo.o' at position 1
739 );
740 try depTokenizer("\nfoo.o",
741 \\ERROR: incomplete target 'foo.o' at position 1
742 );
743 try depTokenizer("\rfoo.o",
744 \\ERROR: incomplete target 'foo.o' at position 1
745 );
746 try depTokenizer("\r\nfoo.o",
747 \\ERROR: incomplete target 'foo.o' at position 2
748 );
749 try depTokenizer(" foo.o",
750 \\ERROR: incomplete target 'foo.o' at position 1
751 );
752
753 try depTokenizer("\\ foo.o",
754 \\ERROR: incomplete target ' foo.o' at position 1
755 );
756 try depTokenizer("\\#foo.o",
757 \\ERROR: incomplete target '#foo.o' at position 1
758 );
759 try depTokenizer("\\\\foo.o",
760 \\ERROR: incomplete target '\foo.o' at position 1
761 );
762 try depTokenizer("$$foo.o",
763 \\ERROR: incomplete target '$foo.o' at position 1
764 );
765}
766
767test "error illegal char at position - bad target escape" {
768 try depTokenizer("\\\t",
769 \\ERROR: illegal char \x09 at position 1: bad target escape
770 );
771 try depTokenizer("\\\n",
772 \\ERROR: illegal char \x0A at position 1: bad target escape
773 );
774 try depTokenizer("\\\r",
775 \\ERROR: illegal char \x0D at position 1: bad target escape
776 );
777 try depTokenizer("\\\r\n",
778 \\ERROR: illegal char \x0D at position 1: bad target escape
779 );
780}
781
782test "error illegal char at position - execting dollar_sign" {
783 try depTokenizer("$\t",
784 \\ERROR: illegal char \x09 at position 1: expecting '$'
785 );
786 try depTokenizer("$\n",
787 \\ERROR: illegal char \x0A at position 1: expecting '$'
788 );
789 try depTokenizer("$\r",
790 \\ERROR: illegal char \x0D at position 1: expecting '$'
791 );
792 try depTokenizer("$\r\n",
793 \\ERROR: illegal char \x0D at position 1: expecting '$'
794 );
795}
796
797test "error illegal char at position - invalid target" {
798 try depTokenizer("foo\t.o",
799 \\ERROR: illegal char \x09 at position 3: invalid target
800 );
801 try depTokenizer("foo\n.o",
802 \\ERROR: illegal char \x0A at position 3: invalid target
803 );
804 try depTokenizer("foo\r.o",
805 \\ERROR: illegal char \x0D at position 3: invalid target
806 );
807 try depTokenizer("foo\r\n.o",
808 \\ERROR: illegal char \x0D at position 3: invalid target
809 );
810}
811
812test "error target - continuation expecting end-of-line" {
813 try depTokenizer("foo.o: \\\t",
814 \\target = {foo.o}
815 \\ERROR: illegal char \x09 at position 8: continuation expecting end-of-line
816 );
817 try depTokenizer("foo.o: \\ ",
818 \\target = {foo.o}
819 \\ERROR: illegal char \x20 at position 8: continuation expecting end-of-line
820 );
821 try depTokenizer("foo.o: \\x",
822 \\target = {foo.o}
823 \\ERROR: illegal char 'x' at position 8: continuation expecting end-of-line
824 );
825 try depTokenizer("foo.o: \\\x0dx",
826 \\target = {foo.o}
827 \\ERROR: illegal char 'x' at position 9: continuation expecting end-of-line
828 );
829}
830
831test "error prereq - continuation expecting end-of-line" {
832 try depTokenizer("foo.o: foo.h\\\x0dx",
833 \\target = {foo.o}
834 \\ERROR: illegal char 'x' at position 14: continuation expecting end-of-line
835 );
836}
837
838// - tokenize input, emit textual representation, and compare to expect
839fn depTokenizer(input: []const u8, expect: []const u8) !void {
840 var direct_allocator = std.heap.DirectAllocator.init();
841 var arena_allocator = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
842 const arena = &arena_allocator.allocator;
843 defer arena_allocator.deinit();
844
845 var it = Tokenizer.init(&direct_allocator.allocator, input);
846 var buffer = try std.Buffer.initSize(arena, 0);
847 var i: usize = 0;
848 while (true) {
849 const r = it.next() catch |err| {
850 switch (err) {
851 Tokenizer.Error.InvalidInput => {
852 if (i != 0) try buffer.append("\n");
853 try buffer.append("ERROR: ");
854 try buffer.append(it.error_text);
855 },
856 else => return err,
857 }
858 break;
859 };
860 const token = r orelse break;
861 if (i != 0) try buffer.append("\n");
862 try buffer.append(@tagName(token.id));
863 try buffer.append(" = {");
864 for (token.bytes) |b| {
865 try buffer.appendByte(printable_char_tab[b]);
866 }
867 try buffer.append("}");
868 i += 1;
869 }
870 const got: []const u8 = buffer.toSlice();
871
872 if (std.mem.eql(u8, expect, got)) {
873 testing.expect(true);
874 return;
875 }
876
877 var out = makeOutput(std.fs.File.write, try std.io.getStdErr());
878
879 try out.write("\n");
880 try printSection(&out, "<<<< input", input);
881 try printSection(&out, "==== expect", expect);
882 try printSection(&out, ">>>> got", got);
883 try printRuler(&out);
884
885 testing.expect(false);
886}
887
888fn printSection(out: var, label: []const u8, bytes: []const u8) !void {
889 try printLabel(out, label, bytes);
890 try hexDump(out, bytes);
891 try printRuler(out);
892 try out.write(bytes);
893 try out.write("\n");
894}
895
896fn printLabel(out: var, label: []const u8, bytes: []const u8) !void {
897 var buf: [80]u8 = undefined;
898 var text = try std.fmt.bufPrint(buf[0..], "{} {} bytes ", label, bytes.len);
899 try out.write(text);
900 var i: usize = text.len;
901 const end = 79;
902 while (i < 79) : (i += 1) {
903 try out.write([]const u8{label[0]});
904 }
905 try out.write("\n");
906}
907
908fn printRuler(out: var) !void {
909 var i: usize = 0;
910 const end = 79;
911 while (i < 79) : (i += 1) {
912 try out.write("-");
913 }
914 try out.write("\n");
915}
916
917fn hexDump(out: var, bytes: []const u8) !void {
918 const n16 = bytes.len >> 4;
919 var line: usize = 0;
920 var offset: usize = 0;
921 while (line < n16) : (line += 1) {
922 try hexDump16(out, offset, bytes[offset .. offset + 16]);
923 offset += 16;
924 }
925
926 const n = bytes.len & 0x0f;
927 if (n > 0) {
928 try printDecValue(out, offset, 8);
929 try out.write(":");
930 try out.write(" ");
931 var end1 = std.math.min(offset + n, offset + 8);
932 for (bytes[offset..end1]) |b| {
933 try out.write(" ");
934 try printHexValue(out, b, 2);
935 }
936 var end2 = offset + n;
937 if (end2 > end1) {
938 try out.write(" ");
939 for (bytes[end1..end2]) |b| {
940 try out.write(" ");
941 try printHexValue(out, b, 2);
942 }
943 }
944 const short = 16 - n;
945 var i: usize = 0;
946 while (i < short) : (i += 1) {
947 try out.write(" ");
948 }
949 if (end2 > end1) {
950 try out.write(" |");
951 } else {
952 try out.write(" |");
953 }
954 try printCharValues(out, bytes[offset..end2]);
955 try out.write("|\n");
956 offset += n;
957 }
958
959 try printDecValue(out, offset, 8);
960 try out.write(":");
961 try out.write("\n");
962}
963
964fn hexDump16(out: var, offset: usize, bytes: []const u8) !void {
965 try printDecValue(out, offset, 8);
966 try out.write(":");
967 try out.write(" ");
968 for (bytes[0..8]) |b| {
969 try out.write(" ");
970 try printHexValue(out, b, 2);
971 }
972 try out.write(" ");
973 for (bytes[8..16]) |b| {
974 try out.write(" ");
975 try printHexValue(out, b, 2);
976 }
977 try out.write(" |");
978 try printCharValues(out, bytes);
979 try out.write("|\n");
980}
981
982fn printDecValue(out: var, value: u64, width: u8) !void {
983 var buffer: [20]u8 = undefined;
984 const len = std.fmt.formatIntBuf(buffer[0..], value, 10, false, width);
985 try out.write(buffer[0..len]);
986}
987
988fn printHexValue(out: var, value: u64, width: u8) !void {
989 var buffer: [16]u8 = undefined;
990 const len = std.fmt.formatIntBuf(buffer[0..], value, 16, false, width);
991 try out.write(buffer[0..len]);
992}
993
994fn printCharValues(out: var, bytes: []const u8) !void {
995 for (bytes) |b| {
996 try out.write([]const u8{printable_char_tab[b]});
997 }
998}
999
1000fn printUnderstandableChar(out: var, char: u8) !void {
1001 if (!std.ascii.isPrint(char) or char == ' ') {
1002 std.fmt.format(out.context, anyerror, out.output, "\\x{X2}", char) catch {};
1003 } else {
1004 try out.write("'");
1005 try out.write([]const u8{printable_char_tab[char]});
1006 try out.write("'");
1007 }
1008}
1009
1010// zig fmt: off
1011const printable_char_tab: []const u8 =
1012 "................................ !\"#$%&'()*+,-./0123456789:;<=>?" ++
1013 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~." ++
1014 "................................................................" ++
1015 "................................................................";
1016// zig fmt: on
1017comptime {
1018 std.debug.assert(printable_char_tab.len == 256);
1019}
1020
1021// Make an output var that wraps a context and output function.
1022// output: must be a function that takes a `self` idiom parameter
1023// and a bytes parameter
1024// context: must be that self
1025fn makeOutput(output: var, context: var) Output(@typeOf(output)) {
1026 return Output(@typeOf(output)){
1027 .output = output,
1028 .context = context,
1029 };
1030}
1031
1032fn Output(comptime T: type) type {
1033 const args = switch (@typeInfo(T)) {
1034 .Fn => |f| f.args,
1035 else => @compileError("output parameter is not a function"),
1036 };
1037 if (args.len != 2) {
1038 @compileError("output function must take 2 arguments");
1039 }
1040 const at0 = args[0].arg_type orelse @compileError("output arg[0] does not have a type");
1041 const at1 = args[1].arg_type orelse @compileError("output arg[1] does not have a type");
1042 const arg1p = switch (@typeInfo(at1)) {
1043 .Pointer => |p| p,
1044 else => @compileError("output arg[1] is not a slice"),
1045 };
1046 if (arg1p.child != u8) @compileError("output arg[1] is not a u8 slice");
1047 return struct {
1048 output: T,
1049 context: at0,
1050
1051 fn write(self: *@This(), bytes: []const u8) !void {
1052 try self.output(self.context, bytes);
1053 }
1054 };
1055}
src-self-hosted/link.zig+1-1
...@@ -670,7 +670,7 @@ const DarwinPlatform = struct {...@@ -670,7 +670,7 @@ const DarwinPlatform = struct {
670 Compilation.DarwinVersionMin.None => blk: {670 Compilation.DarwinVersionMin.None => blk: {
671 assert(comp.target.getOs() == .macosx);671 assert(comp.target.getOs() == .macosx);
672 result.kind = Kind.MacOS;672 result.kind = Kind.MacOS;
673 break :blk "10.10";673 break :blk "10.14";
674 },674 },
675 };675 };
676676
src-self-hosted/stage1.zig+62
...@@ -15,11 +15,16 @@ const self_hosted_main = @import("main.zig");...@@ -15,11 +15,16 @@ const self_hosted_main = @import("main.zig");
15const Args = arg.Args;15const Args = arg.Args;
16const Flag = arg.Flag;16const Flag = arg.Flag;
17const errmsg = @import("errmsg.zig");17const errmsg = @import("errmsg.zig");
18const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
1819
19var stderr_file: fs.File = undefined;20var stderr_file: fs.File = undefined;
20var stderr: *io.OutStream(fs.File.WriteError) = undefined;21var stderr: *io.OutStream(fs.File.WriteError) = undefined;
21var stdout: *io.OutStream(fs.File.WriteError) = undefined;22var stdout: *io.OutStream(fs.File.WriteError) = undefined;
2223
24comptime {
25 _ = @import("dep_tokenizer.zig");
26}
27
23// ABI warning28// ABI warning
24export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {29export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
25 const info_zen = @import("main.zig").info_zen;30 const info_zen = @import("main.zig").info_zen;
...@@ -393,3 +398,60 @@ fn printErrMsgToFile(...@@ -393,3 +398,60 @@ fn printErrMsgToFile(
393 try stream.writeByteNTimes('~', last_token.end - first_token.start);398 try stream.writeByteNTimes('~', last_token.end - first_token.start);
394 try stream.write("\n");399 try stream.write("\n");
395}400}
401
402export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
403 const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
404 t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
405 return stage2_DepTokenizer{
406 .handle = t,
407 };
408}
409
410export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
411 self.handle.deinit();
412}
413
414export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
415 const otoken = self.handle.next() catch {
416 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
417 return stage2_DepNextResult{
418 .type_id = .error_,
419 .textz = textz.toSlice().ptr,
420 };
421 };
422 const token = otoken orelse {
423 return stage2_DepNextResult{
424 .type_id = .null_,
425 .textz = undefined,
426 };
427 };
428 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
429 return stage2_DepNextResult{
430 .type_id = switch (token.id) {
431 .target => stage2_DepNextResult.TypeId.target,
432 .prereq => stage2_DepNextResult.TypeId.prereq,
433 },
434 .textz = textz.toSlice().ptr,
435 };
436}
437
438export const stage2_DepTokenizer = extern struct {
439 handle: *DepTokenizer,
440};
441
442export const stage2_DepNextResult = extern struct {
443 type_id: TypeId,
444
445 // when type_id == error --> error text
446 // when type_id == null --> undefined
447 // when type_id == target --> target pathname
448 // when type_id == prereq --> prereq pathname
449 textz: [*]const u8,
450
451 export const TypeId = extern enum {
452 error_,
453 null_,
454 target,
455 prereq,
456 };
457};
src-self-hosted/translate_c.zig+1-1
...@@ -6,7 +6,7 @@ const builtin = @import("builtin");...@@ -6,7 +6,7 @@ const builtin = @import("builtin");
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const ast = std.zig.ast;7const ast = std.zig.ast;
8const Token = std.zig.Token;8const Token = std.zig.Token;
9use @import("clang.zig");9usingnamespace @import("clang.zig");
1010
11pub const Mode = enum {11pub const Mode = enum {
12 import,12 import,
src/all_types.hpp+21-6
...@@ -1069,6 +1069,7 @@ struct TypeStructField {...@@ -1069,6 +1069,7 @@ struct TypeStructField {
1069 size_t gen_index;1069 size_t gen_index;
1070 size_t offset; // byte offset from beginning of struct1070 size_t offset; // byte offset from beginning of struct
1071 AstNode *decl_node;1071 AstNode *decl_node;
1072 ConstExprValue *init_val; // null and then memoized
1072 uint32_t bit_offset_in_host; // offset from the memory at gen_index1073 uint32_t bit_offset_in_host; // offset from the memory at gen_index
1073 uint32_t host_int_bytes; // size of host integer1074 uint32_t host_int_bytes; // size of host integer
1074};1075};
...@@ -1633,6 +1634,12 @@ enum WantPIC {...@@ -1633,6 +1634,12 @@ enum WantPIC {
1633 WantPICEnabled,1634 WantPICEnabled,
1634};1635};
16351636
1637enum WantStackCheck {
1638 WantStackCheckAuto,
1639 WantStackCheckDisabled,
1640 WantStackCheckEnabled,
1641};
1642
1636struct CFile {1643struct CFile {
1637 ZigList<const char *> args;1644 ZigList<const char *> args;
1638 const char *source_path;1645 const char *source_path;
...@@ -1790,6 +1797,8 @@ struct CodeGen {...@@ -1790,6 +1797,8 @@ struct CodeGen {
1790 TldFn *panic_tld_fn;1797 TldFn *panic_tld_fn;
1791 AstNode *root_export_decl;1798 AstNode *root_export_decl;
17921799
1800 WantPIC want_pic;
1801 WantStackCheck want_stack_check;
1793 CacheHash cache_hash;1802 CacheHash cache_hash;
1794 ErrColor err_color;1803 ErrColor err_color;
1795 uint32_t next_unresolved_index;1804 uint32_t next_unresolved_index;
...@@ -1807,8 +1816,6 @@ struct CodeGen {...@@ -1807,8 +1816,6 @@ struct CodeGen {
1807 bool have_dllmain_crt_startup;1816 bool have_dllmain_crt_startup;
1808 bool have_pub_panic;1817 bool have_pub_panic;
1809 bool have_err_ret_tracing;1818 bool have_err_ret_tracing;
1810 bool have_pic;
1811 bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic
1812 bool c_want_stdint;1819 bool c_want_stdint;
1813 bool c_want_stdbool;1820 bool c_want_stdbool;
1814 bool verbose_tokenize;1821 bool verbose_tokenize;
...@@ -1824,6 +1831,7 @@ struct CodeGen {...@@ -1824,6 +1831,7 @@ struct CodeGen {
1824 bool enable_time_report;1831 bool enable_time_report;
1825 bool system_linker_hack;1832 bool system_linker_hack;
1826 bool reported_bad_link_libc_error;1833 bool reported_bad_link_libc_error;
1834 bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
18271835
1828 //////////////////////////// Participates in Input Parameter Cache Hash1836 //////////////////////////// Participates in Input Parameter Cache Hash
1829 /////// Note: there is a separate cache hash for builtin.zig, when adding fields,1837 /////// Note: there is a separate cache hash for builtin.zig, when adding fields,
...@@ -1850,10 +1858,8 @@ struct CodeGen {...@@ -1850,10 +1858,8 @@ struct CodeGen {
1850 BuildMode build_mode;1858 BuildMode build_mode;
1851 OutType out_type;1859 OutType out_type;
1852 const ZigTarget *zig_target;1860 const ZigTarget *zig_target;
1853 TargetSubsystem subsystem;1861 TargetSubsystem subsystem; // careful using this directly; see detect_subsystem
1854 ValgrindSupport valgrind_support;1862 ValgrindSupport valgrind_support;
1855 WantPIC want_pic;
1856 bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
1857 bool strip_debug_symbols;1863 bool strip_debug_symbols;
1858 bool is_test_build;1864 bool is_test_build;
1859 bool is_single_threaded;1865 bool is_single_threaded;
...@@ -1863,7 +1869,9 @@ struct CodeGen {...@@ -1863,7 +1869,9 @@ struct CodeGen {
1863 bool is_dummy_so;1869 bool is_dummy_so;
1864 bool disable_gen_h;1870 bool disable_gen_h;
1865 bool bundle_compiler_rt;1871 bool bundle_compiler_rt;
1866 bool disable_stack_probing;1872 bool have_pic;
1873 bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic
1874 bool have_stack_probing;
18671875
1868 Buf *mmacosx_version_min;1876 Buf *mmacosx_version_min;
1869 Buf *mios_version_min;1877 Buf *mios_version_min;
...@@ -2299,6 +2307,7 @@ enum IrInstructionId {...@@ -2299,6 +2307,7 @@ enum IrInstructionId {
2299 IrInstructionIdAssertZero,2307 IrInstructionIdAssertZero,
2300 IrInstructionIdAssertNonNull,2308 IrInstructionIdAssertNonNull,
2301 IrInstructionIdHasDecl,2309 IrInstructionIdHasDecl,
2310 IrInstructionIdUndeclaredIdent,
2302};2311};
23032312
2304struct IrInstruction {2313struct IrInstruction {
...@@ -3512,6 +3521,12 @@ struct IrInstructionHasDecl {...@@ -3512,6 +3521,12 @@ struct IrInstructionHasDecl {
3512 IrInstruction *name;3521 IrInstruction *name;
3513};3522};
35143523
3524struct IrInstructionUndeclaredIdent {
3525 IrInstruction base;
3526
3527 Buf *name;
3528};
3529
3515static const size_t slice_ptr_index = 0;3530static const size_t slice_ptr_index = 0;
3516static const size_t slice_len_index = 1;3531static const size_t slice_len_index = 1;
35173532
src/analyze.cpp+81-56
...@@ -965,9 +965,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind...@@ -965,9 +965,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
965 return entry;965 return entry;
966}966}
967967
968static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,968ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {
969 Buf *type_name)
970{
971 size_t backward_branch_count = 0;969 size_t backward_branch_count = 0;
972 size_t backward_branch_quota = default_backward_branch_quota;970 size_t backward_branch_quota = default_backward_branch_quota;
973 return ir_eval_const_value(g, scope, node, type_entry,971 return ir_eval_const_value(g, scope, node, type_entry,
...@@ -981,6 +979,17 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {...@@ -981,6 +979,17 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
981 return g->builtin_types.entry_invalid;979 return g->builtin_types.entry_invalid;
982980
983 assert(result->special != ConstValSpecialRuntime);981 assert(result->special != ConstValSpecialRuntime);
982 // Reject undefined as valid `type` type even though the specification
983 // allows it to be casted to anything.
984 // See also ir_resolve_type()
985 if (result->special == ConstValSpecialUndef) {
986 add_node_error(g, node,
987 buf_sprintf("expected type 'type', found '%s'",
988 buf_ptr(&g->builtin_types.entry_undef->name)));
989 return g->builtin_types.entry_invalid;
990 }
991
992 assert(result->data.x_type != nullptr);
984 return result->data.x_type;993 return result->data.x_type;
985}994}
986995
...@@ -2178,10 +2187,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2178,10 +2187,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2178 type_struct_field->src_index = i;2187 type_struct_field->src_index = i;
2179 type_struct_field->gen_index = SIZE_MAX;2188 type_struct_field->gen_index = SIZE_MAX;
21802189
2181 if (field_node->data.struct_field.value != nullptr) {
2182 add_node_error(g, field_node->data.struct_field.value,
2183 buf_sprintf("enums, not structs, support field assignment"));
2184 }
2185 if (field_type->id == ZigTypeIdOpaque) {2190 if (field_type->id == ZigTypeIdOpaque) {
2186 add_node_error(g, field_node->data.struct_field.type,2191 add_node_error(g, field_node->data.struct_field.type,
2187 buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));2192 buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));
...@@ -2711,12 +2716,10 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi...@@ -2711,12 +2716,10 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi
2711 if (ccc) {2716 if (ccc) {
2712 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {2717 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
2713 g->have_c_main = true;2718 g->have_c_main = true;
2714 g->subsystem = TargetSubsystemConsole;
2715 } else if (buf_eql_str(symbol_name, "WinMain") &&2719 } else if (buf_eql_str(symbol_name, "WinMain") &&
2716 g->zig_target->os == OsWindows)2720 g->zig_target->os == OsWindows)
2717 {2721 {
2718 g->have_winmain = true;2722 g->have_winmain = true;
2719 g->subsystem = TargetSubsystemWindows;
2720 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&2723 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
2721 g->zig_target->os == OsWindows)2724 g->zig_target->os == OsWindows)
2722 {2725 {
...@@ -3442,11 +3445,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {...@@ -3442,11 +3445,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {
3442}3445}
34433446
34443447
3445static bool is_container(ZigType *type_entry) {3448bool is_container(ZigType *type_entry) {
3446 switch (type_entry->id) {3449 switch (type_entry->id) {
3447 case ZigTypeIdInvalid:3450 case ZigTypeIdInvalid:
3448 zig_unreachable();3451 zig_unreachable();
3449 case ZigTypeIdStruct:3452 case ZigTypeIdStruct:
3453 return !type_entry->data.structure.is_slice;
3450 case ZigTypeIdEnum:3454 case ZigTypeIdEnum:
3451 case ZigTypeIdUnion:3455 case ZigTypeIdUnion:
3452 return true;3456 return true;
...@@ -3487,9 +3491,9 @@ bool is_array_ref(ZigType *type_entry) {...@@ -3487,9 +3491,9 @@ bool is_array_ref(ZigType *type_entry) {
3487 return array->id == ZigTypeIdArray;3491 return array->id == ZigTypeIdArray;
3488}3492}
34893493
3490bool is_container_ref(ZigType *type_entry) {3494bool is_container_ref(ZigType *parent_ty) {
3491 return is_ref(type_entry) ?3495 ZigType *ty = is_ref(parent_ty) ? parent_ty->data.pointer.child_type : parent_ty;
3492 is_container(type_entry->data.pointer.child_type) : is_container(type_entry);3496 return is_slice(ty) || is_container(ty);
3493}3497}
34943498
3495ZigType *container_ref_type(ZigType *type_entry) {3499ZigType *container_ref_type(ZigType *type_entry) {
...@@ -3754,49 +3758,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {...@@ -3754,49 +3758,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
3754 analyze_fn_ir(g, fn_table_entry, return_type_node);3758 analyze_fn_ir(g, fn_table_entry, return_type_node);
3755}3759}
37563760
3757static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {3761static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) {
3758 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {3762 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
3759 preview_use_decl(g, src_use_node, decls_scope);3763 preview_use_decl(g, src_use_node, decls_scope);
3760 }3764 }
37613765
3762 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;3766 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3763 if (type_is_invalid(use_target_value->type)) {3767 if (type_is_invalid(use_expr->type)) {
3764 decls_scope->any_imports_failed = true;3768 decls_scope->any_imports_failed = true;
3765 return;3769 return;
3766 }3770 }
37673771
3768 dst_use_node->data.use.resolution = TldResolutionOk;3772 dst_use_node->data.use.resolution = TldResolutionOk;
37693773
3770 assert(use_target_value->special != ConstValSpecialRuntime);3774 assert(use_expr->special != ConstValSpecialRuntime);
37713775
3772 ZigType *target_import = use_target_value->data.x_type;3776 // The source struct for the imported symbols
3773 assert(target_import);3777 ZigType *src_ty = use_expr->data.x_type;
3778 assert(src_ty);
37743779
3775 if (target_import->id != ZigTypeIdStruct) {3780 if (!is_container(src_ty)) {
3776 add_node_error(g, dst_use_node,3781 add_node_error(g, dst_use_node,
3777 buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name)));3782 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name)));
3778 decls_scope->any_imports_failed = true;3783 decls_scope->any_imports_failed = true;
3779 return;3784 return;
3780 }3785 }
37813786
3782 if (get_container_scope(target_import)->any_imports_failed) {3787 // The source scope for the imported symbols
3788 ScopeDecls *src_scope = get_container_scope(src_ty);
3789 // The top-level container where the symbols are defined, it's used in the
3790 // loop below in order to exclude the ones coming from an import statement
3791 ZigType *src_import = get_scope_import(&src_scope->base);
3792 assert(src_import != nullptr);
3793
3794 if (src_scope->any_imports_failed) {
3783 decls_scope->any_imports_failed = true;3795 decls_scope->any_imports_failed = true;
3784 }3796 }
37853797
3786 auto it = get_container_scope(target_import)->decl_table.entry_iterator();3798 auto it = src_scope->decl_table.entry_iterator();
3787 for (;;) {3799 for (;;) {
3788 auto *entry = it.next();3800 auto *entry = it.next();
3789 if (!entry)3801 if (!entry)
3790 break;3802 break;
37913803
3804 Buf *target_tld_name = entry->key;
3792 Tld *target_tld = entry->value;3805 Tld *target_tld = entry->value;
3793 if (target_tld->import != target_import ||3806
3794 target_tld->visib_mod == VisibModPrivate)3807 if (target_tld->visib_mod == VisibModPrivate) {
3795 {
3796 continue;3808 continue;
3797 }3809 }
37983810
3799 Buf *target_tld_name = entry->key;3811 if (target_tld->import != src_import) {
3812 continue;
3813 }
38003814
3801 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);3815 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
3802 if (existing_entry) {3816 if (existing_entry) {
...@@ -3811,10 +3825,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -3811,10 +3825,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
3811 }3825 }
3812 }3826 }
38133827
3814 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {3828 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3815 AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);3829 AstNode *use_decl_node = src_scope->use_decls.at(i);
3816 if (use_decl_node->data.use.visib_mod != VisibModPrivate)3830 if (use_decl_node->data.use.visib_mod != VisibModPrivate)
3817 add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope);3831 add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope);
3818 }3832 }
3819}3833}
38203834
...@@ -3826,7 +3840,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {...@@ -3826,7 +3840,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
3826 {3840 {
3827 return;3841 return;
3828 }3842 }
3829 add_symbols_from_import(g, node, node, decls_scope);3843 add_symbols_from_container(g, node, node, decls_scope);
3830}3844}
38313845
3832void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {3846void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
...@@ -3892,10 +3906,17 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -3892,10 +3906,17 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
3892 buf_init_from_buf(&namespace_name, &package->pkg_path);3906 buf_init_from_buf(&namespace_name, &package->pkg_path);
3893 if (source_kind == SourceKindNonRoot) {3907 if (source_kind == SourceKindNonRoot) {
3894 assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir));3908 assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir));
38953909 if (buf_len(&namespace_name) != 0) {
3896 if (buf_len(&namespace_name) != 0) buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);3910 buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);
3897 buf_append_mem(&namespace_name, buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,3911 }
3898 buf_len(&noextname) - (buf_len(&resolved_root_src_dir) + 1));3912 // The namespace components are obtained from the relative path to the
3913 // source directory
3914 if (buf_len(&noextname) > buf_len(&resolved_root_src_dir)) {
3915 // Skip the trailing separator
3916 buf_append_mem(&namespace_name,
3917 buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,
3918 buf_len(&noextname) - buf_len(&resolved_root_src_dir) - 1);
3919 }
3899 buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);3920 buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);
3900 }3921 }
3901 Buf *bare_name = buf_alloc();3922 Buf *bare_name = buf_alloc();
...@@ -3937,7 +3958,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu...@@ -3937,7 +3958,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
3937 if (is_pub) {3958 if (is_pub) {
3938 if (buf_eql_str(proto_name, "main")) {3959 if (buf_eql_str(proto_name, "main")) {
3939 g->have_pub_main = true;3960 g->have_pub_main = true;
3940 g->subsystem = TargetSubsystemConsole;
3941 } else if (buf_eql_str(proto_name, "panic")) {3961 } else if (buf_eql_str(proto_name, "panic")) {
3942 g->have_pub_panic = true;3962 g->have_pub_panic = true;
3943 }3963 }
...@@ -6368,12 +6388,14 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa...@@ -6368,12 +6388,14 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
6368 len_debug_size_in_bits,6388 len_debug_size_in_bits,
6369 len_debug_align_in_bits,6389 len_debug_align_in_bits,
6370 len_offset_in_bits,6390 len_offset_in_bits,
6371 0, usize_llvm_di_type),6391 ZigLLVM_DIFlags_Zero,
6392 usize_llvm_di_type),
6372 };6393 };
6373 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,6394 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
6374 compile_unit_scope,6395 compile_unit_scope,
6375 buf_ptr(&type->name),6396 buf_ptr(&type->name),
6376 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,6397 di_file, line, debug_size_in_bits, debug_align_in_bits,
6398 ZigLLVM_DIFlags_Zero,
6377 nullptr, di_element_types, 1, 0, nullptr, "");6399 nullptr, di_element_types, 1, 0, nullptr, "");
63786400
6379 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);6401 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
...@@ -6405,18 +6427,19 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa...@@ -6405,18 +6427,19 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
6405 ptr_debug_size_in_bits,6427 ptr_debug_size_in_bits,
6406 ptr_debug_align_in_bits,6428 ptr_debug_align_in_bits,
6407 ptr_offset_in_bits,6429 ptr_offset_in_bits,
6408 0, get_llvm_di_type(g, ptr_type)),6430 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_type)),
6409 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),6431 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
6410 "len", di_file, line,6432 "len", di_file, line,
6411 len_debug_size_in_bits,6433 len_debug_size_in_bits,
6412 len_debug_align_in_bits,6434 len_debug_align_in_bits,
6413 len_offset_in_bits,6435 len_offset_in_bits,
6414 0, usize_llvm_di_type),6436 ZigLLVM_DIFlags_Zero, usize_llvm_di_type),
6415 };6437 };
6416 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,6438 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
6417 compile_unit_scope,6439 compile_unit_scope,
6418 buf_ptr(&type->name),6440 buf_ptr(&type->name),
6419 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,6441 di_file, line, debug_size_in_bits, debug_align_in_bits,
6442 ZigLLVM_DIFlags_Zero,
6420 nullptr, di_element_types, 2, 0, nullptr, "");6443 nullptr, di_element_types, 2, 0, nullptr, "");
64216444
6422 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);6445 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
...@@ -6577,7 +6600,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6577,7 +6600,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6577 debug_size_in_bits,6600 debug_size_in_bits,
6578 debug_align_in_bits,6601 debug_align_in_bits,
6579 debug_offset_in_bits,6602 debug_offset_in_bits,
6580 0, field_di_type);6603 ZigLLVM_DIFlags_Zero, field_di_type);
6581 assert(di_element_types[debug_field_index]);6604 assert(di_element_types[debug_field_index]);
6582 debug_field_index += 1;6605 debug_field_index += 1;
6583 }6606 }
...@@ -6590,7 +6613,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6590,7 +6613,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6590 di_file, line,6613 di_file, line,
6591 debug_size_in_bits,6614 debug_size_in_bits,
6592 debug_align_in_bits,6615 debug_align_in_bits,
6593 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");6616 ZigLLVM_DIFlags_Zero,
6617 nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");
65946618
6595 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);6619 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);
6596 struct_type->llvm_di_type = replacement_di_type;6620 struct_type->llvm_di_type = replacement_di_type;
...@@ -6619,7 +6643,8 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {...@@ -6619,7 +6643,8 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
6619 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),6643 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
6620 debug_size_in_bits,6644 debug_size_in_bits,
6621 debug_align_in_bits,6645 debug_align_in_bits,
6622 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");6646 ZigLLVM_DIFlags_Zero,
6647 nullptr, di_element_types, (int)debug_field_count, 0, nullptr, "");
6623 return;6648 return;
6624 }6649 }
66256650
...@@ -6703,7 +6728,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6703,7 +6728,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6703 store_size_in_bits,6728 store_size_in_bits,
6704 abi_align_in_bits,6729 abi_align_in_bits,
6705 0,6730 0,
6706 0, field_di_type);6731 ZigLLVM_DIFlags_Zero, field_di_type);
67076732
6708 }6733 }
67096734
...@@ -6732,7 +6757,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6732,7 +6757,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6732 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),6757 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
6733 union_type->data.unionation.union_abi_size * 8,6758 union_type->data.unionation.union_abi_size * 8,
6734 most_aligned_union_member->abi_align * 8,6759 most_aligned_union_member->abi_align * 8,
6735 0, union_inner_di_types,6760 ZigLLVM_DIFlags_Zero, union_inner_di_types,
6736 gen_field_count, 0, "");6761 gen_field_count, 0, "");
67376762
6738 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);6763 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
...@@ -6766,7 +6791,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6766,7 +6791,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6766 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",6791 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
6767 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),6792 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
6768 most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align,6793 most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align,
6769 0, union_inner_di_types, gen_field_count, 0, "");6794 ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");
67706795
6771 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,6796 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,
6772 union_type->data.unionation.gen_union_index);6797 union_type->data.unionation.gen_union_index);
...@@ -6779,7 +6804,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6779,7 +6804,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6779 most_aligned_union_member->size_in_bits,6804 most_aligned_union_member->size_in_bits,
6780 8*most_aligned_union_member->abi_align,6805 8*most_aligned_union_member->abi_align,
6781 union_offset_in_bits,6806 union_offset_in_bits,
6782 0, union_di_type);6807 ZigLLVM_DIFlags_Zero, union_di_type);
67836808
6784 uint64_t tag_debug_size_in_bits = tag_type->size_in_bits;6809 uint64_t tag_debug_size_in_bits = tag_type->size_in_bits;
6785 uint64_t tag_debug_align_in_bits = 8*tag_type->abi_align;6810 uint64_t tag_debug_align_in_bits = 8*tag_type->abi_align;
...@@ -6790,7 +6815,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6790,7 +6815,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6790 tag_debug_size_in_bits,6815 tag_debug_size_in_bits,
6791 tag_debug_align_in_bits,6816 tag_debug_align_in_bits,
6792 tag_offset_in_bits,6817 tag_offset_in_bits,
6793 0, get_llvm_di_type(g, tag_type));6818 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, tag_type));
67946819
6795 ZigLLVMDIType *di_root_members[2];6820 ZigLLVMDIType *di_root_members[2];
6796 di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type;6821 di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type;
...@@ -6804,7 +6829,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -6804,7 +6829,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
6804 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),6829 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
6805 debug_size_in_bits,6830 debug_size_in_bits,
6806 debug_align_in_bits,6831 debug_align_in_bits,
6807 0, nullptr, di_root_members, 2, 0, nullptr, "");6832 ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, "");
68086833
6809 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);6834 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
6810 union_type->llvm_di_type = replacement_di_type;6835 union_type->llvm_di_type = replacement_di_type;
...@@ -6932,18 +6957,18 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {...@@ -6932,18 +6957,18 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
6932 val_debug_size_in_bits,6957 val_debug_size_in_bits,
6933 val_debug_align_in_bits,6958 val_debug_align_in_bits,
6934 val_offset_in_bits,6959 val_offset_in_bits,
6935 0, child_llvm_di_type),6960 ZigLLVM_DIFlags_Zero, child_llvm_di_type),
6936 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),6961 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
6937 "maybe", di_file, line,6962 "maybe", di_file, line,
6938 maybe_debug_size_in_bits,6963 maybe_debug_size_in_bits,
6939 maybe_debug_align_in_bits,6964 maybe_debug_align_in_bits,
6940 maybe_offset_in_bits,6965 maybe_offset_in_bits,
6941 0, bool_llvm_di_type),6966 ZigLLVM_DIFlags_Zero, bool_llvm_di_type),
6942 };6967 };
6943 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,6968 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
6944 compile_unit_scope,6969 compile_unit_scope,
6945 buf_ptr(&type->name),6970 buf_ptr(&type->name),
6946 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,6971 di_file, line, debug_size_in_bits, debug_align_in_bits, ZigLLVM_DIFlags_Zero,
6947 nullptr, di_element_types, 2, 0, nullptr, "");6972 nullptr, di_element_types, 2, 0, nullptr, "");
69486973
6949 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);6974 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
...@@ -6996,13 +7021,13 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {...@@ -6996,13 +7021,13 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
6996 tag_debug_size_in_bits,7021 tag_debug_size_in_bits,
6997 tag_debug_align_in_bits,7022 tag_debug_align_in_bits,
6998 tag_offset_in_bits,7023 tag_offset_in_bits,
6999 0, get_llvm_di_type(g, err_set_type)),7024 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type)),
7000 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),7025 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
7001 "value", di_file, line,7026 "value", di_file, line,
7002 value_debug_size_in_bits,7027 value_debug_size_in_bits,
7003 value_debug_align_in_bits,7028 value_debug_align_in_bits,
7004 value_offset_in_bits,7029 value_offset_in_bits,
7005 0, get_llvm_di_type(g, payload_type)),7030 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)),
7006 };7031 };
70077032
7008 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,7033 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
...@@ -7011,7 +7036,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {...@@ -7011,7 +7036,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
7011 di_file, line,7036 di_file, line,
7012 debug_size_in_bits,7037 debug_size_in_bits,
7013 debug_align_in_bits,7038 debug_align_in_bits,
7014 0,7039 ZigLLVM_DIFlags_Zero,
7015 nullptr, di_element_types, 2, 0, nullptr, "");7040 nullptr, di_element_types, 2, 0, nullptr, "");
70167041
7017 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);7042 ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type);
src/analyze.hpp+2
...@@ -250,5 +250,7 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);...@@ -250,5 +250,7 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);
251251
252void src_assert(bool ok, AstNode *source_node);252void src_assert(bool ok, AstNode *source_node);
253bool is_container(ZigType *type_entry);
254ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name);
253255
254#endif256#endif
src/ast_render.cpp+1-1
...@@ -352,7 +352,7 @@ static void string_literal_escape(Buf *source, Buf *dest) {...@@ -352,7 +352,7 @@ static void string_literal_escape(Buf *source, Buf *dest) {
352 } else if (is_printable(c)) {352 } else if (is_printable(c)) {
353 buf_append_char(dest, c);353 buf_append_char(dest, c);
354 } else {354 } else {
355 buf_appendf(dest, "\\x%x", (int)c);355 buf_appendf(dest, "\\x%02x", (int)c);
356 }356 }
357 }357 }
358}358}
src/cache_hash.cpp+47-55
...@@ -5,6 +5,7 @@...@@ -5,6 +5,7 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8#include "userland.h"
8#include "cache_hash.hpp"9#include "cache_hash.hpp"
9#include "all_types.hpp"10#include "all_types.hpp"
10#include "buffer.hpp"11#include "buffer.hpp"
...@@ -473,71 +474,62 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) {...@@ -473,71 +474,62 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) {
473 if (err == ErrorFileNotFound)474 if (err == ErrorFileNotFound)
474 return err;475 return err;
475 if (verbose) {476 if (verbose) {
476 fprintf(stderr, "unable to read .d file: %s\n", err_str(err));477 fprintf(stderr, "%s: unable to read .d file: %s\n", err_str(err), buf_ptr(dep_file_path));
477 }478 }
478 return ErrorReadingDepFile;479 return ErrorReadingDepFile;
479 }480 }
480 SplitIterator it = memSplit(buf_to_slice(contents), str("\r\n"));481 auto it = stage2_DepTokenizer_init(buf_ptr(contents), buf_len(contents));
481 // skip first line482 // skip first token: target
482 SplitIterator_next(&it);483 {
483 for (;;) {484 auto result = stage2_DepTokenizer_next(&it);
484 Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);485 switch (result.type_id) {
485 if (!opt_line.is_some)486 case stage2_DepNextResult::error:
486 break;
487 if (opt_line.value.len == 0)
488 continue;
489 // skip over indentation
490 while (opt_line.value.len != 0 && (opt_line.value.ptr[0] == ' ' || opt_line.value.ptr[0] == '\t')) {
491 opt_line.value.ptr += 1;
492 opt_line.value.len -= 1;
493 }
494 if (opt_line.value.len == 0)
495 continue;
496
497 if (opt_line.value.ptr[0] == '"') {
498 if (opt_line.value.len < 2) {
499 if (verbose) {487 if (verbose) {
500 fprintf(stderr, "unable to process invalid .d file %s: line too short\n", buf_ptr(dep_file_path));488 fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path));
501 }489 }
502 return ErrorInvalidDepFile;490 err = ErrorInvalidDepFile;
503 }491 goto finish;
504 opt_line.value.ptr += 1;492 case stage2_DepNextResult::null:
505 opt_line.value.len -= 2;493 err = ErrorNone;
506 while (opt_line.value.len != 0 && opt_line.value.ptr[opt_line.value.len] != '"') {494 goto finish;
507 opt_line.value.len -= 1;495 case stage2_DepNextResult::target:
508 }496 case stage2_DepNextResult::prereq:
509 if (opt_line.value.len == 0) {497 err = ErrorNone;
510 if (verbose) {498 break;
511 fprintf(stderr, "unable to process invalid .d file %s: missing double quote\n", buf_ptr(dep_file_path));499 }
512 }500 }
513 return ErrorInvalidDepFile;501 // Process 0+ preqreqs.
514 }502 // clang is invoked in single-source mode so we never get more targets.
515 Buf *filename_buf = buf_create_from_slice(opt_line.value);503 for (;;) {
516 if ((err = cache_add_file(ch, filename_buf))) {504 auto result = stage2_DepTokenizer_next(&it);
505 switch (result.type_id) {
506 case stage2_DepNextResult::error:
517 if (verbose) {507 if (verbose) {
518 fprintf(stderr, "unable to add %s to cache: %s\n", buf_ptr(filename_buf), err_str(err));508 fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path));
519 fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path));
520 }
521 return err;
522 }
523 } else {
524 // sometimes there are multiple files on the same line; we actually need space tokenization.
525 SplitIterator line_it = memSplit(opt_line.value, str(" \t"));
526 Slice<uint8_t> filename;
527 while (SplitIterator_next(&line_it).unwrap(&filename)) {
528 Buf *filename_buf = buf_create_from_slice(filename);
529 if (buf_eql_str(filename_buf, "\\")) continue;
530 if ((err = cache_add_file(ch, filename_buf))) {
531 if (verbose) {
532 fprintf(stderr, "unable to add %s to cache: %s\n", buf_ptr(filename_buf), err_str(err));
533 fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path));
534 }
535 return err;
536 }509 }
510 err = ErrorInvalidDepFile;
511 goto finish;
512 case stage2_DepNextResult::null:
513 case stage2_DepNextResult::target:
514 err = ErrorNone;
515 goto finish;
516 case stage2_DepNextResult::prereq:
517 break;
518 }
519 auto textbuf = buf_alloc();
520 buf_init_from_str(textbuf, result.textz);
521 if ((err = cache_add_file(ch, textbuf))) {
522 if (verbose) {
523 fprintf(stderr, "unable to add %s to cache: %s\n", result.textz, err_str(err));
524 fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path));
537 }525 }
526 goto finish;
538 }527 }
539 }528 }
540 return ErrorNone;529
530 finish:
531 stage2_DepTokenizer_deinit(&it);
532 return err;
541}533}
542534
543static Error write_manifest_file(CacheHash *ch) {535static Error write_manifest_file(CacheHash *ch) {
src/codegen.cpp+164-92
...@@ -48,7 +48,7 @@ static void init_darwin_native(CodeGen *g) {...@@ -48,7 +48,7 @@ static void init_darwin_native(CodeGen *g) {
48 } else if (ios_target) {48 } else if (ios_target) {
49 g->mios_version_min = buf_create_from_str(ios_target);49 g->mios_version_min = buf_create_from_str(ios_target);
50 } else if (g->zig_target->os != OsIOS) {50 } else if (g->zig_target->os != OsIOS) {
51 g->mmacosx_version_min = buf_create_from_str("10.10");51 g->mmacosx_version_min = buf_create_from_str("10.14");
52 }52 }
53}53}
5454
...@@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget...@@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
100100
101 codegen_add_time_event(g, "Initialize");101 codegen_add_time_event(g, "Initialize");
102102
103 g->subsystem = TargetSubsystemAuto;
103 g->libc = libc;104 g->libc = libc;
104 g->zig_target = target;105 g->zig_target = target;
105 g->cache_dir = cache_dir;106 g->cache_dir = cache_dir;
...@@ -296,6 +297,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -296,6 +297,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
296static void generate_error_name_table(CodeGen *g);297static void generate_error_name_table(CodeGen *g);
297static bool value_is_all_undef(ConstExprValue *const_val);298static bool value_is_all_undef(ConstExprValue *const_val);
298static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);299static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr);
300static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment);
299301
300static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {302static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
301 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));303 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
...@@ -399,15 +401,6 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {...@@ -399,15 +401,6 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
399 }401 }
400}402}
401403
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
411static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {404static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
412 switch (id) {405 switch (id) {
413 case GlobalLinkageIdInternal:406 case GlobalLinkageIdInternal:
...@@ -596,8 +589,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {...@@ -596,8 +589,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
596 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");589 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
597 addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");590 addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
598 }591 }
599592 }
600 add_probe_stack_attr(g, fn_table_entry->llvm_value);593 if (g->have_stack_probing && !fn_table_entry->def_scope->safety_off) {
594 addLLVMFnAttrStr(fn_table_entry->llvm_value, "probe-stack", "__zig_probe_stack");
601 }595 }
602 } else {596 } else {
603 maybe_import_dll(g, fn_table_entry->llvm_value, linkage);597 maybe_import_dll(g, fn_table_entry->llvm_value, linkage);
...@@ -680,7 +674,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -680,7 +674,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
680 bool is_optimized = g->build_mode != BuildModeDebug;674 bool is_optimized = g->build_mode != BuildModeDebug;
681 bool is_internal_linkage = (fn_table_entry->body_node != nullptr &&675 bool is_internal_linkage = (fn_table_entry->body_node != nullptr &&
682 fn_table_entry->export_list.length == 0);676 fn_table_entry->export_list.length == 0);
683 unsigned flags = 0;677 unsigned flags = ZigLLVM_DIFlags_StaticMember;
684 ZigLLVMDIScope *fn_di_scope = get_di_scope(g, scope->parent);678 ZigLLVMDIScope *fn_di_scope = get_di_scope(g, scope->parent);
685 assert(fn_di_scope != nullptr);679 assert(fn_di_scope != nullptr);
686 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,680 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
...@@ -1526,53 +1520,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1526,53 +1520,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1526 generate_error_name_table(g);1520 generate_error_name_table(g);
1527 assert(g->err_name_table != nullptr);1521 assert(g->err_name_table != nullptr);
15281522
1529 size_t unwrap_err_msg_text_len = strlen(unwrap_err_msg_text);1523 // Generate the constant part of the error message
1530 size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len;1524 LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1);
1531 LLVMValueRef *err_buf_vals = allocate<LLVMValueRef>(err_buf_len);1525 LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), "");
1532 size_t i = 0;1526 LLVMSetInitializer(msg_prefix, msg_prefix_init);
1533 for (; i < unwrap_err_msg_text_len; i += 1) {1527 LLVMSetLinkage(msg_prefix, LLVMInternalLinkage);
1534 err_buf_vals[i] = LLVMConstInt(LLVMInt8Type(), unwrap_err_msg_text[i], false);1528 LLVMSetGlobalConstant(msg_prefix, true);
1535 }
1536 for (; i < err_buf_len; i += 1) {
1537 err_buf_vals[i] = LLVMGetUndef(LLVMInt8Type());
1538 }
1539 uint32_t u8_align_bytes = get_abi_alignment(g, g->builtin_types.entry_u8);
1540 LLVMValueRef init_value = LLVMConstArray(LLVMInt8Type(), err_buf_vals, err_buf_len);
1541 LLVMValueRef global_array = LLVMAddGlobal(g->module, LLVMTypeOf(init_value), "");
1542 LLVMSetInitializer(global_array, init_value);
1543 LLVMSetLinkage(global_array, LLVMInternalLinkage);
1544 LLVMSetGlobalConstant(global_array, false);
1545 LLVMSetUnnamedAddr(global_array, true);
1546 LLVMSetAlignment(global_array, u8_align_bytes);
1547
1548 ZigType *usize = g->builtin_types.entry_usize;
1549 LLVMValueRef full_buf_ptr_indices[] = {
1550 LLVMConstNull(usize->llvm_type),
1551 LLVMConstNull(usize->llvm_type),
1552 };
1553 LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2);
1554
1555
1556 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
1557 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
1558 ZigType *str_type = get_slice_type(g, u8_ptr_type);
1559 LLVMValueRef global_slice_fields[] = {
1560 full_buf_ptr,
1561 LLVMConstNull(usize->llvm_type),
1562 };
1563 LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, str_type), global_slice_fields, 2);
1564 LLVMValueRef global_slice = LLVMAddGlobal(g->module, LLVMTypeOf(slice_init_value), "");
1565 LLVMSetInitializer(global_slice, slice_init_value);
1566 LLVMSetLinkage(global_slice, LLVMInternalLinkage);
1567 LLVMSetGlobalConstant(global_slice, false);
1568 LLVMSetUnnamedAddr(global_slice, true);
1569 LLVMSetAlignment(global_slice, get_abi_alignment(g, str_type));
1570
1571 LLVMValueRef offset_ptr_indices[] = {
1572 LLVMConstNull(usize->llvm_type),
1573 LLVMConstInt(usize->llvm_type, unwrap_err_msg_text_len, false),
1574 };
1575 LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2);
15761529
1577 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);1530 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
1578 LLVMTypeRef fn_type_ref;1531 LLVMTypeRef fn_type_ref;
...@@ -1609,6 +1562,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1609,6 +1562,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1609 LLVMPositionBuilderAtEnd(g->builder, entry_block);1562 LLVMPositionBuilderAtEnd(g->builder, entry_block);
1610 ZigLLVMClearCurrentDebugLocation(g->builder);1563 ZigLLVMClearCurrentDebugLocation(g->builder);
16111564
1565 ZigType *usize_ty = g->builtin_types.entry_usize;
1566 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
1567 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false);
1568 ZigType *str_type = get_slice_type(g, u8_ptr_type);
1569
1570 // Allocate a buffer to hold the fully-formatted error message
1571 const size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len;
1572 LLVMValueRef max_msg_len = LLVMConstInt(usize_ty->llvm_type, err_buf_len, 0);
1573 LLVMValueRef msg_buffer = LLVMBuildArrayAlloca(g->builder, LLVMInt8Type(), max_msg_len, "msg_buffer");
1574
1575 // Allocate a []u8 slice for the message
1576 LLVMValueRef msg_slice = build_alloca(g, str_type, "msg_slice", 0);
1577
1612 LLVMValueRef err_ret_trace_arg;1578 LLVMValueRef err_ret_trace_arg;
1613 LLVMValueRef err_val;1579 LLVMValueRef err_val;
1614 if (g->have_err_ret_tracing) {1580 if (g->have_err_ret_tracing) {
...@@ -1619,8 +1585,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1619,8 +1585,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1619 err_val = LLVMGetParam(fn_val, 0);1585 err_val = LLVMGetParam(fn_val, 0);
1620 }1586 }
16211587
1588 // Fetch the error name from the global table
1622 LLVMValueRef err_table_indices[] = {1589 LLVMValueRef err_table_indices[] = {
1623 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),1590 LLVMConstNull(usize_ty->llvm_type),
1624 err_val,1591 err_val,
1625 };1592 };
1626 LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");1593 LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, "");
...@@ -1631,15 +1598,38 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1631,15 +1598,38 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1631 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");1598 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
1632 LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");1599 LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, "");
16331600
1634 ZigLLVMBuildMemCpy(g->builder, offset_buf_ptr, u8_align_bytes, err_name_ptr, u8_align_bytes, err_name_len, false);1601 LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false);
1602 // Points to the beginning of msg_buffer
1603 LLVMValueRef msg_buffer_ptr_indices[] = {
1604 LLVMConstNull(usize_ty->llvm_type),
1605 };
1606 LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, "");
1607 // Points to the beginning of the constant prefix message
1608 LLVMValueRef msg_prefix_ptr_indices[] = {
1609 LLVMConstNull(usize_ty->llvm_type),
1610 };
1611 LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1);
1612
1613 // Build the message using the prefix...
1614 ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false);
1615 // ..and append the error name
1616 LLVMValueRef msg_buffer_ptr_after_indices[] = {
1617 msg_prefix_len,
1618 };
1619 LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, "");
1620 ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false);
16351621
1636 LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false);1622 // Set the slice pointer
1637 LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, "");1623 LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, "");
1624 gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false);
16381625
1639 LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, "");1626 // Set the slice length
1640 gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);1627 LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, "");
1628 LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, "");
1629 gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false);
16411630
1642 gen_panic(g, global_slice, err_ret_trace_arg);1631 // Call panic()
1632 gen_panic(g, msg_slice, err_ret_trace_arg);
16431633
1644 LLVMPositionBuilderAtEnd(g->builder, prev_block);1634 LLVMPositionBuilderAtEnd(g->builder, prev_block);
1645 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);1635 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
...@@ -2013,7 +2003,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {...@@ -2013,7 +2003,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
2013 render_const_val_global(g, &instruction->value, "");2003 render_const_val_global(g, &instruction->value, "");
2014 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);2004 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
2015 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), "");2005 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), "");
2016 } else if (instruction->value.type->id == ZigTypeIdPointer) {2006 } else if (get_codegen_ptr_type(instruction->value.type) != nullptr) {
2017 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,2007 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,
2018 get_llvm_type(g, instruction->value.type), "");2008 get_llvm_type(g, instruction->value.type), "");
2019 } else {2009 } else {
...@@ -5617,6 +5607,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5617,6 +5607,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5617 case IrInstructionIdBitCast:5607 case IrInstructionIdBitCast:
5618 case IrInstructionIdGlobalAsm:5608 case IrInstructionIdGlobalAsm:
5619 case IrInstructionIdHasDecl:5609 case IrInstructionIdHasDecl:
5610 case IrInstructionIdUndeclaredIdent:
5620 zig_unreachable();5611 zig_unreachable();
56215612
5622 case IrInstructionIdDeclVarGen:5613 case IrInstructionIdDeclVarGen:
...@@ -7252,7 +7243,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -7252,7 +7243,7 @@ static void define_builtin_types(CodeGen *g) {
7252 buf_init_from_str(&entry->name, "void");7243 buf_init_from_str(&entry->name, "void");
7253 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),7244 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
7254 0,7245 0,
7255 ZigLLVMEncoding_DW_ATE_unsigned());7246 ZigLLVMEncoding_DW_ATE_signed());
7256 g->builtin_types.entry_void = entry;7247 g->builtin_types.entry_void = entry;
7257 g->primitive_type_table.put(&entry->name, entry);7248 g->primitive_type_table.put(&entry->name, entry);
7258 }7249 }
...@@ -7427,6 +7418,21 @@ static const char *build_mode_to_str(BuildMode build_mode) {...@@ -7427,6 +7418,21 @@ static const char *build_mode_to_str(BuildMode build_mode) {
7427 zig_unreachable();7418 zig_unreachable();
7428}7419}
74297420
7421static const char *subsystem_to_str(TargetSubsystem subsystem) {
7422 switch (subsystem) {
7423 case TargetSubsystemConsole: return "Console";
7424 case TargetSubsystemWindows: return "Windows";
7425 case TargetSubsystemPosix: return "Posix";
7426 case TargetSubsystemNative: return "Native";
7427 case TargetSubsystemEfiApplication: return "EfiApplication";
7428 case TargetSubsystemEfiBootServiceDriver: return "EfiBootServiceDriver";
7429 case TargetSubsystemEfiRom: return "EfiRom";
7430 case TargetSubsystemEfiRuntimeDriver: return "EfiRuntimeDriver";
7431 case TargetSubsystemAuto: zig_unreachable();
7432 }
7433 zig_unreachable();
7434}
7435
7430static bool detect_dynamic_link(CodeGen *g) {7436static bool detect_dynamic_link(CodeGen *g) {
7431 if (g->is_dynamic)7437 if (g->is_dynamic)
7432 return true;7438 return true;
...@@ -7458,6 +7464,37 @@ static bool detect_pic(CodeGen *g) {...@@ -7458,6 +7464,37 @@ static bool detect_pic(CodeGen *g) {
7458 zig_unreachable();7464 zig_unreachable();
7459}7465}
74607466
7467static bool detect_stack_probing(CodeGen *g) {
7468 if (!target_supports_stack_probing(g->zig_target))
7469 return false;
7470 switch (g->want_stack_check) {
7471 case WantStackCheckDisabled:
7472 return false;
7473 case WantStackCheckEnabled:
7474 return true;
7475 case WantStackCheckAuto:
7476 return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug;
7477 }
7478 zig_unreachable();
7479}
7480
7481// Returns TargetSubsystemAuto to mean "no subsystem"
7482TargetSubsystem detect_subsystem(CodeGen *g) {
7483 if (g->subsystem != TargetSubsystemAuto)
7484 return g->subsystem;
7485 if (g->zig_target->os == OsWindows) {
7486 if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic))
7487 return TargetSubsystemAuto;
7488 if (g->have_c_main || g->have_pub_main || g->is_test_build)
7489 return TargetSubsystemConsole;
7490 if (g->have_winmain || g->have_winmain_crt_startup)
7491 return TargetSubsystemWindows;
7492 } else if (g->zig_target->os == OsUefi) {
7493 return TargetSubsystemEfiApplication;
7494 }
7495 return TargetSubsystemAuto;
7496}
7497
7461static bool detect_single_threaded(CodeGen *g) {7498static bool detect_single_threaded(CodeGen *g) {
7462 if (g->want_single_threaded)7499 if (g->want_single_threaded)
7463 return true;7500 return true;
...@@ -7476,6 +7513,7 @@ static bool detect_err_ret_tracing(CodeGen *g) {...@@ -7476,6 +7513,7 @@ static bool detect_err_ret_tracing(CodeGen *g) {
7476Buf *codegen_generate_builtin_source(CodeGen *g) {7513Buf *codegen_generate_builtin_source(CodeGen *g) {
7477 g->have_dynamic_link = detect_dynamic_link(g);7514 g->have_dynamic_link = detect_dynamic_link(g);
7478 g->have_pic = detect_pic(g);7515 g->have_pic = detect_pic(g);
7516 g->have_stack_probing = detect_stack_probing(g);
7479 g->is_single_threaded = detect_single_threaded(g);7517 g->is_single_threaded = detect_single_threaded(g);
7480 g->have_err_ret_tracing = detect_err_ret_tracing(g);7518 g->have_err_ret_tracing = detect_err_ret_tracing(g);
74817519
...@@ -7724,7 +7762,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7724,7 +7762,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7724 " pub const Struct = struct {\n"7762 " pub const Struct = struct {\n"
7725 " layout: ContainerLayout,\n"7763 " layout: ContainerLayout,\n"
7726 " fields: []StructField,\n"7764 " fields: []StructField,\n"
7727 " defs: []Definition,\n"7765 " decls: []Declaration,\n"
7728 " };\n"7766 " };\n"
7729 "\n"7767 "\n"
7730 " pub const Optional = struct {\n"7768 " pub const Optional = struct {\n"
...@@ -7752,7 +7790,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7752,7 +7790,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7752 " layout: ContainerLayout,\n"7790 " layout: ContainerLayout,\n"
7753 " tag_type: type,\n"7791 " tag_type: type,\n"
7754 " fields: []EnumField,\n"7792 " fields: []EnumField,\n"
7755 " defs: []Definition,\n"7793 " decls: []Declaration,\n"
7756 " };\n"7794 " };\n"
7757 "\n"7795 "\n"
7758 " pub const UnionField = struct {\n"7796 " pub const UnionField = struct {\n"
...@@ -7765,7 +7803,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7765,7 +7803,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7765 " layout: ContainerLayout,\n"7803 " layout: ContainerLayout,\n"
7766 " tag_type: ?type,\n"7804 " tag_type: ?type,\n"
7767 " fields: []UnionField,\n"7805 " fields: []UnionField,\n"
7768 " defs: []Definition,\n"7806 " decls: []Declaration,\n"
7769 " };\n"7807 " };\n"
7770 "\n"7808 "\n"
7771 " pub const CallingConvention = enum {\n"7809 " pub const CallingConvention = enum {\n"
...@@ -7801,7 +7839,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7801,7 +7839,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7801 " child: type,\n"7839 " child: type,\n"
7802 " };\n"7840 " };\n"
7803 "\n"7841 "\n"
7804 " pub const Definition = struct {\n"7842 " pub const Declaration = struct {\n"
7805 " name: []const u8,\n"7843 " name: []const u8,\n"
7806 " is_pub: bool,\n"7844 " is_pub: bool,\n"
7807 " data: Data,\n"7845 " data: Data,\n"
...@@ -7809,9 +7847,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7809,9 +7847,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7809 " pub const Data = union(enum) {\n"7847 " pub const Data = union(enum) {\n"
7810 " Type: type,\n"7848 " Type: type,\n"
7811 " Var: type,\n"7849 " Var: type,\n"
7812 " Fn: FnDef,\n"7850 " Fn: FnDecl,\n"
7813 "\n"7851 "\n"
7814 " pub const FnDef = struct {\n"7852 " pub const FnDecl = struct {\n"
7815 " fn_type: type,\n"7853 " fn_type: type,\n"
7816 " inline_type: Inline,\n"7854 " inline_type: Inline,\n"
7817 " calling_convention: CallingConvention,\n"7855 " calling_convention: CallingConvention,\n"
...@@ -7864,6 +7902,28 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7864,6 +7902,28 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7864 //assert(EndianBig == 0);7902 //assert(EndianBig == 0);
7865 //assert(EndianLittle == 1);7903 //assert(EndianLittle == 1);
7866 }7904 }
7905 {
7906 buf_appendf(contents,
7907 "pub const SubSystem = enum {\n"
7908 " Console,\n"
7909 " Windows,\n"
7910 " Posix,\n"
7911 " Native,\n"
7912 " EfiApplication,\n"
7913 " EfiBootServiceDriver,\n"
7914 " EfiRom,\n"
7915 " EfiRuntimeDriver,\n"
7916 "};\n\n");
7917
7918 assert(TargetSubsystemConsole == 0);
7919 assert(TargetSubsystemWindows == 1);
7920 assert(TargetSubsystemPosix == 2);
7921 assert(TargetSubsystemNative == 3);
7922 assert(TargetSubsystemEfiApplication == 4);
7923 assert(TargetSubsystemEfiBootServiceDriver == 5);
7924 assert(TargetSubsystemEfiRom == 6);
7925 assert(TargetSubsystemEfiRuntimeDriver == 7);
7926 }
7867 {7927 {
7868 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";7928 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
7869 buf_appendf(contents, "pub const endian = %s;\n", endian_str);7929 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
...@@ -7880,6 +7940,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -7880,6 +7940,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
7880 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));7940 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
7881 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));7941 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
78827942
7943 {
7944 TargetSubsystem detected_subsystem = detect_subsystem(g);
7945 if (detected_subsystem != TargetSubsystemAuto) {
7946 buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
7947 }
7948 }
7949
7883 if (g->is_test_build) {7950 if (g->is_test_build) {
7884 buf_appendf(contents,7951 buf_appendf(contents,
7885 "const TestFn = struct {\n"7952 "const TestFn = struct {\n"
...@@ -7923,6 +7990,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -7923,6 +7990,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
7923 cache_bool(&cache_hash, g->have_err_ret_tracing);7990 cache_bool(&cache_hash, g->have_err_ret_tracing);
7924 cache_bool(&cache_hash, g->libc_link_lib != nullptr);7991 cache_bool(&cache_hash, g->libc_link_lib != nullptr);
7925 cache_bool(&cache_hash, g->valgrind_support);7992 cache_bool(&cache_hash, g->valgrind_support);
7993 cache_int(&cache_hash, detect_subsystem(g));
79267994
7927 Buf digest = BUF_INIT;7995 Buf digest = BUF_INIT;
7928 buf_resize(&digest, 0);7996 buf_resize(&digest, 0);
...@@ -7982,6 +8050,7 @@ static void init(CodeGen *g) {...@@ -7982,6 +8050,7 @@ static void init(CodeGen *g) {
79828050
7983 g->have_dynamic_link = detect_dynamic_link(g);8051 g->have_dynamic_link = detect_dynamic_link(g);
7984 g->have_pic = detect_pic(g);8052 g->have_pic = detect_pic(g);
8053 g->have_stack_probing = detect_stack_probing(g);
7985 g->is_single_threaded = detect_single_threaded(g);8054 g->is_single_threaded = detect_single_threaded(g);
7986 g->have_err_ret_tracing = detect_err_ret_tracing(g);8055 g->have_err_ret_tracing = detect_err_ret_tracing(g);
79878056
...@@ -7989,10 +8058,6 @@ static void init(CodeGen *g) {...@@ -7989,10 +8058,6 @@ static void init(CodeGen *g) {
7989 g->is_single_threaded = true;8058 g->is_single_threaded = true;
7990 }8059 }
79918060
7992 if (g->is_test_build) {
7993 g->subsystem = TargetSubsystemConsole;
7994 }
7995
7996 assert(g->root_out_name);8061 assert(g->root_out_name);
7997 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));8062 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
79988063
...@@ -9077,8 +9142,11 @@ static void gen_h_file(CodeGen *g) {...@@ -9077,8 +9142,11 @@ static void gen_h_file(CodeGen *g) {
9077 if (!out_h)9142 if (!out_h)
9078 zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno));9143 zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno));
90799144
9080 Buf *export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)));9145 Buf *export_macro = nullptr;
9081 buf_upcase(export_macro);9146 if (g->is_dynamic) {
9147 export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)));
9148 buf_upcase(export_macro);
9149 }
90829150
9083 Buf *extern_c_macro = preprocessor_mangle(buf_sprintf("%s_EXTERN_C", buf_ptr(g->root_out_name)));9151 Buf *extern_c_macro = preprocessor_mangle(buf_sprintf("%s_EXTERN_C", buf_ptr(g->root_out_name)));
9084 buf_upcase(extern_c_macro);9152 buf_upcase(extern_c_macro);
...@@ -9103,10 +9171,11 @@ static void gen_h_file(CodeGen *g) {...@@ -9103,10 +9171,11 @@ static void gen_h_file(CodeGen *g) {
9103 FnExport *fn_export = &fn_table_entry->export_list.items[0];9171 FnExport *fn_export = &fn_table_entry->export_list.items[0];
9104 symbol_name = &fn_export->name;9172 symbol_name = &fn_export->name;
9105 }9173 }
9174
9106 buf_appendf(&h_buf, "%s %s %s(",9175 buf_appendf(&h_buf, "%s %s %s(",
9107 buf_ptr(export_macro),9176 buf_ptr(g->is_dynamic ? export_macro : extern_c_macro),
9108 buf_ptr(&return_type_c),9177 buf_ptr(&return_type_c),
9109 buf_ptr(symbol_name));9178 buf_ptr(symbol_name));
91109179
9111 Buf param_type_c = BUF_INIT;9180 Buf param_type_c = BUF_INIT;
9112 if (fn_type_id->param_count > 0) {9181 if (fn_type_id->param_count > 0) {
...@@ -9156,13 +9225,16 @@ static void gen_h_file(CodeGen *g) {...@@ -9156,13 +9225,16 @@ static void gen_h_file(CodeGen *g) {
9156 fprintf(out_h, "#define %s\n", buf_ptr(extern_c_macro));9225 fprintf(out_h, "#define %s\n", buf_ptr(extern_c_macro));
9157 fprintf(out_h, "#endif\n");9226 fprintf(out_h, "#endif\n");
9158 fprintf(out_h, "\n");9227 fprintf(out_h, "\n");
9159 fprintf(out_h, "#if defined(_WIN32)\n");9228
9160 fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro));9229 if (g->is_dynamic) {
9161 fprintf(out_h, "#else\n");9230 fprintf(out_h, "#if defined(_WIN32)\n");
9162 fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n",9231 fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro));
9232 fprintf(out_h, "#else\n");
9233 fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n",
9163 buf_ptr(export_macro), buf_ptr(extern_c_macro));9234 buf_ptr(export_macro), buf_ptr(extern_c_macro));
9164 fprintf(out_h, "#endif\n");9235 fprintf(out_h, "#endif\n");
9165 fprintf(out_h, "\n");9236 fprintf(out_h, "\n");
9237 }
91669238
9167 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {9239 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
9168 ZigType *type_entry = gen_h->types_to_declare.at(type_i);9240 ZigType *type_entry = gen_h->types_to_declare.at(type_i);
...@@ -9339,7 +9411,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -9339,7 +9411,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
9339 cache_int(ch, g->zig_target->vendor);9411 cache_int(ch, g->zig_target->vendor);
9340 cache_int(ch, g->zig_target->os);9412 cache_int(ch, g->zig_target->os);
9341 cache_int(ch, g->zig_target->abi);9413 cache_int(ch, g->zig_target->abi);
9342 cache_int(ch, g->subsystem);9414 cache_int(ch, detect_subsystem(g));
9343 cache_bool(ch, g->strip_debug_symbols);9415 cache_bool(ch, g->strip_debug_symbols);
9344 cache_bool(ch, g->is_test_build);9416 cache_bool(ch, g->is_test_build);
9345 if (g->is_test_build) {9417 if (g->is_test_build) {
...@@ -9351,10 +9423,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -9351,10 +9423,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
9351 cache_bool(ch, g->each_lib_rpath);9423 cache_bool(ch, g->each_lib_rpath);
9352 cache_bool(ch, g->disable_gen_h);9424 cache_bool(ch, g->disable_gen_h);
9353 cache_bool(ch, g->bundle_compiler_rt);9425 cache_bool(ch, g->bundle_compiler_rt);
9354 cache_bool(ch, g->disable_stack_probing);
9355 cache_bool(ch, want_valgrind_support(g));9426 cache_bool(ch, want_valgrind_support(g));
9356 cache_bool(ch, g->have_pic);9427 cache_bool(ch, g->have_pic);
9357 cache_bool(ch, g->have_dynamic_link);9428 cache_bool(ch, g->have_dynamic_link);
9429 cache_bool(ch, g->have_stack_probing);
9358 cache_bool(ch, g->is_dummy_so);9430 cache_bool(ch, g->is_dummy_so);
9359 cache_buf_opt(ch, g->mmacosx_version_min);9431 cache_buf_opt(ch, g->mmacosx_version_min);
9360 cache_buf_opt(ch, g->mios_version_min);9432 cache_buf_opt(ch, g->mios_version_min);
src/codegen.hpp+2
...@@ -56,4 +56,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us...@@ -56,4 +56,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
5656
57Buf *codegen_generate_builtin_source(CodeGen *g);57Buf *codegen_generate_builtin_source(CodeGen *g);
5858
59TargetSubsystem detect_subsystem(CodeGen *g);
60
59#endif61#endif
src/ir.cpp+161-113
...@@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {...@@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {
1015 return IrInstructionIdHasDecl;1015 return IrInstructionIdHasDecl;
1016}1016}
10171017
1018static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) {
1019 return IrInstructionIdUndeclaredIdent;
1020}
1021
1018template<typename T>1022template<typename T>
1019static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1023static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1020 T *special_instruction = allocate<T>(1);1024 T *special_instruction = allocate<T>(1);
...@@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s...@@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s
3031 return &instruction->base;3035 return &instruction->base;
3032}3036}
30333037
3038static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node,
3039 Buf *name)
3040{
3041 IrInstructionUndeclaredIdent *instruction = ir_build_instruction<IrInstructionUndeclaredIdent>(irb, scope, source_node);
3042 instruction->name = name;
3043
3044 return &instruction->base;
3045}
3046
3034static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {3047static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
3035 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);3048 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
3036 instruction->scope_is_comptime = scope_is_comptime;3049 instruction->scope_is_comptime = scope_is_comptime;
...@@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
38963909
3897 Buf *variable_name = node->data.symbol_expr.symbol;3910 Buf *variable_name = node->data.symbol_expr.symbol;
38983911
3899 if (buf_eql_str(variable_name, "_") && lval == LValPtr) {3912 if (buf_eql_str(variable_name, "_")) {
3900 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);3913 if (lval == LValPtr) {
3901 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,3914 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
3902 irb->codegen->builtin_types.entry_void, false);3915 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
3903 const_instruction->base.value.special = ConstValSpecialStatic;3916 irb->codegen->builtin_types.entry_void, false);
3904 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;3917 const_instruction->base.value.special = ConstValSpecialStatic;
3905 return &const_instruction->base;3918 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;
3919 return &const_instruction->base;
3920 } else {
3921 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to"));
3922 return irb->codegen->invalid_instruction;
3923 }
3906 }3924 }
39073925
3908 ZigType *primitive_type;3926 ZigType *primitive_type;
...@@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
3943 return irb->codegen->invalid_instruction;3961 return irb->codegen->invalid_instruction;
3944 }3962 }
39453963
3946 // put a variable of same name with invalid type in global scope3964 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
3947 // so that future references to this same name will find a variable with an invalid type
3948 populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name);
3949 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
3950 return irb->codegen->invalid_instruction;
3951}3965}
39523966
3953static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {3967static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
...@@ -10252,12 +10266,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -10252,12 +10266,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
10252 return result;10266 return result;
10253}10267}
1025410268
10255static bool is_container(ZigType *type) {
10256 return type->id == ZigTypeIdStruct ||
10257 type->id == ZigTypeIdEnum ||
10258 type->id == ZigTypeIdUnion;
10259}
10260
10261static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {10269static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
10262 assert(old_bb);10270 assert(old_bb);
1026310271
...@@ -16165,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16165,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1616516173
16166 if (type_is_invalid(container_type)) {16174 if (type_is_invalid(container_type)) {
16167 return ira->codegen->invalid_instruction;16175 return ira->codegen->invalid_instruction;
16168 } else if (is_container_ref(container_type)) {16176 } else if (is_slice(container_type) || is_container_ref(container_type)) {
16169 assert(container_ptr->value.type->id == ZigTypeIdPointer);16177 assert(container_ptr->value.type->id == ZigTypeIdPointer);
16170 if (container_type->id == ZigTypeIdPointer) {16178 if (container_type->id == ZigTypeIdPointer) {
16171 ZigType *bare_type = container_ref_type(container_type);16179 ZigType *bare_type = container_ref_type(container_type);
...@@ -16235,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc...@@ -16235,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1623516243
16236 if (type_is_invalid(child_type)) {16244 if (type_is_invalid(child_type)) {
16237 return ira->codegen->invalid_instruction;16245 return ira->codegen->invalid_instruction;
16238 } else if (is_container(child_type) && !is_slice(child_type)) {16246 } else if (is_container(child_type)) {
16239 if (child_type->id == ZigTypeIdEnum) {16247 if (child_type->id == ZigTypeIdEnum) {
16240 if ((err = ensure_complete_type(ira->codegen, child_type)))16248 if ((err = ensure_complete_type(ira->codegen, child_type)))
16241 return ira->codegen->invalid_instruction;16249 return ira->codegen->invalid_instruction;
...@@ -17879,10 +17887,37 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -17879,10 +17887,37 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1787917887
17880 bool any_missing = false;17888 bool any_missing = false;
17881 for (size_t i = 0; i < actual_field_count; i += 1) {17889 for (size_t i = 0; i < actual_field_count; i += 1) {
17882 if (!field_assign_nodes[i]) {17890 if (field_assign_nodes[i]) continue;
17883 ir_add_error_node(ira, instruction->source_node,17891
17884 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));17892 // look for a default field value
17885 any_missing = true;17893 TypeStructField *field = &container_type->data.structure.fields[i];
17894 if (field->init_val == nullptr) {
17895 // it's not memoized. time to go analyze it
17896 assert(field->decl_node->type == NodeTypeStructField);
17897 AstNode *init_node = field->decl_node->data.struct_field.value;
17898 if (init_node == nullptr) {
17899 ir_add_error_node(ira, instruction->source_node,
17900 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
17901 any_missing = true;
17902 continue;
17903 }
17904 // scope is not the scope of the struct init, it's the scope of the struct type decl
17905 Scope *analyze_scope = &get_container_scope(container_type)->base;
17906 // memoize it
17907 field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node,
17908 field->type_entry, nullptr);
17909 }
17910 if (type_is_invalid(field->init_val->type))
17911 return ira->codegen->invalid_instruction;
17912
17913 IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type);
17914 copy_const_val(&runtime_inst->value, field->init_val, true);
17915
17916 new_fields[i].value = runtime_inst;
17917 new_fields[i].type_struct_field = field;
17918
17919 if (const_val.special == ConstValSpecialStatic) {
17920 copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true);
17886 }17921 }
17887 }17922 }
17888 if (any_missing)17923 if (any_missing)
...@@ -18372,37 +18407,37 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig...@@ -18372,37 +18407,37 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
18372 return var->const_value->data.x_type;18407 return var->const_value->data.x_type;
18373}18408}
1837418409
18375static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,18410static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val,
18376 ScopeDecls *decls_scope)18411 ScopeDecls *decls_scope)
18377{18412{
18378 Error err;18413 Error err;
18379 ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr);18414 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
18380 if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown)))18415 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown)))
18381 return err;18416 return err;
1838218417
18383 ensure_field_index(type_info_definition_type, "name", 0);18418 ensure_field_index(type_info_declaration_type, "name", 0);
18384 ensure_field_index(type_info_definition_type, "is_pub", 1);18419 ensure_field_index(type_info_declaration_type, "is_pub", 1);
18385 ensure_field_index(type_info_definition_type, "data", 2);18420 ensure_field_index(type_info_declaration_type, "data", 2);
1838618421
18387 ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type);18422 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
18388 if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type)))18423 if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type)))
18389 return err;18424 return err;
1839018425
18391 ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type);18426 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type);
18392 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type)))18427 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type)))
18393 return err;18428 return err;
1839418429
18395 ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type);18430 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type);
18396 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type)))18431 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type)))
18397 return err;18432 return err;
1839818433
18399 // Loop through our definitions once to figure out how many definitions we will generate info for.18434 // Loop through our declarations once to figure out how many declarations we will generate info for.
18400 auto decl_it = decls_scope->decl_table.entry_iterator();18435 auto decl_it = decls_scope->decl_table.entry_iterator();
18401 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;18436 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
18402 int definition_count = 0;18437 int declaration_count = 0;
1840318438
18404 while ((curr_entry = decl_it.next()) != nullptr) {18439 while ((curr_entry = decl_it.next()) != nullptr) {
18405 // If the definition is unresolved, force it to be resolved again.18440 // If the declaration is unresolved, force it to be resolved again.
18406 if (curr_entry->value->resolution == TldResolutionUnresolved) {18441 if (curr_entry->value->resolution == TldResolutionUnresolved) {
18407 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node);18442 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node);
18408 if (curr_entry->value->resolution != TldResolutionOk) {18443 if (curr_entry->value->resolution != TldResolutionOk) {
...@@ -18418,21 +18453,21 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18418,21 +18453,21 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18418 continue;18453 continue;
18419 }18454 }
1842018455
18421 definition_count += 1;18456 declaration_count += 1;
18422 }18457 }
18423 }18458 }
1842418459
18425 ConstExprValue *definition_array = create_const_vals(1);18460 ConstExprValue *declaration_array = create_const_vals(1);
18426 definition_array->special = ConstValSpecialStatic;18461 declaration_array->special = ConstValSpecialStatic;
18427 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);18462 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count);
18428 definition_array->data.x_array.special = ConstArraySpecialNone;18463 declaration_array->data.x_array.special = ConstArraySpecialNone;
18429 definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);18464 declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count);
18430 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);18465 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false);
1843118466
18432 // Loop through the definitions and generate info.18467 // Loop through the declarations and generate info.
18433 decl_it = decls_scope->decl_table.entry_iterator();18468 decl_it = decls_scope->decl_table.entry_iterator();
18434 curr_entry = nullptr;18469 curr_entry = nullptr;
18435 int definition_index = 0;18470 int declaration_index = 0;
18436 while ((curr_entry = decl_it.next()) != nullptr) {18471 while ((curr_entry = decl_it.next()) != nullptr) {
18437 // Skip comptime blocks and test functions.18472 // Skip comptime blocks and test functions.
18438 if (curr_entry->value->id == TldIdCompTime) {18473 if (curr_entry->value->id == TldIdCompTime) {
...@@ -18443,10 +18478,10 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18443,10 +18478,10 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18443 continue;18478 continue;
18444 }18479 }
1844518480
18446 ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index];18481 ConstExprValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index];
1844718482
18448 definition_val->special = ConstValSpecialStatic;18483 declaration_val->special = ConstValSpecialStatic;
18449 definition_val->type = type_info_definition_type;18484 declaration_val->type = type_info_declaration_type;
1845018485
18451 ConstExprValue *inner_fields = create_const_vals(3);18486 ConstExprValue *inner_fields = create_const_vals(3);
18452 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);18487 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);
...@@ -18455,9 +18490,9 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18455,9 +18490,9 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18455 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;18490 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
18456 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;18491 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;
18457 inner_fields[2].special = ConstValSpecialStatic;18492 inner_fields[2].special = ConstValSpecialStatic;
18458 inner_fields[2].type = type_info_definition_data_type;18493 inner_fields[2].type = type_info_declaration_data_type;
18459 inner_fields[2].parent.id = ConstParentIdStruct;18494 inner_fields[2].parent.id = ConstParentIdStruct;
18460 inner_fields[2].parent.data.p_struct.struct_val = definition_val;18495 inner_fields[2].parent.data.p_struct.struct_val = declaration_val;
18461 inner_fields[2].parent.data.p_struct.field_index = 1;18496 inner_fields[2].parent.data.p_struct.field_index = 1;
1846218497
18463 switch (curr_entry->value->id) {18498 switch (curr_entry->value->id) {
...@@ -18468,7 +18503,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18468,7 +18503,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18468 return ErrorSemanticAnalyzeFail;18503 return ErrorSemanticAnalyzeFail;
1846918504
18470 if (var->const_value->type->id == ZigTypeIdMetaType) {18505 if (var->const_value->type->id == ZigTypeIdMetaType) {
18471 // We have a variable of type 'type', so it's actually a type definition.18506 // We have a variable of type 'type', so it's actually a type declaration.
18472 // 0: Data.Type: type18507 // 0: Data.Type: type
18473 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);18508 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);
18474 inner_fields[2].data.x_union.payload = var->const_value;18509 inner_fields[2].data.x_union.payload = var->const_value;
...@@ -18488,7 +18523,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18488,7 +18523,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18488 }18523 }
18489 case TldIdFn:18524 case TldIdFn:
18490 {18525 {
18491 // 2: Data.Fn: Data.FnDef18526 // 2: Data.Fn: Data.FnDecl
18492 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);18527 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);
1849318528
18494 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;18529 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
...@@ -18499,70 +18534,70 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18499,70 +18534,70 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18499 return ErrorSemanticAnalyzeFail;18534 return ErrorSemanticAnalyzeFail;
18500 }18535 }
1850118536
18502 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node);18537 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto;
1850318538
18504 ConstExprValue *fn_def_val = create_const_vals(1);18539 ConstExprValue *fn_decl_val = create_const_vals(1);
18505 fn_def_val->special = ConstValSpecialStatic;18540 fn_decl_val->special = ConstValSpecialStatic;
18506 fn_def_val->type = type_info_fn_def_type;18541 fn_decl_val->type = type_info_fn_decl_type;
18507 fn_def_val->parent.id = ConstParentIdUnion;18542 fn_decl_val->parent.id = ConstParentIdUnion;
18508 fn_def_val->parent.data.p_union.union_val = &inner_fields[2];18543 fn_decl_val->parent.data.p_union.union_val = &inner_fields[2];
1850918544
18510 ConstExprValue *fn_def_fields = create_const_vals(9);18545 ConstExprValue *fn_decl_fields = create_const_vals(9);
18511 fn_def_val->data.x_struct.fields = fn_def_fields;18546 fn_decl_val->data.x_struct.fields = fn_decl_fields;
1851218547
18513 // fn_type: type18548 // fn_type: type
18514 ensure_field_index(fn_def_val->type, "fn_type", 0);18549 ensure_field_index(fn_decl_val->type, "fn_type", 0);
18515 fn_def_fields[0].special = ConstValSpecialStatic;18550 fn_decl_fields[0].special = ConstValSpecialStatic;
18516 fn_def_fields[0].type = ira->codegen->builtin_types.entry_type;18551 fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type;
18517 fn_def_fields[0].data.x_type = fn_entry->type_entry;18552 fn_decl_fields[0].data.x_type = fn_entry->type_entry;
18518 // inline_type: Data.FnDef.Inline18553 // inline_type: Data.FnDecl.Inline
18519 ensure_field_index(fn_def_val->type, "inline_type", 1);18554 ensure_field_index(fn_decl_val->type, "inline_type", 1);
18520 fn_def_fields[1].special = ConstValSpecialStatic;18555 fn_decl_fields[1].special = ConstValSpecialStatic;
18521 fn_def_fields[1].type = type_info_fn_def_inline_type;18556 fn_decl_fields[1].type = type_info_fn_decl_inline_type;
18522 bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline);18557 bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline);
18523 // calling_convention: TypeInfo.CallingConvention18558 // calling_convention: TypeInfo.CallingConvention
18524 ensure_field_index(fn_def_val->type, "calling_convention", 2);18559 ensure_field_index(fn_decl_val->type, "calling_convention", 2);
18525 fn_def_fields[2].special = ConstValSpecialStatic;18560 fn_decl_fields[2].special = ConstValSpecialStatic;
18526 fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);18561 fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
18527 bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc);18562 bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc);
18528 // is_var_args: bool18563 // is_var_args: bool
18529 ensure_field_index(fn_def_val->type, "is_var_args", 3);18564 ensure_field_index(fn_decl_val->type, "is_var_args", 3);
18530 bool is_varargs = fn_node->is_var_args;18565 bool is_varargs = fn_node->is_var_args;
18531 fn_def_fields[3].special = ConstValSpecialStatic;18566 fn_decl_fields[3].special = ConstValSpecialStatic;
18532 fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool;18567 fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool;
18533 fn_def_fields[3].data.x_bool = is_varargs;18568 fn_decl_fields[3].data.x_bool = is_varargs;
18534 // is_extern: bool18569 // is_extern: bool
18535 ensure_field_index(fn_def_val->type, "is_extern", 4);18570 ensure_field_index(fn_decl_val->type, "is_extern", 4);
18536 fn_def_fields[4].special = ConstValSpecialStatic;18571 fn_decl_fields[4].special = ConstValSpecialStatic;
18537 fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool;18572 fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool;
18538 fn_def_fields[4].data.x_bool = fn_node->is_extern;18573 fn_decl_fields[4].data.x_bool = fn_node->is_extern;
18539 // is_export: bool18574 // is_export: bool
18540 ensure_field_index(fn_def_val->type, "is_export", 5);18575 ensure_field_index(fn_decl_val->type, "is_export", 5);
18541 fn_def_fields[5].special = ConstValSpecialStatic;18576 fn_decl_fields[5].special = ConstValSpecialStatic;
18542 fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool;18577 fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool;
18543 fn_def_fields[5].data.x_bool = fn_node->is_export;18578 fn_decl_fields[5].data.x_bool = fn_node->is_export;
18544 // lib_name: ?[]const u818579 // lib_name: ?[]const u8
18545 ensure_field_index(fn_def_val->type, "lib_name", 6);18580 ensure_field_index(fn_decl_val->type, "lib_name", 6);
18546 fn_def_fields[6].special = ConstValSpecialStatic;18581 fn_decl_fields[6].special = ConstValSpecialStatic;
18547 ZigType *u8_ptr = get_pointer_to_type_extra(18582 ZigType *u8_ptr = get_pointer_to_type_extra(
18548 ira->codegen, ira->codegen->builtin_types.entry_u8,18583 ira->codegen, ira->codegen->builtin_types.entry_u8,
18549 true, false, PtrLenUnknown,18584 true, false, PtrLenUnknown,
18550 0, 0, 0, false);18585 0, 0, 0, false);
18551 fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));18586 fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
18552 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) {18587 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) {
18553 fn_def_fields[6].data.x_optional = create_const_vals(1);18588 fn_decl_fields[6].data.x_optional = create_const_vals(1);
18554 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);18589 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
18555 init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true);18590 init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true);
18556 } else {18591 } else {
18557 fn_def_fields[6].data.x_optional = nullptr;18592 fn_decl_fields[6].data.x_optional = nullptr;
18558 }18593 }
18559 // return_type: type18594 // return_type: type
18560 ensure_field_index(fn_def_val->type, "return_type", 7);18595 ensure_field_index(fn_decl_val->type, "return_type", 7);
18561 fn_def_fields[7].special = ConstValSpecialStatic;18596 fn_decl_fields[7].special = ConstValSpecialStatic;
18562 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type;18597 fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type;
18563 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;18598 fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
18564 // arg_names: [][] const u818599 // arg_names: [][] const u8
18565 ensure_field_index(fn_def_val->type, "arg_names", 8);18600 ensure_field_index(fn_decl_val->type, "arg_names", 8);
18566 size_t fn_arg_count = fn_entry->variable_list.length;18601 size_t fn_arg_count = fn_entry->variable_list.length;
18567 ConstExprValue *fn_arg_name_array = create_const_vals(1);18602 ConstExprValue *fn_arg_name_array = create_const_vals(1);
18568 fn_arg_name_array->special = ConstValSpecialStatic;18603 fn_arg_name_array->special = ConstValSpecialStatic;
...@@ -18571,7 +18606,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18571,7 +18606,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18571 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;18606 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
18572 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);18607 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
1857318608
18574 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);18609 init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
1857518610
18576 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {18611 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
18577 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);18612 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
...@@ -18583,7 +18618,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18583,7 +18618,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18583 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;18618 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
18584 }18619 }
1858518620
18586 inner_fields[2].data.x_union.payload = fn_def_val;18621 inner_fields[2].data.x_union.payload = fn_decl_val;
18587 break;18622 break;
18588 }18623 }
18589 case TldIdContainer:18624 case TldIdContainer:
...@@ -18607,11 +18642,11 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,...@@ -18607,11 +18642,11 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
18607 zig_unreachable();18642 zig_unreachable();
18608 }18643 }
1860918644
18610 definition_val->data.x_struct.fields = inner_fields;18645 declaration_val->data.x_struct.fields = inner_fields;
18611 definition_index++;18646 declaration_index++;
18612 }18647 }
1861318648
18614 assert(definition_index == definition_count);18649 assert(declaration_index == declaration_count);
18615 return ErrorNone;18650 return ErrorNone;
18616}18651}
1861718652
...@@ -18919,9 +18954,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -18919,9 +18954,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
18919 enum_field_val->parent.data.p_array.array_val = enum_field_array;18954 enum_field_val->parent.data.p_array.array_val = enum_field_array;
18920 enum_field_val->parent.data.p_array.elem_index = enum_field_index;18955 enum_field_val->parent.data.p_array.elem_index = enum_field_index;
18921 }18956 }
18922 // defs: []TypeInfo.Definition18957 // decls: []TypeInfo.Declaration
18923 ensure_field_index(result->type, "defs", 3);18958 ensure_field_index(result->type, "decls", 3);
18924 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],18959 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
18925 type_entry->data.enumeration.decls_scope)))18960 type_entry->data.enumeration.decls_scope)))
18926 {18961 {
18927 return err;18962 return err;
...@@ -19086,9 +19121,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -19086,9 +19121,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
19086 union_field_val->parent.data.p_array.array_val = union_field_array;19121 union_field_val->parent.data.p_array.array_val = union_field_array;
19087 union_field_val->parent.data.p_array.elem_index = union_field_index;19122 union_field_val->parent.data.p_array.elem_index = union_field_index;
19088 }19123 }
19089 // defs: []TypeInfo.Definition19124 // decls: []TypeInfo.Declaration
19090 ensure_field_index(result->type, "defs", 3);19125 ensure_field_index(result->type, "decls", 3);
19091 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],19126 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
19092 type_entry->data.unionation.decls_scope)))19127 type_entry->data.unionation.decls_scope)))
19093 {19128 {
19094 return err;19129 return err;
...@@ -19167,9 +19202,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -19167,9 +19202,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
19167 struct_field_val->parent.data.p_array.array_val = struct_field_array;19202 struct_field_val->parent.data.p_array.array_val = struct_field_array;
19168 struct_field_val->parent.data.p_array.elem_index = struct_field_index;19203 struct_field_val->parent.data.p_array.elem_index = struct_field_index;
19169 }19204 }
19170 // defs: []TypeInfo.Definition19205 // decls: []TypeInfo.Declaration
19171 ensure_field_index(result->type, "defs", 2);19206 ensure_field_index(result->type, "decls", 2);
19172 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[2],19207 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2],
19173 type_entry->data.structure.decls_scope)))19208 type_entry->data.structure.decls_scope)))
19174 {19209 {
19175 return err;19210 return err;
...@@ -23237,6 +23272,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct...@@ -23237,6 +23272,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct
23237 return ir_const_bool(ira, &instruction->base, true);23272 return ir_const_bool(ira, &instruction->base, true);
23238}23273}
2323923274
23275static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) {
23276 // put a variable of same name with invalid type in global scope
23277 // so that future references to this same name will find a variable with an invalid type
23278 populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node,
23279 instruction->name);
23280 ir_add_error(ira, &instruction->base,
23281 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name)));
23282 return ira->codegen->invalid_instruction;
23283}
23284
23240static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {23285static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
23241 switch (instruction->id) {23286 switch (instruction->id) {
23242 case IrInstructionIdInvalid:23287 case IrInstructionIdInvalid:
...@@ -23533,6 +23578,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23533,6 +23578,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23533 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);23578 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);
23534 case IrInstructionIdHasDecl:23579 case IrInstructionIdHasDecl:
23535 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);23580 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
23581 case IrInstructionIdUndeclaredIdent:
23582 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
23536 }23583 }
23537 zig_unreachable();23584 zig_unreachable();
23538}23585}
...@@ -23667,6 +23714,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -23667,6 +23714,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
23667 case IrInstructionIdAssertNonNull:23714 case IrInstructionIdAssertNonNull:
23668 case IrInstructionIdResizeSlice:23715 case IrInstructionIdResizeSlice:
23669 case IrInstructionIdGlobalAsm:23716 case IrInstructionIdGlobalAsm:
23717 case IrInstructionIdUndeclaredIdent:
23670 return true;23718 return true;
2367123719
23672 case IrInstructionIdPhi:23720 case IrInstructionIdPhi:
src/ir_print.cpp+7
...@@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) {...@@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) {
1461 fprintf(irp->f, ")");1461 fprintf(irp->f, ")");
1462}1462}
14631463
1464static void ir_print_undeclared_ident(IrPrint *irp, IrInstructionUndeclaredIdent *instruction) {
1465 fprintf(irp->f, "@undeclaredIdent(%s)", buf_ptr(instruction->name));
1466}
1467
1464static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1468static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1465 ir_print_prefix(irp, instruction);1469 ir_print_prefix(irp, instruction);
1466 switch (instruction->id) {1470 switch (instruction->id) {
...@@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1931 case IrInstructionIdHasDecl:1935 case IrInstructionIdHasDecl:
1932 ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction);1936 ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction);
1933 break;1937 break;
1938 case IrInstructionIdUndeclaredIdent:
1939 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
1940 break;
1934 }1941 }
1935 fprintf(irp->f, "\n");1942 fprintf(irp->f, "\n");
1936}1943}
src/link.cpp+33-30
...@@ -25,7 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou...@@ -25,7 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou
25 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,25 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
26 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());26 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());
27 child_gen->disable_gen_h = true;27 child_gen->disable_gen_h = true;
28 child_gen->disable_stack_probing = true;28 child_gen->want_stack_check = WantStackCheckDisabled;
29 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;29 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
30 child_gen->verbose_ast = parent_gen->verbose_ast;30 child_gen->verbose_ast = parent_gen->verbose_ast;
31 child_gen->verbose_link = parent_gen->verbose_link;31 child_gen->verbose_link = parent_gen->verbose_link;
...@@ -528,9 +528,6 @@ static const char *build_musl(CodeGen *parent) {...@@ -528,9 +528,6 @@ static const char *build_musl(CodeGen *parent) {
528 Buf noextbasename = BUF_INIT;528 Buf noextbasename = BUF_INIT;
529 Buf dirbasename = BUF_INIT;529 Buf dirbasename = BUF_INIT;
530 Buf before_arch_dir = BUF_INIT;530 Buf before_arch_dir = BUF_INIT;
531 Buf override_c = BUF_INIT;
532 Buf override_s = BUF_INIT;
533 Buf override_S = BUF_INIT;
534531
535 auto source_it = source_table.entry_iterator();532 auto source_it = source_table.entry_iterator();
536 for (;;) {533 for (;;) {
...@@ -543,31 +540,37 @@ static const char *build_musl(CodeGen *parent) {...@@ -543,31 +540,37 @@ static const char *build_musl(CodeGen *parent) {
543 os_path_split(src_file, &dirname, &basename);540 os_path_split(src_file, &dirname, &basename);
544 os_path_extname(&basename, &noextbasename, nullptr);541 os_path_extname(&basename, &noextbasename, nullptr);
545 os_path_split(&dirname, &before_arch_dir, &dirbasename);542 os_path_split(&dirname, &before_arch_dir, &dirbasename);
543
544 bool is_arch_specific = false;
545 // Architecture-specific implementations are under a <arch>/ folder.
546 if (is_musl_arch_name(buf_ptr(&dirbasename))) {546 if (is_musl_arch_name(buf_ptr(&dirbasename))) {
547 // We find these by explicitly looking for overrides.547 // Not the architecture we're compiling for.
548 continue;548 if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0)
549 continue;
550 is_arch_specific = true;
549 }551 }
550 // Look for an arch specific override.552
551 buf_resize(&override_c, 0);553 if (!is_arch_specific) {
552 buf_resize(&override_s, 0);554 Buf override_path = BUF_INIT;
553 buf_resize(&override_S, 0);555
554556 // Look for an arch specific override.
555 buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c",557 buf_resize(&override_path, 0);
556 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));558 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s",
557 buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s",559 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
558 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));560 if (source_table.maybe_get(&override_path) != nullptr)
559 buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S",561 continue;
560 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));562
561563 buf_resize(&override_path, 0);
562 if (source_table.maybe_get(&override_c) != nullptr) {564 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S",
563 src_file = &override_c;565 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
564 src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind;566 if (source_table.maybe_get(&override_path) != nullptr)
565 } else if (source_table.maybe_get(&override_s) != nullptr) {567 continue;
566 src_file = &override_s;568
567 src_kind = MuslSrcAsm;569 buf_resize(&override_path, 0);
568 } else if (source_table.maybe_get(&override_S) != nullptr) {570 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c",
569 src_file = &override_S;571 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
570 src_kind = MuslSrcAsm;572 if (source_table.maybe_get(&override_path) != nullptr)
573 continue;
571 }574 }
572575
573 Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",576 Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
...@@ -1225,7 +1228,7 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {...@@ -1225,7 +1228,7 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) {
1225 lj->args.append(get_libc_file(g->libc, "libmingwex.a"));1228 lj->args.append(get_libc_file(g->libc, "libmingwex.a"));
1226 lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));1229 lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));
12271230
1228 if (g->subsystem == TargetSubsystemWindows) {1231 if (detect_subsystem(g) == TargetSubsystemWindows) {
1229 lj->args.append(get_libc_file(g->libc, "libgdi32.a"));1232 lj->args.append(get_libc_file(g->libc, "libgdi32.a"));
1230 lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));1233 lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));
1231 }1234 }
...@@ -1307,7 +1310,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -1307,7 +1310,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
1307 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));1310 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
1308 }1311 }
13091312
1310 switch (g->subsystem) {1313 switch (detect_subsystem(g)) {
1311 case TargetSubsystemAuto:1314 case TargetSubsystemAuto:
1312 if (g->zig_target->os == OsUefi) {1315 if (g->zig_target->os == OsUefi) {
1313 add_uefi_link_args(lj);1316 add_uefi_link_args(lj);
...@@ -1471,7 +1474,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {...@@ -1471,7 +1474,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
1471 platform->kind = IPhoneOS;1474 platform->kind = IPhoneOS;
1472 } else if (g->zig_target->os == OsMacOSX) {1475 } else if (g->zig_target->os == OsMacOSX) {
1473 platform->kind = MacOS;1476 platform->kind = MacOS;
1474 g->mmacosx_version_min = buf_create_from_str("10.10");1477 g->mmacosx_version_min = buf_create_from_str("10.14");
1475 } else {1478 } else {
1476 zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");1479 zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");
1477 }1480 }
src/main.cpp+19-5
...@@ -55,7 +55,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -55,7 +55,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
55 " --disable-gen-h do not generate a C header file (.h)\n"55 " --disable-gen-h do not generate a C header file (.h)\n"
56 " --disable-valgrind omit valgrind client requests in debug builds\n"56 " --disable-valgrind omit valgrind client requests in debug builds\n"
57 " --enable-valgrind include valgrind client requests release builds\n"57 " --enable-valgrind include valgrind client requests release builds\n"
58 " --disable-stack-probing workaround for macosx\n"58 " -fstack-check enable stack probing in unsafe builds\n"
59 " -fno-stack-check disable stack probing in safe builds\n"
59 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"60 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
60 " -fPIC enable Position Independent Code\n"61 " -fPIC enable Position Independent Code\n"
61 " -fno-PIC disable Position Independent Code\n"62 " -fno-PIC disable Position Independent Code\n"
...@@ -443,12 +444,12 @@ int main(int argc, char **argv) {...@@ -443,12 +444,12 @@ int main(int argc, char **argv) {
443 bool want_single_threaded = false;444 bool want_single_threaded = false;
444 bool disable_gen_h = false;445 bool disable_gen_h = false;
445 bool bundle_compiler_rt = false;446 bool bundle_compiler_rt = false;
446 bool disable_stack_probing = false;
447 Buf *override_std_dir = nullptr;447 Buf *override_std_dir = nullptr;
448 Buf *override_lib_dir = nullptr;448 Buf *override_lib_dir = nullptr;
449 Buf *main_pkg_path = nullptr;449 Buf *main_pkg_path = nullptr;
450 ValgrindSupport valgrind_support = ValgrindSupportAuto;450 ValgrindSupport valgrind_support = ValgrindSupportAuto;
451 WantPIC want_pic = WantPICAuto;451 WantPIC want_pic = WantPICAuto;
452 WantStackCheck want_stack_check = WantStackCheckAuto;
452453
453 ZigList<const char *> llvm_argv = {0};454 ZigList<const char *> llvm_argv = {0};
454 llvm_argv.append("zig (LLVM option parsing)");455 llvm_argv.append("zig (LLVM option parsing)");
...@@ -648,6 +649,10 @@ int main(int argc, char **argv) {...@@ -648,6 +649,10 @@ int main(int argc, char **argv) {
648 want_pic = WantPICEnabled;649 want_pic = WantPICEnabled;
649 } else if (strcmp(arg, "-fno-PIC") == 0) {650 } else if (strcmp(arg, "-fno-PIC") == 0) {
650 want_pic = WantPICDisabled;651 want_pic = WantPICDisabled;
652 } else if (strcmp(arg, "-fstack-check") == 0) {
653 want_stack_check = WantStackCheckEnabled;
654 } else if (strcmp(arg, "-fno-stack-check") == 0) {
655 want_stack_check = WantStackCheckDisabled;
651 } else if (strcmp(arg, "--system-linker-hack") == 0) {656 } else if (strcmp(arg, "--system-linker-hack") == 0) {
652 system_linker_hack = true;657 system_linker_hack = true;
653 } else if (strcmp(arg, "--single-threaded") == 0) {658 } else if (strcmp(arg, "--single-threaded") == 0) {
...@@ -656,8 +661,6 @@ int main(int argc, char **argv) {...@@ -656,8 +661,6 @@ int main(int argc, char **argv) {
656 disable_gen_h = true;661 disable_gen_h = true;
657 } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {662 } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
658 bundle_compiler_rt = true;663 bundle_compiler_rt = true;
659 } else if (strcmp(arg, "--disable-stack-probing") == 0) {
660 disable_stack_probing = true;
661 } else if (strcmp(arg, "--test-cmd-bin") == 0) {664 } else if (strcmp(arg, "--test-cmd-bin") == 0) {
662 test_exec_args.append(nullptr);665 test_exec_args.append(nullptr);
663 } else if (arg[1] == 'L' && arg[2] != 0) {666 } else if (arg[1] == 'L' && arg[2] != 0) {
...@@ -951,8 +954,10 @@ int main(int argc, char **argv) {...@@ -951,8 +954,10 @@ int main(int argc, char **argv) {
951 case CmdBuiltin: {954 case CmdBuiltin: {
952 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,955 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
953 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);956 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
957 g->subsystem = subsystem;
954 g->valgrind_support = valgrind_support;958 g->valgrind_support = valgrind_support;
955 g->want_pic = want_pic;959 g->want_pic = want_pic;
960 g->want_stack_check = want_stack_check;
956 g->want_single_threaded = want_single_threaded;961 g->want_single_threaded = want_single_threaded;
957 Buf *builtin_source = codegen_generate_builtin_source(g);962 Buf *builtin_source = codegen_generate_builtin_source(g);
958 if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {963 if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
...@@ -981,6 +986,9 @@ int main(int argc, char **argv) {...@@ -981,6 +986,9 @@ int main(int argc, char **argv) {
981 {986 {
982 fprintf(stderr, "Expected source file argument.\n");987 fprintf(stderr, "Expected source file argument.\n");
983 return print_error_usage(arg0);988 return print_error_usage(arg0);
989 } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) {
990 fprintf(stderr, "Cannot run non-executable file.\n");
991 return print_error_usage(arg0);
984 }992 }
985993
986 assert(cmd != CmdBuild || out_type != OutTypeUnknown);994 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
...@@ -1048,6 +1056,7 @@ int main(int argc, char **argv) {...@@ -1048,6 +1056,7 @@ int main(int argc, char **argv) {
1048 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);1056 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
1049 g->valgrind_support = valgrind_support;1057 g->valgrind_support = valgrind_support;
1050 g->want_pic = want_pic;1058 g->want_pic = want_pic;
1059 g->want_stack_check = want_stack_check;
1051 g->subsystem = subsystem;1060 g->subsystem = subsystem;
10521061
1053 g->enable_time_report = timing_info;1062 g->enable_time_report = timing_info;
...@@ -1074,7 +1083,6 @@ int main(int argc, char **argv) {...@@ -1074,7 +1083,6 @@ int main(int argc, char **argv) {
1074 g->output_dir = output_dir;1083 g->output_dir = output_dir;
1075 g->disable_gen_h = disable_gen_h;1084 g->disable_gen_h = disable_gen_h;
1076 g->bundle_compiler_rt = bundle_compiler_rt;1085 g->bundle_compiler_rt = bundle_compiler_rt;
1077 g->disable_stack_probing = disable_stack_probing;
1078 codegen_set_errmsg_color(g, color);1086 codegen_set_errmsg_color(g, color);
1079 g->system_linker_hack = system_linker_hack;1087 g->system_linker_hack = system_linker_hack;
10801088
...@@ -1185,6 +1193,12 @@ int main(int argc, char **argv) {...@@ -1185,6 +1193,12 @@ int main(int argc, char **argv) {
1185 Buf *test_exe_path = buf_alloc();1193 Buf *test_exe_path = buf_alloc();
1186 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);1194 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
11871195
1196 if (emit_file_type != EmitFileTypeBinary) {
1197 fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",
1198 buf_ptr(test_exe_path));
1199 return 0;
1200 }
1201
1188 for (size_t i = 0; i < test_exec_args.length; i += 1) {1202 for (size_t i = 0; i < test_exec_args.length; i += 1) {
1189 if (test_exec_args.items[i] == nullptr) {1203 if (test_exec_args.items[i] == nullptr) {
1190 test_exec_args.items[i] = buf_ptr(test_exe_path);1204 test_exec_args.items[i] = buf_ptr(test_exe_path);
src/parser.cpp+1-1
...@@ -668,7 +668,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {...@@ -668,7 +668,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
668 return res;668 return res;
669 }669 }
670670
671 Token *use = eat_token_if(pc, TokenIdKeywordUse);671 Token *use = eat_token_if(pc, TokenIdKeywordUsingNamespace);
672 if (use != nullptr) {672 if (use != nullptr) {
673 AstNode *expr = ast_expect(pc, ast_parse_expr);673 AstNode *expr = ast_expect(pc, ast_parse_expr);
674 expect_token(pc, TokenIdSemicolon);674 expect_token(pc, TokenIdSemicolon);
src/target.cpp+4
...@@ -1356,6 +1356,10 @@ bool target_supports_fpic(const ZigTarget *target) {...@@ -1356,6 +1356,10 @@ bool target_supports_fpic(const ZigTarget *target) {
1356 return target->os != OsWindows;1356 return target->os != OsWindows;
1357}1357}
13581358
1359bool target_supports_stack_probing(const ZigTarget *target) {
1360 return target->os != OsWindows && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64);
1361}
1362
1359bool target_requires_pic(const ZigTarget *target, bool linking_libc) {1363bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
1360 // This function returns whether non-pic code is completely invalid on the given target.1364 // This function returns whether non-pic code is completely invalid on the given target.
1361 return target->os == OsWindows || target_os_requires_libc(target->os) ||1365 return target->os == OsWindows || target_os_requires_libc(target->os) ||
src/target.hpp+6-1
...@@ -62,7 +62,6 @@ enum SubArchList {...@@ -62,7 +62,6 @@ enum SubArchList {
62};62};
6363
64enum TargetSubsystem {64enum TargetSubsystem {
65 TargetSubsystemAuto, // Zig should infer the subsystem
66 TargetSubsystemConsole,65 TargetSubsystemConsole,
67 TargetSubsystemWindows,66 TargetSubsystemWindows,
68 TargetSubsystemPosix,67 TargetSubsystemPosix,
...@@ -71,6 +70,11 @@ enum TargetSubsystem {...@@ -71,6 +70,11 @@ enum TargetSubsystem {
71 TargetSubsystemEfiBootServiceDriver,70 TargetSubsystemEfiBootServiceDriver,
72 TargetSubsystemEfiRom,71 TargetSubsystemEfiRom,
73 TargetSubsystemEfiRuntimeDriver,72 TargetSubsystemEfiRuntimeDriver,
73
74 // This means Zig should infer the subsystem.
75 // It's last so that the indexes of other items can line up
76 // with the enum in builtin.zig.
77 TargetSubsystemAuto
74};78};
7579
76struct ZigTarget {80struct ZigTarget {
...@@ -172,6 +176,7 @@ bool target_is_glibc(const ZigTarget *target);...@@ -172,6 +176,7 @@ bool target_is_glibc(const ZigTarget *target);
172bool target_is_musl(const ZigTarget *target);176bool target_is_musl(const ZigTarget *target);
173bool target_is_wasm(const ZigTarget *target);177bool target_is_wasm(const ZigTarget *target);
174bool target_is_single_threaded(const ZigTarget *target);178bool target_is_single_threaded(const ZigTarget *target);
179bool target_supports_stack_probing(const ZigTarget *target);
175180
176uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);181uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
177182
src/tokenizer.cpp+3-2
...@@ -153,7 +153,8 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -153,7 +153,8 @@ static const struct ZigKeyword zig_keywords[] = {
153 {"undefined", TokenIdKeywordUndefined},153 {"undefined", TokenIdKeywordUndefined},
154 {"union", TokenIdKeywordUnion},154 {"union", TokenIdKeywordUnion},
155 {"unreachable", TokenIdKeywordUnreachable},155 {"unreachable", TokenIdKeywordUnreachable},
156 {"use", TokenIdKeywordUse},156 {"use", TokenIdKeywordUsingNamespace},
157 {"usingnamespace", TokenIdKeywordUsingNamespace},
157 {"var", TokenIdKeywordVar},158 {"var", TokenIdKeywordVar},
158 {"volatile", TokenIdKeywordVolatile},159 {"volatile", TokenIdKeywordVolatile},
159 {"while", TokenIdKeywordWhile},160 {"while", TokenIdKeywordWhile},
...@@ -1546,7 +1547,7 @@ const char * token_name(TokenId id) {...@@ -1546,7 +1547,7 @@ const char * token_name(TokenId id) {
1546 case TokenIdKeywordUndefined: return "undefined";1547 case TokenIdKeywordUndefined: return "undefined";
1547 case TokenIdKeywordUnion: return "union";1548 case TokenIdKeywordUnion: return "union";
1548 case TokenIdKeywordUnreachable: return "unreachable";1549 case TokenIdKeywordUnreachable: return "unreachable";
1549 case TokenIdKeywordUse: return "use";1550 case TokenIdKeywordUsingNamespace: return "usingnamespace";
1550 case TokenIdKeywordVar: return "var";1551 case TokenIdKeywordVar: return "var";
1551 case TokenIdKeywordVolatile: return "volatile";1552 case TokenIdKeywordVolatile: return "volatile";
1552 case TokenIdKeywordWhile: return "while";1553 case TokenIdKeywordWhile: return "while";
src/tokenizer.hpp+1-1
...@@ -96,7 +96,7 @@ enum TokenId {...@@ -96,7 +96,7 @@ enum TokenId {
96 TokenIdKeywordUndefined,96 TokenIdKeywordUndefined,
97 TokenIdKeywordUnion,97 TokenIdKeywordUnion,
98 TokenIdKeywordUnreachable,98 TokenIdKeywordUnreachable,
99 TokenIdKeywordUse,99 TokenIdKeywordUsingNamespace,
100 TokenIdKeywordVar,100 TokenIdKeywordVar,
101 TokenIdKeywordVolatile,101 TokenIdKeywordVolatile,
102 TokenIdKeywordWhile,102 TokenIdKeywordWhile,
src/userland.cpp+15
...@@ -42,3 +42,18 @@ int stage2_fmt(int argc, char **argv) {...@@ -42,3 +42,18 @@ int stage2_fmt(int argc, char **argv) {
42 const char *msg = "stage0 called stage2_fmt";42 const char *msg = "stage0 called stage2_fmt";
43 stage2_panic(msg, strlen(msg));43 stage2_panic(msg, strlen(msg));
44}44}
45
46stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) {
47 const char *msg = "stage0 called stage2_DepTokenizer_init";
48 stage2_panic(msg, strlen(msg));
49}
50
51void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) {
52 const char *msg = "stage0 called stage2_DepTokenizer_deinit";
53 stage2_panic(msg, strlen(msg));
54}
55
56stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {
57 const char *msg = "stage0 called stage2_DepTokenizer_next";
58 stage2_panic(msg, strlen(msg));
59}
src/userland.h+33
...@@ -9,6 +9,7 @@...@@ -9,6 +9,7 @@
9#define ZIG_USERLAND_H9#define ZIG_USERLAND_H
1010
11#include <stddef.h>11#include <stddef.h>
12#include <stdint.h>
12#include <stdio.h>13#include <stdio.h>
1314
14#ifdef __cplusplus15#ifdef __cplusplus
...@@ -118,4 +119,36 @@ ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t le...@@ -118,4 +119,36 @@ ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t le
118// ABI warning119// ABI warning
119ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);120ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
120121
122// ABI warning
123struct stage2_DepTokenizer {
124 void *handle;
125};
126
127// ABI warning
128struct stage2_DepNextResult {
129 enum TypeId {
130 error,
131 null,
132 target,
133 prereq,
134 };
135
136 TypeId type_id;
137
138 // when ent == error --> error text
139 // when ent == null --> undefined
140 // when ent == target --> target pathname
141 // when ent == prereq --> prereq pathname
142 const char *textz;
143};
144
145// ABI warning
146ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len);
147
148// ABI warning
149ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
150
151// ABI warning
152ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
153
121#endif154#endif
src/zig_llvm.cpp+10-14
...@@ -318,12 +318,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVM...@@ -318,12 +318,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVM
318 const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,318 const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
319 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)319 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)
320{320{
321 assert(flags == 0);
322 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(321 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
323 reinterpret_cast<DIScope*>(scope),322 reinterpret_cast<DIScope*>(scope),
324 name,323 name,
325 reinterpret_cast<DIFile*>(file),324 reinterpret_cast<DIFile*>(file),
326 line, size_in_bits, align_in_bits, offset_in_bits, DINode::FlagZero,325 line, size_in_bits, align_in_bits, offset_in_bits,
326 static_cast<DINode::DIFlags>(flags),
327 reinterpret_cast<DIType*>(type));327 reinterpret_cast<DIType*>(type));
328 return reinterpret_cast<ZigLLVMDIType*>(di_type);328 return reinterpret_cast<ZigLLVMDIType*>(di_type);
329}329}
...@@ -338,12 +338,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMD...@@ -338,12 +338,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
338 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);338 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
339 fields.push_back(ditype);339 fields.push_back(ditype);
340 }340 }
341 assert(flags == 0);
342 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(341 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
343 reinterpret_cast<DIScope*>(scope),342 reinterpret_cast<DIScope*>(scope),
344 name,343 name,
345 reinterpret_cast<DIFile*>(file),344 reinterpret_cast<DIFile*>(file),
346 line_number, size_in_bits, align_in_bits, DINode::FlagZero,345 line_number, size_in_bits, align_in_bits,
346 static_cast<DINode::DIFlags>(flags),
347 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),347 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
348 run_time_lang, unique_id);348 run_time_lang, unique_id);
349 return reinterpret_cast<ZigLLVMDIType*>(di_type);349 return reinterpret_cast<ZigLLVMDIType*>(di_type);
...@@ -360,12 +360,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVM...@@ -360,12 +360,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVM
360 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);360 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
361 fields.push_back(ditype);361 fields.push_back(ditype);
362 }362 }
363 assert(flags == 0);
364 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(363 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(
365 reinterpret_cast<DIScope*>(scope),364 reinterpret_cast<DIScope*>(scope),
366 name,365 name,
367 reinterpret_cast<DIFile*>(file),366 reinterpret_cast<DIFile*>(file),
368 line_number, size_in_bits, align_in_bits, DINode::FlagZero,367 line_number, size_in_bits, align_in_bits,
368 static_cast<DINode::DIFlags>(flags),
369 reinterpret_cast<DIType*>(derived_from),369 reinterpret_cast<DIType*>(derived_from),
370 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),370 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
371 run_time_lang,371 run_time_lang,
...@@ -426,11 +426,10 @@ ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,...@@ -426,11 +426,10 @@ ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
426 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);426 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
427 types.push_back(ditype);427 types.push_back(ditype);
428 }428 }
429 assert(flags == 0);
430 DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);429 DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
431 DISubroutineType *subroutine_type = dibuilder->createSubroutineType(430 DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
432 dibuilder->getOrCreateTypeArray(types),431 dibuilder->getOrCreateTypeArray(types),
433 DINode::FlagZero);432 static_cast<DINode::DIFlags>(flags));
434 DIType *ditype = subroutine_type;433 DIType *ditype = subroutine_type;
435 return reinterpret_cast<ZigLLVMDIType*>(ditype);434 return reinterpret_cast<ZigLLVMDIType*>(ditype);
436}435}
...@@ -516,7 +515,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,...@@ -516,7 +515,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
516 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,515 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
517 ZigLLVMDIType *type, bool always_preserve, unsigned flags)516 ZigLLVMDIType *type, bool always_preserve, unsigned flags)
518{517{
519 assert(flags == 0);
520 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(518 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(
521 reinterpret_cast<DIScope*>(scope),519 reinterpret_cast<DIScope*>(scope),
522 name,520 name,
...@@ -524,7 +522,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,...@@ -524,7 +522,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
524 line_no,522 line_no,
525 reinterpret_cast<DIType*>(type),523 reinterpret_cast<DIType*>(type),
526 always_preserve,524 always_preserve,
527 DINode::FlagZero);525 static_cast<DINode::DIFlags>(flags));
528 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);526 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
529}527}
530528
...@@ -547,7 +545,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde...@@ -547,7 +545,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde
547 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,545 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
548 ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)546 ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
549{547{
550 assert(flags == 0);
551 assert(arg_no != 0);548 assert(arg_no != 0);
552 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(549 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(
553 reinterpret_cast<DIScope*>(scope),550 reinterpret_cast<DIScope*>(scope),
...@@ -557,7 +554,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde...@@ -557,7 +554,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde
557 line_no,554 line_no,
558 reinterpret_cast<DIType*>(type),555 reinterpret_cast<DIType*>(type),
559 always_preserve,556 always_preserve,
560 DINode::FlagZero);557 static_cast<DINode::DIFlags>(flags));
561 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);558 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
562}559}
563560
...@@ -612,7 +609,6 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD...@@ -612,7 +609,6 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
612 unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)609 unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)
613{610{
614 DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));611 DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));
615 assert(flags == 0);
616 DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(612 DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
617 reinterpret_cast<DIScope*>(scope),613 reinterpret_cast<DIScope*>(scope),
618 name, linkage_name,614 name, linkage_name,
...@@ -620,7 +616,7 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD...@@ -620,7 +616,7 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
620 lineno,616 lineno,
621 di_sub_type,617 di_sub_type,
622 scope_line,618 scope_line,
623 DINode::FlagStaticMember,619 static_cast<DINode::DIFlags>(flags),
624 DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized),620 DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized),
625 nullptr,621 nullptr,
626 reinterpret_cast<DISubprogram *>(decl_subprogram),622 reinterpret_cast<DISubprogram *>(decl_subprogram),
src/zig_llvm.h+33
...@@ -406,6 +406,39 @@ enum ZigLLVM_ObjectFormatType {...@@ -406,6 +406,39 @@ enum ZigLLVM_ObjectFormatType {
406 ZigLLVM_Wasm,406 ZigLLVM_Wasm,
407};407};
408408
409#define ZigLLVM_DIFlags_Zero 0U
410#define ZigLLVM_DIFlags_Private 1U
411#define ZigLLVM_DIFlags_Protected 2U
412#define ZigLLVM_DIFlags_Public 3U
413#define ZigLLVM_DIFlags_FwdDecl (1U << 2)
414#define ZigLLVM_DIFlags_AppleBlock (1U << 3)
415#define ZigLLVM_DIFlags_BlockByrefStruct (1U << 4)
416#define ZigLLVM_DIFlags_Virtual (1U << 5)
417#define ZigLLVM_DIFlags_Artificial (1U << 6)
418#define ZigLLVM_DIFlags_Explicit (1U << 7)
419#define ZigLLVM_DIFlags_Prototyped (1U << 8)
420#define ZigLLVM_DIFlags_ObjcClassComplete (1U << 9)
421#define ZigLLVM_DIFlags_ObjectPointer (1U << 10)
422#define ZigLLVM_DIFlags_Vector (1U << 11)
423#define ZigLLVM_DIFlags_StaticMember (1U << 12)
424#define ZigLLVM_DIFlags_LValueReference (1U << 13)
425#define ZigLLVM_DIFlags_RValueReference (1U << 14)
426#define ZigLLVM_DIFlags_Reserved (1U << 15)
427#define ZigLLVM_DIFlags_SingleInheritance (1U << 16)
428#define ZigLLVM_DIFlags_MultipleInheritance (2 << 16)
429#define ZigLLVM_DIFlags_VirtualInheritance (3 << 16)
430#define ZigLLVM_DIFlags_IntroducedVirtual (1U << 18)
431#define ZigLLVM_DIFlags_BitField (1U << 19)
432#define ZigLLVM_DIFlags_NoReturn (1U << 20)
433#define ZigLLVM_DIFlags_TypePassByValue (1U << 22)
434#define ZigLLVM_DIFlags_TypePassByReference (1U << 23)
435#define ZigLLVM_DIFlags_EnumClass (1U << 24)
436#define ZigLLVM_DIFlags_Thunk (1U << 25)
437#define ZigLLVM_DIFlags_NonTrivial (1U << 26)
438#define ZigLLVM_DIFlags_BigEndian (1U << 27)
439#define ZigLLVM_DIFlags_LittleEndian (1U << 28)
440#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29)
441
409ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);442ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
410ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);443ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
411ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);444ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
std/build.zig+19-1
...@@ -877,6 +877,13 @@ pub const Target = union(enum) {...@@ -877,6 +877,13 @@ pub const Target = union(enum) {
877 };877 };
878 }878 }
879879
880 pub fn getArch(self: Target) builtin.Arch {
881 switch (self) {
882 Target.Native => return builtin.arch,
883 Target.Cross => |t| return t.arch,
884 }
885 }
886
880 pub fn isDarwin(self: Target) bool {887 pub fn isDarwin(self: Target) bool {
881 return switch (self.getOs()) {888 return switch (self.getOs()) {
882 .ios, .macosx, .watchos, .tvos => true,889 .ios, .macosx, .watchos, .tvos => true,
...@@ -891,6 +898,13 @@ pub const Target = union(enum) {...@@ -891,6 +898,13 @@ pub const Target = union(enum) {
891 };898 };
892 }899 }
893900
901 pub fn isWasm(self: Target) bool {
902 return switch (self.getArch()) {
903 .wasm32, .wasm64 => true,
904 else => false,
905 };
906 }
907
894 pub fn isFreeBSD(self: Target) bool {908 pub fn isFreeBSD(self: Target) bool {
895 return switch (self.getOs()) {909 return switch (self.getOs()) {
896 .freebsd => true,910 .freebsd => true,
...@@ -1080,7 +1094,11 @@ pub const LibExeObjStep = struct {...@@ -1080,7 +1094,11 @@ pub const LibExeObjStep = struct {
1080 self.out_filename = self.builder.fmt("{}.lib", self.name);1094 self.out_filename = self.builder.fmt("{}.lib", self.name);
1081 },1095 },
1082 else => {1096 else => {
1083 self.out_filename = self.builder.fmt("lib{}.a", self.name);1097 if (self.target.isWasm()) {
1098 self.out_filename = self.builder.fmt("{}.wasm", self.name);
1099 } else {
1100 self.out_filename = self.builder.fmt("lib{}.a", self.name);
1101 }
1084 },1102 },
1085 }1103 }
1086 self.out_lib_filename = self.out_filename;1104 self.out_lib_filename = self.out_filename;
std/c.zig+2-2
...@@ -2,9 +2,9 @@ const builtin = @import("builtin");...@@ -2,9 +2,9 @@ const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
3const page_size = std.mem.page_size;3const page_size = std.mem.page_size;
44
5pub use @import("os/bits.zig");5pub usingnamespace @import("os/bits.zig");
66
7pub use switch (builtin.os) {7pub usingnamespace switch (builtin.os) {
8 .linux => @import("c/linux.zig"),8 .linux => @import("c/linux.zig"),
9 .windows => @import("c/windows.zig"),9 .windows => @import("c/windows.zig"),
10 .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),10 .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),
std/c/darwin.zig+3-1
...@@ -3,7 +3,7 @@ const assert = std.debug.assert;...@@ -3,7 +3,7 @@ const assert = std.debug.assert;
3const builtin = @import("builtin");3const builtin = @import("builtin");
4const macho = std.macho;4const macho = std.macho;
55
6use @import("../os/bits.zig");6usingnamespace @import("../os/bits.zig");
77
8extern "c" fn __error() *c_int;8extern "c" fn __error() *c_int;
9pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;9pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
...@@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t...@@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t
54pub fn sigaddset(set: *sigset_t, signo: u5) void {54pub fn sigaddset(set: *sigset_t, signo: u5) void {
55 set.* |= u32(1) << (signo - 1);55 set.* |= u32(1) << (signo - 1);
56}56}
57
58pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
std/c/freebsd.zig+4
...@@ -1,4 +1,8 @@...@@ -1,4 +1,8 @@
1const std = @import("../std.zig");
2usingnamespace std.c;
3
1extern "c" fn __error() *c_int;4extern "c" fn __error() *c_int;
2pub const _errno = __error;5pub const _errno = __error;
36
4pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
std/c/linux.zig+4-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2use std.c;2usingnamespace std.c;
33
4extern "c" fn __errno_location() *c_int;4extern "c" fn __errno_location() *c_int;
5pub const _errno = __errno_location;5pub const _errno = __errno_location;
...@@ -7,7 +7,7 @@ pub const _errno = __errno_location;...@@ -7,7 +7,7 @@ pub const _errno = __errno_location;
7pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;7pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
8pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;8pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
9pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;9pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
10pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: *epoll_event) c_int;10pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int;
11pub extern "c" fn epoll_create1(flags: c_uint) c_int;11pub extern "c" fn epoll_create1(flags: c_uint) c_int;
12pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int;12pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int;
13pub extern "c" fn epoll_pwait(13pub extern "c" fn epoll_pwait(
...@@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong;...@@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
2525
26pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;26pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
27pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;27pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
28
29pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
std/c/netbsd.zig+4
...@@ -1,4 +1,8 @@...@@ -1,4 +1,8 @@
1const std = @import("../std.zig");
2usingnamespace std.c;
3
1extern "c" fn __errno() *c_int;4extern "c" fn __errno() *c_int;
2pub const _errno = __errno;5pub const _errno = __errno;
36
4pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
std/dynamic_library.zig+6-7
...@@ -104,17 +104,18 @@ pub const LinuxDynLib = struct {...@@ -104,17 +104,18 @@ pub const LinuxDynLib = struct {
104 memory: []align(mem.page_size) u8,104 memory: []align(mem.page_size) u8,
105105
106 /// Trusts the file106 /// Trusts the file
107 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {107 pub fn open(path: []const u8) !DynLib {
108 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);108 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);
109 errdefer os.close(fd);109 errdefer os.close(fd);
110110
111 // TODO remove this @intCast
111 const size = @intCast(usize, (try os.fstat(fd)).size);112 const size = @intCast(usize, (try os.fstat(fd)).size);
112113
113 const bytes = try os.mmap(114 const bytes = try os.mmap(
114 null,115 null,
115 size,116 mem.alignForward(size, mem.page_size),
116 os.PROT_READ | os.PROT_EXEC,117 os.PROT_READ | os.PROT_EXEC,
117 os.MAP_PRIVATE | os.MAP_LOCKED,118 os.MAP_PRIVATE,
118 fd,119 fd,
119 0,120 0,
120 );121 );
...@@ -244,14 +245,12 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [...@@ -244,14 +245,12 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
244}245}
245246
246pub const WindowsDynLib = struct {247pub const WindowsDynLib = struct {
247 allocator: *mem.Allocator,
248 dll: windows.HMODULE,248 dll: windows.HMODULE,
249249
250 pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {250 pub fn open(path: []const u8) !WindowsDynLib {
251 const wpath = try windows.sliceToPrefixedFileW(path);251 const wpath = try windows.sliceToPrefixedFileW(path);
252252
253 return WindowsDynLib{253 return WindowsDynLib{
254 .allocator = allocator,
255 .dll = try windows.LoadLibraryW(&wpath),254 .dll = try windows.LoadLibraryW(&wpath),
256 };255 };
257 }256 }
...@@ -273,7 +272,7 @@ test "dynamic_library" {...@@ -273,7 +272,7 @@ test "dynamic_library" {
273 else => return,272 else => return,
274 };273 };
275274
276 const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| {275 const dynlib = DynLib.open(libname) catch |err| {
277 testing.expect(err == error.FileNotFound);276 testing.expect(err == error.FileNotFound);
278 return;277 return;
279 };278 };
std/event/loop.zig+1-1
...@@ -421,7 +421,7 @@ pub const Loop = struct {...@@ -421,7 +421,7 @@ pub const Loop = struct {
421 }421 }
422422
423 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {423 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {
424 os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};424 os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, null) catch {};
425 self.finishOneEvent();425 self.finishOneEvent();
426 }426 }
427427
std/fmt.zig+9-19
...@@ -145,23 +145,7 @@ pub fn formatType(...@@ -145,23 +145,7 @@ pub fn formatType(
145 return format(context, Errors, output, "promise@{x}", @ptrToInt(value));145 return format(context, Errors, output, "promise@{x}", @ptrToInt(value));
146 },146 },
147 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {147 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
148 const has_cust_fmt = comptime cf: {148 if (comptime std.meta.trait.hasFn("format")(T)) return value.format(fmt, context, Errors, output);
149 const info = @typeInfo(T);
150 const defs = switch (info) {
151 builtin.TypeId.Struct => |s| s.defs,
152 builtin.TypeId.Union => |u| u.defs,
153 builtin.TypeId.Enum => |e| e.defs,
154 else => unreachable,
155 };
156
157 for (defs) |def| {
158 if (mem.eql(u8, def.name, "format")) {
159 break :cf true;
160 }
161 }
162 break :cf false;
163 };
164 if (has_cust_fmt) return value.format(fmt, context, Errors, output);
165149
166 try output(context, @typeName(T));150 try output(context, @typeName(T));
167 switch (comptime @typeId(T)) {151 switch (comptime @typeId(T)) {
...@@ -236,8 +220,10 @@ pub fn formatType(...@@ -236,8 +220,10 @@ pub fn formatType(
236 if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) {220 if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) {
237 return formatText(value, fmt, context, Errors, output);221 return formatText(value, fmt, context, Errors, output);
238 }222 }
239 const casted_value = ([]const u8)(value);223 if (ptr_info.child == u8) {
240 return output(context, casted_value);224 return formatText(value, fmt, context, Errors, output);
225 }
226 return format(context, Errors, output, "{}@{x}", @typeName(ptr_info.child), @ptrToInt(value.ptr));
241 },227 },
242 builtin.TypeInfo.Pointer.Size.C => {228 builtin.TypeInfo.Pointer.Size.C => {
243 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));229 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
...@@ -1025,6 +1011,10 @@ test "fmt.format" {...@@ -1025,6 +1011,10 @@ test "fmt.format" {
1025 const value: []const u8 = "abc";1011 const value: []const u8 = "abc";
1026 try testFmt("slice: abc\n", "slice: {}\n", value);1012 try testFmt("slice: abc\n", "slice: {}\n", value);
1027 }1013 }
1014 {
1015 const value = @intToPtr([*]const []const u8, 0xdeadbeef)[0..0];
1016 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", value);
1017 }
1028 {1018 {
1029 const value = @intToPtr(*i32, 0xdeadbeef);1019 const value = @intToPtr(*i32, 0xdeadbeef);
1030 try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value);1020 try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value);
std/hash_map.zig+16-8
...@@ -139,9 +139,9 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -139,9 +139,9 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
139 // ensure that the hash map will be at most 60% full if139 // ensure that the hash map will be at most 60% full if
140 // expected_count items are put into it140 // expected_count items are put into it
141 var optimized_capacity = expected_count * 5 / 3;141 var optimized_capacity = expected_count * 5 / 3;
142 // round capacity to the next power of two142 // an overflow here would mean the amount of memory required would not
143 const pow = math.log2_int_ceil(usize, optimized_capacity);143 // be representable in the address space
144 return math.pow(usize, 2, pow);144 return math.ceilPowerOfTwo(usize, optimized_capacity) catch unreachable;
145 }145 }
146146
147 /// Increases capacity so that the hash map will be at most147 /// Increases capacity so that the hash map will be at most
...@@ -155,6 +155,8 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -155,6 +155,8 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
155 /// capacity is greater than the current capacity.155 /// capacity is greater than the current capacity.
156 /// New capacity must be a power of two.156 /// New capacity must be a power of two.
157 fn ensureCapacityExact(self: *Self, new_capacity: usize) !void {157 fn ensureCapacityExact(self: *Self, new_capacity: usize) !void {
158 // capacity must always be a power of two to allow for modulo
159 // optimization in the constrainIndex fn
158 const is_power_of_two = new_capacity & (new_capacity - 1) == 0;160 const is_power_of_two = new_capacity & (new_capacity - 1) == 0;
159 assert(is_power_of_two);161 assert(is_power_of_two);
160162
...@@ -209,7 +211,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -209,7 +211,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
209 {211 {
210 var roll_over: usize = 0;212 var roll_over: usize = 0;
211 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {213 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
212 const index = (start_index + roll_over) % hm.entries.len;214 const index = hm.constrainIndex(start_index + roll_over);
213 var entry = &hm.entries[index];215 var entry = &hm.entries[index];
214216
215 if (!entry.used) return null;217 if (!entry.used) return null;
...@@ -218,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -218,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
218220
219 const removed_kv = entry.kv;221 const removed_kv = entry.kv;
220 while (roll_over < hm.entries.len) : (roll_over += 1) {222 while (roll_over < hm.entries.len) : (roll_over += 1) {
221 const next_index = (start_index + roll_over + 1) % hm.entries.len;223 const next_index = hm.constrainIndex(start_index + roll_over + 1);
222 const next_entry = &hm.entries[next_index];224 const next_entry = &hm.entries[next_index];
223 if (!next_entry.used or next_entry.distance_from_start_index == 0) {225 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
224 entry.used = false;226 entry.used = false;
...@@ -301,7 +303,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -301,7 +303,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
301 roll_over += 1;303 roll_over += 1;
302 distance_from_start_index += 1;304 distance_from_start_index += 1;
303 }) {305 }) {
304 const index = (start_index + roll_over) % self.entries.len;306 const index = self.constrainIndex(start_index + roll_over);
305 const entry = &self.entries[index];307 const entry = &self.entries[index];
306308
307 if (entry.used and !eql(entry.kv.key, key)) {309 if (entry.used and !eql(entry.kv.key, key)) {
...@@ -358,7 +360,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -358,7 +360,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
358 {360 {
359 var roll_over: usize = 0;361 var roll_over: usize = 0;
360 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {362 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
361 const index = (start_index + roll_over) % hm.entries.len;363 const index = hm.constrainIndex(start_index + roll_over);
362 const entry = &hm.entries[index];364 const entry = &hm.entries[index];
363365
364 if (!entry.used) return null;366 if (!entry.used) return null;
...@@ -369,7 +371,13 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -369,7 +371,13 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
369 }371 }
370372
371 fn keyToIndex(hm: Self, key: K) usize {373 fn keyToIndex(hm: Self, key: K) usize {
372 return usize(hash(key)) % hm.entries.len;374 return hm.constrainIndex(usize(hash(key)));
375 }
376
377 fn constrainIndex(hm: Self, i: usize) usize {
378 // this is an optimization for modulo of power of two integers;
379 // it requires hm.entries.len to always be a power of two
380 return i & (hm.entries.len - 1);
373 }381 }
374 };382 };
375}383}
std/io.zig+1-1
...@@ -1131,7 +1131,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1131,7 +1131,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1131 }1131 }
11321132
1133 pub fn alignToByte(self: *Self) void {1133 pub fn alignToByte(self: *Self) void {
1134 if (!is_packed) return;1134 if (packing == .Byte) return;
1135 self.in_stream.alignToByte();1135 self.in_stream.alignToByte();
1136 }1136 }
11371137
std/io/test.zig+1
...@@ -417,6 +417,7 @@ fn testIntSerializerDeserializerInfNaN(...@@ -417,6 +417,7 @@ fn testIntSerializerDeserializerInfNaN(
417 const nan_check_f16 = try deserializer.deserialize(f16);417 const nan_check_f16 = try deserializer.deserialize(f16);
418 const inf_check_f16 = try deserializer.deserialize(f16);418 const inf_check_f16 = try deserializer.deserialize(f16);
419 const nan_check_f32 = try deserializer.deserialize(f32);419 const nan_check_f32 = try deserializer.deserialize(f32);
420 deserializer.alignToByte();
420 const inf_check_f32 = try deserializer.deserialize(f32);421 const inf_check_f32 = try deserializer.deserialize(f32);
421 const nan_check_f64 = try deserializer.deserialize(f64);422 const nan_check_f64 = try deserializer.deserialize(f64);
422 const inf_check_f64 = try deserializer.deserialize(f64);423 const inf_check_f64 = try deserializer.deserialize(f64);
std/math.zig+70-9
...@@ -696,6 +696,76 @@ test "math.floorPowerOfTwo" {...@@ -696,6 +696,76 @@ test "math.floorPowerOfTwo" {
696 comptime testFloorPowerOfTwo();696 comptime testFloorPowerOfTwo();
697}697}
698698
699fn testFloorPowerOfTwo() void {
700 testing.expect(floorPowerOfTwo(u32, 63) == 32);
701 testing.expect(floorPowerOfTwo(u32, 64) == 64);
702 testing.expect(floorPowerOfTwo(u32, 65) == 64);
703 testing.expect(floorPowerOfTwo(u4, 7) == 4);
704 testing.expect(floorPowerOfTwo(u4, 8) == 8);
705 testing.expect(floorPowerOfTwo(u4, 9) == 8);
706}
707
708/// Returns the next power of two (if the value is not already a power of two).
709/// Only unsigned integers can be used. Zero is not an allowed input.
710/// Result is a type with 1 more bit than the input type.
711pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T.bit_count + 1) {
712 comptime assert(@typeId(T) == builtin.TypeId.Int);
713 comptime assert(!T.is_signed);
714 assert(value != 0);
715 comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);
716 comptime const shiftType = std.math.Log2Int(promotedType);
717 return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
718}
719
720/// Returns the next power of two (if the value is not already a power of two).
721/// Only unsigned integers can be used. Zero is not an allowed input.
722/// If the value doesn't fit, returns an error.
723pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {
724 comptime assert(@typeId(T) == builtin.TypeId.Int);
725 comptime assert(!T.is_signed);
726 comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);
727 comptime const overflowBit = promotedType(1) << T.bit_count;
728 var x = ceilPowerOfTwoPromote(T, value);
729 if (overflowBit & x != 0) {
730 return error.Overflow;
731 }
732 return @intCast(T, x);
733}
734
735test "math.ceilPowerOfTwoPromote" {
736 testCeilPowerOfTwoPromote();
737 comptime testCeilPowerOfTwoPromote();
738}
739
740fn testCeilPowerOfTwoPromote() void {
741 testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1));
742 testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2));
743 testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63));
744 testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 64));
745 testing.expectEqual(u33(128), ceilPowerOfTwoPromote(u32, 65));
746 testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 7));
747 testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 8));
748 testing.expectEqual(u6(16), ceilPowerOfTwoPromote(u5, 9));
749 testing.expectEqual(u5(16), ceilPowerOfTwoPromote(u4, 9));
750}
751
752test "math.ceilPowerOfTwo" {
753 try testCeilPowerOfTwo();
754 comptime try testCeilPowerOfTwo();
755}
756
757fn testCeilPowerOfTwo() !void {
758 testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1));
759 testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2));
760 testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63));
761 testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 64));
762 testing.expectEqual(u32(128), try ceilPowerOfTwo(u32, 65));
763 testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 7));
764 testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 8));
765 testing.expectEqual(u5(16), try ceilPowerOfTwo(u5, 9));
766 testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9));
767}
768
699pub fn log2_int(comptime T: type, x: T) Log2Int(T) {769pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
700 assert(x != 0);770 assert(x != 0);
701 return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x));771 return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x));
...@@ -722,15 +792,6 @@ test "std.math.log2_int_ceil" {...@@ -722,15 +792,6 @@ test "std.math.log2_int_ceil" {
722 testing.expect(log2_int_ceil(u32, 10) == 4);792 testing.expect(log2_int_ceil(u32, 10) == 4);
723}793}
724794
725fn testFloorPowerOfTwo() void {
726 testing.expect(floorPowerOfTwo(u32, 63) == 32);
727 testing.expect(floorPowerOfTwo(u32, 64) == 64);
728 testing.expect(floorPowerOfTwo(u32, 65) == 64);
729 testing.expect(floorPowerOfTwo(u4, 7) == 4);
730 testing.expect(floorPowerOfTwo(u4, 8) == 8);
731 testing.expect(floorPowerOfTwo(u4, 9) == 8);
732}
733
734pub fn lossyCast(comptime T: type, value: var) T {795pub fn lossyCast(comptime T: type, value: var) T {
735 switch (@typeInfo(@typeOf(value))) {796 switch (@typeInfo(@typeOf(value))) {
736 builtin.TypeId.Int => return @intToFloat(T, value),797 builtin.TypeId.Int => return @intToFloat(T, value),
std/math/big.zig+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub use @import("big/int.zig");1pub usingnamespace @import("big/int.zig");
2pub use @import("big/rational.zig");2pub usingnamespace @import("big/rational.zig");
33
4test "math.big" {4test "math.big" {
5 _ = @import("big/int.zig");5 _ = @import("big/int.zig");
std/meta.zig+22-22
...@@ -160,16 +160,16 @@ test "std.meta.containerLayout" {...@@ -160,16 +160,16 @@ test "std.meta.containerLayout" {
160 testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);160 testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
161}161}
162162
163pub fn definitions(comptime T: type) []TypeInfo.Definition {163pub fn declarations(comptime T: type) []TypeInfo.Declaration {
164 return switch (@typeInfo(T)) {164 return switch (@typeInfo(T)) {
165 TypeId.Struct => |info| info.defs,165 TypeId.Struct => |info| info.decls,
166 TypeId.Enum => |info| info.defs,166 TypeId.Enum => |info| info.decls,
167 TypeId.Union => |info| info.defs,167 TypeId.Union => |info| info.decls,
168 else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),168 else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
169 };169 };
170}170}
171171
172test "std.meta.definitions" {172test "std.meta.declarations" {
173 const E1 = enum {173 const E1 = enum {
174 A,174 A,
175175
...@@ -184,28 +184,28 @@ test "std.meta.definitions" {...@@ -184,28 +184,28 @@ test "std.meta.definitions" {
184 fn a() void {}184 fn a() void {}
185 };185 };
186186
187 const defs = comptime [][]TypeInfo.Definition{187 const decls = comptime [][]TypeInfo.Declaration{
188 definitions(E1),188 declarations(E1),
189 definitions(S1),189 declarations(S1),
190 definitions(U1),190 declarations(U1),
191 };191 };
192192
193 inline for (defs) |def| {193 inline for (decls) |decl| {
194 testing.expect(def.len == 1);194 testing.expect(decl.len == 1);
195 testing.expect(comptime mem.eql(u8, def[0].name, "a"));195 testing.expect(comptime mem.eql(u8, decl[0].name, "a"));
196 }196 }
197}197}
198198
199pub fn definitionInfo(comptime T: type, comptime def_name: []const u8) TypeInfo.Definition {199pub fn declarationInfo(comptime T: type, comptime decl_name: []const u8) TypeInfo.Declaration {
200 inline for (comptime definitions(T)) |def| {200 inline for (comptime declarations(T)) |decl| {
201 if (comptime mem.eql(u8, def.name, def_name))201 if (comptime mem.eql(u8, decl.name, decl_name))
202 return def;202 return decl;
203 }203 }
204204
205 @compileError("'" ++ @typeName(T) ++ "' has no definition '" ++ def_name ++ "'");205 @compileError("'" ++ @typeName(T) ++ "' has no declaration '" ++ decl_name ++ "'");
206}206}
207207
208test "std.meta.definitionInfo" {208test "std.meta.declarationInfo" {
209 const E1 = enum {209 const E1 = enum {
210 A,210 A,
211211
...@@ -220,10 +220,10 @@ test "std.meta.definitionInfo" {...@@ -220,10 +220,10 @@ test "std.meta.definitionInfo" {
220 fn a() void {}220 fn a() void {}
221 };221 };
222222
223 const infos = comptime []TypeInfo.Definition{223 const infos = comptime []TypeInfo.Declaration{
224 definitionInfo(E1, "a"),224 declarationInfo(E1, "a"),
225 definitionInfo(S1, "a"),225 declarationInfo(S1, "a"),
226 definitionInfo(U1, "a"),226 declarationInfo(U1, "a"),
227 };227 };
228228
229 inline for (infos) |info| {229 inline for (infos) |info| {
std/meta/trait.zig+5-43
...@@ -55,53 +55,15 @@ test "std.meta.trait.multiTrait" {...@@ -55,53 +55,15 @@ test "std.meta.trait.multiTrait" {
55 testing.expect(!isVector(u8));55 testing.expect(!isVector(u8));
56}56}
5757
58///
59pub fn hasDef(comptime name: []const u8) TraitFn {
60 const Closure = struct {
61 pub fn trait(comptime T: type) bool {
62 const info = @typeInfo(T);
63 const defs = switch (info) {
64 builtin.TypeId.Struct => |s| s.defs,
65 builtin.TypeId.Union => |u| u.defs,
66 builtin.TypeId.Enum => |e| e.defs,
67 else => return false,
68 };
69
70 inline for (defs) |def| {
71 if (mem.eql(u8, def.name, name)) return def.is_pub;
72 }
73
74 return false;
75 }
76 };
77 return Closure.trait;
78}
79
80test "std.meta.trait.hasDef" {
81 const TestStruct = struct {
82 pub const value = u8(16);
83 };
84
85 const TestStructFail = struct {
86 const value = u8(16);
87 };
88
89 testing.expect(hasDef("value")(TestStruct));
90 testing.expect(!hasDef("value")(TestStructFail));
91 testing.expect(!hasDef("value")(*TestStruct));
92 testing.expect(!hasDef("value")(**TestStructFail));
93 testing.expect(!hasDef("x")(TestStruct));
94 testing.expect(!hasDef("value")(u8));
95}
96
97///58///
98pub fn hasFn(comptime name: []const u8) TraitFn {59pub fn hasFn(comptime name: []const u8) TraitFn {
99 const Closure = struct {60 const Closure = struct {
100 pub fn trait(comptime T: type) bool {61 pub fn trait(comptime T: type) bool {
101 if (!comptime hasDef(name)(T)) return false;62 if (!comptime isContainer(T)) return false;
102 const DefType = @typeOf(@field(T, name));63 if (!comptime @hasDecl(T, name)) return false;
103 const def_type_id = @typeId(DefType);64 const DeclType = @typeOf(@field(T, name));
104 return def_type_id == builtin.TypeId.Fn;65 const decl_type_id = @typeId(DeclType);
66 return decl_type_id == builtin.TypeId.Fn;
105 }67 }
106 };68 };
107 return Closure.trait;69 return Closure.trait;
std/os.zig+102-6
...@@ -19,6 +19,8 @@ const builtin = @import("builtin");...@@ -19,6 +19,8 @@ const builtin = @import("builtin");
19const assert = std.debug.assert;19const assert = std.debug.assert;
20const math = std.math;20const math = std.math;
21const mem = std.mem;21const mem = std.mem;
22const elf = std.elf;
23const dl = @import("dynamic_library.zig");
22const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;24const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
2325
24comptime {26comptime {
...@@ -46,7 +48,7 @@ pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {...@@ -46,7 +48,7 @@ pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
46 else => struct {},48 else => struct {},
47};49};
4850
49pub use @import("os/bits.zig");51pub usingnamespace @import("os/bits.zig");
5052
51/// See also `getenv`. Populated by startup code before main().53/// See also `getenv`. Populated by startup code before main().
52pub var environ: [][*]u8 = undefined;54pub var environ: [][*]u8 = undefined;
...@@ -1509,7 +1511,7 @@ pub const EpollCtlError = error{...@@ -1509,7 +1511,7 @@ pub const EpollCtlError = error{
1509 Unexpected,1511 Unexpected,
1510};1512};
15111513
1512pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: *epoll_event) EpollCtlError!void {1514pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*epoll_event) EpollCtlError!void {
1513 const rc = system.epoll_ctl(epfd, op, fd, event);1515 const rc = system.epoll_ctl(epfd, op, fd, event);
1514 switch (errno(rc)) {1516 switch (errno(rc)) {
1515 0 => return,1517 0 => return,
...@@ -1883,20 +1885,29 @@ pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {...@@ -1883,20 +1885,29 @@ pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {
1883}1885}
18841886
1885pub const MProtectError = error{1887pub const MProtectError = error{
1888 /// The memory cannot be given the specified access. This can happen, for example, if you
1889 /// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it
1890 /// PROT_WRITE.
1886 AccessDenied,1891 AccessDenied,
1892
1893 /// Changing the protection of a memory region would result in the total number of map‐
1894 /// pings with distinct attributes (e.g., read versus read/write protection) exceeding the
1895 /// allowed maximum. (For example, making the protection of a range PROT_READ in the mid‐
1896 /// dle of a region currently protected as PROT_READ|PROT_WRITE would result in three map‐
1897 /// pings: two read/write mappings at each end and a read-only mapping in the middle.)
1887 OutOfMemory,1898 OutOfMemory,
1888 Unexpected,1899 Unexpected,
1889};1900};
18901901
1891/// `memory.len` must be page-aligned.1902/// `memory.len` must be page-aligned.
1892pub fn mprotect(memory: [*]align(mem.page_size) u8, protection: u32) MProtectError!void {1903pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void {
1893 assert(mem.isAligned(memory.len, mem.page_size));1904 assert(mem.isAligned(memory.len, mem.page_size));
1894 switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {1905 switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
1895 0 => return,1906 0 => return,
1896 EINVAL => unreachable,1907 EINVAL => unreachable,
1897 EACCES => return error.AccessDenied,1908 EACCES => return error.AccessDenied,
1898 ENOMEM => return error.OutOfMemory,1909 ENOMEM => return error.OutOfMemory,
1899 else => return unexpectedErrno(err),1910 else => |err| return unexpectedErrno(err),
1900 }1911 }
1901}1912}
19021913
...@@ -1935,7 +1946,6 @@ pub const MMapError = error{...@@ -1935,7 +1946,6 @@ pub const MMapError = error{
19351946
1936/// Map files or devices into memory.1947/// Map files or devices into memory.
1937/// Use of a mapped region can result in these signals:1948/// Use of a mapped region can result in these signals:
1938/// `length` must be page-aligned.
1939/// * SIGSEGV - Attempted write into a region mapped as read-only.1949/// * SIGSEGV - Attempted write into a region mapped as read-only.
1940/// * SIGBUS - Attempted access to a portion of the buffer that does not correspond to the file1950/// * SIGBUS - Attempted access to a portion of the buffer that does not correspond to the file
1941pub fn mmap(1951pub fn mmap(
...@@ -1946,7 +1956,6 @@ pub fn mmap(...@@ -1946,7 +1956,6 @@ pub fn mmap(
1946 fd: fd_t,1956 fd: fd_t,
1947 offset: isize,1957 offset: isize,
1948) MMapError![]align(mem.page_size) u8 {1958) MMapError![]align(mem.page_size) u8 {
1949 assert(mem.isAligned(length, mem.page_size));
1950 const err = if (builtin.link_libc) blk: {1959 const err = if (builtin.link_libc) blk: {
1951 const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);1960 const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);
1952 if (rc != MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];1961 if (rc != MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length];
...@@ -2359,6 +2368,70 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {...@@ -2359,6 +2368,70 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
2359 }2368 }
2360}2369}
23612370
2371pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize {
2372 // This is implemented only for systems using ELF executables
2373 if (windows.is_the_target or builtin.os == .uefi or wasi.is_the_target or darwin.is_the_target)
2374 @compileError("dl_iterate_phdr is not available for this target");
2375
2376 if (builtin.link_libc) {
2377 return system.dl_iterate_phdr(
2378 @ptrCast(std.c.dl_iterate_phdr_callback, callback),
2379 @ptrCast(?*c_void, data),
2380 );
2381 }
2382
2383 const elf_base = std.process.getBaseAddress();
2384 const ehdr = @intToPtr(*elf.Ehdr, elf_base);
2385 // Make sure the base address points to an ELF image
2386 assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF"));
2387 const n_phdr = ehdr.e_phnum;
2388 const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr];
2389
2390 var it = dl.linkmap_iterator(phdrs) catch unreachable;
2391
2392 // The executable has no dynamic link segment, create a single entry for
2393 // the whole ELF image
2394 if (it.end()) {
2395 var info = dl_phdr_info{
2396 .dlpi_addr = elf_base,
2397 .dlpi_name = c"/proc/self/exe",
2398 .dlpi_phdr = phdrs.ptr,
2399 .dlpi_phnum = ehdr.e_phnum,
2400 };
2401
2402 return callback(&info, @sizeOf(dl_phdr_info), data);
2403 }
2404
2405 // Last return value from the callback function
2406 var last_r: isize = 0;
2407 while (it.next()) |entry| {
2408 var dlpi_phdr: [*]elf.Phdr = undefined;
2409 var dlpi_phnum: u16 = undefined;
2410
2411 if (entry.l_addr != 0) {
2412 const elf_header = @intToPtr(*elf.Ehdr, entry.l_addr);
2413 dlpi_phdr = @intToPtr([*]elf.Phdr, entry.l_addr + elf_header.e_phoff);
2414 dlpi_phnum = elf_header.e_phnum;
2415 } else {
2416 // This is the running ELF image
2417 dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff);
2418 dlpi_phnum = ehdr.e_phnum;
2419 }
2420
2421 var info = dl_phdr_info{
2422 .dlpi_addr = entry.l_addr,
2423 .dlpi_name = entry.l_name,
2424 .dlpi_phdr = dlpi_phdr,
2425 .dlpi_phnum = dlpi_phnum,
2426 };
2427
2428 last_r = callback(&info, @sizeOf(dl_phdr_info), data);
2429 if (last_r != 0) break;
2430 }
2431
2432 return last_r;
2433}
2434
2362pub const ClockGetTimeError = error{2435pub const ClockGetTimeError = error{
2363 UnsupportedClock,2436 UnsupportedClock,
2364 Unexpected,2437 Unexpected,
...@@ -2433,6 +2506,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError {...@@ -2433,6 +2506,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError {
2433 return error.Unexpected;2506 return error.Unexpected;
2434}2507}
24352508
2509pub const SigaltstackError = error{
2510 /// The supplied stack size was less than MINSIGSTKSZ.
2511 SizeTooSmall,
2512
2513 /// Attempted to change the signal stack while it was active.
2514 PermissionDenied,
2515 Unexpected,
2516};
2517
2518pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
2519 if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target)
2520 @compileError("std.os.sigaltstack not available for this target");
2521
2522 switch (errno(system.sigaltstack(ss, old_ss))) {
2523 0 => return,
2524 EFAULT => unreachable,
2525 EINVAL => unreachable,
2526 ENOMEM => return error.SizeTooSmall,
2527 EPERM => return error.PermissionDenied,
2528 else => |err| return unexpectedErrno(err),
2529 }
2530}
2531
2436test "" {2532test "" {
2437 _ = @import("os/darwin.zig");2533 _ = @import("os/darwin.zig");
2438 _ = @import("os/freebsd.zig");2534 _ = @import("os/freebsd.zig");
std/os/bits.zig+1-1
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
33
4const builtin = @import("builtin");4const builtin = @import("builtin");
55
6pub use switch (builtin.os) {6pub usingnamespace switch (builtin.os) {
7 .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"),7 .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
8 .freebsd => @import("bits/freebsd.zig"),8 .freebsd => @import("bits/freebsd.zig"),
9 .linux => @import("bits/linux.zig"),9 .linux => @import("bits/linux.zig"),
std/os/bits/darwin.zig+12
...@@ -1078,3 +1078,15 @@ pub const EQFULL = 106;...@@ -1078,3 +1078,15 @@ pub const EQFULL = 106;
10781078
1079/// Must be equal largest errno1079/// Must be equal largest errno
1080pub const ELAST = 106;1080pub const ELAST = 106;
1081
1082pub const SIGSTKSZ = 131072;
1083pub const MINSIGSTKSZ = 32768;
1084
1085pub const SS_ONSTACK = 1;
1086pub const SS_DISABLE = 4;
1087
1088pub const stack_t = extern struct {
1089 ss_sp: [*]u8,
1090 ss_size: isize,
1091 ss_flags: i32,
1092};
std/os/bits/freebsd.zig+23
...@@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct {...@@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct {
20 __align: c_long,20 __align: c_long,
21};21};
2222
23pub const dl_phdr_info = extern struct {
24 dlpi_addr: usize,
25 dlpi_name: ?[*]const u8,
26 dlpi_phdr: [*]std.elf.Phdr,
27 dlpi_phnum: u16,
28};
29
23pub const msghdr = extern struct {30pub const msghdr = extern struct {
24 /// optional address31 /// optional address
25 msg_name: ?*sockaddr,32 msg_name: ?*sockaddr,
...@@ -835,3 +842,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable...@@ -835,3 +842,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable
835pub const EOWNERDEAD = 96; // Previous owner died842pub const EOWNERDEAD = 96; // Previous owner died
836843
837pub const ELAST = 96; // Must be equal largest errno844pub const ELAST = 96; // Must be equal largest errno
845
846pub const MINSIGSTKSZ = switch (builtin.arch) {
847 .i386, .x86_64 => 2048,
848 .arm, .aarch64 => 4096,
849 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
850};
851pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
852
853pub const SS_ONSTACK = 1;
854pub const SS_DISABLE = 4;
855
856pub const stack_t = extern struct {
857 ss_sp: [*]u8,
858 ss_size: isize,
859 ss_flags: i32,
860};
std/os/bits/linux.zig+30-9
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("../../std.zig");2const std = @import("../../std.zig");
3const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
4use @import("../bits.zig");4usingnamespace @import("../bits.zig");
55
6pub use @import("linux/errno.zig");6pub usingnamespace @import("linux/errno.zig");
7pub use switch (builtin.arch) {7pub usingnamespace switch (builtin.arch) {
8 .x86_64 => @import("linux/x86_64.zig"),8 .x86_64 => @import("linux/x86_64.zig"),
9 .aarch64 => @import("linux/arm64.zig"),9 .aarch64 => @import("linux/arm64.zig"),
10 else => struct {},10 else => struct {},
...@@ -762,16 +762,16 @@ pub const epoll_data = extern union {...@@ -762,16 +762,16 @@ pub const epoll_data = extern union {
762762
763// On x86_64 the structure is packed so that it matches the definition of its763// On x86_64 the structure is packed so that it matches the definition of its
764// 32bit counterpart764// 32bit counterpart
765pub const epoll_event = if (builtin.arch != .x86_64)765pub const epoll_event = switch (builtin.arch) {
766 extern struct {766 .x86_64 => packed struct {
767 events: u32,767 events: u32,
768 data: epoll_data,768 data: epoll_data,
769 }769 },
770else770 else => extern struct {
771 packed struct {
772 events: u32,771 events: u32,
773 data: epoll_data,772 data: epoll_data,
774 };773 },
774};
775775
776pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;776pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
777pub const _LINUX_CAPABILITY_U32S_1 = 1;777pub const _LINUX_CAPABILITY_U32S_1 = 1;
...@@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {...@@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
929//#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)929//#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
930//#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)930//#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
931//#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)931//#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
932
933pub const MINSIGSTKSZ = switch (builtin.arch) {
934 .i386, .x86_64, .arm => 2048,
935 .aarch64 => 5120,
936 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
937};
938pub const SIGSTKSZ = switch (builtin.arch) {
939 .i386, .x86_64, .arm => 8192,
940 .aarch64 => 16384,
941 else => @compileError("SIGSTKSZ not defined for this architecture"),
942};
943
944pub const SS_ONSTACK = 1;
945pub const SS_DISABLE = 2;
946pub const SS_AUTODISARM = 1 << 31;
947
948pub const stack_t = extern struct {
949 ss_sp: [*]u8,
950 ss_flags: i32,
951 ss_size: isize,
952};
std/os/bits/linux/arm64.zig+5-5
...@@ -299,16 +299,16 @@ pub const O_NONBLOCK = 0o4000;...@@ -299,16 +299,16 @@ pub const O_NONBLOCK = 0o4000;
299pub const O_DSYNC = 0o10000;299pub const O_DSYNC = 0o10000;
300pub const O_SYNC = 0o4010000;300pub const O_SYNC = 0o4010000;
301pub const O_RSYNC = 0o4010000;301pub const O_RSYNC = 0o4010000;
302pub const O_DIRECTORY = 0o200000;302pub const O_DIRECTORY = 0o40000;
303pub const O_NOFOLLOW = 0o400000;303pub const O_NOFOLLOW = 0o100000;
304pub const O_CLOEXEC = 0o2000000;304pub const O_CLOEXEC = 0o2000000;
305305
306pub const O_ASYNC = 0o20000;306pub const O_ASYNC = 0o20000;
307pub const O_DIRECT = 0o40000;307pub const O_DIRECT = 0o200000;
308pub const O_LARGEFILE = 0;308pub const O_LARGEFILE = 0o400000;
309pub const O_NOATIME = 0o1000000;309pub const O_NOATIME = 0o1000000;
310pub const O_PATH = 0o10000000;310pub const O_PATH = 0o10000000;
311pub const O_TMPFILE = 0o20200000;311pub const O_TMPFILE = 0o20040000;
312pub const O_NDELAY = O_NONBLOCK;312pub const O_NDELAY = O_NONBLOCK;
313313
314pub const F_DUPFD = 0;314pub const F_DUPFD = 0;
std/os/bits/netbsd.zig+19
...@@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct {...@@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct {
20 pta_private: *c_void,20 pta_private: *c_void,
21};21};
2222
23pub const dl_phdr_info = extern struct {
24 dlpi_addr: usize,
25 dlpi_name: ?[*]const u8,
26 dlpi_phdr: [*]std.elf.Phdr,
27 dlpi_phnum: u16,
28};
29
23pub const msghdr = extern struct {30pub const msghdr = extern struct {
24 /// optional address31 /// optional address
25 msg_name: ?*sockaddr,32 msg_name: ?*sockaddr,
...@@ -723,3 +730,15 @@ pub const ENOLINK = 95; // Link has been severed...@@ -723,3 +730,15 @@ pub const ENOLINK = 95; // Link has been severed
723pub const EPROTO = 96; // Protocol error730pub const EPROTO = 96; // Protocol error
724731
725pub const ELAST = 96; // Must equal largest errno732pub const ELAST = 96; // Must equal largest errno
733
734pub const MINSIGSTKSZ = 8192;
735pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
736
737pub const SS_ONSTACK = 1;
738pub const SS_DISABLE = 4;
739
740pub const stack_t = extern struct {
741 ss_sp: [*]u8,
742 ss_size: isize,
743 ss_flags: i32,
744};
std/os/bits/windows.zig+1-8
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1// The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).1// The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime).
22
3use @import("../windows/bits.zig");3usingnamespace @import("../windows/bits.zig");
44
5pub const fd_t = HANDLE;5pub const fd_t = HANDLE;
6pub const pid_t = HANDLE;6pub const pid_t = HANDLE;
...@@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140;...@@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140;
158pub const EDQUOT = 10069;158pub const EDQUOT = 10069;
159159
160pub const F_OK = 0;160pub const F_OK = 0;
161
162// These are workarounds for "use of undeclared identifier" compile errors
163// TODO make the compiler even more lazy. don't emit "use of undeclared identifier" errors
164// for if branches that aren't taken.
165pub const SIGKILL = @compileError("Windows libc does not have this");
166
167
std/os/darwin.zig+1-1
...@@ -4,4 +4,4 @@ pub const is_the_target = switch (builtin.os) {...@@ -4,4 +4,4 @@ pub const is_the_target = switch (builtin.os) {
4 .macosx, .tvos, .watchos, .ios => true,4 .macosx, .tvos, .watchos, .ios => true,
5 else => false,5 else => false,
6};6};
7pub use std.c;7pub usingnamespace std.c;
std/os/freebsd.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3pub const is_the_target = builtin.os == .freebsd;3pub const is_the_target = builtin.os == .freebsd;
4pub use std.c;4pub usingnamespace std.c;
std/os/linux.zig+33-21
...@@ -14,12 +14,12 @@ const vdso = @import("linux/vdso.zig");...@@ -14,12 +14,12 @@ const vdso = @import("linux/vdso.zig");
14const dl = @import("../dynamic_library.zig");14const dl = @import("../dynamic_library.zig");
1515
16pub const is_the_target = builtin.os == .linux;16pub const is_the_target = builtin.os == .linux;
17pub use switch (builtin.arch) {17pub usingnamespace switch (builtin.arch) {
18 .x86_64 => @import("linux/x86_64.zig"),18 .x86_64 => @import("linux/x86_64.zig"),
19 .aarch64 => @import("linux/arm64.zig"),19 .aarch64 => @import("linux/arm64.zig"),
20 else => struct {},20 else => struct {},
21};21};
22pub use @import("bits.zig");22pub usingnamespace @import("bits.zig");
23pub const tls = @import("linux/tls.zig");23pub const tls = @import("linux/tls.zig");
2424
25/// Set by startup code, used by `getauxval`.25/// Set by startup code, used by `getauxval`.
...@@ -131,7 +131,7 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz...@@ -131,7 +131,7 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz
131 if (@hasDecl(@This(), "SYS_readlink")) {131 if (@hasDecl(@This(), "SYS_readlink")) {
132 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);132 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
133 } else {133 } else {
134 return syscall4(SYS_readlinkat, AT_FDCWD, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);134 return syscall4(SYS_readlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
135 }135 }
136}136}
137137
...@@ -145,7 +145,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {...@@ -145,7 +145,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {
145 if (@hasDecl(@This(), "SYS_mkdir")) {145 if (@hasDecl(@This(), "SYS_mkdir")) {
146 return syscall2(SYS_mkdir, @ptrToInt(path), mode);146 return syscall2(SYS_mkdir, @ptrToInt(path), mode);
147 } else {147 } else {
148 return syscall3(SYS_mkdirat, AT_FDCWD, @ptrToInt(path), mode);148 return syscall3(SYS_mkdirat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode);
149 }149 }
150}150}
151151
...@@ -206,7 +206,7 @@ pub fn rmdir(path: [*]const u8) usize {...@@ -206,7 +206,7 @@ pub fn rmdir(path: [*]const u8) usize {
206 if (@hasDecl(@This(), "SYS_rmdir")) {206 if (@hasDecl(@This(), "SYS_rmdir")) {
207 return syscall1(SYS_rmdir, @ptrToInt(path));207 return syscall1(SYS_rmdir, @ptrToInt(path));
208 } else {208 } else {
209 return syscall3(SYS_unlinkat, AT_FDCWD, @ptrToInt(path), AT_REMOVEDIR);209 return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);
210 }210 }
211}211}
212212
...@@ -215,7 +215,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {...@@ -215,7 +215,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
215 if (@hasDecl(@This(), "SYS_symlink")) {215 if (@hasDecl(@This(), "SYS_symlink")) {
216 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));216 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
217 } else {217 } else {
218 return syscall3(SYS_symlinkat, @ptrToInt(existing), AT_FDCWD, @ptrToInt(new));218 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));
219 }219 }
220}220}
221221
...@@ -231,12 +231,16 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {...@@ -231,12 +231,16 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
231231
232// TODO https://github.com/ziglang/zig/issues/265232// TODO https://github.com/ziglang/zig/issues/265
233pub fn access(path: [*]const u8, mode: u32) usize {233pub fn access(path: [*]const u8, mode: u32) usize {
234 return syscall2(SYS_access, @ptrToInt(path), mode);234 if (@hasDecl(@This(), "SYS_access")) {
235 return syscall2(SYS_access, @ptrToInt(path), mode);
236 } else {
237 return syscall4(SYS_faccessat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode, 0);
238 }
235}239}
236240
237// TODO https://github.com/ziglang/zig/issues/265241// TODO https://github.com/ziglang/zig/issues/265
238pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize {242pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize {
239 return syscall3(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);243 return syscall4(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode, flags);
240}244}
241245
242pub fn pipe(fd: *[2]i32) usize {246pub fn pipe(fd: *[2]i32) usize {
...@@ -264,9 +268,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {...@@ -264,9 +268,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {
264 if (@hasDecl(@This(), "SYS_rename")) {268 if (@hasDecl(@This(), "SYS_rename")) {
265 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));269 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
266 } else if (@hasDecl(@This(), "SYS_renameat")) {270 } else if (@hasDecl(@This(), "SYS_renameat")) {
267 return syscall4(SYS_renameat, AT_FDCWD, @ptrToInt(old), AT_FDCWD, @ptrToInt(new));271 return syscall4(SYS_renameat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));
268 } else {272 } else {
269 return syscall5(SYS_renameat2, AT_FDCWD, @ptrToInt(old), AT_FDCWD, @ptrToInt(new), 0);273 return syscall5(SYS_renameat2, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new), 0);
270 }274 }
271}275}
272276
...@@ -305,7 +309,17 @@ pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const...@@ -305,7 +309,17 @@ pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
305309
306// TODO https://github.com/ziglang/zig/issues/265310// TODO https://github.com/ziglang/zig/issues/265
307pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {311pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
308 return syscall3(SYS_open, @ptrToInt(path), flags, perm);312 if (@hasDecl(@This(), "SYS_open")) {
313 return syscall3(SYS_open, @ptrToInt(path), flags, perm);
314 } else {
315 return syscall4(
316 SYS_openat,
317 @bitCast(usize, isize(AT_FDCWD)),
318 @ptrToInt(path),
319 flags,
320 perm,
321 );
322 }
309}323}
310324
311// TODO https://github.com/ziglang/zig/issues/265325// TODO https://github.com/ziglang/zig/issues/265
...@@ -373,7 +387,7 @@ pub fn unlink(path: [*]const u8) usize {...@@ -373,7 +387,7 @@ pub fn unlink(path: [*]const u8) usize {
373 if (@hasDecl(@This(), "SYS_unlink")) {387 if (@hasDecl(@This(), "SYS_unlink")) {
374 return syscall1(SYS_unlink, @ptrToInt(path));388 return syscall1(SYS_unlink, @ptrToInt(path));
375 } else {389 } else {
376 return syscall3(SYS_unlinkat, AT_FDCWD, @ptrToInt(path), 0);390 return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), 0);
377 }391 }
378}392}
379393
...@@ -759,18 +773,12 @@ pub fn epoll_create1(flags: usize) usize {...@@ -759,18 +773,12 @@ pub fn epoll_create1(flags: usize) usize {
759 return syscall1(SYS_epoll_create1, flags);773 return syscall1(SYS_epoll_create1, flags);
760}774}
761775
762pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {776pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: ?*epoll_event) usize {
763 return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));777 return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));
764}778}
765779
766pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {780pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
767 return syscall4(781 return epoll_pwait(epoll_fd, events, maxevents, timeout, null);
768 SYS_epoll_wait,
769 @bitCast(usize, isize(epoll_fd)),
770 @ptrToInt(events),
771 maxevents,
772 @bitCast(usize, isize(timeout)),
773 );
774}782}
775783
776pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {784pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {
...@@ -818,6 +826,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize {...@@ -818,6 +826,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize {
818 return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap));826 return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap));
819}827}
820828
829pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize {
830 return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss));
831}
832
821// XXX: This should be weak833// XXX: This should be weak
822extern const __ehdr_start: elf.Ehdr = undefined;834extern const __ehdr_start: elf.Ehdr = undefined;
823835
std/os/linux/test.zig-39
...@@ -44,42 +44,3 @@ test "timer" {...@@ -44,42 +44,3 @@ test "timer" {
44 // TODO implicit cast from *[N]T to [*]T44 // TODO implicit cast from *[N]T to [*]T
45 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);45 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
46}46}
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/x86_64.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1use @import("../bits.zig");1usingnamespace @import("../bits.zig");
22
3pub fn syscall0(number: usize) usize {3pub fn syscall0(number: usize) usize {
4 return asm volatile ("syscall"4 return asm volatile ("syscall"
std/os/netbsd.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("../std.zig");2const std = @import("../std.zig");
3pub const is_the_target = builtin.os == .netbsd;3pub const is_the_target = builtin.os == .netbsd;
4pub use std.c;4pub usingnamespace std.c;
std/os/test.zig+61
...@@ -5,6 +5,7 @@ const expect = std.testing.expect;...@@ -5,6 +5,7 @@ const expect = std.testing.expect;
5const io = std.io;5const io = std.io;
6const fs = std.fs;6const fs = std.fs;
7const mem = std.mem;7const mem = std.mem;
8const elf = std.elf;
8const File = std.fs.File;9const File = std.fs.File;
9const Thread = std.Thread;10const Thread = std.Thread;
1011
...@@ -149,3 +150,63 @@ test "realpath" {...@@ -149,3 +150,63 @@ test "realpath" {
149 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;150 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
150 testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));151 testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));
151}152}
153
154test "sigaltstack" {
155 if (builtin.os == .windows or builtin.os == .wasi) return error.SkipZigTest;
156
157 var st: os.stack_t = undefined;
158 try os.sigaltstack(null, &st);
159 // Setting a stack size less than MINSIGSTKSZ returns ENOMEM
160 st.ss_flags = 0;
161 st.ss_size = 1;
162 testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null));
163}
164
165// If the type is not available use void to avoid erroring out when `iter_fn` is
166// analyzed
167const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;
168
169export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
170 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
171 return 0;
172
173 var counter = data.?;
174 // Count how many libraries are loaded
175 counter.* += usize(1);
176
177 // The image should contain at least a PT_LOAD segment
178 if (info.dlpi_phnum < 1) return -1;
179
180 // Quick & dirty validation of the phdr pointers, make sure we're not
181 // pointing to some random gibberish
182 var i: usize = 0;
183 var found_load = false;
184 while (i < info.dlpi_phnum) : (i += 1) {
185 const phdr = info.dlpi_phdr[i];
186
187 if (phdr.p_type != elf.PT_LOAD) continue;
188
189 // Find the ELF header
190 const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset);
191 // Validate the magic
192 if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return -1;
193 // Consistency check
194 if (elf_header.e_phnum != info.dlpi_phnum) return -1;
195
196 found_load = true;
197 break;
198 }
199
200 if (!found_load) return -1;
201
202 return 42;
203}
204
205test "dl_iterate_phdr" {
206 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)
207 return error.SkipZigTest;
208
209 var counter: usize = 0;
210 expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0);
211 expect(counter != 0);
212}
std/os/uefi.zig+4
...@@ -1,2 +1,6 @@...@@ -1,2 +1,6 @@
1// TODO this is where the extern declarations go. For example, see1// TODO this is where the extern declarations go. For example, see
2// inc/efilib.h in gnu-efi-code2// inc/efilib.h in gnu-efi-code
3
4const builtin = @import("builtin");
5
6pub const is_the_target = builtin.os == .uefi;
std/os/wasi.zig+1-1
...@@ -5,7 +5,7 @@ const std = @import("std");...@@ -5,7 +5,7 @@ const std = @import("std");
5const assert = std.debug.assert;5const assert = std.debug.assert;
66
7pub const is_the_target = builtin.os == .wasi;7pub const is_the_target = builtin.os == .wasi;
8pub use @import("bits.zig");8pub usingnamespace @import("bits.zig");
99
10comptime {10comptime {
11 assert(@alignOf(i8) == 1);11 assert(@alignOf(i8) == 1);
std/os/windows.zig+14-2
...@@ -18,7 +18,7 @@ pub const ntdll = @import("windows/ntdll.zig");...@@ -18,7 +18,7 @@ pub const ntdll = @import("windows/ntdll.zig");
18pub const ole32 = @import("windows/ole32.zig");18pub const ole32 = @import("windows/ole32.zig");
19pub const shell32 = @import("windows/shell32.zig");19pub const shell32 = @import("windows/shell32.zig");
2020
21pub use @import("windows/bits.zig");21pub usingnamespace @import("windows/bits.zig");
2222
23pub const CreateFileError = error{23pub const CreateFileError = error{
24 SharingViolation,24 SharingViolation,
...@@ -756,11 +756,23 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)...@@ -756,11 +756,23 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
756 return result;756 return result;
757}757}
758758
759inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {
760 return (s << 10) | p;
761}
762
759/// Call this when you made a windows DLL call or something that does SetLastError763/// Call this when you made a windows DLL call or something that does SetLastError
760/// and you get an unexpected error.764/// and you get an unexpected error.
761pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {765pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {
762 if (std.os.unexpected_error_tracing) {766 if (std.os.unexpected_error_tracing) {
763 std.debug.warn("unexpected GetLastError(): {}\n", err);767 // 614 is the length of the longest windows error desciption
768 var buf_u16: [614]u16 = undefined;
769 var buf_u8: [614]u8 = undefined;
770 var len = kernel32.FormatMessageW(
771 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
772 null, err, MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT),
773 buf_u16[0..].ptr, buf_u16.len / @sizeOf(TCHAR), null);
774 _ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable;
775 std.debug.warn("error.Unexpected: GetLastError({}): {}\n", err, buf_u8[0..len]);
764 std.debug.dumpCurrentStackTrace(null);776 std.debug.dumpCurrentStackTrace(null);
765 }777 }
766 return error.Unexpected;778 return error.Unexpected;
std/os/windows/advapi32.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1use @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "advapi32" stdcallcc fn RegOpenKeyExW(3pub extern "advapi32" stdcallcc fn RegOpenKeyExW(
4 hKey: HKEY,4 hKey: HKEY,
std/os/windows/bits.zig+14
...@@ -6,6 +6,8 @@ const assert = std.debug.assert;...@@ -6,6 +6,8 @@ const assert = std.debug.assert;
6const maxInt = std.math.maxInt;6const maxInt = std.math.maxInt;
77
8pub const ERROR = @import("error.zig");8pub const ERROR = @import("error.zig");
9pub const LANG = @import("lang.zig");
10pub const SUBLANG = @import("sublang.zig");
911
10/// The standard input device. Initially, this is the console input buffer, CONIN$.12/// The standard input device. Initially, this is the console input buffer, CONIN$.
11pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1;13pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1;
...@@ -55,6 +57,10 @@ pub const ULONG = u32;...@@ -55,6 +57,10 @@ pub const ULONG = u32;
55pub const LONG = i32;57pub const LONG = i32;
56pub const ULONGLONG = u64;58pub const ULONGLONG = u64;
57pub const LONGLONG = i64;59pub const LONGLONG = i64;
60pub const HLOCAL = HANDLE;
61pub const LANGID = c_ushort;
62
63pub const va_list = *@OpaqueType();
5864
59pub const TRUE = 1;65pub const TRUE = 1;
60pub const FALSE = 0;66pub const FALSE = 0;
...@@ -525,3 +531,11 @@ pub const COINIT = extern enum {...@@ -525,3 +531,11 @@ pub const COINIT = extern enum {
525/// > this expansion applies to the total length.531/// > this expansion applies to the total length.
526/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation532/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
527pub const PATH_MAX_WIDE = 32767;533pub const PATH_MAX_WIDE = 32767;
534
535pub const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
536pub const FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
537pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
538pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400;
539pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
540pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
541pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF;
std/os/windows/kernel32.zig+3-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1use @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL;3pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL;
44
...@@ -50,6 +50,8 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi...@@ -50,6 +50,8 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi
50pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;50pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
51pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;51pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;
5252
53pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD;
54
53pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;55pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;
5456
55pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;57pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
std/os/windows/lang.zig created+140
...@@ -0,0 +1,140 @@
1pub const NEUTRAL = 0x00;
2pub const INVARIANT = 0x7f;
3pub const AFRIKAANS = 0x36;
4pub const ALBANIAN = 0x1c;
5pub const ALSATIAN = 0x84;
6pub const AMHARIC = 0x5e;
7pub const ARABIC = 0x01;
8pub const ARMENIAN = 0x2b;
9pub const ASSAMESE = 0x4d;
10pub const AZERI = 0x2c;
11pub const AZERBAIJANI = 0x2c;
12pub const BANGLA = 0x45;
13pub const BASHKIR = 0x6d;
14pub const BASQUE = 0x2d;
15pub const BELARUSIAN = 0x23;
16pub const BENGALI = 0x45;
17pub const BRETON = 0x7e;
18pub const BOSNIAN = 0x1a;
19pub const BOSNIAN_NEUTRAL = 0x781a;
20pub const BULGARIAN = 0x02;
21pub const CATALAN = 0x03;
22pub const CENTRAL_KURDISH = 0x92;
23pub const CHEROKEE = 0x5c;
24pub const CHINESE = 0x04;
25pub const CHINESE_SIMPLIFIED = 0x04;
26pub const CHINESE_TRADITIONAL = 0x7c04;
27pub const CORSICAN = 0x83;
28pub const CROATIAN = 0x1a;
29pub const CZECH = 0x05;
30pub const DANISH = 0x06;
31pub const DARI = 0x8c;
32pub const DIVEHI = 0x65;
33pub const DUTCH = 0x13;
34pub const ENGLISH = 0x09;
35pub const ESTONIAN = 0x25;
36pub const FAEROESE = 0x38;
37pub const FARSI = 0x29;
38pub const FILIPINO = 0x64;
39pub const FINNISH = 0x0b;
40pub const FRENCH = 0x0c;
41pub const FRISIAN = 0x62;
42pub const FULAH = 0x67;
43pub const GALICIAN = 0x56;
44pub const GEORGIAN = 0x37;
45pub const GERMAN = 0x07;
46pub const GREEK = 0x08;
47pub const GREENLANDIC = 0x6f;
48pub const GUJARATI = 0x47;
49pub const HAUSA = 0x68;
50pub const HAWAIIAN = 0x75;
51pub const HEBREW = 0x0d;
52pub const HINDI = 0x39;
53pub const HUNGARIAN = 0x0e;
54pub const ICELANDIC = 0x0f;
55pub const IGBO = 0x70;
56pub const INDONESIAN = 0x21;
57pub const INUKTITUT = 0x5d;
58pub const IRISH = 0x3c;
59pub const ITALIAN = 0x10;
60pub const JAPANESE = 0x11;
61pub const KANNADA = 0x4b;
62pub const KASHMIRI = 0x60;
63pub const KAZAK = 0x3f;
64pub const KHMER = 0x53;
65pub const KICHE = 0x86;
66pub const KINYARWANDA = 0x87;
67pub const KONKANI = 0x57;
68pub const KOREAN = 0x12;
69pub const KYRGYZ = 0x40;
70pub const LAO = 0x54;
71pub const LATVIAN = 0x26;
72pub const LITHUANIAN = 0x27;
73pub const LOWER_SORBIAN = 0x2e;
74pub const LUXEMBOURGISH = 0x6e;
75pub const MACEDONIAN = 0x2f;
76pub const MALAY = 0x3e;
77pub const MALAYALAM = 0x4c;
78pub const MALTESE = 0x3a;
79pub const MANIPURI = 0x58;
80pub const MAORI = 0x81;
81pub const MAPUDUNGUN = 0x7a;
82pub const MARATHI = 0x4e;
83pub const MOHAWK = 0x7c;
84pub const MONGOLIAN = 0x50;
85pub const NEPALI = 0x61;
86pub const NORWEGIAN = 0x14;
87pub const OCCITAN = 0x82;
88pub const ODIA = 0x48;
89pub const ORIYA = 0x48;
90pub const PASHTO = 0x63;
91pub const PERSIAN = 0x29;
92pub const POLISH = 0x15;
93pub const PORTUGUESE = 0x16;
94pub const PULAR = 0x67;
95pub const PUNJABI = 0x46;
96pub const QUECHUA = 0x6b;
97pub const ROMANIAN = 0x18;
98pub const ROMANSH = 0x17;
99pub const RUSSIAN = 0x19;
100pub const SAKHA = 0x85;
101pub const SAMI = 0x3b;
102pub const SANSKRIT = 0x4f;
103pub const SCOTTISH_GAELIC = 0x91;
104pub const SERBIAN = 0x1a;
105pub const SERBIAN_NEUTRAL = 0x7c1a;
106pub const SINDHI = 0x59;
107pub const SINHALESE = 0x5b;
108pub const SLOVAK = 0x1b;
109pub const SLOVENIAN = 0x24;
110pub const SOTHO = 0x6c;
111pub const SPANISH = 0x0a;
112pub const SWAHILI = 0x41;
113pub const SWEDISH = 0x1d;
114pub const SYRIAC = 0x5a;
115pub const TAJIK = 0x28;
116pub const TAMAZIGHT = 0x5f;
117pub const TAMIL = 0x49;
118pub const TATAR = 0x44;
119pub const TELUGU = 0x4a;
120pub const THAI = 0x1e;
121pub const TIBETAN = 0x51;
122pub const TIGRIGNA = 0x73;
123pub const TIGRINYA = 0x73;
124pub const TSWANA = 0x32;
125pub const TURKISH = 0x1f;
126pub const TURKMEN = 0x42;
127pub const UIGHUR = 0x80;
128pub const UKRAINIAN = 0x22;
129pub const UPPER_SORBIAN = 0x2e;
130pub const URDU = 0x20;
131pub const UZBEK = 0x43;
132pub const VALENCIAN = 0x03;
133pub const VIETNAMESE = 0x2a;
134pub const WELSH = 0x52;
135pub const WOLOF = 0x88;
136pub const XHOSA = 0x34;
137pub const YAKUT = 0x85;
138pub const YI = 0x78;
139pub const YORUBA = 0x6a;
140pub const ZULU = 0x35;
std/os/windows/ntdll.zig+1-1
...@@ -1,3 +1,3 @@...@@ -1,3 +1,3 @@
1use @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;3pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;
std/os/windows/ole32.zig+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1use @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;3pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;
4pub extern "ole32" stdcallcc fn CoUninitialize() void;4pub extern "ole32" stdcallcc fn CoUninitialize() void;
std/os/windows/shell32.zig+1-1
...@@ -1,3 +1,3 @@...@@ -1,3 +1,3 @@
1use @import("bits.zig");1usingnamespace @import("bits.zig");
22
3pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT;3pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT;
std/os/windows/sublang.zig created+244
...@@ -0,0 +1,244 @@
1pub const NEUTRAL = 0x00;
2pub const DEFAULT = 0x01;
3pub const SYS_DEFAULT = 0x02;
4pub const CUSTOM_DEFAULT = 0x03;
5pub const CUSTOM_UNSPECIFIED = 0x04;
6pub const UI_CUSTOM_DEFAULT = 0x05;
7pub const AFRIKAANS_SOUTH_AFRICA = 0x01;
8pub const ALBANIAN_ALBANIA = 0x01;
9pub const ALSATIAN_FRANCE = 0x01;
10pub const AMHARIC_ETHIOPIA = 0x01;
11pub const ARABIC_SAUDI_ARABIA = 0x01;
12pub const ARABIC_IRAQ = 0x02;
13pub const ARABIC_EGYPT = 0x03;
14pub const ARABIC_LIBYA = 0x04;
15pub const ARABIC_ALGERIA = 0x05;
16pub const ARABIC_MOROCCO = 0x06;
17pub const ARABIC_TUNISIA = 0x07;
18pub const ARABIC_OMAN = 0x08;
19pub const ARABIC_YEMEN = 0x09;
20pub const ARABIC_SYRIA = 0x0a;
21pub const ARABIC_JORDAN = 0x0b;
22pub const ARABIC_LEBANON = 0x0c;
23pub const ARABIC_KUWAIT = 0x0d;
24pub const ARABIC_UAE = 0x0e;
25pub const ARABIC_BAHRAIN = 0x0f;
26pub const ARABIC_QATAR = 0x10;
27pub const ARMENIAN_ARMENIA = 0x01;
28pub const ASSAMESE_INDIA = 0x01;
29pub const AZERI_LATIN = 0x01;
30pub const AZERI_CYRILLIC = 0x02;
31pub const AZERBAIJANI_AZERBAIJAN_LATIN = 0x01;
32pub const AZERBAIJANI_AZERBAIJAN_CYRILLIC = 0x02;
33pub const BANGLA_INDIA = 0x01;
34pub const BANGLA_BANGLADESH = 0x02;
35pub const BASHKIR_RUSSIA = 0x01;
36pub const BASQUE_BASQUE = 0x01;
37pub const BELARUSIAN_BELARUS = 0x01;
38pub const BENGALI_INDIA = 0x01;
39pub const BENGALI_BANGLADESH = 0x02;
40pub const BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 0x05;
41pub const BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x08;
42pub const BRETON_FRANCE = 0x01;
43pub const BULGARIAN_BULGARIA = 0x01;
44pub const CATALAN_CATALAN = 0x01;
45pub const CENTRAL_KURDISH_IRAQ = 0x01;
46pub const CHEROKEE_CHEROKEE = 0x01;
47pub const CHINESE_TRADITIONAL = 0x01;
48pub const CHINESE_SIMPLIFIED = 0x02;
49pub const CHINESE_HONGKONG = 0x03;
50pub const CHINESE_SINGAPORE = 0x04;
51pub const CHINESE_MACAU = 0x05;
52pub const CORSICAN_FRANCE = 0x01;
53pub const CZECH_CZECH_REPUBLIC = 0x01;
54pub const CROATIAN_CROATIA = 0x01;
55pub const CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 0x04;
56pub const DANISH_DENMARK = 0x01;
57pub const DARI_AFGHANISTAN = 0x01;
58pub const DIVEHI_MALDIVES = 0x01;
59pub const DUTCH = 0x01;
60pub const DUTCH_BELGIAN = 0x02;
61pub const ENGLISH_US = 0x01;
62pub const ENGLISH_UK = 0x02;
63pub const ENGLISH_AUS = 0x03;
64pub const ENGLISH_CAN = 0x04;
65pub const ENGLISH_NZ = 0x05;
66pub const ENGLISH_EIRE = 0x06;
67pub const ENGLISH_SOUTH_AFRICA = 0x07;
68pub const ENGLISH_JAMAICA = 0x08;
69pub const ENGLISH_CARIBBEAN = 0x09;
70pub const ENGLISH_BELIZE = 0x0a;
71pub const ENGLISH_TRINIDAD = 0x0b;
72pub const ENGLISH_ZIMBABWE = 0x0c;
73pub const ENGLISH_PHILIPPINES = 0x0d;
74pub const ENGLISH_INDIA = 0x10;
75pub const ENGLISH_MALAYSIA = 0x11;
76pub const ENGLISH_SINGAPORE = 0x12;
77pub const ESTONIAN_ESTONIA = 0x01;
78pub const FAEROESE_FAROE_ISLANDS = 0x01;
79pub const FILIPINO_PHILIPPINES = 0x01;
80pub const FINNISH_FINLAND = 0x01;
81pub const FRENCH = 0x01;
82pub const FRENCH_BELGIAN = 0x02;
83pub const FRENCH_CANADIAN = 0x03;
84pub const FRENCH_SWISS = 0x04;
85pub const FRENCH_LUXEMBOURG = 0x05;
86pub const FRENCH_MONACO = 0x06;
87pub const FRISIAN_NETHERLANDS = 0x01;
88pub const FULAH_SENEGAL = 0x02;
89pub const GALICIAN_GALICIAN = 0x01;
90pub const GEORGIAN_GEORGIA = 0x01;
91pub const GERMAN = 0x01;
92pub const GERMAN_SWISS = 0x02;
93pub const GERMAN_AUSTRIAN = 0x03;
94pub const GERMAN_LUXEMBOURG = 0x04;
95pub const GERMAN_LIECHTENSTEIN = 0x05;
96pub const GREEK_GREECE = 0x01;
97pub const GREENLANDIC_GREENLAND = 0x01;
98pub const GUJARATI_INDIA = 0x01;
99pub const HAUSA_NIGERIA_LATIN = 0x01;
100pub const HAWAIIAN_US = 0x01;
101pub const HEBREW_ISRAEL = 0x01;
102pub const HINDI_INDIA = 0x01;
103pub const HUNGARIAN_HUNGARY = 0x01;
104pub const ICELANDIC_ICELAND = 0x01;
105pub const IGBO_NIGERIA = 0x01;
106pub const INDONESIAN_INDONESIA = 0x01;
107pub const INUKTITUT_CANADA = 0x01;
108pub const INUKTITUT_CANADA_LATIN = 0x02;
109pub const IRISH_IRELAND = 0x02;
110pub const ITALIAN = 0x01;
111pub const ITALIAN_SWISS = 0x02;
112pub const JAPANESE_JAPAN = 0x01;
113pub const KANNADA_INDIA = 0x01;
114pub const KASHMIRI_SASIA = 0x02;
115pub const KASHMIRI_INDIA = 0x02;
116pub const KAZAK_KAZAKHSTAN = 0x01;
117pub const KHMER_CAMBODIA = 0x01;
118pub const KICHE_GUATEMALA = 0x01;
119pub const KINYARWANDA_RWANDA = 0x01;
120pub const KONKANI_INDIA = 0x01;
121pub const KOREAN = 0x01;
122pub const KYRGYZ_KYRGYZSTAN = 0x01;
123pub const LAO_LAO = 0x01;
124pub const LATVIAN_LATVIA = 0x01;
125pub const LITHUANIAN = 0x01;
126pub const LOWER_SORBIAN_GERMANY = 0x02;
127pub const LUXEMBOURGISH_LUXEMBOURG = 0x01;
128pub const MACEDONIAN_MACEDONIA = 0x01;
129pub const MALAY_MALAYSIA = 0x01;
130pub const MALAY_BRUNEI_DARUSSALAM = 0x02;
131pub const MALAYALAM_INDIA = 0x01;
132pub const MALTESE_MALTA = 0x01;
133pub const MAORI_NEW_ZEALAND = 0x01;
134pub const MAPUDUNGUN_CHILE = 0x01;
135pub const MARATHI_INDIA = 0x01;
136pub const MOHAWK_MOHAWK = 0x01;
137pub const MONGOLIAN_CYRILLIC_MONGOLIA = 0x01;
138pub const MONGOLIAN_PRC = 0x02;
139pub const NEPALI_INDIA = 0x02;
140pub const NEPALI_NEPAL = 0x01;
141pub const NORWEGIAN_BOKMAL = 0x01;
142pub const NORWEGIAN_NYNORSK = 0x02;
143pub const OCCITAN_FRANCE = 0x01;
144pub const ODIA_INDIA = 0x01;
145pub const ORIYA_INDIA = 0x01;
146pub const PASHTO_AFGHANISTAN = 0x01;
147pub const PERSIAN_IRAN = 0x01;
148pub const POLISH_POLAND = 0x01;
149pub const PORTUGUESE = 0x02;
150pub const PORTUGUESE_BRAZILIAN = 0x01;
151pub const PULAR_SENEGAL = 0x02;
152pub const PUNJABI_INDIA = 0x01;
153pub const PUNJABI_PAKISTAN = 0x02;
154pub const QUECHUA_BOLIVIA = 0x01;
155pub const QUECHUA_ECUADOR = 0x02;
156pub const QUECHUA_PERU = 0x03;
157pub const ROMANIAN_ROMANIA = 0x01;
158pub const ROMANSH_SWITZERLAND = 0x01;
159pub const RUSSIAN_RUSSIA = 0x01;
160pub const SAKHA_RUSSIA = 0x01;
161pub const SAMI_NORTHERN_NORWAY = 0x01;
162pub const SAMI_NORTHERN_SWEDEN = 0x02;
163pub const SAMI_NORTHERN_FINLAND = 0x03;
164pub const SAMI_LULE_NORWAY = 0x04;
165pub const SAMI_LULE_SWEDEN = 0x05;
166pub const SAMI_SOUTHERN_NORWAY = 0x06;
167pub const SAMI_SOUTHERN_SWEDEN = 0x07;
168pub const SAMI_SKOLT_FINLAND = 0x08;
169pub const SAMI_INARI_FINLAND = 0x09;
170pub const SANSKRIT_INDIA = 0x01;
171pub const SCOTTISH_GAELIC = 0x01;
172pub const SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 0x06;
173pub const SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x07;
174pub const SERBIAN_MONTENEGRO_LATIN = 0x0b;
175pub const SERBIAN_MONTENEGRO_CYRILLIC = 0x0c;
176pub const SERBIAN_SERBIA_LATIN = 0x09;
177pub const SERBIAN_SERBIA_CYRILLIC = 0x0a;
178pub const SERBIAN_CROATIA = 0x01;
179pub const SERBIAN_LATIN = 0x02;
180pub const SERBIAN_CYRILLIC = 0x03;
181pub const SINDHI_INDIA = 0x01;
182pub const SINDHI_PAKISTAN = 0x02;
183pub const SINDHI_AFGHANISTAN = 0x02;
184pub const SINHALESE_SRI_LANKA = 0x01;
185pub const SOTHO_NORTHERN_SOUTH_AFRICA = 0x01;
186pub const SLOVAK_SLOVAKIA = 0x01;
187pub const SLOVENIAN_SLOVENIA = 0x01;
188pub const SPANISH = 0x01;
189pub const SPANISH_MEXICAN = 0x02;
190pub const SPANISH_MODERN = 0x03;
191pub const SPANISH_GUATEMALA = 0x04;
192pub const SPANISH_COSTA_RICA = 0x05;
193pub const SPANISH_PANAMA = 0x06;
194pub const SPANISH_DOMINICAN_REPUBLIC = 0x07;
195pub const SPANISH_VENEZUELA = 0x08;
196pub const SPANISH_COLOMBIA = 0x09;
197pub const SPANISH_PERU = 0x0a;
198pub const SPANISH_ARGENTINA = 0x0b;
199pub const SPANISH_ECUADOR = 0x0c;
200pub const SPANISH_CHILE = 0x0d;
201pub const SPANISH_URUGUAY = 0x0e;
202pub const SPANISH_PARAGUAY = 0x0f;
203pub const SPANISH_BOLIVIA = 0x10;
204pub const SPANISH_EL_SALVADOR = 0x11;
205pub const SPANISH_HONDURAS = 0x12;
206pub const SPANISH_NICARAGUA = 0x13;
207pub const SPANISH_PUERTO_RICO = 0x14;
208pub const SPANISH_US = 0x15;
209pub const SWAHILI_KENYA = 0x01;
210pub const SWEDISH = 0x01;
211pub const SWEDISH_FINLAND = 0x02;
212pub const SYRIAC_SYRIA = 0x01;
213pub const TAJIK_TAJIKISTAN = 0x01;
214pub const TAMAZIGHT_ALGERIA_LATIN = 0x02;
215pub const TAMAZIGHT_MOROCCO_TIFINAGH = 0x04;
216pub const TAMIL_INDIA = 0x01;
217pub const TAMIL_SRI_LANKA = 0x02;
218pub const TATAR_RUSSIA = 0x01;
219pub const TELUGU_INDIA = 0x01;
220pub const THAI_THAILAND = 0x01;
221pub const TIBETAN_PRC = 0x01;
222pub const TIGRIGNA_ERITREA = 0x02;
223pub const TIGRINYA_ERITREA = 0x02;
224pub const TIGRINYA_ETHIOPIA = 0x01;
225pub const TSWANA_BOTSWANA = 0x02;
226pub const TSWANA_SOUTH_AFRICA = 0x01;
227pub const TURKISH_TURKEY = 0x01;
228pub const TURKMEN_TURKMENISTAN = 0x01;
229pub const UIGHUR_PRC = 0x01;
230pub const UKRAINIAN_UKRAINE = 0x01;
231pub const UPPER_SORBIAN_GERMANY = 0x01;
232pub const URDU_PAKISTAN = 0x01;
233pub const URDU_INDIA = 0x02;
234pub const UZBEK_LATIN = 0x01;
235pub const UZBEK_CYRILLIC = 0x02;
236pub const VALENCIAN_VALENCIA = 0x02;
237pub const VIETNAMESE_VIETNAM = 0x01;
238pub const WELSH_UNITED_KINGDOM = 0x01;
239pub const WOLOF_SENEGAL = 0x01;
240pub const XHOSA_SOUTH_AFRICA = 0x01;
241pub const YAKUT_RUSSIA = 0x01;
242pub const YI_PRC = 0x01;
243pub const YORUBA_NIGERIA = 0x01;
244pub const ZULU_SOUTH_AFRICA = 0x01;
std/os/zen.zig+1-1
...@@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1;...@@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1;
80pub const STDERR_FILENO = 2;80pub const STDERR_FILENO = 2;
8181
82// FIXME: let's borrow Linux's error numbers for now.82// FIXME: let's borrow Linux's error numbers for now.
83use @import("bits/linux/errno.zig");83usingnamespace @import("bits/linux/errno.zig");
84// Get the errno from a syscall return value, or 0 for no error.84// Get the errno from a syscall return value, or 0 for no error.
85pub fn getErrno(r: usize) usize {85pub fn getErrno(r: usize) usize {
86 const signed_r = @bitCast(isize, r);86 const signed_r = @bitCast(isize, r);
std/special/c.zig+64-2
...@@ -20,6 +20,12 @@ comptime {...@@ -20,6 +20,12 @@ comptime {
20 if (is_freestanding and is_wasm and builtin.link_libc) {20 if (is_freestanding and is_wasm and builtin.link_libc) {
21 @export("_start", wasm_start, .Strong);21 @export("_start", wasm_start, .Strong);
22 }22 }
23 if (builtin.link_libc) {
24 @export("strcmp", strcmp, .Strong);
25 @export("strncmp", strncmp, .Strong);
26 @export("strerror", strerror, .Strong);
27 @export("strlen", strlen, .Strong);
28 }
23}29}
2430
25extern fn main(argc: c_int, argv: [*][*]u8) c_int;31extern fn main(argc: c_int, argv: [*][*]u8) c_int;
...@@ -27,6 +33,38 @@ extern fn wasm_start() void {...@@ -27,6 +33,38 @@ extern fn wasm_start() void {
27 _ = main(0, undefined);33 _ = main(0, undefined);
28}34}
2935
36extern fn strcmp(s1: [*]const u8, s2: [*]const u8) c_int {
37 return std.cstr.cmp(s1, s2);
38}
39
40extern fn strlen(s: [*]const u8) usize {
41 return std.mem.len(u8, s);
42}
43
44extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int {
45 if (_n == 0) return 0;
46 var l = _l;
47 var r = _r;
48 var n = _n - 1;
49 while (l[0] != 0 and r[0] != 0 and n != 0 and l[0] == r[0]) {
50 l += 1;
51 r += 1;
52 n -= 1;
53 }
54 return c_int(l[0]) - c_int(r[0]);
55}
56
57extern fn strerror(errnum: c_int) [*]const u8 {
58 return c"TODO strerror implementation";
59}
60
61test "strncmp" {
62 std.testing.expect(strncmp(c"a", c"b", 1) == -1);
63 std.testing.expect(strncmp(c"a", c"c", 1) == -2);
64 std.testing.expect(strncmp(c"b", c"a", 1) == 1);
65 std.testing.expect(strncmp(c"\xff", c"\x02", 1) == 253);
66}
67
30// Avoid dragging in the runtime safety mechanisms into this .o file,68// Avoid dragging in the runtime safety mechanisms into this .o file,
31// unless we're trying to test this file.69// unless we're trying to test this file.
32pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {70pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
...@@ -98,8 +136,32 @@ test "test_memcmp" {...@@ -98,8 +136,32 @@ test "test_memcmp" {
98 const arr3 = []u8{ 1, 2, 1 };136 const arr3 = []u8{ 1, 2, 1 };
99137
100 std.testing.expect(memcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0);138 std.testing.expect(memcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0);
101 std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) == 1);139 std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) > 0);
102 std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) == -1);140 std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) < 0);
141}
142
143export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) isize {
144 @setRuntimeSafety(false);
145
146 var index: usize = 0;
147 while (index != n) : (index += 1) {
148 if (vl[index] != vr[index]) {
149 return 1;
150 }
151 }
152
153 return 0;
154}
155
156test "test_bcmp" {
157 const base_arr = []u8{ 1, 1, 1 };
158 const arr1 = []u8{ 1, 1, 1 };
159 const arr2 = []u8{ 1, 0, 1 };
160 const arr3 = []u8{ 1, 2, 1 };
161
162 std.testing.expect(bcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0);
163 std.testing.expect(bcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) != 0);
164 std.testing.expect(bcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) != 0);
103}165}
104166
105comptime {167comptime {
std/thread.zig+23-9
...@@ -223,15 +223,17 @@ pub const Thread = struct {...@@ -223,15 +223,17 @@ pub const Thread = struct {
223 }223 }
224 };224 };
225225
226 const MAP_GROWSDOWN = if (os.linux.is_the_target) os.linux.MAP_GROWSDOWN else 0;226 var guard_end_offset: usize = undefined;
227
228 var stack_end_offset: usize = undefined;227 var stack_end_offset: usize = undefined;
229 var thread_start_offset: usize = undefined;228 var thread_start_offset: usize = undefined;
230 var context_start_offset: usize = undefined;229 var context_start_offset: usize = undefined;
231 var tls_start_offset: usize = undefined;230 var tls_start_offset: usize = undefined;
232 const mmap_len = blk: {231 const mmap_len = blk: {
233 // First in memory will be the stack, which grows downwards.232 var l: usize = mem.page_size;
234 var l: usize = mem.alignForward(default_stack_size, mem.page_size);233 // Allocate a guard page right after the end of the stack region
234 guard_end_offset = l;
235 // The stack itself, which grows downwards.
236 l = mem.alignForward(l + default_stack_size, mem.page_size);
235 stack_end_offset = l;237 stack_end_offset = l;
236 // Above the stack, so that it can be in the same mmap call, put the Thread object.238 // Above the stack, so that it can be in the same mmap call, put the Thread object.
237 l = mem.alignForward(l, @alignOf(Thread));239 l = mem.alignForward(l, @alignOf(Thread));
...@@ -253,20 +255,32 @@ pub const Thread = struct {...@@ -253,20 +255,32 @@ pub const Thread = struct {
253 }255 }
254 break :blk l;256 break :blk l;
255 };257 };
258 // Map the whole stack with no rw permissions to avoid committing the
259 // whole region right away
256 const mmap_slice = os.mmap(260 const mmap_slice = os.mmap(
257 null,261 null,
258 mem.alignForward(mmap_len, mem.page_size),262 mem.alignForward(mmap_len, mem.page_size),
259 os.PROT_READ | os.PROT_WRITE,263 os.PROT_NONE,
260 os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN,264 os.MAP_PRIVATE | os.MAP_ANONYMOUS,
261 -1,265 -1,
262 0,266 0,
263 ) catch |err| switch (err) {267 ) catch |err| switch (err) {
264 error.MemoryMappingNotSupported => unreachable, // no file descriptor268 error.MemoryMappingNotSupported => unreachable,
265 error.AccessDenied => unreachable, // no file descriptor269 error.AccessDenied => unreachable,
266 error.PermissionDenied => unreachable, // no file descriptor270 error.PermissionDenied => unreachable,
267 else => |e| return e,271 else => |e| return e,
268 };272 };
269 errdefer os.munmap(mmap_slice);273 errdefer os.munmap(mmap_slice);
274
275 // Map everything but the guard page as rw
276 os.mprotect(
277 mmap_slice,
278 os.PROT_READ | os.PROT_WRITE,
279 ) catch |err| switch (err) {
280 error.AccessDenied => unreachable,
281 else => |e| return e,
282 };
283
270 const mmap_addr = @ptrToInt(mmap_slice.ptr);284 const mmap_addr = @ptrToInt(mmap_slice.ptr);
271285
272 const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));286 const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));
std/zig/parse.zig+3-3
...@@ -203,7 +203,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*...@@ -203,7 +203,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
203/// TopLevelDecl203/// TopLevelDecl
204/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)204/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
205/// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl205/// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
206/// / KEYWORD_use Expr SEMICOLON206/// / KEYWORD_usingnamespace Expr SEMICOLON
207fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {207fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
208 var lib_name: ?*Node = null;208 var lib_name: ?*Node = null;
209 const extern_export_inline_token = blk: {209 const extern_export_inline_token = blk: {
...@@ -1026,7 +1026,7 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1026,7 +1026,7 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1026 else_node.* = Node.Else{1026 else_node.* = Node.Else{
1027 .base = Node{ .id = .Else },1027 .base = Node{ .id = .Else },
1028 .else_token = else_token,1028 .else_token = else_token,
1029 .payload = null,1029 .payload = payload,
1030 .body = body,1030 .body = body,
1031 };1031 };
10321032
...@@ -2809,7 +2809,7 @@ fn parseTry(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -2809,7 +2809,7 @@ fn parseTry(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2809}2809}
28102810
2811fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {2811fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2812 const token = eatToken(it, .Keyword_use) orelse return null;2812 const token = eatToken(it, .Keyword_usingnamespace) orelse return null;
2813 const node = try arena.create(Node.Use);2813 const node = try arena.create(Node.Use);
2814 node.* = Node.Use{2814 node.* = Node.Use{
2815 .base = Node{ .id = .Use },2815 .base = Node{ .id = .Use },
std/zig/parser_test.zig+66-2
...@@ -1,3 +1,42 @@...@@ -1,3 +1,42 @@
1// TODO remove `use` keyword eventually
2test "zig fmt: change use to usingnamespace" {
3 try testTransform(
4 \\use @import("std");
5 ,
6 \\usingnamespace @import("std");
7 \\
8 );
9}
10
11test "zig fmt: while else err prong with no block" {
12 try testCanonical(
13 \\test "" {
14 \\ const result = while (returnError()) |value| {
15 \\ break value;
16 \\ } else |err| i32(2);
17 \\ expect(result == 2);
18 \\}
19 \\
20 );
21}
22
23test "zig fmt: tagged union with enum values" {
24 try testCanonical(
25 \\const MultipleChoice2 = union(enum(u32)) {
26 \\ Unspecified1: i32,
27 \\ A: f32 = 20,
28 \\ Unspecified2: void,
29 \\ B: bool = 40,
30 \\ Unspecified3: i32,
31 \\ C: i8 = 60,
32 \\ Unspecified4: void,
33 \\ D: void = 1000,
34 \\ Unspecified5: i32,
35 \\};
36 \\
37 );
38}
39
1test "zig fmt: allowzero pointer" {40test "zig fmt: allowzero pointer" {
2 try testCanonical(41 try testCanonical(
3 \\const T = [*]allowzero const u8;42 \\const T = [*]allowzero const u8;
...@@ -2090,8 +2129,8 @@ test "zig fmt: Block after if" {...@@ -2090,8 +2129,8 @@ test "zig fmt: Block after if" {
20902129
2091test "zig fmt: use" {2130test "zig fmt: use" {
2092 try testCanonical(2131 try testCanonical(
2093 \\use @import("std");2132 \\usingnamespace @import("std");
2094 \\pub use @import("std");2133 \\pub usingnamespace @import("std");
2095 \\2134 \\
2096 );2135 );
2097}2136}
...@@ -2170,6 +2209,31 @@ test "zig fmt: inline asm parameter alignment" {...@@ -2170,6 +2209,31 @@ test "zig fmt: inline asm parameter alignment" {
2170 );2209 );
2171}2210}
21722211
2212test "zig fmt: multiline string in array" {
2213 try testCanonical(
2214 \\const Foo = [][]const u8{
2215 \\ \\aaa
2216 \\,
2217 \\ \\bbb
2218 \\};
2219 \\
2220 \\fn bar() void {
2221 \\ const Foo = [][]const u8{
2222 \\ \\aaa
2223 \\ ,
2224 \\ \\bbb
2225 \\ };
2226 \\ const Bar = [][]const u8{ // comment here
2227 \\ \\aaa
2228 \\ \\
2229 \\ , // and another comment can go here
2230 \\ \\bbb
2231 \\ };
2232 \\}
2233 \\
2234 );
2235}
2236
2173const std = @import("std");2237const std = @import("std");
2174const mem = std.mem;2238const mem = std.mem;
2175const warn = std.debug.warn;2239const warn = std.debug.warn;
std/zig/render.zig+27-8
...@@ -168,7 +168,9 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i...@@ -168,7 +168,9 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
168 if (use_decl.visib_token) |visib_token| {168 if (use_decl.visib_token) |visib_token| {
169 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub169 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
170 }170 }
171 try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // use171 // TODO after depracating use, go back to this:
172 //try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace
173 try stream.write("usingnamespace ");
172 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);174 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
173 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;175 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
174 },176 },
...@@ -212,7 +214,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i...@@ -212,7 +214,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
212 try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name214 try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name
213 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // :215 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // :
214 try renderExpression(allocator, stream, tree, indent, start_col, field.type_expr.?, Space.Space); // type216 try renderExpression(allocator, stream, tree, indent, start_col, field.type_expr.?, Space.Space); // type
215 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // =217 try renderToken(tree, stream, tree.nextToken(field.type_expr.?.lastToken()), indent, start_col, Space.Space); // =
216 return renderExpression(allocator, stream, tree, indent, start_col, field.value_expr.?, Space.Comma); // value,218 return renderExpression(allocator, stream, tree, indent, start_col, field.value_expr.?, Space.Comma); // value,
217 }219 }
218 },220 },
...@@ -724,9 +726,15 @@ fn renderExpression(...@@ -724,9 +726,15 @@ fn renderExpression(
724 expr_widths[i] = width;726 expr_widths[i] = width;
725 }727 }
726728
727 const new_indent = indent + indent_delta;729 var new_indent = indent + indent_delta;
728 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);730
729 try stream.writeByteNTimes(' ', new_indent);731 if (tree.tokens.at(tree.nextToken(lbrace)).id != Token.Id.MultilineStringLiteralLine) {
732 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
733 try stream.writeByteNTimes(' ', new_indent);
734 } else {
735 new_indent -= indent_delta;
736 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.None);
737 }
730738
731 it.set(0);739 it.set(0);
732 i = 0;740 i = 0;
...@@ -748,15 +756,24 @@ fn renderExpression(...@@ -748,15 +756,24 @@ fn renderExpression(
748 }756 }
749 col = 1;757 col = 1;
750758
751 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,759 if (tree.tokens.at(tree.nextToken(comma)).id != Token.Id.MultilineStringLiteralLine) {
760 try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // ,
761 } else {
762 try renderToken(tree, stream, comma, new_indent, start_col, Space.None); // ,
763 }
752764
753 try renderExtraNewline(tree, stream, start_col, next_expr.*);765 try renderExtraNewline(tree, stream, start_col, next_expr.*);
754 try stream.writeByteNTimes(' ', new_indent);766 if (next_expr.*.id != ast.Node.Id.MultilineStringLiteral) {
767 try stream.writeByteNTimes(' ', new_indent);
768 }
755 } else {769 } else {
756 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,770 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
757 }771 }
758 }772 }
759 try stream.writeByteNTimes(' ', indent);773 const last_node = it.prev().?;
774 if (last_node.*.id != ast.Node.Id.MultilineStringLiteral) {
775 try stream.writeByteNTimes(' ', indent);
776 }
760 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);777 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
761 } else {778 } else {
762 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);779 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
...@@ -1037,6 +1054,8 @@ fn renderExpression(...@@ -1037,6 +1054,8 @@ fn renderExpression(
1037 },1054 },
10381055
1039 ast.Node.Id.MultilineStringLiteral => {1056 ast.Node.Id.MultilineStringLiteral => {
1057 // TODO: Don't indent in this function, but let the caller indent.
1058 // If this has been implemented, a lot of hacky solutions in i.e. ArrayInit and FunctionCall can be removed
1040 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);1059 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
10411060
1042 var skip_first_indent = true;1061 var skip_first_indent = true;
std/zig/tokenizer.zig+3-2
...@@ -59,7 +59,8 @@ pub const Token = struct {...@@ -59,7 +59,8 @@ pub const Token = struct {
59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
60 Keyword{ .bytes = "union", .id = Id.Keyword_union },60 Keyword{ .bytes = "union", .id = Id.Keyword_union },
61 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },61 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },
62 Keyword{ .bytes = "use", .id = Id.Keyword_use },62 Keyword{ .bytes = "use", .id = Id.Keyword_usingnamespace },
63 Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace },
63 Keyword{ .bytes = "var", .id = Id.Keyword_var },64 Keyword{ .bytes = "var", .id = Id.Keyword_var },
64 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },65 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
65 Keyword{ .bytes = "while", .id = Id.Keyword_while },66 Keyword{ .bytes = "while", .id = Id.Keyword_while },
...@@ -190,7 +191,7 @@ pub const Token = struct {...@@ -190,7 +191,7 @@ pub const Token = struct {
190 Keyword_undefined,191 Keyword_undefined,
191 Keyword_union,192 Keyword_union,
192 Keyword_unreachable,193 Keyword_unreachable,
193 Keyword_use,194 Keyword_usingnamespace,
194 Keyword_var,195 Keyword_var,
195 Keyword_volatile,196 Keyword_volatile,
196 Keyword_while,197 Keyword_while,
test/build_examples.zig+1-3
...@@ -17,9 +17,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {...@@ -17,9 +17,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
17 cases.addBuildFile("test/standalone/use_alias/build.zig");17 cases.addBuildFile("test/standalone/use_alias/build.zig");
18 cases.addBuildFile("test/standalone/brace_expansion/build.zig");18 cases.addBuildFile("test/standalone/brace_expansion/build.zig");
19 cases.addBuildFile("test/standalone/empty_env/build.zig");19 cases.addBuildFile("test/standalone/empty_env/build.zig");
20 if (false) {20 if (builtin.os == builtin.Os.linux) {
21 // TODO this test is disabled because it is failing on the CI server's linux. when this is fixed
22 // enable it for at least linux
23 // TODO hook up the DynLib API for windows using LoadLibraryA21 // TODO hook up the DynLib API for windows using LoadLibraryA
24 // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it22 // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it
25 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");23 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
test/compile_errors.zig+36-17
...@@ -2,6 +2,38 @@ const tests = @import("tests.zig");...@@ -2,6 +2,38 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "compile error in struct init expression",
7 \\const Foo = struct {
8 \\ a: i32 = crap,
9 \\ b: i32,
10 \\};
11 \\export fn entry() void {
12 \\ var x = Foo{
13 \\ .b = 5,
14 \\ };
15 \\}
16 ,
17 "tmp.zig:2:14: error: use of undeclared identifier 'crap'",
18 );
19
20 cases.add(
21 "undefined as field type is rejected",
22 \\const Foo = struct {
23 \\ a: undefined,
24 \\};
25 \\const Bar = union {
26 \\ a: undefined,
27 \\};
28 \\pub fn main() void {
29 \\ const foo: Foo = undefined;
30 \\ const bar: Bar = undefined;
31 \\}
32 ,
33 "tmp.zig:2:8: error: expected type 'type', found '(undefined)'",
34 "tmp.zig:5:8: error: expected type 'type', found '(undefined)'",
35 );
36
5 cases.add(37 cases.add(
6 "@hasDecl with non-container",38 "@hasDecl with non-container",
7 \\export fn entry() void {39 \\export fn entry() void {
...@@ -146,7 +178,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -146,7 +178,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
146 "usingnamespace with wrong type",178 "usingnamespace with wrong type",
147 \\use void;179 \\use void;
148 ,180 ,
149 "tmp.zig:1:1: error: expected struct, found 'void'",181 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
150 );182 );
151183
152 cases.add(184 cases.add(
...@@ -1202,7 +1234,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1202,7 +1234,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1202 \\}1234 \\}
1203 ,1235 ,
1204 "tmp.zig:2:5: error: `_` is not a declarable symbol",1236 "tmp.zig:2:5: error: `_` is not a declarable symbol",
1205 "tmp.zig:3:12: error: use of undeclared identifier '_'",
1206 );1237 );
12071238
1208 cases.add(1239 cases.add(
...@@ -1215,7 +1246,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1215,7 +1246,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1215 \\ }1246 \\ }
1216 \\}1247 \\}
1217 ,1248 ,
1218 "tmp.zig:4:20: error: use of undeclared identifier '_'",1249 "tmp.zig:4:20: error: `_` may only be used to assign things to",
1219 );1250 );
12201251
1221 cases.add(1252 cases.add(
...@@ -1231,7 +1262,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1231,7 +1262,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1231 \\ return 1;1262 \\ return 1;
1232 \\}1263 \\}
1233 ,1264 ,
1234 "tmp.zig:4:20: error: use of undeclared identifier '_'",1265 "tmp.zig:4:20: error: `_` may only be used to assign things to",
1235 );1266 );
12361267
1237 cases.add(1268 cases.add(
...@@ -1249,7 +1280,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1249,7 +1280,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1249 \\ return error.optionalReturnError;1280 \\ return error.optionalReturnError;
1250 \\}1281 \\}
1251 ,1282 ,
1252 "tmp.zig:6:17: error: use of undeclared identifier '_'",1283 "tmp.zig:6:17: error: `_` may only be used to assign things to",
1253 );1284 );
12541285
1255 cases.add(1286 cases.add(
...@@ -5468,18 +5499,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5468,18 +5499,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5468 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",5499 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",
5469 );5500 );
54705501
5471 cases.add(
5472 "struct fields with value assignments",
5473 \\const MultipleChoice = struct {
5474 \\ A: i32 = 20,
5475 \\};
5476 \\export fn entry() void {
5477 \\ var x: MultipleChoice = undefined;
5478 \\}
5479 ,
5480 "tmp.zig:2:14: error: enums, not structs, support field assignment",
5481 );
5482
5483 cases.add(5502 cases.add(
5484 "union fields with value assignments",5503 "union fields with value assignments",
5485 \\const MultipleChoice = union {5504 \\const MultipleChoice = union {
test/gen_h.zig+8-8
...@@ -11,7 +11,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -11,7 +11,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
11 \\ C = 211 \\ C = 2
12 \\};12 \\};
13 \\13 \\
14 \\TEST_EXPORT void entry(enum Foo foo);14 \\TEST_EXTERN_C void entry(enum Foo foo);
15 \\15 \\
16 );16 );
1717
...@@ -35,7 +35,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -35,7 +35,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
35 \\ uint64_t F;35 \\ uint64_t F;
36 \\};36 \\};
37 \\37 \\
38 \\TEST_EXPORT void entry(struct Foo foo);38 \\TEST_EXTERN_C void entry(struct Foo foo);
39 \\39 \\
40 );40 );
4141
...@@ -70,7 +70,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -70,7 +70,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
70 \\ struct Big D;70 \\ struct Big D;
71 \\};71 \\};
72 \\72 \\
73 \\TEST_EXPORT void entry(union Foo foo);73 \\TEST_EXTERN_C void entry(union Foo foo);
74 \\74 \\
75 );75 );
7676
...@@ -81,7 +81,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -81,7 +81,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
81 ,81 ,
82 \\struct Foo;82 \\struct Foo;
83 \\83 \\
84 \\TEST_EXPORT void entry(struct Foo * foo);84 \\TEST_EXTERN_C void entry(struct Foo * foo);
85 );85 );
8686
87 cases.add("array field-type",87 cases.add("array field-type",
...@@ -96,7 +96,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -96,7 +96,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
96 \\ uint32_t * B[4];96 \\ uint32_t * B[4];
97 \\};97 \\};
98 \\98 \\
99 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);99 \\TEST_EXTERN_C void entry(struct Foo foo, uint8_t bar[]);
100 \\100 \\
101 );101 );
102102
...@@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
110 \\}110 \\}
111 ,111 ,
112 \\struct S;112 \\struct S;
113 \\TEST_EXPORT uint8_t a(struct S * s);113 \\TEST_EXTERN_C uint8_t a(struct S * s);
114 \\114 \\
115 );115 );
116116
...@@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
125 \\}125 \\}
126 ,126 ,
127 \\union U;127 \\union U;
128 \\TEST_EXPORT uint8_t a(union U * s);128 \\TEST_EXTERN_C uint8_t a(union U * s);
129 \\129 \\
130 );130 );
131131
...@@ -140,7 +140,7 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -140,7 +140,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
140 \\}140 \\}
141 ,141 ,
142 \\enum E;142 \\enum E;
143 \\TEST_EXPORT uint8_t a(enum E * s);143 \\TEST_EXTERN_C uint8_t a(enum E * s);
144 \\144 \\
145 );145 );
146}146}
test/stage1/behavior.zig+1
...@@ -26,6 +26,7 @@ comptime {...@@ -26,6 +26,7 @@ comptime {
26 _ = @import("behavior/bugs/2006.zig");26 _ = @import("behavior/bugs/2006.zig");
27 _ = @import("behavior/bugs/2114.zig");27 _ = @import("behavior/bugs/2114.zig");
28 _ = @import("behavior/bugs/2346.zig");28 _ = @import("behavior/bugs/2346.zig");
29 _ = @import("behavior/bugs/2578.zig");
29 _ = @import("behavior/bugs/394.zig");30 _ = @import("behavior/bugs/394.zig");
30 _ = @import("behavior/bugs/421.zig");31 _ = @import("behavior/bugs/421.zig");
31 _ = @import("behavior/bugs/529.zig");32 _ = @import("behavior/bugs/529.zig");
test/stage1/behavior/alignof.zig-1
...@@ -15,4 +15,3 @@ test "@alignOf(T) before referencing T" {...@@ -15,4 +15,3 @@ test "@alignOf(T) before referencing T" {
15 comptime expect(@alignOf(Foo) == 4);15 comptime expect(@alignOf(Foo) == 4);
16 }16 }
17}17}
18
test/stage1/behavior/bugs/1076.zig-1
...@@ -13,4 +13,3 @@ fn testCastPtrOfArrayToSliceAndPtr() void {...@@ -13,4 +13,3 @@ fn testCastPtrOfArrayToSliceAndPtr() void {
13 x[0] += 1;13 x[0] += 1;
14 expect(mem.eql(u8, array[0..], "boeu"));14 expect(mem.eql(u8, array[0..], "boeu"));
15}15}
16
test/stage1/behavior/bugs/1486.zig-1
...@@ -8,4 +8,3 @@ test "constant pointer to global variable causes runtime load" {...@@ -8,4 +8,3 @@ test "constant pointer to global variable causes runtime load" {
8 expect(&global == ptr);8 expect(&global == ptr);
9 expect(ptr.* == 1234);9 expect(ptr.* == 1234);
10}10}
11
test/stage1/behavior/bugs/2578.zig created+12
...@@ -0,0 +1,12 @@
1const Foo = struct {
2 y: u8,
3};
4
5var foo: Foo = undefined;
6const t = &foo;
7
8fn bar(pointer: ?*c_void) void {}
9
10test "fixed" {
11 bar(t);
12}
test/stage1/behavior/bugs/421.zig-1
...@@ -13,4 +13,3 @@ fn extractOne64(a: u128) u64 {...@@ -13,4 +13,3 @@ fn extractOne64(a: u128) u64 {
13 const x = @bitCast([2]u64, a);13 const x = @bitCast([2]u64, a);
14 return x[1];14 return x[1];
15}15}
16
test/stage1/behavior/bugs/529.zig-1
...@@ -12,4 +12,3 @@ test "issue 529 fixed" {...@@ -12,4 +12,3 @@ test "issue 529 fixed" {
12 @import("529_other_file.zig").issue529(null);12 @import("529_other_file.zig").issue529(null);
13 issue529(null);13 issue529(null);
14}14}
15
test/stage1/behavior/bugs/726.zig-1
...@@ -13,4 +13,3 @@ test "@ptrCast from var in empty struct to nullable" {...@@ -13,4 +13,3 @@ test "@ptrCast from var in empty struct to nullable" {
13 var x: ?*const u8 = @ptrCast(?*const u8, &container.c);13 var x: ?*const u8 = @ptrCast(?*const u8, &container.c);
14 expect(x.?.* == 4);14 expect(x.?.* == 4);
15}15}
16
test/stage1/behavior/eval.zig+13-5
...@@ -93,11 +93,13 @@ pub const Vec3 = struct {...@@ -93,11 +93,13 @@ pub const Vec3 = struct {
93 data: [3]f32,93 data: [3]f32,
94};94};
95pub fn vec3(x: f32, y: f32, z: f32) Vec3 {95pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
96 return Vec3{ .data = []f32{96 return Vec3{
97 x,97 .data = []f32{
98 y,98 x,
99 z,99 y,
100 } };100 z,
101 },
102 };
101}103}
102104
103test "constant expressions" {105test "constant expressions" {
...@@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 {...@@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 {
776fn scalar(x: u32) u32 {778fn scalar(x: u32) u32 {
777 return x;779 return x;
778}780}
781
782test "no undeclared identifier error in unanalyzed branches" {
783 if (false) {
784 lol_this_doesnt_exist = nonsense;
785 }
786}
test/stage1/behavior/fn.zig-1
...@@ -205,4 +205,3 @@ test "extern struct with stdcallcc fn pointer" {...@@ -205,4 +205,3 @@ test "extern struct with stdcallcc fn pointer" {
205 s.ptr = S.foo;205 s.ptr = S.foo;
206 expect(s.ptr() == 1234);206 expect(s.ptr() == 1234);
207}207}
208
test/stage1/behavior/import.zig+1-1
...@@ -12,7 +12,7 @@ test "importing the same thing gives the same import" {...@@ -12,7 +12,7 @@ test "importing the same thing gives the same import" {
1212
13test "import in non-toplevel scope" {13test "import in non-toplevel scope" {
14 const S = struct {14 const S = struct {
15 use @import("import/a_namespace.zig");15 usingnamespace @import("import/a_namespace.zig");
16 };16 };
17 expectEqual(i32(1234), S.foo());17 expectEqual(i32(1234), S.foo());
18}18}
test/stage1/behavior/popcount.zig-1
...@@ -41,4 +41,3 @@ fn testPopCount() void {...@@ -41,4 +41,3 @@ fn testPopCount() void {
41 expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);41 expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
42 }42 }
43}43}
44
test/stage1/behavior/reflection.zig-1
...@@ -93,4 +93,3 @@ const Bar = union(enum) {...@@ -93,4 +93,3 @@ const Bar = union(enum) {
93 Three: bool,93 Three: bool,
94 Four: f64,94 Four: f64,
95};95};
96
test/stage1/behavior/struct.zig+29
...@@ -549,3 +549,32 @@ test "packed struct with fp fields" {...@@ -549,3 +549,32 @@ test "packed struct with fp fields" {
549 expectEqual(f32(11.0), s.data[1]);549 expectEqual(f32(11.0), s.data[1]);
550 expectEqual(f32(20.0), s.data[2]);550 expectEqual(f32(20.0), s.data[2]);
551}551}
552
553test "use within struct scope" {
554 const S = struct {
555 usingnamespace struct {
556 pub fn inner() i32 {
557 return 42;
558 }
559 };
560 };
561 expectEqual(i32(42), S.inner());
562}
563
564test "default struct initialization fields" {
565 const S = struct {
566 a: i32 = 1234,
567 b: i32,
568 };
569 const x = S{
570 .b = 5,
571 };
572 if (x.a + x.b != 1239) {
573 @compileError("it should be comptime known");
574 }
575 var five: i32 = 5;
576 const y = S{
577 .b = five,
578 };
579 expectEqual(1239, x.a + x.b);
580}
test/stage1/behavior/this.zig-1
...@@ -32,4 +32,3 @@ test "this refer to container" {...@@ -32,4 +32,3 @@ test "this refer to container" {
32 expect(pt.x == 13);32 expect(pt.x == 13);
33 expect(pt.y == 35);33 expect(pt.y == 35);
34}34}
35
test/stage1/behavior/type_info.zig+8-8
...@@ -177,7 +177,7 @@ fn testEnum() void {...@@ -177,7 +177,7 @@ fn testEnum() void {
177 expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));177 expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
178 expect(os_info.Enum.fields[3].value == 3);178 expect(os_info.Enum.fields[3].value == 3);
179 expect(os_info.Enum.tag_type == u2);179 expect(os_info.Enum.tag_type == u2);
180 expect(os_info.Enum.defs.len == 0);180 expect(os_info.Enum.decls.len == 0);
181}181}
182182
183test "type info: union info" {183test "type info: union info" {
...@@ -194,7 +194,7 @@ fn testUnion() void {...@@ -194,7 +194,7 @@ fn testUnion() void {
194 expect(typeinfo_info.Union.fields[4].enum_field != null);194 expect(typeinfo_info.Union.fields[4].enum_field != null);
195 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);195 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
196 expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));196 expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
197 expect(typeinfo_info.Union.defs.len == 21);197 expect(typeinfo_info.Union.decls.len == 21);
198198
199 const TestNoTagUnion = union {199 const TestNoTagUnion = union {
200 Foo: void,200 Foo: void,
...@@ -232,12 +232,12 @@ fn testStruct() void {...@@ -232,12 +232,12 @@ fn testStruct() void {
232 expect(struct_info.Struct.fields.len == 3);232 expect(struct_info.Struct.fields.len == 3);
233 expect(struct_info.Struct.fields[1].offset == null);233 expect(struct_info.Struct.fields[1].offset == null);
234 expect(struct_info.Struct.fields[2].field_type == *TestStruct);234 expect(struct_info.Struct.fields[2].field_type == *TestStruct);
235 expect(struct_info.Struct.defs.len == 2);235 expect(struct_info.Struct.decls.len == 2);
236 expect(struct_info.Struct.defs[0].is_pub);236 expect(struct_info.Struct.decls[0].is_pub);
237 expect(!struct_info.Struct.defs[0].data.Fn.is_extern);237 expect(!struct_info.Struct.decls[0].data.Fn.is_extern);
238 expect(struct_info.Struct.defs[0].data.Fn.lib_name == null);238 expect(struct_info.Struct.decls[0].data.Fn.lib_name == null);
239 expect(struct_info.Struct.defs[0].data.Fn.return_type == void);239 expect(struct_info.Struct.decls[0].data.Fn.return_type == void);
240 expect(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);240 expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);
241}241}
242242
243const TestStruct = packed struct {243const TestStruct = packed struct {
test/stage1/behavior/undefined.zig-1
...@@ -66,4 +66,3 @@ test "type name of undefined" {...@@ -66,4 +66,3 @@ test "type name of undefined" {
66 const x = undefined;66 const x = undefined;
67 expect(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));67 expect(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
68}68}
69
test/stage1/behavior/union.zig+1-1
...@@ -374,7 +374,7 @@ const Attribute = union(enum) {...@@ -374,7 +374,7 @@ const Attribute = union(enum) {
374fn setAttribute(attr: Attribute) void {}374fn setAttribute(attr: Attribute) void {}
375375
376fn Setter(attr: Attribute) type {376fn Setter(attr: Attribute) type {
377 return struct{377 return struct {
378 fn set() void {378 fn set() void {
379 setAttribute(attr);379 setAttribute(attr);
380 }380 }
test/stage1/behavior/widening.zig-1
...@@ -25,4 +25,3 @@ test "float widening" {...@@ -25,4 +25,3 @@ test "float widening" {
25 var d: f128 = c;25 var d: f128 = c;
26 expect(d == a);26 expect(d == a);
27}27}
28
test/standalone/load_dynamic_library/main.zig+3-3
...@@ -1,12 +1,12 @@...@@ -1,12 +1,12 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() !void {3pub fn main() !void {
4 const args = try std.os.argsAlloc(std.debug.global_allocator);4 const args = try std.process.argsAlloc(std.debug.global_allocator);
5 defer std.os.argsFree(std.debug.global_allocator, args);5 defer std.process.argsFree(std.debug.global_allocator, args);
66
7 const dynlib_name = args[1];7 const dynlib_name = args[1];
88
9 var lib = try std.DynLib.open(std.debug.global_allocator, dynlib_name);9 var lib = try std.DynLib.open(dynlib_name);
10 defer lib.close();10 defer lib.close();
1111
12 const addr = lib.lookup("add") orelse return error.SymbolNotFound;12 const addr = lib.lookup("add") orelse return error.SymbolNotFound;
test/standalone/use_alias/c.zig+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1pub use @cImport(@cInclude("foo.h"));1pub usingnamespace @cImport(@cInclude("foo.h"));
test/tests.zig+3-3
...@@ -341,7 +341,7 @@ pub const CompareOutputContext = struct {...@@ -341,7 +341,7 @@ pub const CompareOutputContext = struct {
341 \\341 \\
342 \\========= Expected this output: =========342 \\========= Expected this output: =========
343 \\{}343 \\{}
344 \\================================================344 \\========= But found: ====================
345 \\{}345 \\{}
346 \\346 \\
347 , self.expected_output, stdout.toSliceConst());347 , self.expected_output, stdout.toSliceConst());
...@@ -1036,7 +1036,7 @@ pub const TranslateCContext = struct {...@@ -1036,7 +1036,7 @@ pub const TranslateCContext = struct {
1036 \\1036 \\
1037 \\========= Expected this output: ================1037 \\========= Expected this output: ================
1038 \\{}1038 \\{}
1039 \\================================================1039 \\========= But found: ===========================
1040 \\{}1040 \\{}
1041 \\1041 \\
1042 , expected_line, stdout);1042 , expected_line, stdout);
...@@ -1211,7 +1211,7 @@ pub const GenHContext = struct {...@@ -1211,7 +1211,7 @@ pub const GenHContext = struct {
1211 \\1211 \\
1212 \\========= Expected this output: ================1212 \\========= Expected this output: ================
1213 \\{}1213 \\{}
1214 \\================================================1214 \\========= But found: ===========================
1215 \\{}1215 \\{}
1216 \\1216 \\
1217 , expected_line, actual_h);1217 , expected_line, actual_h);