| author | |
| committer | |
| log | 4bfcd105eff797aceb621d2c8b971c15fef6e450 |
| tree | c52920c273d85b6143fd49a372243e72df2d1389 |
| parent | 4fd3a2e8e82b1793329e329c5a8045bfd6f40a33 |
4 files changed, 98 insertions(+), 52 deletions(-)
src/Sema.zig+18-2| ... | ... | @@ -283,6 +283,10 @@ pub fn analyzeBody( |
| 283 | 283 | try sema.zirStore(block, inst); |
| 284 | 284 | continue; |
| 285 | 285 | }, |
| 286 | .store_node => { | |
| 287 | try sema.zirStoreNode(block, inst); | |
| 288 | continue; | |
| 289 | }, | |
| 286 | 290 | .store_to_block_ptr => { |
| 287 | 291 | try sema.zirStoreToBlockPtr(block, inst); |
| 288 | 292 | continue; |
| ... | ... | @@ -712,7 +716,19 @@ fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!v |
| 712 | 716 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; |
| 713 | 717 | const ptr = try sema.resolveInst(bin_inst.lhs); |
| 714 | 718 | const value = try sema.resolveInst(bin_inst.rhs); |
| 715 | return sema.storePtr(block, .unneeded, ptr, value); | |
| 719 | return sema.storePtr(block, sema.src, ptr, value); | |
| 720 | } | |
| 721 | ||
| 722 | fn zirStoreNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { | |
| 723 | const tracy = trace(@src()); | |
| 724 | defer tracy.end(); | |
| 725 | ||
| 726 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | |
| 727 | const src = inst_data.src(); | |
| 728 | const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data; | |
| 729 | const ptr = try sema.resolveInst(extra.lhs); | |
| 730 | const value = try sema.resolveInst(extra.rhs); | |
| 731 | return sema.storePtr(block, src, ptr, value); | |
| 716 | 732 | } |
| 717 | 733 | |
| 718 | 734 | fn zirParamType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| ... | ... | @@ -3630,7 +3646,7 @@ fn storePtr( |
| 3630 | 3646 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); |
| 3631 | 3647 | |
| 3632 | 3648 | const elem_ty = ptr.ty.elemType(); |
| 3633 | const value = try sema.coerce(block, elem_ty, uncasted_value, uncasted_value.src); | |
| 3649 | const value = try sema.coerce(block, elem_ty, uncasted_value, src); | |
| 3634 | 3650 | if (elem_ty.onePossibleValue() != null) |
| 3635 | 3651 | return; |
| 3636 | 3652 |
src/astgen.zig+17-8| ... | ... | @@ -1130,6 +1130,7 @@ fn blockExprStmts( |
| 1130 | 1130 | .@"unreachable", |
| 1131 | 1131 | .elided, |
| 1132 | 1132 | .store, |
| 1133 | .store_node, | |
| 1133 | 1134 | .store_to_block_ptr, |
| 1134 | 1135 | .store_to_inferred_ptr, |
| 1135 | 1136 | .resolve_inferred_alloc, |
| ... | ... | @@ -3198,7 +3199,9 @@ fn typeOf( |
| 3198 | 3199 | items[param_i] = try expr(mod, scope, .none, param); |
| 3199 | 3200 | } |
| 3200 | 3201 | |
| 3201 | const result = try gz.addPlNode(.typeof_peer, node, zir.Inst.MultiOp{ .operands_len = @intCast(u32, params.len) }); | |
| 3202 | const result = try gz.addPlNode(.typeof_peer, node, zir.Inst.MultiOp{ | |
| 3203 | .operands_len = @intCast(u32, params.len), | |
| 3204 | }); | |
| 3202 | 3205 | try gz.zir_code.appendRefs(items); |
| 3203 | 3206 | |
| 3204 | 3207 | return rvalue(mod, scope, rl, result, node); |
| ... | ... | @@ -3279,12 +3282,15 @@ fn builtinCall( |
| 3279 | 3282 | return rvalue(mod, scope, rl, result, node); |
| 3280 | 3283 | }, |
| 3281 | 3284 | .compile_log => { |
| 3282 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3283 | const arena = scope.arena(); | |
| 3284 | var targets = try arena.alloc(zir.Inst.Ref, params.len); | |
| 3285 | for (params) |param, param_i| | |
| 3286 | targets[param_i] = try expr(mod, scope, .none, param); | |
| 3287 | const result = try addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{}); | |
| 3285 | const arg_refs = try mod.gpa.alloc(zir.Inst.Ref, params.len); | |
| 3286 | defer mod.gpa.free(arg_refs); | |
| 3287 | ||
| 3288 | for (params) |param, i| arg_refs[i] = try expr(mod, scope, .none, param); | |
| 3289 | ||
| 3290 | const result = try gz.addPlNode(.compile_log, node, zir.Inst.MultiOp{ | |
| 3291 | .operands_len = @intCast(u32, params.len), | |
| 3292 | }); | |
| 3293 | try gz.zir_code.appendRefs(arg_refs); | |
| 3288 | 3294 | return rvalue(mod, scope, rl, result, node); |
| 3289 | 3295 | }, |
| 3290 | 3296 | .field => { |
| ... | ... | @@ -3742,7 +3748,10 @@ fn rvalue( |
| 3742 | 3748 | .operand = result, |
| 3743 | 3749 | }), |
| 3744 | 3750 | .ptr => |ptr_inst| { |
| 3745 | _ = try gz.addBin(.store, ptr_inst, result); | |
| 3751 | _ = try gz.addPlNode(.store_node, src_node, zir.Inst.Bin{ | |
| 3752 | .lhs = ptr_inst, | |
| 3753 | .rhs = result, | |
| 3754 | }); | |
| 3746 | 3755 | return result; |
| 3747 | 3756 | }, |
| 3748 | 3757 | .bitcasted_ptr => |bitcasted_ptr| { |
src/zir.zig+25-4| ... | ... | @@ -276,7 +276,7 @@ pub const Inst = struct { |
| 276 | 276 | /// Represents a pointer to a global decl. |
| 277 | 277 | /// Uses the `decl` union field. |
| 278 | 278 | decl_ref, |
| 279 | /// Equivalent to a decl_ref followed by deref. | |
| 279 | /// Equivalent to a decl_ref followed by load. | |
| 280 | 280 | /// Uses the `decl` union field. |
| 281 | 281 | decl_val, |
| 282 | 282 | /// Load the value from a pointer. Assumes `x.*` syntax. |
| ... | ... | @@ -470,9 +470,13 @@ pub const Inst = struct { |
| 470 | 470 | /// Slice operation `array_ptr[start..end:sentinel]`. |
| 471 | 471 | /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`. |
| 472 | 472 | slice_sentinel, |
| 473 | /// Write a value to a pointer. For loading, see `deref`. | |
| 473 | /// Write a value to a pointer. For loading, see `load`. | |
| 474 | /// Source location is assumed to be same as previous instruction. | |
| 474 | 475 | /// Uses the `bin` union field. |
| 475 | 476 | store, |
| 477 | /// Same as `store` except provides a source location. | |
| 478 | /// Uses the `pl_node` union field. Payload is `Bin`. | |
| 479 | store_node, | |
| 476 | 480 | /// Same as `store` but the type of the value being stored will be used to infer |
| 477 | 481 | /// the block type. The LHS is the pointer to store to. |
| 478 | 482 | /// Uses the `bin` union field. |
| ... | ... | @@ -698,6 +702,7 @@ pub const Inst = struct { |
| 698 | 702 | .shl, |
| 699 | 703 | .shr, |
| 700 | 704 | .store, |
| 705 | .store_node, | |
| 701 | 706 | .store_to_block_ptr, |
| 702 | 707 | .store_to_inferred_ptr, |
| 703 | 708 | .str, |
| ... | ... | @@ -1444,7 +1449,6 @@ const Writer = struct { |
| 1444 | 1449 | |
| 1445 | 1450 | .@"asm", |
| 1446 | 1451 | .asm_volatile, |
| 1447 | .compile_log, | |
| 1448 | 1452 | .elem_ptr_node, |
| 1449 | 1453 | .elem_val_node, |
| 1450 | 1454 | .field_ptr, |
| ... | ... | @@ -1455,7 +1459,6 @@ const Writer = struct { |
| 1455 | 1459 | .slice_start, |
| 1456 | 1460 | .slice_end, |
| 1457 | 1461 | .slice_sentinel, |
| 1458 | .typeof_peer, | |
| 1459 | 1462 | => try self.writePlNode(stream, inst), |
| 1460 | 1463 | |
| 1461 | 1464 | .add, |
| ... | ... | @@ -1479,6 +1482,7 @@ const Writer = struct { |
| 1479 | 1482 | .shl, |
| 1480 | 1483 | .shr, |
| 1481 | 1484 | .xor, |
| 1485 | .store_node, | |
| 1482 | 1486 | => try self.writePlNodeBin(stream, inst), |
| 1483 | 1487 | |
| 1484 | 1488 | .call, |
| ... | ... | @@ -1495,6 +1499,10 @@ const Writer = struct { |
| 1495 | 1499 | .condbr_inline, |
| 1496 | 1500 | => try self.writePlNodeCondBr(stream, inst), |
| 1497 | 1501 | |
| 1502 | .compile_log, | |
| 1503 | .typeof_peer, | |
| 1504 | => try self.writePlNodeMultiOp(stream, inst), | |
| 1505 | ||
| 1498 | 1506 | .as_node => try self.writeAs(stream, inst), |
| 1499 | 1507 | |
| 1500 | 1508 | .breakpoint, |
| ... | ... | @@ -1694,6 +1702,19 @@ const Writer = struct { |
| 1694 | 1702 | try self.writeSrc(stream, inst_data.src()); |
| 1695 | 1703 | } |
| 1696 | 1704 | |
| 1705 | fn writePlNodeMultiOp(self: *Writer, stream: anytype, inst: Inst.Index) !void { | |
| 1706 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | |
| 1707 | const extra = self.code.extraData(Inst.MultiOp, inst_data.payload_index); | |
| 1708 | const operands = self.code.refSlice(extra.end, extra.data.operands_len); | |
| 1709 | ||
| 1710 | for (operands) |operand, i| { | |
| 1711 | if (i != 0) try stream.writeAll(", "); | |
| 1712 | try self.writeInstRef(stream, operand); | |
| 1713 | } | |
| 1714 | try stream.writeAll(") "); | |
| 1715 | try self.writeSrc(stream, inst_data.src()); | |
| 1716 | } | |
| 1717 | ||
| 1697 | 1718 | fn writeAs(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 1698 | 1719 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 1699 | 1720 | const extra = self.code.extraData(Inst.As, inst_data.payload_index).data; |
test/stage2/test.zig+38-38| ... | ... | @@ -1072,45 +1072,45 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1072 | 1072 | , &[_][]const u8{":3:9: error: redefinition of 'testing'"}); |
| 1073 | 1073 | } |
| 1074 | 1074 | |
| 1075 | //{ | |
| 1076 | // // TODO make the test harness support checking the compile log output too | |
| 1077 | // var case = ctx.obj("@compileLog", linux_x64); | |
| 1078 | // // The other compile error prevents emission of a "found compile log" statement. | |
| 1079 | // case.addError( | |
| 1080 | // \\export fn _start() noreturn { | |
| 1081 | // \\ const b = true; | |
| 1082 | // \\ var f: u32 = 1; | |
| 1083 | // \\ @compileLog(b, 20, f, x); | |
| 1084 | // \\ @compileLog(1000); | |
| 1085 | // \\ var bruh: usize = true; | |
| 1086 | // \\ unreachable; | |
| 1087 | // \\} | |
| 1088 | // \\export fn other() void { | |
| 1089 | // \\ @compileLog(1234); | |
| 1090 | // \\} | |
| 1091 | // \\fn x() void {} | |
| 1092 | // , &[_][]const u8{ | |
| 1093 | // ":6:23: error: expected usize, found bool", | |
| 1094 | // }); | |
| 1075 | { | |
| 1076 | // TODO make the test harness support checking the compile log output too | |
| 1077 | var case = ctx.obj("@compileLog", linux_x64); | |
| 1078 | // The other compile error prevents emission of a "found compile log" statement. | |
| 1079 | case.addError( | |
| 1080 | \\export fn _start() noreturn { | |
| 1081 | \\ const b = true; | |
| 1082 | \\ var f: u32 = 1; | |
| 1083 | \\ @compileLog(b, 20, f, x); | |
| 1084 | \\ @compileLog(1000); | |
| 1085 | \\ var bruh: usize = true; | |
| 1086 | \\ unreachable; | |
| 1087 | \\} | |
| 1088 | \\export fn other() void { | |
| 1089 | \\ @compileLog(1234); | |
| 1090 | \\} | |
| 1091 | \\fn x() void {} | |
| 1092 | , &[_][]const u8{ | |
| 1093 | ":6:23: error: expected usize, found bool", | |
| 1094 | }); | |
| 1095 | 1095 | |
| 1096 | // // Now only compile log statements remain. One per Decl. | |
| 1097 | // case.addError( | |
| 1098 | // \\export fn _start() noreturn { | |
| 1099 | // \\ const b = true; | |
| 1100 | // \\ var f: u32 = 1; | |
| 1101 | // \\ @compileLog(b, 20, f, x); | |
| 1102 | // \\ @compileLog(1000); | |
| 1103 | // \\ unreachable; | |
| 1104 | // \\} | |
| 1105 | // \\export fn other() void { | |
| 1106 | // \\ @compileLog(1234); | |
| 1107 | // \\} | |
| 1108 | // \\fn x() void {} | |
| 1109 | // , &[_][]const u8{ | |
| 1110 | // ":11:8: error: found compile log statement", | |
| 1111 | // ":4:5: note: also here", | |
| 1112 | // }); | |
| 1113 | //} | |
| 1096 | // Now only compile log statements remain. One per Decl. | |
| 1097 | case.addError( | |
| 1098 | \\export fn _start() noreturn { | |
| 1099 | \\ const b = true; | |
| 1100 | \\ var f: u32 = 1; | |
| 1101 | \\ @compileLog(b, 20, f, x); | |
| 1102 | \\ @compileLog(1000); | |
| 1103 | \\ unreachable; | |
| 1104 | \\} | |
| 1105 | \\export fn other() void { | |
| 1106 | \\ @compileLog(1234); | |
| 1107 | \\} | |
| 1108 | \\fn x() void {} | |
| 1109 | , &[_][]const u8{ | |
| 1110 | ":9:5: error: found compile log statement", | |
| 1111 | ":4:5: note: also here", | |
| 1112 | }); | |
| 1113 | } | |
| 1114 | 1114 | |
| 1115 | 1115 | //{ |
| 1116 | 1116 | // var case = ctx.obj("extern variable has no type", linux_x64); |