Commit 4bfcd105ef

Andrew Kelley <andrew@ziglang.org>
2021-03-26 04:11:23
stage2: fix `@compileLog`.
1 parent 4fd3a2e
Changed files (4)
src/astgen.zig
@@ -1130,6 +1130,7 @@ fn blockExprStmts(
                         .@"unreachable",
                         .elided,
                         .store,
+                        .store_node,
                         .store_to_block_ptr,
                         .store_to_inferred_ptr,
                         .resolve_inferred_alloc,
@@ -3198,7 +3199,9 @@ fn typeOf(
         items[param_i] = try expr(mod, scope, .none, param);
     }
 
-    const result = try gz.addPlNode(.typeof_peer, node, zir.Inst.MultiOp{ .operands_len = @intCast(u32, params.len) });
+    const result = try gz.addPlNode(.typeof_peer, node, zir.Inst.MultiOp{
+        .operands_len = @intCast(u32, params.len),
+    });
     try gz.zir_code.appendRefs(items);
 
     return rvalue(mod, scope, rl, result, node);
@@ -3279,12 +3282,15 @@ fn builtinCall(
             return rvalue(mod, scope, rl, result, node);
         },
         .compile_log => {
-            if (true) @panic("TODO update for zir-memory-layout");
-            const arena = scope.arena();
-            var targets = try arena.alloc(zir.Inst.Ref, params.len);
-            for (params) |param, param_i|
-                targets[param_i] = try expr(mod, scope, .none, param);
-            const result = try addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{});
+            const arg_refs = try mod.gpa.alloc(zir.Inst.Ref, params.len);
+            defer mod.gpa.free(arg_refs);
+
+            for (params) |param, i| arg_refs[i] = try expr(mod, scope, .none, param);
+
+            const result = try gz.addPlNode(.compile_log, node, zir.Inst.MultiOp{
+                .operands_len = @intCast(u32, params.len),
+            });
+            try gz.zir_code.appendRefs(arg_refs);
             return rvalue(mod, scope, rl, result, node);
         },
         .field => {
@@ -3742,7 +3748,10 @@ fn rvalue(
             .operand = result,
         }),
         .ptr => |ptr_inst| {
-            _ = try gz.addBin(.store, ptr_inst, result);
+            _ = try gz.addPlNode(.store_node, src_node, zir.Inst.Bin{
+                .lhs = ptr_inst,
+                .rhs = result,
+            });
             return result;
         },
         .bitcasted_ptr => |bitcasted_ptr| {
src/Sema.zig
@@ -283,6 +283,10 @@ pub fn analyzeBody(
                 try sema.zirStore(block, inst);
                 continue;
             },
+            .store_node => {
+                try sema.zirStoreNode(block, inst);
+                continue;
+            },
             .store_to_block_ptr => {
                 try sema.zirStoreToBlockPtr(block, inst);
                 continue;
@@ -712,7 +716,19 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!v
     const bin_inst = sema.code.instructions.items(.data)[inst].bin;
     const ptr = try sema.resolveInst(bin_inst.lhs);
     const value = try sema.resolveInst(bin_inst.rhs);
-    return sema.storePtr(block, .unneeded, ptr, value);
+    return sema.storePtr(block, sema.src, ptr, value);
+}
+
+fn zirStoreNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void {
+    const tracy = trace(@src());
+    defer tracy.end();
+
+    const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+    const src = inst_data.src();
+    const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
+    const ptr = try sema.resolveInst(extra.lhs);
+    const value = try sema.resolveInst(extra.rhs);
+    return sema.storePtr(block, src, ptr, value);
 }
 
 fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
@@ -3630,7 +3646,7 @@ fn storePtr(
         return sema.mod.fail(&block.base, src, "cannot assign to constant", .{});
 
     const elem_ty = ptr.ty.elemType();
-    const value = try sema.coerce(block, elem_ty, uncasted_value, uncasted_value.src);
+    const value = try sema.coerce(block, elem_ty, uncasted_value, src);
     if (elem_ty.onePossibleValue() != null)
         return;
 
src/zir.zig
@@ -276,7 +276,7 @@ pub const Inst = struct {
         /// Represents a pointer to a global decl.
         /// Uses the `decl` union field.
         decl_ref,
-        /// Equivalent to a decl_ref followed by deref.
+        /// Equivalent to a decl_ref followed by load.
         /// Uses the `decl` union field.
         decl_val,
         /// Load the value from a pointer. Assumes `x.*` syntax.
@@ -470,9 +470,13 @@ pub const Inst = struct {
         /// Slice operation `array_ptr[start..end:sentinel]`.
         /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`.
         slice_sentinel,
-        /// Write a value to a pointer. For loading, see `deref`.
+        /// Write a value to a pointer. For loading, see `load`.
+        /// Source location is assumed to be same as previous instruction.
         /// Uses the `bin` union field.
         store,
+        /// Same as `store` except provides a source location.
+        /// Uses the `pl_node` union field. Payload is `Bin`.
+        store_node,
         /// Same as `store` but the type of the value being stored will be used to infer
         /// the block type. The LHS is the pointer to store to.
         /// Uses the `bin` union field.
@@ -698,6 +702,7 @@ pub const Inst = struct {
                 .shl,
                 .shr,
                 .store,
+                .store_node,
                 .store_to_block_ptr,
                 .store_to_inferred_ptr,
                 .str,
@@ -1444,7 +1449,6 @@ const Writer = struct {
 
             .@"asm",
             .asm_volatile,
-            .compile_log,
             .elem_ptr_node,
             .elem_val_node,
             .field_ptr,
@@ -1455,7 +1459,6 @@ const Writer = struct {
             .slice_start,
             .slice_end,
             .slice_sentinel,
-            .typeof_peer,
             => try self.writePlNode(stream, inst),
 
             .add,
@@ -1479,6 +1482,7 @@ const Writer = struct {
             .shl,
             .shr,
             .xor,
+            .store_node,
             => try self.writePlNodeBin(stream, inst),
 
             .call,
@@ -1495,6 +1499,10 @@ const Writer = struct {
             .condbr_inline,
             => try self.writePlNodeCondBr(stream, inst),
 
+            .compile_log,
+            .typeof_peer,
+            => try self.writePlNodeMultiOp(stream, inst),
+
             .as_node => try self.writeAs(stream, inst),
 
             .breakpoint,
@@ -1694,6 +1702,19 @@ const Writer = struct {
         try self.writeSrc(stream, inst_data.src());
     }
 
+    fn writePlNodeMultiOp(self: *Writer, stream: anytype, inst: Inst.Index) !void {
+        const inst_data = self.code.instructions.items(.data)[inst].pl_node;
+        const extra = self.code.extraData(Inst.MultiOp, inst_data.payload_index);
+        const operands = self.code.refSlice(extra.end, extra.data.operands_len);
+
+        for (operands) |operand, i| {
+            if (i != 0) try stream.writeAll(", ");
+            try self.writeInstRef(stream, operand);
+        }
+        try stream.writeAll(") ");
+        try self.writeSrc(stream, inst_data.src());
+    }
+
     fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void {
         const inst_data = self.code.instructions.items(.data)[inst].pl_node;
         const extra = self.code.extraData(Inst.As, inst_data.payload_index).data;
test/stage2/test.zig
@@ -1072,45 +1072,45 @@ pub fn addCases(ctx: *TestContext) !void {
         , &[_][]const u8{":3:9: error: redefinition of 'testing'"});
     }
 
-    //{
-    //    // TODO make the test harness support checking the compile log output too
-    //    var case = ctx.obj("@compileLog", linux_x64);
-    //    // The other compile error prevents emission of a "found compile log" statement.
-    //    case.addError(
-    //        \\export fn _start() noreturn {
-    //        \\    const b = true;
-    //        \\    var f: u32 = 1;
-    //        \\    @compileLog(b, 20, f, x);
-    //        \\    @compileLog(1000);
-    //        \\    var bruh: usize = true;
-    //        \\    unreachable;
-    //        \\}
-    //        \\export fn other() void {
-    //        \\    @compileLog(1234);
-    //        \\}
-    //        \\fn x() void {}
-    //    , &[_][]const u8{
-    //        ":6:23: error: expected usize, found bool",
-    //    });
+    {
+        // TODO make the test harness support checking the compile log output too
+        var case = ctx.obj("@compileLog", linux_x64);
+        // The other compile error prevents emission of a "found compile log" statement.
+        case.addError(
+            \\export fn _start() noreturn {
+            \\    const b = true;
+            \\    var f: u32 = 1;
+            \\    @compileLog(b, 20, f, x);
+            \\    @compileLog(1000);
+            \\    var bruh: usize = true;
+            \\    unreachable;
+            \\}
+            \\export fn other() void {
+            \\    @compileLog(1234);
+            \\}
+            \\fn x() void {}
+        , &[_][]const u8{
+            ":6:23: error: expected usize, found bool",
+        });
 
-    //    // Now only compile log statements remain. One per Decl.
-    //    case.addError(
-    //        \\export fn _start() noreturn {
-    //        \\    const b = true;
-    //        \\    var f: u32 = 1;
-    //        \\    @compileLog(b, 20, f, x);
-    //        \\    @compileLog(1000);
-    //        \\    unreachable;
-    //        \\}
-    //        \\export fn other() void {
-    //        \\    @compileLog(1234);
-    //        \\}
-    //        \\fn x() void {}
-    //    , &[_][]const u8{
-    //        ":11:8: error: found compile log statement",
-    //        ":4:5: note: also here",
-    //    });
-    //}
+        // Now only compile log statements remain. One per Decl.
+        case.addError(
+            \\export fn _start() noreturn {
+            \\    const b = true;
+            \\    var f: u32 = 1;
+            \\    @compileLog(b, 20, f, x);
+            \\    @compileLog(1000);
+            \\    unreachable;
+            \\}
+            \\export fn other() void {
+            \\    @compileLog(1234);
+            \\}
+            \\fn x() void {}
+        , &[_][]const u8{
+            ":9:5: error: found compile log statement",
+            ":4:5: note: also here",
+        });
+    }
 
     //{
     //    var case = ctx.obj("extern variable has no type", linux_x64);