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
630630 "os/windows/bits.zig"
631631 "os/windows/error.zig"
632632 "os/windows/kernel32.zig"
633 "os/windows/lang.zig"
633634 "os/windows/ntdll.zig"
634635 "os/windows/ole32.zig"
635636 "os/windows/shell32.zig"
637 "os/windows/sublang.zig"
636638 "os/zen.zig"
637639 "packed_int_array.zig"
638640 "pdb.zig"
......@@ -6066,6 +6068,8 @@ set(ZIG_LIBC_FILES
60666068 "include/x86_64-linux-musl/bits/stat.h"
60676069 "include/x86_64-linux-musl/bits/syscall.h"
60686070 "include/x86_64-linux-musl/bits/user.h"
6071 "include/wasm32-freestanding-musl/bits/alltypes.h"
6072 "include/wasm32-freestanding-musl/errno.h"
60696073 "musl/arch/aarch64/atomic_arch.h"
60706074 "musl/arch/aarch64/bits/alltypes.h.in"
60716075 "musl/arch/aarch64/bits/endian.h"
......@@ -6726,9 +6730,13 @@ add_custom_command(
67266730 "-Doutput-dir=${CMAKE_BINARY_DIR}"
67276731 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
67286732 DEPENDS
6733 "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig"
67296734 "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig"
67306735 "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig"
67316736 "${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"
67326740)
67336741add_custom_target(userland_target DEPENDS "${LIBUSERLAND}")
67346742add_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**,
88 * [Introduction](https://ziglang.org/#Introduction)
99 * [Download & Documentation](https://ziglang.org/download)
1010 * [Community](https://github.com/ziglang/zig/wiki/Community)
11 * [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md)
1112
1213## Building from Source
1314
......@@ -96,95 +97,3 @@ use stage 1.
9697```
9798./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
9899```
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
2828 docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm8-1 -j2 $BUILD_SOURCEVERSION
2929 TARBALL="$(ls $ARTIFACTSDIR)"
3030 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
3333 SHASUM=$(sha256sum $ARTIFACTSDIR/$TARBALL | cut '-d ' -f1)
3434 BYTESIZE=$(wc -c < $ARTIFACTSDIR/$TARBALL)
ci/azure/macos_script+3-3
......@@ -6,7 +6,7 @@ set -e
66brew install s3cmd gcc@8
77
88ZIGDIR="$(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"
1010PREFIX="$HOME/$CACHE_BASENAME"
1111TMPDIR="$HOME/tmpz"
1212JOBS="-j2"
......@@ -62,7 +62,7 @@ else
6262 cd $HOME
6363 tar cfJ "$CACHE_BASENAME.tar.xz" "$CACHE_BASENAME"
6464 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"
6666fi
6767
6868cd $ZIGDIR
......@@ -85,7 +85,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
8585 tar cfJ "$TARBALL" "$DIRNAME"
8686
8787 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
9090 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
9191 BYTESIZE=$(wc -c < $TARBALL)
ci/azure/pipelines.yml+1-1
......@@ -1,7 +1,7 @@
11jobs:
22- job: BuildMacOS
33 pool:
4 vmImage: 'macOS 10.13'
4 vmImage: 'macOS 10.14'
55
66 timeoutInMinutes: 360
77
ci/azure/update_download_page+1-1
......@@ -35,7 +35,7 @@ env
3535"../$ZIG" run update-download-page.zig
3636
3737mv "$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/
3939s3cmd put -P "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
4040s3cmd put -P www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
4141s3cmd 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
1919 7z a "$TARBALL" "$DIRNAME"
2020
2121 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
2424 SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1)
2525 BYTESIZE=$(wc -c < $TARBALL)
ci/srht/freebsd_script+1-1
......@@ -36,7 +36,7 @@ if [ -f ~/.s3cfg ]; then
3636 mv release "$DIRNAME"
3737 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
4141 SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
4242 BYTESIZE=$(wc -c < $TARBALL)
doc/docgen.zig+1-1
......@@ -788,7 +788,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
788788 std.zig.Token.Id.Keyword_try,
789789 std.zig.Token.Id.Keyword_union,
790790 std.zig.Token.Id.Keyword_unreachable,
791 std.zig.Token.Id.Keyword_use,
791 std.zig.Token.Id.Keyword_usingnamespace,
792792 std.zig.Token.Id.Keyword_var,
793793 std.zig.Token.Id.Keyword_volatile,
794794 std.zig.Token.Id.Keyword_allowzero,
doc/langref.html.in+61-12
......@@ -2026,9 +2026,9 @@ fn foo(bytes: []u8) u32 {
20262026 {#header_open|allowzero#}
20272027 <p>
20282028 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 pointer
2030 did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a
2031 {#link|Pointer Cast Invalid Null#} panic:
2029 freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use
2030 {#link|Optional Pointers#} instead. In this code example, if the pointer did not have the
2031 {#syntax#}allowzero{#endsyntax#} attribute, this would be a {#link|Pointer Cast Invalid Null#} panic:
20322032 </p>
20332033 {#code_begin|test|allowzero#}
20342034const std = @import("std");
......@@ -2263,6 +2263,28 @@ test "linked list" {
22632263}
22642264 {#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
22662288 {#header_open|extern struct#}
22672289 <p>An {#syntax#}extern struct{#endsyntax#} has in-memory layout guaranteed to match the
22682290 C ABI for the target.</p>
......@@ -3271,6 +3293,7 @@ test "for else" {
32713293 var items = []?i32 { 3, 4, null, 5 };
32723294
32733295 // 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.
32743297 var sum: i32 = 0;
32753298 const result = for (items) |value| {
32763299 if (value == null) {
......@@ -7545,7 +7568,7 @@ pub const TypeInfo = union(TypeId) {
75457568 pub const Struct = struct {
75467569 layout: ContainerLayout,
75477570 fields: []StructField,
7548 defs: []Definition,
7571 decls: []Declaration,
75497572 };
75507573
75517574 pub const Optional = struct {
......@@ -7573,7 +7596,7 @@ pub const TypeInfo = union(TypeId) {
75737596 layout: ContainerLayout,
75747597 tag_type: type,
75757598 fields: []EnumField,
7576 defs: []Definition,
7599 decls: []Declaration,
75777600 };
75787601
75797602 pub const UnionField = struct {
......@@ -7586,7 +7609,7 @@ pub const TypeInfo = union(TypeId) {
75867609 layout: ContainerLayout,
75877610 tag_type: ?type,
75887611 fields: []UnionField,
7589 defs: []Definition,
7612 decls: []Declaration,
75907613 };
75917614
75927615 pub const CallingConvention = enum {
......@@ -7622,7 +7645,7 @@ pub const TypeInfo = union(TypeId) {
76227645 child: type,
76237646 };
76247647
7625 pub const Definition = struct {
7648 pub const Declaration = struct {
76267649 name: []const u8,
76277650 is_pub: bool,
76287651 data: Data,
......@@ -7630,9 +7653,9 @@ pub const TypeInfo = union(TypeId) {
76307653 pub const Data = union(enum) {
76317654 Type: type,
76327655 Var: type,
7633 Fn: FnDef,
7656 Fn: FnDecl,
76347657
7635 pub const FnDef = struct {
7658 pub const FnDecl = struct {
76367659 fn_type: type,
76377660 inline_type: Inline,
76387661 calling_convention: CallingConvention,
......@@ -8466,6 +8489,8 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
84668489 </li>
84678490 <li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
84688491 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>
84698494 <li>
84708495 Is the maximum number of bytes that you will need bounded by a number known at
84718496 {#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>
89969021 {#header_close#}
89979022 {#header_close#}
89989023 {#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>
89999026 {#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#}
90019030 {#target_wasm#}
90029031extern fn print(i32) void;
90039032
......@@ -9006,7 +9035,22 @@ export fn add(a: i32, b: i32) void {
90069035}
90079036 {#code_end#}
90089037 {#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>
90099052 {#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>
90109054 {#code_begin|exe|wasi#}
90119055 {#target_wasi#}
90129056const std = @import("std");
......@@ -9020,6 +9064,10 @@ pub fn main() !void {
90209064 }
90219065}
90229066 {#code_end#}
9067 <pre><code>$ wasmer run wasi.wasm 123 hello
90680: wasi.wasm
90691: 123
90702: hello</code></pre>
90239071 {#header_close#}
90249072 {#header_close#}
90259073 {#header_open|Targets#}
......@@ -9260,6 +9308,7 @@ Available libcs:
92609308 s390x-linux-musl
92619309 sparc-linux-gnu
92629310 sparcv9-linux-gnu
9311 wasm32-freestanding-musl
92639312 x86_64-linux-gnu
92649313 x86_64-linux-gnux32
92659314 x86_64-linux-musl</code></pre>
......@@ -9892,7 +9941,7 @@ KEYWORD_try &lt;- 'try' end_of_word
98929941KEYWORD_undefined &lt;- 'undefined' end_of_word
98939942KEYWORD_union &lt;- 'union' end_of_word
98949943KEYWORD_unreachable &lt;- 'unreachable' end_of_word
9895KEYWORD_use &lt;- 'use' end_of_word
9944KEYWORD_usingnamespace &lt;- 'usingnamespace' end_of_word
98969945KEYWORD_var &lt;- 'var' end_of_word
98979946KEYWORD_volatile &lt;- 'volatile' end_of_word
98989947KEYWORD_while &lt;- 'while' end_of_word
......@@ -9909,7 +9958,7 @@ keyword &lt;- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_anyerror
99099958 / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
99109959 / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
99119960 / 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>
99139962 {#header_close#}
99149963 {#header_open|Zen#}
99159964 <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 @@
1pub use @cImport({
1pub usingnamespace @cImport({
22 @cDefine("__STDC_CONSTANT_MACROS", "");
33 @cDefine("__STDC_LIMIT_MACROS", "");
44 @cInclude("inttypes.h");
src-self-hosted/clang.zig+209-213
......@@ -1,5 +1,6 @@
11pub const struct_ZigClangAPValue = @OpaqueType();
22pub const struct_ZigClangAPSInt = @OpaqueType();
3pub const struct_ZigClangAPFloat = @OpaqueType();
34pub const struct_ZigClangASTContext = @OpaqueType();
45pub const struct_ZigClangASTUnit = @OpaqueType();
56pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();
......@@ -12,7 +13,7 @@ pub const struct_ZigClangCStyleCastExpr = @OpaqueType();
1213pub const struct_ZigClangCallExpr = @OpaqueType();
1314pub const struct_ZigClangCaseStmt = @OpaqueType();
1415pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
15pub const ZigClangCompoundStmt = @OpaqueType();
16pub const struct_ZigClangCompoundStmt = @OpaqueType();
1617pub const struct_ZigClangConditionalOperator = @OpaqueType();
1718pub const struct_ZigClangConstantArrayType = @OpaqueType();
1819pub const struct_ZigClangContinueStmt = @OpaqueType();
......@@ -33,7 +34,7 @@ pub const struct_ZigClangFieldDecl = @OpaqueType();
3334pub const struct_ZigClangFileID = @OpaqueType();
3435pub const struct_ZigClangForStmt = @OpaqueType();
3536pub const struct_ZigClangFullSourceLoc = @OpaqueType();
36pub const ZigClangFunctionDecl = @OpaqueType();
37pub const struct_ZigClangFunctionDecl = @OpaqueType();
3738pub const struct_ZigClangFunctionProtoType = @OpaqueType();
3839pub const struct_ZigClangIfStmt = @OpaqueType();
3940pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
......@@ -68,7 +69,8 @@ pub const struct_ZigClangUnaryOperator = @OpaqueType();
6869pub const struct_ZigClangValueDecl = @OpaqueType();
6970pub const struct_ZigClangVarDecl = @OpaqueType();
7071pub const struct_ZigClangWhileStmt = @OpaqueType();
71pub const ZigClangFunctionType = @OpaqueType();
72pub const struct_ZigClangFunctionType = @OpaqueType();
73pub const struct_ZigClangPredefinedExpr = @OpaqueType();
7274
7375pub const ZigClangBO = extern enum {
7476 PtrMemD,
......@@ -450,188 +452,6 @@ pub const ZigClangAPValueKind = extern enum {
450452 AddrLabelDiff,
451453};
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
635455pub const ZigClangDeclKind = extern enum {
636456 AccessSpec,
637457 Block,
......@@ -709,10 +529,6 @@ pub const ZigClangDeclKind = extern enum {
709529 TranslationUnit,
710530};
711531
712pub const struct_ZigClangQualType = extern struct {
713 ptr: ?*c_void,
714};
715
716532pub const ZigClangBuiltinTypeKind = extern enum {
717533 OCLImage1dRO,
718534 OCLImage1dArrayRO,
......@@ -862,39 +678,219 @@ pub const ZigClangStorageClass = extern enum {
862678 Register,
863679};
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;
868pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
689pub const ZigClangStringLiteral_StringKind = extern enum {
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;
873pub extern fn ZigClangDeclStmt_decl_end(self: *const ZigClangDeclStmt) ZigClangDeclStmt_const_decl_iterator;
766pub extern fn ZigClangFunctionType_getNoReturnAttr(self: *const ZigClangFunctionType) bool;
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;
876pub extern fn ZigClangVarDecl_getInit(*const ZigClangVarDecl) ?*const ZigClangExpr;
877pub extern fn ZigClangVarDecl_getTLSKind(self: ?*const struct_ZigClangVarDecl) ZigClangVarDecl_TLSKind;
878pub const ZigClangVarDecl_TLSKind = extern enum {
879 None,
880 Static,
881 Dynamic,
770pub extern fn ZigClangFunctionProtoType_isVariadic(self: *const struct_ZigClangFunctionProtoType) bool;
771pub extern fn ZigClangFunctionProtoType_getNumParams(self: *const struct_ZigClangFunctionProtoType) c_uint;
772pub extern fn ZigClangFunctionProtoType_getParamType(self: *const struct_ZigClangFunctionProtoType, i: c_uint) ZigClangQualType;
773
774pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
775pub const ZigClangQualType = struct_ZigClangQualType;
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,
882868};
883869
884pub extern fn ZigClangImplicitCastExpr_getBeginLoc(*const ZigClangImplicitCastExpr) ZigClangSourceLocation;
885pub extern fn ZigClangImplicitCastExpr_getCastKind(*const ZigClangImplicitCastExpr) ZigClangCK;
886pub extern fn ZigClangImplicitCastExpr_getSubExpr(*const ZigClangImplicitCastExpr) *const ZigClangExpr;
870pub const struct_ZigClangQualType = extern struct {
871 ptr: ?*c_void,
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;
899pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;
900pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;
895pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
896pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
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 {
670670 Compilation.DarwinVersionMin.None => blk: {
671671 assert(comp.target.getOs() == .macosx);
672672 result.kind = Kind.MacOS;
673 break :blk "10.10";
673 break :blk "10.14";
674674 },
675675 };
676676
src-self-hosted/stage1.zig+62
......@@ -15,11 +15,16 @@ const self_hosted_main = @import("main.zig");
1515const Args = arg.Args;
1616const Flag = arg.Flag;
1717const errmsg = @import("errmsg.zig");
18const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
1819
1920var stderr_file: fs.File = undefined;
2021var stderr: *io.OutStream(fs.File.WriteError) = undefined;
2122var stdout: *io.OutStream(fs.File.WriteError) = undefined;
2223
24comptime {
25 _ = @import("dep_tokenizer.zig");
26}
27
2328// ABI warning
2429export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
2530 const info_zen = @import("main.zig").info_zen;
......@@ -393,3 +398,60 @@ fn printErrMsgToFile(
393398 try stream.writeByteNTimes('~', last_token.end - first_token.start);
394399 try stream.write("\n");
395400}
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");
66const assert = std.debug.assert;
77const ast = std.zig.ast;
88const Token = std.zig.Token;
9use @import("clang.zig");
9usingnamespace @import("clang.zig");
1010
1111pub const Mode = enum {
1212 import,
src/all_types.hpp+21-6
......@@ -1069,6 +1069,7 @@ struct TypeStructField {
10691069 size_t gen_index;
10701070 size_t offset; // byte offset from beginning of struct
10711071 AstNode *decl_node;
1072 ConstExprValue *init_val; // null and then memoized
10721073 uint32_t bit_offset_in_host; // offset from the memory at gen_index
10731074 uint32_t host_int_bytes; // size of host integer
10741075};
......@@ -1633,6 +1634,12 @@ enum WantPIC {
16331634 WantPICEnabled,
16341635};
16351636
1637enum WantStackCheck {
1638 WantStackCheckAuto,
1639 WantStackCheckDisabled,
1640 WantStackCheckEnabled,
1641};
1642
16361643struct CFile {
16371644 ZigList<const char *> args;
16381645 const char *source_path;
......@@ -1790,6 +1797,8 @@ struct CodeGen {
17901797 TldFn *panic_tld_fn;
17911798 AstNode *root_export_decl;
17921799
1800 WantPIC want_pic;
1801 WantStackCheck want_stack_check;
17931802 CacheHash cache_hash;
17941803 ErrColor err_color;
17951804 uint32_t next_unresolved_index;
......@@ -1807,8 +1816,6 @@ struct CodeGen {
18071816 bool have_dllmain_crt_startup;
18081817 bool have_pub_panic;
18091818 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
18121819 bool c_want_stdint;
18131820 bool c_want_stdbool;
18141821 bool verbose_tokenize;
......@@ -1824,6 +1831,7 @@ struct CodeGen {
18241831 bool enable_time_report;
18251832 bool system_linker_hack;
18261833 bool reported_bad_link_libc_error;
1834 bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
18271835
18281836 //////////////////////////// Participates in Input Parameter Cache Hash
18291837 /////// Note: there is a separate cache hash for builtin.zig, when adding fields,
......@@ -1850,10 +1858,8 @@ struct CodeGen {
18501858 BuildMode build_mode;
18511859 OutType out_type;
18521860 const ZigTarget *zig_target;
1853 TargetSubsystem subsystem;
1861 TargetSubsystem subsystem; // careful using this directly; see detect_subsystem
18541862 ValgrindSupport valgrind_support;
1855 WantPIC want_pic;
1856 bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl.
18571863 bool strip_debug_symbols;
18581864 bool is_test_build;
18591865 bool is_single_threaded;
......@@ -1863,7 +1869,9 @@ struct CodeGen {
18631869 bool is_dummy_so;
18641870 bool disable_gen_h;
18651871 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
18681876 Buf *mmacosx_version_min;
18691877 Buf *mios_version_min;
......@@ -2299,6 +2307,7 @@ enum IrInstructionId {
22992307 IrInstructionIdAssertZero,
23002308 IrInstructionIdAssertNonNull,
23012309 IrInstructionIdHasDecl,
2310 IrInstructionIdUndeclaredIdent,
23022311};
23032312
23042313struct IrInstruction {
......@@ -3512,6 +3521,12 @@ struct IrInstructionHasDecl {
35123521 IrInstruction *name;
35133522};
35143523
3524struct IrInstructionUndeclaredIdent {
3525 IrInstruction base;
3526
3527 Buf *name;
3528};
3529
35153530static const size_t slice_ptr_index = 0;
35163531static 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
965965 return entry;
966966}
967967
968static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry,
969 Buf *type_name)
970{
968ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) {
971969 size_t backward_branch_count = 0;
972970 size_t backward_branch_quota = default_backward_branch_quota;
973971 return ir_eval_const_value(g, scope, node, type_entry,
......@@ -981,6 +979,17 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
981979 return g->builtin_types.entry_invalid;
982980
983981 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);
984993 return result->data.x_type;
985994}
986995
......@@ -2178,10 +2187,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
21782187 type_struct_field->src_index = i;
21792188 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 }
21852190 if (field_type->id == ZigTypeIdOpaque) {
21862191 add_node_error(g, field_node->data.struct_field.type,
21872192 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
27112716 if (ccc) {
27122717 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) {
27132718 g->have_c_main = true;
2714 g->subsystem = TargetSubsystemConsole;
27152719 } else if (buf_eql_str(symbol_name, "WinMain") &&
27162720 g->zig_target->os == OsWindows)
27172721 {
27182722 g->have_winmain = true;
2719 g->subsystem = TargetSubsystemWindows;
27202723 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") &&
27212724 g->zig_target->os == OsWindows)
27222725 {
......@@ -3442,11 +3445,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) {
34423445}
34433446
34443447
3445static bool is_container(ZigType *type_entry) {
3448bool is_container(ZigType *type_entry) {
34463449 switch (type_entry->id) {
34473450 case ZigTypeIdInvalid:
34483451 zig_unreachable();
34493452 case ZigTypeIdStruct:
3453 return !type_entry->data.structure.is_slice;
34503454 case ZigTypeIdEnum:
34513455 case ZigTypeIdUnion:
34523456 return true;
......@@ -3487,9 +3491,9 @@ bool is_array_ref(ZigType *type_entry) {
34873491 return array->id == ZigTypeIdArray;
34883492}
34893493
3490bool is_container_ref(ZigType *type_entry) {
3491 return is_ref(type_entry) ?
3492 is_container(type_entry->data.pointer.child_type) : is_container(type_entry);
3494bool is_container_ref(ZigType *parent_ty) {
3495 ZigType *ty = is_ref(parent_ty) ? parent_ty->data.pointer.child_type : parent_ty;
3496 return is_slice(ty) || is_container(ty);
34933497}
34943498
34953499ZigType *container_ref_type(ZigType *type_entry) {
......@@ -3754,49 +3758,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
37543758 analyze_fn_ir(g, fn_table_entry, return_type_node);
37553759}
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) {
37583762 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
37593763 preview_use_decl(g, src_use_node, decls_scope);
37603764 }
37613765
3762 ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value;
3763 if (type_is_invalid(use_target_value->type)) {
3766 ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value;
3767 if (type_is_invalid(use_expr->type)) {
37643768 decls_scope->any_imports_failed = true;
37653769 return;
37663770 }
37673771
37683772 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;
3773 assert(target_import);
3776 // The source struct for the imported symbols
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)) {
37763781 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)));
37783783 decls_scope->any_imports_failed = true;
37793784 return;
37803785 }
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) {
37833795 decls_scope->any_imports_failed = true;
37843796 }
37853797
3786 auto it = get_container_scope(target_import)->decl_table.entry_iterator();
3798 auto it = src_scope->decl_table.entry_iterator();
37873799 for (;;) {
37883800 auto *entry = it.next();
37893801 if (!entry)
37903802 break;
37913803
3804 Buf *target_tld_name = entry->key;
37923805 Tld *target_tld = entry->value;
3793 if (target_tld->import != target_import ||
3794 target_tld->visib_mod == VisibModPrivate)
3795 {
3806
3807 if (target_tld->visib_mod == VisibModPrivate) {
37963808 continue;
37973809 }
37983810
3799 Buf *target_tld_name = entry->key;
3811 if (target_tld->import != src_import) {
3812 continue;
3813 }
38003814
38013815 auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld);
38023816 if (existing_entry) {
......@@ -3811,10 +3825,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
38113825 }
38123826 }
38133827
3814 for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) {
3815 AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i);
3828 for (size_t i = 0; i < src_scope->use_decls.length; i += 1) {
3829 AstNode *use_decl_node = src_scope->use_decls.at(i);
38163830 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);
38183832 }
38193833}
38203834
......@@ -3826,7 +3840,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
38263840 {
38273841 return;
38283842 }
3829 add_symbols_from_import(g, node, node, decls_scope);
3843 add_symbols_from_container(g, node, node, decls_scope);
38303844}
38313845
38323846void 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
38923906 buf_init_from_buf(&namespace_name, &package->pkg_path);
38933907 if (source_kind == SourceKindNonRoot) {
38943908 assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir));
3895
3896 if (buf_len(&namespace_name) != 0) buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);
3897 buf_append_mem(&namespace_name, buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1,
3898 buf_len(&noextname) - (buf_len(&resolved_root_src_dir) + 1));
3909 if (buf_len(&namespace_name) != 0) {
3910 buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR);
3911 }
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 }
38993920 buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR);
39003921 }
39013922 Buf *bare_name = buf_alloc();
......@@ -3937,7 +3958,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
39373958 if (is_pub) {
39383959 if (buf_eql_str(proto_name, "main")) {
39393960 g->have_pub_main = true;
3940 g->subsystem = TargetSubsystemConsole;
39413961 } else if (buf_eql_str(proto_name, "panic")) {
39423962 g->have_pub_panic = true;
39433963 }
......@@ -6368,12 +6388,14 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
63686388 len_debug_size_in_bits,
63696389 len_debug_align_in_bits,
63706390 len_offset_in_bits,
6371 0, usize_llvm_di_type),
6391 ZigLLVM_DIFlags_Zero,
6392 usize_llvm_di_type),
63726393 };
63736394 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
63746395 compile_unit_scope,
63756396 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,
63776399 nullptr, di_element_types, 1, 0, nullptr, "");
63786400
63796401 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
64056427 ptr_debug_size_in_bits,
64066428 ptr_debug_align_in_bits,
64076429 ptr_offset_in_bits,
6408 0, get_llvm_di_type(g, ptr_type)),
6430 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_type)),
64096431 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
64106432 "len", di_file, line,
64116433 len_debug_size_in_bits,
64126434 len_debug_align_in_bits,
64136435 len_offset_in_bits,
6414 0, usize_llvm_di_type),
6436 ZigLLVM_DIFlags_Zero, usize_llvm_di_type),
64156437 };
64166438 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
64176439 compile_unit_scope,
64186440 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,
64206443 nullptr, di_element_types, 2, 0, nullptr, "");
64216444
64226445 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
65776600 debug_size_in_bits,
65786601 debug_align_in_bits,
65796602 debug_offset_in_bits,
6580 0, field_di_type);
6603 ZigLLVM_DIFlags_Zero, field_di_type);
65816604 assert(di_element_types[debug_field_index]);
65826605 debug_field_index += 1;
65836606 }
......@@ -6590,7 +6613,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
65906613 di_file, line,
65916614 debug_size_in_bits,
65926615 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
65956619 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type);
65966620 struct_type->llvm_di_type = replacement_di_type;
......@@ -6619,7 +6643,8 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) {
66196643 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
66206644 debug_size_in_bits,
66216645 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, "");
66236648 return;
66246649 }
66256650
......@@ -6703,7 +6728,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
67036728 store_size_in_bits,
67046729 abi_align_in_bits,
67056730 0,
6706 0, field_di_type);
6731 ZigLLVM_DIFlags_Zero, field_di_type);
67076732
67086733 }
67096734
......@@ -6732,7 +6757,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
67326757 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
67336758 union_type->data.unionation.union_abi_size * 8,
67346759 most_aligned_union_member->abi_align * 8,
6735 0, union_inner_di_types,
6760 ZigLLVM_DIFlags_Zero, union_inner_di_types,
67366761 gen_field_count, 0, "");
67376762
67386763 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
67666791 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
67676792 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
67686793 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
67716796 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type,
67726797 union_type->data.unionation.gen_union_index);
......@@ -6779,7 +6804,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
67796804 most_aligned_union_member->size_in_bits,
67806805 8*most_aligned_union_member->abi_align,
67816806 union_offset_in_bits,
6782 0, union_di_type);
6807 ZigLLVM_DIFlags_Zero, union_di_type);
67836808
67846809 uint64_t tag_debug_size_in_bits = tag_type->size_in_bits;
67856810 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
67906815 tag_debug_size_in_bits,
67916816 tag_debug_align_in_bits,
67926817 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
67956820 ZigLLVMDIType *di_root_members[2];
67966821 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
68046829 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
68056830 debug_size_in_bits,
68066831 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
68096834 ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type);
68106835 union_type->llvm_di_type = replacement_di_type;
......@@ -6932,18 +6957,18 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) {
69326957 val_debug_size_in_bits,
69336958 val_debug_align_in_bits,
69346959 val_offset_in_bits,
6935 0, child_llvm_di_type),
6960 ZigLLVM_DIFlags_Zero, child_llvm_di_type),
69366961 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
69376962 "maybe", di_file, line,
69386963 maybe_debug_size_in_bits,
69396964 maybe_debug_align_in_bits,
69406965 maybe_offset_in_bits,
6941 0, bool_llvm_di_type),
6966 ZigLLVM_DIFlags_Zero, bool_llvm_di_type),
69426967 };
69436968 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
69446969 compile_unit_scope,
69456970 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,
69476972 nullptr, di_element_types, 2, 0, nullptr, "");
69486973
69496974 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) {
69967021 tag_debug_size_in_bits,
69977022 tag_debug_align_in_bits,
69987023 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)),
70007025 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type),
70017026 "value", di_file, line,
70027027 value_debug_size_in_bits,
70037028 value_debug_align_in_bits,
70047029 value_offset_in_bits,
7005 0, get_llvm_di_type(g, payload_type)),
7030 ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)),
70067031 };
70077032
70087033 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
......@@ -7011,7 +7036,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
70117036 di_file, line,
70127037 debug_size_in_bits,
70137038 debug_align_in_bits,
7014 0,
7039 ZigLLVM_DIFlags_Zero,
70157040 nullptr, di_element_types, 2, 0, nullptr, "");
70167041
70177042 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);
250250void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c);
251251
252252void 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
254256#endif
src/ast_render.cpp+1-1
......@@ -352,7 +352,7 @@ static void string_literal_escape(Buf *source, Buf *dest) {
352352 } else if (is_printable(c)) {
353353 buf_append_char(dest, c);
354354 } else {
355 buf_appendf(dest, "\\x%x", (int)c);
355 buf_appendf(dest, "\\x%02x", (int)c);
356356 }
357357 }
358358}
src/cache_hash.cpp+47-55
......@@ -5,6 +5,7 @@
55 * See http://opensource.org/licenses/MIT
66 */
77
8#include "userland.h"
89#include "cache_hash.hpp"
910#include "all_types.hpp"
1011#include "buffer.hpp"
......@@ -473,71 +474,62 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) {
473474 if (err == ErrorFileNotFound)
474475 return err;
475476 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));
477478 }
478479 return ErrorReadingDepFile;
479480 }
480 SplitIterator it = memSplit(buf_to_slice(contents), str("\r\n"));
481 // skip first line
482 SplitIterator_next(&it);
483 for (;;) {
484 Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);
485 if (!opt_line.is_some)
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) {
481 auto it = stage2_DepTokenizer_init(buf_ptr(contents), buf_len(contents));
482 // skip first token: target
483 {
484 auto result = stage2_DepTokenizer_next(&it);
485 switch (result.type_id) {
486 case stage2_DepNextResult::error:
499487 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));
501489 }
502 return ErrorInvalidDepFile;
503 }
504 opt_line.value.ptr += 1;
505 opt_line.value.len -= 2;
506 while (opt_line.value.len != 0 && opt_line.value.ptr[opt_line.value.len] != '"') {
507 opt_line.value.len -= 1;
508 }
509 if (opt_line.value.len == 0) {
510 if (verbose) {
511 fprintf(stderr, "unable to process invalid .d file %s: missing double quote\n", buf_ptr(dep_file_path));
512 }
513 return ErrorInvalidDepFile;
514 }
515 Buf *filename_buf = buf_create_from_slice(opt_line.value);
516 if ((err = cache_add_file(ch, filename_buf))) {
490 err = ErrorInvalidDepFile;
491 goto finish;
492 case stage2_DepNextResult::null:
493 err = ErrorNone;
494 goto finish;
495 case stage2_DepNextResult::target:
496 case stage2_DepNextResult::prereq:
497 err = ErrorNone;
498 break;
499 }
500 }
501 // Process 0+ preqreqs.
502 // clang is invoked in single-source mode so we never get more targets.
503 for (;;) {
504 auto result = stage2_DepTokenizer_next(&it);
505 switch (result.type_id) {
506 case stage2_DepNextResult::error:
517507 if (verbose) {
518 fprintf(stderr, "unable to add %s to cache: %s\n", buf_ptr(filename_buf), err_str(err));
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;
508 fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path));
536509 }
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));
537525 }
526 goto finish;
538527 }
539528 }
540 return ErrorNone;
529
530 finish:
531 stage2_DepTokenizer_deinit(&it);
532 return err;
541533}
542534
543535static Error write_manifest_file(CacheHash *ch) {
src/codegen.cpp+164-92
......@@ -48,7 +48,7 @@ static void init_darwin_native(CodeGen *g) {
4848 } else if (ios_target) {
4949 g->mios_version_min = buf_create_from_str(ios_target);
5050 } 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");
5252 }
5353}
5454
......@@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
100100
101101 codegen_add_time_event(g, "Initialize");
102102
103 g->subsystem = TargetSubsystemAuto;
103104 g->libc = libc;
104105 g->zig_target = target;
105106 g->cache_dir = cache_dir;
......@@ -296,6 +297,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
296297static void generate_error_name_table(CodeGen *g);
297298static bool value_is_all_undef(ConstExprValue *const_val);
298299static 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
300302static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
301303 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
......@@ -399,15 +401,6 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) {
399401 }
400402}
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
411404static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) {
412405 switch (id) {
413406 case GlobalLinkageIdInternal:
......@@ -596,8 +589,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
596589 addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong");
597590 addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
598591 }
599
600 add_probe_stack_attr(g, fn_table_entry->llvm_value);
592 }
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");
601595 }
602596 } else {
603597 maybe_import_dll(g, fn_table_entry->llvm_value, linkage);
......@@ -680,7 +674,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
680674 bool is_optimized = g->build_mode != BuildModeDebug;
681675 bool is_internal_linkage = (fn_table_entry->body_node != nullptr &&
682676 fn_table_entry->export_list.length == 0);
683 unsigned flags = 0;
677 unsigned flags = ZigLLVM_DIFlags_StaticMember;
684678 ZigLLVMDIScope *fn_di_scope = get_di_scope(g, scope->parent);
685679 assert(fn_di_scope != nullptr);
686680 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
......@@ -1526,53 +1520,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
15261520 generate_error_name_table(g);
15271521 assert(g->err_name_table != nullptr);
15281522
1529 size_t unwrap_err_msg_text_len = strlen(unwrap_err_msg_text);
1530 size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len;
1531 LLVMValueRef *err_buf_vals = allocate<LLVMValueRef>(err_buf_len);
1532 size_t i = 0;
1533 for (; i < unwrap_err_msg_text_len; i += 1) {
1534 err_buf_vals[i] = LLVMConstInt(LLVMInt8Type(), unwrap_err_msg_text[i], false);
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);
1523 // Generate the constant part of the error message
1524 LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1);
1525 LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), "");
1526 LLVMSetInitializer(msg_prefix, msg_prefix_init);
1527 LLVMSetLinkage(msg_prefix, LLVMInternalLinkage);
1528 LLVMSetGlobalConstant(msg_prefix, true);
15761529
15771530 Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false);
15781531 LLVMTypeRef fn_type_ref;
......@@ -1609,6 +1562,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
16091562 LLVMPositionBuilderAtEnd(g->builder, entry_block);
16101563 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
16121578 LLVMValueRef err_ret_trace_arg;
16131579 LLVMValueRef err_val;
16141580 if (g->have_err_ret_tracing) {
......@@ -1619,8 +1585,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
16191585 err_val = LLVMGetParam(fn_val, 0);
16201586 }
16211587
1588 // Fetch the error name from the global table
16221589 LLVMValueRef err_table_indices[] = {
1623 LLVMConstNull(g->builtin_types.entry_usize->llvm_type),
1590 LLVMConstNull(usize_ty->llvm_type),
16241591 err_val,
16251592 };
16261593 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) {
16311598 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, "");
16321599 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);
1637 LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, "");
1622 // Set the slice pointer
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, "");
1640 gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type);
1626 // Set the slice length
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
16441634 LLVMPositionBuilderAtEnd(g->builder, prev_block);
16451635 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location);
......@@ -2013,7 +2003,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
20132003 render_const_val_global(g, &instruction->value, "");
20142004 ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
20152005 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) {
20172007 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value,
20182008 get_llvm_type(g, instruction->value.type), "");
20192009 } else {
......@@ -5617,6 +5607,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
56175607 case IrInstructionIdBitCast:
56185608 case IrInstructionIdGlobalAsm:
56195609 case IrInstructionIdHasDecl:
5610 case IrInstructionIdUndeclaredIdent:
56205611 zig_unreachable();
56215612
56225613 case IrInstructionIdDeclVarGen:
......@@ -7252,7 +7243,7 @@ static void define_builtin_types(CodeGen *g) {
72527243 buf_init_from_str(&entry->name, "void");
72537244 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
72547245 0,
7255 ZigLLVMEncoding_DW_ATE_unsigned());
7246 ZigLLVMEncoding_DW_ATE_signed());
72567247 g->builtin_types.entry_void = entry;
72577248 g->primitive_type_table.put(&entry->name, entry);
72587249 }
......@@ -7427,6 +7418,21 @@ static const char *build_mode_to_str(BuildMode build_mode) {
74277418 zig_unreachable();
74287419}
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
74307436static bool detect_dynamic_link(CodeGen *g) {
74317437 if (g->is_dynamic)
74327438 return true;
......@@ -7458,6 +7464,37 @@ static bool detect_pic(CodeGen *g) {
74587464 zig_unreachable();
74597465}
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
74617498static bool detect_single_threaded(CodeGen *g) {
74627499 if (g->want_single_threaded)
74637500 return true;
......@@ -7476,6 +7513,7 @@ static bool detect_err_ret_tracing(CodeGen *g) {
74767513Buf *codegen_generate_builtin_source(CodeGen *g) {
74777514 g->have_dynamic_link = detect_dynamic_link(g);
74787515 g->have_pic = detect_pic(g);
7516 g->have_stack_probing = detect_stack_probing(g);
74797517 g->is_single_threaded = detect_single_threaded(g);
74807518 g->have_err_ret_tracing = detect_err_ret_tracing(g);
74817519
......@@ -7724,7 +7762,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
77247762 " pub const Struct = struct {\n"
77257763 " layout: ContainerLayout,\n"
77267764 " fields: []StructField,\n"
7727 " defs: []Definition,\n"
7765 " decls: []Declaration,\n"
77287766 " };\n"
77297767 "\n"
77307768 " pub const Optional = struct {\n"
......@@ -7752,7 +7790,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
77527790 " layout: ContainerLayout,\n"
77537791 " tag_type: type,\n"
77547792 " fields: []EnumField,\n"
7755 " defs: []Definition,\n"
7793 " decls: []Declaration,\n"
77567794 " };\n"
77577795 "\n"
77587796 " pub const UnionField = struct {\n"
......@@ -7765,7 +7803,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
77657803 " layout: ContainerLayout,\n"
77667804 " tag_type: ?type,\n"
77677805 " fields: []UnionField,\n"
7768 " defs: []Definition,\n"
7806 " decls: []Declaration,\n"
77697807 " };\n"
77707808 "\n"
77717809 " pub const CallingConvention = enum {\n"
......@@ -7801,7 +7839,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
78017839 " child: type,\n"
78027840 " };\n"
78037841 "\n"
7804 " pub const Definition = struct {\n"
7842 " pub const Declaration = struct {\n"
78057843 " name: []const u8,\n"
78067844 " is_pub: bool,\n"
78077845 " data: Data,\n"
......@@ -7809,9 +7847,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
78097847 " pub const Data = union(enum) {\n"
78107848 " Type: type,\n"
78117849 " Var: type,\n"
7812 " Fn: FnDef,\n"
7850 " Fn: FnDecl,\n"
78137851 "\n"
7814 " pub const FnDef = struct {\n"
7852 " pub const FnDecl = struct {\n"
78157853 " fn_type: type,\n"
78167854 " inline_type: Inline,\n"
78177855 " calling_convention: CallingConvention,\n"
......@@ -7864,6 +7902,28 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
78647902 //assert(EndianBig == 0);
78657903 //assert(EndianLittle == 1);
78667904 }
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 }
78677927 {
78687928 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little";
78697929 buf_appendf(contents, "pub const endian = %s;\n", endian_str);
......@@ -7880,6 +7940,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
78807940 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g)));
78817941 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
78837950 if (g->is_test_build) {
78847951 buf_appendf(contents,
78857952 "const TestFn = struct {\n"
......@@ -7923,6 +7990,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
79237990 cache_bool(&cache_hash, g->have_err_ret_tracing);
79247991 cache_bool(&cache_hash, g->libc_link_lib != nullptr);
79257992 cache_bool(&cache_hash, g->valgrind_support);
7993 cache_int(&cache_hash, detect_subsystem(g));
79267994
79277995 Buf digest = BUF_INIT;
79287996 buf_resize(&digest, 0);
......@@ -7982,6 +8050,7 @@ static void init(CodeGen *g) {
79828050
79838051 g->have_dynamic_link = detect_dynamic_link(g);
79848052 g->have_pic = detect_pic(g);
8053 g->have_stack_probing = detect_stack_probing(g);
79858054 g->is_single_threaded = detect_single_threaded(g);
79868055 g->have_err_ret_tracing = detect_err_ret_tracing(g);
79878056
......@@ -7989,10 +8058,6 @@ static void init(CodeGen *g) {
79898058 g->is_single_threaded = true;
79908059 }
79918060
7992 if (g->is_test_build) {
7993 g->subsystem = TargetSubsystemConsole;
7994 }
7995
79968061 assert(g->root_out_name);
79978062 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name));
79988063
......@@ -9077,8 +9142,11 @@ static void gen_h_file(CodeGen *g) {
90779142 if (!out_h)
90789143 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)));
9081 buf_upcase(export_macro);
9145 Buf *export_macro = nullptr;
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
90839151 Buf *extern_c_macro = preprocessor_mangle(buf_sprintf("%s_EXTERN_C", buf_ptr(g->root_out_name)));
90849152 buf_upcase(extern_c_macro);
......@@ -9103,10 +9171,11 @@ static void gen_h_file(CodeGen *g) {
91039171 FnExport *fn_export = &fn_table_entry->export_list.items[0];
91049172 symbol_name = &fn_export->name;
91059173 }
9174
91069175 buf_appendf(&h_buf, "%s %s %s(",
9107 buf_ptr(export_macro),
9108 buf_ptr(&return_type_c),
9109 buf_ptr(symbol_name));
9176 buf_ptr(g->is_dynamic ? export_macro : extern_c_macro),
9177 buf_ptr(&return_type_c),
9178 buf_ptr(symbol_name));
91109179
91119180 Buf param_type_c = BUF_INIT;
91129181 if (fn_type_id->param_count > 0) {
......@@ -9156,13 +9225,16 @@ static void gen_h_file(CodeGen *g) {
91569225 fprintf(out_h, "#define %s\n", buf_ptr(extern_c_macro));
91579226 fprintf(out_h, "#endif\n");
91589227 fprintf(out_h, "\n");
9159 fprintf(out_h, "#if defined(_WIN32)\n");
9160 fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro));
9161 fprintf(out_h, "#else\n");
9162 fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n",
9228
9229 if (g->is_dynamic) {
9230 fprintf(out_h, "#if defined(_WIN32)\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",
91639234 buf_ptr(export_macro), buf_ptr(extern_c_macro));
9164 fprintf(out_h, "#endif\n");
9165 fprintf(out_h, "\n");
9235 fprintf(out_h, "#endif\n");
9236 fprintf(out_h, "\n");
9237 }
91669238
91679239 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
91689240 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) {
93399411 cache_int(ch, g->zig_target->vendor);
93409412 cache_int(ch, g->zig_target->os);
93419413 cache_int(ch, g->zig_target->abi);
9342 cache_int(ch, g->subsystem);
9414 cache_int(ch, detect_subsystem(g));
93439415 cache_bool(ch, g->strip_debug_symbols);
93449416 cache_bool(ch, g->is_test_build);
93459417 if (g->is_test_build) {
......@@ -9351,10 +9423,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
93519423 cache_bool(ch, g->each_lib_rpath);
93529424 cache_bool(ch, g->disable_gen_h);
93539425 cache_bool(ch, g->bundle_compiler_rt);
9354 cache_bool(ch, g->disable_stack_probing);
93559426 cache_bool(ch, want_valgrind_support(g));
93569427 cache_bool(ch, g->have_pic);
93579428 cache_bool(ch, g->have_dynamic_link);
9429 cache_bool(ch, g->have_stack_probing);
93589430 cache_bool(ch, g->is_dummy_so);
93599431 cache_buf_opt(ch, g->mmacosx_version_min);
93609432 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
5656
5757Buf *codegen_generate_builtin_source(CodeGen *g);
5858
59TargetSubsystem detect_subsystem(CodeGen *g);
60
5961#endif
src/ir.cpp+161-113
......@@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) {
10151015 return IrInstructionIdHasDecl;
10161016}
10171017
1018static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) {
1019 return IrInstructionIdUndeclaredIdent;
1020}
1021
10181022template<typename T>
10191023static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
10201024 T *special_instruction = allocate<T>(1);
......@@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s
30313035 return &instruction->base;
30323036}
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
30343047static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
30353048 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
30363049 instruction->scope_is_comptime = scope_is_comptime;
......@@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
38963909
38973910 Buf *variable_name = node->data.symbol_expr.symbol;
38983911
3899 if (buf_eql_str(variable_name, "_") && lval == LValPtr) {
3900 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
3901 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
3902 irb->codegen->builtin_types.entry_void, false);
3903 const_instruction->base.value.special = ConstValSpecialStatic;
3904 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard;
3905 return &const_instruction->base;
3912 if (buf_eql_str(variable_name, "_")) {
3913 if (lval == LValPtr) {
3914 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node);
3915 const_instruction->base.value.type = get_pointer_to_type(irb->codegen,
3916 irb->codegen->builtin_types.entry_void, false);
3917 const_instruction->base.value.special = ConstValSpecialStatic;
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 }
39063924 }
39073925
39083926 ZigType *primitive_type;
......@@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
39433961 return irb->codegen->invalid_instruction;
39443962 }
39453963
3946 // put a variable of same name with invalid type in global scope
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;
3964 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
39513965}
39523966
39533967static 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
1025210266 return result;
1025310267}
1025410268
10255static bool is_container(ZigType *type) {
10256 return type->id == ZigTypeIdStruct ||
10257 type->id == ZigTypeIdEnum ||
10258 type->id == ZigTypeIdUnion;
10259}
10260
1026110269static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) {
1026210270 assert(old_bb);
1026310271
......@@ -16165,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1616516173
1616616174 if (type_is_invalid(container_type)) {
1616716175 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)) {
1616916177 assert(container_ptr->value.type->id == ZigTypeIdPointer);
1617016178 if (container_type->id == ZigTypeIdPointer) {
1617116179 ZigType *bare_type = container_ref_type(container_type);
......@@ -16235,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
1623516243
1623616244 if (type_is_invalid(child_type)) {
1623716245 return ira->codegen->invalid_instruction;
16238 } else if (is_container(child_type) && !is_slice(child_type)) {
16246 } else if (is_container(child_type)) {
1623916247 if (child_type->id == ZigTypeIdEnum) {
1624016248 if ((err = ensure_complete_type(ira->codegen, child_type)))
1624116249 return ira->codegen->invalid_instruction;
......@@ -17879,10 +17887,37 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1787917887
1788017888 bool any_missing = false;
1788117889 for (size_t i = 0; i < actual_field_count; i += 1) {
17882 if (!field_assign_nodes[i]) {
17883 ir_add_error_node(ira, instruction->source_node,
17884 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
17885 any_missing = true;
17890 if (field_assign_nodes[i]) continue;
17891
17892 // look for a default field value
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);
1788617921 }
1788717922 }
1788817923 if (any_missing)
......@@ -18372,37 +18407,37 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
1837218407 return var->const_value->data.x_type;
1837318408}
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,
1837618411 ScopeDecls *decls_scope)
1837718412{
1837818413 Error err;
18379 ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr);
18380 if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown)))
18414 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
18415 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown)))
1838118416 return err;
1838218417
18383 ensure_field_index(type_info_definition_type, "name", 0);
18384 ensure_field_index(type_info_definition_type, "is_pub", 1);
18385 ensure_field_index(type_info_definition_type, "data", 2);
18418 ensure_field_index(type_info_declaration_type, "name", 0);
18419 ensure_field_index(type_info_declaration_type, "is_pub", 1);
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);
18388 if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type)))
18422 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
18423 if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type)))
1838918424 return err;
1839018425
18391 ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type);
18392 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type)))
18426 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type);
18427 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type)))
1839318428 return err;
1839418429
18395 ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type);
18396 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type)))
18430 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type);
18431 if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type)))
1839718432 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.
1840018435 auto decl_it = decls_scope->decl_table.entry_iterator();
1840118436 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
18402 int definition_count = 0;
18437 int declaration_count = 0;
1840318438
1840418439 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.
1840618441 if (curr_entry->value->resolution == TldResolutionUnresolved) {
1840718442 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node);
1840818443 if (curr_entry->value->resolution != TldResolutionOk) {
......@@ -18418,21 +18453,21 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
1841818453 continue;
1841918454 }
1842018455
18421 definition_count += 1;
18456 declaration_count += 1;
1842218457 }
1842318458 }
1842418459
18425 ConstExprValue *definition_array = create_const_vals(1);
18426 definition_array->special = ConstValSpecialStatic;
18427 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);
18428 definition_array->data.x_array.special = ConstArraySpecialNone;
18429 definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);
18430 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);
18460 ConstExprValue *declaration_array = create_const_vals(1);
18461 declaration_array->special = ConstValSpecialStatic;
18462 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count);
18463 declaration_array->data.x_array.special = ConstArraySpecialNone;
18464 declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count);
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.
1843318468 decl_it = decls_scope->decl_table.entry_iterator();
1843418469 curr_entry = nullptr;
18435 int definition_index = 0;
18470 int declaration_index = 0;
1843618471 while ((curr_entry = decl_it.next()) != nullptr) {
1843718472 // Skip comptime blocks and test functions.
1843818473 if (curr_entry->value->id == TldIdCompTime) {
......@@ -18443,10 +18478,10 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
1844318478 continue;
1844418479 }
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;
18449 definition_val->type = type_info_definition_type;
18483 declaration_val->special = ConstValSpecialStatic;
18484 declaration_val->type = type_info_declaration_type;
1845018485
1845118486 ConstExprValue *inner_fields = create_const_vals(3);
1845218487 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,
1845518490 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;
1845618491 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;
1845718492 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;
1845918494 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;
1846118496 inner_fields[2].parent.data.p_struct.field_index = 1;
1846218497
1846318498 switch (curr_entry->value->id) {
......@@ -18468,7 +18503,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
1846818503 return ErrorSemanticAnalyzeFail;
1846918504
1847018505 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.
1847218507 // 0: Data.Type: type
1847318508 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);
1847418509 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,
1848818523 }
1848918524 case TldIdFn:
1849018525 {
18491 // 2: Data.Fn: Data.FnDef
18526 // 2: Data.Fn: Data.FnDecl
1849218527 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);
1849318528
1849418529 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,
1849918534 return ErrorSemanticAnalyzeFail;
1850018535 }
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);
18505 fn_def_val->special = ConstValSpecialStatic;
18506 fn_def_val->type = type_info_fn_def_type;
18507 fn_def_val->parent.id = ConstParentIdUnion;
18508 fn_def_val->parent.data.p_union.union_val = &inner_fields[2];
18539 ConstExprValue *fn_decl_val = create_const_vals(1);
18540 fn_decl_val->special = ConstValSpecialStatic;
18541 fn_decl_val->type = type_info_fn_decl_type;
18542 fn_decl_val->parent.id = ConstParentIdUnion;
18543 fn_decl_val->parent.data.p_union.union_val = &inner_fields[2];
1850918544
18510 ConstExprValue *fn_def_fields = create_const_vals(9);
18511 fn_def_val->data.x_struct.fields = fn_def_fields;
18545 ConstExprValue *fn_decl_fields = create_const_vals(9);
18546 fn_decl_val->data.x_struct.fields = fn_decl_fields;
1851218547
1851318548 // fn_type: type
18514 ensure_field_index(fn_def_val->type, "fn_type", 0);
18515 fn_def_fields[0].special = ConstValSpecialStatic;
18516 fn_def_fields[0].type = ira->codegen->builtin_types.entry_type;
18517 fn_def_fields[0].data.x_type = fn_entry->type_entry;
18518 // inline_type: Data.FnDef.Inline
18519 ensure_field_index(fn_def_val->type, "inline_type", 1);
18520 fn_def_fields[1].special = ConstValSpecialStatic;
18521 fn_def_fields[1].type = type_info_fn_def_inline_type;
18522 bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline);
18549 ensure_field_index(fn_decl_val->type, "fn_type", 0);
18550 fn_decl_fields[0].special = ConstValSpecialStatic;
18551 fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type;
18552 fn_decl_fields[0].data.x_type = fn_entry->type_entry;
18553 // inline_type: Data.FnDecl.Inline
18554 ensure_field_index(fn_decl_val->type, "inline_type", 1);
18555 fn_decl_fields[1].special = ConstValSpecialStatic;
18556 fn_decl_fields[1].type = type_info_fn_decl_inline_type;
18557 bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline);
1852318558 // calling_convention: TypeInfo.CallingConvention
18524 ensure_field_index(fn_def_val->type, "calling_convention", 2);
18525 fn_def_fields[2].special = ConstValSpecialStatic;
18526 fn_def_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);
18559 ensure_field_index(fn_decl_val->type, "calling_convention", 2);
18560 fn_decl_fields[2].special = ConstValSpecialStatic;
18561 fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
18562 bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc);
1852818563 // 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);
1853018565 bool is_varargs = fn_node->is_var_args;
18531 fn_def_fields[3].special = ConstValSpecialStatic;
18532 fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool;
18533 fn_def_fields[3].data.x_bool = is_varargs;
18566 fn_decl_fields[3].special = ConstValSpecialStatic;
18567 fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool;
18568 fn_decl_fields[3].data.x_bool = is_varargs;
1853418569 // is_extern: bool
18535 ensure_field_index(fn_def_val->type, "is_extern", 4);
18536 fn_def_fields[4].special = ConstValSpecialStatic;
18537 fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool;
18538 fn_def_fields[4].data.x_bool = fn_node->is_extern;
18570 ensure_field_index(fn_decl_val->type, "is_extern", 4);
18571 fn_decl_fields[4].special = ConstValSpecialStatic;
18572 fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool;
18573 fn_decl_fields[4].data.x_bool = fn_node->is_extern;
1853918574 // is_export: bool
18540 ensure_field_index(fn_def_val->type, "is_export", 5);
18541 fn_def_fields[5].special = ConstValSpecialStatic;
18542 fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool;
18543 fn_def_fields[5].data.x_bool = fn_node->is_export;
18575 ensure_field_index(fn_decl_val->type, "is_export", 5);
18576 fn_decl_fields[5].special = ConstValSpecialStatic;
18577 fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool;
18578 fn_decl_fields[5].data.x_bool = fn_node->is_export;
1854418579 // lib_name: ?[]const u8
18545 ensure_field_index(fn_def_val->type, "lib_name", 6);
18546 fn_def_fields[6].special = ConstValSpecialStatic;
18580 ensure_field_index(fn_decl_val->type, "lib_name", 6);
18581 fn_decl_fields[6].special = ConstValSpecialStatic;
1854718582 ZigType *u8_ptr = get_pointer_to_type_extra(
1854818583 ira->codegen, ira->codegen->builtin_types.entry_u8,
1854918584 true, false, PtrLenUnknown,
1855018585 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));
1855218587 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);
1855418589 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);
1855618591 } else {
18557 fn_def_fields[6].data.x_optional = nullptr;
18592 fn_decl_fields[6].data.x_optional = nullptr;
1855818593 }
1855918594 // return_type: type
18560 ensure_field_index(fn_def_val->type, "return_type", 7);
18561 fn_def_fields[7].special = ConstValSpecialStatic;
18562 fn_def_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;
18595 ensure_field_index(fn_decl_val->type, "return_type", 7);
18596 fn_decl_fields[7].special = ConstValSpecialStatic;
18597 fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type;
18598 fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
1856418599 // 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);
1856618601 size_t fn_arg_count = fn_entry->variable_list.length;
1856718602 ConstExprValue *fn_arg_name_array = create_const_vals(1);
1856818603 fn_arg_name_array->special = ConstValSpecialStatic;
......@@ -18571,7 +18606,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
1857118606 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
1857218607 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
1857618611 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
1857718612 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,
1858318618 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
1858418619 }
1858518620
18586 inner_fields[2].data.x_union.payload = fn_def_val;
18621 inner_fields[2].data.x_union.payload = fn_decl_val;
1858718622 break;
1858818623 }
1858918624 case TldIdContainer:
......@@ -18607,11 +18642,11 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr,
1860718642 zig_unreachable();
1860818643 }
1860918644
18610 definition_val->data.x_struct.fields = inner_fields;
18611 definition_index++;
18645 declaration_val->data.x_struct.fields = inner_fields;
18646 declaration_index++;
1861218647 }
1861318648
18614 assert(definition_index == definition_count);
18649 assert(declaration_index == declaration_count);
1861518650 return ErrorNone;
1861618651}
1861718652
......@@ -18919,9 +18954,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
1891918954 enum_field_val->parent.data.p_array.array_val = enum_field_array;
1892018955 enum_field_val->parent.data.p_array.elem_index = enum_field_index;
1892118956 }
18922 // defs: []TypeInfo.Definition
18923 ensure_field_index(result->type, "defs", 3);
18924 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],
18957 // decls: []TypeInfo.Declaration
18958 ensure_field_index(result->type, "decls", 3);
18959 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
1892518960 type_entry->data.enumeration.decls_scope)))
1892618961 {
1892718962 return err;
......@@ -19086,9 +19121,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
1908619121 union_field_val->parent.data.p_array.array_val = union_field_array;
1908719122 union_field_val->parent.data.p_array.elem_index = union_field_index;
1908819123 }
19089 // defs: []TypeInfo.Definition
19090 ensure_field_index(result->type, "defs", 3);
19091 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3],
19124 // decls: []TypeInfo.Declaration
19125 ensure_field_index(result->type, "decls", 3);
19126 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],
1909219127 type_entry->data.unionation.decls_scope)))
1909319128 {
1909419129 return err;
......@@ -19167,9 +19202,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
1916719202 struct_field_val->parent.data.p_array.array_val = struct_field_array;
1916819203 struct_field_val->parent.data.p_array.elem_index = struct_field_index;
1916919204 }
19170 // defs: []TypeInfo.Definition
19171 ensure_field_index(result->type, "defs", 2);
19172 if ((err = ir_make_type_info_defs(ira, source_instr, &fields[2],
19205 // decls: []TypeInfo.Declaration
19206 ensure_field_index(result->type, "decls", 2);
19207 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2],
1917319208 type_entry->data.structure.decls_scope)))
1917419209 {
1917519210 return err;
......@@ -23237,6 +23272,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct
2323723272 return ir_const_bool(ira, &instruction->base, true);
2323823273}
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
2324023285static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
2324123286 switch (instruction->id) {
2324223287 case IrInstructionIdInvalid:
......@@ -23533,6 +23578,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
2353323578 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction);
2353423579 case IrInstructionIdHasDecl:
2353523580 return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction);
23581 case IrInstructionIdUndeclaredIdent:
23582 return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction);
2353623583 }
2353723584 zig_unreachable();
2353823585}
......@@ -23667,6 +23714,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2366723714 case IrInstructionIdAssertNonNull:
2366823715 case IrInstructionIdResizeSlice:
2366923716 case IrInstructionIdGlobalAsm:
23717 case IrInstructionIdUndeclaredIdent:
2367023718 return true;
2367123719
2367223720 case IrInstructionIdPhi:
src/ir_print.cpp+7
......@@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) {
14611461 fprintf(irp->f, ")");
14621462}
14631463
1464static void ir_print_undeclared_ident(IrPrint *irp, IrInstructionUndeclaredIdent *instruction) {
1465 fprintf(irp->f, "@undeclaredIdent(%s)", buf_ptr(instruction->name));
1466}
1467
14641468static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14651469 ir_print_prefix(irp, instruction);
14661470 switch (instruction->id) {
......@@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
19311935 case IrInstructionIdHasDecl:
19321936 ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction);
19331937 break;
1938 case IrInstructionIdUndeclaredIdent:
1939 ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction);
1940 break;
19341941 }
19351942 fprintf(irp->f, "\n");
19361943}
src/link.cpp+33-30
......@@ -25,7 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou
2525 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
2626 parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path());
2727 child_gen->disable_gen_h = true;
28 child_gen->disable_stack_probing = true;
28 child_gen->want_stack_check = WantStackCheckDisabled;
2929 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
3030 child_gen->verbose_ast = parent_gen->verbose_ast;
3131 child_gen->verbose_link = parent_gen->verbose_link;
......@@ -528,9 +528,6 @@ static const char *build_musl(CodeGen *parent) {
528528 Buf noextbasename = BUF_INIT;
529529 Buf dirbasename = BUF_INIT;
530530 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
535532 auto source_it = source_table.entry_iterator();
536533 for (;;) {
......@@ -543,31 +540,37 @@ static const char *build_musl(CodeGen *parent) {
543540 os_path_split(src_file, &dirname, &basename);
544541 os_path_extname(&basename, &noextbasename, nullptr);
545542 os_path_split(&dirname, &before_arch_dir, &dirbasename);
543
544 bool is_arch_specific = false;
545 // Architecture-specific implementations are under a <arch>/ folder.
546546 if (is_musl_arch_name(buf_ptr(&dirbasename))) {
547 // We find these by explicitly looking for overrides.
548 continue;
547 // Not the architecture we're compiling for.
548 if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0)
549 continue;
550 is_arch_specific = true;
549551 }
550 // Look for an arch specific override.
551 buf_resize(&override_c, 0);
552 buf_resize(&override_s, 0);
553 buf_resize(&override_S, 0);
554
555 buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c",
556 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
557 buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s",
558 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
559 buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S",
560 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
561
562 if (source_table.maybe_get(&override_c) != nullptr) {
563 src_file = &override_c;
564 src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind;
565 } else if (source_table.maybe_get(&override_s) != nullptr) {
566 src_file = &override_s;
567 src_kind = MuslSrcAsm;
568 } else if (source_table.maybe_get(&override_S) != nullptr) {
569 src_file = &override_S;
570 src_kind = MuslSrcAsm;
552
553 if (!is_arch_specific) {
554 Buf override_path = BUF_INIT;
555
556 // Look for an arch specific override.
557 buf_resize(&override_path, 0);
558 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s",
559 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
560 if (source_table.maybe_get(&override_path) != nullptr)
561 continue;
562
563 buf_resize(&override_path, 0);
564 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S",
565 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
566 if (source_table.maybe_get(&override_path) != nullptr)
567 continue;
568
569 buf_resize(&override_path, 0);
570 buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c",
571 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
572 if (source_table.maybe_get(&override_path) != nullptr)
573 continue;
571574 }
572575
573576 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) {
12251228 lj->args.append(get_libc_file(g->libc, "libmingwex.a"));
12261229 lj->args.append(get_libc_file(g->libc, "libmsvcrt.a"));
12271230
1228 if (g->subsystem == TargetSubsystemWindows) {
1231 if (detect_subsystem(g) == TargetSubsystemWindows) {
12291232 lj->args.append(get_libc_file(g->libc, "libgdi32.a"));
12301233 lj->args.append(get_libc_file(g->libc, "libcomdlg32.a"));
12311234 }
......@@ -1307,7 +1310,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
13071310 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
13081311 }
13091312
1310 switch (g->subsystem) {
1313 switch (detect_subsystem(g)) {
13111314 case TargetSubsystemAuto:
13121315 if (g->zig_target->os == OsUefi) {
13131316 add_uefi_link_args(lj);
......@@ -1471,7 +1474,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
14711474 platform->kind = IPhoneOS;
14721475 } else if (g->zig_target->os == OsMacOSX) {
14731476 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");
14751478 } else {
14761479 zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");
14771480 }
src/main.cpp+19-5
......@@ -55,7 +55,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
5555 " --disable-gen-h do not generate a C header file (.h)\n"
5656 " --disable-valgrind omit valgrind client requests in debug builds\n"
5757 " --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"
5960 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
6061 " -fPIC enable Position Independent Code\n"
6162 " -fno-PIC disable Position Independent Code\n"
......@@ -443,12 +444,12 @@ int main(int argc, char **argv) {
443444 bool want_single_threaded = false;
444445 bool disable_gen_h = false;
445446 bool bundle_compiler_rt = false;
446 bool disable_stack_probing = false;
447447 Buf *override_std_dir = nullptr;
448448 Buf *override_lib_dir = nullptr;
449449 Buf *main_pkg_path = nullptr;
450450 ValgrindSupport valgrind_support = ValgrindSupportAuto;
451451 WantPIC want_pic = WantPICAuto;
452 WantStackCheck want_stack_check = WantStackCheckAuto;
452453
453454 ZigList<const char *> llvm_argv = {0};
454455 llvm_argv.append("zig (LLVM option parsing)");
......@@ -648,6 +649,10 @@ int main(int argc, char **argv) {
648649 want_pic = WantPICEnabled;
649650 } else if (strcmp(arg, "-fno-PIC") == 0) {
650651 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;
651656 } else if (strcmp(arg, "--system-linker-hack") == 0) {
652657 system_linker_hack = true;
653658 } else if (strcmp(arg, "--single-threaded") == 0) {
......@@ -656,8 +661,6 @@ int main(int argc, char **argv) {
656661 disable_gen_h = true;
657662 } else if (strcmp(arg, "--bundle-compiler-rt") == 0) {
658663 bundle_compiler_rt = true;
659 } else if (strcmp(arg, "--disable-stack-probing") == 0) {
660 disable_stack_probing = true;
661664 } else if (strcmp(arg, "--test-cmd-bin") == 0) {
662665 test_exec_args.append(nullptr);
663666 } else if (arg[1] == 'L' && arg[2] != 0) {
......@@ -951,8 +954,10 @@ int main(int argc, char **argv) {
951954 case CmdBuiltin: {
952955 CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
953956 out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr);
957 g->subsystem = subsystem;
954958 g->valgrind_support = valgrind_support;
955959 g->want_pic = want_pic;
960 g->want_stack_check = want_stack_check;
956961 g->want_single_threaded = want_single_threaded;
957962 Buf *builtin_source = codegen_generate_builtin_source(g);
958963 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) {
981986 {
982987 fprintf(stderr, "Expected source file argument.\n");
983988 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);
984992 }
985993
986994 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
......@@ -1048,6 +1056,7 @@ int main(int argc, char **argv) {
10481056 if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2);
10491057 g->valgrind_support = valgrind_support;
10501058 g->want_pic = want_pic;
1059 g->want_stack_check = want_stack_check;
10511060 g->subsystem = subsystem;
10521061
10531062 g->enable_time_report = timing_info;
......@@ -1074,7 +1083,6 @@ int main(int argc, char **argv) {
10741083 g->output_dir = output_dir;
10751084 g->disable_gen_h = disable_gen_h;
10761085 g->bundle_compiler_rt = bundle_compiler_rt;
1077 g->disable_stack_probing = disable_stack_probing;
10781086 codegen_set_errmsg_color(g, color);
10791087 g->system_linker_hack = system_linker_hack;
10801088
......@@ -1185,6 +1193,12 @@ int main(int argc, char **argv) {
11851193 Buf *test_exe_path = buf_alloc();
11861194 *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
11881202 for (size_t i = 0; i < test_exec_args.length; i += 1) {
11891203 if (test_exec_args.items[i] == nullptr) {
11901204 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) {
668668 return res;
669669 }
670670
671 Token *use = eat_token_if(pc, TokenIdKeywordUse);
671 Token *use = eat_token_if(pc, TokenIdKeywordUsingNamespace);
672672 if (use != nullptr) {
673673 AstNode *expr = ast_expect(pc, ast_parse_expr);
674674 expect_token(pc, TokenIdSemicolon);
src/target.cpp+4
......@@ -1356,6 +1356,10 @@ bool target_supports_fpic(const ZigTarget *target) {
13561356 return target->os != OsWindows;
13571357}
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
13591363bool target_requires_pic(const ZigTarget *target, bool linking_libc) {
13601364 // This function returns whether non-pic code is completely invalid on the given target.
13611365 return target->os == OsWindows || target_os_requires_libc(target->os) ||
src/target.hpp+6-1
......@@ -62,7 +62,6 @@ enum SubArchList {
6262};
6363
6464enum TargetSubsystem {
65 TargetSubsystemAuto, // Zig should infer the subsystem
6665 TargetSubsystemConsole,
6766 TargetSubsystemWindows,
6867 TargetSubsystemPosix,
......@@ -71,6 +70,11 @@ enum TargetSubsystem {
7170 TargetSubsystemEfiBootServiceDriver,
7271 TargetSubsystemEfiRom,
7372 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
7478};
7579
7680struct ZigTarget {
......@@ -172,6 +176,7 @@ bool target_is_glibc(const ZigTarget *target);
172176bool target_is_musl(const ZigTarget *target);
173177bool target_is_wasm(const ZigTarget *target);
174178bool target_is_single_threaded(const ZigTarget *target);
179bool target_supports_stack_probing(const ZigTarget *target);
175180
176181uint32_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[] = {
153153 {"undefined", TokenIdKeywordUndefined},
154154 {"union", TokenIdKeywordUnion},
155155 {"unreachable", TokenIdKeywordUnreachable},
156 {"use", TokenIdKeywordUse},
156 {"use", TokenIdKeywordUsingNamespace},
157 {"usingnamespace", TokenIdKeywordUsingNamespace},
157158 {"var", TokenIdKeywordVar},
158159 {"volatile", TokenIdKeywordVolatile},
159160 {"while", TokenIdKeywordWhile},
......@@ -1546,7 +1547,7 @@ const char * token_name(TokenId id) {
15461547 case TokenIdKeywordUndefined: return "undefined";
15471548 case TokenIdKeywordUnion: return "union";
15481549 case TokenIdKeywordUnreachable: return "unreachable";
1549 case TokenIdKeywordUse: return "use";
1550 case TokenIdKeywordUsingNamespace: return "usingnamespace";
15501551 case TokenIdKeywordVar: return "var";
15511552 case TokenIdKeywordVolatile: return "volatile";
15521553 case TokenIdKeywordWhile: return "while";
src/tokenizer.hpp+1-1
......@@ -96,7 +96,7 @@ enum TokenId {
9696 TokenIdKeywordUndefined,
9797 TokenIdKeywordUnion,
9898 TokenIdKeywordUnreachable,
99 TokenIdKeywordUse,
99 TokenIdKeywordUsingNamespace,
100100 TokenIdKeywordVar,
101101 TokenIdKeywordVolatile,
102102 TokenIdKeywordWhile,
src/userland.cpp+15
......@@ -42,3 +42,18 @@ int stage2_fmt(int argc, char **argv) {
4242 const char *msg = "stage0 called stage2_fmt";
4343 stage2_panic(msg, strlen(msg));
4444}
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 @@
99#define ZIG_USERLAND_H
1010
1111#include <stddef.h>
12#include <stdint.h>
1213#include <stdio.h>
1314
1415#ifdef __cplusplus
......@@ -118,4 +119,36 @@ ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t le
118119// ABI warning
119120ZIG_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
121154#endif
src/zig_llvm.cpp+10-14
......@@ -318,12 +318,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVM
318318 const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
319319 uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)
320320{
321 assert(flags == 0);
322321 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
323322 reinterpret_cast<DIScope*>(scope),
324323 name,
325324 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),
327327 reinterpret_cast<DIType*>(type));
328328 return reinterpret_cast<ZigLLVMDIType*>(di_type);
329329}
......@@ -338,12 +338,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
338338 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
339339 fields.push_back(ditype);
340340 }
341 assert(flags == 0);
342341 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
343342 reinterpret_cast<DIScope*>(scope),
344343 name,
345344 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),
347347 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
348348 run_time_lang, unique_id);
349349 return reinterpret_cast<ZigLLVMDIType*>(di_type);
......@@ -360,12 +360,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVM
360360 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
361361 fields.push_back(ditype);
362362 }
363 assert(flags == 0);
364363 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(
365364 reinterpret_cast<DIScope*>(scope),
366365 name,
367366 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),
369369 reinterpret_cast<DIType*>(derived_from),
370370 reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
371371 run_time_lang,
......@@ -426,11 +426,10 @@ ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
426426 DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
427427 types.push_back(ditype);
428428 }
429 assert(flags == 0);
430429 DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
431430 DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
432431 dibuilder->getOrCreateTypeArray(types),
433 DINode::FlagZero);
432 static_cast<DINode::DIFlags>(flags));
434433 DIType *ditype = subroutine_type;
435434 return reinterpret_cast<ZigLLVMDIType*>(ditype);
436435}
......@@ -516,7 +515,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
516515 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
517516 ZigLLVMDIType *type, bool always_preserve, unsigned flags)
518517{
519 assert(flags == 0);
520518 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(
521519 reinterpret_cast<DIScope*>(scope),
522520 name,
......@@ -524,7 +522,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
524522 line_no,
525523 reinterpret_cast<DIType*>(type),
526524 always_preserve,
527 DINode::FlagZero);
525 static_cast<DINode::DIFlags>(flags));
528526 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
529527}
530528
......@@ -547,7 +545,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde
547545 ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
548546 ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
549547{
550 assert(flags == 0);
551548 assert(arg_no != 0);
552549 DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(
553550 reinterpret_cast<DIScope*>(scope),
......@@ -557,7 +554,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde
557554 line_no,
558555 reinterpret_cast<DIType*>(type),
559556 always_preserve,
560 DINode::FlagZero);
557 static_cast<DINode::DIFlags>(flags));
561558 return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
562559}
563560
......@@ -612,7 +609,6 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
612609 unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)
613610{
614611 DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));
615 assert(flags == 0);
616612 DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
617613 reinterpret_cast<DIScope*>(scope),
618614 name, linkage_name,
......@@ -620,7 +616,7 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD
620616 lineno,
621617 di_sub_type,
622618 scope_line,
623 DINode::FlagStaticMember,
619 static_cast<DINode::DIFlags>(flags),
624620 DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized),
625621 nullptr,
626622 reinterpret_cast<DISubprogram *>(decl_subprogram),
src/zig_llvm.h+33
......@@ -406,6 +406,39 @@ enum ZigLLVM_ObjectFormatType {
406406 ZigLLVM_Wasm,
407407};
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
409442ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
410443ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
411444ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
std/build.zig+19-1
......@@ -877,6 +877,13 @@ pub const Target = union(enum) {
877877 };
878878 }
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
880887 pub fn isDarwin(self: Target) bool {
881888 return switch (self.getOs()) {
882889 .ios, .macosx, .watchos, .tvos => true,
......@@ -891,6 +898,13 @@ pub const Target = union(enum) {
891898 };
892899 }
893900
901 pub fn isWasm(self: Target) bool {
902 return switch (self.getArch()) {
903 .wasm32, .wasm64 => true,
904 else => false,
905 };
906 }
907
894908 pub fn isFreeBSD(self: Target) bool {
895909 return switch (self.getOs()) {
896910 .freebsd => true,
......@@ -1080,7 +1094,11 @@ pub const LibExeObjStep = struct {
10801094 self.out_filename = self.builder.fmt("{}.lib", self.name);
10811095 },
10821096 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 }
10841102 },
10851103 }
10861104 self.out_lib_filename = self.out_filename;
std/c.zig+2-2
......@@ -2,9 +2,9 @@ const builtin = @import("builtin");
22const std = @import("std");
33const 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) {
88 .linux => @import("c/linux.zig"),
99 .windows => @import("c/windows.zig"),
1010 .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),
std/c/darwin.zig+3-1
......@@ -3,7 +3,7 @@ const assert = std.debug.assert;
33const builtin = @import("builtin");
44const macho = std.macho;
55
6use @import("../os/bits.zig");
6usingnamespace @import("../os/bits.zig");
77
88extern "c" fn __error() *c_int;
99pub 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
5454pub fn sigaddset(set: *sigset_t, signo: u5) void {
5555 set.* |= u32(1) << (signo - 1);
5656}
57
58pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
std/c/freebsd.zig+4
......@@ -1,4 +1,8 @@
1const std = @import("../std.zig");
2usingnamespace std.c;
3
14extern "c" fn __error() *c_int;
25pub const _errno = __error;
36
47pub 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 @@
11const std = @import("../std.zig");
2use std.c;
2usingnamespace std.c;
33
44extern "c" fn __errno_location() *c_int;
55pub const _errno = __errno_location;
......@@ -7,7 +7,7 @@ pub const _errno = __errno_location;
77pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
88pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
99pub 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;
1111pub extern "c" fn epoll_create1(flags: c_uint) c_int;
1212pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int;
1313pub extern "c" fn epoll_pwait(
......@@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
2525
2626pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
2727pub 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 @@
1const std = @import("../std.zig");
2usingnamespace std.c;
3
14extern "c" fn __errno() *c_int;
25pub const _errno = __errno;
36
47pub 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 {
104104 memory: []align(mem.page_size) u8,
105105
106106 /// Trusts the file
107 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
107 pub fn open(path: []const u8) !DynLib {
108108 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);
109109 errdefer os.close(fd);
110110
111 // TODO remove this @intCast
111112 const size = @intCast(usize, (try os.fstat(fd)).size);
112113
113114 const bytes = try os.mmap(
114115 null,
115 size,
116 mem.alignForward(size, mem.page_size),
116117 os.PROT_READ | os.PROT_EXEC,
117 os.MAP_PRIVATE | os.MAP_LOCKED,
118 os.MAP_PRIVATE,
118119 fd,
119120 0,
120121 );
......@@ -244,14 +245,12 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [
244245}
245246
246247pub const WindowsDynLib = struct {
247 allocator: *mem.Allocator,
248248 dll: windows.HMODULE,
249249
250 pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {
250 pub fn open(path: []const u8) !WindowsDynLib {
251251 const wpath = try windows.sliceToPrefixedFileW(path);
252252
253253 return WindowsDynLib{
254 .allocator = allocator,
255254 .dll = try windows.LoadLibraryW(&wpath),
256255 };
257256 }
......@@ -273,7 +272,7 @@ test "dynamic_library" {
273272 else => return,
274273 };
275274
276 const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| {
275 const dynlib = DynLib.open(libname) catch |err| {
277276 testing.expect(err == error.FileNotFound);
278277 return;
279278 };
std/event/loop.zig+1-1
......@@ -421,7 +421,7 @@ pub const Loop = struct {
421421 }
422422
423423 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 {};
425425 self.finishOneEvent();
426426 }
427427
std/fmt.zig+9-19
......@@ -145,23 +145,7 @@ pub fn formatType(
145145 return format(context, Errors, output, "promise@{x}", @ptrToInt(value));
146146 },
147147 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
148 const has_cust_fmt = comptime cf: {
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);
148 if (comptime std.meta.trait.hasFn("format")(T)) return value.format(fmt, context, Errors, output);
165149
166150 try output(context, @typeName(T));
167151 switch (comptime @typeId(T)) {
......@@ -236,8 +220,10 @@ pub fn formatType(
236220 if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) {
237221 return formatText(value, fmt, context, Errors, output);
238222 }
239 const casted_value = ([]const u8)(value);
240 return output(context, casted_value);
223 if (ptr_info.child == u8) {
224 return formatText(value, fmt, context, Errors, output);
225 }
226 return format(context, Errors, output, "{}@{x}", @typeName(ptr_info.child), @ptrToInt(value.ptr));
241227 },
242228 builtin.TypeInfo.Pointer.Size.C => {
243229 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
......@@ -1025,6 +1011,10 @@ test "fmt.format" {
10251011 const value: []const u8 = "abc";
10261012 try testFmt("slice: abc\n", "slice: {}\n", value);
10271013 }
1014 {
1015 const value = @intToPtr([*]const []const u8, 0xdeadbeef)[0..0];
1016 try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", value);
1017 }
10281018 {
10291019 const value = @intToPtr(*i32, 0xdeadbeef);
10301020 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
139139 // ensure that the hash map will be at most 60% full if
140140 // expected_count items are put into it
141141 var optimized_capacity = expected_count * 5 / 3;
142 // round capacity to the next power of two
143 const pow = math.log2_int_ceil(usize, optimized_capacity);
144 return math.pow(usize, 2, pow);
142 // an overflow here would mean the amount of memory required would not
143 // be representable in the address space
144 return math.ceilPowerOfTwo(usize, optimized_capacity) catch unreachable;
145145 }
146146
147147 /// 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
155155 /// capacity is greater than the current capacity.
156156 /// New capacity must be a power of two.
157157 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
158160 const is_power_of_two = new_capacity & (new_capacity - 1) == 0;
159161 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
209211 {
210212 var roll_over: usize = 0;
211213 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);
213215 var entry = &hm.entries[index];
214216
215217 if (!entry.used) return null;
......@@ -218,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
218220
219221 const removed_kv = entry.kv;
220222 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);
222224 const next_entry = &hm.entries[next_index];
223225 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
224226 entry.used = false;
......@@ -301,7 +303,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
301303 roll_over += 1;
302304 distance_from_start_index += 1;
303305 }) {
304 const index = (start_index + roll_over) % self.entries.len;
306 const index = self.constrainIndex(start_index + roll_over);
305307 const entry = &self.entries[index];
306308
307309 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
358360 {
359361 var roll_over: usize = 0;
360362 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);
362364 const entry = &hm.entries[index];
363365
364366 if (!entry.used) return null;
......@@ -369,7 +371,13 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
369371 }
370372
371373 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);
373381 }
374382 };
375383}
std/io.zig+1-1
......@@ -1131,7 +1131,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
11311131 }
11321132
11331133 pub fn alignToByte(self: *Self) void {
1134 if (!is_packed) return;
1134 if (packing == .Byte) return;
11351135 self.in_stream.alignToByte();
11361136 }
11371137
std/io/test.zig+1
......@@ -417,6 +417,7 @@ fn testIntSerializerDeserializerInfNaN(
417417 const nan_check_f16 = try deserializer.deserialize(f16);
418418 const inf_check_f16 = try deserializer.deserialize(f16);
419419 const nan_check_f32 = try deserializer.deserialize(f32);
420 deserializer.alignToByte();
420421 const inf_check_f32 = try deserializer.deserialize(f32);
421422 const nan_check_f64 = try deserializer.deserialize(f64);
422423 const inf_check_f64 = try deserializer.deserialize(f64);
std/math.zig+70-9
......@@ -696,6 +696,76 @@ test "math.floorPowerOfTwo" {
696696 comptime testFloorPowerOfTwo();
697697}
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
699769pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
700770 assert(x != 0);
701771 return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x));
......@@ -722,15 +792,6 @@ test "std.math.log2_int_ceil" {
722792 testing.expect(log2_int_ceil(u32, 10) == 4);
723793}
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
734795pub fn lossyCast(comptime T: type, value: var) T {
735796 switch (@typeInfo(@typeOf(value))) {
736797 builtin.TypeId.Int => return @intToFloat(T, value),
std/math/big.zig+2-2
......@@ -1,5 +1,5 @@
1pub use @import("big/int.zig");
2pub use @import("big/rational.zig");
1pub usingnamespace @import("big/int.zig");
2pub usingnamespace @import("big/rational.zig");
33
44test "math.big" {
55 _ = @import("big/int.zig");
std/meta.zig+22-22
......@@ -160,16 +160,16 @@ test "std.meta.containerLayout" {
160160 testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
161161}
162162
163pub fn definitions(comptime T: type) []TypeInfo.Definition {
163pub fn declarations(comptime T: type) []TypeInfo.Declaration {
164164 return switch (@typeInfo(T)) {
165 TypeId.Struct => |info| info.defs,
166 TypeId.Enum => |info| info.defs,
167 TypeId.Union => |info| info.defs,
165 TypeId.Struct => |info| info.decls,
166 TypeId.Enum => |info| info.decls,
167 TypeId.Union => |info| info.decls,
168168 else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"),
169169 };
170170}
171171
172test "std.meta.definitions" {
172test "std.meta.declarations" {
173173 const E1 = enum {
174174 A,
175175
......@@ -184,28 +184,28 @@ test "std.meta.definitions" {
184184 fn a() void {}
185185 };
186186
187 const defs = comptime [][]TypeInfo.Definition{
188 definitions(E1),
189 definitions(S1),
190 definitions(U1),
187 const decls = comptime [][]TypeInfo.Declaration{
188 declarations(E1),
189 declarations(S1),
190 declarations(U1),
191191 };
192192
193 inline for (defs) |def| {
194 testing.expect(def.len == 1);
195 testing.expect(comptime mem.eql(u8, def[0].name, "a"));
193 inline for (decls) |decl| {
194 testing.expect(decl.len == 1);
195 testing.expect(comptime mem.eql(u8, decl[0].name, "a"));
196196 }
197197}
198198
199pub fn definitionInfo(comptime T: type, comptime def_name: []const u8) TypeInfo.Definition {
200 inline for (comptime definitions(T)) |def| {
201 if (comptime mem.eql(u8, def.name, def_name))
202 return def;
199pub fn declarationInfo(comptime T: type, comptime decl_name: []const u8) TypeInfo.Declaration {
200 inline for (comptime declarations(T)) |decl| {
201 if (comptime mem.eql(u8, decl.name, decl_name))
202 return decl;
203203 }
204204
205 @compileError("'" ++ @typeName(T) ++ "' has no definition '" ++ def_name ++ "'");
205 @compileError("'" ++ @typeName(T) ++ "' has no declaration '" ++ decl_name ++ "'");
206206}
207207
208test "std.meta.definitionInfo" {
208test "std.meta.declarationInfo" {
209209 const E1 = enum {
210210 A,
211211
......@@ -220,10 +220,10 @@ test "std.meta.definitionInfo" {
220220 fn a() void {}
221221 };
222222
223 const infos = comptime []TypeInfo.Definition{
224 definitionInfo(E1, "a"),
225 definitionInfo(S1, "a"),
226 definitionInfo(U1, "a"),
223 const infos = comptime []TypeInfo.Declaration{
224 declarationInfo(E1, "a"),
225 declarationInfo(S1, "a"),
226 declarationInfo(U1, "a"),
227227 };
228228
229229 inline for (infos) |info| {
std/meta/trait.zig+5-43
......@@ -55,53 +55,15 @@ test "std.meta.trait.multiTrait" {
5555 testing.expect(!isVector(u8));
5656}
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
9758///
9859pub fn hasFn(comptime name: []const u8) TraitFn {
9960 const Closure = struct {
10061 pub fn trait(comptime T: type) bool {
101 if (!comptime hasDef(name)(T)) return false;
102 const DefType = @typeOf(@field(T, name));
103 const def_type_id = @typeId(DefType);
104 return def_type_id == builtin.TypeId.Fn;
62 if (!comptime isContainer(T)) return false;
63 if (!comptime @hasDecl(T, name)) return false;
64 const DeclType = @typeOf(@field(T, name));
65 const decl_type_id = @typeId(DeclType);
66 return decl_type_id == builtin.TypeId.Fn;
10567 }
10668 };
10769 return Closure.trait;
std/os.zig+102-6
......@@ -19,6 +19,8 @@ const builtin = @import("builtin");
1919const assert = std.debug.assert;
2020const math = std.math;
2121const mem = std.mem;
22const elf = std.elf;
23const dl = @import("dynamic_library.zig");
2224const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
2325
2426comptime {
......@@ -46,7 +48,7 @@ pub const system = if (builtin.link_libc) std.c else switch (builtin.os) {
4648 else => struct {},
4749};
4850
49pub use @import("os/bits.zig");
51pub usingnamespace @import("os/bits.zig");
5052
5153/// See also `getenv`. Populated by startup code before main().
5254pub var environ: [][*]u8 = undefined;
......@@ -1509,7 +1511,7 @@ pub const EpollCtlError = error{
15091511 Unexpected,
15101512};
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 {
15131515 const rc = system.epoll_ctl(epfd, op, fd, event);
15141516 switch (errno(rc)) {
15151517 0 => return,
......@@ -1883,20 +1885,29 @@ pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void {
18831885}
18841886
18851887pub 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.
18861891 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.)
18871898 OutOfMemory,
18881899 Unexpected,
18891900};
18901901
18911902/// `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 {
18931904 assert(mem.isAligned(memory.len, mem.page_size));
18941905 switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
18951906 0 => return,
18961907 EINVAL => unreachable,
18971908 EACCES => return error.AccessDenied,
18981909 ENOMEM => return error.OutOfMemory,
1899 else => return unexpectedErrno(err),
1910 else => |err| return unexpectedErrno(err),
19001911 }
19011912}
19021913
......@@ -1935,7 +1946,6 @@ pub const MMapError = error{
19351946
19361947/// Map files or devices into memory.
19371948/// Use of a mapped region can result in these signals:
1938/// `length` must be page-aligned.
19391949/// * SIGSEGV - Attempted write into a region mapped as read-only.
19401950/// * SIGBUS - Attempted access to a portion of the buffer that does not correspond to the file
19411951pub fn mmap(
......@@ -1946,7 +1956,6 @@ pub fn mmap(
19461956 fd: fd_t,
19471957 offset: isize,
19481958) MMapError![]align(mem.page_size) u8 {
1949 assert(mem.isAligned(length, mem.page_size));
19501959 const err = if (builtin.link_libc) blk: {
19511960 const rc = std.c.mmap(ptr, length, prot, flags, fd, offset);
19521961 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 {
23592368 }
23602369}
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
23622435pub const ClockGetTimeError = error{
23632436 UnsupportedClock,
23642437 Unexpected,
......@@ -2433,6 +2506,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError {
24332506 return error.Unexpected;
24342507}
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
24362532test "" {
24372533 _ = @import("os/darwin.zig");
24382534 _ = @import("os/freebsd.zig");
std/os/bits.zig+1-1
......@@ -3,7 +3,7 @@
33
44const builtin = @import("builtin");
55
6pub use switch (builtin.os) {
6pub usingnamespace switch (builtin.os) {
77 .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
88 .freebsd => @import("bits/freebsd.zig"),
99 .linux => @import("bits/linux.zig"),
std/os/bits/darwin.zig+12
......@@ -1078,3 +1078,15 @@ pub const EQFULL = 106;
10781078
10791079/// Must be equal largest errno
10801080pub 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 {
2020 __align: c_long,
2121};
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
2330pub const msghdr = extern struct {
2431 /// optional address
2532 msg_name: ?*sockaddr,
......@@ -835,3 +842,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable
835842pub const EOWNERDEAD = 96; // Previous owner died
836843
837844pub 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 @@
11const builtin = @import("builtin");
22const std = @import("../../std.zig");
33const maxInt = std.math.maxInt;
4use @import("../bits.zig");
4usingnamespace @import("../bits.zig");
55
6pub use @import("linux/errno.zig");
7pub use switch (builtin.arch) {
6pub usingnamespace @import("linux/errno.zig");
7pub usingnamespace switch (builtin.arch) {
88 .x86_64 => @import("linux/x86_64.zig"),
99 .aarch64 => @import("linux/arm64.zig"),
1010 else => struct {},
......@@ -762,16 +762,16 @@ pub const epoll_data = extern union {
762762
763763// On x86_64 the structure is packed so that it matches the definition of its
764764// 32bit counterpart
765pub const epoll_event = if (builtin.arch != .x86_64)
766 extern struct {
765pub const epoll_event = switch (builtin.arch) {
766 .x86_64 => packed struct {
767767 events: u32,
768768 data: epoll_data,
769 }
770else
771 packed struct {
769 },
770 else => extern struct {
772771 events: u32,
773772 data: epoll_data,
774 };
773 },
774};
775775
776776pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
777777pub const _LINUX_CAPABILITY_U32S_1 = 1;
......@@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
929929//#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
930930//#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
931931//#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;
299299pub const O_DSYNC = 0o10000;
300300pub const O_SYNC = 0o4010000;
301301pub const O_RSYNC = 0o4010000;
302pub const O_DIRECTORY = 0o200000;
303pub const O_NOFOLLOW = 0o400000;
302pub const O_DIRECTORY = 0o40000;
303pub const O_NOFOLLOW = 0o100000;
304304pub const O_CLOEXEC = 0o2000000;
305305
306306pub const O_ASYNC = 0o20000;
307pub const O_DIRECT = 0o40000;
308pub const O_LARGEFILE = 0;
307pub const O_DIRECT = 0o200000;
308pub const O_LARGEFILE = 0o400000;
309309pub const O_NOATIME = 0o1000000;
310310pub const O_PATH = 0o10000000;
311pub const O_TMPFILE = 0o20200000;
311pub const O_TMPFILE = 0o20040000;
312312pub const O_NDELAY = O_NONBLOCK;
313313
314314pub const F_DUPFD = 0;
std/os/bits/netbsd.zig+19
......@@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct {
2020 pta_private: *c_void,
2121};
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
2330pub const msghdr = extern struct {
2431 /// optional address
2532 msg_name: ?*sockaddr,
......@@ -723,3 +730,15 @@ pub const ENOLINK = 95; // Link has been severed
723730pub const EPROTO = 96; // Protocol error
724731
725732pub 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 @@
11// 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
55pub const fd_t = HANDLE;
66pub const pid_t = HANDLE;
......@@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140;
158158pub const EDQUOT = 10069;
159159
160160pub 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) {
44 .macosx, .tvos, .watchos, .ios => true,
55 else => false,
66};
7pub use std.c;
7pub usingnamespace std.c;
std/os/freebsd.zig+1-1
......@@ -1,4 +1,4 @@
11const std = @import("../std.zig");
22const builtin = @import("builtin");
33pub 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");
1414const dl = @import("../dynamic_library.zig");
1515
1616pub const is_the_target = builtin.os == .linux;
17pub use switch (builtin.arch) {
17pub usingnamespace switch (builtin.arch) {
1818 .x86_64 => @import("linux/x86_64.zig"),
1919 .aarch64 => @import("linux/arm64.zig"),
2020 else => struct {},
2121};
22pub use @import("bits.zig");
22pub usingnamespace @import("bits.zig");
2323pub const tls = @import("linux/tls.zig");
2424
2525/// 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
131131 if (@hasDecl(@This(), "SYS_readlink")) {
132132 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
133133 } 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);
135135 }
136136}
137137
......@@ -145,7 +145,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {
145145 if (@hasDecl(@This(), "SYS_mkdir")) {
146146 return syscall2(SYS_mkdir, @ptrToInt(path), mode);
147147 } else {
148 return syscall3(SYS_mkdirat, AT_FDCWD, @ptrToInt(path), mode);
148 return syscall3(SYS_mkdirat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode);
149149 }
150150}
151151
......@@ -206,7 +206,7 @@ pub fn rmdir(path: [*]const u8) usize {
206206 if (@hasDecl(@This(), "SYS_rmdir")) {
207207 return syscall1(SYS_rmdir, @ptrToInt(path));
208208 } 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);
210210 }
211211}
212212
......@@ -215,7 +215,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
215215 if (@hasDecl(@This(), "SYS_symlink")) {
216216 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
217217 } 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));
219219 }
220220}
221221
......@@ -231,12 +231,16 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
231231
232232// TODO https://github.com/ziglang/zig/issues/265
233233pub 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 }
235239}
236240
237241// TODO https://github.com/ziglang/zig/issues/265
238pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize {
239 return syscall3(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);
242pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize {
243 return syscall4(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode, flags);
240244}
241245
242246pub fn pipe(fd: *[2]i32) usize {
......@@ -264,9 +268,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {
264268 if (@hasDecl(@This(), "SYS_rename")) {
265269 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
266270 } 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));
268272 } 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);
270274 }
271275}
272276
......@@ -305,7 +309,17 @@ pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
305309
306310// TODO https://github.com/ziglang/zig/issues/265
307311pub 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 }
309323}
310324
311325// TODO https://github.com/ziglang/zig/issues/265
......@@ -373,7 +387,7 @@ pub fn unlink(path: [*]const u8) usize {
373387 if (@hasDecl(@This(), "SYS_unlink")) {
374388 return syscall1(SYS_unlink, @ptrToInt(path));
375389 } else {
376 return syscall3(SYS_unlinkat, AT_FDCWD, @ptrToInt(path), 0);
390 return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), 0);
377391 }
378392}
379393
......@@ -759,18 +773,12 @@ pub fn epoll_create1(flags: usize) usize {
759773 return syscall1(SYS_epoll_create1, flags);
760774}
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 {
763777 return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));
764778}
765779
766780pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
767 return syscall4(
768 SYS_epoll_wait,
769 @bitCast(usize, isize(epoll_fd)),
770 @ptrToInt(events),
771 maxevents,
772 @bitCast(usize, isize(timeout)),
773 );
781 return epoll_pwait(epoll_fd, events, maxevents, timeout, null);
774782}
775783
776784pub 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 {
818826 return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap));
819827}
820828
829pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize {
830 return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss));
831}
832
821833// XXX: This should be weak
822834extern const __ehdr_start: elf.Ehdr = undefined;
823835
std/os/linux/test.zig-39
......@@ -44,42 +44,3 @@ test "timer" {
4444 // TODO implicit cast from *[N]T to [*]T
4545 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
4646}
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 @@
1use @import("../bits.zig");
1usingnamespace @import("../bits.zig");
22
33pub fn syscall0(number: usize) usize {
44 return asm volatile ("syscall"
std/os/netbsd.zig+1-1
......@@ -1,4 +1,4 @@
11const builtin = @import("builtin");
22const std = @import("../std.zig");
33pub 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;
55const io = std.io;
66const fs = std.fs;
77const mem = std.mem;
8const elf = std.elf;
89const File = std.fs.File;
910const Thread = std.Thread;
1011
......@@ -149,3 +150,63 @@ test "realpath" {
149150 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
150151 testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));
151152}
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 @@
11// TODO this is where the extern declarations go. For example, see
22// 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");
55const assert = std.debug.assert;
66
77pub const is_the_target = builtin.os == .wasi;
8pub use @import("bits.zig");
8pub usingnamespace @import("bits.zig");
99
1010comptime {
1111 assert(@alignOf(i8) == 1);
std/os/windows.zig+14-2
......@@ -18,7 +18,7 @@ pub const ntdll = @import("windows/ntdll.zig");
1818pub const ole32 = @import("windows/ole32.zig");
1919pub const shell32 = @import("windows/shell32.zig");
2020
21pub use @import("windows/bits.zig");
21pub usingnamespace @import("windows/bits.zig");
2222
2323pub const CreateFileError = error{
2424 SharingViolation,
......@@ -756,11 +756,23 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
756756 return result;
757757}
758758
759inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {
760 return (s << 10) | p;
761}
762
759763/// Call this when you made a windows DLL call or something that does SetLastError
760764/// and you get an unexpected error.
761765pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {
762766 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]);
764776 std.debug.dumpCurrentStackTrace(null);
765777 }
766778 return error.Unexpected;
std/os/windows/advapi32.zig+1-1
......@@ -1,4 +1,4 @@
1use @import("bits.zig");
1usingnamespace @import("bits.zig");
22
33pub extern "advapi32" stdcallcc fn RegOpenKeyExW(
44 hKey: HKEY,
std/os/windows/bits.zig+14
......@@ -6,6 +6,8 @@ const assert = std.debug.assert;
66const maxInt = std.math.maxInt;
77
88pub const ERROR = @import("error.zig");
9pub const LANG = @import("lang.zig");
10pub const SUBLANG = @import("sublang.zig");
911
1012/// The standard input device. Initially, this is the console input buffer, CONIN$.
1113pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1;
......@@ -55,6 +57,10 @@ pub const ULONG = u32;
5557pub const LONG = i32;
5658pub const ULONGLONG = u64;
5759pub const LONGLONG = i64;
60pub const HLOCAL = HANDLE;
61pub const LANGID = c_ushort;
62
63pub const va_list = *@OpaqueType();
5864
5965pub const TRUE = 1;
6066pub const FALSE = 0;
......@@ -525,3 +531,11 @@ pub const COINIT = extern enum {
525531/// > this expansion applies to the total length.
526532/// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation
527533pub 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 @@
1use @import("bits.zig");
1usingnamespace @import("bits.zig");
22
33pub 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
5050pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
5151pub 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
5355pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;
5456
5557pub 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 @@
1use @import("bits.zig");
1usingnamespace @import("bits.zig");
22
33pub 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 @@
1use @import("bits.zig");
1usingnamespace @import("bits.zig");
22
33pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;
44pub extern "ole32" stdcallcc fn CoUninitialize() void;
std/os/windows/shell32.zig+1-1
......@@ -1,3 +1,3 @@
1use @import("bits.zig");
1usingnamespace @import("bits.zig");
22
33pub 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;
8080pub const STDERR_FILENO = 2;
8181
8282// FIXME: let's borrow Linux's error numbers for now.
83use @import("bits/linux/errno.zig");
83usingnamespace @import("bits/linux/errno.zig");
8484// Get the errno from a syscall return value, or 0 for no error.
8585pub fn getErrno(r: usize) usize {
8686 const signed_r = @bitCast(isize, r);
std/special/c.zig+64-2
......@@ -20,6 +20,12 @@ comptime {
2020 if (is_freestanding and is_wasm and builtin.link_libc) {
2121 @export("_start", wasm_start, .Strong);
2222 }
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 }
2329}
2430
2531extern fn main(argc: c_int, argv: [*][*]u8) c_int;
......@@ -27,6 +33,38 @@ extern fn wasm_start() void {
2733 _ = main(0, undefined);
2834}
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
3068// Avoid dragging in the runtime safety mechanisms into this .o file,
3169// unless we're trying to test this file.
3270pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
......@@ -98,8 +136,32 @@ test "test_memcmp" {
98136 const arr3 = []u8{ 1, 2, 1 };
99137
100138 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);
102 std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) == -1);
139 std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) > 0);
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);
103165}
104166
105167comptime {
std/thread.zig+23-9
......@@ -223,15 +223,17 @@ pub const Thread = struct {
223223 }
224224 };
225225
226 const MAP_GROWSDOWN = if (os.linux.is_the_target) os.linux.MAP_GROWSDOWN else 0;
227
226 var guard_end_offset: usize = undefined;
228227 var stack_end_offset: usize = undefined;
229228 var thread_start_offset: usize = undefined;
230229 var context_start_offset: usize = undefined;
231230 var tls_start_offset: usize = undefined;
232231 const mmap_len = blk: {
233 // First in memory will be the stack, which grows downwards.
234 var l: usize = mem.alignForward(default_stack_size, mem.page_size);
232 var l: usize = 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);
235237 stack_end_offset = l;
236238 // Above the stack, so that it can be in the same mmap call, put the Thread object.
237239 l = mem.alignForward(l, @alignOf(Thread));
......@@ -253,20 +255,32 @@ pub const Thread = struct {
253255 }
254256 break :blk l;
255257 };
258 // Map the whole stack with no rw permissions to avoid committing the
259 // whole region right away
256260 const mmap_slice = os.mmap(
257261 null,
258262 mem.alignForward(mmap_len, mem.page_size),
259 os.PROT_READ | os.PROT_WRITE,
260 os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN,
263 os.PROT_NONE,
264 os.MAP_PRIVATE | os.MAP_ANONYMOUS,
261265 -1,
262266 0,
263267 ) catch |err| switch (err) {
264 error.MemoryMappingNotSupported => unreachable, // no file descriptor
265 error.AccessDenied => unreachable, // no file descriptor
266 error.PermissionDenied => unreachable, // no file descriptor
268 error.MemoryMappingNotSupported => unreachable,
269 error.AccessDenied => unreachable,
270 error.PermissionDenied => unreachable,
267271 else => |e| return e,
268272 };
269273 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
270284 const mmap_addr = @ptrToInt(mmap_slice.ptr);
271285
272286 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) !?*
203203/// TopLevelDecl
204204/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
205205/// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
206/// / KEYWORD_use Expr SEMICOLON
206/// / KEYWORD_usingnamespace Expr SEMICOLON
207207fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
208208 var lib_name: ?*Node = null;
209209 const extern_export_inline_token = blk: {
......@@ -1026,7 +1026,7 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10261026 else_node.* = Node.Else{
10271027 .base = Node{ .id = .Else },
10281028 .else_token = else_token,
1029 .payload = null,
1029 .payload = payload,
10301030 .body = body,
10311031 };
10321032
......@@ -2809,7 +2809,7 @@ fn parseTry(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
28092809}
28102810
28112811fn 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;
28132813 const node = try arena.create(Node.Use);
28142814 node.* = Node.Use{
28152815 .base = Node{ .id = .Use },
std/zig/parser_test.zig+66-2
......@@ -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
140test "zig fmt: allowzero pointer" {
241 try testCanonical(
342 \\const T = [*]allowzero const u8;
......@@ -2090,8 +2129,8 @@ test "zig fmt: Block after if" {
20902129
20912130test "zig fmt: use" {
20922131 try testCanonical(
2093 \\use @import("std");
2094 \\pub use @import("std");
2132 \\usingnamespace @import("std");
2133 \\pub usingnamespace @import("std");
20952134 \\
20962135 );
20972136}
......@@ -2170,6 +2209,31 @@ test "zig fmt: inline asm parameter alignment" {
21702209 );
21712210}
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
21732237const std = @import("std");
21742238const mem = std.mem;
21752239const 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
168168 if (use_decl.visib_token) |visib_token| {
169169 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
170170 }
171 try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // use
171 // 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 ");
172174 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
173175 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
174176 },
......@@ -212,7 +214,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
212214 try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name
213215 try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // :
214216 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); // =
216218 return renderExpression(allocator, stream, tree, indent, start_col, field.value_expr.?, Space.Comma); // value,
217219 }
218220 },
......@@ -724,9 +726,15 @@ fn renderExpression(
724726 expr_widths[i] = width;
725727 }
726728
727 const new_indent = indent + indent_delta;
728 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
729 try stream.writeByteNTimes(' ', new_indent);
729 var new_indent = indent + indent_delta;
730
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
731739 it.set(0);
732740 i = 0;
......@@ -748,15 +756,24 @@ fn renderExpression(
748756 }
749757 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
753765 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 }
755769 } else {
756770 try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // ,
757771 }
758772 }
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 }
760777 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
761778 } else {
762779 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
......@@ -1037,6 +1054,8 @@ fn renderExpression(
10371054 },
10381055
10391056 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
10401059 const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
10411060
10421061 var skip_first_indent = true;
std/zig/tokenizer.zig+3-2
......@@ -59,7 +59,8 @@ pub const Token = struct {
5959 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
6060 Keyword{ .bytes = "union", .id = Id.Keyword_union },
6161 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 },
6364 Keyword{ .bytes = "var", .id = Id.Keyword_var },
6465 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
6566 Keyword{ .bytes = "while", .id = Id.Keyword_while },
......@@ -190,7 +191,7 @@ pub const Token = struct {
190191 Keyword_undefined,
191192 Keyword_union,
192193 Keyword_unreachable,
193 Keyword_use,
194 Keyword_usingnamespace,
194195 Keyword_var,
195196 Keyword_volatile,
196197 Keyword_while,
test/build_examples.zig+1-3
......@@ -17,9 +17,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
1717 cases.addBuildFile("test/standalone/use_alias/build.zig");
1818 cases.addBuildFile("test/standalone/brace_expansion/build.zig");
1919 cases.addBuildFile("test/standalone/empty_env/build.zig");
20 if (false) {
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
20 if (builtin.os == builtin.Os.linux) {
2321 // TODO hook up the DynLib API for windows using LoadLibraryA
2422 // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it
2523 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
test/compile_errors.zig+36-17
......@@ -2,6 +2,38 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33
44pub 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
537 cases.add(
638 "@hasDecl with non-container",
739 \\export fn entry() void {
......@@ -146,7 +178,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
146178 "usingnamespace with wrong type",
147179 \\use void;
148180 ,
149 "tmp.zig:1:1: error: expected struct, found 'void'",
181 "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'",
150182 );
151183
152184 cases.add(
......@@ -1202,7 +1234,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12021234 \\}
12031235 ,
12041236 "tmp.zig:2:5: error: `_` is not a declarable symbol",
1205 "tmp.zig:3:12: error: use of undeclared identifier '_'",
12061237 );
12071238
12081239 cases.add(
......@@ -1215,7 +1246,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12151246 \\ }
12161247 \\}
12171248 ,
1218 "tmp.zig:4:20: error: use of undeclared identifier '_'",
1249 "tmp.zig:4:20: error: `_` may only be used to assign things to",
12191250 );
12201251
12211252 cases.add(
......@@ -1231,7 +1262,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12311262 \\ return 1;
12321263 \\}
12331264 ,
1234 "tmp.zig:4:20: error: use of undeclared identifier '_'",
1265 "tmp.zig:4:20: error: `_` may only be used to assign things to",
12351266 );
12361267
12371268 cases.add(
......@@ -1249,7 +1280,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12491280 \\ return error.optionalReturnError;
12501281 \\}
12511282 ,
1252 "tmp.zig:6:17: error: use of undeclared identifier '_'",
1283 "tmp.zig:6:17: error: `_` may only be used to assign things to",
12531284 );
12541285
12551286 cases.add(
......@@ -5468,18 +5499,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
54685499 "tmp.zig:10:31: error: expected type 'u2', found 'u3'",
54695500 );
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
54835502 cases.add(
54845503 "union fields with value assignments",
54855504 \\const MultipleChoice = union {
test/gen_h.zig+8-8
......@@ -11,7 +11,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
1111 \\ C = 2
1212 \\};
1313 \\
14 \\TEST_EXPORT void entry(enum Foo foo);
14 \\TEST_EXTERN_C void entry(enum Foo foo);
1515 \\
1616 );
1717
......@@ -35,7 +35,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
3535 \\ uint64_t F;
3636 \\};
3737 \\
38 \\TEST_EXPORT void entry(struct Foo foo);
38 \\TEST_EXTERN_C void entry(struct Foo foo);
3939 \\
4040 );
4141
......@@ -70,7 +70,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
7070 \\ struct Big D;
7171 \\};
7272 \\
73 \\TEST_EXPORT void entry(union Foo foo);
73 \\TEST_EXTERN_C void entry(union Foo foo);
7474 \\
7575 );
7676
......@@ -81,7 +81,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
8181 ,
8282 \\struct Foo;
8383 \\
84 \\TEST_EXPORT void entry(struct Foo * foo);
84 \\TEST_EXTERN_C void entry(struct Foo * foo);
8585 );
8686
8787 cases.add("array field-type",
......@@ -96,7 +96,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
9696 \\ uint32_t * B[4];
9797 \\};
9898 \\
99 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);
99 \\TEST_EXTERN_C void entry(struct Foo foo, uint8_t bar[]);
100100 \\
101101 );
102102
......@@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
110110 \\}
111111 ,
112112 \\struct S;
113 \\TEST_EXPORT uint8_t a(struct S * s);
113 \\TEST_EXTERN_C uint8_t a(struct S * s);
114114 \\
115115 );
116116
......@@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
125125 \\}
126126 ,
127127 \\union U;
128 \\TEST_EXPORT uint8_t a(union U * s);
128 \\TEST_EXTERN_C uint8_t a(union U * s);
129129 \\
130130 );
131131
......@@ -140,7 +140,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
140140 \\}
141141 ,
142142 \\enum E;
143 \\TEST_EXPORT uint8_t a(enum E * s);
143 \\TEST_EXTERN_C uint8_t a(enum E * s);
144144 \\
145145 );
146146}
test/stage1/behavior.zig+1
......@@ -26,6 +26,7 @@ comptime {
2626 _ = @import("behavior/bugs/2006.zig");
2727 _ = @import("behavior/bugs/2114.zig");
2828 _ = @import("behavior/bugs/2346.zig");
29 _ = @import("behavior/bugs/2578.zig");
2930 _ = @import("behavior/bugs/394.zig");
3031 _ = @import("behavior/bugs/421.zig");
3132 _ = @import("behavior/bugs/529.zig");
test/stage1/behavior/alignof.zig-1
......@@ -15,4 +15,3 @@ test "@alignOf(T) before referencing T" {
1515 comptime expect(@alignOf(Foo) == 4);
1616 }
1717}
18
test/stage1/behavior/bugs/1076.zig-1
......@@ -13,4 +13,3 @@ fn testCastPtrOfArrayToSliceAndPtr() void {
1313 x[0] += 1;
1414 expect(mem.eql(u8, array[0..], "boeu"));
1515}
16
test/stage1/behavior/bugs/1486.zig-1
......@@ -8,4 +8,3 @@ test "constant pointer to global variable causes runtime load" {
88 expect(&global == ptr);
99 expect(ptr.* == 1234);
1010}
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 {
1313 const x = @bitCast([2]u64, a);
1414 return x[1];
1515}
16
test/stage1/behavior/bugs/529.zig-1
......@@ -12,4 +12,3 @@ test "issue 529 fixed" {
1212 @import("529_other_file.zig").issue529(null);
1313 issue529(null);
1414}
15
test/stage1/behavior/bugs/726.zig-1
......@@ -13,4 +13,3 @@ test "@ptrCast from var in empty struct to nullable" {
1313 var x: ?*const u8 = @ptrCast(?*const u8, &container.c);
1414 expect(x.?.* == 4);
1515}
16
test/stage1/behavior/eval.zig+13-5
......@@ -93,11 +93,13 @@ pub const Vec3 = struct {
9393 data: [3]f32,
9494};
9595pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
96 return Vec3{ .data = []f32{
97 x,
98 y,
99 z,
100 } };
96 return Vec3{
97 .data = []f32{
98 x,
99 y,
100 z,
101 },
102 };
101103}
102104
103105test "constant expressions" {
......@@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 {
776778fn scalar(x: u32) u32 {
777779 return x;
778780}
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" {
205205 s.ptr = S.foo;
206206 expect(s.ptr() == 1234);
207207}
208
test/stage1/behavior/import.zig+1-1
......@@ -12,7 +12,7 @@ test "importing the same thing gives the same import" {
1212
1313test "import in non-toplevel scope" {
1414 const S = struct {
15 use @import("import/a_namespace.zig");
15 usingnamespace @import("import/a_namespace.zig");
1616 };
1717 expectEqual(i32(1234), S.foo());
1818}
test/stage1/behavior/popcount.zig-1
......@@ -41,4 +41,3 @@ fn testPopCount() void {
4141 expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
4242 }
4343}
44
test/stage1/behavior/reflection.zig-1
......@@ -93,4 +93,3 @@ const Bar = union(enum) {
9393 Three: bool,
9494 Four: f64,
9595};
96
test/stage1/behavior/struct.zig+29
......@@ -549,3 +549,32 @@ test "packed struct with fp fields" {
549549 expectEqual(f32(11.0), s.data[1]);
550550 expectEqual(f32(20.0), s.data[2]);
551551}
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" {
3232 expect(pt.x == 13);
3333 expect(pt.y == 35);
3434}
35
test/stage1/behavior/type_info.zig+8-8
......@@ -177,7 +177,7 @@ fn testEnum() void {
177177 expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
178178 expect(os_info.Enum.fields[3].value == 3);
179179 expect(os_info.Enum.tag_type == u2);
180 expect(os_info.Enum.defs.len == 0);
180 expect(os_info.Enum.decls.len == 0);
181181}
182182
183183test "type info: union info" {
......@@ -194,7 +194,7 @@ fn testUnion() void {
194194 expect(typeinfo_info.Union.fields[4].enum_field != null);
195195 expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
196196 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
199199 const TestNoTagUnion = union {
200200 Foo: void,
......@@ -232,12 +232,12 @@ fn testStruct() void {
232232 expect(struct_info.Struct.fields.len == 3);
233233 expect(struct_info.Struct.fields[1].offset == null);
234234 expect(struct_info.Struct.fields[2].field_type == *TestStruct);
235 expect(struct_info.Struct.defs.len == 2);
236 expect(struct_info.Struct.defs[0].is_pub);
237 expect(!struct_info.Struct.defs[0].data.Fn.is_extern);
238 expect(struct_info.Struct.defs[0].data.Fn.lib_name == null);
239 expect(struct_info.Struct.defs[0].data.Fn.return_type == void);
240 expect(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);
235 expect(struct_info.Struct.decls.len == 2);
236 expect(struct_info.Struct.decls[0].is_pub);
237 expect(!struct_info.Struct.decls[0].data.Fn.is_extern);
238 expect(struct_info.Struct.decls[0].data.Fn.lib_name == null);
239 expect(struct_info.Struct.decls[0].data.Fn.return_type == void);
240 expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);
241241}
242242
243243const TestStruct = packed struct {
test/stage1/behavior/undefined.zig-1
......@@ -66,4 +66,3 @@ test "type name of undefined" {
6666 const x = undefined;
6767 expect(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
6868}
69
test/stage1/behavior/union.zig+1-1
......@@ -374,7 +374,7 @@ const Attribute = union(enum) {
374374fn setAttribute(attr: Attribute) void {}
375375
376376fn Setter(attr: Attribute) type {
377 return struct{
377 return struct {
378378 fn set() void {
379379 setAttribute(attr);
380380 }
test/stage1/behavior/widening.zig-1
......@@ -25,4 +25,3 @@ test "float widening" {
2525 var d: f128 = c;
2626 expect(d == a);
2727}
28
test/standalone/load_dynamic_library/main.zig+3-3
......@@ -1,12 +1,12 @@
11const std = @import("std");
22
33pub fn main() !void {
4 const args = try std.os.argsAlloc(std.debug.global_allocator);
5 defer std.os.argsFree(std.debug.global_allocator, args);
4 const args = try std.process.argsAlloc(std.debug.global_allocator);
5 defer std.process.argsFree(std.debug.global_allocator, args);
66
77 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);
1010 defer lib.close();
1111
1212 const addr = lib.lookup("add") orelse return error.SymbolNotFound;
test/standalone/use_alias/c.zig+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 {
341341 \\
342342 \\========= Expected this output: =========
343343 \\{}
344 \\================================================
344 \\========= But found: ====================
345345 \\{}
346346 \\
347347 , self.expected_output, stdout.toSliceConst());
......@@ -1036,7 +1036,7 @@ pub const TranslateCContext = struct {
10361036 \\
10371037 \\========= Expected this output: ================
10381038 \\{}
1039 \\================================================
1039 \\========= But found: ===========================
10401040 \\{}
10411041 \\
10421042 , expected_line, stdout);
......@@ -1211,7 +1211,7 @@ pub const GenHContext = struct {
12111211 \\
12121212 \\========= Expected this output: ================
12131213 \\{}
1214 \\================================================
1214 \\========= But found: ===========================
12151215 \\{}
12161216 \\
12171217 , expected_line, actual_h);