all tests passing with postfix deref syntax

This commit is contained in:
Andrew Kelley 2018-05-17 23:21:44 -04:00
parent 99fc2bd4dd
commit c38b165db4
13 changed files with 302 additions and 289 deletions

View File

@ -30,7 +30,10 @@ pub fn build(b: &Builder) !void {
const test_step = b.step("test", "Run all the tests"); const test_step = b.step("test", "Run all the tests");
// find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library // find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library
const build_info = try b.exec([][]const u8{b.zig_exe, "BUILD_INFO"}); const build_info = try b.exec([][]const u8{
b.zig_exe,
"BUILD_INFO",
});
var index: usize = 0; var index: usize = 0;
const cmake_binary_dir = nextValue(&index, build_info); const cmake_binary_dir = nextValue(&index, build_info);
const cxx_compiler = nextValue(&index, build_info); const cxx_compiler = nextValue(&index, build_info);
@ -67,7 +70,10 @@ pub fn build(b: &Builder) !void {
dependOnLib(exe, llvm); dependOnLib(exe, llvm);
if (exe.target.getOs() == builtin.Os.linux) { if (exe.target.getOs() == builtin.Os.linux) {
const libstdcxx_path_padded = try b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"}); const libstdcxx_path_padded = try b.exec([][]const u8{
cxx_compiler,
"-print-file-name=libstdc++.a",
});
const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next(); const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next();
if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) { if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {
warn( warn(
@ -111,17 +117,11 @@ pub fn build(b: &Builder) !void {
test_step.dependOn(docs_step); test_step.dependOn(docs_step);
test_step.dependOn(tests.addPkgTests(b, test_filter, test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", with_lldb));
"test/behavior.zig", "behavior", "Run the behavior tests",
with_lldb));
test_step.dependOn(tests.addPkgTests(b, test_filter, test_step.dependOn(tests.addPkgTests(b, test_filter, "std/index.zig", "std", "Run the standard library tests", with_lldb));
"std/index.zig", "std", "Run the standard library tests",
with_lldb));
test_step.dependOn(tests.addPkgTests(b, test_filter, test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests", with_lldb));
"std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests",
with_lldb));
test_step.dependOn(tests.addCompareOutputTests(b, test_filter)); test_step.dependOn(tests.addCompareOutputTests(b, test_filter));
test_step.dependOn(tests.addBuildExampleTests(b, test_filter)); test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
@ -149,8 +149,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) vo
fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void { fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib"; const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
} }
const LibraryDep = struct { const LibraryDep = struct {
@ -161,9 +160,19 @@ const LibraryDep = struct {
}; };
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep { fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {
const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"}); const libs_output = try b.exec([][]const u8{
const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"}); llvm_config_exe,
const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"}); "--libs",
"--system-libs",
});
const includes_output = try b.exec([][]const u8{
llvm_config_exe,
"--includedir",
});
const libdir_output = try b.exec([][]const u8{
llvm_config_exe,
"--libdir",
});
var result = LibraryDep{ var result = LibraryDep{
.libs = ArrayList([]const u8).init(b.allocator), .libs = ArrayList([]const u8).init(b.allocator),
@ -227,17 +236,17 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
} }
fn nextValue(index: &usize, build_info: []const u8) []const u8 { fn nextValue(index: &usize, build_info: []const u8) []const u8 {
const start = *index; const start = index.*;
while (true) : (*index += 1) { while (true) : (index.* += 1) {
switch (build_info[*index]) { switch (build_info[index.*]) {
'\n' => { '\n' => {
const result = build_info[start..*index]; const result = build_info[start..index.*];
*index += 1; index.* += 1;
return result; return result;
}, },
'\r' => { '\r' => {
const result = build_info[start..*index]; const result = build_info[start..index.*];
*index += 2; index.* += 2;
return result; return result;
}, },
else => continue, else => continue,

View File

@ -1232,7 +1232,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
</td> </td>
</tr> </tr>
<tr> <tr>
<td><pre><code class="zig">*a<code></pre></td> <td><pre><code class="zig">a.*<code></pre></td>
<td> <td>
<ul> <ul>
<li>{#link|Pointers#}</li> <li>{#link|Pointers#}</li>
@ -1244,7 +1244,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
<td> <td>
<pre><code class="zig">const x: u32 = 1234; <pre><code class="zig">const x: u32 = 1234;
const ptr = &amp;x; const ptr = &amp;x;
*x == 1234</code></pre> x.* == 1234</code></pre>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -1258,7 +1258,7 @@ const ptr = &amp;x;
<td> <td>
<pre><code class="zig">const x: u32 = 1234; <pre><code class="zig">const x: u32 = 1234;
const ptr = &amp;x; const ptr = &amp;x;
*x == 1234</code></pre> x.* == 1234</code></pre>
</td> </td>
</tr> </tr>
</table> </table>
@ -1267,8 +1267,8 @@ const ptr = &amp;x;
{#header_open|Precedence#} {#header_open|Precedence#}
<pre><code>x() x[] x.y <pre><code>x() x[] x.y
a!b a!b
!x -x -%x ~x *x &amp;x ?x ??x !x -x -%x ~x &amp;x ?x ??x
x{} x{} x.*
! * / % ** *% ! * / % ** *%
+ - ++ +% -% + - ++ +% -%
&lt;&lt; &gt;&gt; &lt;&lt; &gt;&gt;
@ -1316,7 +1316,7 @@ var some_integers: [100]i32 = undefined;
test "modify an array" { test "modify an array" {
for (some_integers) |*item, i| { for (some_integers) |*item, i| {
*item = i32(i); item.* = i32(i);
} }
assert(some_integers[10] == 10); assert(some_integers[10] == 10);
assert(some_integers[99] == 99); assert(some_integers[99] == 99);
@ -1357,7 +1357,7 @@ comptime {
var fancy_array = init: { var fancy_array = init: {
var initial_value: [10]Point = undefined; var initial_value: [10]Point = undefined;
for (initial_value) |*pt, i| { for (initial_value) |*pt, i| {
*pt = Point { pt.* = Point {
.x = i32(i), .x = i32(i),
.y = i32(i) * 2, .y = i32(i) * 2,
}; };
@ -1400,7 +1400,7 @@ test "address of syntax" {
const x_ptr = &x; const x_ptr = &x;
// Deference a pointer: // Deference a pointer:
assert(*x_ptr == 1234); assert(x_ptr.* == 1234);
// When you get the address of a const variable, you get a const pointer. // When you get the address of a const variable, you get a const pointer.
assert(@typeOf(x_ptr) == &const i32); assert(@typeOf(x_ptr) == &const i32);
@ -1409,8 +1409,8 @@ test "address of syntax" {
var y: i32 = 5678; var y: i32 = 5678;
const y_ptr = &y; const y_ptr = &y;
assert(@typeOf(y_ptr) == &i32); assert(@typeOf(y_ptr) == &i32);
*y_ptr += 1; y_ptr.* += 1;
assert(*y_ptr == 5679); assert(y_ptr.* == 5679);
} }
test "pointer array access" { test "pointer array access" {
@ -1448,9 +1448,9 @@ comptime {
// @ptrCast. // @ptrCast.
var x: i32 = 1; var x: i32 = 1;
const ptr = &x; const ptr = &x;
*ptr += 1; ptr.* += 1;
x += 1; x += 1;
assert(*ptr == 3); assert(ptr.* == 3);
} }
test "@ptrToInt and @intToPtr" { test "@ptrToInt and @intToPtr" {
@ -1492,7 +1492,7 @@ test "nullable pointers" {
var x: i32 = 1; var x: i32 = 1;
ptr = &x; ptr = &x;
assert(*??ptr == 1); assert((??ptr).* == 1);
// Nullable pointers are the same size as normal pointers, because pointer // Nullable pointers are the same size as normal pointers, because pointer
// value 0 is used as the null value. // value 0 is used as the null value.
@ -1505,7 +1505,7 @@ test "pointer casting" {
// conversions are not possible. // conversions are not possible.
const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12}; const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
const u32_ptr = @ptrCast(&const u32, &bytes[0]); const u32_ptr = @ptrCast(&const u32, &bytes[0]);
assert(*u32_ptr == 0x12121212); assert(u32_ptr.* == 0x12121212);
// Even this example is contrived - there are better ways to do the above than // Even this example is contrived - there are better ways to do the above than
// pointer casting. For example, using a slice narrowing cast: // pointer casting. For example, using a slice narrowing cast:
@ -1610,7 +1610,7 @@ fn foo(bytes: []u8) u32 {
<code>u8</code> can alias any memory. <code>u8</code> can alias any memory.
</p> </p>
<p>As an example, this code produces undefined behavior:</p> <p>As an example, this code produces undefined behavior:</p>
<pre><code class="zig">*@ptrCast(&amp;u32, f32(12.34))</code></pre> <pre><code class="zig">@ptrCast(&amp;u32, f32(12.34)).*</code></pre>
<p>Instead, use {#link|@bitCast#}: <p>Instead, use {#link|@bitCast#}:
<pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre> <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
<p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p> <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
@ -2040,7 +2040,7 @@ const Variant = union(enum) {
Bool: bool, Bool: bool,
fn truthy(self: &const Variant) bool { fn truthy(self: &const Variant) bool {
return switch (*self) { return switch (self.*) {
Variant.Int => |x_int| x_int != 0, Variant.Int => |x_int| x_int != 0,
Variant.Bool => |x_bool| x_bool, Variant.Bool => |x_bool| x_bool,
}; };
@ -2151,7 +2151,7 @@ test "switch enum" {
// A reference to the matched value can be obtained using `*` syntax. // A reference to the matched value can be obtained using `*` syntax.
Item.C => |*item| blk: { Item.C => |*item| blk: {
(*item).x += 1; item.*.x += 1;
break :blk 6; break :blk 6;
}, },
@ -2374,7 +2374,7 @@ test "for reference" {
// Iterate over the slice by reference by // Iterate over the slice by reference by
// specifying that the capture value is a pointer. // specifying that the capture value is a pointer.
for (items) |*value| { for (items) |*value| {
*value += 1; value.* += 1;
} }
assert(items[0] == 4); assert(items[0] == 4);
@ -2483,7 +2483,7 @@ test "if nullable" {
// Access the value by reference using a pointer capture. // Access the value by reference using a pointer capture.
var c: ?u32 = 3; var c: ?u32 = 3;
if (c) |*value| { if (c) |*value| {
*value = 2; value.* = 2;
} }
if (c) |value| { if (c) |value| {
@ -2524,7 +2524,7 @@ test "if error union" {
// Access the value by reference using a pointer capture. // Access the value by reference using a pointer capture.
var c: error!u32 = 3; var c: error!u32 = 3;
if (c) |*value| { if (c) |*value| {
*value = 9; value.* = 9;
} else |err| { } else |err| {
unreachable; unreachable;
} }
@ -3872,7 +3872,7 @@ pub fn main() void {
{#header_open|@addWithOverflow#} {#header_open|@addWithOverflow#}
<pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre> <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p> <p>
Performs <code>*result = a + b</code>. If overflow or underflow occurs, Performs <code>result.* = a + b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>. stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>. If no overflow or underflow occurs, returns <code>false</code>.
</p> </p>
@ -4073,9 +4073,9 @@ comptime {
</p> </p>
{#code_begin|syntax#} {#code_begin|syntax#}
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T { fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
const old_value = *ptr; const old_value = ptr.*;
if (old_value == expected_value) { if (old_value == expected_value) {
*ptr = new_value; ptr.* = new_value;
return null; return null;
} else { } else {
return old_value; return old_value;
@ -4100,9 +4100,9 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_v
</p> </p>
{#code_begin|syntax#} {#code_begin|syntax#}
fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T { fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
const old_value = *ptr; const old_value = ptr.*;
if (old_value == expected_value and usuallyTrueButSometimesFalse()) { if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
*ptr = new_value; ptr.* = new_value;
return null; return null;
} else { } else {
return old_value; return old_value;
@ -4447,7 +4447,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>
This function is a low level intrinsic with no safety mechanisms. Most This function is a low level intrinsic with no safety mechanisms. Most
code should not use this function, instead using something like this: code should not use this function, instead using something like this:
</p> </p>
<pre><code class="zig">for (dest[0...byte_count]) |*b| *b = c;</code></pre> <pre><code class="zig">for (dest[0...byte_count]) |*b| b.* = c;</code></pre>
<p> <p>
The optimizer is intelligent enough to turn the above snippet into a memset. The optimizer is intelligent enough to turn the above snippet into a memset.
</p> </p>
@ -4480,7 +4480,7 @@ mem.set(u8, dest, c);</code></pre>
{#header_open|@mulWithOverflow#} {#header_open|@mulWithOverflow#}
<pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre> <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p> <p>
Performs <code>*result = a * b</code>. If overflow or underflow occurs, Performs <code>result.* = a * b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>. stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>. If no overflow or underflow occurs, returns <code>false</code>.
</p> </p>
@ -4514,7 +4514,7 @@ fn targetFunction(x: i32) usize {
var local_variable: i32 = 42; var local_variable: i32 = 42;
const ptr = &local_variable; const ptr = &local_variable;
*ptr += 1; ptr.* += 1;
assert(local_variable == 43); assert(local_variable == 43);
return @ptrToInt(ptr); return @ptrToInt(ptr);
@ -4746,7 +4746,7 @@ pub const FloatMode = enum {
{#header_open|@shlWithOverflow#} {#header_open|@shlWithOverflow#}
<pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre> <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre>
<p> <p>
Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs, Performs <code>result.* = a &lt;&lt; b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>. stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>. If no overflow or underflow occurs, returns <code>false</code>.
</p> </p>
@ -4790,7 +4790,7 @@ pub const FloatMode = enum {
{#header_open|@subWithOverflow#} {#header_open|@subWithOverflow#}
<pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre> <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p> <p>
Performs <code>*result = a - b</code>. If overflow or underflow occurs, Performs <code>result.* = a - b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>. stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>. If no overflow or underflow occurs, returns <code>false</code>.
</p> </p>

View File

@ -30,18 +30,16 @@ fn argInAllowedSet(maybe_set: ?[]const []const u8, arg: []const u8) bool {
} }
// Modifies the current argument index during iteration // Modifies the current argument index during iteration
fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required: usize, fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required: usize, allowed_set: ?[]const []const u8, index: &usize) !FlagArg {
allowed_set: ?[]const []const u8, index: &usize) !FlagArg {
switch (required) { switch (required) {
0 => return FlagArg{ .None = undefined }, // TODO: Required to force non-tag but value? 0 => return FlagArg{ .None = undefined }, // TODO: Required to force non-tag but value?
1 => { 1 => {
if (*index + 1 >= args.len) { if (index.* + 1 >= args.len) {
return error.MissingFlagArguments; return error.MissingFlagArguments;
} }
*index += 1; index.* += 1;
const arg = args[*index]; const arg = args[index.*];
if (!argInAllowedSet(allowed_set, arg)) { if (!argInAllowedSet(allowed_set, arg)) {
return error.ArgumentNotInAllowedSet; return error.ArgumentNotInAllowedSet;
@ -55,12 +53,12 @@ fn readFlagArguments(allocator: &Allocator, args: []const []const u8, required:
var j: usize = 0; var j: usize = 0;
while (j < needed) : (j += 1) { while (j < needed) : (j += 1) {
if (*index + 1 >= args.len) { if (index.* + 1 >= args.len) {
return error.MissingFlagArguments; return error.MissingFlagArguments;
} }
*index += 1; index.* += 1;
const arg = args[*index]; const arg = args[index.*];
if (!argInAllowedSet(allowed_set, arg)) { if (!argInAllowedSet(allowed_set, arg)) {
return error.ArgumentNotInAllowedSet; return error.ArgumentNotInAllowedSet;
@ -116,11 +114,7 @@ pub const Args = struct {
}; };
if (flag.mergable) { if (flag.mergable) {
var prev = var prev = if (parsed.flags.get(flag_name_trimmed)) |entry| entry.value.Many else ArrayList([]const u8).init(allocator);
if (parsed.flags.get(flag_name_trimmed)) |entry|
entry.value.Many
else
ArrayList([]const u8).init(allocator);
// MergeN creation disallows 0 length flag entry (doesn't make sense) // MergeN creation disallows 0 length flag entry (doesn't make sense)
switch (flag_args) { switch (flag_args) {
@ -163,7 +157,9 @@ pub const Args = struct {
pub fn single(self: &Args, name: []const u8) ?[]const u8 { pub fn single(self: &Args, name: []const u8) ?[]const u8 {
if (self.flags.get(name)) |entry| { if (self.flags.get(name)) |entry| {
switch (entry.value) { switch (entry.value) {
FlagArg.Single => |inner| { return inner; }, FlagArg.Single => |inner| {
return inner;
},
else => @panic("attempted to retrieve flag with wrong type"), else => @panic("attempted to retrieve flag with wrong type"),
} }
} else { } else {
@ -175,7 +171,9 @@ pub const Args = struct {
pub fn many(self: &Args, name: []const u8) ?[]const []const u8 { pub fn many(self: &Args, name: []const u8) ?[]const []const u8 {
if (self.flags.get(name)) |entry| { if (self.flags.get(name)) |entry| {
switch (entry.value) { switch (entry.value) {
FlagArg.Many => |inner| { return inner.toSliceConst(); }, FlagArg.Many => |inner| {
return inner.toSliceConst();
},
else => @panic("attempted to retrieve flag with wrong type"), else => @panic("attempted to retrieve flag with wrong type"),
} }
} else { } else {
@ -243,7 +241,11 @@ test "parse arguments" {
Flag.Bool("--help"), Flag.Bool("--help"),
Flag.Bool("--init"), Flag.Bool("--init"),
Flag.Arg1("--build-file"), Flag.Arg1("--build-file"),
Flag.Option("--color", []const []const u8 { "on", "off", "auto" }), Flag.Option("--color", []const []const u8{
"on",
"off",
"auto",
}),
Flag.ArgN("--pkg-begin", 2), Flag.ArgN("--pkg-begin", 2),
Flag.ArgMergeN("--object", 1), Flag.ArgMergeN("--object", 1),
Flag.ArgN("--library", 1), Flag.ArgN("--library", 1),
@ -253,12 +255,18 @@ test "parse arguments" {
"build", "build",
"--help", "--help",
"pos1", "pos1",
"--build-file", "build.zig", "--build-file",
"--object", "obj1", "build.zig",
"--object", "obj2", "--object",
"--library", "lib1", "obj1",
"--library", "lib2", "--object",
"--color", "on", "obj2",
"--library",
"lib1",
"--library",
"lib2",
"--color",
"on",
"pos2", "pos2",
}; };

View File

@ -96,6 +96,7 @@ pub const Module = struct {
pub const LinkLib = struct { pub const LinkLib = struct {
name: []const u8, name: []const u8,
path: ?[]const u8, path: ?[]const u8,
/// the list of symbols we depend on from this lib /// the list of symbols we depend on from this lib
symbols: ArrayList([]u8), symbols: ArrayList([]u8),
provided_explicitly: bool, provided_explicitly: bool,
@ -130,9 +131,7 @@ pub const Module = struct {
} }
}; };
pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) !&Module {
kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) !&Module
{
var name_buffer = try Buffer.init(allocator, name); var name_buffer = try Buffer.init(allocator, name);
errdefer name_buffer.deinit(); errdefer name_buffer.deinit();
@ -148,14 +147,14 @@ pub const Module = struct {
const module_ptr = try allocator.create(Module); const module_ptr = try allocator.create(Module);
errdefer allocator.destroy(module_ptr); errdefer allocator.destroy(module_ptr);
*module_ptr = Module { module_ptr.* = Module{
.allocator = allocator, .allocator = allocator,
.name = name_buffer, .name = name_buffer,
.root_src_path = root_src_path, .root_src_path = root_src_path,
.module = module, .module = module,
.context = context, .context = context,
.builder = builder, .builder = builder,
.target = *target, .target = target.*,
.kind = kind, .kind = kind,
.build_mode = build_mode, .build_mode = build_mode,
.zig_lib_dir = zig_lib_dir, .zig_lib_dir = zig_lib_dir,
@ -221,8 +220,10 @@ pub const Module = struct {
pub fn build(self: &Module) !void { pub fn build(self: &Module) !void {
if (self.llvm_argv.len != 0) { if (self.llvm_argv.len != 0) {
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator, var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator, [][]const []const u8{
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, }); [][]const u8{"zig (LLVM option parsing)"},
self.llvm_argv,
});
defer c_compatible_args.deinit(); defer c_compatible_args.deinit();
c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr); c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
} }
@ -261,7 +262,6 @@ pub const Module = struct {
warn("====llvm ir:====\n"); warn("====llvm ir:====\n");
self.dump(); self.dump();
} }
pub fn link(self: &Module, out_file: ?[]const u8) !void { pub fn link(self: &Module, out_file: ?[]const u8) !void {
@ -285,7 +285,7 @@ pub const Module = struct {
} }
const link_lib = try self.allocator.create(LinkLib); const link_lib = try self.allocator.create(LinkLib);
*link_lib = LinkLib { link_lib.* = LinkLib{
.name = name, .name = name,
.path = null, .path = null,
.provided_explicitly = provided_explicitly, .provided_explicitly = provided_explicitly,

View File

@ -12,7 +12,7 @@ pub const Target = union(enum) {
Cross: CrossTarget, Cross: CrossTarget,
pub fn oFileExt(self: &const Target) []const u8 { pub fn oFileExt(self: &const Target) []const u8 {
const environ = switch (*self) { const environ = switch (self.*) {
Target.Native => builtin.environ, Target.Native => builtin.environ,
Target.Cross => |t| t.environ, Target.Cross => |t| t.environ,
}; };
@ -30,7 +30,7 @@ pub const Target = union(enum) {
} }
pub fn getOs(self: &const Target) builtin.Os { pub fn getOs(self: &const Target) builtin.Os {
return switch (*self) { return switch (self.*) {
Target.Native => builtin.os, Target.Native => builtin.os,
Target.Cross => |t| t.os, Target.Cross => |t| t.os,
}; };
@ -38,7 +38,8 @@ pub const Target = union(enum) {
pub fn isDarwin(self: &const Target) bool { pub fn isDarwin(self: &const Target) bool {
return switch (self.getOs()) { return switch (self.getOs()) {
builtin.Os.ios, builtin.Os.macosx => true, builtin.Os.ios,
builtin.Os.macosx => true,
else => false, else => false,
}; };
} }

View File

@ -1485,6 +1485,7 @@ pub const Node = struct {
BitNot, BitNot,
BoolNot, BoolNot,
Cancel, Cancel,
PointerType,
MaybeType, MaybeType,
Negation, Negation,
NegationWrap, NegationWrap,

View File

@ -3134,7 +3134,7 @@ fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {
Token.Id.Minus => ast.Node.PrefixOp.Op{ .Negation = void{} }, Token.Id.Minus => ast.Node.PrefixOp.Op{ .Negation = void{} },
Token.Id.MinusPercent => ast.Node.PrefixOp.Op{ .NegationWrap = void{} }, Token.Id.MinusPercent => ast.Node.PrefixOp.Op{ .NegationWrap = void{} },
Token.Id.Asterisk, Token.Id.Asterisk,
Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op{ .Deref = void{} }, Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op{ .PointerType = void{} },
Token.Id.Ampersand => ast.Node.PrefixOp.Op{ .AddrOf = ast.Node.PrefixOp.AddrOfInfo{ Token.Id.Ampersand => ast.Node.PrefixOp.Op{ .AddrOf = ast.Node.PrefixOp.AddrOfInfo{
.align_expr = null, .align_expr = null,
.bit_offset_start_token = null, .bit_offset_start_token = null,

View File

@ -311,6 +311,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
ast.Node.PrefixOp.Op.Try => try stream.write("try "), ast.Node.PrefixOp.Op.Try => try stream.write("try "),
ast.Node.PrefixOp.Op.UnwrapMaybe => try stream.write("??"), ast.Node.PrefixOp.Op.UnwrapMaybe => try stream.write("??"),
ast.Node.PrefixOp.Op.MaybeType => try stream.write("?"), ast.Node.PrefixOp.Op.MaybeType => try stream.write("?"),
ast.Node.PrefixOp.Op.PointerType => try stream.write("*"),
ast.Node.PrefixOp.Op.Await => try stream.write("await "), ast.Node.PrefixOp.Op.Await => try stream.write("await "),
ast.Node.PrefixOp.Op.Cancel => try stream.write("cancel "), ast.Node.PrefixOp.Op.Cancel => try stream.write("cancel "),
ast.Node.PrefixOp.Op.Resume => try stream.write("resume "), ast.Node.PrefixOp.Op.Resume => try stream.write("resume "),
@ -350,7 +351,7 @@ fn renderExpression(allocator: &mem.Allocator, stream: var, tree: &ast.Tree, ind
try stream.write("]"); try stream.write("]");
}, },
ast.Node.SuffixOp.Op.SuffixOp => { ast.Node.SuffixOp.Op.Deref => {
try renderExpression(allocator, stream, tree, indent, suffix_op.lhs); try renderExpression(allocator, stream, tree, indent, suffix_op.lhs);
try stream.write(".*"); try stream.write(".*");
}, },

View File

@ -287,9 +287,9 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int { \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
\\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable); \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);
\\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable); \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);
\\ if (*a_int < *b_int) { \\ if (a_int.* < b_int.*) {
\\ return -1; \\ return -1;
\\ } else if (*a_int > *b_int) { \\ } else if (a_int.* > b_int.*) {
\\ return 1; \\ return 1;
\\ } else { \\ } else {
\\ return 0; \\ return 0;

View File

@ -4,7 +4,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
cases.add("invalid deref on switch target", cases.add("invalid deref on switch target",
\\comptime { \\comptime {
\\ var tile = Tile.Empty; \\ var tile = Tile.Empty;
\\ switch (*tile) { \\ switch (tile.*) {
\\ Tile.Empty => {}, \\ Tile.Empty => {},
\\ Tile.Filled => {}, \\ Tile.Filled => {},
\\ } \\ }
@ -14,7 +14,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ Filled, \\ Filled,
\\}; \\};
, ,
".tmp_source.zig:3:13: error: invalid deref on switch target"); ".tmp_source.zig:3:17: error: invalid deref on switch target");
cases.add("invalid field access in comptime", cases.add("invalid field access in comptime",
\\comptime { var x = doesnt_exist.whatever; } \\comptime { var x = doesnt_exist.whatever; }
@ -1408,14 +1408,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ Two: i32, \\ Two: i32,
\\}; \\};
\\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool { \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {
\\ return *a == *b; \\ return a.* == b.*;
\\} \\}
\\ \\
\\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); } \\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }
\\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); } \\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }
, ,
".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'", ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'"); ".tmp_source.zig:9:16: error: operator not allowed for type 'EnumWithData'");
cases.add("non-const switch number literal", cases.add("non-const switch number literal",
\\export fn foo() void { \\export fn foo() void {
@ -1513,7 +1513,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\var bytes: [ext()]u8 = undefined; \\var bytes: [ext()]u8 = undefined;
\\export fn f() void { \\export fn f() void {
\\ for (bytes) |*b, i| { \\ for (bytes) |*b, i| {
\\ *b = u8(i); \\ b.* = u8(i);
\\ } \\ }
\\} \\}
, ".tmp_source.zig:2:13: error: unable to evaluate constant expression"); , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
@ -1819,7 +1819,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\} \\}
\\ \\
\\fn bar(x: &const u3) u3 { \\fn bar(x: &const u3) u3 {
\\ return *x; \\ return x.*;
\\} \\}
\\ \\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); } \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
@ -1903,12 +1903,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\var s_buffer: [10]u8 = undefined; \\var s_buffer: [10]u8 = undefined;
\\pub fn pass(in: []u8) []u8 { \\pub fn pass(in: []u8) []u8 {
\\ var out = &s_buffer; \\ var out = &s_buffer;
\\ *out[0] = in[0]; \\ out[0].* = in[0];
\\ return (*out)[0..1]; \\ return out.*[0..1];
\\} \\}
\\ \\
\\export fn entry() usize { return @sizeOf(@typeOf(pass)); } \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
, ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'"); , ".tmp_source.zig:4:11: error: attempt to dereference non pointer type '[10]u8'");
cases.add("pass const ptr to mutable ptr fn", cases.add("pass const ptr to mutable ptr fn",
\\fn foo() bool { \\fn foo() bool {
@ -2434,7 +2434,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\} \\}
\\ \\
\\fn bar(x: &u32) void { \\fn bar(x: &u32) void {
\\ *x += 1; \\ x.* += 1;
\\} \\}
, ,
".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'"); ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");
@ -2461,7 +2461,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\export fn entry() u32 { \\export fn entry() u32 {
\\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04}; \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
\\ const ptr = @ptrCast(&u32, &bytes[0]); \\ const ptr = @ptrCast(&u32, &bytes[0]);
\\ return *ptr; \\ return ptr.*;
\\} \\}
, ,
".tmp_source.zig:3:17: error: cast increases pointer alignment", ".tmp_source.zig:3:17: error: cast increases pointer alignment",
@ -2540,14 +2540,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ \\
\\export fn entry(opaque: &Opaque) void { \\export fn entry(opaque: &Opaque) void {
\\ var m2 = &2; \\ var m2 = &2;
\\ const y: u32 = *m2; \\ const y: u32 = m2.*;
\\ \\
\\ var a = undefined; \\ var a = undefined;
\\ var b = 1; \\ var b = 1;
\\ var c = 1.0; \\ var c = 1.0;
\\ var d = this; \\ var d = this;
\\ var e = null; \\ var e = null;
\\ var f = *opaque; \\ var f = opaque.*;
\\ var g = i32; \\ var g = i32;
\\ var h = @import("std"); \\ var h = @import("std");
\\ var i = (Foo {}).bar; \\ var i = (Foo {}).bar;
@ -3136,13 +3136,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ foo(a); \\ foo(a);
\\} \\}
\\fn foo(a: &const Payload) void { \\fn foo(a: &const Payload) void {
\\ switch (*a) { \\ switch (a.*) {
\\ Payload.A => {}, \\ Payload.A => {},
\\ else => unreachable, \\ else => unreachable,
\\ } \\ }
\\} \\}
, ,
".tmp_source.zig:11:13: error: switch on union which has no attached enum", ".tmp_source.zig:11:14: error: switch on union which has no attached enum",
".tmp_source.zig:1:17: note: consider 'union(enum)' here"); ".tmp_source.zig:1:17: note: consider 'union(enum)' here");
cases.add("enum in field count range but not matching tag", cases.add("enum in field count range but not matching tag",

View File

@ -29,7 +29,8 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
for (input) |b, i| { for (input) |b, i| {
switch (state) { switch (state) {
State.Start => switch (b) { State.Start => switch (b) {
'a'...'z', 'A'...'Z' => { 'a' ... 'z',
'A' ... 'Z' => {
state = State.Word; state = State.Word;
tok_begin = i; tok_begin = i;
}, },
@ -39,8 +40,11 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
else => return error.InvalidInput, else => return error.InvalidInput,
}, },
State.Word => switch (b) { State.Word => switch (b) {
'a'...'z', 'A'...'Z' => {}, 'a' ... 'z',
'{', '}', ',' => { 'A' ... 'Z' => {},
'{',
'}',
',' => {
try token_list.append(Token{ .Word = input[tok_begin..i] }); try token_list.append(Token{ .Word = input[tok_begin..i] });
switch (b) { switch (b) {
'{' => try token_list.append(Token.OpenBrace), '{' => try token_list.append(Token.OpenBrace),
@ -74,8 +78,8 @@ const ParseError = error {
}; };
fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node { fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
const first_token = tokens.items[*token_index]; const first_token = tokens.items[token_index.*];
*token_index += 1; token_index.* += 1;
const result_node = switch (first_token) { const result_node = switch (first_token) {
Token.Word => |word| Node{ .Scalar = word }, Token.Word => |word| Node{ .Scalar = word },
@ -84,8 +88,8 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
while (true) { while (true) {
try list.append(try parse(tokens, token_index)); try list.append(try parse(tokens, token_index));
const token = tokens.items[*token_index]; const token = tokens.items[token_index.*];
*token_index += 1; token_index.* += 1;
switch (token) { switch (token) {
Token.CloseBrace => break, Token.CloseBrace => break,
@ -98,8 +102,9 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
else => return error.InvalidInput, else => return error.InvalidInput,
}; };
switch (tokens.items[*token_index]) { switch (tokens.items[token_index.*]) {
Token.Word, Token.OpenBrace => { Token.Word,
Token.OpenBrace => {
const pair = try global_allocator.alloc(Node, 2); const pair = try global_allocator.alloc(Node, 2);
pair[0] = result_node; pair[0] = result_node;
pair[1] = try parse(tokens, token_index); pair[1] = try parse(tokens, token_index);
@ -137,13 +142,11 @@ fn expandString(input: []const u8, output: &Buffer) !void {
} }
} }
const ExpandNodeError = error { const ExpandNodeError = error{OutOfMemory};
OutOfMemory,
};
fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void { fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void {
assert(output.len == 0); assert(output.len == 0);
switch (*node) { switch (node.*) {
Node.Scalar => |scalar| { Node.Scalar => |scalar| {
try output.append(try Buffer.init(global_allocator, scalar)); try output.append(try Buffer.init(global_allocator, scalar));
}, },

View File

@ -49,7 +49,7 @@ const max_stdout_size = 1 * 1024 * 1024; // 1 MB
pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(CompareOutputContext) catch unreachable; const cases = b.allocator.create(CompareOutputContext) catch unreachable;
*cases = CompareOutputContext { cases.* = CompareOutputContext{
.b = b, .b = b,
.step = b.step("test-compare-output", "Run the compare output tests"), .step = b.step("test-compare-output", "Run the compare output tests"),
.test_index = 0, .test_index = 0,
@ -63,7 +63,7 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build
pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(CompareOutputContext) catch unreachable; const cases = b.allocator.create(CompareOutputContext) catch unreachable;
*cases = CompareOutputContext { cases.* = CompareOutputContext{
.b = b, .b = b,
.step = b.step("test-runtime-safety", "Run the runtime safety tests"), .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
.test_index = 0, .test_index = 0,
@ -77,7 +77,7 @@ pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build
pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(CompileErrorContext) catch unreachable; const cases = b.allocator.create(CompileErrorContext) catch unreachable;
*cases = CompileErrorContext { cases.* = CompileErrorContext{
.b = b, .b = b,
.step = b.step("test-compile-errors", "Run the compile error tests"), .step = b.step("test-compile-errors", "Run the compile error tests"),
.test_index = 0, .test_index = 0,
@ -91,7 +91,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.
pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(BuildExamplesContext) catch unreachable; const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
*cases = BuildExamplesContext { cases.* = BuildExamplesContext{
.b = b, .b = b,
.step = b.step("test-build-examples", "Build the examples"), .step = b.step("test-build-examples", "Build the examples"),
.test_index = 0, .test_index = 0,
@ -105,7 +105,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.
pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(CompareOutputContext) catch unreachable; const cases = b.allocator.create(CompareOutputContext) catch unreachable;
*cases = CompareOutputContext { cases.* = CompareOutputContext{
.b = b, .b = b,
.step = b.step("test-asm-link", "Run the assemble and link tests"), .step = b.step("test-asm-link", "Run the assemble and link tests"),
.test_index = 0, .test_index = 0,
@ -119,7 +119,7 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &bui
pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(TranslateCContext) catch unreachable; const cases = b.allocator.create(TranslateCContext) catch unreachable;
*cases = TranslateCContext { cases.* = TranslateCContext{
.b = b, .b = b,
.step = b.step("test-translate-c", "Run the C transation tests"), .step = b.step("test-translate-c", "Run the C transation tests"),
.test_index = 0, .test_index = 0,
@ -133,7 +133,7 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.St
pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step { pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
const cases = b.allocator.create(GenHContext) catch unreachable; const cases = b.allocator.create(GenHContext) catch unreachable;
*cases = GenHContext { cases.* = GenHContext{
.b = b, .b = b,
.step = b.step("test-gen-h", "Run the C header file generation tests"), .step = b.step("test-gen-h", "Run the C header file generation tests"),
.test_index = 0, .test_index = 0,
@ -145,22 +145,26 @@ pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
return cases.step; return cases.step;
} }
pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8, name: []const u8, desc: []const u8, with_lldb: bool) &build.Step {
pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,
name:[] const u8, desc: []const u8, with_lldb: bool) &build.Step
{
const step = b.step(b.fmt("test-{}", name), desc); const step = b.step(b.fmt("test-{}", name), desc);
for (test_targets) |test_target| { for (test_targets) |test_target| {
const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch); const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);
for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| { for ([]Mode{
for ([]bool{false, true}) |link_libc| { Mode.Debug,
Mode.ReleaseSafe,
Mode.ReleaseFast,
Mode.ReleaseSmall,
}) |mode| {
for ([]bool{
false,
true,
}) |link_libc| {
if (link_libc and !is_native) { if (link_libc and !is_native) {
// don't assume we have a cross-compiling libc set up // don't assume we have a cross-compiling libc set up
continue; continue;
} }
const these_tests = b.addTest(root_src); const these_tests = b.addTest(root_src);
these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os), these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os), @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
@tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
these_tests.setFilter(test_filter); these_tests.setFilter(test_filter);
these_tests.setBuildMode(mode); these_tests.setBuildMode(mode);
if (!is_native) { if (!is_native) {
@ -171,7 +175,15 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
} }
if (with_lldb) { if (with_lldb) {
these_tests.setExecCmd([]?[]const u8{ these_tests.setExecCmd([]?[]const u8{
"lldb", null, "-o", "run", "-o", "bt", "-o", "exit"}); "lldb",
null,
"-o",
"run",
"-o",
"bt",
"-o",
"exit",
});
} }
step.dependOn(&these_tests.step); step.dependOn(&these_tests.step);
} }
@ -226,13 +238,10 @@ pub const CompareOutputContext = struct {
test_index: usize, test_index: usize,
cli_args: []const []const u8, cli_args: []const []const u8,
pub fn create(context: &CompareOutputContext, exe_path: []const u8, pub fn create(context: &CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) &RunCompareOutputStep {
name: []const u8, expected_output: []const u8,
cli_args: []const []const u8) &RunCompareOutputStep
{
const allocator = context.b.allocator; const allocator = context.b.allocator;
const ptr = allocator.create(RunCompareOutputStep) catch unreachable; const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
*ptr = RunCompareOutputStep { ptr.* = RunCompareOutputStep{
.context = context, .context = context,
.exe_path = exe_path, .exe_path = exe_path,
.name = name, .name = name,
@ -295,7 +304,6 @@ pub const CompareOutputContext = struct {
}, },
} }
if (!mem.eql(u8, self.expected_output, stdout.toSliceConst())) { if (!mem.eql(u8, self.expected_output, stdout.toSliceConst())) {
warn( warn(
\\ \\
@ -318,12 +326,10 @@ pub const CompareOutputContext = struct {
name: []const u8, name: []const u8,
test_index: usize, test_index: usize,
pub fn create(context: &CompareOutputContext, exe_path: []const u8, pub fn create(context: &CompareOutputContext, exe_path: []const u8, name: []const u8) &RuntimeSafetyRunStep {
name: []const u8) &RuntimeSafetyRunStep
{
const allocator = context.b.allocator; const allocator = context.b.allocator;
const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable; const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
*ptr = RuntimeSafetyRunStep { ptr.* = RuntimeSafetyRunStep{
.context = context, .context = context,
.exe_path = exe_path, .exe_path = exe_path,
.name = name, .name = name,
@ -358,19 +364,16 @@ pub const CompareOutputContext = struct {
switch (term) { switch (term) {
Term.Exited => |code| { Term.Exited => |code| {
if (code != expected_exit_code) { if (code != expected_exit_code) {
warn("\nProgram expected to exit with code {} " ++ warn("\nProgram expected to exit with code {} " ++ "but exited with code {}\n", expected_exit_code, code);
"but exited with code {}\n", expected_exit_code, code);
return error.TestFailed; return error.TestFailed;
} }
}, },
Term.Signal => |sig| { Term.Signal => |sig| {
warn("\nProgram expected to exit with code {} " ++ warn("\nProgram expected to exit with code {} " ++ "but instead signaled {}\n", expected_exit_code, sig);
"but instead signaled {}\n", expected_exit_code, sig);
return error.TestFailed; return error.TestFailed;
}, },
else => { else => {
warn("\nProgram expected to exit with code {}" ++ warn("\nProgram expected to exit with code {}" ++ " but exited in an unexpected way\n", expected_exit_code);
" but exited in an unexpected way\n", expected_exit_code);
return error.TestFailed; return error.TestFailed;
}, },
} }
@ -379,9 +382,7 @@ pub const CompareOutputContext = struct {
} }
}; };
pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8, pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8, special: Special) TestCase {
expected_output: []const u8, special: Special) TestCase
{
var tc = TestCase{ var tc = TestCase{
.name = name, .name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
@ -395,9 +396,7 @@ pub const CompareOutputContext = struct {
return tc; return tc;
} }
pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8, pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) TestCase {
expected_output: []const u8) TestCase
{
return createExtra(self, name, source, expected_output, Special.None); return createExtra(self, name, source, expected_output, Special.None);
} }
@ -431,8 +430,7 @@ pub const CompareOutputContext = struct {
Special.Asm => { Special.Asm => {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name) catch unreachable; const annotated_case_name = fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
return;
} }
const exe = b.addExecutable("test", null); const exe = b.addExecutable("test", null);
@ -444,19 +442,21 @@ pub const CompareOutputContext = struct {
exe.step.dependOn(&write_src.step); exe.step.dependOn(&write_src.step);
} }
const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
case.expected_output, case.cli_args);
run_and_cmp_output.step.dependOn(&exe.step); run_and_cmp_output.step.dependOn(&exe.step);
self.step.dependOn(&run_and_cmp_output.step); self.step.dependOn(&run_and_cmp_output.step);
}, },
Special.None => { Special.None => {
for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| { for ([]Mode{
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})", Mode.Debug,
"compare-output", case.name, @tagName(mode)) catch unreachable; Mode.ReleaseSafe,
Mode.ReleaseFast,
Mode.ReleaseSmall,
}) |mode| {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})", "compare-output", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
continue;
} }
const exe = b.addExecutable("test", root_src); const exe = b.addExecutable("test", root_src);
@ -471,8 +471,7 @@ pub const CompareOutputContext = struct {
exe.step.dependOn(&write_src.step); exe.step.dependOn(&write_src.step);
} }
const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
annotated_case_name, case.expected_output, case.cli_args);
run_and_cmp_output.step.dependOn(&exe.step); run_and_cmp_output.step.dependOn(&exe.step);
self.step.dependOn(&run_and_cmp_output.step); self.step.dependOn(&run_and_cmp_output.step);
@ -481,8 +480,7 @@ pub const CompareOutputContext = struct {
Special.RuntimeSafety => { Special.RuntimeSafety => {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable; const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
return;
} }
const exe = b.addExecutable("test", root_src); const exe = b.addExecutable("test", root_src);
@ -543,12 +541,10 @@ pub const CompileErrorContext = struct {
case: &const TestCase, case: &const TestCase,
build_mode: Mode, build_mode: Mode,
pub fn create(context: &CompileErrorContext, name: []const u8, pub fn create(context: &CompileErrorContext, name: []const u8, case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep {
case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep
{
const allocator = context.b.allocator; const allocator = context.b.allocator;
const ptr = allocator.create(CompileCmpOutputStep) catch unreachable; const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
*ptr = CompileCmpOutputStep { ptr.* = CompileCmpOutputStep{
.step = build.Step.init("CompileCmpOutput", allocator, make), .step = build.Step.init("CompileCmpOutput", allocator, make),
.context = context, .context = context,
.name = name, .name = name,
@ -626,7 +622,6 @@ pub const CompileErrorContext = struct {
}, },
} }
const stdout = stdout_buf.toSliceConst(); const stdout = stdout_buf.toSliceConst();
const stderr = stderr_buf.toSliceConst(); const stderr = stderr_buf.toSliceConst();
@ -666,11 +661,9 @@ pub const CompileErrorContext = struct {
warn("\n"); warn("\n");
} }
pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8, pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
expected_lines: ...) &TestCase
{
const tc = self.b.allocator.create(TestCase) catch unreachable; const tc = self.b.allocator.create(TestCase) catch unreachable;
*tc = TestCase { tc.* = TestCase{
.name = name, .name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_errors = ArrayList([]const u8).init(self.b.allocator), .expected_errors = ArrayList([]const u8).init(self.b.allocator),
@ -705,12 +698,13 @@ pub const CompileErrorContext = struct {
pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void { pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {
const b = self.b; const b = self.b;
for ([]Mode{Mode.Debug, Mode.ReleaseFast}) |mode| { for ([]Mode{
const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", Mode.Debug,
case.name, @tagName(mode)) catch unreachable; Mode.ReleaseFast,
}) |mode| {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
continue;
} }
const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode); const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);
@ -744,8 +738,7 @@ pub const BuildExamplesContext = struct {
const annotated_case_name = b.fmt("build {} (Debug)", build_file); const annotated_case_name = b.fmt("build {} (Debug)", build_file);
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
return;
} }
var zig_args = ArrayList([]const u8).init(b.allocator); var zig_args = ArrayList([]const u8).init(b.allocator);
@ -773,12 +766,15 @@ pub const BuildExamplesContext = struct {
pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void { pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void {
const b = self.b; const b = self.b;
for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast, Mode.ReleaseSmall}) |mode| { for ([]Mode{
const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})", Mode.Debug,
root_src, @tagName(mode)) catch unreachable; Mode.ReleaseSafe,
Mode.ReleaseFast,
Mode.ReleaseSmall,
}) |mode| {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})", root_src, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
continue;
} }
const exe = b.addExecutable("test", root_src); const exe = b.addExecutable("test", root_src);
@ -834,7 +830,7 @@ pub const TranslateCContext = struct {
pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep { pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep {
const allocator = context.b.allocator; const allocator = context.b.allocator;
const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable; const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
*ptr = TranslateCCmpOutputStep { ptr.* = TranslateCCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make), .step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context, .context = context,
.name = name, .name = name,
@ -939,11 +935,9 @@ pub const TranslateCContext = struct {
warn("\n"); warn("\n");
} }
pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
source: []const u8, expected_lines: ...) &TestCase
{
const tc = self.b.allocator.create(TestCase) catch unreachable; const tc = self.b.allocator.create(TestCase) catch unreachable;
*tc = TestCase { tc.* = TestCase{
.name = name, .name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator), .expected_lines = ArrayList([]const u8).init(self.b.allocator),
@ -977,8 +971,7 @@ pub const TranslateCContext = struct {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable; const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
return;
} }
const translate_c_and_cmp = TranslateCCmpOutputStep.create(self, annotated_case_name, case); const translate_c_and_cmp = TranslateCCmpOutputStep.create(self, annotated_case_name, case);
@ -1031,7 +1024,7 @@ pub const GenHContext = struct {
pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep { pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep {
const allocator = context.b.allocator; const allocator = context.b.allocator;
const ptr = allocator.create(GenHCmpOutputStep) catch unreachable; const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
*ptr = GenHCmpOutputStep { ptr.* = GenHCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make), .step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context, .context = context,
.h_path = h_path, .h_path = h_path,
@ -1076,11 +1069,9 @@ pub const GenHContext = struct {
warn("\n"); warn("\n");
} }
pub fn create(self: &GenHContext, filename: []const u8, name: []const u8, pub fn create(self: &GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) &TestCase {
source: []const u8, expected_lines: ...) &TestCase
{
const tc = self.b.allocator.create(TestCase) catch unreachable; const tc = self.b.allocator.create(TestCase) catch unreachable;
*tc = TestCase { tc.* = TestCase{
.name = name, .name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator), .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator), .expected_lines = ArrayList([]const u8).init(self.b.allocator),
@ -1105,8 +1096,7 @@ pub const GenHContext = struct {
const mode = builtin.Mode.Debug; const mode = builtin.Mode.Debug;
const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable; const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| { if (self.test_filter) |filter| {
if (mem.indexOf(u8, annotated_case_name, filter) == null) if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
return;
} }
const obj = b.addObject("test", root_src); const obj = b.addObject("test", root_src);

View File

@ -720,43 +720,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ var a: c_int = 0; \\ var a: c_int = 0;
\\ a += x: { \\ a += x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) + 1); \\ _ref.* = (_ref.* + 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a -= x: { \\ a -= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) - 1); \\ _ref.* = (_ref.* - 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a *= x: { \\ a *= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) * 1); \\ _ref.* = (_ref.* * 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a &= x: { \\ a &= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) & 1); \\ _ref.* = (_ref.* & 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a |= x: { \\ a |= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) | 1); \\ _ref.* = (_ref.* | 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a ^= x: { \\ a ^= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) ^ 1); \\ _ref.* = (_ref.* ^ 1);
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a >>= @import("std").math.Log2Int(c_int)(x: { \\ a >>= @import("std").math.Log2Int(c_int)(x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_int)(1)); \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }); \\ });
\\ a <<= @import("std").math.Log2Int(c_int)(x: { \\ a <<= @import("std").math.Log2Int(c_int)(x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_int)(1)); \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }); \\ });
\\} \\}
); );
@ -778,43 +778,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ var a: c_uint = c_uint(0); \\ var a: c_uint = c_uint(0);
\\ a +%= x: { \\ a +%= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) +% c_uint(1)); \\ _ref.* = (_ref.* +% c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a -%= x: { \\ a -%= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) -% c_uint(1)); \\ _ref.* = (_ref.* -% c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a *%= x: { \\ a *%= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) *% c_uint(1)); \\ _ref.* = (_ref.* *% c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a &= x: { \\ a &= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) & c_uint(1)); \\ _ref.* = (_ref.* & c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a |= x: { \\ a |= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) | c_uint(1)); \\ _ref.* = (_ref.* | c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a ^= x: { \\ a ^= x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) ^ c_uint(1)); \\ _ref.* = (_ref.* ^ c_uint(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ a >>= @import("std").math.Log2Int(c_uint)(x: { \\ a >>= @import("std").math.Log2Int(c_uint)(x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_uint)(1)); \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }); \\ });
\\ a <<= @import("std").math.Log2Int(c_uint)(x: { \\ a <<= @import("std").math.Log2Int(c_uint)(x: {
\\ const _ref = &a; \\ const _ref = &a;
\\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_uint)(1)); \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));
\\ break :x *_ref; \\ break :x _ref.*;
\\ }); \\ });
\\} \\}
); );
@ -853,26 +853,26 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ u -%= 1; \\ u -%= 1;
\\ i = x: { \\ i = x: {
\\ const _ref = &i; \\ const _ref = &i;
\\ const _tmp = *_ref; \\ const _tmp = _ref.*;
\\ (*_ref) += 1; \\ _ref.* += 1;
\\ break :x _tmp; \\ break :x _tmp;
\\ }; \\ };
\\ i = x: { \\ i = x: {
\\ const _ref = &i; \\ const _ref = &i;
\\ const _tmp = *_ref; \\ const _tmp = _ref.*;
\\ (*_ref) -= 1; \\ _ref.* -= 1;
\\ break :x _tmp; \\ break :x _tmp;
\\ }; \\ };
\\ u = x: { \\ u = x: {
\\ const _ref = &u; \\ const _ref = &u;
\\ const _tmp = *_ref; \\ const _tmp = _ref.*;
\\ (*_ref) +%= 1; \\ _ref.* +%= 1;
\\ break :x _tmp; \\ break :x _tmp;
\\ }; \\ };
\\ u = x: { \\ u = x: {
\\ const _ref = &u; \\ const _ref = &u;
\\ const _tmp = *_ref; \\ const _tmp = _ref.*;
\\ (*_ref) -%= 1; \\ _ref.* -%= 1;
\\ break :x _tmp; \\ break :x _tmp;
\\ }; \\ };
\\} \\}
@ -901,23 +901,23 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ u -%= 1; \\ u -%= 1;
\\ i = x: { \\ i = x: {
\\ const _ref = &i; \\ const _ref = &i;
\\ (*_ref) += 1; \\ _ref.* += 1;
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ i = x: { \\ i = x: {
\\ const _ref = &i; \\ const _ref = &i;
\\ (*_ref) -= 1; \\ _ref.* -= 1;
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ u = x: { \\ u = x: {
\\ const _ref = &u; \\ const _ref = &u;
\\ (*_ref) +%= 1; \\ _ref.* +%= 1;
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\ u = x: { \\ u = x: {
\\ const _ref = &u; \\ const _ref = &u;
\\ (*_ref) -%= 1; \\ _ref.* -%= 1;
\\ break :x *_ref; \\ break :x _ref.*;
\\ }; \\ };
\\} \\}
); );
@ -985,7 +985,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\} \\}
, ,
\\pub export fn foo(x: ?&c_int) void { \\pub export fn foo(x: ?&c_int) void {
\\ (*??x) = 1; \\ (??x).* = 1;
\\} \\}
); );
@ -1013,7 +1013,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub fn foo() c_int { \\pub fn foo() c_int {
\\ var x: c_int = 1234; \\ var x: c_int = 1234;
\\ var ptr: ?&c_int = &x; \\ var ptr: ?&c_int = &x;
\\ return *??ptr; \\ return (??ptr).*;
\\} \\}
); );