From 3b6fc3fdc7618502a9338c4266c4d1aa1ad94bf3 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Sun, 19 May 2019 19:26:10 -0700 Subject: [PATCH 01/84] docs: wasm --- doc/langref.html.in | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index d578be4ba8875ac51144c67ab289c1292296d7a6..3808ea706ad8bcf11cb4d695f12ed660fed54316 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -8434,6 +8434,8 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
  • Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely the right choice, at least for your main allocator.
  • +
  • Are you building for WebAssembly? In this case, {#syntax#}std.heap.wasm_allocator{#endsyntax#} is likely + the only possible choice for your main allocator.
  • Is the maximum number of bytes that you will need bounded by a number known at {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or @@ -8964,8 +8966,12 @@ all your base are belong to us {#header_close#} {#header_close#} {#header_open|WebAssembly#} +

    Zig supports building for WebAssembly out of the box. There is also a specialized {#syntax#}std.heap.wasm_allocator{#endsyntax#} + memory allocator for WebAssembly environments.

    {#header_open|Freestanding#} - {#code_begin|lib|wasm#} +

    For embedded environments like the web browser and nodejs, build as a library using the freestanding OS target. + Here's an example of running Zig code compiled to WebAssembly with nodejs.

    + {#code_begin|lib|math#} {#target_wasm#} extern fn print(i32) void; @@ -8974,7 +8980,22 @@ export fn add(a: i32, b: i32) void { } {#code_end#} {#header_close#} +

    test.js

    +
    const fs = require('fs');
    +const source = fs.readFileSync("./math.wasm");
    +const typedArray = new Uint8Array(source);
    +
    +WebAssembly.instantiate(typedArray, {
    +  env: {
    +    print: (result) => { console.log(`The result is ${result}`); }
    +  }}).then(result => {
    +  const add = result.instance.exports.add;
    +  add(1, 2);
    +});
    +
    $ node test.js
    +The result is 3
    {#header_open|WASI#} +

    Zig's support for WebAssembly System Interface (WASI) is under active development. Example of using the standard library and reading command line arguments:

    {#code_begin|exe|wasi#} {#target_wasi#} const std = @import("std"); @@ -8988,6 +9009,10 @@ pub fn main() !void { } } {#code_end#} +
    $ wasmer run wasi.wasm 123 hello
    +0: wasi.wasm
    +1: 123
    +2: hello
    {#header_close#} {#header_close#} {#header_open|Targets#} @@ -9228,6 +9253,7 @@ Available libcs: s390x-linux-musl sparc-linux-gnu sparcv9-linux-gnu + wasm32-freestanding-musl x86_64-linux-gnu x86_64-linux-gnux32 x86_64-linux-musl -- 2.54.0 From f67ca206557de58df91011744f656ed049d36372 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 21 May 2019 17:07:40 +0200 Subject: [PATCH 02/84] Make use work with arbitrary structs --- src/analyze.cpp | 52 ++++++++++++++++++++------------- test/stage1/behavior/struct.zig | 11 +++++++ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index d6396832c40a97970a5ead592e756a9f08e8c2be..58b91b343de909f1c9f45dae663d30937a9a9fd5 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3754,49 +3754,59 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { analyze_fn_ir(g, fn_table_entry, return_type_node); } -static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) { +static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) { if (src_use_node->data.use.resolution == TldResolutionUnresolved) { preview_use_decl(g, src_use_node, decls_scope); } - ConstExprValue *use_target_value = src_use_node->data.use.using_namespace_value; - if (type_is_invalid(use_target_value->type)) { + ConstExprValue *use_expr = src_use_node->data.use.using_namespace_value; + if (type_is_invalid(use_expr->type)) { decls_scope->any_imports_failed = true; return; } dst_use_node->data.use.resolution = TldResolutionOk; - assert(use_target_value->special != ConstValSpecialRuntime); + assert(use_expr->special != ConstValSpecialRuntime); - ZigType *target_import = use_target_value->data.x_type; - assert(target_import); + // The source struct for the imported symbols + ZigType *src_ty = use_expr->data.x_type; + assert(src_ty); - if (target_import->id != ZigTypeIdStruct) { + if (src_ty->id != ZigTypeIdStruct) { add_node_error(g, dst_use_node, - buf_sprintf("expected struct, found '%s'", buf_ptr(&target_import->name))); + buf_sprintf("expected struct, found '%s'", buf_ptr(&src_ty->name))); decls_scope->any_imports_failed = true; return; } - if (get_container_scope(target_import)->any_imports_failed) { + // The source scope for the imported symbols + ScopeDecls *src_scope = get_container_scope(src_ty); + // The top-level container where the symbols are defined, it's used in the + // loop below in order to exclude the ones coming from an import statement + ZigType *src_import = get_scope_import(reinterpret_cast(src_scope)); + assert(src_import && src_import->id == ZigTypeIdStruct); + + if (src_scope->any_imports_failed) { decls_scope->any_imports_failed = true; } - auto it = get_container_scope(target_import)->decl_table.entry_iterator(); + auto it = src_scope->decl_table.entry_iterator(); for (;;) { auto *entry = it.next(); if (!entry) break; - Tld *target_tld = entry->value; - if (target_tld->import != target_import || - target_tld->visib_mod == VisibModPrivate) - { - continue; - } - Buf *target_tld_name = entry->key; + Tld *target_tld = entry->value; + + if (target_tld->visib_mod == VisibModPrivate) { + continue; + } + + if (target_tld->import != src_import) { + continue; + } auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld); if (existing_entry) { @@ -3811,10 +3821,10 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode * } } - for (size_t i = 0; i < get_container_scope(target_import)->use_decls.length; i += 1) { - AstNode *use_decl_node = get_container_scope(target_import)->use_decls.at(i); + for (size_t i = 0; i < src_scope->use_decls.length; i += 1) { + AstNode *use_decl_node = src_scope->use_decls.at(i); if (use_decl_node->data.use.visib_mod != VisibModPrivate) - add_symbols_from_import(g, use_decl_node, dst_use_node, decls_scope); + add_symbols_from_struct(g, use_decl_node, dst_use_node, decls_scope); } } @@ -3826,7 +3836,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { { return; } - add_symbols_from_import(g, node, node, decls_scope); + add_symbols_from_struct(g, node, node, decls_scope); } void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index c38359be243a9970b8ab56c64d2b21674f84c7ac..d7bbee5d15256743d37d9908bed09075524b7ab0 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -549,3 +549,14 @@ test "packed struct with fp fields" { expectEqual(f32(11.0), s.data[1]); expectEqual(f32(20.0), s.data[2]); } + +test "use within struct scope" { + const S = struct { + use struct { + pub fn inner() i32 { + return 42; + } + }; + }; + expectEqual(i32(42), S.inner()); +} -- 2.54.0 From 9e65a144fa85eeadfacfdfc9a543116cdb95fdb5 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Wed, 22 May 2019 07:43:12 -0700 Subject: [PATCH 03/84] docs: clarify why wasm_allocator should be used --- doc/langref.html.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 3808ea706ad8bcf11cb4d695f12ed660fed54316..ec1a93433bc3ef4ea63c1771a5264b537483d5ba 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -8435,7 +8435,7 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
  • Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely the right choice, at least for your main allocator.
  • Are you building for WebAssembly? In this case, {#syntax#}std.heap.wasm_allocator{#endsyntax#} is likely - the only possible choice for your main allocator.
  • + the right choice for your main allocator as it uses WebAssembly's memory instructions.
  • Is the maximum number of bytes that you will need bounded by a number known at {#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or -- 2.54.0 From b618a0b866edb546b33e6fdb540faeed06f0e8bd Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Wed, 22 May 2019 08:12:15 -0700 Subject: [PATCH 04/84] doc: wasm: embedded->host --- doc/langref.html.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index ec1a93433bc3ef4ea63c1771a5264b537483d5ba..67e803d5b0be22f8fdcf5945d0280652790a7dd3 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -8969,7 +8969,7 @@ all your base are belong to us

    Zig supports building for WebAssembly out of the box. There is also a specialized {#syntax#}std.heap.wasm_allocator{#endsyntax#} memory allocator for WebAssembly environments.

    {#header_open|Freestanding#} -

    For embedded environments like the web browser and nodejs, build as a library using the freestanding OS target. +

    For host environments like the web browser and nodejs, build as a library using the freestanding OS target. Here's an example of running Zig code compiled to WebAssembly with nodejs.

    {#code_begin|lib|math#} {#target_wasm#} -- 2.54.0 From 86b3007b945d2145bc7467625c658fd5480b5135 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 24 May 2019 13:20:44 +0200 Subject: [PATCH 05/84] Reject slices in use expressions Co-Authored-By: emekoi --- src/analyze.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 58b91b343de909f1c9f45dae663d30937a9a9fd5..a1f0571c5b24adb9ffff50c2d09ddd1e7a0e7eae 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3773,7 +3773,7 @@ static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode * ZigType *src_ty = use_expr->data.x_type; assert(src_ty); - if (src_ty->id != ZigTypeIdStruct) { + if (src_ty->id != ZigTypeIdStruct || is_slice(src_ty)) { add_node_error(g, dst_use_node, buf_sprintf("expected struct, found '%s'", buf_ptr(&src_ty->name))); decls_scope->any_imports_failed = true; -- 2.54.0 From c89b5222337d6adc14c83b8fa20a139196c4a38b Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 25 May 2019 13:43:52 +0200 Subject: [PATCH 06/84] test: slightly better output for failure of tests based on text comparison --- test/tests.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tests.zig b/test/tests.zig index a17938fc3c111a211286a656f038a12c4a8b8d52..9218971074dbd069bae1fc2d0a56b44941346445 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -343,7 +343,7 @@ pub const CompareOutputContext = struct { \\ \\========= Expected this output: ========= \\{} - \\================================================ + \\========= But found: ==================== \\{} \\ , self.expected_output, stdout.toSliceConst()); @@ -1038,7 +1038,7 @@ pub const TranslateCContext = struct { \\ \\========= Expected this output: ================ \\{} - \\================================================ + \\========= But found: =========================== \\{} \\ , expected_line, stdout); @@ -1213,7 +1213,7 @@ pub const GenHContext = struct { \\ \\========= Expected this output: ================ \\{} - \\================================================ + \\========= But found: =========================== \\{} \\ , expected_line, actual_h); -- 2.54.0 From 99ee0608f74268248a2dc684cb9e6e9b03e3a9f5 Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 25 May 2019 14:17:59 +0200 Subject: [PATCH 07/84] gen-h: do not output visibility macros when the build is static --- src/codegen.cpp | 29 ++++++++++++++++++----------- test/gen_h.zig | 16 ++++++++-------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 3a34894bb3662ef8736c4d7f3286cf19535c6d76..085298dc18ceb461fb0920a379e51f50e1997c2e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9075,8 +9075,11 @@ static void gen_h_file(CodeGen *g) { if (!out_h) zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno)); - Buf *export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); - buf_upcase(export_macro); + Buf *export_macro = nullptr; + if (g->is_dynamic) { + export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); + buf_upcase(export_macro); + } Buf *extern_c_macro = preprocessor_mangle(buf_sprintf("%s_EXTERN_C", buf_ptr(g->root_out_name))); buf_upcase(extern_c_macro); @@ -9101,10 +9104,11 @@ static void gen_h_file(CodeGen *g) { FnExport *fn_export = &fn_table_entry->export_list.items[0]; symbol_name = &fn_export->name; } + buf_appendf(&h_buf, "%s %s %s(", - buf_ptr(export_macro), - buf_ptr(&return_type_c), - buf_ptr(symbol_name)); + buf_ptr(g->is_dynamic ? export_macro : extern_c_macro), + buf_ptr(&return_type_c), + buf_ptr(symbol_name)); Buf param_type_c = BUF_INIT; if (fn_type_id->param_count > 0) { @@ -9154,13 +9158,16 @@ static void gen_h_file(CodeGen *g) { fprintf(out_h, "#define %s\n", buf_ptr(extern_c_macro)); fprintf(out_h, "#endif\n"); fprintf(out_h, "\n"); - fprintf(out_h, "#if defined(_WIN32)\n"); - fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro)); - fprintf(out_h, "#else\n"); - fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n", + + if (g->is_dynamic) { + fprintf(out_h, "#if defined(_WIN32)\n"); + fprintf(out_h, "#define %s %s __declspec(dllimport)\n", buf_ptr(export_macro), buf_ptr(extern_c_macro)); + fprintf(out_h, "#else\n"); + fprintf(out_h, "#define %s %s __attribute__((visibility (\"default\")))\n", buf_ptr(export_macro), buf_ptr(extern_c_macro)); - fprintf(out_h, "#endif\n"); - fprintf(out_h, "\n"); + fprintf(out_h, "#endif\n"); + fprintf(out_h, "\n"); + } for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { ZigType *type_entry = gen_h->types_to_declare.at(type_i); diff --git a/test/gen_h.zig b/test/gen_h.zig index 11fb55344f52d7d529686855a84dcee2d4948177..5979afd66a5125e965b061c81f83e56ad85e2194 100644 --- a/test/gen_h.zig +++ b/test/gen_h.zig @@ -11,7 +11,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\ C = 2 \\}; \\ - \\TEST_EXPORT void entry(enum Foo foo); + \\TEST_EXTERN_C void entry(enum Foo foo); \\ ); @@ -35,7 +35,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\ uint64_t F; \\}; \\ - \\TEST_EXPORT void entry(struct Foo foo); + \\TEST_EXTERN_C void entry(struct Foo foo); \\ ); @@ -70,7 +70,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\ struct Big D; \\}; \\ - \\TEST_EXPORT void entry(union Foo foo); + \\TEST_EXTERN_C void entry(union Foo foo); \\ ); @@ -81,7 +81,7 @@ pub fn addCases(cases: *tests.GenHContext) void { , \\struct Foo; \\ - \\TEST_EXPORT void entry(struct Foo * foo); + \\TEST_EXTERN_C void entry(struct Foo * foo); ); cases.add("array field-type", @@ -96,7 +96,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\ uint32_t * B[4]; \\}; \\ - \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]); + \\TEST_EXTERN_C void entry(struct Foo foo, uint8_t bar[]); \\ ); @@ -110,7 +110,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\} , \\struct S; - \\TEST_EXPORT uint8_t a(struct S * s); + \\TEST_EXTERN_C uint8_t a(struct S * s); \\ ); @@ -125,7 +125,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\} , \\union U; - \\TEST_EXPORT uint8_t a(union U * s); + \\TEST_EXTERN_C uint8_t a(union U * s); \\ ); @@ -140,7 +140,7 @@ pub fn addCases(cases: *tests.GenHContext) void { \\} , \\enum E; - \\TEST_EXPORT uint8_t a(enum E * s); + \\TEST_EXTERN_C uint8_t a(enum E * s); \\ ); } -- 2.54.0 From d4b241c14e7e9eb8f0c5fcb767c6021e8651c93f Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Mon, 27 May 2019 19:47:10 -0400 Subject: [PATCH 08/84] new .d file parser for C compilation - wip for #2046 - clang .d output must be created with `clang -MV` switch - implemented in Zig - hybridized for zig stage0 and stage1 - zig test src-self-hosted/dep_tokenizer.zig --- CMakeLists.txt | 1 + src-self-hosted/dep_tokenizer.zig | 1131 +++++++++++++++++++++++++++++ src-self-hosted/stage1.zig | 4 + src/cache_hash.cpp | 110 ++- src/userland.cpp | 15 + src/userland.h | 33 + 6 files changed, 1235 insertions(+), 59 deletions(-) create mode 100644 src-self-hosted/dep_tokenizer.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 985216ed7b6a3b42dc7be175abeed4df35d8ab2d..16f270777ac8a3fd47ee24cbd252cfbf3ea46a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6726,6 +6726,7 @@ add_custom_command( "-Doutput-dir=${CMAKE_BINARY_DIR}" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" DEPENDS + "${CMAKE_SOURCE_DIR}/src-self-hosted/dep_tokenizer.zig" "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig" "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig" "${CMAKE_SOURCE_DIR}/build.zig" diff --git a/src-self-hosted/dep_tokenizer.zig b/src-self-hosted/dep_tokenizer.zig new file mode 100644 index 0000000000000000000000000000000000000000..c0a31c16492c76ce27eb407b2178755bdbcbe21a --- /dev/null +++ b/src-self-hosted/dep_tokenizer.zig @@ -0,0 +1,1131 @@ +const std = @import("std"); +const testing = std.testing; + +pub const Tokenizer = struct { + arena: std.heap.ArenaAllocator, + index: usize, + bytes: []const u8, + error_text: []const u8, + state: State, + + pub fn init(allocator: *std.mem.Allocator, bytes: []const u8) Tokenizer { + return Tokenizer{ + .arena = std.heap.ArenaAllocator.init(allocator), + .index = 0, + .bytes = bytes, + .error_text = "", + .state = State{ .lhs = {} }, + }; + } + + pub fn deinit(self: *Tokenizer) void { + self.arena.deinit(); + } + + pub fn next(self: *Tokenizer) Error!?Token { + while (self.index < self.bytes.len) { + const char = self.bytes[self.index]; + while (true) { + switch (self.state) { + .lhs => switch (char) { + '\t', '\n', '\r', ' ' => { + // silently ignore whitespace + break; // advance + }, + else => { + self.state = State{ .target = try std.Buffer.initSize(&self.arena.allocator, 0) }; + }, + }, + .target => |*target| switch (char) { + '\t', '\n', '\r', ' ' => { + return self.errorIllegalChar(self.index, char, "invalid target"); + }, + '$' => { + self.state = State{ .target_dollar_sign = target.* }; + break; // advance + }, + '\\' => { + self.state = State{ .target_reverse_solidus = target.* }; + break; // advance + }, + ':' => { + self.state = State{ .target_colon = target.* }; + break; // advance + }, + else => { + try target.appendByte(char); + break; // advance + }, + }, + .target_reverse_solidus => |*target| switch (char) { + '\t', '\n', '\r' => { + return self.errorIllegalChar(self.index, char, "bad target escape"); + }, + ' ', '#', '\\' => { + try target.appendByte(char); + self.state = State{ .target = target.* }; + break; // advance + }, + '$' => { + try target.append(self.bytes[self.index - 1 .. self.index]); + self.state = State{ .target_dollar_sign = target.* }; + break; // advance + }, + else => { + try target.append(self.bytes[self.index - 1 .. self.index + 1]); + self.state = State{ .target = target.* }; + break; // advance + }, + }, + .target_dollar_sign => |*target| switch (char) { + '$' => { + try target.appendByte(char); + self.state = State{ .target = target.* }; + break; // advance + }, + else => { + return self.errorIllegalChar(self.index, char, "expecting '$'"); + }, + }, + .target_colon => |*target| switch (char) { + '\n', '\r' => { + const bytes = target.toSlice(); + if (bytes.len != 0) { + self.state = State{ .lhs = {} }; + return Token{ .id = .target, .bytes = bytes }; + } + // silently ignore null target + self.state = State{ .lhs = {} }; + continue; + }, + '\\' => { + self.state = State{ .target_colon_reverse_solidus = target.* }; + break; // advance + }, + else => { + const bytes = target.toSlice(); + if (bytes.len != 0) { + self.state = State{ .rhs = {} }; + return Token{ .id = .target, .bytes = bytes }; + } + // silently ignore null target + self.state = State{ .lhs = {} }; + continue; + }, + }, + .target_colon_reverse_solidus => |*target| switch (char) { + '\n', '\r' => { + const bytes = target.toSlice(); + if (bytes.len != 0) { + self.state = State{ .lhs = {} }; + return Token{ .id = .target, .bytes = bytes }; + } + // silently ignore null target + self.state = State{ .lhs = {} }; + continue; + }, + else => { + try target.append(self.bytes[self.index - 2 .. self.index + 1]); + self.state = State{ .target = target.* }; + break; + }, + }, + .rhs => switch (char) { + '\t', ' ' => { + // silently ignore horizontal whitespace + break; // advance + }, + '\n', '\r' => { + self.state = State{ .lhs = {} }; + continue; + }, + '\\' => { + self.state = State{ .rhs_continuation = {} }; + break; // advance + }, + '"' => { + self.state = State{ .prereq_quote = try std.Buffer.initSize(&self.arena.allocator, 0) }; + break; // advance + }, + else => { + self.state = State{ .prereq = try std.Buffer.initSize(&self.arena.allocator, 0) }; + }, + }, + .rhs_continuation => switch (char) { + '\n' => { + self.state = State{ .rhs = {} }; + break; // advance + }, + '\r' => { + self.state = State{ .rhs_continuation_linefeed = {} }; + break; // advance + }, + else => { + return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line"); + }, + }, + .rhs_continuation_linefeed => switch (char) { + '\n' => { + self.state = State{ .rhs = {} }; + break; // advance + }, + else => { + return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line"); + }, + }, + .prereq_quote => |*prereq| switch (char) { + '"' => { + const bytes = prereq.toSlice(); + self.index += 1; + self.state = State{ .rhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + else => { + try prereq.appendByte(char); + break; // advance + }, + }, + .prereq => |*prereq| switch (char) { + '\t', ' ' => { + const bytes = prereq.toSlice(); + self.state = State{ .rhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + '\n', '\r' => { + const bytes = prereq.toSlice(); + self.state = State{ .lhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + '\\' => { + self.state = State{ .prereq_continuation = prereq.* }; + break; // advance + }, + else => { + try prereq.appendByte(char); + break; // advance + }, + }, + .prereq_continuation => |*prereq| switch (char) { + '\n' => { + const bytes = prereq.toSlice(); + self.index += 1; + self.state = State{ .rhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + '\r' => { + self.state = State{ .prereq_continuation_linefeed = prereq.* }; + break; // advance + }, + else => { + // not continuation + try prereq.append(self.bytes[self.index - 1 .. self.index + 1]); + self.state = State{ .prereq = prereq.* }; + break; // advance + }, + }, + .prereq_continuation_linefeed => |prereq| switch (char) { + '\n' => { + const bytes = prereq.toSlice(); + self.index += 1; + self.state = State{ .rhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + else => { + return self.errorIllegalChar(self.index, char, "continuation expecting end-of-line"); + }, + }, + } + } + self.index += 1; + } + + // eof, handle maybe incomplete token + if (self.index == 0) return null; + const idx = self.index - 1; + switch (self.state) { + .lhs, + .rhs, + .rhs_continuation, + .rhs_continuation_linefeed, + => {}, + .target => |target| { + return self.errorPosition(idx, target.toSlice(), "incomplete target"); + }, + .target_reverse_solidus, + .target_dollar_sign, + => { + const index = self.index - 1; + return self.errorIllegalChar(idx, self.bytes[idx], "incomplete escape"); + }, + .target_colon => |target| { + const bytes = target.toSlice(); + if (bytes.len != 0) { + self.index += 1; + self.state = State{ .rhs = {} }; + return Token{ .id = .target, .bytes = bytes }; + } + // silently ignore null target + self.state = State{ .lhs = {} }; + }, + .target_colon_reverse_solidus => |target| { + const bytes = target.toSlice(); + if (bytes.len != 0) { + self.index += 1; + self.state = State{ .rhs = {} }; + return Token{ .id = .target, .bytes = bytes }; + } + // silently ignore null target + self.state = State{ .lhs = {} }; + }, + .prereq_quote => |prereq| { + return self.errorPosition(idx, prereq.toSlice(), "incomplete quoted prerequisite"); + }, + .prereq => |prereq| { + const bytes = prereq.toSlice(); + self.state = State{ .lhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + .prereq_continuation => |prereq| { + const bytes = prereq.toSlice(); + self.state = State{ .lhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + .prereq_continuation_linefeed => |prereq| { + const bytes = prereq.toSlice(); + self.state = State{ .lhs = {} }; + return Token{ .id = .prereq, .bytes = bytes }; + }, + } + return null; + } + + fn errorf(self: *Tokenizer, comptime fmt: []const u8, args: ...) Error { + self.error_text = (try std.Buffer.allocPrint(&self.arena.allocator, fmt, args)).toSlice(); + return Error.InvalidInput; + } + + fn errorPosition(self: *Tokenizer, position: usize, bytes: []const u8, comptime fmt: []const u8, args: ...) Error { + var buffer = try std.Buffer.initSize(&self.arena.allocator, 0); + std.fmt.format(&buffer, anyerror, std.Buffer.append, fmt, args) catch {}; + try buffer.append(" '"); + var out = makeOutput(std.Buffer.append, &buffer); + try printCharValues(&out, bytes); + try buffer.append("'"); + std.fmt.format(&buffer, anyerror, std.Buffer.append, " at position {}", position - (bytes.len - 1)) catch {}; + self.error_text = buffer.toSlice(); + return Error.InvalidInput; + } + + fn errorIllegalChar(self: *Tokenizer, position: usize, char: u8, comptime fmt: []const u8, args: ...) Error { + var buffer = try std.Buffer.initSize(&self.arena.allocator, 0); + try buffer.append("illegal char "); + var out = makeOutput(std.Buffer.append, &buffer); + try printUnderstandableChar(&out, char); + std.fmt.format(&buffer, anyerror, std.Buffer.append, " at position {}", position) catch {}; + if (fmt.len != 0) std.fmt.format(&buffer, anyerror, std.Buffer.append, ": " ++ fmt, args) catch {}; + self.error_text = buffer.toSlice(); + return Error.InvalidInput; + } + + const Error = error{ + OutOfMemory, + InvalidInput, + }; + + const State = union(enum) { + lhs: void, + target: std.Buffer, + target_reverse_solidus: std.Buffer, + target_dollar_sign: std.Buffer, + target_colon: std.Buffer, + target_colon_reverse_solidus: std.Buffer, + rhs: void, + rhs_continuation: void, + rhs_continuation_linefeed: void, + prereq_quote: std.Buffer, + prereq: std.Buffer, + prereq_continuation: std.Buffer, + prereq_continuation_linefeed: std.Buffer, + }; + + const Token = struct { + id: ID, + bytes: []const u8, + + const ID = enum { + target, + prereq, + }; + }; +}; + +// stage1 compiler support +var stage2_da = std.heap.DirectAllocator.init(); + +export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { + const t = stage2_da.allocator.create(Tokenizer) catch unreachable; + t.* = Tokenizer.init(&stage2_da.allocator, input[0..len]); + return stage2_DepTokenizer{ + .handle = t, + }; +} + +export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { + self.handle.deinit(); +} + +export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { + const otoken = self.handle.next() catch { + return stage2_DepNextResult{ + .ent = 0, + .textz = (std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch unreachable).toSlice().ptr, + }; + }; + const token = otoken orelse { + return stage2_DepNextResult{ + .ent = 1, + .textz = undefined, + }; + }; + return stage2_DepNextResult{ + .ent = @enumToInt(token.id) + u8(2), + .textz = (std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch unreachable).toSlice().ptr, + }; +} + +export const stage2_DepTokenizer = extern struct { + handle: *Tokenizer, +}; + +export const stage2_DepNextResult = extern struct { + // 0=error, 1=null, 2=token=target, 3=token=prereq + ent: u8, + // ent=0 -- error text + // ent=1 -- NEVER + // ent=2 -- token text value + // ent=3 -- token text value + textz: [*]const u8, +}; + +test "empty file" { + try depTokenizer("", ""); +} + +test "empty whitespace" { + try depTokenizer("\n", ""); + try depTokenizer("\r", ""); + try depTokenizer("\r\n", ""); + try depTokenizer(" ", ""); +} + +test "empty colon" { + try depTokenizer(":", ""); + try depTokenizer("\n:", ""); + try depTokenizer("\r:", ""); + try depTokenizer("\r\n:", ""); + try depTokenizer(" :", ""); +} + +test "empty target" { + try depTokenizer("foo.o:", "target = {foo.o}"); + try depTokenizer( + \\foo.o: + \\bar.o: + \\abcd.o: + , + \\target = {foo.o} + \\target = {bar.o} + \\target = {abcd.o} + ); +} + +test "whitespace empty target" { + try depTokenizer("\nfoo.o:", "target = {foo.o}"); + try depTokenizer("\rfoo.o:", "target = {foo.o}"); + try depTokenizer("\r\nfoo.o:", "target = {foo.o}"); + try depTokenizer(" foo.o:", "target = {foo.o}"); +} + +test "escape empty target" { + try depTokenizer("\\ foo.o:", "target = { foo.o}"); + try depTokenizer("\\#foo.o:", "target = {#foo.o}"); + try depTokenizer("\\\\foo.o:", "target = {\\foo.o}"); + try depTokenizer("$$foo.o:", "target = {$foo.o}"); +} + +test "empty target linefeeds" { + try depTokenizer("\n", ""); + try depTokenizer("\r\n", ""); + + const expect = "target = {foo.o}"; + try depTokenizer( + \\foo.o: + , + expect + ); + try depTokenizer( + \\foo.o: + \\ + , + expect + ); + try depTokenizer( + \\foo.o: + , + expect + ); + try depTokenizer( + \\foo.o: + \\ + , + expect + ); +} + +test "empty target linefeeds + continuations" { + const expect = "target = {foo.o}"; + try depTokenizer( + \\foo.o:\ + , + expect + ); + try depTokenizer( + \\foo.o:\ + \\ + , + expect + ); + try depTokenizer( + \\foo.o:\ + , + expect + ); + try depTokenizer( + \\foo.o:\ + \\ + , + expect + ); +} + +test "empty target linefeeds + hspace + continuations" { + const expect = "target = {foo.o}"; + try depTokenizer( + \\foo.o: \ + , + expect + ); + try depTokenizer( + \\foo.o: \ + \\ + , + expect + ); + try depTokenizer( + \\foo.o: \ + , + expect + ); + try depTokenizer( + \\foo.o: \ + \\ + , + expect + ); +} + +test "prereq" { + const expect = + \\target = {foo.o} + \\prereq = {foo.c} + ; + try depTokenizer("foo.o: foo.c", expect); + try depTokenizer( + \\foo.o: \ + \\foo.c + , expect); + try depTokenizer( + \\foo.o: \ + \\ foo.c + , expect); + try depTokenizer( + \\foo.o: \ + \\ foo.c + , expect); +} + +test "prereq continuation" { + const expect = + \\target = {foo.o} + \\prereq = {foo.h} + \\prereq = {bar.h} + ; + try depTokenizer( + \\foo.o: foo.h\ + \\bar.h + , + expect + ); + try depTokenizer( + \\foo.o: foo.h\ + \\bar.h + , + expect + ); +} + +test "multiple prereqs" { + const expect = + \\target = {foo.o} + \\prereq = {foo.c} + \\prereq = {foo.h} + \\prereq = {bar.h} + ; + try depTokenizer("foo.o: foo.c foo.h bar.h", expect); + try depTokenizer( + \\foo.o: \ + \\foo.c foo.h bar.h + , expect); + try depTokenizer( + \\foo.o: foo.c foo.h bar.h\ + , expect); + try depTokenizer( + \\foo.o: foo.c foo.h bar.h\ + \\ + , expect); + try depTokenizer( + \\foo.o: \ + \\foo.c \ + \\ foo.h\ + \\bar.h + \\ + , expect); + try depTokenizer( + \\foo.o: \ + \\foo.c \ + \\ foo.h\ + \\bar.h\ + \\ + , expect); + try depTokenizer( + \\foo.o: \ + \\foo.c \ + \\ foo.h\ + \\bar.h\ + , expect); +} + +test "multiple targets and prereqs" { + try depTokenizer( + \\foo.o: foo.c + \\bar.o: bar.c a.h b.h c.h + \\abc.o: abc.c \ + \\ one.h two.h \ + \\ three.h four.h + , + \\target = {foo.o} + \\prereq = {foo.c} + \\target = {bar.o} + \\prereq = {bar.c} + \\prereq = {a.h} + \\prereq = {b.h} + \\prereq = {c.h} + \\target = {abc.o} + \\prereq = {abc.c} + \\prereq = {one.h} + \\prereq = {two.h} + \\prereq = {three.h} + \\prereq = {four.h} + ); + try depTokenizer( + \\ascii.o: ascii.c + \\base64.o: base64.c stdio.h + \\elf.o: elf.c a.h b.h c.h + \\macho.o: \ + \\ macho.c\ + \\ a.h b.h c.h + , + \\target = {ascii.o} + \\prereq = {ascii.c} + \\target = {base64.o} + \\prereq = {base64.c} + \\prereq = {stdio.h} + \\target = {elf.o} + \\prereq = {elf.c} + \\prereq = {a.h} + \\prereq = {b.h} + \\prereq = {c.h} + \\target = {macho.o} + \\prereq = {macho.c} + \\prereq = {a.h} + \\prereq = {b.h} + \\prereq = {c.h} + ); + try depTokenizer( + \\a$$scii.o: ascii.c + \\\\base64.o: "\base64.c" "s t#dio.h" + \\e\\lf.o: "e\lf.c" "a.h$$" "$$b.h c.h$$" + \\macho.o: \ + \\ "macho!.c" \ + \\ a.h b.h c.h + , + \\target = {a$scii.o} + \\prereq = {ascii.c} + \\target = {\base64.o} + \\prereq = {\base64.c} + \\prereq = {s t#dio.h} + \\target = {e\lf.o} + \\prereq = {e\lf.c} + \\prereq = {a.h$$} + \\prereq = {$$b.h c.h$$} + \\target = {macho.o} + \\prereq = {macho!.c} + \\prereq = {a.h} + \\prereq = {b.h} + \\prereq = {c.h} + ); +} + +test "windows quoted prereqs" { + try depTokenizer( + \\c:\foo.o: "C:\Program Files (x86)\Microsoft Visual Studio\foo.c" + \\c:\foo2.o: "C:\Program Files (x86)\Microsoft Visual Studio\foo2.c" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo1.h" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\foo2.h" + , + \\target = {c:\foo.o} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo.c} + \\target = {c:\foo2.o} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.c} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo1.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\foo2.h} + ); +} + +test "windows mixed prereqs" { + try depTokenizer( + \\cimport.o: \ + \\ C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h" \ + \\ C:\msys64\opt\zig\lib\zig\include\vadefs.h \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h" \ + \\ "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h" \ + \\ "C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h" + , + \\target = {cimport.o} + \\prereq = {C:\msys64\home\anon\project\zig\master\zig-cache\o\qhvhbUo7GU5iKyQ5mpA8TcQpncCYaQu0wwvr3ybiSTj_Dtqi1Nmcb70kfODJ2Qlg\cimport.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\stdio.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\sal.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\concurrencysal.h} + \\prereq = {C:\msys64\opt\zig\lib\zig\include\vadefs.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vadefs.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstdio.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_stdio_config.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\string.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memory.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_memcpy_s.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\errno.h} + \\prereq = {C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.21.27702\lib\x64\\..\..\include\vcruntime_string.h} + \\prereq = {C:\Program Files (x86)\Windows Kits\10\\Include\10.0.17763.0\ucrt\corecrt_wstring.h} + ); +} + +test "funky targets" { + try depTokenizer( + \\C:\Users\anon\foo.o: + \\C:\Users\anon\foo\ .o: + \\C:\Users\anon\foo\#.o: + \\C:\Users\anon\foo$$.o: + \\C:\Users\anon\\\ foo.o: + \\C:\Users\anon\\#foo.o: + \\C:\Users\anon\$$foo.o: + \\C:\Users\anon\\\ \ \ \ \ foo.o: + , + \\target = {C:\Users\anon\foo.o} + \\target = {C:\Users\anon\foo .o} + \\target = {C:\Users\anon\foo#.o} + \\target = {C:\Users\anon\foo$.o} + \\target = {C:\Users\anon\ foo.o} + \\target = {C:\Users\anon\#foo.o} + \\target = {C:\Users\anon\$foo.o} + \\target = {C:\Users\anon\ foo.o} + ); +} + +test "error incomplete escape - reverse_solidus" { + try depTokenizer("\\", + \\ERROR: illegal char '\' at position 0: incomplete escape + ); + try depTokenizer("\t\\", + \\ERROR: illegal char '\' at position 1: incomplete escape + ); + try depTokenizer("\n\\", + \\ERROR: illegal char '\' at position 1: incomplete escape + ); + try depTokenizer("\r\\", + \\ERROR: illegal char '\' at position 1: incomplete escape + ); + try depTokenizer("\r\n\\", + \\ERROR: illegal char '\' at position 2: incomplete escape + ); + try depTokenizer(" \\", + \\ERROR: illegal char '\' at position 1: incomplete escape + ); +} + +test "error incomplete escape - dollar_sign" { + try depTokenizer("$", + \\ERROR: illegal char '$' at position 0: incomplete escape + ); + try depTokenizer("\t$", + \\ERROR: illegal char '$' at position 1: incomplete escape + ); + try depTokenizer("\n$", + \\ERROR: illegal char '$' at position 1: incomplete escape + ); + try depTokenizer("\r$", + \\ERROR: illegal char '$' at position 1: incomplete escape + ); + try depTokenizer("\r\n$", + \\ERROR: illegal char '$' at position 2: incomplete escape + ); + try depTokenizer(" $", + \\ERROR: illegal char '$' at position 1: incomplete escape + ); +} + +test "error incomplete target" { + try depTokenizer("foo.o", + \\ERROR: incomplete target 'foo.o' at position 0 + ); + try depTokenizer("\tfoo.o", + \\ERROR: incomplete target 'foo.o' at position 1 + ); + try depTokenizer("\nfoo.o", + \\ERROR: incomplete target 'foo.o' at position 1 + ); + try depTokenizer("\rfoo.o", + \\ERROR: incomplete target 'foo.o' at position 1 + ); + try depTokenizer("\r\nfoo.o", + \\ERROR: incomplete target 'foo.o' at position 2 + ); + try depTokenizer(" foo.o", + \\ERROR: incomplete target 'foo.o' at position 1 + ); + + try depTokenizer("\\ foo.o", + \\ERROR: incomplete target ' foo.o' at position 1 + ); + try depTokenizer("\\#foo.o", + \\ERROR: incomplete target '#foo.o' at position 1 + ); + try depTokenizer("\\\\foo.o", + \\ERROR: incomplete target '\foo.o' at position 1 + ); + try depTokenizer("$$foo.o", + \\ERROR: incomplete target '$foo.o' at position 1 + ); +} + +test "error illegal char at position - bad target escape" { + try depTokenizer("\\\t", + \\ERROR: illegal char \x09 at position 1: bad target escape + ); + try depTokenizer("\\\n", + \\ERROR: illegal char \x0A at position 1: bad target escape + ); + try depTokenizer("\\\r", + \\ERROR: illegal char \x0D at position 1: bad target escape + ); + try depTokenizer("\\\r\n", + \\ERROR: illegal char \x0D at position 1: bad target escape + ); +} + +test "error illegal char at position - execting dollar_sign" { + try depTokenizer("$\t", + \\ERROR: illegal char \x09 at position 1: expecting '$' + ); + try depTokenizer("$\n", + \\ERROR: illegal char \x0A at position 1: expecting '$' + ); + try depTokenizer("$\r", + \\ERROR: illegal char \x0D at position 1: expecting '$' + ); + try depTokenizer("$\r\n", + \\ERROR: illegal char \x0D at position 1: expecting '$' + ); +} + +test "error illegal char at position - invalid target" { + try depTokenizer("foo\t.o", + \\ERROR: illegal char \x09 at position 3: invalid target + ); + try depTokenizer("foo\n.o", + \\ERROR: illegal char \x0A at position 3: invalid target + ); + try depTokenizer("foo\r.o", + \\ERROR: illegal char \x0D at position 3: invalid target + ); + try depTokenizer("foo\r\n.o", + \\ERROR: illegal char \x0D at position 3: invalid target + ); +} + +test "error target - continuation expecting end-of-line" { + try depTokenizer("foo.o: \\\t", + \\target = {foo.o} + \\ERROR: illegal char \x09 at position 8: continuation expecting end-of-line + ); + try depTokenizer("foo.o: \\ ", + \\target = {foo.o} + \\ERROR: illegal char \x20 at position 8: continuation expecting end-of-line + ); + try depTokenizer("foo.o: \\x", + \\target = {foo.o} + \\ERROR: illegal char 'x' at position 8: continuation expecting end-of-line + ); + try depTokenizer("foo.o: \\ x", + \\target = {foo.o} + \\ERROR: illegal char 'x' at position 9: continuation expecting end-of-line + ); +} + +test "error prereq - continuation expecting end-of-line" { + try depTokenizer("foo.o: foo.h\\ x", + \\target = {foo.o} + \\ERROR: illegal char 'x' at position 14: continuation expecting end-of-line + ); +} + +// - tokenize input, emit textual representation, and compare to expect +fn depTokenizer(input: []const u8, expect: []const u8) !void { + var direct_allocator = std.heap.DirectAllocator.init(); + var arena_allocator = std.heap.ArenaAllocator.init(&direct_allocator.allocator); + const arena = &arena_allocator.allocator; + defer arena_allocator.deinit(); + + var it = Tokenizer.init(&direct_allocator.allocator, input); + var buffer = try std.Buffer.initSize(arena, 0); + var i: usize = 0; + while (true) { + const r = it.next() catch |err| { + switch (err) { + Tokenizer.Error.InvalidInput => { + if (i != 0) try buffer.append("\n"); + try buffer.append("ERROR: "); + try buffer.append(it.error_text); + }, + else => return err, + } + break; + }; + const token = r orelse break; + if (i != 0) try buffer.append("\n"); + try buffer.append(@tagName(token.id)); + try buffer.append(" = {"); + for (token.bytes) |b| { + try buffer.appendByte(printable_char_tab[b]); + } + try buffer.append("}"); + i += 1; + } + const got: []const u8 = buffer.toSlice(); + + if (std.mem.eql(u8, expect, got)) { + testing.expect(true); + return; + } + + var out = makeOutput(std.fs.File.write, try std.io.getStdErr()); + + try out.write("\n"); + try printSection(&out, "<<<< input", input); + try printSection(&out, "==== expect", expect); + try printSection(&out, ">>>> got", got); + try printRuler(&out); + + testing.expect(false); +} + +fn printSection(out: var, label: []const u8, bytes: []const u8) !void { + try printLabel(out, label, bytes); + try hexDump(out, bytes); + try printRuler(out); + try out.write(bytes); + try out.write("\n"); +} + +fn printLabel(out: var, label: []const u8, bytes: []const u8) !void { + var buf: [80]u8 = undefined; + var text = try std.fmt.bufPrint(buf[0..], "{} {} bytes ", label, bytes.len); + try out.write(text); + var i: usize = text.len; + const end = 79; + while (i < 79) : (i += 1) { + try out.write([]const u8{label[0]}); + } + try out.write("\n"); +} + +fn printRuler(out: var) !void { + var i: usize = 0; + const end = 79; + while (i < 79) : (i += 1) { + try out.write("-"); + } + try out.write("\n"); +} + +fn hexDump(out: var, bytes: []const u8) !void { + const n16 = bytes.len >> 4; + var line: usize = 0; + var offset: usize = 0; + while (line < n16) : (line += 1) { + try hexDump16(out, offset, bytes[offset .. offset + 16]); + offset += 16; + } + + const n = bytes.len & 0x0f; + if (n > 0) { + try printDecValue(out, offset, 8); + try out.write(":"); + try out.write(" "); + var end1 = std.math.min(offset + n, offset + 8); + for (bytes[offset..end1]) |b| { + try out.write(" "); + try printHexValue(out, b, 2); + } + var end2 = offset + n; + if (end2 > end1) { + try out.write(" "); + for (bytes[end1..end2]) |b| { + try out.write(" "); + try printHexValue(out, b, 2); + } + } + const short = 16 - n; + var i: usize = 0; + while (i < short) : (i += 1) { + try out.write(" "); + } + if (end2 > end1) { + try out.write(" |"); + } else { + try out.write(" |"); + } + try printCharValues(out, bytes[offset..end2]); + try out.write("|\n"); + offset += n; + } + + try printDecValue(out, offset, 8); + try out.write(":"); + try out.write("\n"); +} + +fn hexDump16(out: var, offset: usize, bytes: []const u8) !void { + try printDecValue(out, offset, 8); + try out.write(":"); + try out.write(" "); + for (bytes[0..8]) |b| { + try out.write(" "); + try printHexValue(out, b, 2); + } + try out.write(" "); + for (bytes[8..16]) |b| { + try out.write(" "); + try printHexValue(out, b, 2); + } + try out.write(" |"); + try printCharValues(out, bytes); + try out.write("|\n"); +} + +fn printDecValue(out: var, value: u64, width: u8) !void { + var buffer: [20]u8 = undefined; + const len = std.fmt.formatIntBuf(buffer[0..], value, 10, false, width); + try out.write(buffer[0..len]); +} + +fn printHexValue(out: var, value: u64, width: u8) !void { + var buffer: [16]u8 = undefined; + const len = std.fmt.formatIntBuf(buffer[0..], value, 16, false, width); + try out.write(buffer[0..len]); +} + +fn printCharValues(out: var, bytes: []const u8) !void { + for (bytes) |b| { + try out.write([]const u8{printable_char_tab[b]}); + } +} + +fn printUnderstandableChar(out: var, char: u8) !void { + if (!std.ascii.isPrint(char) or char == ' ') { + std.fmt.format(out.context, anyerror, out.output, "\\x{X2}", char) catch {}; + } else { + try out.write("'"); + try out.write([]const u8{printable_char_tab[char]}); + try out.write("'"); + } +} + +// zig fmt: off +const printable_char_tab: []const u8 = + "................................ !\"#$%&'()*+,-./0123456789:;<=>?" ++ + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~." ++ + "................................................................" ++ + "................................................................"; +// zig fmt: on +comptime { + std.debug.assert(printable_char_tab.len == 256); +} + +// Make an output var that wraps a context and output function. +// output: must be a function that takes a `self` idiom parameter +// and a bytes parameter +// context: must be that self +fn makeOutput(output: var, context: var) Output(@typeOf(output)) { + return Output(@typeOf(output)){ + .output = output, + .context = context, + }; +} + +fn Output(comptime T: type) type { + const args = switch (@typeInfo(T)) { + .Fn => |f| f.args, + else => @compileError("output parameter is not a function"), + }; + if (args.len != 2) { + @compileError("output function must take 2 arguments"); + } + const at0 = args[0].arg_type orelse @compileError("output arg[0] does not have a type"); + const at1 = args[1].arg_type orelse @compileError("output arg[1] does not have a type"); + const arg1p = switch (@typeInfo(at1)) { + .Pointer => |p| p, + else => @compileError("output arg[1] is not a slice"), + }; + if (arg1p.child != u8) @compileError("output arg[1] is not a u8 slice"); + return struct { + output: T, + context: at0, + + fn write(self: *@This(), bytes: []const u8) !void { + try self.output(self.context, bytes); + } + }; +} diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index dd1c137c74ccefc007987d2c1f37d753765a15e5..b5beb02f10fc412c24d138dd129be0aa49eb04d0 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -20,6 +20,10 @@ var stderr_file: fs.File = undefined; var stderr: *io.OutStream(fs.File.WriteError) = undefined; var stdout: *io.OutStream(fs.File.WriteError) = undefined; +comptime { + _ = @import("dep_tokenizer.zig"); +} + // ABI warning export fn stage2_zen(ptr: *[*]const u8, len: *usize) void { const info_zen = @import("main.zig").info_zen; diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index cd0cc5324da7a638aa4e1faf42c9fcafa3bd39cc..381a29a2f173554800d8de9fb0e72789dc0d80cc 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -5,6 +5,7 @@ * See http://opensource.org/licenses/MIT */ +#include "userland.h" #include "cache_hash.hpp" #include "all_types.hpp" #include "buffer.hpp" @@ -473,71 +474,62 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) { if (err == ErrorFileNotFound) return err; if (verbose) { - fprintf(stderr, "unable to read .d file: %s\n", err_str(err)); + fprintf(stderr, "%s: unable to read .d file: %s\n", err_str(err), buf_ptr(dep_file_path)); } return ErrorReadingDepFile; } - SplitIterator it = memSplit(buf_to_slice(contents), str("\r\n")); - // skip first line - SplitIterator_next(&it); + auto it = stage2_DepTokenizer_init(buf_ptr(contents), buf_len(contents)); + // skip first token: target + { + auto result = stage2_DepTokenizer_next(&it); + switch (result.ent) { + case stage2_DepNextResult::error: + if (verbose) { + fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); + } + err = ErrorInvalidDepFile; + goto finish; + case stage2_DepNextResult::null: + err = ErrorNone; + goto finish; + case stage2_DepNextResult::target: + case stage2_DepNextResult::prereq: + err = ErrorNone; + break; + } + } + // Process 0+ preqreqs. + // clang is invoked in single-source mode so we never get more targets. for (;;) { - Optional> opt_line = SplitIterator_next(&it); - if (!opt_line.is_some) - break; - if (opt_line.value.len == 0) - continue; - // skip over indentation - while (opt_line.value.len != 0 && (opt_line.value.ptr[0] == ' ' || opt_line.value.ptr[0] == '\t')) { - opt_line.value.ptr += 1; - opt_line.value.len -= 1; + auto result = stage2_DepTokenizer_next(&it); + switch (result.ent) { + case stage2_DepNextResult::error: + if (verbose) { + fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); + } + err = ErrorInvalidDepFile; + goto finish; + case stage2_DepNextResult::null: + case stage2_DepNextResult::target: + err = ErrorNone; + goto finish; + case stage2_DepNextResult::prereq: + break; } - if (opt_line.value.len == 0) - continue; + auto textbuf = buf_alloc(); + buf_init_from_str(textbuf, result.textz); + if ((err = cache_add_file(ch, textbuf))) { + if (verbose) { + fprintf(stderr, "unable to add %s to cache: %s\n", result.textz, err_str(err)); + fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path)); + } + goto finish; + } + } - if (opt_line.value.ptr[0] == '"') { - if (opt_line.value.len < 2) { - if (verbose) { - fprintf(stderr, "unable to process invalid .d file %s: line too short\n", buf_ptr(dep_file_path)); - } - return ErrorInvalidDepFile; - } - opt_line.value.ptr += 1; - opt_line.value.len -= 2; - while (opt_line.value.len != 0 && opt_line.value.ptr[opt_line.value.len] != '"') { - opt_line.value.len -= 1; - } - if (opt_line.value.len == 0) { - if (verbose) { - fprintf(stderr, "unable to process invalid .d file %s: missing double quote\n", buf_ptr(dep_file_path)); - } - return ErrorInvalidDepFile; - } - Buf *filename_buf = buf_create_from_slice(opt_line.value); - if ((err = cache_add_file(ch, filename_buf))) { - if (verbose) { - fprintf(stderr, "unable to add %s to cache: %s\n", buf_ptr(filename_buf), err_str(err)); - fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path)); - } - return err; - } - } else { - // sometimes there are multiple files on the same line; we actually need space tokenization. - SplitIterator line_it = memSplit(opt_line.value, str(" \t")); - Slice filename; - while (SplitIterator_next(&line_it).unwrap(&filename)) { - Buf *filename_buf = buf_create_from_slice(filename); - if (buf_eql_str(filename_buf, "\\")) continue; - if ((err = cache_add_file(ch, filename_buf))) { - if (verbose) { - fprintf(stderr, "unable to add %s to cache: %s\n", buf_ptr(filename_buf), err_str(err)); - fprintf(stderr, "when processing .d file: %s\n", buf_ptr(dep_file_path)); - } - return err; - } - } - } - } - return ErrorNone; + finish: + stage2_DepTokenizer_deinit(&it); + return err; } static Error write_manifest_file(CacheHash *ch) { diff --git a/src/userland.cpp b/src/userland.cpp index 20740711e5c64d34ae9fa5517a5a2b78abd22fd5..d0330669ddb18ffb85295ce939032cb43d281796 100644 --- a/src/userland.cpp +++ b/src/userland.cpp @@ -42,3 +42,18 @@ int stage2_fmt(int argc, char **argv) { const char *msg = "stage0 called stage2_fmt"; stage2_panic(msg, strlen(msg)); } + +stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) { + const char *msg = "stage0 called stage2_DepTokenizer_init"; + stage2_panic(msg, strlen(msg)); +} + +void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) { + const char *msg = "stage0 called stage2_DepTokenizer_deinit"; + stage2_panic(msg, strlen(msg)); +} + +stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) { + const char *msg = "stage0 called stage2_DepTokenizer_next"; + stage2_panic(msg, strlen(msg)); +} diff --git a/src/userland.h b/src/userland.h index d61081c0a0cc0719bce81c5adfd60d78f1b316f8..488113d6b68e85b68e233738dcbc0b5dda601d66 100644 --- a/src/userland.h +++ b/src/userland.h @@ -9,6 +9,7 @@ #define ZIG_USERLAND_H #include +#include #include #ifdef __cplusplus @@ -118,4 +119,36 @@ ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t le // ABI warning ZIG_EXTERN_C int stage2_fmt(int argc, char **argv); +// ABI warning +struct stage2_DepTokenizer { + void *handle; +}; + +// ABI warning +struct stage2_DepNextResult { + enum Ent : uint8_t { + error, + null, + target, + prereq, + }; + + Ent ent; + + // when ent == error --> error text + // when ent == null --> undefined + // when ent == target --> target pathname + // when ent == prereq --> prereq pathname + const char *textz; +}; + +// ABI warning +ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len); + +// ABI warning +ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self); + +// ABI warning +ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self); + #endif -- 2.54.0 From 2c0280ba085893984007706fb40c7b291f43074d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 27 May 2019 20:59:19 -0400 Subject: [PATCH 09/84] improve the stack check CLI options See #2526 --- src/all_types.hpp | 17 ++++++++++++----- src/codegen.cpp | 32 ++++++++++++++++++++------------ src/link.cpp | 2 +- src/main.cpp | 14 +++++++++----- src/target.cpp | 4 ++++ src/target.hpp | 1 + 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 2cd4a5f9586a075a8f3277ca5b71f14c0872ed10..a0b4fadedcb217d353f04879ca43c9bb8e18f4eb 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1633,6 +1633,12 @@ enum WantPIC { WantPICEnabled, }; +enum WantStackCheck { + WantStackCheckAuto, + WantStackCheckDisabled, + WantStackCheckEnabled, +}; + struct CFile { ZigList args; const char *source_path; @@ -1790,6 +1796,8 @@ struct CodeGen { TldFn *panic_tld_fn; AstNode *root_export_decl; + WantPIC want_pic; + WantStackCheck want_stack_check; CacheHash cache_hash; ErrColor err_color; uint32_t next_unresolved_index; @@ -1807,8 +1815,6 @@ struct CodeGen { bool have_dllmain_crt_startup; bool have_pub_panic; bool have_err_ret_tracing; - bool have_pic; - bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic bool c_want_stdint; bool c_want_stdbool; bool verbose_tokenize; @@ -1824,6 +1830,7 @@ struct CodeGen { bool enable_time_report; bool system_linker_hack; bool reported_bad_link_libc_error; + bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl. //////////////////////////// Participates in Input Parameter Cache Hash /////// Note: there is a separate cache hash for builtin.zig, when adding fields, @@ -1852,8 +1859,6 @@ struct CodeGen { const ZigTarget *zig_target; TargetSubsystem subsystem; ValgrindSupport valgrind_support; - WantPIC want_pic; - bool is_dynamic; // shared library rather than static library. dynamic musl rather than static musl. bool strip_debug_symbols; bool is_test_build; bool is_single_threaded; @@ -1863,7 +1868,9 @@ struct CodeGen { bool is_dummy_so; bool disable_gen_h; bool bundle_compiler_rt; - bool disable_stack_probing; + bool have_pic; + bool have_dynamic_link; // this is whether the final thing will be dynamically linked. see also is_dynamic + bool have_stack_probing; Buf *mmacosx_version_min; Buf *mios_version_min; diff --git a/src/codegen.cpp b/src/codegen.cpp index 00a43388105468dae308366c2962c830ed02a056..2c3e30b3d8153f952875b75f85d8dd934a05d2ba 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -399,15 +399,6 @@ static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { } } -static void add_probe_stack_attr(CodeGen *g, LLVMValueRef fn_val) { - // Windows already emits its own stack probes - if (!g->disable_stack_probing && g->zig_target->os != OsWindows && - (g->zig_target->arch == ZigLLVM_x86 || - g->zig_target->arch == ZigLLVM_x86_64)) { - addLLVMFnAttrStr(fn_val, "probe-stack", "__zig_probe_stack"); - } -} - static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { switch (id) { case GlobalLinkageIdInternal: @@ -596,8 +587,9 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) { addLLVMFnAttr(fn_table_entry->llvm_value, "sspstrong"); addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4"); } - - add_probe_stack_attr(g, fn_table_entry->llvm_value); + } + if (g->have_stack_probing && !fn_table_entry->def_scope->safety_off) { + addLLVMFnAttrStr(fn_table_entry->llvm_value, "probe-stack", "__zig_probe_stack"); } } else { maybe_import_dll(g, fn_table_entry->llvm_value, linkage); @@ -7458,6 +7450,20 @@ static bool detect_pic(CodeGen *g) { zig_unreachable(); } +static bool detect_stack_probing(CodeGen *g) { + if (!target_supports_stack_probing(g->zig_target)) + return false; + switch (g->want_stack_check) { + case WantStackCheckDisabled: + return false; + case WantStackCheckEnabled: + return true; + case WantStackCheckAuto: + return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; + } + zig_unreachable(); +} + static bool detect_single_threaded(CodeGen *g) { if (g->want_single_threaded) return true; @@ -7476,6 +7482,7 @@ static bool detect_err_ret_tracing(CodeGen *g) { Buf *codegen_generate_builtin_source(CodeGen *g) { g->have_dynamic_link = detect_dynamic_link(g); g->have_pic = detect_pic(g); + g->have_stack_probing = detect_stack_probing(g); g->is_single_threaded = detect_single_threaded(g); g->have_err_ret_tracing = detect_err_ret_tracing(g); @@ -7982,6 +7989,7 @@ static void init(CodeGen *g) { g->have_dynamic_link = detect_dynamic_link(g); g->have_pic = detect_pic(g); + g->have_stack_probing = detect_stack_probing(g); g->is_single_threaded = detect_single_threaded(g); g->have_err_ret_tracing = detect_err_ret_tracing(g); @@ -9351,10 +9359,10 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->each_lib_rpath); cache_bool(ch, g->disable_gen_h); cache_bool(ch, g->bundle_compiler_rt); - cache_bool(ch, g->disable_stack_probing); cache_bool(ch, want_valgrind_support(g)); cache_bool(ch, g->have_pic); cache_bool(ch, g->have_dynamic_link); + cache_bool(ch, g->have_stack_probing); cache_bool(ch, g->is_dummy_so); cache_buf_opt(ch, g->mmacosx_version_min); cache_buf_opt(ch, g->mios_version_min); diff --git a/src/link.cpp b/src/link.cpp index b47da87c681b48ff5948f9fd4a34adfcb7252d6f..4c3b3d476979fd4d1ca0a6744daa81b523efc7b8 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -25,7 +25,7 @@ static CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, Ou CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir, libc, get_stage1_cache_path()); child_gen->disable_gen_h = true; - child_gen->disable_stack_probing = true; + child_gen->want_stack_check = WantStackCheckDisabled; child_gen->verbose_tokenize = parent_gen->verbose_tokenize; child_gen->verbose_ast = parent_gen->verbose_ast; child_gen->verbose_link = parent_gen->verbose_link; diff --git a/src/main.cpp b/src/main.cpp index 934c9984352935d73de65ca8981f30757122875e..cbfd9468996fc6581d2bd148dd32391f38c0714e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,7 +55,8 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { " --disable-gen-h do not generate a C header file (.h)\n" " --disable-valgrind omit valgrind client requests in debug builds\n" " --enable-valgrind include valgrind client requests release builds\n" - " --disable-stack-probing workaround for macosx\n" + " -fstack-check enable stack probing in unsafe builds\n" + " -fno-stack-check disable stack probing in safe builds\n" " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" " -fPIC enable Position Independent Code\n" " -fno-PIC disable Position Independent Code\n" @@ -443,12 +444,12 @@ int main(int argc, char **argv) { bool want_single_threaded = false; bool disable_gen_h = false; bool bundle_compiler_rt = false; - bool disable_stack_probing = false; Buf *override_std_dir = nullptr; Buf *override_lib_dir = nullptr; Buf *main_pkg_path = nullptr; ValgrindSupport valgrind_support = ValgrindSupportAuto; WantPIC want_pic = WantPICAuto; + WantStackCheck want_stack_check = WantStackCheckAuto; ZigList llvm_argv = {0}; llvm_argv.append("zig (LLVM option parsing)"); @@ -648,6 +649,10 @@ int main(int argc, char **argv) { want_pic = WantPICEnabled; } else if (strcmp(arg, "-fno-PIC") == 0) { want_pic = WantPICDisabled; + } else if (strcmp(arg, "-fstack-check") == 0) { + want_stack_check = WantStackCheckEnabled; + } else if (strcmp(arg, "-fno-stack-check") == 0) { + want_stack_check = WantStackCheckDisabled; } else if (strcmp(arg, "--system-linker-hack") == 0) { system_linker_hack = true; } else if (strcmp(arg, "--single-threaded") == 0) { @@ -656,8 +661,6 @@ int main(int argc, char **argv) { disable_gen_h = true; } else if (strcmp(arg, "--bundle-compiler-rt") == 0) { bundle_compiler_rt = true; - } else if (strcmp(arg, "--disable-stack-probing") == 0) { - disable_stack_probing = true; } else if (strcmp(arg, "--test-cmd-bin") == 0) { test_exec_args.append(nullptr); } else if (arg[1] == 'L' && arg[2] != 0) { @@ -953,6 +956,7 @@ int main(int argc, char **argv) { out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr); g->valgrind_support = valgrind_support; g->want_pic = want_pic; + g->want_stack_check = want_stack_check; g->want_single_threaded = want_single_threaded; Buf *builtin_source = codegen_generate_builtin_source(g); if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) { @@ -1048,6 +1052,7 @@ int main(int argc, char **argv) { if (llvm_argv.length >= 2) codegen_set_llvm_argv(g, llvm_argv.items + 1, llvm_argv.length - 2); g->valgrind_support = valgrind_support; g->want_pic = want_pic; + g->want_stack_check = want_stack_check; g->subsystem = subsystem; g->enable_time_report = timing_info; @@ -1074,7 +1079,6 @@ int main(int argc, char **argv) { g->output_dir = output_dir; g->disable_gen_h = disable_gen_h; g->bundle_compiler_rt = bundle_compiler_rt; - g->disable_stack_probing = disable_stack_probing; codegen_set_errmsg_color(g, color); g->system_linker_hack = system_linker_hack; diff --git a/src/target.cpp b/src/target.cpp index 630096204ba42b31de1aad549484e81841ada436..7862f6d44934f2c52a34f7519192ed16185625ad 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -1356,6 +1356,10 @@ bool target_supports_fpic(const ZigTarget *target) { return target->os != OsWindows; } +bool target_supports_stack_probing(const ZigTarget *target) { + return target->os != OsWindows && (target->arch == ZigLLVM_x86 || target->arch == ZigLLVM_x86_64); +} + bool target_requires_pic(const ZigTarget *target, bool linking_libc) { // This function returns whether non-pic code is completely invalid on the given target. return target->os == OsWindows || target_os_requires_libc(target->os) || diff --git a/src/target.hpp b/src/target.hpp index fd5c7471c34f4c8a5967fab4a722da259f5a981c..f3cde902a09e9db51e2a8f8698b1c8703ac7ff83 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -172,6 +172,7 @@ bool target_is_glibc(const ZigTarget *target); bool target_is_musl(const ZigTarget *target); bool target_is_wasm(const ZigTarget *target); bool target_is_single_threaded(const ZigTarget *target); +bool target_supports_stack_probing(const ZigTarget *target); uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch); -- 2.54.0 From 3f302594b855e4d0dff9fbbfb2fe9d1d1801cb6e Mon Sep 17 00:00:00 2001 From: emekoi Date: Sat, 25 May 2019 14:25:46 -0500 Subject: [PATCH 10/84] respect subsystem flag in all cases --- src/analyze.cpp | 6 +++--- src/codegen.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index d6396832c40a97970a5ead592e756a9f08e8c2be..0c629d67522d5274b3231e1039ad3a82a11aafd1 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2711,12 +2711,12 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->subsystem = TargetSubsystemConsole; + g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target->os == OsWindows) { g->have_winmain = true; - g->subsystem = TargetSubsystemWindows; + g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemWindows : g->subsystem; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target->os == OsWindows) { @@ -3937,7 +3937,7 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu if (is_pub) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->subsystem = TargetSubsystemConsole; + g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index 6b6564ffba6aa6c6abd9327a322e3efd48d9e03b..54e9c44f92dfe182dcef5e089e6aa0eaefcd7dd5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7998,7 +7998,7 @@ static void init(CodeGen *g) { } if (g->is_test_build) { - g->subsystem = TargetSubsystemConsole; + g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; } assert(g->root_out_name); -- 2.54.0 From bcdbd8d1697725992cb08eb1c3c59bd63fda6dc7 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 28 May 2019 15:22:19 +0200 Subject: [PATCH 11/84] Add sigaltstack syscall --- std/c/freebsd.zig | 4 ++++ std/c/linux.zig | 2 ++ std/c/netbsd.zig | 4 ++++ std/os/bits/darwin.zig | 12 ++++++++++++ std/os/bits/freebsd.zig | 16 ++++++++++++++++ std/os/bits/linux.zig | 21 +++++++++++++++++++++ std/os/bits/netbsd.zig | 12 ++++++++++++ std/os/linux.zig | 4 ++++ std/os/linux/test.zig | 9 +++++++++ 9 files changed, 84 insertions(+) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index 70f3aeb9ca9d2c1c2e229c9c6b56f5870982ae75..eaa073677ddb0b11a42b890cb0afa5c692674c6b 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -1,4 +1,8 @@ +const std = @import("../std.zig"); +use std.c; + extern "c" fn __error() *c_int; pub const _errno = __error; pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; diff --git a/std/c/linux.zig b/std/c/linux.zig index 9e028728c7560c97612b69067ab3757ee8b282f6..eb150634e551001c390484ed81cbdfc9ba957ad6 100644 --- a/std/c/linux.zig +++ b/std/c/linux.zig @@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong; pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int; pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; + +pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; diff --git a/std/c/netbsd.zig b/std/c/netbsd.zig index c677e1500b892de54555a1566e927f3518f8c3be..0ee94e822090fdab156ed539455a093a78012add 100644 --- a/std/c/netbsd.zig +++ b/std/c/netbsd.zig @@ -1,4 +1,8 @@ +const std = @import("../std.zig"); +use std.c; + extern "c" fn __errno() *c_int; pub const _errno = __errno; pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; diff --git a/std/os/bits/darwin.zig b/std/os/bits/darwin.zig index a685735da03e8ad7fa433aa582a53dbae13d87f0..39dae6e7a1dabd012c7ba51108e20ab9a24ce6fe 100644 --- a/std/os/bits/darwin.zig +++ b/std/os/bits/darwin.zig @@ -1078,3 +1078,15 @@ pub const EQFULL = 106; /// Must be equal largest errno pub const ELAST = 106; + +pub const SIGSTKSZ = 131072; +pub const MINSIGSTKSZ = 32768; + +pub const SS_ONSTACK = 1; +pub const SS_DISABLE = 4; + +pub const stack_t = extern struct { + ss_sp: [*]u8, + ss_size: isize, + ss_flags: i32, +}; diff --git a/std/os/bits/freebsd.zig b/std/os/bits/freebsd.zig index 1925b75f3fab2e73f50953a5524b4e6eaa11b441..3fc019f9c16eba57ae5125c37d6f95982aed082d 100644 --- a/std/os/bits/freebsd.zig +++ b/std/os/bits/freebsd.zig @@ -835,3 +835,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable pub const EOWNERDEAD = 96; // Previous owner died pub const ELAST = 96; // Must be equal largest errno + +pub const MINSIGSTKSZ = switch (builtin.arch) { + .i386, .x86_64 => 2048, + .arm, .aarch64 => 4096, + else => @compileError("MINSIGSTKSZ not defined for this architecture"), +}; +pub const SIGSTKSZ = MINSIGSTKSZ + 32768; + +pub const SS_ONSTACK = 1; +pub const SS_DISABLE = 4; + +pub const stack_t = extern struct { + ss_sp: [*]u8, + ss_size: isize, + ss_flags: i32, +}; diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig index 6532e72362800c45c60aed530b6b77264d99549a..b9386e9b05b671cecabc9959e7cbfab9f983b55f 100644 --- a/std/os/bits/linux.zig +++ b/std/os/bits/linux.zig @@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t { //#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set) //#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set) //#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2) + +pub const MINSIGSTKSZ = switch (builtin.arch) { + .i386, .x86_64, .arm => 2048, + .aarch64 => 5120, + else => @compileError("MINSIGSTKSZ not defined for this architecture"), +}; +pub const SIGSTKSZ = switch (builtin.arch) { + .i386, .x86_64, .arm => 8192, + .aarch64 => 16384, + else => @compileError("SIGSTKSZ not defined for this architecture"), +}; + +pub const SS_ONSTACK = 1; +pub const SS_DISABLE = 2; +pub const SS_AUTODISARM = 1 << 31; + +pub const stack_t = extern struct { + ss_sp: [*]u8, + ss_flags: i32, + ss_size: isize, +}; diff --git a/std/os/bits/netbsd.zig b/std/os/bits/netbsd.zig index fc4c2904e027c42002c972bb31b9b6e3ea7e2dd3..e7a0f6ea5299e68815f130921e591b5df2cdaa1a 100644 --- a/std/os/bits/netbsd.zig +++ b/std/os/bits/netbsd.zig @@ -723,3 +723,15 @@ pub const ENOLINK = 95; // Link has been severed pub const EPROTO = 96; // Protocol error pub const ELAST = 96; // Must equal largest errno + +pub const MINSIGSTKSZ = 8192; +pub const SIGSTKSZ = MINSIGSTKSZ + 32768; + +pub const SS_ONSTACK = 1; +pub const SS_DISABLE = 4; + +pub const stack_t = extern struct { + ss_sp: [*]u8, + ss_size: isize, + ss_flags: i32, +}; diff --git a/std/os/linux.zig b/std/os/linux.zig index 282aa19bf13c8af05fabfba89b77aa659d2acc24..e4253becc55fa843c80d5b6e38701fdf358cb16f 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -818,6 +818,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize { return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap)); } +pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize { + return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss)); +} + // XXX: This should be weak extern const __ehdr_start: elf.Ehdr = undefined; diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig index c78b071c746b3eabdc2902fdcfee72ae6b36aece..063c10257c9cd53ce895dc4a2edc9be6396a6ea0 100644 --- a/std/os/linux/test.zig +++ b/std/os/linux/test.zig @@ -83,3 +83,12 @@ test "dl_iterate_phdr" { expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0); expect(counter != 0); } + +test "sigaltstack" { + var st: linux.stack_t = undefined; + expect(linux.sigaltstack(null, &st) == 0); + // Setting a stack size less than MINSIGSTKSZ returns ENOMEM + st.ss_flags = 0; + st.ss_size = 1; + expect(linux.getErrno(linux.sigaltstack(&st, null)) == linux.ENOMEM); +} -- 2.54.0 From b8cd4b18b068d83bd4c2ae44777f60244d8d1853 Mon Sep 17 00:00:00 2001 From: emekoi Date: Mon, 27 May 2019 10:12:07 -0500 Subject: [PATCH 12/84] remove unneed allocator from DynLib --- std/dynamic_library.zig | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig index 3ae3b4c66abf3d9a580340020c5feb7c17b377ea..db5dffeefd60b9649ab3c48cfb1633983bc46ffb 100644 --- a/std/dynamic_library.zig +++ b/std/dynamic_library.zig @@ -104,9 +104,9 @@ pub const LinuxDynLib = struct { memory: []align(mem.page_size) u8, /// Trusts the file - pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib { - const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC); - errdefer os.close(fd); + pub fn open(path: []const u8) !DynLib { + const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC); + errdefer std.os.close(fd); const size = @intCast(usize, (try os.fstat(fd)).size); @@ -244,15 +244,21 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [ } pub const WindowsDynLib = struct { - allocator: *mem.Allocator, dll: windows.HMODULE, - pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib { - const wpath = try windows.sliceToPrefixedFileW(path); + pub fn open(path: []const u8) !WindowsDynLib { + const wpath = try win_util.sliceToPrefixedFileW(path); return WindowsDynLib{ - .allocator = allocator, - .dll = try windows.LoadLibraryW(&wpath), + .dll = windows.LoadLibraryW(&wpath) orelse { + const err = windows.GetLastError(); + switch (err) { + windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, + windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, + windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound, + else => return os.unexpectedErrorWindows(err), + } + }, }; } @@ -273,7 +279,7 @@ test "dynamic_library" { else => return, }; - const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| { + const dynlib = DynLib.open(libname) catch |err| { testing.expect(err == error.FileNotFound); return; }; -- 2.54.0 From 775a25b7fda884a99240c63627e399ec347d2446 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Tue, 21 May 2019 15:23:28 +0200 Subject: [PATCH 13/84] Add declarations missing from clang.zig --- src-self-hosted/clang.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 92fe7b7cd38fbf7d060cfeeff4240ae7b9b7fe6e..b706c1c547ad99b48c70bdc6a614f17aec456fa5 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -1,5 +1,6 @@ pub const struct_ZigClangAPValue = @OpaqueType(); pub const struct_ZigClangAPSInt = @OpaqueType(); +pub const struct_ZigClangAPFloat = @OpaqueType(); pub const struct_ZigClangASTContext = @OpaqueType(); pub const struct_ZigClangASTUnit = @OpaqueType(); pub const struct_ZigClangArraySubscriptExpr = @OpaqueType(); @@ -69,6 +70,7 @@ pub const struct_ZigClangValueDecl = @OpaqueType(); pub const struct_ZigClangVarDecl = @OpaqueType(); pub const struct_ZigClangWhileStmt = @OpaqueType(); pub const ZigClangFunctionType = @OpaqueType(); +pub const struct_ZigClangPredefinedExpr = @OpaqueType(); pub const ZigClangBO = extern enum { PtrMemD, -- 2.54.0 From 333c050a1dbb42c36051d8ec4dc9550d9d6eee63 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:28:27 +0200 Subject: [PATCH 14/84] clang.zig cleanup #1: move block around --- src-self-hosted/clang.zig | 154 +++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index b706c1c547ad99b48c70bdc6a614f17aec456fa5..5386641df7ee371a75d958fb6dea002621cf35a5 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -452,6 +452,83 @@ pub const ZigClangAPValueKind = extern enum { AddrLabelDiff, }; +pub const ZigClangDeclKind = extern enum { + AccessSpec, + Block, + Captured, + ClassScopeFunctionSpecialization, + Empty, + Export, + ExternCContext, + FileScopeAsm, + Friend, + FriendTemplate, + Import, + LinkageSpec, + Label, + Namespace, + NamespaceAlias, + ObjCCompatibleAlias, + ObjCCategory, + ObjCCategoryImpl, + ObjCImplementation, + ObjCInterface, + ObjCProtocol, + ObjCMethod, + ObjCProperty, + BuiltinTemplate, + ClassTemplate, + FunctionTemplate, + TypeAliasTemplate, + VarTemplate, + TemplateTemplateParm, + Enum, + Record, + CXXRecord, + ClassTemplateSpecialization, + ClassTemplatePartialSpecialization, + TemplateTypeParm, + ObjCTypeParam, + TypeAlias, + Typedef, + UnresolvedUsingTypename, + Using, + UsingDirective, + UsingPack, + UsingShadow, + ConstructorUsingShadow, + Binding, + Field, + ObjCAtDefsField, + ObjCIvar, + Function, + CXXDeductionGuide, + CXXMethod, + CXXConstructor, + CXXConversion, + CXXDestructor, + MSProperty, + NonTypeTemplateParm, + Var, + Decomposition, + ImplicitParam, + OMPCapturedExpr, + ParmVar, + VarTemplateSpecialization, + VarTemplatePartialSpecialization, + EnumConstant, + IndirectField, + OMPDeclareReduction, + UnresolvedUsingValue, + OMPRequires, + OMPThreadPrivate, + ObjCPropertyImpl, + PragmaComment, + PragmaDetectMismatch, + StaticAssert, + TranslationUnit, +}; + pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; @@ -632,83 +709,6 @@ pub extern fn ZigClangLoadFromCommandLine( pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind; pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*]const u8; -pub const ZigClangDeclKind = extern enum { - AccessSpec, - Block, - Captured, - ClassScopeFunctionSpecialization, - Empty, - Export, - ExternCContext, - FileScopeAsm, - Friend, - FriendTemplate, - Import, - LinkageSpec, - Label, - Namespace, - NamespaceAlias, - ObjCCompatibleAlias, - ObjCCategory, - ObjCCategoryImpl, - ObjCImplementation, - ObjCInterface, - ObjCProtocol, - ObjCMethod, - ObjCProperty, - BuiltinTemplate, - ClassTemplate, - FunctionTemplate, - TypeAliasTemplate, - VarTemplate, - TemplateTemplateParm, - Enum, - Record, - CXXRecord, - ClassTemplateSpecialization, - ClassTemplatePartialSpecialization, - TemplateTypeParm, - ObjCTypeParam, - TypeAlias, - Typedef, - UnresolvedUsingTypename, - Using, - UsingDirective, - UsingPack, - UsingShadow, - ConstructorUsingShadow, - Binding, - Field, - ObjCAtDefsField, - ObjCIvar, - Function, - CXXDeductionGuide, - CXXMethod, - CXXConstructor, - CXXConversion, - CXXDestructor, - MSProperty, - NonTypeTemplateParm, - Var, - Decomposition, - ImplicitParam, - OMPCapturedExpr, - ParmVar, - VarTemplateSpecialization, - VarTemplatePartialSpecialization, - EnumConstant, - IndirectField, - OMPDeclareReduction, - UnresolvedUsingValue, - OMPRequires, - OMPThreadPrivate, - ObjCPropertyImpl, - PragmaComment, - PragmaDetectMismatch, - StaticAssert, - TranslationUnit, -}; - pub const struct_ZigClangQualType = extern struct { ptr: ?*c_void, }; -- 2.54.0 From abf97cc2329450619ecfbbe50b4c685e7ff003da Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:29:27 +0200 Subject: [PATCH 15/84] clang.zig cleanup #2: move block around --- src-self-hosted/clang.zig | 238 +++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 119 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 5386641df7ee371a75d958fb6dea002621cf35a5..a2c01610c8c2be3434c656a0cffcd26cad28604d 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -529,6 +529,125 @@ pub const ZigClangDeclKind = extern enum { TranslationUnit, }; +pub const ZigClangBuiltinTypeKind = extern enum { + OCLImage1dRO, + OCLImage1dArrayRO, + OCLImage1dBufferRO, + OCLImage2dRO, + OCLImage2dArrayRO, + OCLImage2dDepthRO, + OCLImage2dArrayDepthRO, + OCLImage2dMSAARO, + OCLImage2dArrayMSAARO, + OCLImage2dMSAADepthRO, + OCLImage2dArrayMSAADepthRO, + OCLImage3dRO, + OCLImage1dWO, + OCLImage1dArrayWO, + OCLImage1dBufferWO, + OCLImage2dWO, + OCLImage2dArrayWO, + OCLImage2dDepthWO, + OCLImage2dArrayDepthWO, + OCLImage2dMSAAWO, + OCLImage2dArrayMSAAWO, + OCLImage2dMSAADepthWO, + OCLImage2dArrayMSAADepthWO, + OCLImage3dWO, + OCLImage1dRW, + OCLImage1dArrayRW, + OCLImage1dBufferRW, + OCLImage2dRW, + OCLImage2dArrayRW, + OCLImage2dDepthRW, + OCLImage2dArrayDepthRW, + OCLImage2dMSAARW, + OCLImage2dArrayMSAARW, + OCLImage2dMSAADepthRW, + OCLImage2dArrayMSAADepthRW, + OCLImage3dRW, + OCLIntelSubgroupAVCMcePayload, + OCLIntelSubgroupAVCImePayload, + OCLIntelSubgroupAVCRefPayload, + OCLIntelSubgroupAVCSicPayload, + OCLIntelSubgroupAVCMceResult, + OCLIntelSubgroupAVCImeResult, + OCLIntelSubgroupAVCRefResult, + OCLIntelSubgroupAVCSicResult, + OCLIntelSubgroupAVCImeResultSingleRefStreamout, + OCLIntelSubgroupAVCImeResultDualRefStreamout, + OCLIntelSubgroupAVCImeSingleRefStreamin, + OCLIntelSubgroupAVCImeDualRefStreamin, + Void, + Bool, + Char_U, + UChar, + WChar_U, + Char8, + Char16, + Char32, + UShort, + UInt, + ULong, + ULongLong, + UInt128, + Char_S, + SChar, + WChar_S, + Short, + Int, + Long, + LongLong, + Int128, + ShortAccum, + Accum, + LongAccum, + UShortAccum, + UAccum, + ULongAccum, + ShortFract, + Fract, + LongFract, + UShortFract, + UFract, + ULongFract, + SatShortAccum, + SatAccum, + SatLongAccum, + SatUShortAccum, + SatUAccum, + SatULongAccum, + SatShortFract, + SatFract, + SatLongFract, + SatUShortFract, + SatUFract, + SatULongFract, + Half, + Float, + Double, + LongDouble, + Float16, + Float128, + NullPtr, + ObjCId, + ObjCClass, + ObjCSel, + OCLSampler, + OCLEvent, + OCLClkEvent, + OCLQueue, + OCLReserveID, + Dependent, + Overload, + BoundMember, + PseudoObject, + UnknownAny, + BuiltinFn, + ARCUnbridgedCast, + OMPArraySection, +}; + pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; @@ -713,125 +832,6 @@ pub const struct_ZigClangQualType = extern struct { ptr: ?*c_void, }; -pub const ZigClangBuiltinTypeKind = extern enum { - OCLImage1dRO, - OCLImage1dArrayRO, - OCLImage1dBufferRO, - OCLImage2dRO, - OCLImage2dArrayRO, - OCLImage2dDepthRO, - OCLImage2dArrayDepthRO, - OCLImage2dMSAARO, - OCLImage2dArrayMSAARO, - OCLImage2dMSAADepthRO, - OCLImage2dArrayMSAADepthRO, - OCLImage3dRO, - OCLImage1dWO, - OCLImage1dArrayWO, - OCLImage1dBufferWO, - OCLImage2dWO, - OCLImage2dArrayWO, - OCLImage2dDepthWO, - OCLImage2dArrayDepthWO, - OCLImage2dMSAAWO, - OCLImage2dArrayMSAAWO, - OCLImage2dMSAADepthWO, - OCLImage2dArrayMSAADepthWO, - OCLImage3dWO, - OCLImage1dRW, - OCLImage1dArrayRW, - OCLImage1dBufferRW, - OCLImage2dRW, - OCLImage2dArrayRW, - OCLImage2dDepthRW, - OCLImage2dArrayDepthRW, - OCLImage2dMSAARW, - OCLImage2dArrayMSAARW, - OCLImage2dMSAADepthRW, - OCLImage2dArrayMSAADepthRW, - OCLImage3dRW, - OCLIntelSubgroupAVCMcePayload, - OCLIntelSubgroupAVCImePayload, - OCLIntelSubgroupAVCRefPayload, - OCLIntelSubgroupAVCSicPayload, - OCLIntelSubgroupAVCMceResult, - OCLIntelSubgroupAVCImeResult, - OCLIntelSubgroupAVCRefResult, - OCLIntelSubgroupAVCSicResult, - OCLIntelSubgroupAVCImeResultSingleRefStreamout, - OCLIntelSubgroupAVCImeResultDualRefStreamout, - OCLIntelSubgroupAVCImeSingleRefStreamin, - OCLIntelSubgroupAVCImeDualRefStreamin, - Void, - Bool, - Char_U, - UChar, - WChar_U, - Char8, - Char16, - Char32, - UShort, - UInt, - ULong, - ULongLong, - UInt128, - Char_S, - SChar, - WChar_S, - Short, - Int, - Long, - LongLong, - Int128, - ShortAccum, - Accum, - LongAccum, - UShortAccum, - UAccum, - ULongAccum, - ShortFract, - Fract, - LongFract, - UShortFract, - UFract, - ULongFract, - SatShortAccum, - SatAccum, - SatLongAccum, - SatUShortAccum, - SatUAccum, - SatULongAccum, - SatShortFract, - SatFract, - SatLongFract, - SatUShortFract, - SatUFract, - SatULongFract, - Half, - Float, - Double, - LongDouble, - Float16, - Float128, - NullPtr, - ObjCId, - ObjCClass, - ObjCSel, - OCLSampler, - OCLEvent, - OCLClkEvent, - OCLQueue, - OCLReserveID, - Dependent, - Overload, - BoundMember, - PseudoObject, - UnknownAny, - BuiltinFn, - ARCUnbridgedCast, - OMPArraySection, -}; - pub const ZigClangCallingConv = extern enum { C, X86StdCall, -- 2.54.0 From 5df2e791c26df0ac9ef6ba0e3558eda7fe10d6b0 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:29:49 +0200 Subject: [PATCH 16/84] clang.zig cleanup #3: move block around --- src-self-hosted/clang.zig | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index a2c01610c8c2be3434c656a0cffcd26cad28604d..1edd5690a0a3388c99f3f8e4145e432f07994560 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -648,6 +648,27 @@ pub const ZigClangBuiltinTypeKind = extern enum { OMPArraySection, }; +pub const ZigClangCallingConv = extern enum { + C, + X86StdCall, + X86FastCall, + X86ThisCall, + X86VectorCall, + X86Pascal, + Win64, + X86_64SysV, + X86RegCall, + AAPCS, + AAPCS_VFP, + IntelOclBicc, + SpirFunction, + OpenCLKernel, + Swift, + PreserveMost, + PreserveAll, + AArch64VectorCall, +}; + pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; @@ -832,27 +853,6 @@ pub const struct_ZigClangQualType = extern struct { ptr: ?*c_void, }; -pub const ZigClangCallingConv = extern enum { - C, - X86StdCall, - X86FastCall, - X86ThisCall, - X86VectorCall, - X86Pascal, - Win64, - X86_64SysV, - X86RegCall, - AAPCS, - AAPCS_VFP, - IntelOclBicc, - SpirFunction, - OpenCLKernel, - Swift, - PreserveMost, - PreserveAll, - AArch64VectorCall, -}; - pub const ZigClangStorageClass = extern enum { None, Extern, -- 2.54.0 From 7f1dd05fa79bef8aba5f1cf697ff6866fca96617 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:30:08 +0200 Subject: [PATCH 17/84] clang.zig cleanup #4: move block around --- src-self-hosted/clang.zig | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 1edd5690a0a3388c99f3f8e4145e432f07994560..413d745d3e81bbe5a0777f8318c821a893bd8b7c 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -669,6 +669,15 @@ pub const ZigClangCallingConv = extern enum { AArch64VectorCall, }; +pub const ZigClangStorageClass = extern enum { + None, + Extern, + Static, + PrivateExtern, + Auto, + Register, +}; + pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; @@ -853,15 +862,6 @@ pub const struct_ZigClangQualType = extern struct { ptr: ?*c_void, }; -pub const ZigClangStorageClass = extern enum { - None, - Extern, - Static, - PrivateExtern, - Auto, - Register, -}; - pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt; pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; -- 2.54.0 From fd9e63da53afc1cf2a62c194a0d2ffaa93ef4709 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:32:51 +0200 Subject: [PATCH 18/84] clang.zig cleanup #5: add missing enums --- src-self-hosted/clang.zig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 413d745d3e81bbe5a0777f8318c821a893bd8b7c..206e78533e499ec4f5e4d1b383496f45b25fb135 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -678,6 +678,22 @@ pub const ZigClangStorageClass = extern enum { Register, }; +pub const ZigClangAPFloat_roundingMode = extern enum { + NearestTiesToEven, + TowardPositive, + TowardNegative, + TowardZero, + NearestTiesToAway, +}; + +pub const ZigClangStringLiteral_StringKind = extern enum { + Ascii, + Wide, + UTF8, + UTF16, + UTF32, +}; + pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; -- 2.54.0 From f4b4ea402e5de38b7a27e02e32852b2505ca408c Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:35:31 +0200 Subject: [PATCH 19/84] clang.zig cleanup #6: move block around --- src-self-hosted/clang.zig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 206e78533e499ec4f5e4d1b383496f45b25fb135..910761f149793697c88d1b8f668bb5f32d0aa1b0 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -861,6 +861,11 @@ pub const Stage2ErrorMsg = extern struct { // byte offset into source offset: c_uint, }; + +pub const struct_ZigClangQualType = extern struct { + ptr: ?*c_void, +}; + pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void; pub extern fn ZigClangLoadFromCommandLine( @@ -874,10 +879,6 @@ pub extern fn ZigClangLoadFromCommandLine( pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind; pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*]const u8; -pub const struct_ZigClangQualType = extern struct { - ptr: ?*c_void, -}; - pub const ZigClangCompoundStmt_const_body_iterator = [*c]const *struct_ZigClangStmt; pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator; -- 2.54.0 From b639447263e89b2d23b3c1857f0e766207152591 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:36:07 +0200 Subject: [PATCH 20/84] clang.zig cleanup #7: add missing struct --- src-self-hosted/clang.zig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 910761f149793697c88d1b8f668bb5f32d0aa1b0..21e2f5a4173111422a7491bed04df7a4931aeb1e 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -866,6 +866,12 @@ pub const struct_ZigClangQualType = extern struct { ptr: ?*c_void, }; +pub const struct_ZigClangAPValueLValueBase = extern struct { + Ptr: ?*c_void, + CallIndex: c_uint, + Version: c_uint, +}; + pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void; pub extern fn ZigClangLoadFromCommandLine( -- 2.54.0 From 8d50d4f3fcf23e1960e2f63e439e71a0e6d52640 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Wed, 22 May 2019 15:41:44 +0200 Subject: [PATCH 21/84] clang.zig cleanup #8: add missing consts --- src-self-hosted/clang.zig | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 21e2f5a4173111422a7491bed04df7a4931aeb1e..8be1d362cb434e79cddc9fbeefd78830592fd883 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -13,7 +13,7 @@ pub const struct_ZigClangCStyleCastExpr = @OpaqueType(); pub const struct_ZigClangCallExpr = @OpaqueType(); pub const struct_ZigClangCaseStmt = @OpaqueType(); pub const struct_ZigClangCompoundAssignOperator = @OpaqueType(); -pub const ZigClangCompoundStmt = @OpaqueType(); +pub const struct_ZigClangCompoundStmt = @OpaqueType(); pub const struct_ZigClangConditionalOperator = @OpaqueType(); pub const struct_ZigClangConstantArrayType = @OpaqueType(); pub const struct_ZigClangContinueStmt = @OpaqueType(); @@ -34,7 +34,7 @@ pub const struct_ZigClangFieldDecl = @OpaqueType(); pub const struct_ZigClangFileID = @OpaqueType(); pub const struct_ZigClangForStmt = @OpaqueType(); pub const struct_ZigClangFullSourceLoc = @OpaqueType(); -pub const ZigClangFunctionDecl = @OpaqueType(); +pub const struct_ZigClangFunctionDecl = @OpaqueType(); pub const struct_ZigClangFunctionProtoType = @OpaqueType(); pub const struct_ZigClangIfStmt = @OpaqueType(); pub const struct_ZigClangImplicitCastExpr = @OpaqueType(); @@ -69,7 +69,7 @@ pub const struct_ZigClangUnaryOperator = @OpaqueType(); pub const struct_ZigClangValueDecl = @OpaqueType(); pub const struct_ZigClangVarDecl = @OpaqueType(); pub const struct_ZigClangWhileStmt = @OpaqueType(); -pub const ZigClangFunctionType = @OpaqueType(); +pub const struct_ZigClangFunctionType = @OpaqueType(); pub const struct_ZigClangPredefinedExpr = @OpaqueType(); pub const ZigClangBO = extern enum { @@ -776,6 +776,7 @@ pub const ZigClangQualType = struct_ZigClangQualType; pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase; pub const ZigClangAPValue = struct_ZigClangAPValue; pub const ZigClangAPSInt = struct_ZigClangAPSInt; +pub const ZigClangAPFloat = struct_ZigClangAPFloat; pub const ZigClangASTContext = struct_ZigClangASTContext; pub const ZigClangASTUnit = struct_ZigClangASTUnit; pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr; @@ -788,6 +789,7 @@ pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr; pub const ZigClangCallExpr = struct_ZigClangCallExpr; pub const ZigClangCaseStmt = struct_ZigClangCaseStmt; pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator; +pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt; pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator; pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType; pub const ZigClangContinueStmt = struct_ZigClangContinueStmt; @@ -808,6 +810,7 @@ pub const ZigClangFieldDecl = struct_ZigClangFieldDecl; pub const ZigClangFileID = struct_ZigClangFileID; pub const ZigClangForStmt = struct_ZigClangForStmt; pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc; +pub const ZigClangFunctionDecl = struct_ZigClangFunctionDecl; pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType; pub const ZigClangIfStmt = struct_ZigClangIfStmt; pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr; @@ -842,6 +845,8 @@ pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator; pub const ZigClangValueDecl = struct_ZigClangValueDecl; pub const ZigClangVarDecl = struct_ZigClangVarDecl; pub const ZigClangWhileStmt = struct_ZigClangWhileStmt; +pub const ZigClangFunctionType = struct_ZigClangFunctionType; +pub const ZigClangPredefinedExpr = struct_ZigClangPredefinedExpr; pub const struct_ZigClangSourceLocation = extern struct { ID: c_uint, -- 2.54.0 From 6547468af60be75e4256805dd2bdff4b14688262 Mon Sep 17 00:00:00 2001 From: Gonzalo Diethelm Date: Tue, 28 May 2019 17:58:22 +0200 Subject: [PATCH 22/84] clang.zig cleanup #9: rename arg0 to self --- src-self-hosted/clang.zig | 46 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig index 8be1d362cb434e79cddc9fbeefd78830592fd883..20a815cb7587743e844b24ae67c9c43d67c015f7 100644 --- a/src-self-hosted/clang.zig +++ b/src-self-hosted/clang.zig @@ -694,41 +694,41 @@ pub const ZigClangStringLiteral_StringKind = extern enum { UTF32, }; -pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; +pub extern fn ZigClangSourceManager_getSpellingLoc(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation; pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*]const u8; -pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; -pub extern fn ZigClangSourceManager_getSpellingColumnNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; -pub extern fn ZigClangSourceManager_getCharacterData(arg0: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8; -pub extern fn ZigClangASTContext_getPointerType(arg0: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType; -pub extern fn ZigClangASTUnit_getASTContext(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext; +pub extern fn ZigClangSourceManager_getSpellingLineNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; +pub extern fn ZigClangSourceManager_getSpellingColumnNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint; +pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8; +pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType; +pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext; pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager; pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool; pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl; pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl; pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl; -pub extern fn ZigClangEnumDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; -pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; -pub extern fn ZigClangRecordDecl_getDefinition(arg0: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl; -pub extern fn ZigClangEnumDecl_getDefinition(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl; -pub extern fn ZigClangRecordDecl_getLocation(arg0: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation; -pub extern fn ZigClangEnumDecl_getLocation(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation; -pub extern fn ZigClangTypedefNameDecl_getLocation(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl; +pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl; +pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl; +pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl; +pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangEnumDecl_getLocation(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation; +pub extern fn ZigClangTypedefNameDecl_getLocation(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation; pub extern fn ZigClangDecl_getLocation(self: *const ZigClangDecl) ZigClangSourceLocation; pub extern fn ZigClangRecordDecl_isUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool; pub extern fn ZigClangRecordDecl_isStruct(record_decl: ?*const struct_ZigClangRecordDecl) bool; pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool; -pub extern fn ZigClangEnumDecl_getIntegerType(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType; +pub extern fn ZigClangEnumDecl_getIntegerType(self: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType; pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8; pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool; -pub extern fn ZigClangTypedefType_getDecl(arg0: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl; -pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType; -pub extern fn ZigClangQualType_getCanonicalType(arg0: struct_ZigClangQualType) struct_ZigClangQualType; +pub extern fn ZigClangTypedefType_getDecl(self: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl; +pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(self: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType; +pub extern fn ZigClangQualType_getCanonicalType(self: struct_ZigClangQualType) struct_ZigClangQualType; pub extern fn ZigClangQualType_getTypePtr(self: struct_ZigClangQualType) *const struct_ZigClangType; -pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void; -pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool; -pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) bool; -pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool; -pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_addConst(self: [*c]struct_ZigClangQualType) void; +pub extern fn ZigClangQualType_eq(self: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isConstQualified(self: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isVolatileQualified(self: struct_ZigClangQualType) bool; +pub extern fn ZigClangQualType_isRestrictQualified(self: struct_ZigClangQualType) bool; pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) ZigClangTypeClass; pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool; pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*]const u8; @@ -752,7 +752,7 @@ pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void; pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64; pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint; pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr; -pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void; +pub extern fn ZigClangASTUnit_delete(self: ?*struct_ZigClangASTUnit) void; pub extern fn ZigClangFunctionDecl_getType(self: *const ZigClangFunctionDecl) struct_ZigClangQualType; pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl) struct_ZigClangSourceLocation; -- 2.54.0 From f2b64fd18f73fe26934b388c1da95e1b4e770c83 Mon Sep 17 00:00:00 2001 From: emekoi Date: Tue, 28 May 2019 11:18:30 -0500 Subject: [PATCH 23/84] updated dynamic libraries to new std --- std/dynamic_library.zig | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig index db5dffeefd60b9649ab3c48cfb1633983bc46ffb..e55d6df84ffdb0a31fe2f23e1b1ed13ae2900913 100644 --- a/std/dynamic_library.zig +++ b/std/dynamic_library.zig @@ -105,8 +105,8 @@ pub const LinuxDynLib = struct { /// Trusts the file pub fn open(path: []const u8) !DynLib { - const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC); - errdefer std.os.close(fd); + const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC); + errdefer os.close(fd); const size = @intCast(usize, (try os.fstat(fd)).size); @@ -247,18 +247,10 @@ pub const WindowsDynLib = struct { dll: windows.HMODULE, pub fn open(path: []const u8) !WindowsDynLib { - const wpath = try win_util.sliceToPrefixedFileW(path); + const wpath = try windows.sliceToPrefixedFileW(path); return WindowsDynLib{ - .dll = windows.LoadLibraryW(&wpath) orelse { - const err = windows.GetLastError(); - switch (err) { - windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound, - windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound, - windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound, - else => return os.unexpectedErrorWindows(err), - } - }, + .dll = try windows.LoadLibraryW(&wpath), }; } -- 2.54.0 From 594366a4824d7e65485033ca1002d8635ff6fbf9 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 28 May 2019 18:25:48 +0200 Subject: [PATCH 24/84] Fix os.mprotect signature --- std/os.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/os.zig b/std/os.zig index be2be92f7d7fc3bd7ef4faf29c630ff9489a1991..14f205c1aa5d90937c7e726c94f4097fbd43f9b8 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1889,14 +1889,14 @@ pub const MProtectError = error{ }; /// `memory.len` must be page-aligned. -pub fn mprotect(memory: [*]align(mem.page_size) u8, protection: u32) MProtectError!void { +pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void { assert(mem.isAligned(memory.len, mem.page_size)); switch (errno(system.mprotect(memory.ptr, memory.len, protection))) { 0 => return, EINVAL => unreachable, EACCES => return error.AccessDenied, ENOMEM => return error.OutOfMemory, - else => return unexpectedErrno(err), + else => |err| return unexpectedErrno(err), } } -- 2.54.0 From 381f845287c8aef25a5351be81dfdfad055f0785 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 28 May 2019 18:26:38 +0200 Subject: [PATCH 25/84] Add a guard page for each thread --- std/thread.zig | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/std/thread.zig b/std/thread.zig index 49b2decb09c8206daa1a614235bde7ccc0d56e4f..afed605b39102e77daf2a4aec6f13c735a6f4ec7 100644 --- a/std/thread.zig +++ b/std/thread.zig @@ -223,15 +223,17 @@ pub const Thread = struct { } }; - const MAP_GROWSDOWN = if (os.linux.is_the_target) os.linux.MAP_GROWSDOWN else 0; - + var guard_end_offset: usize = undefined; var stack_end_offset: usize = undefined; var thread_start_offset: usize = undefined; var context_start_offset: usize = undefined; var tls_start_offset: usize = undefined; const mmap_len = blk: { - // First in memory will be the stack, which grows downwards. - var l: usize = mem.alignForward(default_stack_size, mem.page_size); + var l: usize = mem.page_size; + // Allocate a guard page right after the end of the stack region + guard_end_offset = l; + // The stack itself, which grows downwards. + l = mem.alignForward(l + default_stack_size, mem.page_size); stack_end_offset = l; // Above the stack, so that it can be in the same mmap call, put the Thread object. l = mem.alignForward(l, @alignOf(Thread)); @@ -253,20 +255,33 @@ pub const Thread = struct { } break :blk l; }; + // Map the whole stack with no rw permissions to avoid committing the + // whole region right away const mmap_slice = os.mmap( null, mem.alignForward(mmap_len, mem.page_size), - os.PROT_READ | os.PROT_WRITE, - os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN, + os.PROT_NONE, + os.MAP_PRIVATE | os.MAP_ANONYMOUS, -1, 0, ) catch |err| switch (err) { - error.MemoryMappingNotSupported => unreachable, // no file descriptor - error.AccessDenied => unreachable, // no file descriptor - error.PermissionDenied => unreachable, // no file descriptor + error.MemoryMappingNotSupported => unreachable, + error.AccessDenied => unreachable, + error.PermissionDenied => unreachable, else => |e| return e, }; errdefer os.munmap(mmap_slice); + + // Map everything but the guard page as rw + os.mprotect( + mmap_slice, + os.PROT_READ | os.PROT_WRITE, + ) catch |err| switch (err) { + error.OutOfMemory => unreachable, + error.AccessDenied => unreachable, + else => |e| return e, + }; + const mmap_addr = @ptrToInt(mmap_slice.ptr); const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset)); -- 2.54.0 From c518b7b8bf71ad77adc96b5c9dabea277fe3ee43 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 12:46:44 -0400 Subject: [PATCH 26/84] thread.spawn: bubble up mprotect error.OutOfMemory --- std/os.zig | 9 +++++++++ std/thread.zig | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/std/os.zig b/std/os.zig index 14f205c1aa5d90937c7e726c94f4097fbd43f9b8..6f1f0135ce9301824dbac688f2a525840f02cdc7 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1883,7 +1883,16 @@ pub fn inotify_rm_watch(inotify_fd: i32, wd: i32) void { } pub const MProtectError = error{ + /// The memory cannot be given the specified access. This can happen, for example, if you + /// mmap(2) a file to which you have read-only access, then ask mprotect() to mark it + /// PROT_WRITE. AccessDenied, + + /// Changing the protection of a memory region would result in the total number of map‐ + /// pings with distinct attributes (e.g., read versus read/write protection) exceeding the + /// allowed maximum. (For example, making the protection of a range PROT_READ in the mid‐ + /// dle of a region currently protected as PROT_READ|PROT_WRITE would result in three map‐ + /// pings: two read/write mappings at each end and a read-only mapping in the middle.) OutOfMemory, Unexpected, }; diff --git a/std/thread.zig b/std/thread.zig index afed605b39102e77daf2a4aec6f13c735a6f4ec7..abf2f1cae1304b6e98466c519201ed4a997ae4c2 100644 --- a/std/thread.zig +++ b/std/thread.zig @@ -277,7 +277,6 @@ pub const Thread = struct { mmap_slice, os.PROT_READ | os.PROT_WRITE, ) catch |err| switch (err) { - error.OutOfMemory => unreachable, error.AccessDenied => unreachable, else => |e| return e, }; -- 2.54.0 From e2c22634343691a76ee7815806c25ee8bc976a42 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 14 May 2019 11:12:54 +0200 Subject: [PATCH 27/84] Move __zig_fail_unwrap locals on stack --- src/codegen.cpp | 105 +++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 54e9c44f92dfe182dcef5e089e6aa0eaefcd7dd5..c5fd875987f3ff80ed57a166b5bedbefff3ceb7a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -296,6 +296,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c static void generate_error_name_table(CodeGen *g); static bool value_is_all_undef(ConstExprValue *const_val); static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); +static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); @@ -1518,53 +1519,12 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { generate_error_name_table(g); assert(g->err_name_table != nullptr); - size_t unwrap_err_msg_text_len = strlen(unwrap_err_msg_text); - size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len; - LLVMValueRef *err_buf_vals = allocate(err_buf_len); - size_t i = 0; - for (; i < unwrap_err_msg_text_len; i += 1) { - err_buf_vals[i] = LLVMConstInt(LLVMInt8Type(), unwrap_err_msg_text[i], false); - } - for (; i < err_buf_len; i += 1) { - err_buf_vals[i] = LLVMGetUndef(LLVMInt8Type()); - } - uint32_t u8_align_bytes = get_abi_alignment(g, g->builtin_types.entry_u8); - LLVMValueRef init_value = LLVMConstArray(LLVMInt8Type(), err_buf_vals, err_buf_len); - LLVMValueRef global_array = LLVMAddGlobal(g->module, LLVMTypeOf(init_value), ""); - LLVMSetInitializer(global_array, init_value); - LLVMSetLinkage(global_array, LLVMInternalLinkage); - LLVMSetGlobalConstant(global_array, false); - LLVMSetUnnamedAddr(global_array, true); - LLVMSetAlignment(global_array, u8_align_bytes); - - ZigType *usize = g->builtin_types.entry_usize; - LLVMValueRef full_buf_ptr_indices[] = { - LLVMConstNull(usize->llvm_type), - LLVMConstNull(usize->llvm_type), - }; - LLVMValueRef full_buf_ptr = LLVMConstInBoundsGEP(global_array, full_buf_ptr_indices, 2); - - - ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, - PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); - ZigType *str_type = get_slice_type(g, u8_ptr_type); - LLVMValueRef global_slice_fields[] = { - full_buf_ptr, - LLVMConstNull(usize->llvm_type), - }; - LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, str_type), global_slice_fields, 2); - LLVMValueRef global_slice = LLVMAddGlobal(g->module, LLVMTypeOf(slice_init_value), ""); - LLVMSetInitializer(global_slice, slice_init_value); - LLVMSetLinkage(global_slice, LLVMInternalLinkage); - LLVMSetGlobalConstant(global_slice, false); - LLVMSetUnnamedAddr(global_slice, true); - LLVMSetAlignment(global_slice, get_abi_alignment(g, str_type)); - - LLVMValueRef offset_ptr_indices[] = { - LLVMConstNull(usize->llvm_type), - LLVMConstInt(usize->llvm_type, unwrap_err_msg_text_len, false), - }; - LLVMValueRef offset_buf_ptr = LLVMConstInBoundsGEP(global_array, offset_ptr_indices, 2); + // Generate the constant part of the error message + LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1); + LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), ""); + LLVMSetInitializer(msg_prefix, msg_prefix_init); + LLVMSetLinkage(msg_prefix, LLVMInternalLinkage); + LLVMSetGlobalConstant(msg_prefix, true); Buf *fn_name = get_mangled_name(g, buf_create_from_str("__zig_fail_unwrap"), false); LLVMTypeRef fn_type_ref; @@ -1601,6 +1561,19 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMPositionBuilderAtEnd(g->builder, entry_block); ZigLLVMClearCurrentDebugLocation(g->builder); + ZigType *usize_ty = g->builtin_types.entry_usize; + ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, + PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); + ZigType *str_type = get_slice_type(g, u8_ptr_type); + + // Allocate a buffer to hold the fully-formatted error message + const size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len; + LLVMValueRef max_msg_len = LLVMConstInt(usize_ty->llvm_type, err_buf_len, 0); + LLVMValueRef msg_buffer = LLVMBuildArrayAlloca(g->builder, LLVMInt8Type(), max_msg_len, "msg_buffer"); + + // Allocate a []u8 slice for the message + LLVMValueRef msg_slice = build_alloca(g, str_type, "msg_slice", 0); + LLVMValueRef err_ret_trace_arg; LLVMValueRef err_val; if (g->have_err_ret_tracing) { @@ -1611,8 +1584,9 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { err_val = LLVMGetParam(fn_val, 0); } + // Fetch the error name from the global table LLVMValueRef err_table_indices[] = { - LLVMConstNull(g->builtin_types.entry_usize->llvm_type), + LLVMConstNull(usize_ty->llvm_type), err_val, }; LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, ""); @@ -1623,15 +1597,38 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, ""); LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, ""); - ZigLLVMBuildMemCpy(g->builder, offset_buf_ptr, u8_align_bytes, err_name_ptr, u8_align_bytes, err_name_len, false); + LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false); + // Points to the beginning of msg_buffer + LLVMValueRef msg_buffer_ptr_indices[] = { + LLVMConstNull(usize_ty->llvm_type), + }; + LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, ""); + // Points to the beginning of the constant prefix message + LLVMValueRef msg_prefix_ptr_indices[] = { + LLVMConstNull(usize_ty->llvm_type), + }; + LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1); - LLVMValueRef const_prefix_len = LLVMConstInt(LLVMTypeOf(err_name_len), strlen(unwrap_err_msg_text), false); - LLVMValueRef full_buf_len = LLVMBuildNUWAdd(g->builder, const_prefix_len, err_name_len, ""); + // Build the message using the prefix... + ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false); + // ..and append the error name + LLVMValueRef msg_buffer_ptr_after_indices[] = { + msg_prefix_len, + }; + LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, ""); + ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false); - LLVMValueRef global_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, global_slice, slice_len_index, ""); - gen_store(g, full_buf_len, global_slice_len_field_ptr, u8_ptr_type); + // Set the slice pointer + LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, ""); + gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false); - gen_panic(g, global_slice, err_ret_trace_arg); + // Set the slice length + LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, ""); + LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, ""); + gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false); + + // Call panic() + gen_panic(g, msg_slice, err_ret_trace_arg); LLVMPositionBuilderAtEnd(g->builder, prev_block); LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); -- 2.54.0 From 8a65478801f8d41d3e62826e99ec23163051a9f0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 14:36:03 -0400 Subject: [PATCH 28/84] Create FUNDING.yml --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000000000000000000000000000000000..86b8f6f471cc17705c24c38bf3e4d4cc13e14062 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: [andrewrk] +patreon: andrewrk -- 2.54.0 From a37ea5acf3d98824c64c2859ed72d6203c4de4bb Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 14:50:02 -0400 Subject: [PATCH 29/84] extract CONTRIBUTING.md from README.md --- CONTRIBUTING.md | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 92 ------------------------------------------------- 2 files changed, 91 insertions(+), 92 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..c19ef4882966d299faa73a8984ed90a3c9369d5f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,91 @@ +## Contributing + +### Start a Project Using Zig + +One of the best ways you can contribute to Zig is to start using it for a +personal project. Here are some great examples: + + * [Oxid](https://github.com/dbandstra/oxid) - arcade style game + * [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games + * [trOS](https://github.com/sjdh02/trOS) - tiny aarch64 baremetal OS thingy + +Without fail, these projects lead to discovering bugs and helping flesh out use +cases, which lead to further design iterations of Zig. Importantly, each issue +found this way comes with real world motivations, so it is easy to explain +your reasoning behind proposals and feature requests. + +Ideally, such a project will help you to learn new skills and add something +to your personal portfolio at the same time. + +### Spread the Word + +Another way to contribute is to write about Zig, or speak about Zig at a +conference, or do either of those things for your project which uses Zig. +Here are some examples: + + * [Iterative Replacement of C with Zig](http://tiehuis.github.io/blog/zig1.html) + * [The Right Tool for the Right Job: Redis Modules & Zig](https://www.youtube.com/watch?v=eCHM8-_poZY) + +Zig is a brand new language, with no advertising budget. Word of mouth is the +only way people find out about the project, and the more people hear about it, +the more people will use it, and the better chance we have to take over the +world. + +### Finding Contributor Friendly Issues + +Please note that issues labeled +[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal) +but do not also have the +[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted) +label are still under consideration, and efforts to implement such a proposal +have a high risk of being wasted. If you are interested in a proposal which is +still under consideration, please express your interest in the issue tracker, +providing extra insights and considerations that others have not yet expressed. +The most highly regarded argument in such a discussion is a real world use case. + +The issue label +[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22) +exists to help contributors find issues that are "limited in scope and/or +knowledge of Zig internals." + +### Editing Source Code + +First, build the Stage 1 compiler as described in [the Building section](#building). + +When making changes to the standard library, be sure to edit the files in the +`std` directory and not the installed copy in the build directory. If you add a +new file to the standard library, you must also add the file path in +CMakeLists.txt. + +To test changes, do the following from the build directory: + +1. Run `make install` (on POSIX) or + `msbuild -p:Configuration=Release INSTALL.vcxproj` (on Windows). +2. `bin/zig build --build-file ../build.zig test` (on POSIX) or + `bin\zig.exe build --build-file ..\build.zig test` (on Windows). + +That runs the whole test suite, which does a lot of extra testing that you +likely won't always need, and can take upwards of 2 hours. This is what the +CI server runs when you make a pull request. + +To save time, you can add the `--help` option to the `zig build` command and +see what options are available. One of the most helpful ones is +`-Dskip-release`. Adding this option to the command in step 2 above will take +the time down from around 2 hours to about 6 minutes, and this is a good +enough amount of testing before making a pull request. + +Another example is choosing a different set of things to test. For example, +`test-std` instead of `test` will only run the standard library tests, and +not the other ones. Combining this suggestion with the previous one, you could +do this: + +`bin/zig build --build-file ../build.zig test-std -Dskip-release` (on POSIX) or +`bin\zig.exe build --build-file ..\build.zig test-std -Dskip-release` (on Windows). + +This will run only the standard library tests, in debug mode only, for all +targets (it will cross-compile the tests for non-native targets but not run +them). + +When making changes to the compiler source code, the most helpful test step to +run is `test-behavior`. When editing documentation it is `docs`. You can find +this information and more in the `--help` menu. diff --git a/README.md b/README.md index 4ca79232d835925b1cb911726daf38682575769a..fa03b818f12aff9eedae75772ca6e33b7388d8b7 100644 --- a/README.md +++ b/README.md @@ -96,95 +96,3 @@ use stage 1. ``` ./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast ``` - -## Contributing - -### Start a Project Using Zig - -One of the best ways you can contribute to Zig is to start using it for a -personal project. Here are some great examples: - - * [Oxid](https://github.com/dbandstra/oxid) - arcade style game - * [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games - * [trOS](https://github.com/sjdh02/trOS) - tiny aarch64 baremetal OS thingy - -Without fail, these projects lead to discovering bugs and helping flesh out use -cases, which lead to further design iterations of Zig. Importantly, each issue -found this way comes with real world motivations, so it is easy to explain -your reasoning behind proposals and feature requests. - -Ideally, such a project will help you to learn new skills and add something -to your personal portfolio at the same time. - -### Spread the Word - -Another way to contribute is to write about Zig, or speak about Zig at a -conference, or do either of those things for your project which uses Zig. -Here are some examples: - - * [Iterative Replacement of C with Zig](http://tiehuis.github.io/blog/zig1.html) - * [The Right Tool for the Right Job: Redis Modules & Zig](https://www.youtube.com/watch?v=eCHM8-_poZY) - -Zig is a brand new language, with no advertising budget. Word of mouth is the -only way people find out about the project, and the more people hear about it, -the more people will use it, and the better chance we have to take over the -world. - -### Finding Contributor Friendly Issues - -Please note that issues labeled -[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal) -but do not also have the -[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted) -label are still under consideration, and efforts to implement such a proposal -have a high risk of being wasted. If you are interested in a proposal which is -still under consideration, please express your interest in the issue tracker, -providing extra insights and considerations that others have not yet expressed. -The most highly regarded argument in such a discussion is a real world use case. - -The issue label -[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22) -exists to help contributors find issues that are "limited in scope and/or -knowledge of Zig internals." - -### Editing Source Code - -First, build the Stage 1 compiler as described in [the Building section](#building). - -When making changes to the standard library, be sure to edit the files in the -`std` directory and not the installed copy in the build directory. If you add a -new file to the standard library, you must also add the file path in -CMakeLists.txt. - -To test changes, do the following from the build directory: - -1. Run `make install` (on POSIX) or - `msbuild -p:Configuration=Release INSTALL.vcxproj` (on Windows). -2. `bin/zig build --build-file ../build.zig test` (on POSIX) or - `bin\zig.exe build --build-file ..\build.zig test` (on Windows). - -That runs the whole test suite, which does a lot of extra testing that you -likely won't always need, and can take upwards of 2 hours. This is what the -CI server runs when you make a pull request. - -To save time, you can add the `--help` option to the `zig build` command and -see what options are available. One of the most helpful ones is -`-Dskip-release`. Adding this option to the command in step 2 above will take -the time down from around 2 hours to about 6 minutes, and this is a good -enough amount of testing before making a pull request. - -Another example is choosing a different set of things to test. For example, -`test-std` instead of `test` will only run the standard library tests, and -not the other ones. Combining this suggestion with the previous one, you could -do this: - -`bin/zig build --build-file ../build.zig test-std -Dskip-release` (on POSIX) or -`bin\zig.exe build --build-file ..\build.zig test-std -Dskip-release` (on Windows). - -This will run only the standard library tests, in debug mode only, for all -targets (it will cross-compile the tests for non-native targets but not run -them). - -When making changes to the compiler source code, the most helpful test step to -run is `test-behavior`. When editing documentation it is `docs`. You can find -this information and more in the `--help` menu. -- 2.54.0 From 508fdfea7227bf8c201134bf0b8c2b9c1c3ff787 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 14:53:01 -0400 Subject: [PATCH 30/84] link to contributing in readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fa03b818f12aff9eedae75772ca6e33b7388d8b7..92ad435f5be9db222d05514ad261e44e3364b015 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Zig is an open-source programming language designed for **robustness**, * [Introduction](https://ziglang.org/#Introduction) * [Download & Documentation](https://ziglang.org/download) * [Community](https://github.com/ziglang/zig/wiki/Community) + * [Contributing](https://github.com/ziglang/zig/blob/master/CONTRIBUTING.md) ## Building from Source -- 2.54.0 From 9d16839420c674fd7dff0b28b3efcc9a7953ed74 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 16:11:09 -0400 Subject: [PATCH 31/84] fix invalid LLVM IR generated for ?*void const casts closes #2578 --- src/codegen.cpp | 2 +- test/stage1/behavior.zig | 1 + test/stage1/behavior/bugs/2578.zig | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/stage1/behavior/bugs/2578.zig diff --git a/src/codegen.cpp b/src/codegen.cpp index c5fd875987f3ff80ed57a166b5bedbefff3ceb7a..e00ec12615556ad7d3d135ee2d5b85397b5aba00 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2002,7 +2002,7 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { render_const_val_global(g, &instruction->value, ""); ZigType *ptr_type = get_pointer_to_type(g, instruction->value.type, true); instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, get_llvm_type(g, ptr_type), ""); - } else if (instruction->value.type->id == ZigTypeIdPointer) { + } else if (get_codegen_ptr_type(instruction->value.type) != nullptr) { instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, get_llvm_type(g, instruction->value.type), ""); } else { diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index e9ff84c03586dd18db939e5f6e491ce90f638cbf..f477bb64edc7dc2fe9622cf4b730121ba261b284 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -26,6 +26,7 @@ comptime { _ = @import("behavior/bugs/2006.zig"); _ = @import("behavior/bugs/2114.zig"); _ = @import("behavior/bugs/2346.zig"); + _ = @import("behavior/bugs/2578.zig"); _ = @import("behavior/bugs/394.zig"); _ = @import("behavior/bugs/421.zig"); _ = @import("behavior/bugs/529.zig"); diff --git a/test/stage1/behavior/bugs/2578.zig b/test/stage1/behavior/bugs/2578.zig new file mode 100644 index 0000000000000000000000000000000000000000..cf7d941562ae6901a7cf1a840de2f598014c4be6 --- /dev/null +++ b/test/stage1/behavior/bugs/2578.zig @@ -0,0 +1,12 @@ +const Foo = struct { + y: u8, +}; + +var foo: Foo = undefined; +const t = &foo; + +fn bar(pointer: ?*c_void) void {} + +test "fixed" { + bar(t); +} -- 2.54.0 From 048169cbea759b3ebf3cf79145a972907b41dc80 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 21 May 2019 15:50:42 +0200 Subject: [PATCH 32/84] Avoid a crash when there are no namespace components Fixes #2500 --- src/analyze.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 0c629d67522d5274b3231e1039ad3a82a11aafd1..4f58fd07f65881f0afcea7255c1ff557719884dd 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3892,10 +3892,17 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu buf_init_from_buf(&namespace_name, &package->pkg_path); if (source_kind == SourceKindNonRoot) { assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir)); - - if (buf_len(&namespace_name) != 0) buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR); - buf_append_mem(&namespace_name, buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1, - buf_len(&noextname) - (buf_len(&resolved_root_src_dir) + 1)); + if (buf_len(&namespace_name) != 0) { + buf_append_char(&namespace_name, NAMESPACE_SEP_CHAR); + } + // The namespace components are obtained from the relative path to the + // source directory + if (buf_len(&noextname) > buf_len(&resolved_root_src_dir)) { + // Skip the trailing separator + buf_append_mem(&namespace_name, + buf_ptr(&noextname) + buf_len(&resolved_root_src_dir) + 1, + buf_len(&noextname) - buf_len(&resolved_root_src_dir) - 1); + } buf_replace(&namespace_name, ZIG_OS_SEP_CHAR, NAMESPACE_SEP_CHAR); } Buf *bare_name = buf_alloc(); -- 2.54.0 From a169d844c70a8e2a6e29be639b4d0a1c26df0662 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 22 May 2019 22:14:53 +0200 Subject: [PATCH 33/84] Warn the user if run/test is paired with emit options --- src/main.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index cbfd9468996fc6581d2bd148dd32391f38c0714e..4ebd93563fd2568f9309518d9c03cb96dfd41198 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -985,6 +985,9 @@ int main(int argc, char **argv) { { fprintf(stderr, "Expected source file argument.\n"); return print_error_usage(arg0); + } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) { + fprintf(stderr, "Cannot run non-executable file.\n"); + return print_error_usage(arg0); } assert(cmd != CmdBuild || out_type != OutTypeUnknown); @@ -1189,6 +1192,12 @@ int main(int argc, char **argv) { Buf *test_exe_path = buf_alloc(); *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1); + if (emit_file_type != EmitFileTypeBinary) { + fprintf(stderr, "Created %s but skipping execution because it is non executable.\n", + buf_ptr(test_exe_path)); + return 0; + } + for (size_t i = 0; i < test_exec_args.length; i += 1) { if (test_exec_args.items[i] == nullptr) { test_exec_args.items[i] = buf_ptr(test_exe_path); -- 2.54.0 From 528c151a55a76451b278057c40b29242241a70fd Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Mon, 27 May 2019 17:39:56 +0200 Subject: [PATCH 34/84] Reject undefined as type Make analyze_type_expr behave like ir_resolve_type when the user tries to use `undefined` as a type. Closes #2436 --- src/analyze.cpp | 11 +++++++++++ test/compile_errors.zig | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/analyze.cpp b/src/analyze.cpp index 4f58fd07f65881f0afcea7255c1ff557719884dd..a1b1c56670b2a0f8ccc03fc403e106822940f19c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -981,6 +981,17 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { return g->builtin_types.entry_invalid; assert(result->special != ConstValSpecialRuntime); + // Reject undefined as valid `type` type even though the specification + // allows it to be casted to anything. + // See also ir_resolve_type() + if (result->special == ConstValSpecialUndef) { + add_node_error(g, node, + buf_sprintf("expected type 'type', found '%s'", + buf_ptr(&g->builtin_types.entry_undef->name))); + return g->builtin_types.entry_invalid; + } + + assert(result->data.x_type != nullptr); return result->data.x_type; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index d151b31343cf6923e17ed452fbe9327c19ec3d11..0d28ac493230bde1035d2d87b75208ab678dbc7e 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,23 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "undefined as field type is rejected", + \\const Foo = struct { + \\ a: undefined, + \\}; + \\const Bar = union { + \\ a: undefined, + \\}; + \\pub fn main() void { + \\ const foo: Foo = undefined; + \\ const bar: Bar = undefined; + \\} + , + "tmp.zig:2:8: error: expected type 'type', found '(undefined)'", + "tmp.zig:5:8: error: expected type 'type', found '(undefined)'", + ); + cases.add( "@hasDecl with non-container", \\export fn entry() void { -- 2.54.0 From b66438eb8092ea93b255f0ba11f857b1d6ccb052 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 28 May 2019 18:18:52 -0400 Subject: [PATCH 35/84] no "use of undeclared identifer" in dead comptime branches --- src/all_types.hpp | 7 +++++ src/codegen.cpp | 1 + src/ir.cpp | 51 ++++++++++++++++++++++++++--------- src/ir_print.cpp | 7 +++++ std/os/bits/windows.zig | 7 ----- test/compile_errors.zig | 7 +++-- test/stage1/behavior/eval.zig | 18 +++++++++---- 7 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index a0b4fadedcb217d353f04879ca43c9bb8e18f4eb..91676d0c39b2ff87059d2fe2d7f3ae1e60170380 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2306,6 +2306,7 @@ enum IrInstructionId { IrInstructionIdAssertZero, IrInstructionIdAssertNonNull, IrInstructionIdHasDecl, + IrInstructionIdUndeclaredIdent, }; struct IrInstruction { @@ -3519,6 +3520,12 @@ struct IrInstructionHasDecl { IrInstruction *name; }; +struct IrInstructionUndeclaredIdent { + IrInstruction base; + + Buf *name; +}; + static const size_t slice_ptr_index = 0; static const size_t slice_len_index = 1; diff --git a/src/codegen.cpp b/src/codegen.cpp index e00ec12615556ad7d3d135ee2d5b85397b5aba00..7d9e03baf4e516047d61c6761269b06c9d5c9b57 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5606,6 +5606,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdBitCast: case IrInstructionIdGlobalAsm: case IrInstructionIdHasDecl: + case IrInstructionIdUndeclaredIdent: zig_unreachable(); case IrInstructionIdDeclVarGen: diff --git a/src/ir.cpp b/src/ir.cpp index 42b1acc4df35c071c347103b128b085ab955c360..5d3cf5303c8fd78bfa2f5d8e0f93f5428c00b10f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1015,6 +1015,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { return IrInstructionIdHasDecl; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionUndeclaredIdent *) { + return IrInstructionIdUndeclaredIdent; +} + template static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { T *special_instruction = allocate(1); @@ -3031,6 +3035,15 @@ static IrInstruction *ir_build_has_decl(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } +static IrInstruction *ir_build_undeclared_identifier(IrBuilder *irb, Scope *scope, AstNode *source_node, + Buf *name) +{ + IrInstructionUndeclaredIdent *instruction = ir_build_instruction(irb, scope, source_node); + instruction->name = name; + + return &instruction->base; +} + static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { IrInstructionCheckRuntimeScope *instruction = ir_build_instruction(irb, scope, source_node); instruction->scope_is_comptime = scope_is_comptime; @@ -3896,13 +3909,18 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, Buf *variable_name = node->data.symbol_expr.symbol; - if (buf_eql_str(variable_name, "_") && lval == LValPtr) { - IrInstructionConst *const_instruction = ir_build_instruction(irb, scope, node); - const_instruction->base.value.type = get_pointer_to_type(irb->codegen, - irb->codegen->builtin_types.entry_void, false); - const_instruction->base.value.special = ConstValSpecialStatic; - const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; - return &const_instruction->base; + if (buf_eql_str(variable_name, "_")) { + if (lval == LValPtr) { + IrInstructionConst *const_instruction = ir_build_instruction(irb, scope, node); + const_instruction->base.value.type = get_pointer_to_type(irb->codegen, + irb->codegen->builtin_types.entry_void, false); + const_instruction->base.value.special = ConstValSpecialStatic; + const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; + return &const_instruction->base; + } else { + add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); + return irb->codegen->invalid_instruction; + } } ZigType *primitive_type; @@ -3943,11 +3961,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, return irb->codegen->invalid_instruction; } - // put a variable of same name with invalid type in global scope - // so that future references to this same name will find a variable with an invalid type - populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name); - add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); - return irb->codegen->invalid_instruction; + return ir_build_undeclared_identifier(irb, scope, node, variable_name); } static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { @@ -23237,6 +23251,16 @@ static IrInstruction *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstruct return ir_const_bool(ira, &instruction->base, true); } +static IrInstruction *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstructionUndeclaredIdent *instruction) { + // put a variable of same name with invalid type in global scope + // so that future references to this same name will find a variable with an invalid type + populate_invalid_variable_in_scope(ira->codegen, instruction->base.scope, instruction->base.source_node, + instruction->name); + ir_add_error(ira, &instruction->base, + buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); + return ira->codegen->invalid_instruction; +} + static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: @@ -23533,6 +23557,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); case IrInstructionIdHasDecl: return ir_analyze_instruction_has_decl(ira, (IrInstructionHasDecl *)instruction); + case IrInstructionIdUndeclaredIdent: + return ir_analyze_instruction_undeclared_ident(ira, (IrInstructionUndeclaredIdent *)instruction); } zig_unreachable(); } @@ -23667,6 +23693,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdAssertNonNull: case IrInstructionIdResizeSlice: case IrInstructionIdGlobalAsm: + case IrInstructionIdUndeclaredIdent: return true; case IrInstructionIdPhi: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index dd671231c0269495acf8552c854cca2454ee3c4d..bf9ced89c5eee36a513003366813c68f71495b4e 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1461,6 +1461,10 @@ static void ir_print_has_decl(IrPrint *irp, IrInstructionHasDecl *instruction) { fprintf(irp->f, ")"); } +static void ir_print_undeclared_ident(IrPrint *irp, IrInstructionUndeclaredIdent *instruction) { + fprintf(irp->f, "@undeclaredIdent(%s)", buf_ptr(instruction->name)); +} + static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { ir_print_prefix(irp, instruction); switch (instruction->id) { @@ -1931,6 +1935,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdHasDecl: ir_print_has_decl(irp, (IrInstructionHasDecl *)instruction); break; + case IrInstructionIdUndeclaredIdent: + ir_print_undeclared_ident(irp, (IrInstructionUndeclaredIdent *)instruction); + break; } fprintf(irp->f, "\n"); } diff --git a/std/os/bits/windows.zig b/std/os/bits/windows.zig index a242113ba0153163fa74e9db4e639477aee0c3b7..4959249a9a76673c37700bdf99cffe2b5a9c8f4d 100644 --- a/std/os/bits/windows.zig +++ b/std/os/bits/windows.zig @@ -158,10 +158,3 @@ pub const EWOULDBLOCK = 140; pub const EDQUOT = 10069; pub const F_OK = 0; - -// These are workarounds for "use of undeclared identifier" compile errors -// TODO make the compiler even more lazy. don't emit "use of undeclared identifier" errors -// for if branches that aren't taken. -pub const SIGKILL = @compileError("Windows libc does not have this"); - - diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 0d28ac493230bde1035d2d87b75208ab678dbc7e..7da5247d89baad672f727194f10207b421332fd9 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1219,7 +1219,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\} , "tmp.zig:2:5: error: `_` is not a declarable symbol", - "tmp.zig:3:12: error: use of undeclared identifier '_'", ); cases.add( @@ -1232,7 +1231,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ } \\} , - "tmp.zig:4:20: error: use of undeclared identifier '_'", + "tmp.zig:4:20: error: `_` may only be used to assign things to", ); cases.add( @@ -1248,7 +1247,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return 1; \\} , - "tmp.zig:4:20: error: use of undeclared identifier '_'", + "tmp.zig:4:20: error: `_` may only be used to assign things to", ); cases.add( @@ -1266,7 +1265,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ return error.optionalReturnError; \\} , - "tmp.zig:6:17: error: use of undeclared identifier '_'", + "tmp.zig:6:17: error: `_` may only be used to assign things to", ); cases.add( diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig index 6d5ede418ebe7450e582a9295c96474df983090b..6d581c1128d115e51613ec0d53c8c70c86cfafe0 100644 --- a/test/stage1/behavior/eval.zig +++ b/test/stage1/behavior/eval.zig @@ -93,11 +93,13 @@ pub const Vec3 = struct { data: [3]f32, }; pub fn vec3(x: f32, y: f32, z: f32) Vec3 { - return Vec3{ .data = []f32{ - x, - y, - z, - } }; + return Vec3{ + .data = []f32{ + x, + y, + z, + }, + }; } test "constant expressions" { @@ -776,3 +778,9 @@ fn oneItem(x: i32) [1]i32 { fn scalar(x: u32) u32 { return x; } + +test "no undeclared identifier error in unanalyzed branches" { + if (false) { + lol_this_doesnt_exist = nonsense; + } +} -- 2.54.0 From 2975bdc684b74b013dc4d45c39535b872ac46a0a Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Wed, 29 May 2019 14:39:13 -0400 Subject: [PATCH 36/84] add review changes - use std.heap.c_allocator - use @panic instead of unreachable - use extern enum for tokenizer result type --- src-self-hosted/dep_tokenizer.zig | 41 +++++++++++++++++++------------ src/cache_hash.cpp | 4 +-- src/userland.h | 4 +-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src-self-hosted/dep_tokenizer.zig b/src-self-hosted/dep_tokenizer.zig index c0a31c16492c76ce27eb407b2178755bdbcbe21a..9ce965fff765df002ec773a205f68d8345dee989 100644 --- a/src-self-hosted/dep_tokenizer.zig +++ b/src-self-hosted/dep_tokenizer.zig @@ -359,12 +359,9 @@ pub const Tokenizer = struct { }; }; -// stage1 compiler support -var stage2_da = std.heap.DirectAllocator.init(); - export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { - const t = stage2_da.allocator.create(Tokenizer) catch unreachable; - t.* = Tokenizer.init(&stage2_da.allocator, input[0..len]); + const t = std.heap.c_allocator.create(Tokenizer) catch @panic("failed to create .d tokenizer"); + t.* = Tokenizer.init(std.heap.c_allocator, input[0..len]); return stage2_DepTokenizer{ .handle = t, }; @@ -376,20 +373,25 @@ export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { const otoken = self.handle.next() catch { + const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); return stage2_DepNextResult{ - .ent = 0, - .textz = (std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch unreachable).toSlice().ptr, + .type_id = .error_, + .textz = textz.toSlice().ptr, }; }; const token = otoken orelse { return stage2_DepNextResult{ - .ent = 1, + .type_id = .null_, .textz = undefined, }; }; + const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); return stage2_DepNextResult{ - .ent = @enumToInt(token.id) + u8(2), - .textz = (std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch unreachable).toSlice().ptr, + .type_id = switch (token.id) { + .target => stage2_DepNextResult.TypeId.target, + .prereq => stage2_DepNextResult.TypeId.prereq, + }, + .textz = textz.toSlice().ptr, }; } @@ -398,13 +400,20 @@ export const stage2_DepTokenizer = extern struct { }; export const stage2_DepNextResult = extern struct { - // 0=error, 1=null, 2=token=target, 3=token=prereq - ent: u8, - // ent=0 -- error text - // ent=1 -- NEVER - // ent=2 -- token text value - // ent=3 -- token text value + type_id: TypeId, + + // when type_id == error --> error text + // when type_id == null --> undefined + // when type_id == target --> target pathname + // when type_id == prereq --> prereq pathname textz: [*]const u8, + + export const TypeId = extern enum { + error_, + null_, + target, + prereq, + }; }; test "empty file" { diff --git a/src/cache_hash.cpp b/src/cache_hash.cpp index 381a29a2f173554800d8de9fb0e72789dc0d80cc..714b9b4c1861b2645e53adeabf5c686f20cdac8e 100644 --- a/src/cache_hash.cpp +++ b/src/cache_hash.cpp @@ -482,7 +482,7 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) { // skip first token: target { auto result = stage2_DepTokenizer_next(&it); - switch (result.ent) { + switch (result.type_id) { case stage2_DepNextResult::error: if (verbose) { fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); @@ -502,7 +502,7 @@ Error cache_add_dep_file(CacheHash *ch, Buf *dep_file_path, bool verbose) { // clang is invoked in single-source mode so we never get more targets. for (;;) { auto result = stage2_DepTokenizer_next(&it); - switch (result.ent) { + switch (result.type_id) { case stage2_DepNextResult::error: if (verbose) { fprintf(stderr, "%s: failed processing .d file: %s\n", result.textz, buf_ptr(dep_file_path)); diff --git a/src/userland.h b/src/userland.h index 488113d6b68e85b68e233738dcbc0b5dda601d66..eac28053e6fb38c69e6c1940e605b39c678a2555 100644 --- a/src/userland.h +++ b/src/userland.h @@ -126,14 +126,14 @@ struct stage2_DepTokenizer { // ABI warning struct stage2_DepNextResult { - enum Ent : uint8_t { + enum TypeId { error, null, target, prereq, }; - Ent ent; + TypeId type_id; // when ent == error --> error text // when ent == null --> undefined -- 2.54.0 From 1ccbd1fb67898c0691c74e65a7b9786fb5698619 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 16:31:49 -0400 Subject: [PATCH 37/84] `use` works on unions and enums in addition to structs --- src/analyze.cpp | 23 ++++++++++++----------- src/analyze.hpp | 1 + src/ir.cpp | 10 ++-------- test/compile_errors.zig | 2 +- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 3731f3b94c78261eb8061329349cde4ef0d9aa6a..182bcc93a6fe7bf00990fe0ad46582acbbb4e875 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3453,11 +3453,12 @@ TypeEnumField *find_enum_field_by_tag(ZigType *enum_type, const BigInt *tag) { } -static bool is_container(ZigType *type_entry) { +bool is_container(ZigType *type_entry) { switch (type_entry->id) { case ZigTypeIdInvalid: zig_unreachable(); case ZigTypeIdStruct: + return !type_entry->data.structure.is_slice; case ZigTypeIdEnum: case ZigTypeIdUnion: return true; @@ -3498,9 +3499,9 @@ bool is_array_ref(ZigType *type_entry) { return array->id == ZigTypeIdArray; } -bool is_container_ref(ZigType *type_entry) { - return is_ref(type_entry) ? - is_container(type_entry->data.pointer.child_type) : is_container(type_entry); +bool is_container_ref(ZigType *parent_ty) { + ZigType *ty = is_ref(parent_ty) ? parent_ty->data.pointer.child_type : parent_ty; + return is_slice(ty) || is_container(ty); } ZigType *container_ref_type(ZigType *type_entry) { @@ -3765,7 +3766,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { analyze_fn_ir(g, fn_table_entry, return_type_node); } -static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) { +static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) { if (src_use_node->data.use.resolution == TldResolutionUnresolved) { preview_use_decl(g, src_use_node, decls_scope); } @@ -3784,9 +3785,9 @@ static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode * ZigType *src_ty = use_expr->data.x_type; assert(src_ty); - if (src_ty->id != ZigTypeIdStruct || is_slice(src_ty)) { + if (!is_container(src_ty)) { add_node_error(g, dst_use_node, - buf_sprintf("expected struct, found '%s'", buf_ptr(&src_ty->name))); + buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name))); decls_scope->any_imports_failed = true; return; } @@ -3795,8 +3796,8 @@ static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode * ScopeDecls *src_scope = get_container_scope(src_ty); // The top-level container where the symbols are defined, it's used in the // loop below in order to exclude the ones coming from an import statement - ZigType *src_import = get_scope_import(reinterpret_cast(src_scope)); - assert(src_import && src_import->id == ZigTypeIdStruct); + ZigType *src_import = get_scope_import(&src_scope->base); + assert(src_import != nullptr); if (src_scope->any_imports_failed) { decls_scope->any_imports_failed = true; @@ -3835,7 +3836,7 @@ static void add_symbols_from_struct(CodeGen *g, AstNode *src_use_node, AstNode * for (size_t i = 0; i < src_scope->use_decls.length; i += 1) { AstNode *use_decl_node = src_scope->use_decls.at(i); if (use_decl_node->data.use.visib_mod != VisibModPrivate) - add_symbols_from_struct(g, use_decl_node, dst_use_node, decls_scope); + add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope); } } @@ -3847,7 +3848,7 @@ void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { { return; } - add_symbols_from_struct(g, node, node, decls_scope); + add_symbols_from_container(g, node, node, decls_scope); } void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { diff --git a/src/analyze.hpp b/src/analyze.hpp index a43b3063e0143027b060c9f90ca69fd6faad8e5f..d89bb9112615f0f9a6f88a4b46ef27ed790ea020 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -250,5 +250,6 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c); void src_assert(bool ok, AstNode *source_node); +bool is_container(ZigType *type_entry); #endif diff --git a/src/ir.cpp b/src/ir.cpp index 5d3cf5303c8fd78bfa2f5d8e0f93f5428c00b10f..fa60751ca584a03468723f1fecd0e13aa034b83a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10266,12 +10266,6 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc return result; } -static bool is_container(ZigType *type) { - return type->id == ZigTypeIdStruct || - type->id == ZigTypeIdEnum || - type->id == ZigTypeIdUnion; -} - static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { assert(old_bb); @@ -16179,7 +16173,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc if (type_is_invalid(container_type)) { return ira->codegen->invalid_instruction; - } else if (is_container_ref(container_type)) { + } else if (is_slice(container_type) || is_container_ref(container_type)) { assert(container_ptr->value.type->id == ZigTypeIdPointer); if (container_type->id == ZigTypeIdPointer) { ZigType *bare_type = container_ref_type(container_type); @@ -16249,7 +16243,7 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc if (type_is_invalid(child_type)) { return ira->codegen->invalid_instruction; - } else if (is_container(child_type) && !is_slice(child_type)) { + } else if (is_container(child_type)) { if (child_type->id == ZigTypeIdEnum) { if ((err = ensure_complete_type(ira->codegen, child_type))) return ira->codegen->invalid_instruction; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 7da5247d89baad672f727194f10207b421332fd9..fbecacb94b81123bdb35a5f1da760cdffc81713f 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -163,7 +163,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "usingnamespace with wrong type", \\use void; , - "tmp.zig:1:1: error: expected struct, found 'void'", + "tmp.zig:1:1: error: expected struct, enum, or union; found 'void'", ); cases.add( -- 2.54.0 From 399e026cc00af430df66d3d4b77a12fd775973cd Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 29 May 2019 09:43:39 +0200 Subject: [PATCH 38/84] Add sigaltstack wrapper in os.zig --- std/os.zig | 23 +++++++++++++++++++++++ std/os/linux/test.zig | 9 --------- std/os/test.zig | 11 +++++++++++ std/os/uefi.zig | 4 ++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/std/os.zig b/std/os.zig index be2be92f7d7fc3bd7ef4faf29c630ff9489a1991..a7067c89086fbead4205f985fb426eeb96b53383 100644 --- a/std/os.zig +++ b/std/os.zig @@ -2433,6 +2433,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError { return error.Unexpected; } +pub const SigaltstackError = error{ + /// The supplied stack size was less than MINSIGSTKSZ. + SizeTooSmall, + + /// Attempted to change the signal stack while it was active. + PermissionDenied, + Unexpected, +}; + +pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { + if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target) + @compileError("std.os.sigaltstack not available for this target"); + + switch (errno(system.sigaltstack(ss, old_ss))) { + 0 => return, + EFAULT => unreachable, + EINVAL => unreachable, + ENOMEM => return error.SizeTooSmall, + EPERM => return error.PermissionDenied, + else => |err| return unexpectedErrno(err), + } +} + test "" { _ = @import("os/darwin.zig"); _ = @import("os/freebsd.zig"); diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig index 063c10257c9cd53ce895dc4a2edc9be6396a6ea0..c78b071c746b3eabdc2902fdcfee72ae6b36aece 100644 --- a/std/os/linux/test.zig +++ b/std/os/linux/test.zig @@ -83,12 +83,3 @@ test "dl_iterate_phdr" { expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0); expect(counter != 0); } - -test "sigaltstack" { - var st: linux.stack_t = undefined; - expect(linux.sigaltstack(null, &st) == 0); - // Setting a stack size less than MINSIGSTKSZ returns ENOMEM - st.ss_flags = 0; - st.ss_size = 1; - expect(linux.getErrno(linux.sigaltstack(&st, null)) == linux.ENOMEM); -} diff --git a/std/os/test.zig b/std/os/test.zig index d4d662e97fbd0306453d5bb84a093db1941c1caa..dfcd25c4bb26fe4b09430f3f1a88456398bcca4b 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -149,3 +149,14 @@ test "realpath" { var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf)); } + +test "sigaltstack" { + if (builtin.os == .windows or builtin.os == .wasi) return error.SkipZigTest; + + var st: os.stack_t = undefined; + try os.sigaltstack(null, &st); + // Setting a stack size less than MINSIGSTKSZ returns ENOMEM + st.ss_flags = 0; + st.ss_size = 1; + testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null)); +} diff --git a/std/os/uefi.zig b/std/os/uefi.zig index 8ed60d9c9b34cfc24cc321446e53572899ff9b82..7102938d700d598077261d2098a8e8beabcb0e1b 100644 --- a/std/os/uefi.zig +++ b/std/os/uefi.zig @@ -1,2 +1,6 @@ // TODO this is where the extern declarations go. For example, see // inc/efilib.h in gnu-efi-code + +const builtin = @import("builtin"); + +pub const is_the_target = builtin.os == .uefi; -- 2.54.0 From b8d1060f0a240a3907033490a3e6615f78334a97 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 29 May 2019 22:36:38 +0200 Subject: [PATCH 39/84] Add missing sigaltstack definition for darwin --- std/c/darwin.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/std/c/darwin.zig b/std/c/darwin.zig index e45a158f68d3f5e67143e1d3e36a94d78a9a9dd6..d25cd14fc42a5271438cd6d780e010bbc62ebe83 100644 --- a/std/c/darwin.zig +++ b/std/c/darwin.zig @@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t pub fn sigaddset(set: *sigset_t, signo: u5) void { set.* |= u32(1) << (signo - 1); } + +pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; -- 2.54.0 From fb5dc2892171b4f9f14460844b67163b5aa4d269 Mon Sep 17 00:00:00 2001 From: emekoi Date: Thu, 9 May 2019 18:01:12 -0500 Subject: [PATCH 40/84] added subsystem to builtin.zig --- src/codegen.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d9e03baf4e516047d61c6761269b06c9d5c9b57..46dc0df0e22ead99fc3f60f809cb8fa1435134d7 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7869,6 +7869,30 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { //assert(EndianBig == 0); //assert(EndianLittle == 1); } + { + buf_appendf(contents, + "pub const SubSystem = enum {\n" + " Auto,\n" + " Console,\n" + " Windows,\n" + " Posix,\n" + " Native,\n" + " EfiApplication,\n" + " EfiBootServiceDriver,\n" + " EfiRom,\n" + " EfiRuntimeDriver,\n" + "};\n\n"); + + assert(TargetSubsystemAuto == 0); + assert(TargetSubsystemConsole == 1); + assert(TargetSubsystemWindows == 2); + assert(TargetSubsystemPosix == 3); + assert(TargetSubsystemNative == 4); + assert(TargetSubsystemEfiApplication == 5); + assert(TargetSubsystemEfiBootServiceDriver == 6); + assert(TargetSubsystemEfiRom == 7); + assert(TargetSubsystemEfiRuntimeDriver == 8); + } { const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; buf_appendf(contents, "pub const endian = %s;\n", endian_str); @@ -7885,6 +7909,21 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g))); buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); + { + static const char* subsystem_strings[] = { + "Auto", + "Console", + "Windows", + "Posix", + "Native", + "EfiApplication", + "EfiBootServiceDriver", + "EfiRom", + "EfiRuntimeDriver", + }; + buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[g->subsystem]); + } + if (g->is_test_build) { buf_appendf(contents, "const TestFn = struct {\n" @@ -7928,6 +7967,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); cache_bool(&cache_hash, g->valgrind_support); + cache_int(&cache_hash, g->subsystem); Buf digest = BUF_INIT; buf_resize(&digest, 0); -- 2.54.0 From 6bc5b07e3e24871fc81ddd5a3780523bf95cf8d5 Mon Sep 17 00:00:00 2001 From: emekoi Date: Fri, 10 May 2019 09:48:32 -0500 Subject: [PATCH 41/84] try to resolve TargetSubSystemAuto to actual subsystem --- src/codegen.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 46dc0df0e22ead99fc3f60f809cb8fa1435134d7..b401c9d9732cd515bb0c6c7dc40a4e3a9d2e90a4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7872,7 +7872,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { { buf_appendf(contents, "pub const SubSystem = enum {\n" - " Auto,\n" " Console,\n" " Windows,\n" " Posix,\n" @@ -7883,7 +7882,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " EfiRuntimeDriver,\n" "};\n\n"); - assert(TargetSubsystemAuto == 0); assert(TargetSubsystemConsole == 1); assert(TargetSubsystemWindows == 2); assert(TargetSubsystemPosix == 3); @@ -7911,7 +7909,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { { static const char* subsystem_strings[] = { - "Auto", "Console", "Windows", "Posix", @@ -7921,7 +7918,19 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { "EfiRom", "EfiRuntimeDriver", }; - buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[g->subsystem]); + + if (g->subsystem == TargetSubsystemAuto) { + if (g->have_c_main || g->have_pub_main) { + buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemConsole - 1]); + } else if (g->have_winmain || g->have_winmain_crt_startup) { + buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemWindows - 1]); + } else if (g->have_dllmain_crt_startup || g->out_type == OutTypeLib) { + buf_appendf(contents, "pub const subsystem = null;\n"); + } + } else { + buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[g->subsystem - 1]); + } + } if (g->is_test_build) { @@ -7967,7 +7976,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); cache_bool(&cache_hash, g->valgrind_support); - cache_int(&cache_hash, g->subsystem); + cache_int(&cache_hash, g->subsystem - 1); Buf digest = BUF_INIT; buf_resize(&digest, 0); -- 2.54.0 From b461e600e2cb4d2f5a1f8b15003d7b7a5e397482 Mon Sep 17 00:00:00 2001 From: emekoi Date: Fri, 10 May 2019 09:57:02 -0500 Subject: [PATCH 42/84] set subsystem to null if not on windows or uefi --- src/codegen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index b401c9d9732cd515bb0c6c7dc40a4e3a9d2e90a4..ef3851006f031c5b43bb53f957bd620e3fa641ac 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7919,13 +7919,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { "EfiRuntimeDriver", }; - if (g->subsystem == TargetSubsystemAuto) { + if (g->zig_target->os != OsWindows || g->zig_target->os != OsUefi || g->have_dllmain_crt_startup || g->out_type == OutTypeLib) { + buf_appendf(contents, "pub const subsystem = null;\n"); + } else if (g->subsystem == TargetSubsystemAuto) { if (g->have_c_main || g->have_pub_main) { buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemConsole - 1]); } else if (g->have_winmain || g->have_winmain_crt_startup) { buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemWindows - 1]); - } else if (g->have_dllmain_crt_startup || g->out_type == OutTypeLib) { - buf_appendf(contents, "pub const subsystem = null;\n"); } } else { buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[g->subsystem - 1]); -- 2.54.0 From 1ab0ac3ea2a187648b9d13de7f3e0bd1c7c4bf4a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 11:56:36 -0400 Subject: [PATCH 43/84] cleanups for windows subsystem in builtin.zig --- src/all_types.hpp | 2 +- src/analyze.cpp | 3 -- src/codegen.cpp | 81 ++++++++++++++++++++++++++--------------------- src/codegen.hpp | 2 ++ src/link.cpp | 4 +-- src/target.hpp | 6 +++- 6 files changed, 55 insertions(+), 43 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 91676d0c39b2ff87059d2fe2d7f3ae1e60170380..4bb76ff64f2a4a8cf19d2d35c4d811a3be818af7 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1857,7 +1857,7 @@ struct CodeGen { BuildMode build_mode; OutType out_type; const ZigTarget *zig_target; - TargetSubsystem subsystem; + TargetSubsystem subsystem; // careful using this directly; see detect_subsystem ValgrindSupport valgrind_support; bool strip_debug_symbols; bool is_test_build; diff --git a/src/analyze.cpp b/src/analyze.cpp index 182bcc93a6fe7bf00990fe0ad46582acbbb4e875..3769ae47c2850668da756450e1dc96438e25a7a4 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2722,12 +2722,10 @@ void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, Buf *symbol_name, GlobalLi if (ccc) { if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { g->have_c_main = true; - g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; } else if (buf_eql_str(symbol_name, "WinMain") && g->zig_target->os == OsWindows) { g->have_winmain = true; - g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemWindows : g->subsystem; } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && g->zig_target->os == OsWindows) { @@ -3966,7 +3964,6 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu if (is_pub) { if (buf_eql_str(proto_name, "main")) { g->have_pub_main = true; - g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; } else if (buf_eql_str(proto_name, "panic")) { g->have_pub_panic = true; } diff --git a/src/codegen.cpp b/src/codegen.cpp index ef3851006f031c5b43bb53f957bd620e3fa641ac..57f895dedbe9215dca19817ab910dce4d504f38e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7417,6 +7417,21 @@ static const char *build_mode_to_str(BuildMode build_mode) { zig_unreachable(); } +static const char *subsystem_to_str(TargetSubsystem subsystem) { + switch (subsystem) { + case TargetSubsystemConsole: return "Console"; + case TargetSubsystemWindows: return "Windows"; + case TargetSubsystemPosix: return "Posix"; + case TargetSubsystemNative: return "Native"; + case TargetSubsystemEfiApplication: return "EfiApplication"; + case TargetSubsystemEfiBootServiceDriver: return "EfiBootServiceDriver"; + case TargetSubsystemEfiRom: return "EfiRom"; + case TargetSubsystemEfiRuntimeDriver: return "EfiRuntimeDriver"; + case TargetSubsystemAuto: zig_unreachable(); + } + zig_unreachable(); +} + static bool detect_dynamic_link(CodeGen *g) { if (g->is_dynamic) return true; @@ -7462,6 +7477,23 @@ static bool detect_stack_probing(CodeGen *g) { zig_unreachable(); } +// Returns TargetSubsystemAuto to mean "no subsystem" +TargetSubsystem detect_subsystem(CodeGen *g) { + if (g->subsystem != TargetSubsystemAuto) + return g->subsystem; + if (g->zig_target->os == OsWindows) { + if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic)) + return TargetSubsystemAuto; + if (g->have_c_main || g->have_pub_main || g->is_test_build) + return TargetSubsystemConsole; + if (g->have_winmain || g->have_winmain_crt_startup) + return TargetSubsystemWindows; + } else if (g->zig_target->os == OsUefi) { + return TargetSubsystemEfiApplication; + } + return TargetSubsystemAuto; +} + static bool detect_single_threaded(CodeGen *g) { if (g->want_single_threaded) return true; @@ -7882,14 +7914,14 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " EfiRuntimeDriver,\n" "};\n\n"); - assert(TargetSubsystemConsole == 1); - assert(TargetSubsystemWindows == 2); - assert(TargetSubsystemPosix == 3); - assert(TargetSubsystemNative == 4); - assert(TargetSubsystemEfiApplication == 5); - assert(TargetSubsystemEfiBootServiceDriver == 6); - assert(TargetSubsystemEfiRom == 7); - assert(TargetSubsystemEfiRuntimeDriver == 8); + assert(TargetSubsystemConsole == 0); + assert(TargetSubsystemWindows == 1); + assert(TargetSubsystemPosix == 2); + assert(TargetSubsystemNative == 3); + assert(TargetSubsystemEfiApplication == 4); + assert(TargetSubsystemEfiBootServiceDriver == 5); + assert(TargetSubsystemEfiRom == 6); + assert(TargetSubsystemEfiRuntimeDriver == 7); } { const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; @@ -7908,29 +7940,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); { - static const char* subsystem_strings[] = { - "Console", - "Windows", - "Posix", - "Native", - "EfiApplication", - "EfiBootServiceDriver", - "EfiRom", - "EfiRuntimeDriver", - }; - - if (g->zig_target->os != OsWindows || g->zig_target->os != OsUefi || g->have_dllmain_crt_startup || g->out_type == OutTypeLib) { - buf_appendf(contents, "pub const subsystem = null;\n"); - } else if (g->subsystem == TargetSubsystemAuto) { - if (g->have_c_main || g->have_pub_main) { - buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemConsole - 1]); - } else if (g->have_winmain || g->have_winmain_crt_startup) { - buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[TargetSubsystemWindows - 1]); - } - } else { - buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_strings[g->subsystem - 1]); + TargetSubsystem detected_subsystem = detect_subsystem(g); + if (detected_subsystem != TargetSubsystemAuto) { + buf_appendf(contents, "pub const subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem)); } - } if (g->is_test_build) { @@ -7976,7 +7989,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->have_err_ret_tracing); cache_bool(&cache_hash, g->libc_link_lib != nullptr); cache_bool(&cache_hash, g->valgrind_support); - cache_int(&cache_hash, g->subsystem - 1); + cache_int(&cache_hash, detect_subsystem(g)); Buf digest = BUF_INIT; buf_resize(&digest, 0); @@ -8044,10 +8057,6 @@ static void init(CodeGen *g) { g->is_single_threaded = true; } - if (g->is_test_build) { - g->subsystem = g->subsystem == TargetSubsystemAuto ? TargetSubsystemConsole : g->subsystem; - } - assert(g->root_out_name); g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name)); @@ -9401,7 +9410,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->zig_target->vendor); cache_int(ch, g->zig_target->os); cache_int(ch, g->zig_target->abi); - cache_int(ch, g->subsystem); + cache_int(ch, detect_subsystem(g)); cache_bool(ch, g->strip_debug_symbols); cache_bool(ch, g->is_test_build); if (g->is_test_build) { diff --git a/src/codegen.hpp b/src/codegen.hpp index 47c0097e4baf4d7af81a99eaa53c66ccc472199f..9a340d720507ee15e22e4962a7c53340d159e758 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -56,4 +56,6 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us Buf *codegen_generate_builtin_source(CodeGen *g); +TargetSubsystem detect_subsystem(CodeGen *g); + #endif diff --git a/src/link.cpp b/src/link.cpp index 4c3b3d476979fd4d1ca0a6744daa81b523efc7b8..f94b1219f6b9cac86469d5753173eb67bad14312 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1225,7 +1225,7 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { lj->args.append(get_libc_file(g->libc, "libmingwex.a")); lj->args.append(get_libc_file(g->libc, "libmsvcrt.a")); - if (g->subsystem == TargetSubsystemWindows) { + if (detect_subsystem(g) == TargetSubsystemWindows) { lj->args.append(get_libc_file(g->libc, "libgdi32.a")); lj->args.append(get_libc_file(g->libc, "libcomdlg32.a")); } @@ -1307,7 +1307,7 @@ static void construct_linker_job_coff(LinkJob *lj) { lj->args.append((const char *)buf_ptr(g->link_objects.at(i))); } - switch (g->subsystem) { + switch (detect_subsystem(g)) { case TargetSubsystemAuto: if (g->zig_target->os == OsUefi) { add_uefi_link_args(lj); diff --git a/src/target.hpp b/src/target.hpp index f3cde902a09e9db51e2a8f8698b1c8703ac7ff83..7fa99bcda8d1cb0097eeb1bacb5c9579f43b08c0 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -62,7 +62,6 @@ enum SubArchList { }; enum TargetSubsystem { - TargetSubsystemAuto, // Zig should infer the subsystem TargetSubsystemConsole, TargetSubsystemWindows, TargetSubsystemPosix, @@ -71,6 +70,11 @@ enum TargetSubsystem { TargetSubsystemEfiBootServiceDriver, TargetSubsystemEfiRom, TargetSubsystemEfiRuntimeDriver, + + // This means Zig should infer the subsystem. + // It's last so that the indexes of other items can line up + // with the enum in builtin.zig. + TargetSubsystemAuto }; struct ZigTarget { -- 2.54.0 From 3819654c3931b762b0d3dac3b79d58eb791a646d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 12:08:21 -0400 Subject: [PATCH 44/84] codegen: initialize subsystem --- src/codegen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/codegen.cpp b/src/codegen.cpp index 57f895dedbe9215dca19817ab910dce4d504f38e..fc9cdfc9b8b1df3480f57837c15aad5cacf465a9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -100,6 +100,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget codegen_add_time_event(g, "Initialize"); + g->subsystem = TargetSubsystemAuto; g->libc = libc; g->zig_target = target; g->cache_dir = cache_dir; -- 2.54.0 From 9a7cf73b3b4fd27f5f251143dd0b50ea90ed338f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 18:18:18 -0400 Subject: [PATCH 45/84] main: set subsystem in `zig builtin` when explicitly provided --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main.cpp b/src/main.cpp index 4ebd93563fd2568f9309518d9c03cb96dfd41198..29c17212cf93320ecc1884e45cb6956e904a3275 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -954,6 +954,7 @@ int main(int argc, char **argv) { case CmdBuiltin: { CodeGen *g = codegen_create(main_pkg_path, nullptr, &target, out_type, build_mode, override_lib_dir, override_std_dir, nullptr, nullptr); + g->subsystem = subsystem; g->valgrind_support = valgrind_support; g->want_pic = want_pic; g->want_stack_check = want_stack_check; -- 2.54.0 From b7a82288adae12ed52abafbc4e5a9ab391a1f09b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 17:39:26 -0400 Subject: [PATCH 46/84] change `use` to `usingnamespace` See #2014 `use` syntax is still accepted for now. `zig fmt` automatically updates code. After a release cycle the old syntax will be removed. --- doc/docgen.zig | 2 +- doc/langref.html.in | 4 ++-- src/parser.cpp | 2 +- src/tokenizer.cpp | 5 +++-- src/tokenizer.hpp | 2 +- std/zig/parse.zig | 4 ++-- std/zig/parser_test.zig | 14 ++++++++++++-- std/zig/render.zig | 4 +++- std/zig/tokenizer.zig | 5 +++-- 9 files changed, 28 insertions(+), 14 deletions(-) diff --git a/doc/docgen.zig b/doc/docgen.zig index 998db54bbc8deb21778ea14f4637b52c0b4919a2..461ff5cac2fa628954874b2e2ec5ec39d70a2d15 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -788,7 +788,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok std.zig.Token.Id.Keyword_try, std.zig.Token.Id.Keyword_union, std.zig.Token.Id.Keyword_unreachable, - std.zig.Token.Id.Keyword_use, + std.zig.Token.Id.Keyword_usingnamespace, std.zig.Token.Id.Keyword_var, std.zig.Token.Id.Keyword_volatile, std.zig.Token.Id.Keyword_allowzero, diff --git a/doc/langref.html.in b/doc/langref.html.in index 150c14c9cf469d7bb66a874866d5f1fc2a1c4b4c..d583e02b1b0a811dac1b1c418636d4b85b08318e 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -9918,7 +9918,7 @@ KEYWORD_try <- 'try' end_of_word KEYWORD_undefined <- 'undefined' end_of_word KEYWORD_union <- 'union' end_of_word KEYWORD_unreachable <- 'unreachable' end_of_word -KEYWORD_use <- 'use' end_of_word +KEYWORD_usingnamespace <- 'usingnamespace' end_of_word KEYWORD_var <- 'var' end_of_word KEYWORD_volatile <- 'volatile' end_of_word KEYWORD_while <- 'while' end_of_word @@ -9935,7 +9935,7 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_anyerror / KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try / KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable - / KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while + / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while {#header_close#} {#header_open|Zen#}
      diff --git a/src/parser.cpp b/src/parser.cpp index 583accfd72ec11b2892496ee650004b20ed61a09..3d7bbf7801317b67eb998fad85a2b36f1240c43f 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -668,7 +668,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) { return res; } - Token *use = eat_token_if(pc, TokenIdKeywordUse); + Token *use = eat_token_if(pc, TokenIdKeywordUsingNamespace); if (use != nullptr) { AstNode *expr = ast_expect(pc, ast_parse_expr); expect_token(pc, TokenIdSemicolon); diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 958c4f7ef7ead1bcbc3a50c10a607ffaf5acbd93..7bae45f477c93317c7d7f67e1e9ca88cddb2319e 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -153,7 +153,8 @@ static const struct ZigKeyword zig_keywords[] = { {"undefined", TokenIdKeywordUndefined}, {"union", TokenIdKeywordUnion}, {"unreachable", TokenIdKeywordUnreachable}, - {"use", TokenIdKeywordUse}, + {"use", TokenIdKeywordUsingNamespace}, + {"usingnamespace", TokenIdKeywordUsingNamespace}, {"var", TokenIdKeywordVar}, {"volatile", TokenIdKeywordVolatile}, {"while", TokenIdKeywordWhile}, @@ -1546,7 +1547,7 @@ const char * token_name(TokenId id) { case TokenIdKeywordUndefined: return "undefined"; case TokenIdKeywordUnion: return "union"; case TokenIdKeywordUnreachable: return "unreachable"; - case TokenIdKeywordUse: return "use"; + case TokenIdKeywordUsingNamespace: return "usingnamespace"; case TokenIdKeywordVar: return "var"; case TokenIdKeywordVolatile: return "volatile"; case TokenIdKeywordWhile: return "while"; diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index f898ca4e5949d08bff32ca95fa605e53a884cd2a..b17d056109e92e2b89e3e7aa44029203e3b5ffc7 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -96,7 +96,7 @@ enum TokenId { TokenIdKeywordUndefined, TokenIdKeywordUnion, TokenIdKeywordUnreachable, - TokenIdKeywordUse, + TokenIdKeywordUsingNamespace, TokenIdKeywordVar, TokenIdKeywordVolatile, TokenIdKeywordWhile, diff --git a/std/zig/parse.zig b/std/zig/parse.zig index 12a28bf65794a89571abdcefa5a3bee673e0a46a..7312cca370e6a0f38d96ea9e4d85a4fb9f7eaa24 100644 --- a/std/zig/parse.zig +++ b/std/zig/parse.zig @@ -203,7 +203,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?* /// TopLevelDecl /// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block) /// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl -/// / KEYWORD_use Expr SEMICOLON +/// / KEYWORD_usingnamespace Expr SEMICOLON fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { var lib_name: ?*Node = null; const extern_export_inline_token = blk: { @@ -2809,7 +2809,7 @@ fn parseTry(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { } fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { - const token = eatToken(it, .Keyword_use) orelse return null; + const token = eatToken(it, .Keyword_usingnamespace) orelse return null; const node = try arena.create(Node.Use); node.* = Node.Use{ .base = Node{ .id = .Use }, diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 9165c9bbe84e868becf7406310f80ebd35dae120..9f670bc364e1fafa4ffe2c87e812ac1f377a5186 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -1,3 +1,13 @@ +// TODO remove `use` keyword eventually +test "zig fmt: change use to usingnamespace" { + try testTransform( + \\use @import("std"); + , + \\usingnamespace @import("std"); + \\ + ); +} + test "zig fmt: allowzero pointer" { try testCanonical( \\const T = [*]allowzero const u8; @@ -2090,8 +2100,8 @@ test "zig fmt: Block after if" { test "zig fmt: use" { try testCanonical( - \\use @import("std"); - \\pub use @import("std"); + \\usingnamespace @import("std"); + \\pub usingnamespace @import("std"); \\ ); } diff --git a/std/zig/render.zig b/std/zig/render.zig index dc879ee49f589f7f756503c6b010a405e9d8834c..609dcaa0ccc26ec214857ee53c1e0ce8b2e01e8f 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -168,7 +168,9 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i if (use_decl.visib_token) |visib_token| { try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub } - try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // use + // TODO after depracating use, go back to this: + //try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace + try stream.write("usingnamespace "); try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None); try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ; }, diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig index 2ace430a15fdb2beb8d7191c6a74f49567e762b9..9a59d8ab08c5b8a3ad4283e744ad868419d729cf 100644 --- a/std/zig/tokenizer.zig +++ b/std/zig/tokenizer.zig @@ -59,7 +59,8 @@ pub const Token = struct { Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined }, Keyword{ .bytes = "union", .id = Id.Keyword_union }, Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable }, - Keyword{ .bytes = "use", .id = Id.Keyword_use }, + Keyword{ .bytes = "use", .id = Id.Keyword_usingnamespace }, + Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace }, Keyword{ .bytes = "var", .id = Id.Keyword_var }, Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile }, Keyword{ .bytes = "while", .id = Id.Keyword_while }, @@ -190,7 +191,7 @@ pub const Token = struct { Keyword_undefined, Keyword_union, Keyword_unreachable, - Keyword_use, + Keyword_usingnamespace, Keyword_var, Keyword_volatile, Keyword_while, -- 2.54.0 From 8a4ee5942b996d2ffe9c61d7d73fe10f8b1ecea4 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 18:54:46 -0400 Subject: [PATCH 47/84] zig fmt: fix 2 bugs of mangling source files --- CMakeLists.txt | 3 +++ std/zig/parse.zig | 2 +- std/zig/parser_test.zig | 29 +++++++++++++++++++++++++++++ std/zig/render.zig | 2 +- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 985216ed7b6a3b42dc7be175abeed4df35d8ab2d..3f8e65d577d6afcdd1cd4d943c9289facd1b4fcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6729,6 +6729,9 @@ add_custom_command( "${CMAKE_SOURCE_DIR}/src-self-hosted/stage1.zig" "${CMAKE_SOURCE_DIR}/src-self-hosted/translate_c.zig" "${CMAKE_SOURCE_DIR}/build.zig" + "${CMAKE_SOURCE_DIR}/std/zig/parse.zig" + "${CMAKE_SOURCE_DIR}/std/zig/render.zig" + "${CMAKE_SOURCE_DIR}/std/zig/tokenizer.zig" ) add_custom_target(userland_target DEPENDS "${LIBUSERLAND}") add_executable(zig "${ZIG_MAIN_SRC}") diff --git a/std/zig/parse.zig b/std/zig/parse.zig index 7312cca370e6a0f38d96ea9e4d85a4fb9f7eaa24..7a8287db0c4bd62ac4638240c9723d8ec308d4d1 100644 --- a/std/zig/parse.zig +++ b/std/zig/parse.zig @@ -1026,7 +1026,7 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node { else_node.* = Node.Else{ .base = Node{ .id = .Else }, .else_token = else_token, - .payload = null, + .payload = payload, .body = body, }; diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 9f670bc364e1fafa4ffe2c87e812ac1f377a5186..9dfc3b04aa77f363cd0f693abb454ed9de3e31d2 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -8,6 +8,35 @@ test "zig fmt: change use to usingnamespace" { ); } +test "zig fmt: while else err prong with no block" { + try testCanonical( + \\test "" { + \\ const result = while (returnError()) |value| { + \\ break value; + \\ } else |err| i32(2); + \\ expect(result == 2); + \\} + \\ + ); +} + +test "zig fmt: tagged union with enum values" { + try testCanonical( + \\const MultipleChoice2 = union(enum(u32)) { + \\ Unspecified1: i32, + \\ A: f32 = 20, + \\ Unspecified2: void, + \\ B: bool = 40, + \\ Unspecified3: i32, + \\ C: i8 = 60, + \\ Unspecified4: void, + \\ D: void = 1000, + \\ Unspecified5: i32, + \\}; + \\ + ); +} + test "zig fmt: allowzero pointer" { try testCanonical( \\const T = [*]allowzero const u8; diff --git a/std/zig/render.zig b/std/zig/render.zig index 609dcaa0ccc26ec214857ee53c1e0ce8b2e01e8f..49f9d61849b8b83eb408250e16662e5de1e5f002 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -214,7 +214,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i try renderToken(tree, stream, field.name_token, indent, start_col, Space.None); // name try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // : try renderExpression(allocator, stream, tree, indent, start_col, field.type_expr.?, Space.Space); // type - try renderToken(tree, stream, tree.nextToken(field.name_token), indent, start_col, Space.Space); // = + try renderToken(tree, stream, tree.nextToken(field.type_expr.?.lastToken()), indent, start_col, Space.Space); // = return renderExpression(allocator, stream, tree, indent, start_col, field.value_expr.?, Space.Comma); // value, } }, -- 2.54.0 From bfc86776d501dc317737be09e8ed8d13da18f67c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 18:55:42 -0400 Subject: [PATCH 48/84] run zig fmt to update `use` to `usingnamespace` --- src-self-hosted/c.zig | 2 +- src-self-hosted/translate_c.zig | 2 +- std/c.zig | 4 ++-- std/c/darwin.zig | 2 +- std/c/linux.zig | 2 +- std/math/big.zig | 4 ++-- std/os.zig | 2 +- std/os/bits.zig | 2 +- std/os/bits/linux.zig | 6 +++--- std/os/bits/windows.zig | 2 +- std/os/darwin.zig | 2 +- std/os/freebsd.zig | 2 +- std/os/linux.zig | 4 ++-- std/os/linux/x86_64.zig | 2 +- std/os/netbsd.zig | 2 +- std/os/wasi.zig | 2 +- std/os/windows.zig | 2 +- std/os/windows/advapi32.zig | 2 +- std/os/windows/kernel32.zig | 2 +- std/os/windows/ntdll.zig | 2 +- std/os/windows/ole32.zig | 2 +- std/os/windows/shell32.zig | 2 +- std/os/zen.zig | 2 +- test/stage1/behavior/alignof.zig | 1 - test/stage1/behavior/bugs/1076.zig | 1 - test/stage1/behavior/bugs/1486.zig | 1 - test/stage1/behavior/bugs/421.zig | 1 - test/stage1/behavior/bugs/529.zig | 1 - test/stage1/behavior/bugs/726.zig | 1 - test/stage1/behavior/fn.zig | 1 - test/stage1/behavior/import.zig | 2 +- test/stage1/behavior/popcount.zig | 1 - test/stage1/behavior/reflection.zig | 1 - test/stage1/behavior/struct.zig | 2 +- test/stage1/behavior/this.zig | 1 - test/stage1/behavior/undefined.zig | 1 - test/stage1/behavior/union.zig | 2 +- test/stage1/behavior/widening.zig | 1 - test/standalone/use_alias/c.zig | 2 +- 39 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src-self-hosted/c.zig b/src-self-hosted/c.zig index 778d851240b94a06908a693d89cc8ce1d51b2ef1..1de2b6a24c3b045f67ac0de2e3004ce6b64f36f8 100644 --- a/src-self-hosted/c.zig +++ b/src-self-hosted/c.zig @@ -1,4 +1,4 @@ -pub use @cImport({ +pub usingnamespace @cImport({ @cDefine("__STDC_CONSTANT_MACROS", ""); @cDefine("__STDC_LIMIT_MACROS", ""); @cInclude("inttypes.h"); diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index dac4c2b1ca0e339eef2f9238217997dfc6ac81ca..b7ced4a89f97451e38e24a9b7295515f264a72bf 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -6,7 +6,7 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const ast = std.zig.ast; const Token = std.zig.Token; -use @import("clang.zig"); +usingnamespace @import("clang.zig"); pub const Mode = enum { import, diff --git a/std/c.zig b/std/c.zig index 4a223cc9e26b6299124f94aaee7642da701e4f36..029b92e549c790d90802a1a3f7faa33ecf2a6502 100644 --- a/std/c.zig +++ b/std/c.zig @@ -2,9 +2,9 @@ const builtin = @import("builtin"); const std = @import("std"); const page_size = std.mem.page_size; -pub use @import("os/bits.zig"); +pub usingnamespace @import("os/bits.zig"); -pub use switch (builtin.os) { +pub usingnamespace switch (builtin.os) { .linux => @import("c/linux.zig"), .windows => @import("c/windows.zig"), .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"), diff --git a/std/c/darwin.zig b/std/c/darwin.zig index e45a158f68d3f5e67143e1d3e36a94d78a9a9dd6..156429e7b9fec5135a9a9d57e51c96ffaba568e2 100644 --- a/std/c/darwin.zig +++ b/std/c/darwin.zig @@ -3,7 +3,7 @@ const assert = std.debug.assert; const builtin = @import("builtin"); const macho = std.macho; -use @import("../os/bits.zig"); +usingnamespace @import("../os/bits.zig"); extern "c" fn __error() *c_int; pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int; diff --git a/std/c/linux.zig b/std/c/linux.zig index 9e028728c7560c97612b69067ab3757ee8b282f6..83c6bdfe5bb4cc6ad603f1e5bba1daf7b54880fd 100644 --- a/std/c/linux.zig +++ b/std/c/linux.zig @@ -1,5 +1,5 @@ const std = @import("../std.zig"); -use std.c; +usingnamespace std.c; extern "c" fn __errno_location() *c_int; pub const _errno = __errno_location; diff --git a/std/math/big.zig b/std/math/big.zig index 44b5ce675fadef3ca828ff32aae607a739e7a252..8105beb5065a742eff0f4556d54991a3315614e2 100644 --- a/std/math/big.zig +++ b/std/math/big.zig @@ -1,5 +1,5 @@ -pub use @import("big/int.zig"); -pub use @import("big/rational.zig"); +pub usingnamespace @import("big/int.zig"); +pub usingnamespace @import("big/rational.zig"); test "math.big" { _ = @import("big/int.zig"); diff --git a/std/os.zig b/std/os.zig index 6f1f0135ce9301824dbac688f2a525840f02cdc7..631cc266a80bd8856f6e388f9021760470a91edf 100644 --- a/std/os.zig +++ b/std/os.zig @@ -46,7 +46,7 @@ pub const system = if (builtin.link_libc) std.c else switch (builtin.os) { else => struct {}, }; -pub use @import("os/bits.zig"); +pub usingnamespace @import("os/bits.zig"); /// See also `getenv`. Populated by startup code before main(). pub var environ: [][*]u8 = undefined; diff --git a/std/os/bits.zig b/std/os/bits.zig index 7b87cc6e4d98df5c0d6a1dbe03ea1cfd9f2a8f7f..f16da2487b862a633beb3b5aab29e3893c3eef4c 100644 --- a/std/os/bits.zig +++ b/std/os/bits.zig @@ -3,7 +3,7 @@ const builtin = @import("builtin"); -pub use switch (builtin.os) { +pub usingnamespace switch (builtin.os) { .macosx, .ios, .tvos, .watchos => @import("bits/darwin.zig"), .freebsd => @import("bits/freebsd.zig"), .linux => @import("bits/linux.zig"), diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig index 6532e72362800c45c60aed530b6b77264d99549a..44e713b15f74889f2b1df1fc25e36f3212ec7b32 100644 --- a/std/os/bits/linux.zig +++ b/std/os/bits/linux.zig @@ -1,10 +1,10 @@ const builtin = @import("builtin"); const std = @import("../../std.zig"); const maxInt = std.math.maxInt; -use @import("../bits.zig"); +usingnamespace @import("../bits.zig"); -pub use @import("linux/errno.zig"); -pub use switch (builtin.arch) { +pub usingnamespace @import("linux/errno.zig"); +pub usingnamespace switch (builtin.arch) { .x86_64 => @import("linux/x86_64.zig"), .aarch64 => @import("linux/arm64.zig"), else => struct {}, diff --git a/std/os/bits/windows.zig b/std/os/bits/windows.zig index 4959249a9a76673c37700bdf99cffe2b5a9c8f4d..fc148d812ff417e6954e475993f378c3c87f4db2 100644 --- a/std/os/bits/windows.zig +++ b/std/os/bits/windows.zig @@ -1,6 +1,6 @@ // The reference for these types and values is Microsoft Windows's ucrt (Universal C RunTime). -use @import("../windows/bits.zig"); +usingnamespace @import("../windows/bits.zig"); pub const fd_t = HANDLE; pub const pid_t = HANDLE; diff --git a/std/os/darwin.zig b/std/os/darwin.zig index d6e0a1b77cae1c58dc214bc68d30bbf33814501d..67ce9a06cff54ead18902b8f3e69611128130466 100644 --- a/std/os/darwin.zig +++ b/std/os/darwin.zig @@ -4,4 +4,4 @@ pub const is_the_target = switch (builtin.os) { .macosx, .tvos, .watchos, .ios => true, else => false, }; -pub use std.c; +pub usingnamespace std.c; diff --git a/std/os/freebsd.zig b/std/os/freebsd.zig index c0f3382bd04f0430d9b37633eb299970dcc09b0d..d418ccd415b8bf97788e6128ddb56943048479ef 100644 --- a/std/os/freebsd.zig +++ b/std/os/freebsd.zig @@ -1,4 +1,4 @@ const std = @import("../std.zig"); const builtin = @import("builtin"); pub const is_the_target = builtin.os == .freebsd; -pub use std.c; +pub usingnamespace std.c; diff --git a/std/os/linux.zig b/std/os/linux.zig index 282aa19bf13c8af05fabfba89b77aa659d2acc24..5d26446682747c85645b2724e8a1a0aaaef89e4a 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -14,12 +14,12 @@ const vdso = @import("linux/vdso.zig"); const dl = @import("../dynamic_library.zig"); pub const is_the_target = builtin.os == .linux; -pub use switch (builtin.arch) { +pub usingnamespace switch (builtin.arch) { .x86_64 => @import("linux/x86_64.zig"), .aarch64 => @import("linux/arm64.zig"), else => struct {}, }; -pub use @import("bits.zig"); +pub usingnamespace @import("bits.zig"); pub const tls = @import("linux/tls.zig"); /// Set by startup code, used by `getauxval`. diff --git a/std/os/linux/x86_64.zig b/std/os/linux/x86_64.zig index fa866cff4c7e57ac75da1899783ce5aa77bee9cf..82eed0256b851118d967b16508596d8d172ad568 100644 --- a/std/os/linux/x86_64.zig +++ b/std/os/linux/x86_64.zig @@ -1,4 +1,4 @@ -use @import("../bits.zig"); +usingnamespace @import("../bits.zig"); pub fn syscall0(number: usize) usize { return asm volatile ("syscall" diff --git a/std/os/netbsd.zig b/std/os/netbsd.zig index 25e72c10a829b41cbe0ae45c1785d69b951f8ab1..cd63e40f5cf4d6c4ef1c46855799b79486f29d30 100644 --- a/std/os/netbsd.zig +++ b/std/os/netbsd.zig @@ -1,4 +1,4 @@ const builtin = @import("builtin"); const std = @import("../std.zig"); pub const is_the_target = builtin.os == .netbsd; -pub use std.c; +pub usingnamespace std.c; diff --git a/std/os/wasi.zig b/std/os/wasi.zig index adfe9e821d4ac3271717b7b2f40130dd3912bed7..57b708395c3aaf0ed869514154dc8cf9bd1580b2 100644 --- a/std/os/wasi.zig +++ b/std/os/wasi.zig @@ -5,7 +5,7 @@ const std = @import("std"); const assert = std.debug.assert; pub const is_the_target = builtin.os == .wasi; -pub use @import("bits.zig"); +pub usingnamespace @import("bits.zig"); comptime { assert(@alignOf(i8) == 1); diff --git a/std/os/windows.zig b/std/os/windows.zig index 526ac1cfd6513bf38c9ea625bdc059796a5969a1..1d59004012facee6daa5118d8fc3e595b54a1795 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -18,7 +18,7 @@ pub const ntdll = @import("windows/ntdll.zig"); pub const ole32 = @import("windows/ole32.zig"); pub const shell32 = @import("windows/shell32.zig"); -pub use @import("windows/bits.zig"); +pub usingnamespace @import("windows/bits.zig"); pub const CreateFileError = error{ SharingViolation, diff --git a/std/os/windows/advapi32.zig b/std/os/windows/advapi32.zig index df3220e24c0da1b1b6482da97e25da1bd7db4c80..165a2c10a3219707424d68cfb16bbd4f59d88294 100644 --- a/std/os/windows/advapi32.zig +++ b/std/os/windows/advapi32.zig @@ -1,4 +1,4 @@ -use @import("bits.zig"); +usingnamespace @import("bits.zig"); pub extern "advapi32" stdcallcc fn RegOpenKeyExW( hKey: HKEY, diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index 2bd1824620a27bf9ffabaf7acb41b1970ce57139..852369df20e50d1fb22b493be123caef2a927c07 100644 --- a/std/os/windows/kernel32.zig +++ b/std/os/windows/kernel32.zig @@ -1,4 +1,4 @@ -use @import("bits.zig"); +usingnamespace @import("bits.zig"); pub extern "kernel32" stdcallcc fn CancelIoEx(hFile: HANDLE, lpOverlapped: LPOVERLAPPED) BOOL; diff --git a/std/os/windows/ntdll.zig b/std/os/windows/ntdll.zig index 60c03ffc07d156b34b7446b390925f4fa55bbcf1..e5469cdcf90d03d2ebb759f66adfa16325a21cee 100644 --- a/std/os/windows/ntdll.zig +++ b/std/os/windows/ntdll.zig @@ -1,3 +1,3 @@ -use @import("bits.zig"); +usingnamespace @import("bits.zig"); pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD; diff --git a/std/os/windows/ole32.zig b/std/os/windows/ole32.zig index 80f5bebc360a9756397a93d4f38bdf833fe96914..39c12d074c0174e215a5f5a9c8f124c2837a738c 100644 --- a/std/os/windows/ole32.zig +++ b/std/os/windows/ole32.zig @@ -1,4 +1,4 @@ -use @import("bits.zig"); +usingnamespace @import("bits.zig"); pub extern "ole32" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; pub extern "ole32" stdcallcc fn CoUninitialize() void; diff --git a/std/os/windows/shell32.zig b/std/os/windows/shell32.zig index 9f24acc5c4a84c48e1d80d112b22b5e8d9317f88..c178997aad9ee6000b66ebc839f087af56e04e40 100644 --- a/std/os/windows/shell32.zig +++ b/std/os/windows/shell32.zig @@ -1,3 +1,3 @@ -use @import("bits.zig"); +usingnamespace @import("bits.zig"); pub extern "shell32" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; diff --git a/std/os/zen.zig b/std/os/zen.zig index 8d2f9634863b0f131f98048097300ea13c4b75d0..727f55fa6d9e854279266da43b315a45bfb26a66 100644 --- a/std/os/zen.zig +++ b/std/os/zen.zig @@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1; pub const STDERR_FILENO = 2; // FIXME: let's borrow Linux's error numbers for now. -use @import("bits/linux/errno.zig"); +usingnamespace @import("bits/linux/errno.zig"); // Get the errno from a syscall return value, or 0 for no error. pub fn getErrno(r: usize) usize { const signed_r = @bitCast(isize, r); diff --git a/test/stage1/behavior/alignof.zig b/test/stage1/behavior/alignof.zig index d4d9661ead4987cae4f28d90057b749d8cbc9bb6..f923fd935577b34837d86d2d4b2d474672aab0f8 100644 --- a/test/stage1/behavior/alignof.zig +++ b/test/stage1/behavior/alignof.zig @@ -15,4 +15,3 @@ test "@alignOf(T) before referencing T" { comptime expect(@alignOf(Foo) == 4); } } - diff --git a/test/stage1/behavior/bugs/1076.zig b/test/stage1/behavior/bugs/1076.zig index 9dc1d111eae88b8040563377e73c0edf32128285..550ee9703a0fdab2193e8fb1b109662d2c7dc206 100644 --- a/test/stage1/behavior/bugs/1076.zig +++ b/test/stage1/behavior/bugs/1076.zig @@ -13,4 +13,3 @@ fn testCastPtrOfArrayToSliceAndPtr() void { x[0] += 1; expect(mem.eql(u8, array[0..], "boeu")); } - diff --git a/test/stage1/behavior/bugs/1486.zig b/test/stage1/behavior/bugs/1486.zig index d1bb8d7053008d1b9b249fef623d1f790feeb133..1b8e5ca4a108beb3e7594e6cb268ddfcb2b8d43c 100644 --- a/test/stage1/behavior/bugs/1486.zig +++ b/test/stage1/behavior/bugs/1486.zig @@ -8,4 +8,3 @@ test "constant pointer to global variable causes runtime load" { expect(&global == ptr); expect(ptr.* == 1234); } - diff --git a/test/stage1/behavior/bugs/421.zig b/test/stage1/behavior/bugs/421.zig index e5f67f61b7fc9e97bec44e49f0045fc39beeab0f..a618876e004fa53931d3b2ff042f319ec0167b07 100644 --- a/test/stage1/behavior/bugs/421.zig +++ b/test/stage1/behavior/bugs/421.zig @@ -13,4 +13,3 @@ fn extractOne64(a: u128) u64 { const x = @bitCast([2]u64, a); return x[1]; } - diff --git a/test/stage1/behavior/bugs/529.zig b/test/stage1/behavior/bugs/529.zig index 08d6768f7cf3da29241c0b24fa28e675641252ec..6aeb73c3312416c9f2370b1a85dada4376bd6153 100644 --- a/test/stage1/behavior/bugs/529.zig +++ b/test/stage1/behavior/bugs/529.zig @@ -12,4 +12,3 @@ test "issue 529 fixed" { @import("529_other_file.zig").issue529(null); issue529(null); } - diff --git a/test/stage1/behavior/bugs/726.zig b/test/stage1/behavior/bugs/726.zig index dd2a135b5668ab3394bbec5d7c44015f1d843212..632d3b1511cd82b4d29e70f1e00d9590e733a0a5 100644 --- a/test/stage1/behavior/bugs/726.zig +++ b/test/stage1/behavior/bugs/726.zig @@ -13,4 +13,3 @@ test "@ptrCast from var in empty struct to nullable" { var x: ?*const u8 = @ptrCast(?*const u8, &container.c); expect(x.?.* == 4); } - diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index 3f78c8029018a564d1cdf37c597949ac7cd44476..86f382674c15fe468d5453d3c8ef26325fbb61ff 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -205,4 +205,3 @@ test "extern struct with stdcallcc fn pointer" { s.ptr = S.foo; expect(s.ptr() == 1234); } - diff --git a/test/stage1/behavior/import.zig b/test/stage1/behavior/import.zig index 11d696f81e61d88dc0e067f19dde2d603e1575ca..aa6e9d82bae9077dc98512f4ed8e63ecd574bbca 100644 --- a/test/stage1/behavior/import.zig +++ b/test/stage1/behavior/import.zig @@ -12,7 +12,7 @@ test "importing the same thing gives the same import" { test "import in non-toplevel scope" { const S = struct { - use @import("import/a_namespace.zig"); + usingnamespace @import("import/a_namespace.zig"); }; expectEqual(i32(1234), S.foo()); } diff --git a/test/stage1/behavior/popcount.zig b/test/stage1/behavior/popcount.zig index 327bee62a1a03698151a5a5cca3e3c5813f7b9b3..044864cedee2b31345119e0d6ab46ae15214a3b1 100644 --- a/test/stage1/behavior/popcount.zig +++ b/test/stage1/behavior/popcount.zig @@ -41,4 +41,3 @@ fn testPopCount() void { expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24); } } - diff --git a/test/stage1/behavior/reflection.zig b/test/stage1/behavior/reflection.zig index 55efc85b97175675ff9e9e67539573283e9222d9..739e0b318a2af384f324a39ff131574a8e78e3cd 100644 --- a/test/stage1/behavior/reflection.zig +++ b/test/stage1/behavior/reflection.zig @@ -93,4 +93,3 @@ const Bar = union(enum) { Three: bool, Four: f64, }; - diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index d7bbee5d15256743d37d9908bed09075524b7ab0..7a84fcc763c5657224c6f780974eb1398ada35b2 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -552,7 +552,7 @@ test "packed struct with fp fields" { test "use within struct scope" { const S = struct { - use struct { + usingnamespace struct { pub fn inner() i32 { return 42; } diff --git a/test/stage1/behavior/this.zig b/test/stage1/behavior/this.zig index a0bee3a3ee5b0f07c1ea53109e6cbc8b4fa002e4..927c0808ea9e4fb2c0afe07d9da58140fa7d2ef0 100644 --- a/test/stage1/behavior/this.zig +++ b/test/stage1/behavior/this.zig @@ -32,4 +32,3 @@ test "this refer to container" { expect(pt.x == 13); expect(pt.y == 35); } - diff --git a/test/stage1/behavior/undefined.zig b/test/stage1/behavior/undefined.zig index 4c233576cd44c9389ccd52b5803dc473568254a3..4f2cbed3bce55239bfcc2b3dab17f0376e0e3cfb 100644 --- a/test/stage1/behavior/undefined.zig +++ b/test/stage1/behavior/undefined.zig @@ -66,4 +66,3 @@ test "type name of undefined" { const x = undefined; expect(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)")); } - diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index b8bb9a51b87d07aad5c8dd8d9f37e61312e79e21..58a5203e8aaeb7e4f7e2c6e37b44b9c54cc049aa 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -374,7 +374,7 @@ const Attribute = union(enum) { fn setAttribute(attr: Attribute) void {} fn Setter(attr: Attribute) type { - return struct{ + return struct { fn set() void { setAttribute(attr); } diff --git a/test/stage1/behavior/widening.zig b/test/stage1/behavior/widening.zig index f7c238ee8d9515e7109203a5ae335b16bbb49909..d79270b811c428f733220d85a67bd41012245282 100644 --- a/test/stage1/behavior/widening.zig +++ b/test/stage1/behavior/widening.zig @@ -25,4 +25,3 @@ test "float widening" { var d: f128 = c; expect(d == a); } - diff --git a/test/standalone/use_alias/c.zig b/test/standalone/use_alias/c.zig index 1bc325b117337fdabc3b83c3e7173be649c230ec..2835a51615cab602363baf3d6fc85291f32128fd 100644 --- a/test/standalone/use_alias/c.zig +++ b/test/standalone/use_alias/c.zig @@ -1 +1 @@ -pub use @cImport(@cInclude("foo.h")); +pub usingnamespace @cImport(@cInclude("foo.h")); -- 2.54.0 From dab1dc79a717bd5b484ada458f99ce17a5c468cb Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Thu, 23 May 2019 00:06:34 -0700 Subject: [PATCH 49/84] LinuxDynLib: remove MAP_LOCKED flag --- std/dynamic_library.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig index e55d6df84ffdb0a31fe2f23e1b1ed13ae2900913..79e325b81eec9c30ef2480e058786dda80648b52 100644 --- a/std/dynamic_library.zig +++ b/std/dynamic_library.zig @@ -114,7 +114,7 @@ pub const LinuxDynLib = struct { null, size, os.PROT_READ | os.PROT_EXEC, - os.MAP_PRIVATE | os.MAP_LOCKED, + os.MAP_PRIVATE, fd, 0, ); -- 2.54.0 From e716c9ba4b0550159157238ad8e3ef0a136c6c42 Mon Sep 17 00:00:00 2001 From: NBonaparte Date: Thu, 23 May 2019 00:10:46 -0700 Subject: [PATCH 50/84] build_examples: reenable load_dynamic_library --- test/build_examples.zig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/build_examples.zig b/test/build_examples.zig index c75c38b138f03c06bb86b5c893b5692377ca473b..d38336939daca87eb07c0cedcbf0c5a3086c4fbd 100644 --- a/test/build_examples.zig +++ b/test/build_examples.zig @@ -17,9 +17,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void { cases.addBuildFile("test/standalone/use_alias/build.zig"); cases.addBuildFile("test/standalone/brace_expansion/build.zig"); cases.addBuildFile("test/standalone/empty_env/build.zig"); - if (false) { - // TODO this test is disabled because it is failing on the CI server's linux. when this is fixed - // enable it for at least linux + if (builtin.os == builtin.Os.linux) { // TODO hook up the DynLib API for windows using LoadLibraryA // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it cases.addBuildFile("test/standalone/load_dynamic_library/build.zig"); -- 2.54.0 From 4e1f3a9ba35530f129e43e11ac0676c562e4cb98 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Thu, 30 May 2019 00:11:16 +0200 Subject: [PATCH 51/84] Correct formatting for multiline string in arrays --- std/zig/parser_test.zig | 19 +++++++++++++++++++ std/zig/render.zig | 21 +++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 9dfc3b04aa77f363cd0f693abb454ed9de3e31d2..2a10e95e6c3e95cb4bc1ed57adfe286101d51388 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -2209,6 +2209,25 @@ test "zig fmt: inline asm parameter alignment" { ); } +test "zig fmt: multiline string in array" { + try testCanonical( + \\const Foo = [][]const u8{ + \\ \\aaa + \\, + \\ \\bbb + \\}; + \\ + \\fn bar() void { + \\ const Foo = [][]const u8{ + \\ \\aaa + \\ , + \\ \\bbb + \\ }; + \\} + \\ + ); +} + const std = @import("std"); const mem = std.mem; const warn = std.debug.warn; diff --git a/std/zig/render.zig b/std/zig/render.zig index 49f9d61849b8b83eb408250e16662e5de1e5f002..3bf279eaf307e19efdc0a29f90c9f656463934fd 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -726,15 +726,21 @@ fn renderExpression( expr_widths[i] = width; } - const new_indent = indent + indent_delta; + var new_indent = indent + indent_delta; try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); - try stream.writeByteNTimes(' ', new_indent); + + if (tree.tokens.at(lbrace + 1).id != Token.Id.MultilineStringLiteralLine) { + try stream.writeByteNTimes(' ', new_indent); + } it.set(0); i = 0; var col: usize = 1; while (it.next()) |expr| : (i += 1) { if (it.peek()) |next_expr| { + if (expr.*.id == ast.Node.Id.MultilineStringLiteral) { + new_indent -= indent_delta; + } try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None); const comma = tree.nextToken(expr.*.lastToken()); @@ -753,12 +759,17 @@ fn renderExpression( try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // , try renderExtraNewline(tree, stream, start_col, next_expr.*); - try stream.writeByteNTimes(' ', new_indent); + if (next_expr.*.id != ast.Node.Id.MultilineStringLiteral) { + try stream.writeByteNTimes(' ', new_indent); + } } else { try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // , } } - try stream.writeByteNTimes(' ', indent); + const last_node = it.prev() orelse unreachable; + if (last_node.*.id != ast.Node.Id.MultilineStringLiteral) { + try stream.writeByteNTimes(' ', indent); + } return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); } else { try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); @@ -1039,6 +1050,8 @@ fn renderExpression( }, ast.Node.Id.MultilineStringLiteral => { + // TODO: Don't indent in this function, but let the caller indent. + // If this has been implemented, a lot of hacky solutions in i.e. ArrayInit and FunctionCall can be removed const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base); var skip_first_indent = true; -- 2.54.0 From 4188faeac56d9c022fa33449aa4283b1f55395cf Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Tue, 9 Apr 2019 15:00:53 -0500 Subject: [PATCH 52/84] stage1: AstNodes cannot be casted, but are rather accessed via a union. Unlike IrInstruction[Foo]s, which all start with: IrInstruction base; AstNodes do not work like this, and instead use a pointer to their specializations. The code assumed otherwise. --- src/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index fa60751ca584a03468723f1fecd0e13aa034b83a..ba6f256b40135d512b231cd0aea40481a9084681 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -18507,7 +18507,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, return ErrorSemanticAnalyzeFail; } - AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); + AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; ConstExprValue *fn_def_val = create_const_vals(1); fn_def_val->special = ConstValSpecialStatic; -- 2.54.0 From 01a4897da54d6c789b0a5232188bbafbbd660946 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 16 May 2019 19:40:12 -0400 Subject: [PATCH 53/84] improve the libc of wasm32-freestanding target * introduce wasm32-freestanding-musl .h files to fix conflicts with stddef.h and errno.h * fix an issue with zig build system regarding installation of webassembly libraries * add implementations to zig's libc: - strcmp - strncmp - strerror - strlen See #514 --- CMakeLists.txt | 2 + .../wasm32-freestanding-musl/bits/alltypes.h | 385 ++++++++++++++++++ libc/include/wasm32-freestanding-musl/errno.h | 24 ++ std/build.zig | 20 +- std/special/c.zig | 38 ++ 5 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 libc/include/wasm32-freestanding-musl/bits/alltypes.h create mode 100644 libc/include/wasm32-freestanding-musl/errno.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f8e65d577d6afcdd1cd4d943c9289facd1b4fcd..25d6bd0a12de1fab717fceea582ae1e092485164 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6066,6 +6066,8 @@ set(ZIG_LIBC_FILES "include/x86_64-linux-musl/bits/stat.h" "include/x86_64-linux-musl/bits/syscall.h" "include/x86_64-linux-musl/bits/user.h" + "include/wasm32-freestanding-musl/bits/alltypes.h" + "include/wasm32-freestanding-musl/errno.h" "musl/arch/aarch64/atomic_arch.h" "musl/arch/aarch64/bits/alltypes.h.in" "musl/arch/aarch64/bits/endian.h" diff --git a/libc/include/wasm32-freestanding-musl/bits/alltypes.h b/libc/include/wasm32-freestanding-musl/bits/alltypes.h new file mode 100644 index 0000000000000000000000000000000000000000..5c5a52c7e9f2dc5982f82c5eeb40868b11da7809 --- /dev/null +++ b/libc/include/wasm32-freestanding-musl/bits/alltypes.h @@ -0,0 +1,385 @@ +#define _Addr long +#define _Int64 long long +#define _Reg long + +#if defined(__NEED_va_list) && !defined(__DEFINED_va_list) +typedef __builtin_va_list va_list; +#define __DEFINED_va_list +#endif + +#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list) +typedef __builtin_va_list __isoc_va_list; +#define __DEFINED___isoc_va_list +#endif + + +#ifndef __cplusplus +#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t) +typedef int wchar_t; +#define __DEFINED_wchar_t +#endif + +#endif + +#if defined(__NEED_float_t) && !defined(__DEFINED_float_t) +typedef float float_t; +#define __DEFINED_float_t +#endif + +#if defined(__NEED_double_t) && !defined(__DEFINED_double_t) +typedef double double_t; +#define __DEFINED_double_t +#endif + + +#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t) +typedef struct { long long __ll; long double __ld; } max_align_t; +#define __DEFINED_max_align_t +#endif + + +#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) +typedef long time_t; +#define __DEFINED_time_t +#endif + +#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t) +typedef long suseconds_t; +#define __DEFINED_suseconds_t +#endif + + +#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t; +#define __DEFINED_pthread_attr_t +#endif + +#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) +typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t; +#define __DEFINED_pthread_mutex_t +#endif + +#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) +typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t; +#define __DEFINED_mtx_t +#endif + +#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t; +#define __DEFINED_pthread_cond_t +#endif + +#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t) +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t; +#define __DEFINED_cnd_t +#endif + +#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t) +typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t; +#define __DEFINED_pthread_rwlock_t +#endif + +#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t) +typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t; +#define __DEFINED_pthread_barrier_t +#endif + +#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) +typedef unsigned _Addr size_t; +#define __DEFINED_size_t +#endif + +#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) +typedef unsigned _Addr uintptr_t; +#define __DEFINED_uintptr_t +#endif + +#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t) +typedef _Addr ptrdiff_t; +#define __DEFINED_ptrdiff_t +#endif + +#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t) +typedef _Addr ssize_t; +#define __DEFINED_ssize_t +#endif + +#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) +typedef _Addr intptr_t; +#define __DEFINED_intptr_t +#endif + +#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t) +typedef _Addr regoff_t; +#define __DEFINED_regoff_t +#endif + +#if defined(__NEED_register_t) && !defined(__DEFINED_register_t) +typedef _Reg register_t; +#define __DEFINED_register_t +#endif + + +#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) +typedef signed char int8_t; +#define __DEFINED_int8_t +#endif + +#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) +typedef signed short int16_t; +#define __DEFINED_int16_t +#endif + +#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) +typedef signed int int32_t; +#define __DEFINED_int32_t +#endif + +#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) +typedef signed _Int64 int64_t; +#define __DEFINED_int64_t +#endif + +#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) +typedef signed _Int64 intmax_t; +#define __DEFINED_intmax_t +#endif + +#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) +typedef unsigned char uint8_t; +#define __DEFINED_uint8_t +#endif + +#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) +typedef unsigned short uint16_t; +#define __DEFINED_uint16_t +#endif + +#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) +typedef unsigned int uint32_t; +#define __DEFINED_uint32_t +#endif + +#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) +typedef unsigned _Int64 uint64_t; +#define __DEFINED_uint64_t +#endif + +#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t) +typedef unsigned _Int64 u_int64_t; +#define __DEFINED_u_int64_t +#endif + +#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) +typedef unsigned _Int64 uintmax_t; +#define __DEFINED_uintmax_t +#endif + + +#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t) +typedef unsigned mode_t; +#define __DEFINED_mode_t +#endif + +#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t) +typedef unsigned _Reg nlink_t; +#define __DEFINED_nlink_t +#endif + +#if defined(__NEED_off_t) && !defined(__DEFINED_off_t) +typedef _Int64 off_t; +#define __DEFINED_off_t +#endif + +#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t) +typedef unsigned _Int64 ino_t; +#define __DEFINED_ino_t +#endif + +#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t) +typedef unsigned _Int64 dev_t; +#define __DEFINED_dev_t +#endif + +#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t) +typedef long blksize_t; +#define __DEFINED_blksize_t +#endif + +#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t) +typedef _Int64 blkcnt_t; +#define __DEFINED_blkcnt_t +#endif + +#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t) +typedef unsigned _Int64 fsblkcnt_t; +#define __DEFINED_fsblkcnt_t +#endif + +#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t) +typedef unsigned _Int64 fsfilcnt_t; +#define __DEFINED_fsfilcnt_t +#endif + + +#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t) +typedef unsigned wint_t; +#define __DEFINED_wint_t +#endif + +#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) +typedef unsigned long wctype_t; +#define __DEFINED_wctype_t +#endif + + +#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t) +typedef void * timer_t; +#define __DEFINED_timer_t +#endif + +#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) +typedef int clockid_t; +#define __DEFINED_clockid_t +#endif + +#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t) +typedef long clock_t; +#define __DEFINED_clock_t +#endif + +#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval) +struct timeval { time_t tv_sec; suseconds_t tv_usec; }; +#define __DEFINED_struct_timeval +#endif + +#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) +struct timespec { time_t tv_sec; long tv_nsec; }; +#define __DEFINED_struct_timespec +#endif + + +#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t) +typedef int pid_t; +#define __DEFINED_pid_t +#endif + +#if defined(__NEED_id_t) && !defined(__DEFINED_id_t) +typedef unsigned id_t; +#define __DEFINED_id_t +#endif + +#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t) +typedef unsigned uid_t; +#define __DEFINED_uid_t +#endif + +#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t) +typedef unsigned gid_t; +#define __DEFINED_gid_t +#endif + +#if defined(__NEED_key_t) && !defined(__DEFINED_key_t) +typedef int key_t; +#define __DEFINED_key_t +#endif + +#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t) +typedef unsigned useconds_t; +#define __DEFINED_useconds_t +#endif + + +#ifdef __cplusplus +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef unsigned long pthread_t; +#define __DEFINED_pthread_t +#endif + +#else +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef struct __pthread * pthread_t; +#define __DEFINED_pthread_t +#endif + +#endif +#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t) +typedef int pthread_once_t; +#define __DEFINED_pthread_once_t +#endif + +#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t) +typedef unsigned pthread_key_t; +#define __DEFINED_pthread_key_t +#endif + +#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t) +typedef int pthread_spinlock_t; +#define __DEFINED_pthread_spinlock_t +#endif + +#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) +typedef struct { unsigned __attr; } pthread_mutexattr_t; +#define __DEFINED_pthread_mutexattr_t +#endif + +#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t) +typedef struct { unsigned __attr; } pthread_condattr_t; +#define __DEFINED_pthread_condattr_t +#endif + +#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t) +typedef struct { unsigned __attr; } pthread_barrierattr_t; +#define __DEFINED_pthread_barrierattr_t +#endif + +#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t) +typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t; +#define __DEFINED_pthread_rwlockattr_t +#endif + + +#if defined(__NEED_FILE) && !defined(__DEFINED_FILE) +typedef struct _IO_FILE FILE; +#define __DEFINED_FILE +#endif + + +#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t) +typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t; +#define __DEFINED_mbstate_t +#endif + + +#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) +typedef struct __locale_struct * locale_t; +#define __DEFINED_locale_t +#endif + + +#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t) +typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t; +#define __DEFINED_sigset_t +#endif + + +#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec) +struct iovec { void *iov_base; size_t iov_len; }; +#define __DEFINED_struct_iovec +#endif + + +#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t) +typedef unsigned socklen_t; +#define __DEFINED_socklen_t +#endif + +#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t) +typedef unsigned short sa_family_t; +#define __DEFINED_sa_family_t +#endif + + +#undef _Addr +#undef _Int64 +#undef _Reg diff --git a/libc/include/wasm32-freestanding-musl/errno.h b/libc/include/wasm32-freestanding-musl/errno.h new file mode 100644 index 0000000000000000000000000000000000000000..e26c76e7541eb87036fc5d35b80e027aa900e147 --- /dev/null +++ b/libc/include/wasm32-freestanding-musl/errno.h @@ -0,0 +1,24 @@ +#ifndef _ERRNO_H +#define _ERRNO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef WASM_THREAD_MODEL_SINGLE +extern int errno; +#else +#ifdef __cplusplus +extern thread_local int errno; +#else +extern _Thread_local int errno; +#endif +#endif + +#define errno errno + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/std/build.zig b/std/build.zig index d4275212515d633b4c16627693a8ab275ef24b2b..363890bd4be3bdbda571db5eb50a84d1173ddaa4 100644 --- a/std/build.zig +++ b/std/build.zig @@ -877,6 +877,13 @@ pub const Target = union(enum) { }; } + pub fn getArch(self: Target) builtin.Arch { + switch (self) { + Target.Native => return builtin.arch, + Target.Cross => |t| return t.arch, + } + } + pub fn isDarwin(self: Target) bool { return switch (self.getOs()) { .ios, .macosx, .watchos, .tvos => true, @@ -891,6 +898,13 @@ pub const Target = union(enum) { }; } + pub fn isWasm(self: Target) bool { + return switch (self.getArch()) { + .wasm32, .wasm64 => true, + else => false, + }; + } + pub fn isFreeBSD(self: Target) bool { return switch (self.getOs()) { .freebsd => true, @@ -1080,7 +1094,11 @@ pub const LibExeObjStep = struct { self.out_filename = self.builder.fmt("{}.lib", self.name); }, else => { - self.out_filename = self.builder.fmt("lib{}.a", self.name); + if (self.target.isWasm()) { + self.out_filename = self.builder.fmt("{}.wasm", self.name); + } else { + self.out_filename = self.builder.fmt("lib{}.a", self.name); + } }, } self.out_lib_filename = self.out_filename; diff --git a/std/special/c.zig b/std/special/c.zig index 08789c920f2159ec231a519b2dbeca411308ab6d..9a05f6f22e08d478699c7e72dad40e5e38a77398 100644 --- a/std/special/c.zig +++ b/std/special/c.zig @@ -20,6 +20,12 @@ comptime { if (is_freestanding and is_wasm and builtin.link_libc) { @export("_start", wasm_start, .Strong); } + if (builtin.link_libc) { + @export("strcmp", strcmp, .Strong); + @export("strncmp", strncmp, .Strong); + @export("strerror", strerror, .Strong); + @export("strlen", strlen, .Strong); + } } extern fn main(argc: c_int, argv: [*][*]u8) c_int; @@ -27,6 +33,38 @@ extern fn wasm_start() void { _ = main(0, undefined); } +extern fn strcmp(s1: [*]const u8, s2: [*]const u8) c_int { + return std.cstr.cmp(s1, s2); +} + +extern fn strlen(s: [*]const u8) usize { + return std.mem.len(u8, s); +} + +extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int { + if (_n == 0) return 0; + var l = _l; + var r = _r; + var n = _n - 1; + while (l[0] != 0 and r[0] != 0 and n != 0 and l[0] == r[0]) { + l += 1; + r += 1; + n -= 1; + } + return c_int(l[0]) - c_int(r[0]); +} + +extern fn strerror(errnum: c_int) [*]const u8 { + return c"TODO strerror implementation"; +} + +test "strncmp" { + std.testing.expect(strncmp(c"a", c"b", 1) == -1); + std.testing.expect(strncmp(c"a", c"c", 1) == -2); + std.testing.expect(strncmp(c"b", c"a", 1) == 1); + std.testing.expect(strncmp(c"\xff", c"\x02", 1) == 253); +} + // Avoid dragging in the runtime safety mechanisms into this .o file, // unless we're trying to test this file. pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn { -- 2.54.0 From f9e7bd2682a83bad2b74686dd9b860fc2ce7ef8f Mon Sep 17 00:00:00 2001 From: tgschultz Date: Sun, 26 May 2019 21:22:45 +0000 Subject: [PATCH 54/84] std.meta/trait: def/definition => decl/declaration TypeInfo: defs/Definition => decls/Declarations --- doc/langref.html.in | 12 +- src/codegen.cpp | 12 +- src/ir.cpp | 176 ++++++++++++++--------------- std/fmt.zig | 18 +-- std/meta.zig | 44 ++++---- std/meta/trait.zig | 48 +------- test/stage1/behavior/type_info.zig | 16 +-- 7 files changed, 136 insertions(+), 190 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index d583e02b1b0a811dac1b1c418636d4b85b08318e..68f3926839cdd0ea3a51e87015940979dcdcf649 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7545,7 +7545,7 @@ pub const TypeInfo = union(TypeId) { pub const Struct = struct { layout: ContainerLayout, fields: []StructField, - defs: []Definition, + decls: []Declaration, }; pub const Optional = struct { @@ -7573,7 +7573,7 @@ pub const TypeInfo = union(TypeId) { layout: ContainerLayout, tag_type: type, fields: []EnumField, - defs: []Definition, + decls: []Declaration, }; pub const UnionField = struct { @@ -7586,7 +7586,7 @@ pub const TypeInfo = union(TypeId) { layout: ContainerLayout, tag_type: ?type, fields: []UnionField, - defs: []Definition, + decls: []Declaration, }; pub const CallingConvention = enum { @@ -7622,7 +7622,7 @@ pub const TypeInfo = union(TypeId) { child: type, }; - pub const Definition = struct { + pub const Declaration = struct { name: []const u8, is_pub: bool, data: Data, @@ -7630,9 +7630,9 @@ pub const TypeInfo = union(TypeId) { pub const Data = union(enum) { Type: type, Var: type, - Fn: FnDef, + Fn: FnDecl, - pub const FnDef = struct { + pub const FnDecl = struct { fn_type: type, inline_type: Inline, calling_convention: CallingConvention, diff --git a/src/codegen.cpp b/src/codegen.cpp index fc9cdfc9b8b1df3480f57837c15aad5cacf465a9..826a9463ac5ab769744c5b67107844c4415e27f3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7762,7 +7762,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " pub const Struct = struct {\n" " layout: ContainerLayout,\n" " fields: []StructField,\n" - " defs: []Definition,\n" + " decls: []Declaration,\n" " };\n" "\n" " pub const Optional = struct {\n" @@ -7790,7 +7790,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: type,\n" " fields: []EnumField,\n" - " defs: []Definition,\n" + " decls: []Declaration,\n" " };\n" "\n" " pub const UnionField = struct {\n" @@ -7803,7 +7803,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: ?type,\n" " fields: []UnionField,\n" - " defs: []Definition,\n" + " decls: []Declaration,\n" " };\n" "\n" " pub const CallingConvention = enum {\n" @@ -7839,7 +7839,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " child: type,\n" " };\n" "\n" - " pub const Definition = struct {\n" + " pub const Declaration = struct {\n" " name: []const u8,\n" " is_pub: bool,\n" " data: Data,\n" @@ -7847,9 +7847,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " pub const Data = union(enum) {\n" " Type: type,\n" " Var: type,\n" - " Fn: FnDef,\n" + " Fn: FnDecl,\n" "\n" - " pub const FnDef = struct {\n" + " pub const FnDecl = struct {\n" " fn_type: type,\n" " inline_type: Inline,\n" " calling_convention: CallingConvention,\n" diff --git a/src/ir.cpp b/src/ir.cpp index ba6f256b40135d512b231cd0aea40481a9084681..c4c3808545e4231a66968cc207961021362de24f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -18380,37 +18380,37 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig return var->const_value->data.x_type; } -static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, +static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr, ConstExprValue *out_val, ScopeDecls *decls_scope) { Error err; - ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); - if ((err = type_resolve(ira->codegen, type_info_definition_type, ResolveStatusSizeKnown))) + ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); + if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) return err; - ensure_field_index(type_info_definition_type, "name", 0); - ensure_field_index(type_info_definition_type, "is_pub", 1); - ensure_field_index(type_info_definition_type, "data", 2); + ensure_field_index(type_info_declaration_type, "name", 0); + ensure_field_index(type_info_declaration_type, "is_pub", 1); + ensure_field_index(type_info_declaration_type, "data", 2); - ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); - if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type))) + ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); + if ((err = ensure_complete_type(ira->codegen, type_info_declaration_data_type))) return err; - ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); - if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type))) + ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); + if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_type))) return err; - ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); - if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type))) + ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); + if ((err = ensure_complete_type(ira->codegen, type_info_fn_decl_inline_type))) return err; - // Loop through our definitions once to figure out how many definitions we will generate info for. + // Loop through our declarations once to figure out how many declarations we will generate info for. auto decl_it = decls_scope->decl_table.entry_iterator(); decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; - int definition_count = 0; + int declaration_count = 0; while ((curr_entry = decl_it.next()) != nullptr) { - // If the definition is unresolved, force it to be resolved again. + // If the declaration is unresolved, force it to be resolved again. if (curr_entry->value->resolution == TldResolutionUnresolved) { resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); if (curr_entry->value->resolution != TldResolutionOk) { @@ -18426,21 +18426,21 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, continue; } - definition_count += 1; + declaration_count += 1; } } - ConstExprValue *definition_array = create_const_vals(1); - definition_array->special = ConstValSpecialStatic; - definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); - definition_array->data.x_array.special = ConstArraySpecialNone; - definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count); - init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); + ConstExprValue *declaration_array = create_const_vals(1); + declaration_array->special = ConstValSpecialStatic; + declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count); + declaration_array->data.x_array.special = ConstArraySpecialNone; + declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); + init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); - // Loop through the definitions and generate info. + // Loop through the declarations and generate info. decl_it = decls_scope->decl_table.entry_iterator(); curr_entry = nullptr; - int definition_index = 0; + int declaration_index = 0; while ((curr_entry = decl_it.next()) != nullptr) { // Skip comptime blocks and test functions. if (curr_entry->value->id == TldIdCompTime) { @@ -18451,10 +18451,10 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, continue; } - ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index]; + ConstExprValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; - definition_val->special = ConstValSpecialStatic; - definition_val->type = type_info_definition_type; + declaration_val->special = ConstValSpecialStatic; + declaration_val->type = type_info_declaration_type; ConstExprValue *inner_fields = create_const_vals(3); ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); @@ -18463,9 +18463,9 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, inner_fields[1].type = ira->codegen->builtin_types.entry_bool; inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; inner_fields[2].special = ConstValSpecialStatic; - inner_fields[2].type = type_info_definition_data_type; + inner_fields[2].type = type_info_declaration_data_type; inner_fields[2].parent.id = ConstParentIdStruct; - inner_fields[2].parent.data.p_struct.struct_val = definition_val; + inner_fields[2].parent.data.p_struct.struct_val = declaration_val; inner_fields[2].parent.data.p_struct.field_index = 1; switch (curr_entry->value->id) { @@ -18476,7 +18476,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, return ErrorSemanticAnalyzeFail; if (var->const_value->type->id == ZigTypeIdMetaType) { - // We have a variable of type 'type', so it's actually a type definition. + // We have a variable of type 'type', so it's actually a type declaration. // 0: Data.Type: type bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); inner_fields[2].data.x_union.payload = var->const_value; @@ -18496,7 +18496,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, } case TldIdFn: { - // 2: Data.Fn: Data.FnDef + // 2: Data.Fn: Data.FnDecl bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; @@ -18509,68 +18509,68 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; - ConstExprValue *fn_def_val = create_const_vals(1); - fn_def_val->special = ConstValSpecialStatic; - fn_def_val->type = type_info_fn_def_type; - fn_def_val->parent.id = ConstParentIdUnion; - fn_def_val->parent.data.p_union.union_val = &inner_fields[2]; + ConstExprValue *fn_decl_val = create_const_vals(1); + fn_decl_val->special = ConstValSpecialStatic; + fn_decl_val->type = type_info_fn_decl_type; + fn_decl_val->parent.id = ConstParentIdUnion; + fn_decl_val->parent.data.p_union.union_val = &inner_fields[2]; - ConstExprValue *fn_def_fields = create_const_vals(9); - fn_def_val->data.x_struct.fields = fn_def_fields; + ConstExprValue *fn_decl_fields = create_const_vals(9); + fn_decl_val->data.x_struct.fields = fn_decl_fields; // fn_type: type - ensure_field_index(fn_def_val->type, "fn_type", 0); - fn_def_fields[0].special = ConstValSpecialStatic; - fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; - fn_def_fields[0].data.x_type = fn_entry->type_entry; - // inline_type: Data.FnDef.Inline - ensure_field_index(fn_def_val->type, "inline_type", 1); - fn_def_fields[1].special = ConstValSpecialStatic; - fn_def_fields[1].type = type_info_fn_def_inline_type; - bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); + ensure_field_index(fn_decl_val->type, "fn_type", 0); + fn_decl_fields[0].special = ConstValSpecialStatic; + fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type; + fn_decl_fields[0].data.x_type = fn_entry->type_entry; + // inline_type: Data.FnDecl.Inline + ensure_field_index(fn_decl_val->type, "inline_type", 1); + fn_decl_fields[1].special = ConstValSpecialStatic; + fn_decl_fields[1].type = type_info_fn_decl_inline_type; + bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline); // calling_convention: TypeInfo.CallingConvention - ensure_field_index(fn_def_val->type, "calling_convention", 2); - fn_def_fields[2].special = ConstValSpecialStatic; - fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); - bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); + ensure_field_index(fn_decl_val->type, "calling_convention", 2); + fn_decl_fields[2].special = ConstValSpecialStatic; + fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); + bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc); // is_var_args: bool - ensure_field_index(fn_def_val->type, "is_var_args", 3); + ensure_field_index(fn_decl_val->type, "is_var_args", 3); bool is_varargs = fn_node->is_var_args; - fn_def_fields[3].special = ConstValSpecialStatic; - fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; - fn_def_fields[3].data.x_bool = is_varargs; + fn_decl_fields[3].special = ConstValSpecialStatic; + fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[3].data.x_bool = is_varargs; // is_extern: bool - ensure_field_index(fn_def_val->type, "is_extern", 4); - fn_def_fields[4].special = ConstValSpecialStatic; - fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; - fn_def_fields[4].data.x_bool = fn_node->is_extern; + ensure_field_index(fn_decl_val->type, "is_extern", 4); + fn_decl_fields[4].special = ConstValSpecialStatic; + fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[4].data.x_bool = fn_node->is_extern; // is_export: bool - ensure_field_index(fn_def_val->type, "is_export", 5); - fn_def_fields[5].special = ConstValSpecialStatic; - fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; - fn_def_fields[5].data.x_bool = fn_node->is_export; + ensure_field_index(fn_decl_val->type, "is_export", 5); + fn_decl_fields[5].special = ConstValSpecialStatic; + fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[5].data.x_bool = fn_node->is_export; // lib_name: ?[]const u8 - ensure_field_index(fn_def_val->type, "lib_name", 6); - fn_def_fields[6].special = ConstValSpecialStatic; + ensure_field_index(fn_decl_val->type, "lib_name", 6); + fn_decl_fields[6].special = ConstValSpecialStatic; ZigType *u8_ptr = get_pointer_to_type_extra( ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); - fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); + fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) { - fn_def_fields[6].data.x_optional = create_const_vals(1); + fn_decl_fields[6].data.x_optional = create_const_vals(1); ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); - init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); + init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); } else { - fn_def_fields[6].data.x_optional = nullptr; + fn_decl_fields[6].data.x_optional = nullptr; } // return_type: type - ensure_field_index(fn_def_val->type, "return_type", 7); - fn_def_fields[7].special = ConstValSpecialStatic; - fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; - fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; + ensure_field_index(fn_decl_val->type, "return_type", 7); + fn_decl_fields[7].special = ConstValSpecialStatic; + fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type; + fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; // arg_names: [][] const u8 - ensure_field_index(fn_def_val->type, "arg_names", 8); + ensure_field_index(fn_decl_val->type, "arg_names", 8); size_t fn_arg_count = fn_entry->variable_list.length; ConstExprValue *fn_arg_name_array = create_const_vals(1); fn_arg_name_array->special = ConstValSpecialStatic; @@ -18579,7 +18579,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); - init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); + init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); @@ -18591,7 +18591,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; } - inner_fields[2].data.x_union.payload = fn_def_val; + inner_fields[2].data.x_union.payload = fn_decl_val; break; } case TldIdContainer: @@ -18615,11 +18615,11 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, zig_unreachable(); } - definition_val->data.x_struct.fields = inner_fields; - definition_index++; + declaration_val->data.x_struct.fields = inner_fields; + declaration_index++; } - assert(definition_index == definition_count); + assert(declaration_index == declaration_count); return ErrorNone; } @@ -18927,9 +18927,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr enum_field_val->parent.data.p_array.array_val = enum_field_array; enum_field_val->parent.data.p_array.elem_index = enum_field_index; } - // defs: []TypeInfo.Definition - ensure_field_index(result->type, "defs", 3); - if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3], + // decls: []TypeInfo.Declaration + ensure_field_index(result->type, "decls", 3); + if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], type_entry->data.enumeration.decls_scope))) { return err; @@ -19094,9 +19094,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr union_field_val->parent.data.p_array.array_val = union_field_array; union_field_val->parent.data.p_array.elem_index = union_field_index; } - // defs: []TypeInfo.Definition - ensure_field_index(result->type, "defs", 3); - if ((err = ir_make_type_info_defs(ira, source_instr, &fields[3], + // decls: []TypeInfo.Declaration + ensure_field_index(result->type, "decls", 3); + if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], type_entry->data.unionation.decls_scope))) { return err; @@ -19175,9 +19175,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr struct_field_val->parent.data.p_array.array_val = struct_field_array; struct_field_val->parent.data.p_array.elem_index = struct_field_index; } - // defs: []TypeInfo.Definition - ensure_field_index(result->type, "defs", 2); - if ((err = ir_make_type_info_defs(ira, source_instr, &fields[2], + // decls: []TypeInfo.Declaration + ensure_field_index(result->type, "decls", 2); + if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2], type_entry->data.structure.decls_scope))) { return err; diff --git a/std/fmt.zig b/std/fmt.zig index 74c36f7086fe30209131ad44b89281cb4b0d45f6..c663530866967776cbc95e36ba79af8e491e269b 100644 --- a/std/fmt.zig +++ b/std/fmt.zig @@ -145,23 +145,7 @@ pub fn formatType( return format(context, Errors, output, "promise@{x}", @ptrToInt(value)); }, builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => { - const has_cust_fmt = comptime cf: { - const info = @typeInfo(T); - const defs = switch (info) { - builtin.TypeId.Struct => |s| s.defs, - builtin.TypeId.Union => |u| u.defs, - builtin.TypeId.Enum => |e| e.defs, - else => unreachable, - }; - - for (defs) |def| { - if (mem.eql(u8, def.name, "format")) { - break :cf true; - } - } - break :cf false; - }; - if (has_cust_fmt) return value.format(fmt, context, Errors, output); + if (comptime std.meta.trait.hasFn("format")(T)) return value.format(fmt, context, Errors, output); try output(context, @typeName(T)); switch (comptime @typeId(T)) { diff --git a/std/meta.zig b/std/meta.zig index a8c7e4b415f23084001a581af9d3f2fdb4d1b710..297b55894ed720692cfaa86168d638e38ce1b259 100644 --- a/std/meta.zig +++ b/std/meta.zig @@ -160,16 +160,16 @@ test "std.meta.containerLayout" { testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern); } -pub fn definitions(comptime T: type) []TypeInfo.Definition { +pub fn declarations(comptime T: type) []TypeInfo.Declaration { return switch (@typeInfo(T)) { - TypeId.Struct => |info| info.defs, - TypeId.Enum => |info| info.defs, - TypeId.Union => |info| info.defs, + TypeId.Struct => |info| info.decls, + TypeId.Enum => |info| info.decls, + TypeId.Union => |info| info.decls, else => @compileError("Expected struct, enum or union type, found '" ++ @typeName(T) ++ "'"), }; } -test "std.meta.definitions" { +test "std.meta.declarations" { const E1 = enum { A, @@ -184,28 +184,28 @@ test "std.meta.definitions" { fn a() void {} }; - const defs = comptime [][]TypeInfo.Definition{ - definitions(E1), - definitions(S1), - definitions(U1), + const decls = comptime [][]TypeInfo.Declaration{ + declarations(E1), + declarations(S1), + declarations(U1), }; - inline for (defs) |def| { - testing.expect(def.len == 1); - testing.expect(comptime mem.eql(u8, def[0].name, "a")); + inline for (decls) |decl| { + testing.expect(decl.len == 1); + testing.expect(comptime mem.eql(u8, decl[0].name, "a")); } } -pub fn definitionInfo(comptime T: type, comptime def_name: []const u8) TypeInfo.Definition { - inline for (comptime definitions(T)) |def| { - if (comptime mem.eql(u8, def.name, def_name)) - return def; +pub fn declarationInfo(comptime T: type, comptime decl_name: []const u8) TypeInfo.Declaration { + inline for (comptime declarations(T)) |decl| { + if (comptime mem.eql(u8, decl.name, decl_name)) + return decl; } - @compileError("'" ++ @typeName(T) ++ "' has no definition '" ++ def_name ++ "'"); + @compileError("'" ++ @typeName(T) ++ "' has no declaration '" ++ decl_name ++ "'"); } -test "std.meta.definitionInfo" { +test "std.meta.declarationInfo" { const E1 = enum { A, @@ -220,10 +220,10 @@ test "std.meta.definitionInfo" { fn a() void {} }; - const infos = comptime []TypeInfo.Definition{ - definitionInfo(E1, "a"), - definitionInfo(S1, "a"), - definitionInfo(U1, "a"), + const infos = comptime []TypeInfo.Declaration{ + declarationInfo(E1, "a"), + declarationInfo(S1, "a"), + declarationInfo(U1, "a"), }; inline for (infos) |info| { diff --git a/std/meta/trait.zig b/std/meta/trait.zig index f77619ec3931890a5947bd728542695d02a6d5b7..db3e52fc3fdb4598d3526dfa91e1bc2821a6b5c2 100644 --- a/std/meta/trait.zig +++ b/std/meta/trait.zig @@ -55,53 +55,15 @@ test "std.meta.trait.multiTrait" { testing.expect(!isVector(u8)); } -/// -pub fn hasDef(comptime name: []const u8) TraitFn { - const Closure = struct { - pub fn trait(comptime T: type) bool { - const info = @typeInfo(T); - const defs = switch (info) { - builtin.TypeId.Struct => |s| s.defs, - builtin.TypeId.Union => |u| u.defs, - builtin.TypeId.Enum => |e| e.defs, - else => return false, - }; - - inline for (defs) |def| { - if (mem.eql(u8, def.name, name)) return def.is_pub; - } - - return false; - } - }; - return Closure.trait; -} - -test "std.meta.trait.hasDef" { - const TestStruct = struct { - pub const value = u8(16); - }; - - const TestStructFail = struct { - const value = u8(16); - }; - - testing.expect(hasDef("value")(TestStruct)); - testing.expect(!hasDef("value")(TestStructFail)); - testing.expect(!hasDef("value")(*TestStruct)); - testing.expect(!hasDef("value")(**TestStructFail)); - testing.expect(!hasDef("x")(TestStruct)); - testing.expect(!hasDef("value")(u8)); -} - /// pub fn hasFn(comptime name: []const u8) TraitFn { const Closure = struct { pub fn trait(comptime T: type) bool { - if (!comptime hasDef(name)(T)) return false; - const DefType = @typeOf(@field(T, name)); - const def_type_id = @typeId(DefType); - return def_type_id == builtin.TypeId.Fn; + if (!comptime isContainer(T)) return false; + if (!comptime @hasDecl(T, name)) return false; + const DeclType = @typeOf(@field(T, name)); + const decl_type_id = @typeId(DeclType); + return decl_type_id == builtin.TypeId.Fn; } }; return Closure.trait; diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index 2d088fa26138e499e84dbab36d25e5384ce11e9c..f05b02e7abd78a7c13e1bd4943819bcd586bd617 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -177,7 +177,7 @@ fn testEnum() void { expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos")); expect(os_info.Enum.fields[3].value == 3); expect(os_info.Enum.tag_type == u2); - expect(os_info.Enum.defs.len == 0); + expect(os_info.Enum.decls.len == 0); } test "type info: union info" { @@ -194,7 +194,7 @@ fn testUnion() void { expect(typeinfo_info.Union.fields[4].enum_field != null); expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4); expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int)); - expect(typeinfo_info.Union.defs.len == 21); + expect(typeinfo_info.Union.decls.len == 21); const TestNoTagUnion = union { Foo: void, @@ -232,12 +232,12 @@ fn testStruct() void { expect(struct_info.Struct.fields.len == 3); expect(struct_info.Struct.fields[1].offset == null); expect(struct_info.Struct.fields[2].field_type == *TestStruct); - expect(struct_info.Struct.defs.len == 2); - expect(struct_info.Struct.defs[0].is_pub); - expect(!struct_info.Struct.defs[0].data.Fn.is_extern); - expect(struct_info.Struct.defs[0].data.Fn.lib_name == null); - expect(struct_info.Struct.defs[0].data.Fn.return_type == void); - expect(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void); + expect(struct_info.Struct.decls.len == 2); + expect(struct_info.Struct.decls[0].is_pub); + expect(!struct_info.Struct.decls[0].data.Fn.is_extern); + expect(struct_info.Struct.decls[0].data.Fn.lib_name == null); + expect(struct_info.Struct.decls[0].data.Fn.return_type == void); + expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void); } const TestStruct = packed struct { -- 2.54.0 From 8eaf1387c712c62e96fa165ac3390c8f8f924daa Mon Sep 17 00:00:00 2001 From: tgschultz Date: Wed, 29 May 2019 10:23:21 -0500 Subject: [PATCH 55/84] Fix fmt.zig handling of slices of slices Discovered while calling testing.expectError on an error union with payload [][]const u8. Even though the payload was not going to be printed, the current format handling caused a compile error anyway because it couldn't be casted to []const u8. The new handling treats a []u8 as a string but otherwise treats the slice as a pointer. --- std/fmt.zig | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/std/fmt.zig b/std/fmt.zig index c663530866967776cbc95e36ba79af8e491e269b..be3e26b585909aa8b48d164a92e3f37056ac2e89 100644 --- a/std/fmt.zig +++ b/std/fmt.zig @@ -220,8 +220,10 @@ pub fn formatType( if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) { return formatText(value, fmt, context, Errors, output); } - const casted_value = ([]const u8)(value); - return output(context, casted_value); + if (ptr_info.child == u8) { + return formatText(value, fmt, context, Errors, output); + } + return format(context, Errors, output, "{}@{x}", @typeName(ptr_info.child), @ptrToInt(value.ptr)); }, builtin.TypeInfo.Pointer.Size.C => { return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)); @@ -1009,6 +1011,10 @@ test "fmt.format" { const value: []const u8 = "abc"; try testFmt("slice: abc\n", "slice: {}\n", value); } + { + const value = @intToPtr([*]const []const u8, 0xdeadbeef)[0..0]; + try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", value); + } { const value = @intToPtr(*i32, 0xdeadbeef); try testFmt("pointer: i32@deadbeef\n", "pointer: {}\n", value); -- 2.54.0 From 8ca294c430ecc4e878d9e5cfb178c20c07b83514 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 29 May 2019 23:45:28 -0400 Subject: [PATCH 56/84] update load dynamic library test for std lib changes --- std/dynamic_library.zig | 3 ++- test/standalone/load_dynamic_library/main.zig | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig index 79e325b81eec9c30ef2480e058786dda80648b52..341378801970212b5d90d0ab8f55eb26271dea0a 100644 --- a/std/dynamic_library.zig +++ b/std/dynamic_library.zig @@ -108,11 +108,12 @@ pub const LinuxDynLib = struct { const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC); errdefer os.close(fd); + // TODO remove this @intCast const size = @intCast(usize, (try os.fstat(fd)).size); const bytes = try os.mmap( null, - size, + mem.alignForward(size, mem.page_size), os.PROT_READ | os.PROT_EXEC, os.MAP_PRIVATE, fd, diff --git a/test/standalone/load_dynamic_library/main.zig b/test/standalone/load_dynamic_library/main.zig index 4c45ad6fdef122ca7b80d43f22f00e4bccdeecde..a222f5b31539cc5c686da2bb3006670847b4f7fa 100644 --- a/test/standalone/load_dynamic_library/main.zig +++ b/test/standalone/load_dynamic_library/main.zig @@ -1,12 +1,12 @@ const std = @import("std"); pub fn main() !void { - const args = try std.os.argsAlloc(std.debug.global_allocator); - defer std.os.argsFree(std.debug.global_allocator, args); + const args = try std.process.argsAlloc(std.debug.global_allocator); + defer std.process.argsFree(std.debug.global_allocator, args); const dynlib_name = args[1]; - var lib = try std.DynLib.open(std.debug.global_allocator, dynlib_name); + var lib = try std.DynLib.open(dynlib_name); defer lib.close(); const addr = lib.lookup("add") orelse return error.SymbolNotFound; -- 2.54.0 From 477ee9c8b992612c952dfd13c4f951d4e04adb22 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 30 May 2019 16:28:33 +0200 Subject: [PATCH 57/84] Fix some syscalls on arm64 --- std/c/linux.zig | 2 +- std/event/loop.zig | 2 +- std/os.zig | 2 +- std/os/bits/linux.zig | 12 +++++------ std/os/linux.zig | 46 +++++++++++++++++++++++++------------------ 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/std/c/linux.zig b/std/c/linux.zig index 50c4b185d852490745e008c91de8211865604e43..9689f61082a6429a33fb8b6c000cc2f760993ea7 100644 --- a/std/c/linux.zig +++ b/std/c/linux.zig @@ -7,7 +7,7 @@ pub const _errno = __errno_location; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int; pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int; pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int; -pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: *epoll_event) c_int; +pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: ?*epoll_event) c_int; pub extern "c" fn epoll_create1(flags: c_uint) c_int; pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int; pub extern "c" fn epoll_pwait( diff --git a/std/event/loop.zig b/std/event/loop.zig index 61732d78f56016bbb311542da0400b19e83314a7..6cddb50ef5e8e76ea7a93489c7cc808a0934eaee 100644 --- a/std/event/loop.zig +++ b/std/event/loop.zig @@ -421,7 +421,7 @@ pub const Loop = struct { } pub fn linuxRemoveFd(self: *Loop, fd: i32) void { - os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {}; + os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, null) catch {}; self.finishOneEvent(); } diff --git a/std/os.zig b/std/os.zig index ee476258ae0739af15b7c9a84b5fe54bca0e6db0..07c9f880c7b222fc451ff3300eb30e6d13cbc456 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1509,7 +1509,7 @@ pub const EpollCtlError = error{ Unexpected, }; -pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: *epoll_event) EpollCtlError!void { +pub fn epoll_ctl(epfd: i32, op: u32, fd: i32, event: ?*epoll_event) EpollCtlError!void { const rc = system.epoll_ctl(epfd, op, fd, event); switch (errno(rc)) { 0 => return, diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig index 4a1734a145edcdf1c1dea9a0f97ac5bf75bc0992..ff541077d971c84061007cdd227ec5e880f1c7fc 100644 --- a/std/os/bits/linux.zig +++ b/std/os/bits/linux.zig @@ -762,16 +762,16 @@ pub const epoll_data = extern union { // On x86_64 the structure is packed so that it matches the definition of its // 32bit counterpart -pub const epoll_event = if (builtin.arch != .x86_64) - extern struct { +pub const epoll_event = switch (builtin.arch) { + .x86_64 => packed struct { events: u32, data: epoll_data, - } -else - packed struct { + }, + else => extern struct { events: u32, data: epoll_data, - }; + }, +}; pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; pub const _LINUX_CAPABILITY_U32S_1 = 1; diff --git a/std/os/linux.zig b/std/os/linux.zig index aee34b10a2ab3fd3c4a4b59847173bf0c2933406..61a13ff164ecb83f1c7a669c726f13f2513e053e 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -131,7 +131,7 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz if (@hasDecl(@This(), "SYS_readlink")) { return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); } else { - return syscall4(SYS_readlinkat, AT_FDCWD, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); + return syscall4(SYS_readlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len); } } @@ -145,7 +145,7 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize { if (@hasDecl(@This(), "SYS_mkdir")) { return syscall2(SYS_mkdir, @ptrToInt(path), mode); } else { - return syscall3(SYS_mkdirat, AT_FDCWD, @ptrToInt(path), mode); + return syscall3(SYS_mkdirat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode); } } @@ -206,7 +206,7 @@ pub fn rmdir(path: [*]const u8) usize { if (@hasDecl(@This(), "SYS_rmdir")) { return syscall1(SYS_rmdir, @ptrToInt(path)); } else { - return syscall3(SYS_unlinkat, AT_FDCWD, @ptrToInt(path), AT_REMOVEDIR); + return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR); } } @@ -215,7 +215,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { if (@hasDecl(@This(), "SYS_symlink")) { return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new)); } else { - return syscall3(SYS_symlinkat, @ptrToInt(existing), AT_FDCWD, @ptrToInt(new)); + return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new)); } } @@ -231,12 +231,16 @@ pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn access(path: [*]const u8, mode: u32) usize { - return syscall2(SYS_access, @ptrToInt(path), mode); + if (@hasDecl(@This(), "SYS_access")) { + return syscall2(SYS_access, @ptrToInt(path), mode); + } else { + return syscall4(SYS_faccessat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode, 0); + } } // TODO https://github.com/ziglang/zig/issues/265 -pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32) usize { - return syscall3(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode); +pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize { + return syscall4(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode, flags); } pub fn pipe(fd: *[2]i32) usize { @@ -264,9 +268,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize { if (@hasDecl(@This(), "SYS_rename")) { return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new)); } else if (@hasDecl(@This(), "SYS_renameat")) { - return syscall4(SYS_renameat, AT_FDCWD, @ptrToInt(old), AT_FDCWD, @ptrToInt(new)); + return syscall4(SYS_renameat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new)); } else { - return syscall5(SYS_renameat2, AT_FDCWD, @ptrToInt(old), AT_FDCWD, @ptrToInt(new), 0); + return syscall5(SYS_renameat2, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new), 0); } } @@ -305,7 +309,17 @@ pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const // TODO https://github.com/ziglang/zig/issues/265 pub fn open(path: [*]const u8, flags: u32, perm: usize) usize { - return syscall3(SYS_open, @ptrToInt(path), flags, perm); + if (@hasDecl(@This(), "SYS_open")) { + return syscall3(SYS_open, @ptrToInt(path), flags, perm); + } else { + return syscall4( + SYS_openat, + @bitCast(usize, isize(AT_FDCWD)), + @ptrToInt(path), + flags, + perm, + ); + } } // TODO https://github.com/ziglang/zig/issues/265 @@ -373,7 +387,7 @@ pub fn unlink(path: [*]const u8) usize { if (@hasDecl(@This(), "SYS_unlink")) { return syscall1(SYS_unlink, @ptrToInt(path)); } else { - return syscall3(SYS_unlinkat, AT_FDCWD, @ptrToInt(path), 0); + return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), 0); } } @@ -759,18 +773,12 @@ pub fn epoll_create1(flags: usize) usize { return syscall1(SYS_epoll_create1, flags); } -pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize { +pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: ?*epoll_event) usize { return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev)); } pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize { - return syscall4( - SYS_epoll_wait, - @bitCast(usize, isize(epoll_fd)), - @ptrToInt(events), - maxevents, - @bitCast(usize, isize(timeout)), - ); + return epoll_pwait(epoll_fd, events, maxevents, timeout, null); } pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize { -- 2.54.0 From 51fc375b0d17f50bb6e0a542e9eebfff1534c581 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 30 May 2019 17:05:39 +0200 Subject: [PATCH 58/84] Correct flag definitions for arm64 --- std/os/bits/linux/arm64.zig | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/std/os/bits/linux/arm64.zig b/std/os/bits/linux/arm64.zig index 8966df30d2d7b5c1f35aa948a2162b4b1c2d7d88..527b78bbcd7933ac6937e1bfd1b2859bf2936d27 100644 --- a/std/os/bits/linux/arm64.zig +++ b/std/os/bits/linux/arm64.zig @@ -299,16 +299,16 @@ pub const O_NONBLOCK = 0o4000; pub const O_DSYNC = 0o10000; pub const O_SYNC = 0o4010000; pub const O_RSYNC = 0o4010000; -pub const O_DIRECTORY = 0o200000; -pub const O_NOFOLLOW = 0o400000; +pub const O_DIRECTORY = 0o40000; +pub const O_NOFOLLOW = 0o100000; pub const O_CLOEXEC = 0o2000000; pub const O_ASYNC = 0o20000; -pub const O_DIRECT = 0o40000; -pub const O_LARGEFILE = 0; +pub const O_DIRECT = 0o200000; +pub const O_LARGEFILE = 0o400000; pub const O_NOATIME = 0o1000000; pub const O_PATH = 0o10000000; -pub const O_TMPFILE = 0o20200000; +pub const O_TMPFILE = 0o20040000; pub const O_NDELAY = O_NONBLOCK; pub const F_DUPFD = 0; -- 2.54.0 From 7878f9660fcb8fa64fda0b2b67320fe9ddc2727b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 May 2019 12:07:55 -0400 Subject: [PATCH 59/84] dep tokenizer: run zig fmt and move exports to canonical location --- src-self-hosted/dep_tokenizer.zig | 117 ++++-------------------------- src-self-hosted/stage1.zig | 60 ++++++++++++++- 2 files changed, 75 insertions(+), 102 deletions(-) diff --git a/src-self-hosted/dep_tokenizer.zig b/src-self-hosted/dep_tokenizer.zig index 9ce965fff765df002ec773a205f68d8345dee989..0dde6da71c55a26afa643d747e21e02325c8b407 100644 --- a/src-self-hosted/dep_tokenizer.zig +++ b/src-self-hosted/dep_tokenizer.zig @@ -359,63 +359,6 @@ pub const Tokenizer = struct { }; }; -export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { - const t = std.heap.c_allocator.create(Tokenizer) catch @panic("failed to create .d tokenizer"); - t.* = Tokenizer.init(std.heap.c_allocator, input[0..len]); - return stage2_DepTokenizer{ - .handle = t, - }; -} - -export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { - self.handle.deinit(); -} - -export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { - const otoken = self.handle.next() catch { - const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); - return stage2_DepNextResult{ - .type_id = .error_, - .textz = textz.toSlice().ptr, - }; - }; - const token = otoken orelse { - return stage2_DepNextResult{ - .type_id = .null_, - .textz = undefined, - }; - }; - const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); - return stage2_DepNextResult{ - .type_id = switch (token.id) { - .target => stage2_DepNextResult.TypeId.target, - .prereq => stage2_DepNextResult.TypeId.prereq, - }, - .textz = textz.toSlice().ptr, - }; -} - -export const stage2_DepTokenizer = extern struct { - handle: *Tokenizer, -}; - -export const stage2_DepNextResult = extern struct { - type_id: TypeId, - - // when type_id == error --> error text - // when type_id == null --> undefined - // when type_id == target --> target pathname - // when type_id == prereq --> prereq pathname - textz: [*]const u8, - - export const TypeId = extern enum { - error_, - null_, - target, - prereq, - }; -}; - test "empty file" { try depTokenizer("", ""); } @@ -469,78 +412,54 @@ test "empty target linefeeds" { const expect = "target = {foo.o}"; try depTokenizer( \\foo.o: - , - expect - ); + , expect); try depTokenizer( \\foo.o: \\ - , - expect - ); + , expect); try depTokenizer( \\foo.o: - , - expect - ); + , expect); try depTokenizer( \\foo.o: \\ - , - expect - ); + , expect); } test "empty target linefeeds + continuations" { const expect = "target = {foo.o}"; try depTokenizer( \\foo.o:\ - , - expect - ); + , expect); try depTokenizer( \\foo.o:\ \\ - , - expect - ); + , expect); try depTokenizer( \\foo.o:\ - , - expect - ); + , expect); try depTokenizer( \\foo.o:\ \\ - , - expect - ); + , expect); } test "empty target linefeeds + hspace + continuations" { const expect = "target = {foo.o}"; try depTokenizer( \\foo.o: \ - , - expect - ); + , expect); try depTokenizer( \\foo.o: \ \\ - , - expect - ); + , expect); try depTokenizer( \\foo.o: \ - , - expect - ); + , expect); try depTokenizer( \\foo.o: \ \\ - , - expect - ); + , expect); } test "prereq" { @@ -572,15 +491,11 @@ test "prereq continuation" { try depTokenizer( \\foo.o: foo.h\ \\bar.h - , - expect - ); + , expect); try depTokenizer( \\foo.o: foo.h\ \\bar.h - , - expect - ); + , expect); } test "multiple prereqs" { @@ -907,14 +822,14 @@ test "error target - continuation expecting end-of-line" { \\target = {foo.o} \\ERROR: illegal char 'x' at position 8: continuation expecting end-of-line ); - try depTokenizer("foo.o: \\ x", + try depTokenizer("foo.o: \\\x0dx", \\target = {foo.o} \\ERROR: illegal char 'x' at position 9: continuation expecting end-of-line ); } test "error prereq - continuation expecting end-of-line" { - try depTokenizer("foo.o: foo.h\\ x", + try depTokenizer("foo.o: foo.h\\\x0dx", \\target = {foo.o} \\ERROR: illegal char 'x' at position 14: continuation expecting end-of-line ); diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig index b5beb02f10fc412c24d138dd129be0aa49eb04d0..bc1a746154cc46f5842a571c6d5d0f84d280f18a 100644 --- a/src-self-hosted/stage1.zig +++ b/src-self-hosted/stage1.zig @@ -15,13 +15,14 @@ const self_hosted_main = @import("main.zig"); const Args = arg.Args; const Flag = arg.Flag; const errmsg = @import("errmsg.zig"); +const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer; var stderr_file: fs.File = undefined; var stderr: *io.OutStream(fs.File.WriteError) = undefined; var stdout: *io.OutStream(fs.File.WriteError) = undefined; comptime { - _ = @import("dep_tokenizer.zig"); + _ = @import("dep_tokenizer.zig"); } // ABI warning @@ -397,3 +398,60 @@ fn printErrMsgToFile( try stream.writeByteNTimes('~', last_token.end - first_token.start); try stream.write("\n"); } + +export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer { + const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer"); + t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]); + return stage2_DepTokenizer{ + .handle = t, + }; +} + +export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void { + self.handle.deinit(); +} + +export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult { + const otoken = self.handle.next() catch { + const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text"); + return stage2_DepNextResult{ + .type_id = .error_, + .textz = textz.toSlice().ptr, + }; + }; + const token = otoken orelse { + return stage2_DepNextResult{ + .type_id = .null_, + .textz = undefined, + }; + }; + const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text"); + return stage2_DepNextResult{ + .type_id = switch (token.id) { + .target => stage2_DepNextResult.TypeId.target, + .prereq => stage2_DepNextResult.TypeId.prereq, + }, + .textz = textz.toSlice().ptr, + }; +} + +export const stage2_DepTokenizer = extern struct { + handle: *DepTokenizer, +}; + +export const stage2_DepNextResult = extern struct { + type_id: TypeId, + + // when type_id == error --> error text + // when type_id == null --> undefined + // when type_id == target --> target pathname + // when type_id == prereq --> prereq pathname + textz: [*]const u8, + + export const TypeId = extern enum { + error_, + null_, + target, + prereq, + }; +}; -- 2.54.0 From 78f32259daa79aaced1c49bcdace936121a2ccc5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 May 2019 15:35:30 -0400 Subject: [PATCH 60/84] default struct field initialization expressions closes #485 --- doc/langref.html.in | 22 +++++++++++++++++++++ src/all_types.hpp | 1 + src/analyze.cpp | 8 +------- src/analyze.hpp | 1 + src/ir.cpp | 35 +++++++++++++++++++++++++++++---- test/compile_errors.zig | 27 ++++++++++++++----------- test/stage1/behavior/struct.zig | 18 +++++++++++++++++ 7 files changed, 89 insertions(+), 23 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 68f3926839cdd0ea3a51e87015940979dcdcf649..622a3aeb602ad50fb5cc2c697d188229d0577e5e 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2263,6 +2263,28 @@ test "linked list" { } {#code_end#} + {#header_open|Default Field Values#} +

      + Each struct field may have an expression indicating the default field value. Such expressions + are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression: +

      + {#code_begin|test#} +const Foo = struct { + a: i32 = 1234, + b: i32, +}; + +test "default struct initialization fields" { + const x = Foo{ + .b = 5, + }; + if (x.a + x.b != 1239) { + @compileError("it's even comptime known!"); + } +} + {#code_end#} + {#header_close#} + {#header_open|extern struct#}

      An {#syntax#}extern struct{#endsyntax#} has in-memory layout guaranteed to match the C ABI for the target.

      diff --git a/src/all_types.hpp b/src/all_types.hpp index 4bb76ff64f2a4a8cf19d2d35c4d811a3be818af7..2a6bb1feb51928e6f4db0888b65c04d256a9240a 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1069,6 +1069,7 @@ struct TypeStructField { size_t gen_index; size_t offset; // byte offset from beginning of struct AstNode *decl_node; + ConstExprValue *init_val; // null and then memoized uint32_t bit_offset_in_host; // offset from the memory at gen_index uint32_t host_int_bytes; // size of host integer }; diff --git a/src/analyze.cpp b/src/analyze.cpp index 3769ae47c2850668da756450e1dc96438e25a7a4..a62c24460e1f2a3aa33ea398fd9342627c0a99bf 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -965,9 +965,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind return entry; } -static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, - Buf *type_name) -{ +ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name) { size_t backward_branch_count = 0; size_t backward_branch_quota = default_backward_branch_quota; return ir_eval_const_value(g, scope, node, type_entry, @@ -2189,10 +2187,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { type_struct_field->src_index = i; type_struct_field->gen_index = SIZE_MAX; - if (field_node->data.struct_field.value != nullptr) { - add_node_error(g, field_node->data.struct_field.value, - buf_sprintf("enums, not structs, support field assignment")); - } if (field_type->id == ZigTypeIdOpaque) { add_node_error(g, field_node->data.struct_field.type, buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs")); diff --git a/src/analyze.hpp b/src/analyze.hpp index d89bb9112615f0f9a6f88a4b46ef27ed790ea020..57f10723553228702334c5a6160d698c46d7b583 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -251,5 +251,6 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa void src_assert(bool ok, AstNode *source_node); bool is_container(ZigType *type_entry); +ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, ZigType *type_entry, Buf *type_name); #endif diff --git a/src/ir.cpp b/src/ir.cpp index c4c3808545e4231a66968cc207961021362de24f..fb9e7b51c7b977709069284571b54ae8e4a4ad35 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17887,10 +17887,37 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc bool any_missing = false; for (size_t i = 0; i < actual_field_count; i += 1) { - if (!field_assign_nodes[i]) { - ir_add_error_node(ira, instruction->source_node, - buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); - any_missing = true; + if (field_assign_nodes[i]) continue; + + // look for a default field value + TypeStructField *field = &container_type->data.structure.fields[i]; + if (field->init_val == nullptr) { + // it's not memoized. time to go analyze it + assert(field->decl_node->type == NodeTypeStructField); + AstNode *init_node = field->decl_node->data.struct_field.value; + if (init_node == nullptr) { + ir_add_error_node(ira, instruction->source_node, + buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); + any_missing = true; + continue; + } + // scope is not the scope of the struct init, it's the scope of the struct type decl + Scope *analyze_scope = &get_container_scope(container_type)->base; + // memoize it + field->init_val = analyze_const_value(ira->codegen, analyze_scope, init_node, + field->type_entry, nullptr); + } + if (type_is_invalid(field->init_val->type)) + return ira->codegen->invalid_instruction; + + IrInstruction *runtime_inst = ir_const(ira, instruction, field->init_val->type); + copy_const_val(&runtime_inst->value, field->init_val, true); + + new_fields[i].value = runtime_inst; + new_fields[i].type_struct_field = field; + + if (const_val.special == ConstValSpecialStatic) { + copy_const_val(&const_val.data.x_struct.fields[i], field->init_val, true); } } if (any_missing) diff --git a/test/compile_errors.zig b/test/compile_errors.zig index fbecacb94b81123bdb35a5f1da760cdffc81713f..7ee58965683ee9b719e2727affef89a1076b6d18 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,21 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "compile error in struct init expression", + \\const Foo = struct { + \\ a: i32 = crap, + \\ b: i32, + \\}; + \\export fn entry() void { + \\ var x = Foo{ + \\ .b = 5, + \\ }; + \\} + , + "tmp.zig:2:14: error: use of undeclared identifier 'crap'", + ); + cases.add( "undefined as field type is rejected", \\const Foo = struct { @@ -5484,18 +5499,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:10:31: error: expected type 'u2', found 'u3'", ); - cases.add( - "struct fields with value assignments", - \\const MultipleChoice = struct { - \\ A: i32 = 20, - \\}; - \\export fn entry() void { - \\ var x: MultipleChoice = undefined; - \\} - , - "tmp.zig:2:14: error: enums, not structs, support field assignment", - ); - cases.add( "union fields with value assignments", \\const MultipleChoice = union { diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index 7a84fcc763c5657224c6f780974eb1398ada35b2..3c1db4989c0489725ecb3dc87e85726f9586acf5 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -560,3 +560,21 @@ test "use within struct scope" { }; expectEqual(i32(42), S.inner()); } + +test "default struct initialization fields" { + const S = struct { + a: i32 = 1234, + b: i32, + }; + const x = S{ + .b = 5, + }; + if (x.a + x.b != 1239) { + @compileError("it should be comptime known"); + } + var five: i32 = 5; + const y = S{ + .b = five, + }; + expectEqual(1239, x.a + x.b); +} -- 2.54.0 From 6d73e5de058ea421a98a53ae6c0844860715cc01 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Thu, 30 May 2019 19:38:26 -0700 Subject: [PATCH 61/84] doc: recommend optional pointers for nullptrs instead of allowzero --- doc/langref.html.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 622a3aeb602ad50fb5cc2c697d188229d0577e5e..a98705afd5a66cf984d6acb099683546664048fe 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2026,9 +2026,9 @@ fn foo(bytes: []u8) u32 { {#header_open|allowzero#}

      This pointer attribute allows a pointer to have address zero. This is only ever needed on the - freestanding OS target, where the address zero is mappable. In this code example, if the pointer - did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a - {#link|Pointer Cast Invalid Null#} panic: + freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use + {#link|Optional Pointers#} instead. In this code example, if the pointer did not have the + {#syntax#}allowzero{#endsyntax#} attribute, this would be a {#link|Pointer Cast Invalid Null#} panic:

      {#code_begin|test|allowzero#} const std = @import("std"); -- 2.54.0 From 4b30e40a9199accee765e759bbcae133298fa54a Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 29 May 2019 09:44:53 +0200 Subject: [PATCH 62/84] Remove length restriction in mmap wrapper --- std/os.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/std/os.zig b/std/os.zig index 07c9f880c7b222fc451ff3300eb30e6d13cbc456..56a1c13dcf44a78c47f5d3e78f3f2e99b88e3399 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1955,7 +1955,6 @@ pub fn mmap( fd: fd_t, offset: isize, ) MMapError![]align(mem.page_size) u8 { - assert(mem.isAligned(length, mem.page_size)); const err = if (builtin.link_libc) blk: { const rc = std.c.mmap(ptr, length, prot, flags, fd, offset); if (rc != MAP_FAILED) return @ptrCast([*]align(mem.page_size) u8, @alignCast(mem.page_size, rc))[0..length]; -- 2.54.0 From 46cbed621b287d339a97e77e8e1bfd5090bd247c Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 29 May 2019 10:30:30 +0200 Subject: [PATCH 63/84] Move dl_iterate_phdr to os.zig --- std/os.zig | 66 +++++++++++++++++++++++++++++++++++++++++ std/os/bits/freebsd.zig | 7 +++++ std/os/bits/netbsd.zig | 7 +++++ std/os/linux/test.zig | 39 ------------------------ std/os/test.zig | 50 +++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 39 deletions(-) diff --git a/std/os.zig b/std/os.zig index 56a1c13dcf44a78c47f5d3e78f3f2e99b88e3399..cc440250318a3e3e76f82e04bec275eafb39e2ec 100644 --- a/std/os.zig +++ b/std/os.zig @@ -19,6 +19,8 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const math = std.math; const mem = std.mem; +const elf = std.elf; +const dl = @import("dynamic_library.zig"); const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES; comptime { @@ -2367,6 +2369,70 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void { } } +pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize { + // This is implemented only for systems using ELF executables + if (windows.is_the_target or builtin.os == .uefi or wasi.is_the_target or darwin.is_the_target) + @compileError("dl_iterate_phdr is not available for this target"); + + if (builtin.link_libc) { + return system.dl_iterate_phdr( + @ptrCast(std.c.dl_iterate_phdr_callback, callback), + @ptrCast(?*c_void, data), + ); + } + + const elf_base = std.process.getBaseAddress(); + const ehdr = @intToPtr(*elf.Ehdr, elf_base); + // Make sure the base address points to an ELF image + assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF")); + const n_phdr = ehdr.e_phnum; + const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr]; + + var it = dl.linkmap_iterator(phdrs) catch unreachable; + + // The executable has no dynamic link segment, create a single entry for + // the whole ELF image + if (it.end()) { + var info = dl_phdr_info{ + .dlpi_addr = elf_base, + .dlpi_name = c"/proc/self/exe", + .dlpi_phdr = phdrs.ptr, + .dlpi_phnum = ehdr.e_phnum, + }; + + return callback(&info, @sizeOf(dl_phdr_info), data); + } + + // Last return value from the callback function + var last_r: isize = 0; + while (it.next()) |entry| { + var dlpi_phdr: [*]elf.Phdr = undefined; + var dlpi_phnum: u16 = undefined; + + if (entry.l_addr != 0) { + const elf_header = @intToPtr(*elf.Ehdr, entry.l_addr); + dlpi_phdr = @intToPtr([*]elf.Phdr, entry.l_addr + elf_header.e_phoff); + dlpi_phnum = elf_header.e_phnum; + } else { + // This is the running ELF image + dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff); + dlpi_phnum = ehdr.e_phnum; + } + + var info = dl_phdr_info{ + .dlpi_addr = entry.l_addr, + .dlpi_name = entry.l_name, + .dlpi_phdr = dlpi_phdr, + .dlpi_phnum = dlpi_phnum, + }; + + last_r = callback(&info, @sizeOf(dl_phdr_info), data); + if (last_r != 0) break; + } + + return last_r; +} + pub const ClockGetTimeError = error{ UnsupportedClock, Unexpected, diff --git a/std/os/bits/freebsd.zig b/std/os/bits/freebsd.zig index 3fc019f9c16eba57ae5125c37d6f95982aed082d..c73887d6483dadc89d425ca87135a3a3ffd691a8 100644 --- a/std/os/bits/freebsd.zig +++ b/std/os/bits/freebsd.zig @@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct { __align: c_long, }; +pub const dl_phdr_info = extern struct { + dlpi_addr: usize, + dlpi_name: ?[*]const u8, + dlpi_phdr: [*]std.elf.Phdr, + dlpi_phnum: u16, +}; + pub const msghdr = extern struct { /// optional address msg_name: ?*sockaddr, diff --git a/std/os/bits/netbsd.zig b/std/os/bits/netbsd.zig index e7a0f6ea5299e68815f130921e591b5df2cdaa1a..d83ea82b062cd7166bb1d64ce4ab57b5b8ca3ce7 100644 --- a/std/os/bits/netbsd.zig +++ b/std/os/bits/netbsd.zig @@ -20,6 +20,13 @@ pub const pthread_attr_t = extern struct { pta_private: *c_void, }; +pub const dl_phdr_info = extern struct { + dlpi_addr: usize, + dlpi_name: ?[*]const u8, + dlpi_phdr: [*]std.elf.Phdr, + dlpi_phnum: u16, +}; + pub const msghdr = extern struct { /// optional address msg_name: ?*sockaddr, diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig index c78b071c746b3eabdc2902fdcfee72ae6b36aece..637308638a8565e25f78c8cedfbe08b8f0ecf336 100644 --- a/std/os/linux/test.zig +++ b/std/os/linux/test.zig @@ -44,42 +44,3 @@ test "timer" { // TODO implicit cast from *[N]T to [*]T err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); } - -export fn iter_fn(info: *linux.dl_phdr_info, size: usize, data: ?*usize) i32 { - var counter = data.?; - // Count how many libraries are loaded - counter.* += usize(1); - - // The image should contain at least a PT_LOAD segment - if (info.dlpi_phnum < 1) return -1; - - // Quick & dirty validation of the phdr pointers, make sure we're not - // pointing to some random gibberish - var i: usize = 0; - var found_load = false; - while (i < info.dlpi_phnum) : (i += 1) { - const phdr = info.dlpi_phdr[i]; - - if (phdr.p_type != elf.PT_LOAD) continue; - - // Find the ELF header - const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset); - // Validate the magic - if (!mem.eql(u8, elf_header.e_ident[0..], "\x7fELF")) return -1; - // Consistency check - if (elf_header.e_phnum != info.dlpi_phnum) return -1; - - found_load = true; - break; - } - - if (!found_load) return -1; - - return 42; -} - -test "dl_iterate_phdr" { - var counter: usize = 0; - expect(linux.dl_iterate_phdr(usize, iter_fn, &counter) != 0); - expect(counter != 0); -} diff --git a/std/os/test.zig b/std/os/test.zig index dfcd25c4bb26fe4b09430f3f1a88456398bcca4b..a821c5dd9fe2acd9e1fbdbcfc7b63a72137c0c0a 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -5,6 +5,7 @@ const expect = std.testing.expect; const io = std.io; const fs = std.fs; const mem = std.mem; +const elf = std.elf; const File = std.fs.File; const Thread = std.Thread; @@ -160,3 +161,52 @@ test "sigaltstack" { st.ss_size = 1; testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null)); } + +// If the type is not available use void to avoid erroring out when `iter_fn` is +// analyzed +const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void; + +export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 { + if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) + return 0; + + var counter = data.?; + // Count how many libraries are loaded + counter.* += usize(1); + + // The image should contain at least a PT_LOAD segment + if (info.dlpi_phnum < 1) return -1; + + // Quick & dirty validation of the phdr pointers, make sure we're not + // pointing to some random gibberish + var i: usize = 0; + var found_load = false; + while (i < info.dlpi_phnum) : (i += 1) { + const phdr = info.dlpi_phdr[i]; + + if (phdr.p_type != elf.PT_LOAD) continue; + + // Find the ELF header + const elf_header = @intToPtr(*elf.Ehdr, phdr.p_vaddr - phdr.p_offset); + // Validate the magic + if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return -1; + // Consistency check + if (elf_header.e_phnum != info.dlpi_phnum) return -1; + + found_load = true; + break; + } + + if (!found_load) return -1; + + return 42; +} + +test "dl_iterate_phdr" { + if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx) + return error.SkipZigTest; + + var counter: usize = 0; + expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0); + expect(counter != 0); +} -- 2.54.0 From 3eca5a42e650878922437a854a352300052c878a Mon Sep 17 00:00:00 2001 From: tgschultz Date: Sat, 1 Jun 2019 12:25:57 +0000 Subject: [PATCH 64/84] fixed Deserializer.alignToByte() and added test coverage --- std/io.zig | 2 +- std/io/test.zig | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/std/io.zig b/std/io.zig index 258961fdfce3b2be8c834e0b16f2ba47db352ae7..de33d9562672b243c25ac2e364ae94cde7b47c06 100644 --- a/std/io.zig +++ b/std/io.zig @@ -1131,7 +1131,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing, } pub fn alignToByte(self: *Self) void { - if (!is_packed) return; + if (packing == .Byte) return; self.in_stream.alignToByte(); } diff --git a/std/io/test.zig b/std/io/test.zig index fc3b0f89025f26370cabd7ebabe4f69a57124407..bd0a0a902a732ee1b7d24e74036ee6dd00e58a1c 100644 --- a/std/io/test.zig +++ b/std/io/test.zig @@ -417,6 +417,7 @@ fn testIntSerializerDeserializerInfNaN( const nan_check_f16 = try deserializer.deserialize(f16); const inf_check_f16 = try deserializer.deserialize(f16); const nan_check_f32 = try deserializer.deserialize(f32); + deserializer.alignToByte(); const inf_check_f32 = try deserializer.deserialize(f32); const nan_check_f64 = try deserializer.deserialize(f64); const inf_check_f64 = try deserializer.deserialize(f64); -- 2.54.0 From 9bed6e1bf94b79ff027cb5aab3fa7231973337a9 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Sun, 2 Jun 2019 22:09:22 -0700 Subject: [PATCH 65/84] std.math: Add ceilPowerOfTwo and ceilPowerOfTwoPromote Closes #2426 --- std/math.zig | 81 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 9 deletions(-) diff --git a/std/math.zig b/std/math.zig index 04f0d0a49ab1d8444f840ca556c9c787d853992a..c0673e79adfc956704de979b4c35a0c15e916a6f 100644 --- a/std/math.zig +++ b/std/math.zig @@ -696,6 +696,78 @@ test "math.floorPowerOfTwo" { comptime testFloorPowerOfTwo(); } +fn testFloorPowerOfTwo() void { + testing.expect(floorPowerOfTwo(u32, 63) == 32); + testing.expect(floorPowerOfTwo(u32, 64) == 64); + testing.expect(floorPowerOfTwo(u32, 65) == 64); + testing.expect(floorPowerOfTwo(u4, 7) == 4); + testing.expect(floorPowerOfTwo(u4, 8) == 8); + testing.expect(floorPowerOfTwo(u4, 9) == 8); +} + +/// Returns the next power of two (if the value is not already a power of two). +/// Result is a type with 1 more bit than the input type. +pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T.bit_count + 1) { + if (T.is_signed) { + @compileError("signed integers not supported"); + } + comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); + comptime const shiftType = std.math.Log2Int(promotedType); + if (value == 0) return promotedType(0); + return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1)); +} + +/// Returns the next power of two (if the value is not already a power of two). +/// If the value doesn't fit, returns an error. +pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) { + if (T.is_signed) { + @compileError("signed integers not supported"); + } + comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); + comptime const overflowBit = promotedType(1) << T.bit_count; + var x = ceilPowerOfTwoPromote(T, value); + if (overflowBit & x != 0) { + return error.Overflow; + } + return @intCast(T, x); +} + +test "math.ceilPowerOfTwoPromote" { + testCeilPowerOfTwoPromote(); + comptime testCeilPowerOfTwoPromote(); +} + +fn testCeilPowerOfTwoPromote() void { + testing.expectEqual(u33(0), ceilPowerOfTwoPromote(u32, 0)); + testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1)); + testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2)); + testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63)); + testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 64)); + testing.expectEqual(u33(128), ceilPowerOfTwoPromote(u32, 65)); + testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 7)); + testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 8)); + testing.expectEqual(u6(16), ceilPowerOfTwoPromote(u5, 9)); + testing.expectEqual(u5(16), ceilPowerOfTwoPromote(u4, 9)); +} + +test "math.ceilPowerOfTwo" { + try testCeilPowerOfTwo(); + comptime try testCeilPowerOfTwo(); +} + +fn testCeilPowerOfTwo() !void { + testing.expectEqual(u32(0), try ceilPowerOfTwo(u32, 0)); + testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1)); + testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2)); + testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63)); + testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 64)); + testing.expectEqual(u32(128), try ceilPowerOfTwo(u32, 65)); + testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 7)); + testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 8)); + testing.expectEqual(u5(16), try ceilPowerOfTwo(u5, 9)); + testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9)); +} + pub fn log2_int(comptime T: type, x: T) Log2Int(T) { assert(x != 0); return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x)); @@ -722,15 +794,6 @@ test "std.math.log2_int_ceil" { testing.expect(log2_int_ceil(u32, 10) == 4); } -fn testFloorPowerOfTwo() void { - testing.expect(floorPowerOfTwo(u32, 63) == 32); - testing.expect(floorPowerOfTwo(u32, 64) == 64); - testing.expect(floorPowerOfTwo(u32, 65) == 64); - testing.expect(floorPowerOfTwo(u4, 7) == 4); - testing.expect(floorPowerOfTwo(u4, 8) == 8); - testing.expect(floorPowerOfTwo(u4, 9) == 8); -} - pub fn lossyCast(comptime T: type, value: var) T { switch (@typeInfo(@typeOf(value))) { builtin.TypeId.Int => return @intToFloat(T, value), -- 2.54.0 From ebe921e48f4495634de1403caafc4d31158453fb Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 4 Jun 2019 09:05:12 +0200 Subject: [PATCH 66/84] Make `void` a signed type Follow the convention set by C so that lldb stops complaining about it. --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen.cpp b/src/codegen.cpp index 826a9463ac5ab769744c5b67107844c4415e27f3..ef1cb4c5fcaee06db61b7427f264058ffff8802e 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7243,7 +7243,7 @@ static void define_builtin_types(CodeGen *g) { buf_init_from_str(&entry->name, "void"); entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 0, - ZigLLVMEncoding_DW_ATE_unsigned()); + ZigLLVMEncoding_DW_ATE_signed()); g->builtin_types.entry_void = entry; g->primitive_type_table.put(&entry->name, entry); } -- 2.54.0 From 80cd142c96c421b50f26a7227066530a2a5d5978 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 4 Jun 2019 09:05:33 +0200 Subject: [PATCH 67/84] Propagate DIFlags to LLVM --- src/analyze.cpp | 45 +++++++++++++++++++++++++-------------------- src/codegen.cpp | 2 +- src/zig_llvm.cpp | 24 ++++++++++-------------- src/zig_llvm.h | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index a62c24460e1f2a3aa33ea398fd9342627c0a99bf..0878cf04a7992b407f6c049d828d47a8d2b4f451 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -6388,12 +6388,14 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa len_debug_size_in_bits, len_debug_align_in_bits, len_offset_in_bits, - 0, usize_llvm_di_type), + ZigLLVM_DIFlags_Zero, + usize_llvm_di_type), }; ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, compile_unit_scope, buf_ptr(&type->name), - di_file, line, debug_size_in_bits, debug_align_in_bits, 0, + di_file, line, debug_size_in_bits, debug_align_in_bits, + ZigLLVM_DIFlags_Zero, nullptr, di_element_types, 1, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); @@ -6425,18 +6427,19 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa ptr_debug_size_in_bits, ptr_debug_align_in_bits, ptr_offset_in_bits, - 0, get_llvm_di_type(g, ptr_type)), + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, ptr_type)), ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), "len", di_file, line, len_debug_size_in_bits, len_debug_align_in_bits, len_offset_in_bits, - 0, usize_llvm_di_type), + ZigLLVM_DIFlags_Zero, usize_llvm_di_type), }; ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, compile_unit_scope, buf_ptr(&type->name), - di_file, line, debug_size_in_bits, debug_align_in_bits, 0, + di_file, line, debug_size_in_bits, debug_align_in_bits, + ZigLLVM_DIFlags_Zero, nullptr, di_element_types, 2, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); @@ -6597,7 +6600,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS debug_size_in_bits, debug_align_in_bits, debug_offset_in_bits, - 0, field_di_type); + ZigLLVM_DIFlags_Zero, field_di_type); assert(di_element_types[debug_field_index]); debug_field_index += 1; } @@ -6610,7 +6613,8 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS di_file, line, debug_size_in_bits, debug_align_in_bits, - 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); + ZigLLVM_DIFlags_Zero, + nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, struct_type->llvm_di_type, replacement_di_type); struct_type->llvm_di_type = replacement_di_type; @@ -6639,7 +6643,8 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type) { import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), debug_size_in_bits, debug_align_in_bits, - 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); + ZigLLVM_DIFlags_Zero, + nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); return; } @@ -6723,7 +6728,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta store_size_in_bits, abi_align_in_bits, 0, - 0, field_di_type); + ZigLLVM_DIFlags_Zero, field_di_type); } @@ -6752,7 +6757,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), union_type->data.unionation.union_abi_size * 8, most_aligned_union_member->abi_align * 8, - 0, union_inner_di_types, + ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type); @@ -6786,7 +6791,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion", import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align, - 0, union_inner_di_types, gen_field_count, 0, ""); + ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, ""); uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->llvm_type, union_type->data.unionation.gen_union_index); @@ -6799,7 +6804,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta most_aligned_union_member->size_in_bits, 8*most_aligned_union_member->abi_align, union_offset_in_bits, - 0, union_di_type); + ZigLLVM_DIFlags_Zero, union_di_type); uint64_t tag_debug_size_in_bits = tag_type->size_in_bits; uint64_t tag_debug_align_in_bits = 8*tag_type->abi_align; @@ -6810,7 +6815,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta tag_debug_size_in_bits, tag_debug_align_in_bits, tag_offset_in_bits, - 0, get_llvm_di_type(g, tag_type)); + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, tag_type)); ZigLLVMDIType *di_root_members[2]; di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type; @@ -6824,7 +6829,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1), debug_size_in_bits, debug_align_in_bits, - 0, nullptr, di_root_members, 2, 0, nullptr, ""); + ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, union_type->llvm_di_type, replacement_di_type); union_type->llvm_di_type = replacement_di_type; @@ -6952,18 +6957,18 @@ static void resolve_llvm_types_optional(CodeGen *g, ZigType *type) { val_debug_size_in_bits, val_debug_align_in_bits, val_offset_in_bits, - 0, child_llvm_di_type), + ZigLLVM_DIFlags_Zero, child_llvm_di_type), ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), "maybe", di_file, line, maybe_debug_size_in_bits, maybe_debug_align_in_bits, maybe_offset_in_bits, - 0, bool_llvm_di_type), + ZigLLVM_DIFlags_Zero, bool_llvm_di_type), }; ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, compile_unit_scope, buf_ptr(&type->name), - di_file, line, debug_size_in_bits, debug_align_in_bits, 0, + di_file, line, debug_size_in_bits, debug_align_in_bits, ZigLLVM_DIFlags_Zero, nullptr, di_element_types, 2, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); @@ -7016,13 +7021,13 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { tag_debug_size_in_bits, tag_debug_align_in_bits, tag_offset_in_bits, - 0, get_llvm_di_type(g, err_set_type)), + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, err_set_type)), ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(type->llvm_di_type), "value", di_file, line, value_debug_size_in_bits, value_debug_align_in_bits, value_offset_in_bits, - 0, get_llvm_di_type(g, payload_type)), + ZigLLVM_DIFlags_Zero, get_llvm_di_type(g, payload_type)), }; ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, @@ -7031,7 +7036,7 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) { di_file, line, debug_size_in_bits, debug_align_in_bits, - 0, + ZigLLVM_DIFlags_Zero, nullptr, di_element_types, 2, 0, nullptr, ""); ZigLLVMReplaceTemporary(g->dbuilder, type->llvm_di_type, replacement_di_type); diff --git a/src/codegen.cpp b/src/codegen.cpp index ef1cb4c5fcaee06db61b7427f264058ffff8802e..4f1cb51a125a254d277f30f310c16a5987384bae 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -674,7 +674,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { bool is_optimized = g->build_mode != BuildModeDebug; bool is_internal_linkage = (fn_table_entry->body_node != nullptr && fn_table_entry->export_list.length == 0); - unsigned flags = 0; + unsigned flags = ZigLLVM_DIFlags_StaticMember; ZigLLVMDIScope *fn_di_scope = get_di_scope(g, scope->parent); assert(fn_di_scope != nullptr); ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index c825ed38969c3036c88571ba02d3f360bb8f287f..fe1b279cf00cb7a464b6462b10026d34fb45fc0d 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -318,12 +318,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVM const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits, uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type) { - assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createMemberType( reinterpret_cast(scope), name, reinterpret_cast(file), - line, size_in_bits, align_in_bits, offset_in_bits, DINode::FlagZero, + line, size_in_bits, align_in_bits, offset_in_bits, + static_cast(flags), reinterpret_cast(type)); return reinterpret_cast(di_type); } @@ -338,12 +338,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMD DIType *ditype = reinterpret_cast(types_array[i]); fields.push_back(ditype); } - assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createUnionType( reinterpret_cast(scope), name, reinterpret_cast(file), - line_number, size_in_bits, align_in_bits, DINode::FlagZero, + line_number, size_in_bits, align_in_bits, + static_cast(flags), reinterpret_cast(dibuilder)->getOrCreateArray(fields), run_time_lang, unique_id); return reinterpret_cast(di_type); @@ -360,12 +360,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVM DIType *ditype = reinterpret_cast(types_array[i]); fields.push_back(ditype); } - assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createStructType( reinterpret_cast(scope), name, reinterpret_cast(file), - line_number, size_in_bits, align_in_bits, DINode::FlagZero, + line_number, size_in_bits, align_in_bits, + static_cast(flags), reinterpret_cast(derived_from), reinterpret_cast(dibuilder)->getOrCreateArray(fields), run_time_lang, @@ -426,11 +426,10 @@ ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped, DIType *ditype = reinterpret_cast(types_array[i]); types.push_back(ditype); } - assert(flags == 0); DIBuilder *dibuilder = reinterpret_cast(dibuilder_wrapped); DISubroutineType *subroutine_type = dibuilder->createSubroutineType( dibuilder->getOrCreateTypeArray(types), - DINode::FlagZero); + static_cast(flags)); DIType *ditype = subroutine_type; return reinterpret_cast(ditype); } @@ -516,7 +515,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no, ZigLLVMDIType *type, bool always_preserve, unsigned flags) { - assert(flags == 0); DILocalVariable *result = reinterpret_cast(dbuilder)->createAutoVariable( reinterpret_cast(scope), name, @@ -524,7 +522,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder, line_no, reinterpret_cast(type), always_preserve, - DINode::FlagZero); + static_cast(flags)); return reinterpret_cast(result); } @@ -547,7 +545,6 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no, ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no) { - assert(flags == 0); assert(arg_no != 0); DILocalVariable *result = reinterpret_cast(dbuilder)->createParameterVariable( reinterpret_cast(scope), @@ -557,7 +554,7 @@ ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilde line_no, reinterpret_cast(type), always_preserve, - DINode::FlagZero); + static_cast(flags)); return reinterpret_cast(result); } @@ -612,7 +609,6 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram) { DISubroutineType *di_sub_type = static_cast(reinterpret_cast(fn_di_type)); - assert(flags == 0); DISubprogram *result = reinterpret_cast(dibuilder)->createFunction( reinterpret_cast(scope), name, linkage_name, @@ -620,7 +616,7 @@ ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMD lineno, di_sub_type, scope_line, - DINode::FlagStaticMember, + static_cast(flags), DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized), nullptr, reinterpret_cast(decl_subprogram), diff --git a/src/zig_llvm.h b/src/zig_llvm.h index c60cfd058d7ef97a5ad61df9c841f5b8f4397206..d667e0423d9e36437113871ad3c1ec3f9540b86b 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -406,6 +406,39 @@ enum ZigLLVM_ObjectFormatType { ZigLLVM_Wasm, }; +#define ZigLLVM_DIFlags_Zero 0U +#define ZigLLVM_DIFlags_Private 1U +#define ZigLLVM_DIFlags_Protected 2U +#define ZigLLVM_DIFlags_Public 3U +#define ZigLLVM_DIFlags_FwdDecl (1U << 2) +#define ZigLLVM_DIFlags_AppleBlock (1U << 3) +#define ZigLLVM_DIFlags_BlockByrefStruct (1U << 4) +#define ZigLLVM_DIFlags_Virtual (1U << 5) +#define ZigLLVM_DIFlags_Artificial (1U << 6) +#define ZigLLVM_DIFlags_Explicit (1U << 7) +#define ZigLLVM_DIFlags_Prototyped (1U << 8) +#define ZigLLVM_DIFlags_ObjcClassComplete (1U << 9) +#define ZigLLVM_DIFlags_ObjectPointer (1U << 10) +#define ZigLLVM_DIFlags_Vector (1U << 11) +#define ZigLLVM_DIFlags_StaticMember (1U << 12) +#define ZigLLVM_DIFlags_LValueReference (1U << 13) +#define ZigLLVM_DIFlags_RValueReference (1U << 14) +#define ZigLLVM_DIFlags_Reserved (1U << 15) +#define ZigLLVM_DIFlags_SingleInheritance (1U << 16) +#define ZigLLVM_DIFlags_MultipleInheritance (2 << 16) +#define ZigLLVM_DIFlags_VirtualInheritance (3 << 16) +#define ZigLLVM_DIFlags_IntroducedVirtual (1U << 18) +#define ZigLLVM_DIFlags_BitField (1U << 19) +#define ZigLLVM_DIFlags_NoReturn (1U << 20) +#define ZigLLVM_DIFlags_TypePassByValue (1U << 22) +#define ZigLLVM_DIFlags_TypePassByReference (1U << 23) +#define ZigLLVM_DIFlags_EnumClass (1U << 24) +#define ZigLLVM_DIFlags_Thunk (1U << 25) +#define ZigLLVM_DIFlags_NonTrivial (1U << 26) +#define ZigLLVM_DIFlags_BigEndian (1U << 27) +#define ZigLLVM_DIFlags_LittleEndian (1U << 28) +#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29) + ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch); ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch); ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor); -- 2.54.0 From 7eb82b8651e134c18fe7377dca271d6963333d61 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 4 Jun 2019 12:31:20 -0400 Subject: [PATCH 68/84] std.os.mmap: update doc comments for previous commits --- std/os.zig | 1 - 1 file changed, 1 deletion(-) diff --git a/std/os.zig b/std/os.zig index cc440250318a3e3e76f82e04bec275eafb39e2ec..46f73bc7ceced94a82fdb6764b78e3b5aec21855 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1946,7 +1946,6 @@ pub const MMapError = error{ /// Map files or devices into memory. /// Use of a mapped region can result in these signals: -/// `length` must be page-aligned. /// * SIGSEGV - Attempted write into a region mapped as read-only. /// * SIGBUS - Attempted access to a portion of the buffer that does not correspond to the file pub fn mmap( -- 2.54.0 From fd771ea9fb8926127b4ecb2793608b04a4430b2d Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Tue, 4 Jun 2019 14:46:06 +0200 Subject: [PATCH 69/84] Added LineComment support when MultiLines are used in ArrayInit also added the corresponding testcase --- std/zig/parser_test.zig | 6 ++++++ std/zig/render.zig | 18 +++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig index 2a10e95e6c3e95cb4bc1ed57adfe286101d51388..281f09d57b2771b2357a94392cdc0d7f991a4f67 100644 --- a/std/zig/parser_test.zig +++ b/std/zig/parser_test.zig @@ -2223,6 +2223,12 @@ test "zig fmt: multiline string in array" { \\ , \\ \\bbb \\ }; + \\ const Bar = [][]const u8{ // comment here + \\ \\aaa + \\ \\ + \\ , // and another comment can go here + \\ \\bbb + \\ }; \\} \\ ); diff --git a/std/zig/render.zig b/std/zig/render.zig index 3bf279eaf307e19efdc0a29f90c9f656463934fd..ef5c8f2346214473ee07382f288eb5be4cb9c07d 100644 --- a/std/zig/render.zig +++ b/std/zig/render.zig @@ -727,10 +727,13 @@ fn renderExpression( } var new_indent = indent + indent_delta; - try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); - if (tree.tokens.at(lbrace + 1).id != Token.Id.MultilineStringLiteralLine) { + if (tree.tokens.at(tree.nextToken(lbrace)).id != Token.Id.MultilineStringLiteralLine) { + try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline); try stream.writeByteNTimes(' ', new_indent); + } else { + new_indent -= indent_delta; + try renderToken(tree, stream, lbrace, new_indent, start_col, Space.None); } it.set(0); @@ -738,9 +741,6 @@ fn renderExpression( var col: usize = 1; while (it.next()) |expr| : (i += 1) { if (it.peek()) |next_expr| { - if (expr.*.id == ast.Node.Id.MultilineStringLiteral) { - new_indent -= indent_delta; - } try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.None); const comma = tree.nextToken(expr.*.lastToken()); @@ -756,7 +756,11 @@ fn renderExpression( } col = 1; - try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // , + if (tree.tokens.at(tree.nextToken(comma)).id != Token.Id.MultilineStringLiteralLine) { + try renderToken(tree, stream, comma, new_indent, start_col, Space.Newline); // , + } else { + try renderToken(tree, stream, comma, new_indent, start_col, Space.None); // , + } try renderExtraNewline(tree, stream, start_col, next_expr.*); if (next_expr.*.id != ast.Node.Id.MultilineStringLiteral) { @@ -766,7 +770,7 @@ fn renderExpression( try renderExpression(allocator, stream, tree, new_indent, start_col, expr.*, Space.Comma); // , } } - const last_node = it.prev() orelse unreachable; + const last_node = it.prev().?; if (last_node.*.id != ast.Node.Id.MultilineStringLiteral) { try stream.writeByteNTimes(' ', indent); } -- 2.54.0 From 291aaee97773e2f9c40e061410db52ca00f4d651 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 1 Jun 2019 16:59:12 +0200 Subject: [PATCH 70/84] Stop the musl builder from skipping necessary files The code assumed that the architecture-specific bits, found in the arch/ subfolder, were only overrides for the generic .c files. Changed the logic to always include the whole architecture-specific implementations and discard the generic ones, this way we won't exclude files with no .c counterpart. --- src/link.cpp | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index f94b1219f6b9cac86469d5753173eb67bad14312..fe5a73a52b8d80a0e4b8e38d3d225793455712e3 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -528,9 +528,6 @@ static const char *build_musl(CodeGen *parent) { Buf noextbasename = BUF_INIT; Buf dirbasename = BUF_INIT; Buf before_arch_dir = BUF_INIT; - Buf override_c = BUF_INIT; - Buf override_s = BUF_INIT; - Buf override_S = BUF_INIT; auto source_it = source_table.entry_iterator(); for (;;) { @@ -543,31 +540,37 @@ static const char *build_musl(CodeGen *parent) { os_path_split(src_file, &dirname, &basename); os_path_extname(&basename, &noextbasename, nullptr); os_path_split(&dirname, &before_arch_dir, &dirbasename); + + bool is_arch_specific = false; + // Architecture-specific implementations are under a / folder. if (is_musl_arch_name(buf_ptr(&dirbasename))) { - // We find these by explicitly looking for overrides. - continue; + // Not the architecture we're compiling for. + if (strcmp(buf_ptr(&dirbasename), target_musl_arch_name) != 0) + continue; + is_arch_specific = true; } - // Look for an arch specific override. - buf_resize(&override_c, 0); - buf_resize(&override_s, 0); - buf_resize(&override_S, 0); - buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); - buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); - buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S", - buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + if (!is_arch_specific) { + Buf override_path = BUF_INIT; - if (source_table.maybe_get(&override_c) != nullptr) { - src_file = &override_c; - src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind; - } else if (source_table.maybe_get(&override_s) != nullptr) { - src_file = &override_s; - src_kind = MuslSrcAsm; - } else if (source_table.maybe_get(&override_S) != nullptr) { - src_file = &override_S; - src_kind = MuslSrcAsm; + // Look for an arch specific override. + buf_resize(&override_path, 0); + buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.s", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + if (source_table.maybe_get(&override_path) != nullptr) + continue; + + buf_resize(&override_path, 0); + buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.S", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + if (source_table.maybe_get(&override_path) != nullptr) + continue; + + buf_resize(&override_path, 0); + buf_appendf(&override_path, "%s" OS_SEP "%s" OS_SEP "%s.c", + buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename)); + if (source_table.maybe_get(&override_path) != nullptr) + continue; } Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s", -- 2.54.0 From d83b15febf00518e201160f8b089c0d846d18e4c Mon Sep 17 00:00:00 2001 From: Nick Erdmann Date: Sun, 2 Jun 2019 17:27:09 +0200 Subject: [PATCH 71/84] src/ast_render.cpp: fix rendering of character literals <= 0x0f --- src/ast_render.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 95ae216f704074f7cf6b2d4c40f5077c9b6c1305..defe40cb190fd2de188f55e997ff42a5602d3e81 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -352,7 +352,7 @@ static void string_literal_escape(Buf *source, Buf *dest) { } else if (is_printable(c)) { buf_append_char(dest, c); } else { - buf_appendf(dest, "\\x%x", (int)c); + buf_appendf(dest, "\\x%02x", (int)c); } } } -- 2.54.0 From a0d66fa1e6e8b9620e4990a33c32b0db11469aec Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Tue, 4 Jun 2019 15:49:27 -0700 Subject: [PATCH 72/84] std.math: Clarify ceilPowerOfTwo inputs and disallow zero as an input --- std/math.zig | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/std/math.zig b/std/math.zig index c0673e79adfc956704de979b4c35a0c15e916a6f..765df6280cd59f7d5c15381b9e0e9bde1f04c470 100644 --- a/std/math.zig +++ b/std/math.zig @@ -706,23 +706,23 @@ fn testFloorPowerOfTwo() void { } /// Returns the next power of two (if the value is not already a power of two). +/// Only unsigned integers can be used. Zero is not an allowed input. /// Result is a type with 1 more bit than the input type. pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T.bit_count + 1) { - if (T.is_signed) { - @compileError("signed integers not supported"); - } + comptime assert(@typeId(T) == builtin.TypeId.Int); + comptime assert(!T.is_signed); + assert(value != 0); comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); comptime const shiftType = std.math.Log2Int(promotedType); - if (value == 0) return promotedType(0); return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1)); } /// Returns the next power of two (if the value is not already a power of two). +/// Only unsigned integers can be used. Zero is not an allowed input. /// If the value doesn't fit, returns an error. pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) { - if (T.is_signed) { - @compileError("signed integers not supported"); - } + comptime assert(@typeId(T) == builtin.TypeId.Int); + comptime assert(!T.is_signed); comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1); comptime const overflowBit = promotedType(1) << T.bit_count; var x = ceilPowerOfTwoPromote(T, value); @@ -738,7 +738,6 @@ test "math.ceilPowerOfTwoPromote" { } fn testCeilPowerOfTwoPromote() void { - testing.expectEqual(u33(0), ceilPowerOfTwoPromote(u32, 0)); testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1)); testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2)); testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63)); @@ -756,7 +755,6 @@ test "math.ceilPowerOfTwo" { } fn testCeilPowerOfTwo() !void { - testing.expectEqual(u32(0), try ceilPowerOfTwo(u32, 0)); testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1)); testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2)); testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63)); -- 2.54.0 From fdddd131068775f8c811a51fdc08939165ee9e58 Mon Sep 17 00:00:00 2001 From: mrkishi Date: Tue, 4 Jun 2019 21:29:38 -0300 Subject: [PATCH 73/84] add cache-control headers to tarballs on ci --- ci/azure/linux_script | 2 +- ci/azure/macos_script | 4 ++-- ci/azure/update_download_page | 2 +- ci/azure/windows_upload | 2 +- ci/srht/freebsd_script | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ci/azure/linux_script b/ci/azure/linux_script index aaa75d6fce43bde90fc6134451fc24e72b72cdf4..20373f3a4984bc887fe0980d94158439659908b4 100755 --- a/ci/azure/linux_script +++ b/ci/azure/linux_script @@ -28,7 +28,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm8-1 -j2 $BUILD_SOURCEVERSION TARBALL="$(ls $ARTIFACTSDIR)" mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg" - s3cmd put -P "$ARTIFACTSDIR/$TARBALL" s3://ziglang.org/builds/ + s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$ARTIFACTSDIR/$TARBALL" s3://ziglang.org/builds/ SHASUM=$(sha256sum $ARTIFACTSDIR/$TARBALL | cut '-d ' -f1) BYTESIZE=$(wc -c < $ARTIFACTSDIR/$TARBALL) diff --git a/ci/azure/macos_script b/ci/azure/macos_script index 1b1d8741faf54f6013282c1f588bd06aa7a7ab95..13c24abd239b3e035bc18e71f8cbeef3d641c9a4 100755 --- a/ci/azure/macos_script +++ b/ci/azure/macos_script @@ -62,7 +62,7 @@ else cd $HOME tar cfJ "$CACHE_BASENAME.tar.xz" "$CACHE_BASENAME" cp "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg" - s3cmd put -P "$CACHE_BASENAME.tar.xz" "s3://ziglang.org/builds/$CACHE_BASENAME.tar.xz" + s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$CACHE_BASENAME.tar.xz" "s3://ziglang.org/builds/$CACHE_BASENAME.tar.xz" fi cd $ZIGDIR @@ -85,7 +85,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then tar cfJ "$TARBALL" "$DIRNAME" mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg" - s3cmd put -P "$TARBALL" s3://ziglang.org/builds/ + s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/ SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1) BYTESIZE=$(wc -c < $TARBALL) diff --git a/ci/azure/update_download_page b/ci/azure/update_download_page index c1e816a309d166887e1c84812fc1f1ee6c28a098..c6a690e8e611d1060c8e8f091e30a92d519510e6 100755 --- a/ci/azure/update_download_page +++ b/ci/azure/update_download_page @@ -35,7 +35,7 @@ env "../$ZIG" run update-download-page.zig mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg" -s3cmd put -P "../$SRC_TARBALL" s3://ziglang.org/builds/ +s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "../$SRC_TARBALL" s3://ziglang.org/builds/ s3cmd put -P "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate" s3cmd put -P www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate" s3cmd put -P www/download/index.json s3://ziglang.org/download/index.json --add-header="Cache-Control: max-age=0, must-revalidate" diff --git a/ci/azure/windows_upload b/ci/azure/windows_upload index 8478be0e0b4d80c730e276b72d8fcfe797ed6625..266d1b57ddba0f52c0b8692d660a5912abaf12aa 100755 --- a/ci/azure/windows_upload +++ b/ci/azure/windows_upload @@ -19,7 +19,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then 7z a "$TARBALL" "$DIRNAME" mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg" - s3cmd put -P "$TARBALL" s3://ziglang.org/builds/ + s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/ SHASUM=$(sha256sum $TARBALL | cut '-d ' -f1) BYTESIZE=$(wc -c < $TARBALL) diff --git a/ci/srht/freebsd_script b/ci/srht/freebsd_script index 0ff66aaec5db58a43026af6f518d9523a90732ba..9edf076c5369d212bd15a6c9c85d38a8caba67a8 100755 --- a/ci/srht/freebsd_script +++ b/ci/srht/freebsd_script @@ -36,7 +36,7 @@ if [ -f ~/.s3cfg ]; then mv release "$DIRNAME" tar cfJ "$TARBALL" "$DIRNAME" - s3cmd put -P "$TARBALL" s3://ziglang.org/builds/ + s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/ SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1) BYTESIZE=$(wc -c < $TARBALL) -- 2.54.0 From b74bcc9d76c25d6ae0f872f36f8c390dcd985bec Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 5 Jun 2019 14:42:36 -0500 Subject: [PATCH 74/84] windows.unexpectedError prints a human friendly string --- std/os/windows.zig | 10 +- std/os/windows/bits.zig | 15 ++ std/os/windows/kernel32.zig | 4 + std/os/windows/lang.zig | 384 ++++++++++++++++++++++++++++++++++++ 4 files changed, 412 insertions(+), 1 deletion(-) create mode 100644 std/os/windows/lang.zig diff --git a/std/os/windows.zig b/std/os/windows.zig index 1d59004012facee6daa5118d8fc3e595b54a1795..0757d9924f3130468f6a511a35daa85717ddf0ba 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -756,11 +756,19 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) return result; } +inline fn MAKELANGID(p: USHORT, s: USHORT) LANGID { + return (s << 10) | p; +} + /// Call this when you made a windows DLL call or something that does SetLastError /// and you get an unexpected error. pub fn unexpectedError(err: DWORD) std.os.UnexpectedError { if (std.os.unexpected_error_tracing) { - std.debug.warn("unexpected GetLastError(): {}\n", err); + var buf: LPSTR = undefined; + const len = kernel32.FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.LANG_NEUTRAL, LANG.SUBLANG_DEFAULT), buf, 0, null); + defer _ = kernel32.LocalFree(@ptrCast(HLOCAL, buf)); + std.debug.warn("error.Unexpected: {}: {}\n", err, buf[0..len]); + std.debug.dumpCurrentStackTrace(null); } return error.Unexpected; diff --git a/std/os/windows/bits.zig b/std/os/windows/bits.zig index 0bf29919035c97b8112b3356effbf298549f6794..d05266c9fc1b01e0081966a570471edb548aed0b 100644 --- a/std/os/windows/bits.zig +++ b/std/os/windows/bits.zig @@ -6,6 +6,7 @@ const assert = std.debug.assert; const maxInt = std.math.maxInt; pub const ERROR = @import("error.zig"); +pub const LANG = @import("lang.zig"); /// The standard input device. Initially, this is the console input buffer, CONIN$. pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1; @@ -55,6 +56,10 @@ pub const ULONG = u32; pub const LONG = i32; pub const ULONGLONG = u64; pub const LONGLONG = i64; +pub const HLOCAL = HANDLE; +pub const LANGID = c_ushort; + +pub const va_list = *@OpaqueType(); pub const TRUE = 1; pub const FALSE = 0; @@ -525,3 +530,13 @@ pub const COINIT = extern enum { /// > this expansion applies to the total length. /// from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation pub const PATH_MAX_WIDE = 32767; + +pub const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100; +pub const FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000; +pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; +pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400; +pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; +pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; +pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF; +pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; +pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400; diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index 852369df20e50d1fb22b493be123caef2a927c07..bee1b82544672e8d4f78beb9540bbab491ced6ed 100644 --- a/std/os/windows/kernel32.zig +++ b/std/os/windows/kernel32.zig @@ -50,6 +50,8 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; +pub extern "kernel32" stdcallcc fn FormatMessageA(dwFlags: DWORD, lpSource: LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; + pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; @@ -116,6 +118,8 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL; +pub extern "kernel32" stdcallcc fn LocalFree(hMem: HLOCAL) ?HLOCAL; + pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID; pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL; diff --git a/std/os/windows/lang.zig b/std/os/windows/lang.zig new file mode 100644 index 0000000000000000000000000000000000000000..7e6e2d1a799e25030b87d44bb8a7c053581a8a4d --- /dev/null +++ b/std/os/windows/lang.zig @@ -0,0 +1,384 @@ +pub const LANG_NEUTRAL = 0x00; +pub const LANG_INVARIANT = 0x7f; +pub const LANG_AFRIKAANS = 0x36; +pub const LANG_ALBANIAN = 0x1c; +pub const LANG_ALSATIAN = 0x84; +pub const LANG_AMHARIC = 0x5e; +pub const LANG_ARABIC = 0x01; +pub const LANG_ARMENIAN = 0x2b; +pub const LANG_ASSAMESE = 0x4d; +pub const LANG_AZERI = 0x2c; +pub const LANG_AZERBAIJANI = 0x2c; +pub const LANG_BANGLA = 0x45; +pub const LANG_BASHKIR = 0x6d; +pub const LANG_BASQUE = 0x2d; +pub const LANG_BELARUSIAN = 0x23; +pub const LANG_BENGALI = 0x45; +pub const LANG_BRETON = 0x7e; +pub const LANG_BOSNIAN = 0x1a; +pub const LANG_BOSNIAN_NEUTRAL = 0x781a; +pub const LANG_BULGARIAN = 0x02; +pub const LANG_CATALAN = 0x03; +pub const LANG_CENTRAL_KURDISH = 0x92; +pub const LANG_CHEROKEE = 0x5c; +pub const LANG_CHINESE = 0x04; +pub const LANG_CHINESE_SIMPLIFIED = 0x04; +pub const LANG_CHINESE_TRADITIONAL = 0x7c04; +pub const LANG_CORSICAN = 0x83; +pub const LANG_CROATIAN = 0x1a; +pub const LANG_CZECH = 0x05; +pub const LANG_DANISH = 0x06; +pub const LANG_DARI = 0x8c; +pub const LANG_DIVEHI = 0x65; +pub const LANG_DUTCH = 0x13; +pub const LANG_ENGLISH = 0x09; +pub const LANG_ESTONIAN = 0x25; +pub const LANG_FAEROESE = 0x38; +pub const LANG_FARSI = 0x29; +pub const LANG_FILIPINO = 0x64; +pub const LANG_FINNISH = 0x0b; +pub const LANG_FRENCH = 0x0c; +pub const LANG_FRISIAN = 0x62; +pub const LANG_FULAH = 0x67; +pub const LANG_GALICIAN = 0x56; +pub const LANG_GEORGIAN = 0x37; +pub const LANG_GERMAN = 0x07; +pub const LANG_GREEK = 0x08; +pub const LANG_GREENLANDIC = 0x6f; +pub const LANG_GUJARATI = 0x47; +pub const LANG_HAUSA = 0x68; +pub const LANG_HAWAIIAN = 0x75; +pub const LANG_HEBREW = 0x0d; +pub const LANG_HINDI = 0x39; +pub const LANG_HUNGARIAN = 0x0e; +pub const LANG_ICELANDIC = 0x0f; +pub const LANG_IGBO = 0x70; +pub const LANG_INDONESIAN = 0x21; +pub const LANG_INUKTITUT = 0x5d; +pub const LANG_IRISH = 0x3c; +pub const LANG_ITALIAN = 0x10; +pub const LANG_JAPANESE = 0x11; +pub const LANG_KANNADA = 0x4b; +pub const LANG_KASHMIRI = 0x60; +pub const LANG_KAZAK = 0x3f; +pub const LANG_KHMER = 0x53; +pub const LANG_KICHE = 0x86; +pub const LANG_KINYARWANDA = 0x87; +pub const LANG_KONKANI = 0x57; +pub const LANG_KOREAN = 0x12; +pub const LANG_KYRGYZ = 0x40; +pub const LANG_LAO = 0x54; +pub const LANG_LATVIAN = 0x26; +pub const LANG_LITHUANIAN = 0x27; +pub const LANG_LOWER_SORBIAN = 0x2e; +pub const LANG_LUXEMBOURGISH = 0x6e; +pub const LANG_MACEDONIAN = 0x2f; +pub const LANG_MALAY = 0x3e; +pub const LANG_MALAYALAM = 0x4c; +pub const LANG_MALTESE = 0x3a; +pub const LANG_MANIPURI = 0x58; +pub const LANG_MAORI = 0x81; +pub const LANG_MAPUDUNGUN = 0x7a; +pub const LANG_MARATHI = 0x4e; +pub const LANG_MOHAWK = 0x7c; +pub const LANG_MONGOLIAN = 0x50; +pub const LANG_NEPALI = 0x61; +pub const LANG_NORWEGIAN = 0x14; +pub const LANG_OCCITAN = 0x82; +pub const LANG_ODIA = 0x48; +pub const LANG_ORIYA = 0x48; +pub const LANG_PASHTO = 0x63; +pub const LANG_PERSIAN = 0x29; +pub const LANG_POLISH = 0x15; +pub const LANG_PORTUGUESE = 0x16; +pub const LANG_PULAR = 0x67; +pub const LANG_PUNJABI = 0x46; +pub const LANG_QUECHUA = 0x6b; +pub const LANG_ROMANIAN = 0x18; +pub const LANG_ROMANSH = 0x17; +pub const LANG_RUSSIAN = 0x19; +pub const LANG_SAKHA = 0x85; +pub const LANG_SAMI = 0x3b; +pub const LANG_SANSKRIT = 0x4f; +pub const LANG_SCOTTISH_GAELIC = 0x91; +pub const LANG_SERBIAN = 0x1a; +pub const LANG_SERBIAN_NEUTRAL = 0x7c1a; +pub const LANG_SINDHI = 0x59; +pub const LANG_SINHALESE = 0x5b; +pub const LANG_SLOVAK = 0x1b; +pub const LANG_SLOVENIAN = 0x24; +pub const LANG_SOTHO = 0x6c; +pub const LANG_SPANISH = 0x0a; +pub const LANG_SWAHILI = 0x41; +pub const LANG_SWEDISH = 0x1d; +pub const LANG_SYRIAC = 0x5a; +pub const LANG_TAJIK = 0x28; +pub const LANG_TAMAZIGHT = 0x5f; +pub const LANG_TAMIL = 0x49; +pub const LANG_TATAR = 0x44; +pub const LANG_TELUGU = 0x4a; +pub const LANG_THAI = 0x1e; +pub const LANG_TIBETAN = 0x51; +pub const LANG_TIGRIGNA = 0x73; +pub const LANG_TIGRINYA = 0x73; +pub const LANG_TSWANA = 0x32; +pub const LANG_TURKISH = 0x1f; +pub const LANG_TURKMEN = 0x42; +pub const LANG_UIGHUR = 0x80; +pub const LANG_UKRAINIAN = 0x22; +pub const LANG_UPPER_SORBIAN = 0x2e; +pub const LANG_URDU = 0x20; +pub const LANG_UZBEK = 0x43; +pub const LANG_VALENCIAN = 0x03; +pub const LANG_VIETNAMESE = 0x2a; +pub const LANG_WELSH = 0x52; +pub const LANG_WOLOF = 0x88; +pub const LANG_XHOSA = 0x34; +pub const LANG_YAKUT = 0x85; +pub const LANG_YI = 0x78; +pub const LANG_YORUBA = 0x6a; +pub const LANG_ZULU = 0x35; +pub const SUBLANG_NEUTRAL = 0x00; +pub const SUBLANG_DEFAULT = 0x01; +pub const SUBLANG_SYS_DEFAULT = 0x02; +pub const SUBLANG_CUSTOM_DEFAULT = 0x03; +pub const SUBLANG_CUSTOM_UNSPECIFIED = 0x04; +pub const SUBLANG_UI_CUSTOM_DEFAULT = 0x05; +pub const SUBLANG_AFRIKAANS_SOUTH_AFRICA = 0x01; +pub const SUBLANG_ALBANIAN_ALBANIA = 0x01; +pub const SUBLANG_ALSATIAN_FRANCE = 0x01; +pub const SUBLANG_AMHARIC_ETHIOPIA = 0x01; +pub const SUBLANG_ARABIC_SAUDI_ARABIA = 0x01; +pub const SUBLANG_ARABIC_IRAQ = 0x02; +pub const SUBLANG_ARABIC_EGYPT = 0x03; +pub const SUBLANG_ARABIC_LIBYA = 0x04; +pub const SUBLANG_ARABIC_ALGERIA = 0x05; +pub const SUBLANG_ARABIC_MOROCCO = 0x06; +pub const SUBLANG_ARABIC_TUNISIA = 0x07; +pub const SUBLANG_ARABIC_OMAN = 0x08; +pub const SUBLANG_ARABIC_YEMEN = 0x09; +pub const SUBLANG_ARABIC_SYRIA = 0x0a; +pub const SUBLANG_ARABIC_JORDAN = 0x0b; +pub const SUBLANG_ARABIC_LEBANON = 0x0c; +pub const SUBLANG_ARABIC_KUWAIT = 0x0d; +pub const SUBLANG_ARABIC_UAE = 0x0e; +pub const SUBLANG_ARABIC_BAHRAIN = 0x0f; +pub const SUBLANG_ARABIC_QATAR = 0x10; +pub const SUBLANG_ARMENIAN_ARMENIA = 0x01; +pub const SUBLANG_ASSAMESE_INDIA = 0x01; +pub const SUBLANG_AZERI_LATIN = 0x01; +pub const SUBLANG_AZERI_CYRILLIC = 0x02; +pub const SUBLANG_AZERBAIJANI_AZERBAIJAN_LATIN = 0x01; +pub const SUBLANG_AZERBAIJANI_AZERBAIJAN_CYRILLIC = 0x02; +pub const SUBLANG_BANGLA_INDIA = 0x01; +pub const SUBLANG_BANGLA_BANGLADESH = 0x02; +pub const SUBLANG_BASHKIR_RUSSIA = 0x01; +pub const SUBLANG_BASQUE_BASQUE = 0x01; +pub const SUBLANG_BELARUSIAN_BELARUS = 0x01; +pub const SUBLANG_BENGALI_INDIA = 0x01; +pub const SUBLANG_BENGALI_BANGLADESH = 0x02; +pub const SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 0x05; +pub const SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x08; +pub const SUBLANG_BRETON_FRANCE = 0x01; +pub const SUBLANG_BULGARIAN_BULGARIA = 0x01; +pub const SUBLANG_CATALAN_CATALAN = 0x01; +pub const SUBLANG_CENTRAL_KURDISH_IRAQ = 0x01; +pub const SUBLANG_CHEROKEE_CHEROKEE = 0x01; +pub const SUBLANG_CHINESE_TRADITIONAL = 0x01; +pub const SUBLANG_CHINESE_SIMPLIFIED = 0x02; +pub const SUBLANG_CHINESE_HONGKONG = 0x03; +pub const SUBLANG_CHINESE_SINGAPORE = 0x04; +pub const SUBLANG_CHINESE_MACAU = 0x05; +pub const SUBLANG_CORSICAN_FRANCE = 0x01; +pub const SUBLANG_CZECH_CZECH_REPUBLIC = 0x01; +pub const SUBLANG_CROATIAN_CROATIA = 0x01; +pub const SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 0x04; +pub const SUBLANG_DANISH_DENMARK = 0x01; +pub const SUBLANG_DARI_AFGHANISTAN = 0x01; +pub const SUBLANG_DIVEHI_MALDIVES = 0x01; +pub const SUBLANG_DUTCH = 0x01; +pub const SUBLANG_DUTCH_BELGIAN = 0x02; +pub const SUBLANG_ENGLISH_US = 0x01; +pub const SUBLANG_ENGLISH_UK = 0x02; +pub const SUBLANG_ENGLISH_AUS = 0x03; +pub const SUBLANG_ENGLISH_CAN = 0x04; +pub const SUBLANG_ENGLISH_NZ = 0x05; +pub const SUBLANG_ENGLISH_EIRE = 0x06; +pub const SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07; +pub const SUBLANG_ENGLISH_JAMAICA = 0x08; +pub const SUBLANG_ENGLISH_CARIBBEAN = 0x09; +pub const SUBLANG_ENGLISH_BELIZE = 0x0a; +pub const SUBLANG_ENGLISH_TRINIDAD = 0x0b; +pub const SUBLANG_ENGLISH_ZIMBABWE = 0x0c; +pub const SUBLANG_ENGLISH_PHILIPPINES = 0x0d; +pub const SUBLANG_ENGLISH_INDIA = 0x10; +pub const SUBLANG_ENGLISH_MALAYSIA = 0x11; +pub const SUBLANG_ENGLISH_SINGAPORE = 0x12; +pub const SUBLANG_ESTONIAN_ESTONIA = 0x01; +pub const SUBLANG_FAEROESE_FAROE_ISLANDS = 0x01; +pub const SUBLANG_FILIPINO_PHILIPPINES = 0x01; +pub const SUBLANG_FINNISH_FINLAND = 0x01; +pub const SUBLANG_FRENCH = 0x01; +pub const SUBLANG_FRENCH_BELGIAN = 0x02; +pub const SUBLANG_FRENCH_CANADIAN = 0x03; +pub const SUBLANG_FRENCH_SWISS = 0x04; +pub const SUBLANG_FRENCH_LUXEMBOURG = 0x05; +pub const SUBLANG_FRENCH_MONACO = 0x06; +pub const SUBLANG_FRISIAN_NETHERLANDS = 0x01; +pub const SUBLANG_FULAH_SENEGAL = 0x02; +pub const SUBLANG_GALICIAN_GALICIAN = 0x01; +pub const SUBLANG_GEORGIAN_GEORGIA = 0x01; +pub const SUBLANG_GERMAN = 0x01; +pub const SUBLANG_GERMAN_SWISS = 0x02; +pub const SUBLANG_GERMAN_AUSTRIAN = 0x03; +pub const SUBLANG_GERMAN_LUXEMBOURG = 0x04; +pub const SUBLANG_GERMAN_LIECHTENSTEIN = 0x05; +pub const SUBLANG_GREEK_GREECE = 0x01; +pub const SUBLANG_GREENLANDIC_GREENLAND = 0x01; +pub const SUBLANG_GUJARATI_INDIA = 0x01; +pub const SUBLANG_HAUSA_NIGERIA_LATIN = 0x01; +pub const SUBLANG_HAWAIIAN_US = 0x01; +pub const SUBLANG_HEBREW_ISRAEL = 0x01; +pub const SUBLANG_HINDI_INDIA = 0x01; +pub const SUBLANG_HUNGARIAN_HUNGARY = 0x01; +pub const SUBLANG_ICELANDIC_ICELAND = 0x01; +pub const SUBLANG_IGBO_NIGERIA = 0x01; +pub const SUBLANG_INDONESIAN_INDONESIA = 0x01; +pub const SUBLANG_INUKTITUT_CANADA = 0x01; +pub const SUBLANG_INUKTITUT_CANADA_LATIN = 0x02; +pub const SUBLANG_IRISH_IRELAND = 0x02; +pub const SUBLANG_ITALIAN = 0x01; +pub const SUBLANG_ITALIAN_SWISS = 0x02; +pub const SUBLANG_JAPANESE_JAPAN = 0x01; +pub const SUBLANG_KANNADA_INDIA = 0x01; +pub const SUBLANG_KASHMIRI_SASIA = 0x02; +pub const SUBLANG_KASHMIRI_INDIA = 0x02; +pub const SUBLANG_KAZAK_KAZAKHSTAN = 0x01; +pub const SUBLANG_KHMER_CAMBODIA = 0x01; +pub const SUBLANG_KICHE_GUATEMALA = 0x01; +pub const SUBLANG_KINYARWANDA_RWANDA = 0x01; +pub const SUBLANG_KONKANI_INDIA = 0x01; +pub const SUBLANG_KOREAN = 0x01; +pub const SUBLANG_KYRGYZ_KYRGYZSTAN = 0x01; +pub const SUBLANG_LAO_LAO = 0x01; +pub const SUBLANG_LATVIAN_LATVIA = 0x01; +pub const SUBLANG_LITHUANIAN = 0x01; +pub const SUBLANG_LOWER_SORBIAN_GERMANY = 0x02; +pub const SUBLANG_LUXEMBOURGISH_LUXEMBOURG = 0x01; +pub const SUBLANG_MACEDONIAN_MACEDONIA = 0x01; +pub const SUBLANG_MALAY_MALAYSIA = 0x01; +pub const SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02; +pub const SUBLANG_MALAYALAM_INDIA = 0x01; +pub const SUBLANG_MALTESE_MALTA = 0x01; +pub const SUBLANG_MAORI_NEW_ZEALAND = 0x01; +pub const SUBLANG_MAPUDUNGUN_CHILE = 0x01; +pub const SUBLANG_MARATHI_INDIA = 0x01; +pub const SUBLANG_MOHAWK_MOHAWK = 0x01; +pub const SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA = 0x01; +pub const SUBLANG_MONGOLIAN_PRC = 0x02; +pub const SUBLANG_NEPALI_INDIA = 0x02; +pub const SUBLANG_NEPALI_NEPAL = 0x01; +pub const SUBLANG_NORWEGIAN_BOKMAL = 0x01; +pub const SUBLANG_NORWEGIAN_NYNORSK = 0x02; +pub const SUBLANG_OCCITAN_FRANCE = 0x01; +pub const SUBLANG_ODIA_INDIA = 0x01; +pub const SUBLANG_ORIYA_INDIA = 0x01; +pub const SUBLANG_PASHTO_AFGHANISTAN = 0x01; +pub const SUBLANG_PERSIAN_IRAN = 0x01; +pub const SUBLANG_POLISH_POLAND = 0x01; +pub const SUBLANG_PORTUGUESE = 0x02; +pub const SUBLANG_PORTUGUESE_BRAZILIAN = 0x01; +pub const SUBLANG_PULAR_SENEGAL = 0x02; +pub const SUBLANG_PUNJABI_INDIA = 0x01; +pub const SUBLANG_PUNJABI_PAKISTAN = 0x02; +pub const SUBLANG_QUECHUA_BOLIVIA = 0x01; +pub const SUBLANG_QUECHUA_ECUADOR = 0x02; +pub const SUBLANG_QUECHUA_PERU = 0x03; +pub const SUBLANG_ROMANIAN_ROMANIA = 0x01; +pub const SUBLANG_ROMANSH_SWITZERLAND = 0x01; +pub const SUBLANG_RUSSIAN_RUSSIA = 0x01; +pub const SUBLANG_SAKHA_RUSSIA = 0x01; +pub const SUBLANG_SAMI_NORTHERN_NORWAY = 0x01; +pub const SUBLANG_SAMI_NORTHERN_SWEDEN = 0x02; +pub const SUBLANG_SAMI_NORTHERN_FINLAND = 0x03; +pub const SUBLANG_SAMI_LULE_NORWAY = 0x04; +pub const SUBLANG_SAMI_LULE_SWEDEN = 0x05; +pub const SUBLANG_SAMI_SOUTHERN_NORWAY = 0x06; +pub const SUBLANG_SAMI_SOUTHERN_SWEDEN = 0x07; +pub const SUBLANG_SAMI_SKOLT_FINLAND = 0x08; +pub const SUBLANG_SAMI_INARI_FINLAND = 0x09; +pub const SUBLANG_SANSKRIT_INDIA = 0x01; +pub const SUBLANG_SCOTTISH_GAELIC = 0x01; +pub const SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 0x06; +pub const SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x07; +pub const SUBLANG_SERBIAN_MONTENEGRO_LATIN = 0x0b; +pub const SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC = 0x0c; +pub const SUBLANG_SERBIAN_SERBIA_LATIN = 0x09; +pub const SUBLANG_SERBIAN_SERBIA_CYRILLIC = 0x0a; +pub const SUBLANG_SERBIAN_CROATIA = 0x01; +pub const SUBLANG_SERBIAN_LATIN = 0x02; +pub const SUBLANG_SERBIAN_CYRILLIC = 0x03; +pub const SUBLANG_SINDHI_INDIA = 0x01; +pub const SUBLANG_SINDHI_PAKISTAN = 0x02; +pub const SUBLANG_SINDHI_AFGHANISTAN = 0x02; +pub const SUBLANG_SINHALESE_SRI_LANKA = 0x01; +pub const SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA = 0x01; +pub const SUBLANG_SLOVAK_SLOVAKIA = 0x01; +pub const SUBLANG_SLOVENIAN_SLOVENIA = 0x01; +pub const SUBLANG_SPANISH = 0x01; +pub const SUBLANG_SPANISH_MEXICAN = 0x02; +pub const SUBLANG_SPANISH_MODERN = 0x03; +pub const SUBLANG_SPANISH_GUATEMALA = 0x04; +pub const SUBLANG_SPANISH_COSTA_RICA = 0x05; +pub const SUBLANG_SPANISH_PANAMA = 0x06; +pub const SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07; +pub const SUBLANG_SPANISH_VENEZUELA = 0x08; +pub const SUBLANG_SPANISH_COLOMBIA = 0x09; +pub const SUBLANG_SPANISH_PERU = 0x0a; +pub const SUBLANG_SPANISH_ARGENTINA = 0x0b; +pub const SUBLANG_SPANISH_ECUADOR = 0x0c; +pub const SUBLANG_SPANISH_CHILE = 0x0d; +pub const SUBLANG_SPANISH_URUGUAY = 0x0e; +pub const SUBLANG_SPANISH_PARAGUAY = 0x0f; +pub const SUBLANG_SPANISH_BOLIVIA = 0x10; +pub const SUBLANG_SPANISH_EL_SALVADOR = 0x11; +pub const SUBLANG_SPANISH_HONDURAS = 0x12; +pub const SUBLANG_SPANISH_NICARAGUA = 0x13; +pub const SUBLANG_SPANISH_PUERTO_RICO = 0x14; +pub const SUBLANG_SPANISH_US = 0x15; +pub const SUBLANG_SWAHILI_KENYA = 0x01; +pub const SUBLANG_SWEDISH = 0x01; +pub const SUBLANG_SWEDISH_FINLAND = 0x02; +pub const SUBLANG_SYRIAC_SYRIA = 0x01; +pub const SUBLANG_TAJIK_TAJIKISTAN = 0x01; +pub const SUBLANG_TAMAZIGHT_ALGERIA_LATIN = 0x02; +pub const SUBLANG_TAMAZIGHT_MOROCCO_TIFINAGH = 0x04; +pub const SUBLANG_TAMIL_INDIA = 0x01; +pub const SUBLANG_TAMIL_SRI_LANKA = 0x02; +pub const SUBLANG_TATAR_RUSSIA = 0x01; +pub const SUBLANG_TELUGU_INDIA = 0x01; +pub const SUBLANG_THAI_THAILAND = 0x01; +pub const SUBLANG_TIBETAN_PRC = 0x01; +pub const SUBLANG_TIGRIGNA_ERITREA = 0x02; +pub const SUBLANG_TIGRINYA_ERITREA = 0x02; +pub const SUBLANG_TIGRINYA_ETHIOPIA = 0x01; +pub const SUBLANG_TSWANA_BOTSWANA = 0x02; +pub const SUBLANG_TSWANA_SOUTH_AFRICA = 0x01; +pub const SUBLANG_TURKISH_TURKEY = 0x01; +pub const SUBLANG_TURKMEN_TURKMENISTAN = 0x01; +pub const SUBLANG_UIGHUR_PRC = 0x01; +pub const SUBLANG_UKRAINIAN_UKRAINE = 0x01; +pub const SUBLANG_UPPER_SORBIAN_GERMANY = 0x01; +pub const SUBLANG_URDU_PAKISTAN = 0x01; +pub const SUBLANG_URDU_INDIA = 0x02; +pub const SUBLANG_UZBEK_LATIN = 0x01; +pub const SUBLANG_UZBEK_CYRILLIC = 0x02; +pub const SUBLANG_VALENCIAN_VALENCIA = 0x02; +pub const SUBLANG_VIETNAMESE_VIETNAM = 0x01; +pub const SUBLANG_WELSH_UNITED_KINGDOM = 0x01; +pub const SUBLANG_WOLOF_SENEGAL = 0x01; +pub const SUBLANG_XHOSA_SOUTH_AFRICA = 0x01; +pub const SUBLANG_YAKUT_RUSSIA = 0x01; +pub const SUBLANG_YI_PRC = 0x01; +pub const SUBLANG_YORUBA_NIGERIA = 0x01; +pub const SUBLANG_ZULU_SOUTH_AFRICA = 0x01; -- 2.54.0 From 0aabfb09f9a33f7199e53996a0baa9b5eb8b1e50 Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 5 Jun 2019 14:57:20 -0500 Subject: [PATCH 75/84] removed duplicate definitions --- std/os/windows/bits.zig | 2 -- 1 file changed, 2 deletions(-) diff --git a/std/os/windows/bits.zig b/std/os/windows/bits.zig index d05266c9fc1b01e0081966a570471edb548aed0b..b463ef4c61fecdb8ca16984ba2022edac9232967 100644 --- a/std/os/windows/bits.zig +++ b/std/os/windows/bits.zig @@ -538,5 +538,3 @@ pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400; pub const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000; pub const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200; pub const FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF; -pub const FORMAT_MESSAGE_FROM_HMODULE = 0x00000800; -pub const FORMAT_MESSAGE_FROM_STRING = 0x00000400; -- 2.54.0 From ddfab40e30e04e1874bff95e5cae54eaaca5542f Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 5 Jun 2019 14:54:24 -0500 Subject: [PATCH 76/84] updated std.c.{freebsd, netbsd} to usingnamespace --- std/c/freebsd.zig | 2 +- std/c/netbsd.zig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/std/c/freebsd.zig b/std/c/freebsd.zig index eaa073677ddb0b11a42b890cb0afa5c692674c6b..bcc60e65ed0a3345438f1c29cb5234689721752c 100644 --- a/std/c/freebsd.zig +++ b/std/c/freebsd.zig @@ -1,5 +1,5 @@ const std = @import("../std.zig"); -use std.c; +usingnamespace std.c; extern "c" fn __error() *c_int; pub const _errno = __error; diff --git a/std/c/netbsd.zig b/std/c/netbsd.zig index 0ee94e822090fdab156ed539455a093a78012add..417c78db6994450851d14453bdecd7672b90168c 100644 --- a/std/c/netbsd.zig +++ b/std/c/netbsd.zig @@ -1,5 +1,5 @@ const std = @import("../std.zig"); -use std.c; +usingnamespace std.c; extern "c" fn __errno() *c_int; pub const _errno = __errno; -- 2.54.0 From 0288034c2f2d158970cd481e1810a2301ab0b50a Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 5 Jun 2019 15:30:01 -0500 Subject: [PATCH 77/84] fixed mismatched types --- CMakeLists.txt | 1 + std/os/windows.zig | 4 ++-- std/os/windows/kernel32.zig | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ff4cebf40c962c67a229dec96b4e1de4b729bc7..206e2ccf9949066ce6fcce600867f12369d7f0e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -630,6 +630,7 @@ set(ZIG_STD_FILES "os/windows/bits.zig" "os/windows/error.zig" "os/windows/kernel32.zig" + "os/windows/lang.zig" "os/windows/ntdll.zig" "os/windows/ole32.zig" "os/windows/shell32.zig" diff --git a/std/os/windows.zig b/std/os/windows.zig index 0757d9924f3130468f6a511a35daa85717ddf0ba..4d5dda0142a3a9ef4d8489fefe5d438c140835a9 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -756,7 +756,7 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) return result; } -inline fn MAKELANGID(p: USHORT, s: USHORT) LANGID { +inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID { return (s << 10) | p; } @@ -765,7 +765,7 @@ inline fn MAKELANGID(p: USHORT, s: USHORT) LANGID { pub fn unexpectedError(err: DWORD) std.os.UnexpectedError { if (std.os.unexpected_error_tracing) { var buf: LPSTR = undefined; - const len = kernel32.FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.LANG_NEUTRAL, LANG.SUBLANG_DEFAULT), buf, 0, null); + const len = kernel32.FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.LANG_NEUTRAL, LANG.SUBLANG_DEFAULT), @ptrCast(LPSTR, &buf), 0, null); defer _ = kernel32.LocalFree(@ptrCast(HLOCAL, buf)); std.debug.warn("error.Unexpected: {}: {}\n", err, buf[0..len]); diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index bee1b82544672e8d4f78beb9540bbab491ced6ed..fb1cff00f7b7aea2b27b28c09a1a8c005922aea6 100644 --- a/std/os/windows/kernel32.zig +++ b/std/os/windows/kernel32.zig @@ -50,7 +50,7 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; -pub extern "kernel32" stdcallcc fn FormatMessageA(dwFlags: DWORD, lpSource: LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; +pub extern "kernel32" stdcallcc fn FormatMessageA(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; -- 2.54.0 From 26613bfa011ec63b1f3a141e0201223853cc04e6 Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 5 Jun 2019 17:18:56 -0500 Subject: [PATCH 78/84] switched to fixed-length buffer for error messages --- CMakeLists.txt | 1 + std/os/windows.zig | 14 +- std/os/windows/bits.zig | 1 + std/os/windows/kernel32.zig | 4 +- std/os/windows/lang.zig | 524 ++++++++++-------------------------- std/os/windows/sublang.zig | 244 +++++++++++++++++ 6 files changed, 396 insertions(+), 392 deletions(-) create mode 100644 std/os/windows/sublang.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index 206e2ccf9949066ce6fcce600867f12369d7f0e1..d77b6f09ab0cdea4a78f4c9bdffc95d279611c31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -634,6 +634,7 @@ set(ZIG_STD_FILES "os/windows/ntdll.zig" "os/windows/ole32.zig" "os/windows/shell32.zig" + "os/windows/sublang.zig" "os/zen.zig" "packed_int_array.zig" "pdb.zig" diff --git a/std/os/windows.zig b/std/os/windows.zig index 4d5dda0142a3a9ef4d8489fefe5d438c140835a9..1b25f59a55b53a1aad87d7e984f2d7c88f32aee7 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -764,11 +764,15 @@ inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID { /// and you get an unexpected error. pub fn unexpectedError(err: DWORD) std.os.UnexpectedError { if (std.os.unexpected_error_tracing) { - var buf: LPSTR = undefined; - const len = kernel32.FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, err, MAKELANGID(LANG.LANG_NEUTRAL, LANG.SUBLANG_DEFAULT), @ptrCast(LPSTR, &buf), 0, null); - defer _ = kernel32.LocalFree(@ptrCast(HLOCAL, buf)); - std.debug.warn("error.Unexpected: {}: {}\n", err, buf[0..len]); - + // 614 is the length of the longest windows error desciption + var buf_u16: [614]u16 = undefined; + var buf_u8: [614]u8 = undefined; + var len = kernel32.FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + null, err, MAKELANGID(LANG.NEUTRAL, SUBLANG.DEFAULT), + buf_u16[0..].ptr, buf_u16.len / @sizeOf(TCHAR), null); + _ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable; + std.debug.warn("error.Unexpected: GetLastError({}): {}\n", err, buf_u8[0..len]); std.debug.dumpCurrentStackTrace(null); } return error.Unexpected; diff --git a/std/os/windows/bits.zig b/std/os/windows/bits.zig index b463ef4c61fecdb8ca16984ba2022edac9232967..c99f3ae4639f8e6e84d4113afb648e776aa0742e 100644 --- a/std/os/windows/bits.zig +++ b/std/os/windows/bits.zig @@ -7,6 +7,7 @@ const maxInt = std.math.maxInt; pub const ERROR = @import("error.zig"); pub const LANG = @import("lang.zig"); +pub const SUBLANG = @import("sublang.zig"); /// The standard input device. Initially, this is the console input buffer, CONIN$. pub const STD_INPUT_HANDLE = maxInt(DWORD) - 10 + 1; diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig index fb1cff00f7b7aea2b27b28c09a1a8c005922aea6..27516342ac33e63191ec9e43cb39cb89dfef2642 100644 --- a/std/os/windows/kernel32.zig +++ b/std/os/windows/kernel32.zig @@ -50,7 +50,7 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL; -pub extern "kernel32" stdcallcc fn FormatMessageA(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; +pub extern "kernel32" stdcallcc fn FormatMessageW(dwFlags: DWORD, lpSource: ?LPVOID, dwMessageId: DWORD, dwLanguageId: DWORD, lpBuffer: LPWSTR, nSize: DWORD, Arguments: ?*va_list) DWORD; pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL; @@ -118,8 +118,6 @@ pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: ?*const c_void) BOOL; -pub extern "kernel32" stdcallcc fn LocalFree(hMem: HLOCAL) ?HLOCAL; - pub extern "kernel32" stdcallcc fn VirtualAlloc(lpAddress: ?LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD) ?LPVOID; pub extern "kernel32" stdcallcc fn VirtualFree(lpAddress: ?LPVOID, dwSize: SIZE_T, dwFreeType: DWORD) BOOL; diff --git a/std/os/windows/lang.zig b/std/os/windows/lang.zig index 7e6e2d1a799e25030b87d44bb8a7c053581a8a4d..b173a62a73dc846a2e174031ed54d55da217a5bf 100644 --- a/std/os/windows/lang.zig +++ b/std/os/windows/lang.zig @@ -1,384 +1,140 @@ -pub const LANG_NEUTRAL = 0x00; -pub const LANG_INVARIANT = 0x7f; -pub const LANG_AFRIKAANS = 0x36; -pub const LANG_ALBANIAN = 0x1c; -pub const LANG_ALSATIAN = 0x84; -pub const LANG_AMHARIC = 0x5e; -pub const LANG_ARABIC = 0x01; -pub const LANG_ARMENIAN = 0x2b; -pub const LANG_ASSAMESE = 0x4d; -pub const LANG_AZERI = 0x2c; -pub const LANG_AZERBAIJANI = 0x2c; -pub const LANG_BANGLA = 0x45; -pub const LANG_BASHKIR = 0x6d; -pub const LANG_BASQUE = 0x2d; -pub const LANG_BELARUSIAN = 0x23; -pub const LANG_BENGALI = 0x45; -pub const LANG_BRETON = 0x7e; -pub const LANG_BOSNIAN = 0x1a; -pub const LANG_BOSNIAN_NEUTRAL = 0x781a; -pub const LANG_BULGARIAN = 0x02; -pub const LANG_CATALAN = 0x03; -pub const LANG_CENTRAL_KURDISH = 0x92; -pub const LANG_CHEROKEE = 0x5c; -pub const LANG_CHINESE = 0x04; -pub const LANG_CHINESE_SIMPLIFIED = 0x04; -pub const LANG_CHINESE_TRADITIONAL = 0x7c04; -pub const LANG_CORSICAN = 0x83; -pub const LANG_CROATIAN = 0x1a; -pub const LANG_CZECH = 0x05; -pub const LANG_DANISH = 0x06; -pub const LANG_DARI = 0x8c; -pub const LANG_DIVEHI = 0x65; -pub const LANG_DUTCH = 0x13; -pub const LANG_ENGLISH = 0x09; -pub const LANG_ESTONIAN = 0x25; -pub const LANG_FAEROESE = 0x38; -pub const LANG_FARSI = 0x29; -pub const LANG_FILIPINO = 0x64; -pub const LANG_FINNISH = 0x0b; -pub const LANG_FRENCH = 0x0c; -pub const LANG_FRISIAN = 0x62; -pub const LANG_FULAH = 0x67; -pub const LANG_GALICIAN = 0x56; -pub const LANG_GEORGIAN = 0x37; -pub const LANG_GERMAN = 0x07; -pub const LANG_GREEK = 0x08; -pub const LANG_GREENLANDIC = 0x6f; -pub const LANG_GUJARATI = 0x47; -pub const LANG_HAUSA = 0x68; -pub const LANG_HAWAIIAN = 0x75; -pub const LANG_HEBREW = 0x0d; -pub const LANG_HINDI = 0x39; -pub const LANG_HUNGARIAN = 0x0e; -pub const LANG_ICELANDIC = 0x0f; -pub const LANG_IGBO = 0x70; -pub const LANG_INDONESIAN = 0x21; -pub const LANG_INUKTITUT = 0x5d; -pub const LANG_IRISH = 0x3c; -pub const LANG_ITALIAN = 0x10; -pub const LANG_JAPANESE = 0x11; -pub const LANG_KANNADA = 0x4b; -pub const LANG_KASHMIRI = 0x60; -pub const LANG_KAZAK = 0x3f; -pub const LANG_KHMER = 0x53; -pub const LANG_KICHE = 0x86; -pub const LANG_KINYARWANDA = 0x87; -pub const LANG_KONKANI = 0x57; -pub const LANG_KOREAN = 0x12; -pub const LANG_KYRGYZ = 0x40; -pub const LANG_LAO = 0x54; -pub const LANG_LATVIAN = 0x26; -pub const LANG_LITHUANIAN = 0x27; -pub const LANG_LOWER_SORBIAN = 0x2e; -pub const LANG_LUXEMBOURGISH = 0x6e; -pub const LANG_MACEDONIAN = 0x2f; -pub const LANG_MALAY = 0x3e; -pub const LANG_MALAYALAM = 0x4c; -pub const LANG_MALTESE = 0x3a; -pub const LANG_MANIPURI = 0x58; -pub const LANG_MAORI = 0x81; -pub const LANG_MAPUDUNGUN = 0x7a; -pub const LANG_MARATHI = 0x4e; -pub const LANG_MOHAWK = 0x7c; -pub const LANG_MONGOLIAN = 0x50; -pub const LANG_NEPALI = 0x61; -pub const LANG_NORWEGIAN = 0x14; -pub const LANG_OCCITAN = 0x82; -pub const LANG_ODIA = 0x48; -pub const LANG_ORIYA = 0x48; -pub const LANG_PASHTO = 0x63; -pub const LANG_PERSIAN = 0x29; -pub const LANG_POLISH = 0x15; -pub const LANG_PORTUGUESE = 0x16; -pub const LANG_PULAR = 0x67; -pub const LANG_PUNJABI = 0x46; -pub const LANG_QUECHUA = 0x6b; -pub const LANG_ROMANIAN = 0x18; -pub const LANG_ROMANSH = 0x17; -pub const LANG_RUSSIAN = 0x19; -pub const LANG_SAKHA = 0x85; -pub const LANG_SAMI = 0x3b; -pub const LANG_SANSKRIT = 0x4f; -pub const LANG_SCOTTISH_GAELIC = 0x91; -pub const LANG_SERBIAN = 0x1a; -pub const LANG_SERBIAN_NEUTRAL = 0x7c1a; -pub const LANG_SINDHI = 0x59; -pub const LANG_SINHALESE = 0x5b; -pub const LANG_SLOVAK = 0x1b; -pub const LANG_SLOVENIAN = 0x24; -pub const LANG_SOTHO = 0x6c; -pub const LANG_SPANISH = 0x0a; -pub const LANG_SWAHILI = 0x41; -pub const LANG_SWEDISH = 0x1d; -pub const LANG_SYRIAC = 0x5a; -pub const LANG_TAJIK = 0x28; -pub const LANG_TAMAZIGHT = 0x5f; -pub const LANG_TAMIL = 0x49; -pub const LANG_TATAR = 0x44; -pub const LANG_TELUGU = 0x4a; -pub const LANG_THAI = 0x1e; -pub const LANG_TIBETAN = 0x51; -pub const LANG_TIGRIGNA = 0x73; -pub const LANG_TIGRINYA = 0x73; -pub const LANG_TSWANA = 0x32; -pub const LANG_TURKISH = 0x1f; -pub const LANG_TURKMEN = 0x42; -pub const LANG_UIGHUR = 0x80; -pub const LANG_UKRAINIAN = 0x22; -pub const LANG_UPPER_SORBIAN = 0x2e; -pub const LANG_URDU = 0x20; -pub const LANG_UZBEK = 0x43; -pub const LANG_VALENCIAN = 0x03; -pub const LANG_VIETNAMESE = 0x2a; -pub const LANG_WELSH = 0x52; -pub const LANG_WOLOF = 0x88; -pub const LANG_XHOSA = 0x34; -pub const LANG_YAKUT = 0x85; -pub const LANG_YI = 0x78; -pub const LANG_YORUBA = 0x6a; -pub const LANG_ZULU = 0x35; -pub const SUBLANG_NEUTRAL = 0x00; -pub const SUBLANG_DEFAULT = 0x01; -pub const SUBLANG_SYS_DEFAULT = 0x02; -pub const SUBLANG_CUSTOM_DEFAULT = 0x03; -pub const SUBLANG_CUSTOM_UNSPECIFIED = 0x04; -pub const SUBLANG_UI_CUSTOM_DEFAULT = 0x05; -pub const SUBLANG_AFRIKAANS_SOUTH_AFRICA = 0x01; -pub const SUBLANG_ALBANIAN_ALBANIA = 0x01; -pub const SUBLANG_ALSATIAN_FRANCE = 0x01; -pub const SUBLANG_AMHARIC_ETHIOPIA = 0x01; -pub const SUBLANG_ARABIC_SAUDI_ARABIA = 0x01; -pub const SUBLANG_ARABIC_IRAQ = 0x02; -pub const SUBLANG_ARABIC_EGYPT = 0x03; -pub const SUBLANG_ARABIC_LIBYA = 0x04; -pub const SUBLANG_ARABIC_ALGERIA = 0x05; -pub const SUBLANG_ARABIC_MOROCCO = 0x06; -pub const SUBLANG_ARABIC_TUNISIA = 0x07; -pub const SUBLANG_ARABIC_OMAN = 0x08; -pub const SUBLANG_ARABIC_YEMEN = 0x09; -pub const SUBLANG_ARABIC_SYRIA = 0x0a; -pub const SUBLANG_ARABIC_JORDAN = 0x0b; -pub const SUBLANG_ARABIC_LEBANON = 0x0c; -pub const SUBLANG_ARABIC_KUWAIT = 0x0d; -pub const SUBLANG_ARABIC_UAE = 0x0e; -pub const SUBLANG_ARABIC_BAHRAIN = 0x0f; -pub const SUBLANG_ARABIC_QATAR = 0x10; -pub const SUBLANG_ARMENIAN_ARMENIA = 0x01; -pub const SUBLANG_ASSAMESE_INDIA = 0x01; -pub const SUBLANG_AZERI_LATIN = 0x01; -pub const SUBLANG_AZERI_CYRILLIC = 0x02; -pub const SUBLANG_AZERBAIJANI_AZERBAIJAN_LATIN = 0x01; -pub const SUBLANG_AZERBAIJANI_AZERBAIJAN_CYRILLIC = 0x02; -pub const SUBLANG_BANGLA_INDIA = 0x01; -pub const SUBLANG_BANGLA_BANGLADESH = 0x02; -pub const SUBLANG_BASHKIR_RUSSIA = 0x01; -pub const SUBLANG_BASQUE_BASQUE = 0x01; -pub const SUBLANG_BELARUSIAN_BELARUS = 0x01; -pub const SUBLANG_BENGALI_INDIA = 0x01; -pub const SUBLANG_BENGALI_BANGLADESH = 0x02; -pub const SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 0x05; -pub const SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x08; -pub const SUBLANG_BRETON_FRANCE = 0x01; -pub const SUBLANG_BULGARIAN_BULGARIA = 0x01; -pub const SUBLANG_CATALAN_CATALAN = 0x01; -pub const SUBLANG_CENTRAL_KURDISH_IRAQ = 0x01; -pub const SUBLANG_CHEROKEE_CHEROKEE = 0x01; -pub const SUBLANG_CHINESE_TRADITIONAL = 0x01; -pub const SUBLANG_CHINESE_SIMPLIFIED = 0x02; -pub const SUBLANG_CHINESE_HONGKONG = 0x03; -pub const SUBLANG_CHINESE_SINGAPORE = 0x04; -pub const SUBLANG_CHINESE_MACAU = 0x05; -pub const SUBLANG_CORSICAN_FRANCE = 0x01; -pub const SUBLANG_CZECH_CZECH_REPUBLIC = 0x01; -pub const SUBLANG_CROATIAN_CROATIA = 0x01; -pub const SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 0x04; -pub const SUBLANG_DANISH_DENMARK = 0x01; -pub const SUBLANG_DARI_AFGHANISTAN = 0x01; -pub const SUBLANG_DIVEHI_MALDIVES = 0x01; -pub const SUBLANG_DUTCH = 0x01; -pub const SUBLANG_DUTCH_BELGIAN = 0x02; -pub const SUBLANG_ENGLISH_US = 0x01; -pub const SUBLANG_ENGLISH_UK = 0x02; -pub const SUBLANG_ENGLISH_AUS = 0x03; -pub const SUBLANG_ENGLISH_CAN = 0x04; -pub const SUBLANG_ENGLISH_NZ = 0x05; -pub const SUBLANG_ENGLISH_EIRE = 0x06; -pub const SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07; -pub const SUBLANG_ENGLISH_JAMAICA = 0x08; -pub const SUBLANG_ENGLISH_CARIBBEAN = 0x09; -pub const SUBLANG_ENGLISH_BELIZE = 0x0a; -pub const SUBLANG_ENGLISH_TRINIDAD = 0x0b; -pub const SUBLANG_ENGLISH_ZIMBABWE = 0x0c; -pub const SUBLANG_ENGLISH_PHILIPPINES = 0x0d; -pub const SUBLANG_ENGLISH_INDIA = 0x10; -pub const SUBLANG_ENGLISH_MALAYSIA = 0x11; -pub const SUBLANG_ENGLISH_SINGAPORE = 0x12; -pub const SUBLANG_ESTONIAN_ESTONIA = 0x01; -pub const SUBLANG_FAEROESE_FAROE_ISLANDS = 0x01; -pub const SUBLANG_FILIPINO_PHILIPPINES = 0x01; -pub const SUBLANG_FINNISH_FINLAND = 0x01; -pub const SUBLANG_FRENCH = 0x01; -pub const SUBLANG_FRENCH_BELGIAN = 0x02; -pub const SUBLANG_FRENCH_CANADIAN = 0x03; -pub const SUBLANG_FRENCH_SWISS = 0x04; -pub const SUBLANG_FRENCH_LUXEMBOURG = 0x05; -pub const SUBLANG_FRENCH_MONACO = 0x06; -pub const SUBLANG_FRISIAN_NETHERLANDS = 0x01; -pub const SUBLANG_FULAH_SENEGAL = 0x02; -pub const SUBLANG_GALICIAN_GALICIAN = 0x01; -pub const SUBLANG_GEORGIAN_GEORGIA = 0x01; -pub const SUBLANG_GERMAN = 0x01; -pub const SUBLANG_GERMAN_SWISS = 0x02; -pub const SUBLANG_GERMAN_AUSTRIAN = 0x03; -pub const SUBLANG_GERMAN_LUXEMBOURG = 0x04; -pub const SUBLANG_GERMAN_LIECHTENSTEIN = 0x05; -pub const SUBLANG_GREEK_GREECE = 0x01; -pub const SUBLANG_GREENLANDIC_GREENLAND = 0x01; -pub const SUBLANG_GUJARATI_INDIA = 0x01; -pub const SUBLANG_HAUSA_NIGERIA_LATIN = 0x01; -pub const SUBLANG_HAWAIIAN_US = 0x01; -pub const SUBLANG_HEBREW_ISRAEL = 0x01; -pub const SUBLANG_HINDI_INDIA = 0x01; -pub const SUBLANG_HUNGARIAN_HUNGARY = 0x01; -pub const SUBLANG_ICELANDIC_ICELAND = 0x01; -pub const SUBLANG_IGBO_NIGERIA = 0x01; -pub const SUBLANG_INDONESIAN_INDONESIA = 0x01; -pub const SUBLANG_INUKTITUT_CANADA = 0x01; -pub const SUBLANG_INUKTITUT_CANADA_LATIN = 0x02; -pub const SUBLANG_IRISH_IRELAND = 0x02; -pub const SUBLANG_ITALIAN = 0x01; -pub const SUBLANG_ITALIAN_SWISS = 0x02; -pub const SUBLANG_JAPANESE_JAPAN = 0x01; -pub const SUBLANG_KANNADA_INDIA = 0x01; -pub const SUBLANG_KASHMIRI_SASIA = 0x02; -pub const SUBLANG_KASHMIRI_INDIA = 0x02; -pub const SUBLANG_KAZAK_KAZAKHSTAN = 0x01; -pub const SUBLANG_KHMER_CAMBODIA = 0x01; -pub const SUBLANG_KICHE_GUATEMALA = 0x01; -pub const SUBLANG_KINYARWANDA_RWANDA = 0x01; -pub const SUBLANG_KONKANI_INDIA = 0x01; -pub const SUBLANG_KOREAN = 0x01; -pub const SUBLANG_KYRGYZ_KYRGYZSTAN = 0x01; -pub const SUBLANG_LAO_LAO = 0x01; -pub const SUBLANG_LATVIAN_LATVIA = 0x01; -pub const SUBLANG_LITHUANIAN = 0x01; -pub const SUBLANG_LOWER_SORBIAN_GERMANY = 0x02; -pub const SUBLANG_LUXEMBOURGISH_LUXEMBOURG = 0x01; -pub const SUBLANG_MACEDONIAN_MACEDONIA = 0x01; -pub const SUBLANG_MALAY_MALAYSIA = 0x01; -pub const SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02; -pub const SUBLANG_MALAYALAM_INDIA = 0x01; -pub const SUBLANG_MALTESE_MALTA = 0x01; -pub const SUBLANG_MAORI_NEW_ZEALAND = 0x01; -pub const SUBLANG_MAPUDUNGUN_CHILE = 0x01; -pub const SUBLANG_MARATHI_INDIA = 0x01; -pub const SUBLANG_MOHAWK_MOHAWK = 0x01; -pub const SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA = 0x01; -pub const SUBLANG_MONGOLIAN_PRC = 0x02; -pub const SUBLANG_NEPALI_INDIA = 0x02; -pub const SUBLANG_NEPALI_NEPAL = 0x01; -pub const SUBLANG_NORWEGIAN_BOKMAL = 0x01; -pub const SUBLANG_NORWEGIAN_NYNORSK = 0x02; -pub const SUBLANG_OCCITAN_FRANCE = 0x01; -pub const SUBLANG_ODIA_INDIA = 0x01; -pub const SUBLANG_ORIYA_INDIA = 0x01; -pub const SUBLANG_PASHTO_AFGHANISTAN = 0x01; -pub const SUBLANG_PERSIAN_IRAN = 0x01; -pub const SUBLANG_POLISH_POLAND = 0x01; -pub const SUBLANG_PORTUGUESE = 0x02; -pub const SUBLANG_PORTUGUESE_BRAZILIAN = 0x01; -pub const SUBLANG_PULAR_SENEGAL = 0x02; -pub const SUBLANG_PUNJABI_INDIA = 0x01; -pub const SUBLANG_PUNJABI_PAKISTAN = 0x02; -pub const SUBLANG_QUECHUA_BOLIVIA = 0x01; -pub const SUBLANG_QUECHUA_ECUADOR = 0x02; -pub const SUBLANG_QUECHUA_PERU = 0x03; -pub const SUBLANG_ROMANIAN_ROMANIA = 0x01; -pub const SUBLANG_ROMANSH_SWITZERLAND = 0x01; -pub const SUBLANG_RUSSIAN_RUSSIA = 0x01; -pub const SUBLANG_SAKHA_RUSSIA = 0x01; -pub const SUBLANG_SAMI_NORTHERN_NORWAY = 0x01; -pub const SUBLANG_SAMI_NORTHERN_SWEDEN = 0x02; -pub const SUBLANG_SAMI_NORTHERN_FINLAND = 0x03; -pub const SUBLANG_SAMI_LULE_NORWAY = 0x04; -pub const SUBLANG_SAMI_LULE_SWEDEN = 0x05; -pub const SUBLANG_SAMI_SOUTHERN_NORWAY = 0x06; -pub const SUBLANG_SAMI_SOUTHERN_SWEDEN = 0x07; -pub const SUBLANG_SAMI_SKOLT_FINLAND = 0x08; -pub const SUBLANG_SAMI_INARI_FINLAND = 0x09; -pub const SUBLANG_SANSKRIT_INDIA = 0x01; -pub const SUBLANG_SCOTTISH_GAELIC = 0x01; -pub const SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 0x06; -pub const SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x07; -pub const SUBLANG_SERBIAN_MONTENEGRO_LATIN = 0x0b; -pub const SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC = 0x0c; -pub const SUBLANG_SERBIAN_SERBIA_LATIN = 0x09; -pub const SUBLANG_SERBIAN_SERBIA_CYRILLIC = 0x0a; -pub const SUBLANG_SERBIAN_CROATIA = 0x01; -pub const SUBLANG_SERBIAN_LATIN = 0x02; -pub const SUBLANG_SERBIAN_CYRILLIC = 0x03; -pub const SUBLANG_SINDHI_INDIA = 0x01; -pub const SUBLANG_SINDHI_PAKISTAN = 0x02; -pub const SUBLANG_SINDHI_AFGHANISTAN = 0x02; -pub const SUBLANG_SINHALESE_SRI_LANKA = 0x01; -pub const SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA = 0x01; -pub const SUBLANG_SLOVAK_SLOVAKIA = 0x01; -pub const SUBLANG_SLOVENIAN_SLOVENIA = 0x01; -pub const SUBLANG_SPANISH = 0x01; -pub const SUBLANG_SPANISH_MEXICAN = 0x02; -pub const SUBLANG_SPANISH_MODERN = 0x03; -pub const SUBLANG_SPANISH_GUATEMALA = 0x04; -pub const SUBLANG_SPANISH_COSTA_RICA = 0x05; -pub const SUBLANG_SPANISH_PANAMA = 0x06; -pub const SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07; -pub const SUBLANG_SPANISH_VENEZUELA = 0x08; -pub const SUBLANG_SPANISH_COLOMBIA = 0x09; -pub const SUBLANG_SPANISH_PERU = 0x0a; -pub const SUBLANG_SPANISH_ARGENTINA = 0x0b; -pub const SUBLANG_SPANISH_ECUADOR = 0x0c; -pub const SUBLANG_SPANISH_CHILE = 0x0d; -pub const SUBLANG_SPANISH_URUGUAY = 0x0e; -pub const SUBLANG_SPANISH_PARAGUAY = 0x0f; -pub const SUBLANG_SPANISH_BOLIVIA = 0x10; -pub const SUBLANG_SPANISH_EL_SALVADOR = 0x11; -pub const SUBLANG_SPANISH_HONDURAS = 0x12; -pub const SUBLANG_SPANISH_NICARAGUA = 0x13; -pub const SUBLANG_SPANISH_PUERTO_RICO = 0x14; -pub const SUBLANG_SPANISH_US = 0x15; -pub const SUBLANG_SWAHILI_KENYA = 0x01; -pub const SUBLANG_SWEDISH = 0x01; -pub const SUBLANG_SWEDISH_FINLAND = 0x02; -pub const SUBLANG_SYRIAC_SYRIA = 0x01; -pub const SUBLANG_TAJIK_TAJIKISTAN = 0x01; -pub const SUBLANG_TAMAZIGHT_ALGERIA_LATIN = 0x02; -pub const SUBLANG_TAMAZIGHT_MOROCCO_TIFINAGH = 0x04; -pub const SUBLANG_TAMIL_INDIA = 0x01; -pub const SUBLANG_TAMIL_SRI_LANKA = 0x02; -pub const SUBLANG_TATAR_RUSSIA = 0x01; -pub const SUBLANG_TELUGU_INDIA = 0x01; -pub const SUBLANG_THAI_THAILAND = 0x01; -pub const SUBLANG_TIBETAN_PRC = 0x01; -pub const SUBLANG_TIGRIGNA_ERITREA = 0x02; -pub const SUBLANG_TIGRINYA_ERITREA = 0x02; -pub const SUBLANG_TIGRINYA_ETHIOPIA = 0x01; -pub const SUBLANG_TSWANA_BOTSWANA = 0x02; -pub const SUBLANG_TSWANA_SOUTH_AFRICA = 0x01; -pub const SUBLANG_TURKISH_TURKEY = 0x01; -pub const SUBLANG_TURKMEN_TURKMENISTAN = 0x01; -pub const SUBLANG_UIGHUR_PRC = 0x01; -pub const SUBLANG_UKRAINIAN_UKRAINE = 0x01; -pub const SUBLANG_UPPER_SORBIAN_GERMANY = 0x01; -pub const SUBLANG_URDU_PAKISTAN = 0x01; -pub const SUBLANG_URDU_INDIA = 0x02; -pub const SUBLANG_UZBEK_LATIN = 0x01; -pub const SUBLANG_UZBEK_CYRILLIC = 0x02; -pub const SUBLANG_VALENCIAN_VALENCIA = 0x02; -pub const SUBLANG_VIETNAMESE_VIETNAM = 0x01; -pub const SUBLANG_WELSH_UNITED_KINGDOM = 0x01; -pub const SUBLANG_WOLOF_SENEGAL = 0x01; -pub const SUBLANG_XHOSA_SOUTH_AFRICA = 0x01; -pub const SUBLANG_YAKUT_RUSSIA = 0x01; -pub const SUBLANG_YI_PRC = 0x01; -pub const SUBLANG_YORUBA_NIGERIA = 0x01; -pub const SUBLANG_ZULU_SOUTH_AFRICA = 0x01; +pub const NEUTRAL = 0x00; +pub const INVARIANT = 0x7f; +pub const AFRIKAANS = 0x36; +pub const ALBANIAN = 0x1c; +pub const ALSATIAN = 0x84; +pub const AMHARIC = 0x5e; +pub const ARABIC = 0x01; +pub const ARMENIAN = 0x2b; +pub const ASSAMESE = 0x4d; +pub const AZERI = 0x2c; +pub const AZERBAIJANI = 0x2c; +pub const BANGLA = 0x45; +pub const BASHKIR = 0x6d; +pub const BASQUE = 0x2d; +pub const BELARUSIAN = 0x23; +pub const BENGALI = 0x45; +pub const BRETON = 0x7e; +pub const BOSNIAN = 0x1a; +pub const BOSNIAN_NEUTRAL = 0x781a; +pub const BULGARIAN = 0x02; +pub const CATALAN = 0x03; +pub const CENTRAL_KURDISH = 0x92; +pub const CHEROKEE = 0x5c; +pub const CHINESE = 0x04; +pub const CHINESE_SIMPLIFIED = 0x04; +pub const CHINESE_TRADITIONAL = 0x7c04; +pub const CORSICAN = 0x83; +pub const CROATIAN = 0x1a; +pub const CZECH = 0x05; +pub const DANISH = 0x06; +pub const DARI = 0x8c; +pub const DIVEHI = 0x65; +pub const DUTCH = 0x13; +pub const ENGLISH = 0x09; +pub const ESTONIAN = 0x25; +pub const FAEROESE = 0x38; +pub const FARSI = 0x29; +pub const FILIPINO = 0x64; +pub const FINNISH = 0x0b; +pub const FRENCH = 0x0c; +pub const FRISIAN = 0x62; +pub const FULAH = 0x67; +pub const GALICIAN = 0x56; +pub const GEORGIAN = 0x37; +pub const GERMAN = 0x07; +pub const GREEK = 0x08; +pub const GREENLANDIC = 0x6f; +pub const GUJARATI = 0x47; +pub const HAUSA = 0x68; +pub const HAWAIIAN = 0x75; +pub const HEBREW = 0x0d; +pub const HINDI = 0x39; +pub const HUNGARIAN = 0x0e; +pub const ICELANDIC = 0x0f; +pub const IGBO = 0x70; +pub const INDONESIAN = 0x21; +pub const INUKTITUT = 0x5d; +pub const IRISH = 0x3c; +pub const ITALIAN = 0x10; +pub const JAPANESE = 0x11; +pub const KANNADA = 0x4b; +pub const KASHMIRI = 0x60; +pub const KAZAK = 0x3f; +pub const KHMER = 0x53; +pub const KICHE = 0x86; +pub const KINYARWANDA = 0x87; +pub const KONKANI = 0x57; +pub const KOREAN = 0x12; +pub const KYRGYZ = 0x40; +pub const LAO = 0x54; +pub const LATVIAN = 0x26; +pub const LITHUANIAN = 0x27; +pub const LOWER_SORBIAN = 0x2e; +pub const LUXEMBOURGISH = 0x6e; +pub const MACEDONIAN = 0x2f; +pub const MALAY = 0x3e; +pub const MALAYALAM = 0x4c; +pub const MALTESE = 0x3a; +pub const MANIPURI = 0x58; +pub const MAORI = 0x81; +pub const MAPUDUNGUN = 0x7a; +pub const MARATHI = 0x4e; +pub const MOHAWK = 0x7c; +pub const MONGOLIAN = 0x50; +pub const NEPALI = 0x61; +pub const NORWEGIAN = 0x14; +pub const OCCITAN = 0x82; +pub const ODIA = 0x48; +pub const ORIYA = 0x48; +pub const PASHTO = 0x63; +pub const PERSIAN = 0x29; +pub const POLISH = 0x15; +pub const PORTUGUESE = 0x16; +pub const PULAR = 0x67; +pub const PUNJABI = 0x46; +pub const QUECHUA = 0x6b; +pub const ROMANIAN = 0x18; +pub const ROMANSH = 0x17; +pub const RUSSIAN = 0x19; +pub const SAKHA = 0x85; +pub const SAMI = 0x3b; +pub const SANSKRIT = 0x4f; +pub const SCOTTISH_GAELIC = 0x91; +pub const SERBIAN = 0x1a; +pub const SERBIAN_NEUTRAL = 0x7c1a; +pub const SINDHI = 0x59; +pub const SINHALESE = 0x5b; +pub const SLOVAK = 0x1b; +pub const SLOVENIAN = 0x24; +pub const SOTHO = 0x6c; +pub const SPANISH = 0x0a; +pub const SWAHILI = 0x41; +pub const SWEDISH = 0x1d; +pub const SYRIAC = 0x5a; +pub const TAJIK = 0x28; +pub const TAMAZIGHT = 0x5f; +pub const TAMIL = 0x49; +pub const TATAR = 0x44; +pub const TELUGU = 0x4a; +pub const THAI = 0x1e; +pub const TIBETAN = 0x51; +pub const TIGRIGNA = 0x73; +pub const TIGRINYA = 0x73; +pub const TSWANA = 0x32; +pub const TURKISH = 0x1f; +pub const TURKMEN = 0x42; +pub const UIGHUR = 0x80; +pub const UKRAINIAN = 0x22; +pub const UPPER_SORBIAN = 0x2e; +pub const URDU = 0x20; +pub const UZBEK = 0x43; +pub const VALENCIAN = 0x03; +pub const VIETNAMESE = 0x2a; +pub const WELSH = 0x52; +pub const WOLOF = 0x88; +pub const XHOSA = 0x34; +pub const YAKUT = 0x85; +pub const YI = 0x78; +pub const YORUBA = 0x6a; +pub const ZULU = 0x35; diff --git a/std/os/windows/sublang.zig b/std/os/windows/sublang.zig new file mode 100644 index 0000000000000000000000000000000000000000..e9929c6d79c22fdd1e1f68a041bc1a0a3b23c2e3 --- /dev/null +++ b/std/os/windows/sublang.zig @@ -0,0 +1,244 @@ +pub const NEUTRAL = 0x00; +pub const DEFAULT = 0x01; +pub const SYS_DEFAULT = 0x02; +pub const CUSTOM_DEFAULT = 0x03; +pub const CUSTOM_UNSPECIFIED = 0x04; +pub const UI_CUSTOM_DEFAULT = 0x05; +pub const AFRIKAANS_SOUTH_AFRICA = 0x01; +pub const ALBANIAN_ALBANIA = 0x01; +pub const ALSATIAN_FRANCE = 0x01; +pub const AMHARIC_ETHIOPIA = 0x01; +pub const ARABIC_SAUDI_ARABIA = 0x01; +pub const ARABIC_IRAQ = 0x02; +pub const ARABIC_EGYPT = 0x03; +pub const ARABIC_LIBYA = 0x04; +pub const ARABIC_ALGERIA = 0x05; +pub const ARABIC_MOROCCO = 0x06; +pub const ARABIC_TUNISIA = 0x07; +pub const ARABIC_OMAN = 0x08; +pub const ARABIC_YEMEN = 0x09; +pub const ARABIC_SYRIA = 0x0a; +pub const ARABIC_JORDAN = 0x0b; +pub const ARABIC_LEBANON = 0x0c; +pub const ARABIC_KUWAIT = 0x0d; +pub const ARABIC_UAE = 0x0e; +pub const ARABIC_BAHRAIN = 0x0f; +pub const ARABIC_QATAR = 0x10; +pub const ARMENIAN_ARMENIA = 0x01; +pub const ASSAMESE_INDIA = 0x01; +pub const AZERI_LATIN = 0x01; +pub const AZERI_CYRILLIC = 0x02; +pub const AZERBAIJANI_AZERBAIJAN_LATIN = 0x01; +pub const AZERBAIJANI_AZERBAIJAN_CYRILLIC = 0x02; +pub const BANGLA_INDIA = 0x01; +pub const BANGLA_BANGLADESH = 0x02; +pub const BASHKIR_RUSSIA = 0x01; +pub const BASQUE_BASQUE = 0x01; +pub const BELARUSIAN_BELARUS = 0x01; +pub const BENGALI_INDIA = 0x01; +pub const BENGALI_BANGLADESH = 0x02; +pub const BOSNIAN_BOSNIA_HERZEGOVINA_LATIN = 0x05; +pub const BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x08; +pub const BRETON_FRANCE = 0x01; +pub const BULGARIAN_BULGARIA = 0x01; +pub const CATALAN_CATALAN = 0x01; +pub const CENTRAL_KURDISH_IRAQ = 0x01; +pub const CHEROKEE_CHEROKEE = 0x01; +pub const CHINESE_TRADITIONAL = 0x01; +pub const CHINESE_SIMPLIFIED = 0x02; +pub const CHINESE_HONGKONG = 0x03; +pub const CHINESE_SINGAPORE = 0x04; +pub const CHINESE_MACAU = 0x05; +pub const CORSICAN_FRANCE = 0x01; +pub const CZECH_CZECH_REPUBLIC = 0x01; +pub const CROATIAN_CROATIA = 0x01; +pub const CROATIAN_BOSNIA_HERZEGOVINA_LATIN = 0x04; +pub const DANISH_DENMARK = 0x01; +pub const DARI_AFGHANISTAN = 0x01; +pub const DIVEHI_MALDIVES = 0x01; +pub const DUTCH = 0x01; +pub const DUTCH_BELGIAN = 0x02; +pub const ENGLISH_US = 0x01; +pub const ENGLISH_UK = 0x02; +pub const ENGLISH_AUS = 0x03; +pub const ENGLISH_CAN = 0x04; +pub const ENGLISH_NZ = 0x05; +pub const ENGLISH_EIRE = 0x06; +pub const ENGLISH_SOUTH_AFRICA = 0x07; +pub const ENGLISH_JAMAICA = 0x08; +pub const ENGLISH_CARIBBEAN = 0x09; +pub const ENGLISH_BELIZE = 0x0a; +pub const ENGLISH_TRINIDAD = 0x0b; +pub const ENGLISH_ZIMBABWE = 0x0c; +pub const ENGLISH_PHILIPPINES = 0x0d; +pub const ENGLISH_INDIA = 0x10; +pub const ENGLISH_MALAYSIA = 0x11; +pub const ENGLISH_SINGAPORE = 0x12; +pub const ESTONIAN_ESTONIA = 0x01; +pub const FAEROESE_FAROE_ISLANDS = 0x01; +pub const FILIPINO_PHILIPPINES = 0x01; +pub const FINNISH_FINLAND = 0x01; +pub const FRENCH = 0x01; +pub const FRENCH_BELGIAN = 0x02; +pub const FRENCH_CANADIAN = 0x03; +pub const FRENCH_SWISS = 0x04; +pub const FRENCH_LUXEMBOURG = 0x05; +pub const FRENCH_MONACO = 0x06; +pub const FRISIAN_NETHERLANDS = 0x01; +pub const FULAH_SENEGAL = 0x02; +pub const GALICIAN_GALICIAN = 0x01; +pub const GEORGIAN_GEORGIA = 0x01; +pub const GERMAN = 0x01; +pub const GERMAN_SWISS = 0x02; +pub const GERMAN_AUSTRIAN = 0x03; +pub const GERMAN_LUXEMBOURG = 0x04; +pub const GERMAN_LIECHTENSTEIN = 0x05; +pub const GREEK_GREECE = 0x01; +pub const GREENLANDIC_GREENLAND = 0x01; +pub const GUJARATI_INDIA = 0x01; +pub const HAUSA_NIGERIA_LATIN = 0x01; +pub const HAWAIIAN_US = 0x01; +pub const HEBREW_ISRAEL = 0x01; +pub const HINDI_INDIA = 0x01; +pub const HUNGARIAN_HUNGARY = 0x01; +pub const ICELANDIC_ICELAND = 0x01; +pub const IGBO_NIGERIA = 0x01; +pub const INDONESIAN_INDONESIA = 0x01; +pub const INUKTITUT_CANADA = 0x01; +pub const INUKTITUT_CANADA_LATIN = 0x02; +pub const IRISH_IRELAND = 0x02; +pub const ITALIAN = 0x01; +pub const ITALIAN_SWISS = 0x02; +pub const JAPANESE_JAPAN = 0x01; +pub const KANNADA_INDIA = 0x01; +pub const KASHMIRI_SASIA = 0x02; +pub const KASHMIRI_INDIA = 0x02; +pub const KAZAK_KAZAKHSTAN = 0x01; +pub const KHMER_CAMBODIA = 0x01; +pub const KICHE_GUATEMALA = 0x01; +pub const KINYARWANDA_RWANDA = 0x01; +pub const KONKANI_INDIA = 0x01; +pub const KOREAN = 0x01; +pub const KYRGYZ_KYRGYZSTAN = 0x01; +pub const LAO_LAO = 0x01; +pub const LATVIAN_LATVIA = 0x01; +pub const LITHUANIAN = 0x01; +pub const LOWER_SORBIAN_GERMANY = 0x02; +pub const LUXEMBOURGISH_LUXEMBOURG = 0x01; +pub const MACEDONIAN_MACEDONIA = 0x01; +pub const MALAY_MALAYSIA = 0x01; +pub const MALAY_BRUNEI_DARUSSALAM = 0x02; +pub const MALAYALAM_INDIA = 0x01; +pub const MALTESE_MALTA = 0x01; +pub const MAORI_NEW_ZEALAND = 0x01; +pub const MAPUDUNGUN_CHILE = 0x01; +pub const MARATHI_INDIA = 0x01; +pub const MOHAWK_MOHAWK = 0x01; +pub const MONGOLIAN_CYRILLIC_MONGOLIA = 0x01; +pub const MONGOLIAN_PRC = 0x02; +pub const NEPALI_INDIA = 0x02; +pub const NEPALI_NEPAL = 0x01; +pub const NORWEGIAN_BOKMAL = 0x01; +pub const NORWEGIAN_NYNORSK = 0x02; +pub const OCCITAN_FRANCE = 0x01; +pub const ODIA_INDIA = 0x01; +pub const ORIYA_INDIA = 0x01; +pub const PASHTO_AFGHANISTAN = 0x01; +pub const PERSIAN_IRAN = 0x01; +pub const POLISH_POLAND = 0x01; +pub const PORTUGUESE = 0x02; +pub const PORTUGUESE_BRAZILIAN = 0x01; +pub const PULAR_SENEGAL = 0x02; +pub const PUNJABI_INDIA = 0x01; +pub const PUNJABI_PAKISTAN = 0x02; +pub const QUECHUA_BOLIVIA = 0x01; +pub const QUECHUA_ECUADOR = 0x02; +pub const QUECHUA_PERU = 0x03; +pub const ROMANIAN_ROMANIA = 0x01; +pub const ROMANSH_SWITZERLAND = 0x01; +pub const RUSSIAN_RUSSIA = 0x01; +pub const SAKHA_RUSSIA = 0x01; +pub const SAMI_NORTHERN_NORWAY = 0x01; +pub const SAMI_NORTHERN_SWEDEN = 0x02; +pub const SAMI_NORTHERN_FINLAND = 0x03; +pub const SAMI_LULE_NORWAY = 0x04; +pub const SAMI_LULE_SWEDEN = 0x05; +pub const SAMI_SOUTHERN_NORWAY = 0x06; +pub const SAMI_SOUTHERN_SWEDEN = 0x07; +pub const SAMI_SKOLT_FINLAND = 0x08; +pub const SAMI_INARI_FINLAND = 0x09; +pub const SANSKRIT_INDIA = 0x01; +pub const SCOTTISH_GAELIC = 0x01; +pub const SERBIAN_BOSNIA_HERZEGOVINA_LATIN = 0x06; +pub const SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC = 0x07; +pub const SERBIAN_MONTENEGRO_LATIN = 0x0b; +pub const SERBIAN_MONTENEGRO_CYRILLIC = 0x0c; +pub const SERBIAN_SERBIA_LATIN = 0x09; +pub const SERBIAN_SERBIA_CYRILLIC = 0x0a; +pub const SERBIAN_CROATIA = 0x01; +pub const SERBIAN_LATIN = 0x02; +pub const SERBIAN_CYRILLIC = 0x03; +pub const SINDHI_INDIA = 0x01; +pub const SINDHI_PAKISTAN = 0x02; +pub const SINDHI_AFGHANISTAN = 0x02; +pub const SINHALESE_SRI_LANKA = 0x01; +pub const SOTHO_NORTHERN_SOUTH_AFRICA = 0x01; +pub const SLOVAK_SLOVAKIA = 0x01; +pub const SLOVENIAN_SLOVENIA = 0x01; +pub const SPANISH = 0x01; +pub const SPANISH_MEXICAN = 0x02; +pub const SPANISH_MODERN = 0x03; +pub const SPANISH_GUATEMALA = 0x04; +pub const SPANISH_COSTA_RICA = 0x05; +pub const SPANISH_PANAMA = 0x06; +pub const SPANISH_DOMINICAN_REPUBLIC = 0x07; +pub const SPANISH_VENEZUELA = 0x08; +pub const SPANISH_COLOMBIA = 0x09; +pub const SPANISH_PERU = 0x0a; +pub const SPANISH_ARGENTINA = 0x0b; +pub const SPANISH_ECUADOR = 0x0c; +pub const SPANISH_CHILE = 0x0d; +pub const SPANISH_URUGUAY = 0x0e; +pub const SPANISH_PARAGUAY = 0x0f; +pub const SPANISH_BOLIVIA = 0x10; +pub const SPANISH_EL_SALVADOR = 0x11; +pub const SPANISH_HONDURAS = 0x12; +pub const SPANISH_NICARAGUA = 0x13; +pub const SPANISH_PUERTO_RICO = 0x14; +pub const SPANISH_US = 0x15; +pub const SWAHILI_KENYA = 0x01; +pub const SWEDISH = 0x01; +pub const SWEDISH_FINLAND = 0x02; +pub const SYRIAC_SYRIA = 0x01; +pub const TAJIK_TAJIKISTAN = 0x01; +pub const TAMAZIGHT_ALGERIA_LATIN = 0x02; +pub const TAMAZIGHT_MOROCCO_TIFINAGH = 0x04; +pub const TAMIL_INDIA = 0x01; +pub const TAMIL_SRI_LANKA = 0x02; +pub const TATAR_RUSSIA = 0x01; +pub const TELUGU_INDIA = 0x01; +pub const THAI_THAILAND = 0x01; +pub const TIBETAN_PRC = 0x01; +pub const TIGRIGNA_ERITREA = 0x02; +pub const TIGRINYA_ERITREA = 0x02; +pub const TIGRINYA_ETHIOPIA = 0x01; +pub const TSWANA_BOTSWANA = 0x02; +pub const TSWANA_SOUTH_AFRICA = 0x01; +pub const TURKISH_TURKEY = 0x01; +pub const TURKMEN_TURKMENISTAN = 0x01; +pub const UIGHUR_PRC = 0x01; +pub const UKRAINIAN_UKRAINE = 0x01; +pub const UPPER_SORBIAN_GERMANY = 0x01; +pub const URDU_PAKISTAN = 0x01; +pub const URDU_INDIA = 0x02; +pub const UZBEK_LATIN = 0x01; +pub const UZBEK_CYRILLIC = 0x02; +pub const VALENCIAN_VALENCIA = 0x02; +pub const VIETNAMESE_VIETNAM = 0x01; +pub const WELSH_UNITED_KINGDOM = 0x01; +pub const WOLOF_SENEGAL = 0x01; +pub const XHOSA_SOUTH_AFRICA = 0x01; +pub const YAKUT_RUSSIA = 0x01; +pub const YI_PRC = 0x01; +pub const YORUBA_NIGERIA = 0x01; +pub const ZULU_SOUTH_AFRICA = 0x01; -- 2.54.0 From 656ac43735094f7cc6b4616cd95e0d427b0174a6 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 5 Jun 2019 23:26:48 -0700 Subject: [PATCH 79/84] std.HashMap: optimize indexing by avoiding modulo operator x % y can be optimized if y is a power of two by doing x & (y-1) instead. HashMap already enforces power of two capacity, so we can take advantage of this optimization. --- std/hash_map.zig | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/std/hash_map.zig b/std/hash_map.zig index 8cbff7be9d70ae20809841f5ba18a446abea25ed..af58ae076a62f9634813b845d45e8fe46d20b635 100644 --- a/std/hash_map.zig +++ b/std/hash_map.zig @@ -155,6 +155,8 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 /// capacity is greater than the current capacity. /// New capacity must be a power of two. fn ensureCapacityExact(self: *Self, new_capacity: usize) !void { + // capacity must always be a power of two to allow for modulo + // optimization in the constrainIndex fn const is_power_of_two = new_capacity & (new_capacity - 1) == 0; assert(is_power_of_two); @@ -209,7 +211,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 { var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) { - const index = (start_index + roll_over) % hm.entries.len; + const index = hm.constrainIndex(start_index + roll_over); var entry = &hm.entries[index]; if (!entry.used) return null; @@ -218,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 const removed_kv = entry.kv; while (roll_over < hm.entries.len) : (roll_over += 1) { - const next_index = (start_index + roll_over + 1) % hm.entries.len; + const next_index = hm.constrainIndex(start_index + roll_over + 1); const next_entry = &hm.entries[next_index]; if (!next_entry.used or next_entry.distance_from_start_index == 0) { entry.used = false; @@ -301,7 +303,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 roll_over += 1; distance_from_start_index += 1; }) { - const index = (start_index + roll_over) % self.entries.len; + const index = self.constrainIndex(start_index + roll_over); const entry = &self.entries[index]; 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 { var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) { - const index = (start_index + roll_over) % hm.entries.len; + const index = hm.constrainIndex(start_index + roll_over); const entry = &hm.entries[index]; if (!entry.used) return null; @@ -369,7 +371,13 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 } fn keyToIndex(hm: Self, key: K) usize { - return usize(hash(key)) % hm.entries.len; + return hm.constrainIndex(usize(hash(key))); + } + + fn constrainIndex(hm: Self, i: usize) usize { + // this is an optimization for modulo of power of two integers; + // it requires hm.entries.len to always be a power of two + return i & (hm.entries.len - 1); } }; } -- 2.54.0 From 8f4229a61c311c0fc990c34b280ec91010595bc9 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 5 Jun 2019 23:36:51 -0700 Subject: [PATCH 80/84] std.HashMap: use std.math.ceilPowerOfTwo --- std/hash_map.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/std/hash_map.zig b/std/hash_map.zig index af58ae076a62f9634813b845d45e8fe46d20b635..e64bdd09b4dc7ee2c71309e3ac0900ddba6b90aa 100644 --- a/std/hash_map.zig +++ b/std/hash_map.zig @@ -139,9 +139,9 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 // ensure that the hash map will be at most 60% full if // expected_count items are put into it var optimized_capacity = expected_count * 5 / 3; - // round capacity to the next power of two - const pow = math.log2_int_ceil(usize, optimized_capacity); - return math.pow(usize, 2, pow); + // an overflow here would mean the amount of memory required would not + // be representable in the address space + return math.ceilPowerOfTwo(usize, optimized_capacity) catch unreachable; } /// Increases capacity so that the hash map will be at most -- 2.54.0 From 786f3cdd135fa29906ec9b78155c03406f9e79ce Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 7 Jun 2019 12:07:23 -0400 Subject: [PATCH 81/84] ci: let's try a new build of llvm+clang on 10.14 --- ci/azure/macos_script | 2 +- ci/azure/pipelines.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/azure/macos_script b/ci/azure/macos_script index 13c24abd239b3e035bc18e71f8cbeef3d641c9a4..7a7f1d1bce6b6f7574f114715b7ea30c20a4bd94 100755 --- a/ci/azure/macos_script +++ b/ci/azure/macos_script @@ -6,7 +6,7 @@ set -e brew install s3cmd gcc@8 ZIGDIR="$(pwd)" -CACHE_BASENAME="llvm+clang-8.0.0-macos-x86_64-gcc8-release-static" +CACHE_BASENAME="llvm+clang-8.0.0-macos-x86_64-gcc8-release" PREFIX="$HOME/$CACHE_BASENAME" TMPDIR="$HOME/tmpz" JOBS="-j2" diff --git a/ci/azure/pipelines.yml b/ci/azure/pipelines.yml index 37fce2a27a37f3c99633a2a42cf6d6b38c27ab47..8e6fcde6365b42c4beb83a34758d1e15ab0c5d38 100644 --- a/ci/azure/pipelines.yml +++ b/ci/azure/pipelines.yml @@ -1,7 +1,7 @@ jobs: - job: BuildMacOS pool: - vmImage: 'macOS 10.13' + vmImage: 'macOS 10.14' timeoutInMinutes: 360 -- 2.54.0 From 5784631fab1fdcc4dcf9c04db11c4136d530413a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 7 Jun 2019 12:20:02 -0400 Subject: [PATCH 82/84] update the default macos version min to 10.14 --- src-self-hosted/link.zig | 2 +- src/codegen.cpp | 2 +- src/link.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig index a47dbbbe928b4daa69b313eae9d70247bc588805..838cbbc4801d102899488a01d851a372623538e0 100644 --- a/src-self-hosted/link.zig +++ b/src-self-hosted/link.zig @@ -670,7 +670,7 @@ const DarwinPlatform = struct { Compilation.DarwinVersionMin.None => blk: { assert(comp.target.getOs() == .macosx); result.kind = Kind.MacOS; - break :blk "10.10"; + break :blk "10.14"; }, }; diff --git a/src/codegen.cpp b/src/codegen.cpp index 4f1cb51a125a254d277f30f310c16a5987384bae..12b07ea6bcb43127c8a8a96ff2baebc44a96ed48 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -48,7 +48,7 @@ static void init_darwin_native(CodeGen *g) { } else if (ios_target) { g->mios_version_min = buf_create_from_str(ios_target); } else if (g->zig_target->os != OsIOS) { - g->mmacosx_version_min = buf_create_from_str("10.10"); + g->mmacosx_version_min = buf_create_from_str("10.14"); } } diff --git a/src/link.cpp b/src/link.cpp index fe5a73a52b8d80a0e4b8e38d3d225793455712e3..3a437e4eda1cd637f1d92719cd4eb9a3cfdf7720 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -1474,7 +1474,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) { platform->kind = IPhoneOS; } else if (g->zig_target->os == OsMacOSX) { platform->kind = MacOS; - g->mmacosx_version_min = buf_create_from_str("10.10"); + g->mmacosx_version_min = buf_create_from_str("10.14"); } else { zig_panic("unable to infer -mmacosx-version-min or -mios-version-min"); } -- 2.54.0 From 404e4b026888471d50ff74306a9c3ec75039f6a9 Mon Sep 17 00:00:00 2001 From: Shritesh Bhattarai Date: Sat, 8 Jun 2019 12:49:56 -0700 Subject: [PATCH 83/84] docs: add comment about for else and break --- doc/langref.html.in | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/langref.html.in b/doc/langref.html.in index a98705afd5a66cf984d6acb099683546664048fe..ba093881abc5d2f0436f008a67f455aeda3f8f88 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -3293,6 +3293,7 @@ test "for else" { var items = []?i32 { 3, 4, null, 5 }; // For loops can also be used as expressions. + // Similar to while loops, when you break from a for loop, the else branch is not evaluated. var sum: i32 = 0; const result = for (items) |value| { if (value == null) { -- 2.54.0 From 720ed74413f086a93f5ed66159300d8dd48e8034 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Sat, 8 Jun 2019 14:34:15 -0500 Subject: [PATCH 84/84] add bcmp implementation as LLVM 9 now emits those MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The optimizer will now convert calls to memcmp into a calls to bcmp in some circumstances. Users who are building freestanding code (not depending on the platform’s libc) without specifying -ffreestanding may need to either pass -fno-builtin-bcmp, or provide a bcmp function. http://llvm.org/docs/ReleaseNotes.html#non-comprehensive-list-of-changes-in-this-release --- std/special/c.zig | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/std/special/c.zig b/std/special/c.zig index 9a05f6f22e08d478699c7e72dad40e5e38a77398..456070f609620b2cc58a90b8a95ab75fb9d35de6 100644 --- a/std/special/c.zig +++ b/std/special/c.zig @@ -136,8 +136,32 @@ test "test_memcmp" { const arr3 = []u8{ 1, 2, 1 }; std.testing.expect(memcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0); - std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) == 1); - std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) == -1); + std.testing.expect(memcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) > 0); + std.testing.expect(memcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) < 0); +} + +export fn bcmp(vl: [*]allowzero const u8, vr: [*]allowzero const u8, n: usize) isize { + @setRuntimeSafety(false); + + var index: usize = 0; + while (index != n) : (index += 1) { + if (vl[index] != vr[index]) { + return 1; + } + } + + return 0; +} + +test "test_bcmp" { + const base_arr = []u8{ 1, 1, 1 }; + const arr1 = []u8{ 1, 1, 1 }; + const arr2 = []u8{ 1, 0, 1 }; + const arr3 = []u8{ 1, 2, 1 }; + + std.testing.expect(bcmp(base_arr[0..].ptr, arr1[0..].ptr, base_arr.len) == 0); + std.testing.expect(bcmp(base_arr[0..].ptr, arr2[0..].ptr, base_arr.len) != 0); + std.testing.expect(bcmp(base_arr[0..].ptr, arr3[0..].ptr, base_arr.len) != 0); } comptime { -- 2.54.0