diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig index 569b88184d..42af19ddd9 100644 --- a/src-self-hosted/test.zig +++ b/src-self-hosted/test.zig @@ -38,7 +38,6 @@ pub const TestContext = struct { }; // TODO: remove - pub const ZIRErrorCase = struct { name: []const u8, src: [:0]const u8, @@ -71,7 +70,7 @@ pub const TestContext = struct { src: [:0]const u8, case: union(ZIRUpdateType) { /// The expected output ZIR - Transformation: []const u8, + Transformation: [:0]const u8, /// A slice containing the expected errors *in sequential order*. Error: []const ErrorMsg, @@ -106,21 +105,30 @@ pub const TestContext = struct { /// such as QEMU is required for tests to complete. /// target: std.zig.CrossTarget, - updates: []const ZIRUpdate, + updates: std.ArrayList(ZIRUpdate), + + pub fn addTransform(self: *ZIRCase, src: [:0]const u8, result: [:0]const u8) void { + self.updates.append(.{ + .src = src, + .case = .{ .Transformation = result }, + }) catch unreachable; + } + + pub fn addError(self: *ZIRCase, src: [:0]const u8, errors: []const []const u8) void {} }; - pub fn addZIRCase( + pub fn addZIRMulti( ctx: *TestContext, name: []const u8, target: std.zig.CrossTarget, - updates: []const ZIRUpdate, - ) void { + ) *ZIRCase { const case = ZIRCase{ .name = name, .target = target, - .updates = updates, + .updates = std.ArrayList(ZIRUpdate).init(ctx.zir_cases.allocator), }; - ctx.zir_cases.append(case) catch |err| std.debug.panic("Error: {}", .{err}); + ctx.zir_cases.append(case) catch unreachable; + return &ctx.zir_cases.items[ctx.zir_cases.items.len - 1]; } pub fn addZIRCompareOutput( @@ -136,6 +144,17 @@ pub const TestContext = struct { }) catch unreachable; } + pub fn addZIRTransform( + ctx: *TestContext, + name: []const u8, + target: std.zig.CrossTarget, + src: [:0]const u8, + result: [:0]const u8, + ) void { + var c = ctx.addZIRMulti(name, target); + c.addTransform(src, result); + } + pub fn addZIRError( ctx: *TestContext, name: []const u8, @@ -194,6 +213,9 @@ pub const TestContext = struct { self.zir_error_cases.allocator.free(e.expected_errors); } self.zir_error_cases.deinit(); + for (self.zir_cases.items) |c| { + c.updates.deinit(); + } self.zir_cases.deinit(); self.* = undefined; } @@ -234,7 +256,7 @@ pub const TestContext = struct { const root_pkg = try Package.create(allocator, tmp.dir, ".", tmp_src_path); defer root_pkg.destroy(); - var prg_node = root_node.start(case.name, case.updates.len); + var prg_node = root_node.start(case.name, case.updates.items.len); prg_node.activate(); defer prg_node.end(); @@ -255,7 +277,7 @@ pub const TestContext = struct { }); defer module.deinit(); - for (case.updates) |s| { + for (case.updates.items) |s| { // TODO: remove before committing. This is for ZLS ;) const update: ZIRUpdate = s; diff --git a/test/stage2/zir.zig b/test/stage2/zir.zig index a8cf4ca964..d58b30c29d 100644 --- a/test/stage2/zir.zig +++ b/test/stage2/zir.zig @@ -1,6 +1,5 @@ const std = @import("std"); const TestContext = @import("../../src-self-hosted/test.zig").TestContext; -const ZIRUpdate = TestContext.ZIRUpdate; // self-hosted does not yet support PE executable files / COFF object files // or mach-o files. So we do the ZIR transform test cases cross compiling for // x86_64-linux. @@ -10,61 +9,90 @@ const linux_x64 = std.zig.CrossTarget{ }; pub fn addCases(ctx: *TestContext) void { - ctx.addZIRCase("elemptr, add, cmp, condbr, return, breakpoint", linux_x64, &[_]ZIRUpdate{ZIRUpdate{ - .src = - \\@void = primitive(void) - \\@usize = primitive(usize) - \\@fnty = fntype([], @void, cc=C) - \\@0 = int(0) - \\@1 = int(1) - \\@2 = int(2) - \\@3 = int(3) - \\ - \\@entry = fn(@fnty, { - \\ %a = str("\x32\x08\x01\x0a") - \\ %aref = ref(%a) - \\ %eptr0 = elemptr(%aref, @0) - \\ %eptr1 = elemptr(%aref, @1) - \\ %eptr2 = elemptr(%aref, @2) - \\ %eptr3 = elemptr(%aref, @3) - \\ %v0 = deref(%eptr0) - \\ %v1 = deref(%eptr1) - \\ %v2 = deref(%eptr2) - \\ %v3 = deref(%eptr3) - \\ %x0 = add(%v0, %v1) - \\ %x1 = add(%v2, %v3) - \\ %result = add(%x0, %x1) - \\ - \\ %expected = int(69) - \\ %ok = cmp(%result, eq, %expected) - \\ %10 = condbr(%ok, { - \\ %11 = return() - \\ }, { - \\ %12 = breakpoint() - \\ }) - \\}) - \\ - \\@9 = str("entry") - \\@10 = ref(@9) - \\@11 = export(@10, @entry) - , - .case = .{ - .Transformation = - \\@0 = primitive(void) - \\@1 = fntype([], @0, cc=C) - \\@2 = fn(@1, { - \\ %0 = return() - \\}) - \\@3 = str("entry") - \\@4 = ref(@3) - \\@5 = export(@4, @2) - \\ - }, - }}); + ctx.addZIRTransform("referencing decls which appear later in the file", linux_x64, + \\@void = primitive(void) + \\@fnty = fntype([], @void, cc=C) + \\ + \\@9 = str("entry") + \\@10 = ref(@9) + \\@11 = export(@10, @entry) + \\ + \\@entry = fn(@fnty, { + \\ %11 = return() + \\}) + , + \\@void = primitive(void) + \\@fnty = fntype([], @void, cc=C) + \\@9 = str("entry") + \\@10 = ref(@9) + \\@unnamed$6 = str("entry") + \\@unnamed$7 = ref(@unnamed$6) + \\@unnamed$8 = export(@unnamed$7, @entry) + \\@unnamed$10 = fntype([], @void, cc=C) + \\@entry = fn(@unnamed$10, { + \\ %0 = return() + \\}) + \\ + ); + ctx.addZIRTransform("elemptr, add, cmp, condbr, return, breakpoint", linux_x64, + \\@void = primitive(void) + \\@usize = primitive(usize) + \\@fnty = fntype([], @void, cc=C) + \\@0 = int(0) + \\@1 = int(1) + \\@2 = int(2) + \\@3 = int(3) + \\ + \\@entry = fn(@fnty, { + \\ %a = str("\x32\x08\x01\x0a") + \\ %aref = ref(%a) + \\ %eptr0 = elemptr(%aref, @0) + \\ %eptr1 = elemptr(%aref, @1) + \\ %eptr2 = elemptr(%aref, @2) + \\ %eptr3 = elemptr(%aref, @3) + \\ %v0 = deref(%eptr0) + \\ %v1 = deref(%eptr1) + \\ %v2 = deref(%eptr2) + \\ %v3 = deref(%eptr3) + \\ %x0 = add(%v0, %v1) + \\ %x1 = add(%v2, %v3) + \\ %result = add(%x0, %x1) + \\ + \\ %expected = int(69) + \\ %ok = cmp(%result, eq, %expected) + \\ %10 = condbr(%ok, { + \\ %11 = return() + \\ }, { + \\ %12 = breakpoint() + \\ }) + \\}) + \\ + \\@9 = str("entry") + \\@10 = ref(@9) + \\@11 = export(@10, @entry) + , + \\@void = primitive(void) + \\@fnty = fntype([], @void, cc=C) + \\@0 = int(0) + \\@1 = int(1) + \\@2 = int(2) + \\@3 = int(3) + \\@unnamed$7 = fntype([], @void, cc=C) + \\@entry = fn(@unnamed$7, { + \\ %0 = return() + \\}) + \\@a = str("2\x08\x01\n") + \\@9 = str("entry") + \\@10 = ref(@9) + \\@unnamed$14 = str("entry") + \\@unnamed$15 = ref(@unnamed$14) + \\@unnamed$16 = export(@unnamed$15, @entry) + \\ + ); { var case = ctx.addZIRMulti("reference cycle with compile error in the cycle", linux_x64); - case.addZIR( + case.addTransform( \\@void = primitive(void) \\@fnty = fntype([], @void, cc=C) \\ @@ -143,7 +171,7 @@ pub fn addCases(ctx: *TestContext) void { // Now we remove the call to `a`. `a` and `b` form a cycle, but no entry points are // referencing either of them. This tests that the cycle is detected, and the error // goes away. - case.addZIR( + case.addTransform( \\@void = primitive(void) \\@fnty = fntype([], @void, cc=C) \\