| author | |
| committer | |
| log | b27d0526768a5be715eeb9381a61d335e9a05e9e |
| tree | a94afd7f10280876250778528490137b74a0e920 |
| parent | e8143f6cbe3d1bdaeda5cd5af13447f6639b80ad |
* remove the LazySrcLoc.todo tag
* finish updating Sema and AstGen, remove the last of the
`@panic("TODO")`.7 files changed, 158 insertions(+), 159 deletions(-)
BRANCH_TODO-3| ... | @@ -1,9 +1,6 @@ | ... | @@ -1,9 +1,6 @@ |
| 1 | this is my WIP branch scratch pad, to be deleted before merging into master | 1 | this is my WIP branch scratch pad, to be deleted before merging into master |
| 2 | 2 | ||
| 3 | Merge TODO list: | 3 | Merge TODO list: |
| 4 | * remove the LazySrcLoc.todo tag | ||
| 5 | * update astgen.zig | ||
| 6 | * finish updating Sema.zig | ||
| 7 | * finish implementing SrcLoc byteOffset function | 4 | * finish implementing SrcLoc byteOffset function |
| 8 | * audit all the .unneeded src locations | 5 | * audit all the .unneeded src locations |
| 9 | * audit the calls in codegen toSrcLocWithDecl specifically if there is inlined function | 6 | * audit the calls in codegen toSrcLocWithDecl specifically if there is inlined function |
lib/std/zig/ast.zig+5| ... | @@ -1252,6 +1252,7 @@ pub const Tree = struct { | ... | @@ -1252,6 +1252,7 @@ pub const Tree = struct { |
| 1252 | buffer[0] = data.lhs; | 1252 | buffer[0] = data.lhs; |
| 1253 | const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1]; | 1253 | const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1]; |
| 1254 | return tree.fullFnProto(.{ | 1254 | return tree.fullFnProto(.{ |
| 1255 | .proto_node = node, | ||
| 1255 | .fn_token = tree.nodes.items(.main_token)[node], | 1256 | .fn_token = tree.nodes.items(.main_token)[node], |
| 1256 | .return_type = data.rhs, | 1257 | .return_type = data.rhs, |
| 1257 | .params = params, | 1258 | .params = params, |
| ... | @@ -1267,6 +1268,7 @@ pub const Tree = struct { | ... | @@ -1267,6 +1268,7 @@ pub const Tree = struct { |
| 1267 | const params_range = tree.extraData(data.lhs, Node.SubRange); | 1268 | const params_range = tree.extraData(data.lhs, Node.SubRange); |
| 1268 | const params = tree.extra_data[params_range.start..params_range.end]; | 1269 | const params = tree.extra_data[params_range.start..params_range.end]; |
| 1269 | return tree.fullFnProto(.{ | 1270 | return tree.fullFnProto(.{ |
| 1271 | .proto_node = node, | ||
| 1270 | .fn_token = tree.nodes.items(.main_token)[node], | 1272 | .fn_token = tree.nodes.items(.main_token)[node], |
| 1271 | .return_type = data.rhs, | 1273 | .return_type = data.rhs, |
| 1272 | .params = params, | 1274 | .params = params, |
| ... | @@ -1283,6 +1285,7 @@ pub const Tree = struct { | ... | @@ -1283,6 +1285,7 @@ pub const Tree = struct { |
| 1283 | buffer[0] = extra.param; | 1285 | buffer[0] = extra.param; |
| 1284 | const params = if (extra.param == 0) buffer[0..0] else buffer[0..1]; | 1286 | const params = if (extra.param == 0) buffer[0..0] else buffer[0..1]; |
| 1285 | return tree.fullFnProto(.{ | 1287 | return tree.fullFnProto(.{ |
| 1288 | .proto_node = node, | ||
| 1286 | .fn_token = tree.nodes.items(.main_token)[node], | 1289 | .fn_token = tree.nodes.items(.main_token)[node], |
| 1287 | .return_type = data.rhs, | 1290 | .return_type = data.rhs, |
| 1288 | .params = params, | 1291 | .params = params, |
| ... | @@ -1298,6 +1301,7 @@ pub const Tree = struct { | ... | @@ -1298,6 +1301,7 @@ pub const Tree = struct { |
| 1298 | const extra = tree.extraData(data.lhs, Node.FnProto); | 1301 | const extra = tree.extraData(data.lhs, Node.FnProto); |
| 1299 | const params = tree.extra_data[extra.params_start..extra.params_end]; | 1302 | const params = tree.extra_data[extra.params_start..extra.params_end]; |
| 1300 | return tree.fullFnProto(.{ | 1303 | return tree.fullFnProto(.{ |
| 1304 | .proto_node = node, | ||
| 1301 | .fn_token = tree.nodes.items(.main_token)[node], | 1305 | .fn_token = tree.nodes.items(.main_token)[node], |
| 1302 | .return_type = data.rhs, | 1306 | .return_type = data.rhs, |
| 1303 | .params = params, | 1307 | .params = params, |
| ... | @@ -2120,6 +2124,7 @@ pub const full = struct { | ... | @@ -2120,6 +2124,7 @@ pub const full = struct { |
| 2120 | ast: Ast, | 2124 | ast: Ast, |
| 2121 | 2125 | ||
| 2122 | pub const Ast = struct { | 2126 | pub const Ast = struct { |
| 2127 | proto_node: Node.Index, | ||
| 2123 | fn_token: TokenIndex, | 2128 | fn_token: TokenIndex, |
| 2124 | return_type: Node.Index, | 2129 | return_type: Node.Index, |
| 2125 | params: []const Node.Index, | 2130 | params: []const Node.Index, |
src/AstGen.zig+24-53| ... | @@ -133,10 +133,6 @@ pub const ResultLoc = union(enum) { | ... | @@ -133,10 +133,6 @@ pub const ResultLoc = union(enum) { |
| 133 | /// The result instruction from the expression must be ignored. | 133 | /// The result instruction from the expression must be ignored. |
| 134 | /// Always an instruction with tag `alloc_inferred`. | 134 | /// Always an instruction with tag `alloc_inferred`. |
| 135 | inferred_ptr: zir.Inst.Ref, | 135 | inferred_ptr: zir.Inst.Ref, |
| 136 | /// The expression must store its result into this pointer, which is a typed pointer that | ||
| 137 | /// has been bitcasted to whatever the expression's type is. | ||
| 138 | /// The result instruction from the expression must be ignored. | ||
| 139 | bitcasted_ptr: zir.Inst.Ref, | ||
| 140 | /// There is a pointer for the expression to store its result into, however, its type | 136 | /// There is a pointer for the expression to store its result into, however, its type |
| 141 | /// is inferred based on peer type resolution for a `zir.Inst.Block`. | 137 | /// is inferred based on peer type resolution for a `zir.Inst.Block`. |
| 142 | /// The result instruction from the expression must be ignored. | 138 | /// The result instruction from the expression must be ignored. |
| ... | @@ -172,7 +168,7 @@ pub const ResultLoc = union(enum) { | ... | @@ -172,7 +168,7 @@ pub const ResultLoc = union(enum) { |
| 172 | .tag = .break_void, | 168 | .tag = .break_void, |
| 173 | .elide_store_to_block_ptr_instructions = false, | 169 | .elide_store_to_block_ptr_instructions = false, |
| 174 | }, | 170 | }, |
| 175 | .inferred_ptr, .bitcasted_ptr, .block_ptr => { | 171 | .inferred_ptr, .block_ptr => { |
| 176 | if (block_scope.rvalue_rl_count == block_scope.break_count) { | 172 | if (block_scope.rvalue_rl_count == block_scope.break_count) { |
| 177 | // Neither prong of the if consumed the result location, so we can | 173 | // Neither prong of the if consumed the result location, so we can |
| 178 | // use break instructions to create an rvalue. | 174 | // use break instructions to create an rvalue. |
| ... | @@ -388,7 +384,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!zir.Ins | ... | @@ -388,7 +384,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!zir.Ins |
| 388 | } | 384 | } |
| 389 | 385 | ||
| 390 | /// Turn Zig AST into untyped ZIR istructions. | 386 | /// Turn Zig AST into untyped ZIR istructions. |
| 391 | /// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the | 387 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the |
| 392 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, | 388 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, |
| 393 | /// it must otherwise not be used. | 389 | /// it must otherwise not be used. |
| 394 | pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref { | 390 | pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref { |
| ... | @@ -1155,7 +1151,6 @@ fn blockExprStmts( | ... | @@ -1155,7 +1151,6 @@ fn blockExprStmts( |
| 1155 | .asm_volatile, | 1151 | .asm_volatile, |
| 1156 | .bit_and, | 1152 | .bit_and, |
| 1157 | .bitcast, | 1153 | .bitcast, |
| 1158 | .bitcast_ref, | ||
| 1159 | .bitcast_result_ptr, | 1154 | .bitcast_result_ptr, |
| 1160 | .bit_or, | 1155 | .bit_or, |
| 1161 | .block, | 1156 | .block, |
| ... | @@ -1804,7 +1799,7 @@ fn orelseCatchExpr( | ... | @@ -1804,7 +1799,7 @@ fn orelseCatchExpr( |
| 1804 | // TODO handle catch | 1799 | // TODO handle catch |
| 1805 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { | 1800 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { |
| 1806 | .ref => .ref, | 1801 | .ref => .ref, |
| 1807 | .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => .none, | 1802 | .discard, .none, .block_ptr, .inferred_ptr => .none, |
| 1808 | .ty => |elem_ty| blk: { | 1803 | .ty => |elem_ty| blk: { |
| 1809 | const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node); | 1804 | const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node); |
| 1810 | break :blk .{ .ty = wrapped_ty }; | 1805 | break :blk .{ .ty = wrapped_ty }; |
| ... | @@ -3519,7 +3514,6 @@ fn as( | ... | @@ -3519,7 +3514,6 @@ fn as( |
| 3519 | gz: *GenZir, | 3514 | gz: *GenZir, |
| 3520 | scope: *Scope, | 3515 | scope: *Scope, |
| 3521 | rl: ResultLoc, | 3516 | rl: ResultLoc, |
| 3522 | builtin_token: ast.TokenIndex, | ||
| 3523 | node: ast.Node.Index, | 3517 | node: ast.Node.Index, |
| 3524 | lhs: ast.Node.Index, | 3518 | lhs: ast.Node.Index, |
| 3525 | rhs: ast.Node.Index, | 3519 | rhs: ast.Node.Index, |
| ... | @@ -3538,13 +3532,9 @@ fn as( | ... | @@ -3538,13 +3532,9 @@ fn as( |
| 3538 | return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type); | 3532 | return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type); |
| 3539 | }, | 3533 | }, |
| 3540 | 3534 | ||
| 3541 | .bitcasted_ptr => |bitcasted_ptr| { | ||
| 3542 | // TODO here we should be able to resolve the inference; we now have a type for the result. | ||
| 3543 | return gz.astgen.mod.failTok(scope, builtin_token, "TODO implement @as with result location @bitCast", .{}); | ||
| 3544 | }, | ||
| 3545 | .inferred_ptr => |result_alloc| { | 3535 | .inferred_ptr => |result_alloc| { |
| 3546 | // TODO here we should be able to resolve the inference; we now have a type for the result. | 3536 | // TODO here we should be able to resolve the inference; we now have a type for the result. |
| 3547 | return gz.astgen.mod.failTok(scope, builtin_token, "TODO implement @as with inferred-type result location pointer", .{}); | 3537 | return gz.astgen.mod.failNode(scope, node, "TODO implement @as with inferred-type result location pointer", .{}); |
| 3548 | }, | 3538 | }, |
| 3549 | } | 3539 | } |
| 3550 | } | 3540 | } |
| ... | @@ -3599,47 +3589,32 @@ fn bitCast( | ... | @@ -3599,47 +3589,32 @@ fn bitCast( |
| 3599 | gz: *GenZir, | 3589 | gz: *GenZir, |
| 3600 | scope: *Scope, | 3590 | scope: *Scope, |
| 3601 | rl: ResultLoc, | 3591 | rl: ResultLoc, |
| 3602 | builtin_token: ast.TokenIndex, | ||
| 3603 | node: ast.Node.Index, | 3592 | node: ast.Node.Index, |
| 3604 | lhs: ast.Node.Index, | 3593 | lhs: ast.Node.Index, |
| 3605 | rhs: ast.Node.Index, | 3594 | rhs: ast.Node.Index, |
| 3606 | ) InnerError!zir.Inst.Ref { | 3595 | ) InnerError!zir.Inst.Ref { |
| 3607 | if (true) @panic("TODO update for zir-memory-layout"); | 3596 | const mod = gz.astgen.mod; |
| 3608 | const dest_type = try typeExpr(gz, scope, lhs); | 3597 | const dest_type = try typeExpr(gz, scope, lhs); |
| 3609 | switch (rl) { | 3598 | switch (rl) { |
| 3610 | .none => { | 3599 | .none, .discard, .ty => { |
| 3611 | const operand = try expr(gz, scope, .none, rhs); | 3600 | const operand = try expr(gz, scope, .none, rhs); |
| 3612 | return addZIRBinOp(mod, scope, src, .bitcast, dest_type, operand); | 3601 | const result = try gz.addPlNode(.bitcast, node, zir.Inst.Bin{ |
| 3613 | }, | 3602 | .lhs = dest_type, |
| 3614 | .discard => { | 3603 | .rhs = operand, |
| 3615 | const operand = try expr(gz, scope, .none, rhs); | 3604 | }); |
| 3616 | const result = try addZIRBinOp(mod, scope, src, .bitcast, dest_type, operand); | 3605 | return rvalue(gz, scope, rl, result, node); |
| 3617 | _ = try addZIRUnOp(mod, scope, result.src, .ensure_result_non_error, result); | ||
| 3618 | return result; | ||
| 3619 | }, | ||
| 3620 | .ref => { | ||
| 3621 | const operand = try expr(gz, scope, .ref, rhs); | ||
| 3622 | const result = try addZIRBinOp(mod, scope, src, .bitcast_ref, dest_type, operand); | ||
| 3623 | return result; | ||
| 3624 | }, | ||
| 3625 | .ty => |result_ty| { | ||
| 3626 | const result = try expr(gz, scope, .none, rhs); | ||
| 3627 | const bitcasted = try addZIRBinOp(mod, scope, src, .bitcast, dest_type, result); | ||
| 3628 | return addZIRBinOp(mod, scope, src, .as, result_ty, bitcasted); | ||
| 3629 | }, | 3606 | }, |
| 3607 | .ref => unreachable, // `@bitCast` is not allowed as an r-value. | ||
| 3630 | .ptr => |result_ptr| { | 3608 | .ptr => |result_ptr| { |
| 3631 | const casted_result_ptr = try addZIRUnOp(mod, scope, src, .bitcast_result_ptr, result_ptr); | 3609 | const casted_result_ptr = try gz.addUnNode(.bitcast_result_ptr, result_ptr, node); |
| 3632 | return expr(gz, scope, .{ .bitcasted_ptr = casted_result_ptr.castTag(.bitcast_result_ptr).? }, rhs); | 3610 | return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs); |
| 3633 | }, | ||
| 3634 | .bitcasted_ptr => |bitcasted_ptr| { | ||
| 3635 | return mod.failTok(scope, builtin_token, "TODO implement @bitCast with result location another @bitCast", .{}); | ||
| 3636 | }, | 3611 | }, |
| 3637 | .block_ptr => |block_ptr| { | 3612 | .block_ptr => |block_ptr| { |
| 3638 | return mod.failTok(scope, builtin_token, "TODO implement @bitCast with result location inferred peer types", .{}); | 3613 | return mod.failNode(scope, node, "TODO implement @bitCast with result location inferred peer types", .{}); |
| 3639 | }, | 3614 | }, |
| 3640 | .inferred_ptr => |result_alloc| { | 3615 | .inferred_ptr => |result_alloc| { |
| 3641 | // TODO here we should be able to resolve the inference; we now have a type for the result. | 3616 | // TODO here we should be able to resolve the inference; we now have a type for the result. |
| 3642 | return mod.failTok(scope, builtin_token, "TODO implement @bitCast with inferred-type result location pointer", .{}); | 3617 | return mod.failNode(scope, node, "TODO implement @bitCast with inferred-type result location pointer", .{}); |
| 3643 | }, | 3618 | }, |
| 3644 | } | 3619 | } |
| 3645 | } | 3620 | } |
| ... | @@ -3648,12 +3623,11 @@ fn typeOf( | ... | @@ -3648,12 +3623,11 @@ fn typeOf( |
| 3648 | gz: *GenZir, | 3623 | gz: *GenZir, |
| 3649 | scope: *Scope, | 3624 | scope: *Scope, |
| 3650 | rl: ResultLoc, | 3625 | rl: ResultLoc, |
| 3651 | builtin_token: ast.TokenIndex, | ||
| 3652 | node: ast.Node.Index, | 3626 | node: ast.Node.Index, |
| 3653 | params: []const ast.Node.Index, | 3627 | params: []const ast.Node.Index, |
| 3654 | ) InnerError!zir.Inst.Ref { | 3628 | ) InnerError!zir.Inst.Ref { |
| 3655 | if (params.len < 1) { | 3629 | if (params.len < 1) { |
| 3656 | return gz.astgen.mod.failTok(scope, builtin_token, "expected at least 1 argument, found 0", .{}); | 3630 | return gz.astgen.mod.failNode(scope, node, "expected at least 1 argument, found 0", .{}); |
| 3657 | } | 3631 | } |
| 3658 | if (params.len == 1) { | 3632 | if (params.len == 1) { |
| 3659 | const result = try gz.addUnNode(.typeof, try expr(gz, scope, .none, params[0]), node); | 3633 | const result = try gz.addUnNode(.typeof, try expr(gz, scope, .none, params[0]), node); |
| ... | @@ -3693,14 +3667,14 @@ fn builtinCall( | ... | @@ -3693,14 +3667,14 @@ fn builtinCall( |
| 3693 | // Also, some builtins have a variable number of parameters. | 3667 | // Also, some builtins have a variable number of parameters. |
| 3694 | 3668 | ||
| 3695 | const info = BuiltinFn.list.get(builtin_name) orelse { | 3669 | const info = BuiltinFn.list.get(builtin_name) orelse { |
| 3696 | return mod.failTok(scope, builtin_token, "invalid builtin function: '{s}'", .{ | 3670 | return mod.failNode(scope, node, "invalid builtin function: '{s}'", .{ |
| 3697 | builtin_name, | 3671 | builtin_name, |
| 3698 | }); | 3672 | }); |
| 3699 | }; | 3673 | }; |
| 3700 | if (info.param_count) |expected| { | 3674 | if (info.param_count) |expected| { |
| 3701 | if (expected != params.len) { | 3675 | if (expected != params.len) { |
| 3702 | const s = if (expected == 1) "" else "s"; | 3676 | const s = if (expected == 1) "" else "s"; |
| 3703 | return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{ | 3677 | return mod.failNode(scope, node, "expected {d} parameter{s}, found {d}", .{ |
| 3704 | expected, s, params.len, | 3678 | expected, s, params.len, |
| 3705 | }); | 3679 | }); |
| 3706 | } | 3680 | } |
| ... | @@ -3788,9 +3762,9 @@ fn builtinCall( | ... | @@ -3788,9 +3762,9 @@ fn builtinCall( |
| 3788 | }); | 3762 | }); |
| 3789 | return rvalue(gz, scope, rl, result, node); | 3763 | return rvalue(gz, scope, rl, result, node); |
| 3790 | }, | 3764 | }, |
| 3791 | .as => return as(gz, scope, rl, builtin_token, node, params[0], params[1]), | 3765 | .as => return as(gz, scope, rl, node, params[0], params[1]), |
| 3792 | .bit_cast => return bitCast(gz, scope, rl, builtin_token, node, params[0], params[1]), | 3766 | .bit_cast => return bitCast(gz, scope, rl, node, params[0], params[1]), |
| 3793 | .TypeOf => return typeOf(gz, scope, rl, builtin_token, node, params), | 3767 | .TypeOf => return typeOf(gz, scope, rl, node, params), |
| 3794 | 3768 | ||
| 3795 | .add_with_overflow, | 3769 | .add_with_overflow, |
| 3796 | .align_cast, | 3770 | .align_cast, |
| ... | @@ -3875,7 +3849,7 @@ fn builtinCall( | ... | @@ -3875,7 +3849,7 @@ fn builtinCall( |
| 3875 | .type_info, | 3849 | .type_info, |
| 3876 | .type_name, | 3850 | .type_name, |
| 3877 | .union_init, | 3851 | .union_init, |
| 3878 | => return mod.failTok(scope, builtin_token, "TODO: implement builtin function {s}", .{ | 3852 | => return mod.failNode(scope, node, "TODO: implement builtin function {s}", .{ |
| 3879 | builtin_name, | 3853 | builtin_name, |
| 3880 | }), | 3854 | }), |
| 3881 | 3855 | ||
| ... | @@ -3884,7 +3858,7 @@ fn builtinCall( | ... | @@ -3884,7 +3858,7 @@ fn builtinCall( |
| 3884 | .Frame, | 3858 | .Frame, |
| 3885 | .frame_address, | 3859 | .frame_address, |
| 3886 | .frame_size, | 3860 | .frame_size, |
| 3887 | => return mod.failTok(scope, builtin_token, "async and related features are not yet supported", .{}), | 3861 | => return mod.failNode(scope, node, "async and related features are not yet supported", .{}), |
| 3888 | } | 3862 | } |
| 3889 | } | 3863 | } |
| 3890 | 3864 | ||
| ... | @@ -4286,9 +4260,6 @@ fn rvalue( | ... | @@ -4286,9 +4260,6 @@ fn rvalue( |
| 4286 | }); | 4260 | }); |
| 4287 | return result; | 4261 | return result; |
| 4288 | }, | 4262 | }, |
| 4289 | .bitcasted_ptr => |bitcasted_ptr| { | ||
| 4290 | return gz.astgen.mod.failNode(scope, src_node, "TODO implement rvalue .bitcasted_ptr", .{}); | ||
| 4291 | }, | ||
| 4292 | .inferred_ptr => |alloc| { | 4263 | .inferred_ptr => |alloc| { |
| 4293 | _ = try gz.addBin(.store_to_inferred_ptr, alloc, result); | 4264 | _ = try gz.addBin(.store_to_inferred_ptr, alloc, result); |
| 4294 | return result; | 4265 | return result; |
src/Module.zig+42-27| ... | @@ -1016,11 +1016,6 @@ pub const Scope = struct { | ... | @@ -1016,11 +1016,6 @@ pub const Scope = struct { |
| 1016 | gz.break_result_loc = .{ .block_ptr = gz }; | 1016 | gz.break_result_loc = .{ .block_ptr = gz }; |
| 1017 | }, | 1017 | }, |
| 1018 | 1018 | ||
| 1019 | .bitcasted_ptr => |ptr| { | ||
| 1020 | gz.rl_ptr = ptr; | ||
| 1021 | gz.break_result_loc = .{ .block_ptr = gz }; | ||
| 1022 | }, | ||
| 1023 | |||
| 1024 | .block_ptr => |parent_block_scope| { | 1019 | .block_ptr => |parent_block_scope| { |
| 1025 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; | 1020 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; |
| 1026 | gz.rl_ptr = parent_block_scope.rl_ptr; | 1021 | gz.rl_ptr = parent_block_scope.rl_ptr; |
| ... | @@ -1052,10 +1047,12 @@ pub const Scope = struct { | ... | @@ -1052,10 +1047,12 @@ pub const Scope = struct { |
| 1052 | } | 1047 | } |
| 1053 | 1048 | ||
| 1054 | pub fn addFnTypeCc(gz: *GenZir, tag: zir.Inst.Tag, args: struct { | 1049 | pub fn addFnTypeCc(gz: *GenZir, tag: zir.Inst.Tag, args: struct { |
| 1050 | src_node: ast.Node.Index, | ||
| 1055 | param_types: []const zir.Inst.Ref, | 1051 | param_types: []const zir.Inst.Ref, |
| 1056 | ret_ty: zir.Inst.Ref, | 1052 | ret_ty: zir.Inst.Ref, |
| 1057 | cc: zir.Inst.Ref, | 1053 | cc: zir.Inst.Ref, |
| 1058 | }) !zir.Inst.Ref { | 1054 | }) !zir.Inst.Ref { |
| 1055 | assert(args.src_node != 0); | ||
| 1059 | assert(args.ret_ty != .none); | 1056 | assert(args.ret_ty != .none); |
| 1060 | assert(args.cc != .none); | 1057 | assert(args.cc != .none); |
| 1061 | const gpa = gz.astgen.mod.gpa; | 1058 | const gpa = gz.astgen.mod.gpa; |
| ... | @@ -1065,6 +1062,7 @@ pub const Scope = struct { | ... | @@ -1065,6 +1062,7 @@ pub const Scope = struct { |
| 1065 | @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len); | 1062 | @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len); |
| 1066 | 1063 | ||
| 1067 | const payload_index = gz.astgen.addExtraAssumeCapacity(zir.Inst.FnTypeCc{ | 1064 | const payload_index = gz.astgen.addExtraAssumeCapacity(zir.Inst.FnTypeCc{ |
| 1065 | .return_type = args.ret_ty, | ||
| 1068 | .cc = args.cc, | 1066 | .cc = args.cc, |
| 1069 | .param_types_len = @intCast(u32, args.param_types.len), | 1067 | .param_types_len = @intCast(u32, args.param_types.len), |
| 1070 | }); | 1068 | }); |
| ... | @@ -1073,8 +1071,8 @@ pub const Scope = struct { | ... | @@ -1073,8 +1071,8 @@ pub const Scope = struct { |
| 1073 | const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len); | 1071 | const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len); |
| 1074 | gz.astgen.instructions.appendAssumeCapacity(.{ | 1072 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 1075 | .tag = tag, | 1073 | .tag = tag, |
| 1076 | .data = .{ .fn_type = .{ | 1074 | .data = .{ .pl_node = .{ |
| 1077 | .return_type = args.ret_ty, | 1075 | .src_node = gz.astgen.decl.nodeIndexToRelative(args.src_node), |
| 1078 | .payload_index = payload_index, | 1076 | .payload_index = payload_index, |
| 1079 | } }, | 1077 | } }, |
| 1080 | }); | 1078 | }); |
| ... | @@ -1082,29 +1080,30 @@ pub const Scope = struct { | ... | @@ -1082,29 +1080,30 @@ pub const Scope = struct { |
| 1082 | return gz.astgen.indexToRef(new_index); | 1080 | return gz.astgen.indexToRef(new_index); |
| 1083 | } | 1081 | } |
| 1084 | 1082 | ||
| 1085 | pub fn addFnType( | 1083 | pub fn addFnType(gz: *GenZir, tag: zir.Inst.Tag, args: struct { |
| 1086 | gz: *GenZir, | 1084 | src_node: ast.Node.Index, |
| 1087 | tag: zir.Inst.Tag, | ||
| 1088 | ret_ty: zir.Inst.Ref, | 1085 | ret_ty: zir.Inst.Ref, |
| 1089 | param_types: []const zir.Inst.Ref, | 1086 | param_types: []const zir.Inst.Ref, |
| 1090 | ) !zir.Inst.Ref { | 1087 | }) !zir.Inst.Ref { |
| 1091 | assert(ret_ty != .none); | 1088 | assert(args.src_node != 0); |
| 1089 | assert(args.ret_ty != .none); | ||
| 1092 | const gpa = gz.astgen.mod.gpa; | 1090 | const gpa = gz.astgen.mod.gpa; |
| 1093 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); | 1091 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); |
| 1094 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); | 1092 | try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1); |
| 1095 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + | 1093 | try gz.astgen.extra.ensureCapacity(gpa, gz.astgen.extra.items.len + |
| 1096 | @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len); | 1094 | @typeInfo(zir.Inst.FnType).Struct.fields.len + args.param_types.len); |
| 1097 | 1095 | ||
| 1098 | const payload_index = gz.astgen.addExtraAssumeCapacity(zir.Inst.FnType{ | 1096 | const payload_index = gz.astgen.addExtraAssumeCapacity(zir.Inst.FnType{ |
| 1099 | .param_types_len = @intCast(u32, param_types.len), | 1097 | .return_type = args.ret_ty, |
| 1098 | .param_types_len = @intCast(u32, args.param_types.len), | ||
| 1100 | }); | 1099 | }); |
| 1101 | gz.astgen.appendRefsAssumeCapacity(param_types); | 1100 | gz.astgen.appendRefsAssumeCapacity(args.param_types); |
| 1102 | 1101 | ||
| 1103 | const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len); | 1102 | const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len); |
| 1104 | gz.astgen.instructions.appendAssumeCapacity(.{ | 1103 | gz.astgen.instructions.appendAssumeCapacity(.{ |
| 1105 | .tag = tag, | 1104 | .tag = tag, |
| 1106 | .data = .{ .fn_type = .{ | 1105 | .data = .{ .pl_node = .{ |
| 1107 | .return_type = ret_ty, | 1106 | .src_node = gz.astgen.decl.nodeIndexToRelative(args.src_node), |
| 1108 | .payload_index = payload_index, | 1107 | .payload_index = payload_index, |
| 1109 | } }, | 1108 | } }, |
| 1110 | }); | 1109 | }); |
| ... | @@ -1513,7 +1512,6 @@ pub const SrcLoc = struct { | ... | @@ -1513,7 +1512,6 @@ pub const SrcLoc = struct { |
| 1513 | pub fn fileScope(src_loc: SrcLoc) *Scope.File { | 1512 | pub fn fileScope(src_loc: SrcLoc) *Scope.File { |
| 1514 | return switch (src_loc.lazy) { | 1513 | return switch (src_loc.lazy) { |
| 1515 | .unneeded => unreachable, | 1514 | .unneeded => unreachable, |
| 1516 | .todo => unreachable, | ||
| 1517 | 1515 | ||
| 1518 | .byte_abs, | 1516 | .byte_abs, |
| 1519 | .token_abs, | 1517 | .token_abs, |
| ... | @@ -1542,6 +1540,8 @@ pub const SrcLoc = struct { | ... | @@ -1542,6 +1540,8 @@ pub const SrcLoc = struct { |
| 1542 | .node_offset_switch_operand, | 1540 | .node_offset_switch_operand, |
| 1543 | .node_offset_switch_special_prong, | 1541 | .node_offset_switch_special_prong, |
| 1544 | .node_offset_switch_range, | 1542 | .node_offset_switch_range, |
| 1543 | .node_offset_fn_type_cc, | ||
| 1544 | .node_offset_fn_type_ret_ty, | ||
| 1545 | => src_loc.container.decl.container.file_scope, | 1545 | => src_loc.container.decl.container.file_scope, |
| 1546 | }; | 1546 | }; |
| 1547 | } | 1547 | } |
| ... | @@ -1549,7 +1549,6 @@ pub const SrcLoc = struct { | ... | @@ -1549,7 +1549,6 @@ pub const SrcLoc = struct { |
| 1549 | pub fn byteOffset(src_loc: SrcLoc) !u32 { | 1549 | pub fn byteOffset(src_loc: SrcLoc) !u32 { |
| 1550 | switch (src_loc.lazy) { | 1550 | switch (src_loc.lazy) { |
| 1551 | .unneeded => unreachable, | 1551 | .unneeded => unreachable, |
| 1552 | .todo => unreachable, | ||
| 1553 | 1552 | ||
| 1554 | .byte_abs => |byte_index| return byte_index, | 1553 | .byte_abs => |byte_index| return byte_index, |
| 1555 | 1554 | ||
| ... | @@ -1676,6 +1675,8 @@ pub const SrcLoc = struct { | ... | @@ -1676,6 +1675,8 @@ pub const SrcLoc = struct { |
| 1676 | .node_offset_switch_operand => @panic("TODO"), | 1675 | .node_offset_switch_operand => @panic("TODO"), |
| 1677 | .node_offset_switch_special_prong => @panic("TODO"), | 1676 | .node_offset_switch_special_prong => @panic("TODO"), |
| 1678 | .node_offset_switch_range => @panic("TODO"), | 1677 | .node_offset_switch_range => @panic("TODO"), |
| 1678 | .node_offset_fn_type_cc => @panic("TODO"), | ||
| 1679 | .node_offset_fn_type_ret_ty => @panic("TODO"), | ||
| 1679 | } | 1680 | } |
| 1680 | } | 1681 | } |
| 1681 | }; | 1682 | }; |
| ... | @@ -1695,11 +1696,6 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1695,11 +1696,6 @@ pub const LazySrcLoc = union(enum) { |
| 1695 | /// look into using reverse-continue with a memory watchpoint to see where the | 1696 | /// look into using reverse-continue with a memory watchpoint to see where the |
| 1696 | /// value is being set to this tag. | 1697 | /// value is being set to this tag. |
| 1697 | unneeded, | 1698 | unneeded, |
| 1698 | /// Same as `unneeded`, except the code setting up this tag knew that actually | ||
| 1699 | /// the source location was needed, and I wanted to get other stuff compiling | ||
| 1700 | /// and working before coming back to messing with source locations. | ||
| 1701 | /// TODO delete this tag before merging the zir-memory-layout branch. | ||
| 1702 | todo, | ||
| 1703 | /// The source location points to a byte offset within a source file, | 1699 | /// The source location points to a byte offset within a source file, |
| 1704 | /// offset from 0. The source file is determined contextually. | 1700 | /// offset from 0. The source file is determined contextually. |
| 1705 | /// Inside a `SrcLoc`, the `file_scope` union field will be active. | 1701 | /// Inside a `SrcLoc`, the `file_scope` union field will be active. |
| ... | @@ -1824,12 +1820,23 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1824,12 +1820,23 @@ pub const LazySrcLoc = union(enum) { |
| 1824 | /// range nodes. The error applies to all of them. | 1820 | /// range nodes. The error applies to all of them. |
| 1825 | /// The Decl is determined contextually. | 1821 | /// The Decl is determined contextually. |
| 1826 | node_offset_switch_range: i32, | 1822 | node_offset_switch_range: i32, |
| 1823 | /// The source location points to the calling convention of a function type | ||
| 1824 | /// expression, found by taking this AST node index offset from the containing | ||
| 1825 | /// Decl AST node, which points to a function type AST node. Next, nagivate to | ||
| 1826 | /// the calling convention node. | ||
| 1827 | /// The Decl is determined contextually. | ||
| 1828 | node_offset_fn_type_cc: i32, | ||
| 1829 | /// The source location points to the return type of a function type | ||
| 1830 | /// expression, found by taking this AST node index offset from the containing | ||
| 1831 | /// Decl AST node, which points to a function type AST node. Next, nagivate to | ||
| 1832 | /// the return type node. | ||
| 1833 | /// The Decl is determined contextually. | ||
| 1834 | node_offset_fn_type_ret_ty: i32, | ||
| 1827 | 1835 | ||
| 1828 | /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. | 1836 | /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope. |
| 1829 | pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { | 1837 | pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc { |
| 1830 | return switch (lazy) { | 1838 | return switch (lazy) { |
| 1831 | .unneeded, | 1839 | .unneeded, |
| 1832 | .todo, | ||
| 1833 | .byte_abs, | 1840 | .byte_abs, |
| 1834 | .token_abs, | 1841 | .token_abs, |
| 1835 | .node_abs, | 1842 | .node_abs, |
| ... | @@ -1860,6 +1867,8 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1860,6 +1867,8 @@ pub const LazySrcLoc = union(enum) { |
| 1860 | .node_offset_switch_operand, | 1867 | .node_offset_switch_operand, |
| 1861 | .node_offset_switch_special_prong, | 1868 | .node_offset_switch_special_prong, |
| 1862 | .node_offset_switch_range, | 1869 | .node_offset_switch_range, |
| 1870 | .node_offset_fn_type_cc, | ||
| 1871 | .node_offset_fn_type_ret_ty, | ||
| 1863 | => .{ | 1872 | => .{ |
| 1864 | .container = .{ .decl = scope.srcDecl().? }, | 1873 | .container = .{ .decl = scope.srcDecl().? }, |
| 1865 | .lazy = lazy, | 1874 | .lazy = lazy, |
| ... | @@ -1871,7 +1880,6 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1871,7 +1880,6 @@ pub const LazySrcLoc = union(enum) { |
| 1871 | pub fn toSrcLocWithDecl(lazy: LazySrcLoc, decl: *Decl) SrcLoc { | 1880 | pub fn toSrcLocWithDecl(lazy: LazySrcLoc, decl: *Decl) SrcLoc { |
| 1872 | return switch (lazy) { | 1881 | return switch (lazy) { |
| 1873 | .unneeded, | 1882 | .unneeded, |
| 1874 | .todo, | ||
| 1875 | .byte_abs, | 1883 | .byte_abs, |
| 1876 | .token_abs, | 1884 | .token_abs, |
| 1877 | .node_abs, | 1885 | .node_abs, |
| ... | @@ -1902,6 +1910,8 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -1902,6 +1910,8 @@ pub const LazySrcLoc = union(enum) { |
| 1902 | .node_offset_switch_operand, | 1910 | .node_offset_switch_operand, |
| 1903 | .node_offset_switch_special_prong, | 1911 | .node_offset_switch_special_prong, |
| 1904 | .node_offset_switch_range, | 1912 | .node_offset_switch_range, |
| 1913 | .node_offset_fn_type_cc, | ||
| 1914 | .node_offset_fn_type_ret_ty, | ||
| 1905 | => .{ | 1915 | => .{ |
| 1906 | .container = .{ .decl = decl }, | 1916 | .container = .{ .decl = decl }, |
| 1907 | .lazy = lazy, | 1917 | .lazy = lazy, |
| ... | @@ -2340,13 +2350,18 @@ fn astgenAndSemaFn( | ... | @@ -2340,13 +2350,18 @@ fn astgenAndSemaFn( |
| 2340 | const fn_type_inst: zir.Inst.Ref = if (cc != .none) fn_type: { | 2350 | const fn_type_inst: zir.Inst.Ref = if (cc != .none) fn_type: { |
| 2341 | const tag: zir.Inst.Tag = if (is_var_args) .fn_type_cc_var_args else .fn_type_cc; | 2351 | const tag: zir.Inst.Tag = if (is_var_args) .fn_type_cc_var_args else .fn_type_cc; |
| 2342 | break :fn_type try fn_type_scope.addFnTypeCc(tag, .{ | 2352 | break :fn_type try fn_type_scope.addFnTypeCc(tag, .{ |
| 2353 | .src_node = fn_proto.ast.proto_node, | ||
| 2343 | .ret_ty = return_type_inst, | 2354 | .ret_ty = return_type_inst, |
| 2344 | .param_types = param_types, | 2355 | .param_types = param_types, |
| 2345 | .cc = cc, | 2356 | .cc = cc, |
| 2346 | }); | 2357 | }); |
| 2347 | } else fn_type: { | 2358 | } else fn_type: { |
| 2348 | const tag: zir.Inst.Tag = if (is_var_args) .fn_type_var_args else .fn_type; | 2359 | const tag: zir.Inst.Tag = if (is_var_args) .fn_type_var_args else .fn_type; |
| 2349 | break :fn_type try fn_type_scope.addFnType(tag, return_type_inst, param_types); | 2360 | break :fn_type try fn_type_scope.addFnType(tag, .{ |
| 2361 | .src_node = fn_proto.ast.proto_node, | ||
| 2362 | .ret_ty = return_type_inst, | ||
| 2363 | .param_types = param_types, | ||
| 2364 | }); | ||
| 2350 | }; | 2365 | }; |
| 2351 | _ = try fn_type_scope.addBreak(.break_inline, 0, fn_type_inst); | 2366 | _ = try fn_type_scope.addBreak(.break_inline, 0, fn_type_inst); |
| 2352 | 2367 |
src/Sema.zig+56-40| ... | @@ -148,7 +148,6 @@ pub fn analyzeBody( | ... | @@ -148,7 +148,6 @@ pub fn analyzeBody( |
| 148 | .bit_not => try sema.zirBitNot(block, inst), | 148 | .bit_not => try sema.zirBitNot(block, inst), |
| 149 | .bit_or => try sema.zirBitwise(block, inst, .bit_or), | 149 | .bit_or => try sema.zirBitwise(block, inst, .bit_or), |
| 150 | .bitcast => try sema.zirBitcast(block, inst), | 150 | .bitcast => try sema.zirBitcast(block, inst), |
| 151 | .bitcast_ref => try sema.zirBitcastRef(block, inst), | ||
| 152 | .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst), | 151 | .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst), |
| 153 | .block => try sema.zirBlock(block, inst), | 152 | .block => try sema.zirBlock(block, inst), |
| 154 | .bool_not => try sema.zirBoolNot(block, inst), | 153 | .bool_not => try sema.zirBoolNot(block, inst), |
| ... | @@ -498,12 +497,6 @@ fn zirConst(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!* | ... | @@ -498,12 +497,6 @@ fn zirConst(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!* |
| 498 | return sema.mod.constInst(sema.arena, .unneeded, typed_value_copy); | 497 | return sema.mod.constInst(sema.arena, .unneeded, typed_value_copy); |
| 499 | } | 498 | } |
| 500 | 499 | ||
| 501 | fn zirBitcastRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | ||
| 502 | const tracy = trace(@src()); | ||
| 503 | defer tracy.end(); | ||
| 504 | return sema.mod.fail(&block.base, sema.src, "TODO implement zir_sema.zirBitcastRef", .{}); | ||
| 505 | } | ||
| 506 | |||
| 507 | fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 500 | fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| 508 | const tracy = trace(@src()); | 501 | const tracy = trace(@src()); |
| 509 | defer tracy.end(); | 502 | defer tracy.end(); |
| ... | @@ -942,7 +935,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE | ... | @@ -942,7 +935,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE |
| 942 | try child_block.instructions.append(sema.gpa, &loop_inst.base); | 935 | try child_block.instructions.append(sema.gpa, &loop_inst.base); |
| 943 | loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, loop_block.instructions.items) }; | 936 | loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, loop_block.instructions.items) }; |
| 944 | 937 | ||
| 945 | return sema.analyzeBlockBody(parent_block, &child_block, merges); | 938 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 946 | } | 939 | } |
| 947 | 940 | ||
| 948 | fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 941 | fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| ... | @@ -992,12 +985,13 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inner | ... | @@ -992,12 +985,13 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inner |
| 992 | 985 | ||
| 993 | _ = try sema.analyzeBody(&child_block, body); | 986 | _ = try sema.analyzeBody(&child_block, body); |
| 994 | 987 | ||
| 995 | return sema.analyzeBlockBody(parent_block, &child_block, merges); | 988 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 996 | } | 989 | } |
| 997 | 990 | ||
| 998 | fn analyzeBlockBody( | 991 | fn analyzeBlockBody( |
| 999 | sema: *Sema, | 992 | sema: *Sema, |
| 1000 | parent_block: *Scope.Block, | 993 | parent_block: *Scope.Block, |
| 994 | src: LazySrcLoc, | ||
| 1001 | child_block: *Scope.Block, | 995 | child_block: *Scope.Block, |
| 1002 | merges: *Scope.Block.Merges, | 996 | merges: *Scope.Block.Merges, |
| 1003 | ) InnerError!*Inst { | 997 | ) InnerError!*Inst { |
| ... | @@ -1034,7 +1028,7 @@ fn analyzeBlockBody( | ... | @@ -1034,7 +1028,7 @@ fn analyzeBlockBody( |
| 1034 | // Need to set the type and emit the Block instruction. This allows machine code generation | 1028 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 1035 | // to emit a jump instruction to after the block when it encounters the break. | 1029 | // to emit a jump instruction to after the block when it encounters the break. |
| 1036 | try parent_block.instructions.append(sema.gpa, &merges.block_inst.base); | 1030 | try parent_block.instructions.append(sema.gpa, &merges.block_inst.base); |
| 1037 | const resolved_ty = try sema.resolvePeerTypes(parent_block, .todo, merges.results.items); | 1031 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items); |
| 1038 | merges.block_inst.base.ty = resolved_ty; | 1032 | merges.block_inst.base.ty = resolved_ty; |
| 1039 | merges.block_inst.body = .{ | 1033 | merges.block_inst.body = .{ |
| 1040 | .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items), | 1034 | .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items), |
| ... | @@ -1048,7 +1042,7 @@ fn analyzeBlockBody( | ... | @@ -1048,7 +1042,7 @@ fn analyzeBlockBody( |
| 1048 | } | 1042 | } |
| 1049 | var coerce_block = parent_block.makeSubBlock(); | 1043 | var coerce_block = parent_block.makeSubBlock(); |
| 1050 | defer coerce_block.instructions.deinit(sema.gpa); | 1044 | defer coerce_block.instructions.deinit(sema.gpa); |
| 1051 | const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, .todo); | 1045 | const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, br.operand.src); |
| 1052 | // If no instructions were produced, such as in the case of a coercion of a | 1046 | // If no instructions were produced, such as in the case of a coercion of a |
| 1053 | // constant value to a new type, we can simply point the br operand to it. | 1047 | // constant value to a new type, we can simply point the br operand to it. |
| 1054 | if (coerce_block.instructions.items.len == 0) { | 1048 | if (coerce_block.instructions.items.len == 0) { |
| ... | @@ -1334,7 +1328,7 @@ fn analyzeCall( | ... | @@ -1334,7 +1328,7 @@ fn analyzeCall( |
| 1334 | // the block_inst above. | 1328 | // the block_inst above. |
| 1335 | _ = try inline_sema.root(&child_block); | 1329 | _ = try inline_sema.root(&child_block); |
| 1336 | 1330 | ||
| 1337 | const result = try inline_sema.analyzeBlockBody(block, &child_block, merges); | 1331 | const result = try inline_sema.analyzeBlockBody(block, call_src, &child_block, merges); |
| 1338 | 1332 | ||
| 1339 | sema.branch_quota = inline_sema.branch_quota; | 1333 | sema.branch_quota = inline_sema.branch_quota; |
| 1340 | sema.branch_count = inline_sema.branch_count; | 1334 | sema.branch_count = inline_sema.branch_count; |
| ... | @@ -1845,15 +1839,16 @@ fn zirFnType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: b | ... | @@ -1845,15 +1839,16 @@ fn zirFnType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: b |
| 1845 | const tracy = trace(@src()); | 1839 | const tracy = trace(@src()); |
| 1846 | defer tracy.end(); | 1840 | defer tracy.end(); |
| 1847 | 1841 | ||
| 1848 | const inst_data = sema.code.instructions.items(.data)[inst].fn_type; | 1842 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1843 | const src = inst_data.src(); | ||
| 1849 | const extra = sema.code.extraData(zir.Inst.FnType, inst_data.payload_index); | 1844 | const extra = sema.code.extraData(zir.Inst.FnType, inst_data.payload_index); |
| 1850 | const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len); | 1845 | const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len); |
| 1851 | 1846 | ||
| 1852 | return sema.fnTypeCommon( | 1847 | return sema.fnTypeCommon( |
| 1853 | block, | 1848 | block, |
| 1854 | .unneeded, | 1849 | inst_data.src_node, |
| 1855 | param_types, | 1850 | param_types, |
| 1856 | inst_data.return_type, | 1851 | extra.data.return_type, |
| 1857 | .Unspecified, | 1852 | .Unspecified, |
| 1858 | var_args, | 1853 | var_args, |
| 1859 | ); | 1854 | ); |
| ... | @@ -1863,21 +1858,23 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: | ... | @@ -1863,21 +1858,23 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: |
| 1863 | const tracy = trace(@src()); | 1858 | const tracy = trace(@src()); |
| 1864 | defer tracy.end(); | 1859 | defer tracy.end(); |
| 1865 | 1860 | ||
| 1866 | const inst_data = sema.code.instructions.items(.data)[inst].fn_type; | 1861 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1862 | const src = inst_data.src(); | ||
| 1863 | const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node }; | ||
| 1867 | const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index); | 1864 | const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index); |
| 1868 | const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len); | 1865 | const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len); |
| 1869 | 1866 | ||
| 1870 | const cc_tv = try sema.resolveInstConst(block, .todo, extra.data.cc); | 1867 | const cc_tv = try sema.resolveInstConst(block, cc_src, extra.data.cc); |
| 1871 | // TODO once we're capable of importing and analyzing decls from | 1868 | // TODO once we're capable of importing and analyzing decls from |
| 1872 | // std.builtin, this needs to change | 1869 | // std.builtin, this needs to change |
| 1873 | const cc_str = cc_tv.val.castTag(.enum_literal).?.data; | 1870 | const cc_str = cc_tv.val.castTag(.enum_literal).?.data; |
| 1874 | const cc = std.meta.stringToEnum(std.builtin.CallingConvention, cc_str) orelse | 1871 | const cc = std.meta.stringToEnum(std.builtin.CallingConvention, cc_str) orelse |
| 1875 | return sema.mod.fail(&block.base, .todo, "Unknown calling convention {s}", .{cc_str}); | 1872 | return sema.mod.fail(&block.base, cc_src, "Unknown calling convention {s}", .{cc_str}); |
| 1876 | return sema.fnTypeCommon( | 1873 | return sema.fnTypeCommon( |
| 1877 | block, | 1874 | block, |
| 1878 | .unneeded, | 1875 | inst_data.src_node, |
| 1879 | param_types, | 1876 | param_types, |
| 1880 | inst_data.return_type, | 1877 | extra.data.return_type, |
| 1881 | cc, | 1878 | cc, |
| 1882 | var_args, | 1879 | var_args, |
| 1883 | ); | 1880 | ); |
| ... | @@ -1886,13 +1883,15 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: | ... | @@ -1886,13 +1883,15 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: |
| 1886 | fn fnTypeCommon( | 1883 | fn fnTypeCommon( |
| 1887 | sema: *Sema, | 1884 | sema: *Sema, |
| 1888 | block: *Scope.Block, | 1885 | block: *Scope.Block, |
| 1889 | src: LazySrcLoc, | 1886 | src_node_offset: i32, |
| 1890 | zir_param_types: []const zir.Inst.Ref, | 1887 | zir_param_types: []const zir.Inst.Ref, |
| 1891 | zir_return_type: zir.Inst.Ref, | 1888 | zir_return_type: zir.Inst.Ref, |
| 1892 | cc: std.builtin.CallingConvention, | 1889 | cc: std.builtin.CallingConvention, |
| 1893 | var_args: bool, | 1890 | var_args: bool, |
| 1894 | ) InnerError!*Inst { | 1891 | ) InnerError!*Inst { |
| 1895 | const return_type = try sema.resolveType(block, src, zir_return_type); | 1892 | const src: LazySrcLoc = .{ .node_offset = src_node_offset }; |
| 1893 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset }; | ||
| 1894 | const return_type = try sema.resolveType(block, ret_ty_src, zir_return_type); | ||
| 1896 | 1895 | ||
| 1897 | // Hot path for some common function types. | 1896 | // Hot path for some common function types. |
| 1898 | if (zir_param_types.len == 0 and !var_args) { | 1897 | if (zir_param_types.len == 0 and !var_args) { |
| ... | @@ -1915,12 +1914,11 @@ fn fnTypeCommon( | ... | @@ -1915,12 +1914,11 @@ fn fnTypeCommon( |
| 1915 | 1914 | ||
| 1916 | const param_types = try sema.arena.alloc(Type, zir_param_types.len); | 1915 | const param_types = try sema.arena.alloc(Type, zir_param_types.len); |
| 1917 | for (zir_param_types) |param_type, i| { | 1916 | for (zir_param_types) |param_type, i| { |
| 1918 | const resolved = try sema.resolveType(block, src, param_type); | 1917 | // TODO make a compile error from `resolveType` report the source location |
| 1919 | // TODO skip for comptime params | 1918 | // of the specific parameter. Will need to take a similar strategy as |
| 1920 | if (!resolved.isValidVarType(false)) { | 1919 | // `resolveSwitchItemVal` to avoid resolving the source location unless |
| 1921 | return sema.mod.fail(&block.base, .todo, "parameter of type '{}' must be declared comptime", .{resolved}); | 1920 | // we actually need to report an error. |
| 1922 | } | 1921 | param_types[i] = try sema.resolveType(block, src, param_type); |
| 1923 | param_types[i] = resolved; | ||
| 1924 | } | 1922 | } |
| 1925 | 1923 | ||
| 1926 | const fn_ty = try Type.Tag.function.create(sema.arena, .{ | 1924 | const fn_ty = try Type.Tag.function.create(sema.arena, .{ |
| ... | @@ -2082,9 +2080,14 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError | ... | @@ -2082,9 +2080,14 @@ fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError |
| 2082 | const tracy = trace(@src()); | 2080 | const tracy = trace(@src()); |
| 2083 | defer tracy.end(); | 2081 | defer tracy.end(); |
| 2084 | 2082 | ||
| 2085 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 2083 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2086 | const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs); | 2084 | const src = inst_data.src(); |
| 2087 | const operand = try sema.resolveInst(bin_inst.rhs); | 2085 | const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 2086 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | ||
| 2087 | const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data; | ||
| 2088 | |||
| 2089 | const dest_type = try sema.resolveType(block, dest_ty_src, extra.lhs); | ||
| 2090 | const operand = try sema.resolveInst(extra.rhs); | ||
| 2088 | return sema.bitcast(block, dest_type, operand); | 2091 | return sema.bitcast(block, dest_type, operand); |
| 2089 | } | 2092 | } |
| 2090 | 2093 | ||
| ... | @@ -2234,7 +2237,12 @@ fn zirSwitchCapture( | ... | @@ -2234,7 +2237,12 @@ fn zirSwitchCapture( |
| 2234 | const tracy = trace(@src()); | 2237 | const tracy = trace(@src()); |
| 2235 | defer tracy.end(); | 2238 | defer tracy.end(); |
| 2236 | 2239 | ||
| 2237 | @panic("TODO implement Sema for zirSwitchCapture"); | 2240 | const zir_datas = sema.code.instructions.items(.data); |
| 2241 | const capture_info = zir_datas[inst].switch_capture; | ||
| 2242 | const switch_info = zir_datas[capture_info.switch_inst].pl_node; | ||
| 2243 | const src = switch_info.src(); | ||
| 2244 | |||
| 2245 | return sema.mod.fail(&block.base, src, "TODO implement Sema for zirSwitchCapture", .{}); | ||
| 2238 | } | 2246 | } |
| 2239 | 2247 | ||
| 2240 | fn zirSwitchCaptureElse( | 2248 | fn zirSwitchCaptureElse( |
| ... | @@ -2246,7 +2254,12 @@ fn zirSwitchCaptureElse( | ... | @@ -2246,7 +2254,12 @@ fn zirSwitchCaptureElse( |
| 2246 | const tracy = trace(@src()); | 2254 | const tracy = trace(@src()); |
| 2247 | defer tracy.end(); | 2255 | defer tracy.end(); |
| 2248 | 2256 | ||
| 2249 | @panic("TODO implement Sema for zirSwitchCaptureElse"); | 2257 | const zir_datas = sema.code.instructions.items(.data); |
| 2258 | const capture_info = zir_datas[inst].switch_capture; | ||
| 2259 | const switch_info = zir_datas[capture_info.switch_inst].pl_node; | ||
| 2260 | const src = switch_info.src(); | ||
| 2261 | |||
| 2262 | return sema.mod.fail(&block.base, src, "TODO implement Sema for zirSwitchCaptureElse", .{}); | ||
| 2250 | } | 2263 | } |
| 2251 | 2264 | ||
| 2252 | fn zirSwitchBlock( | 2265 | fn zirSwitchBlock( |
| ... | @@ -2631,8 +2644,9 @@ fn analyzeSwitch( | ... | @@ -2631,8 +2644,9 @@ fn analyzeSwitch( |
| 2631 | const body = sema.code.extra[extra_index..][0..body_len]; | 2644 | const body = sema.code.extra[extra_index..][0..body_len]; |
| 2632 | extra_index += body_len; | 2645 | extra_index += body_len; |
| 2633 | 2646 | ||
| 2634 | const item = try sema.resolveInst(item_ref); | 2647 | // Validation above ensured these will succeed. |
| 2635 | const item_val = try sema.resolveConstValue(block, item.src, item); | 2648 | const item = sema.resolveInst(item_ref) catch unreachable; |
| 2649 | const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable; | ||
| 2636 | if (operand_val.eql(item_val)) { | 2650 | if (operand_val.eql(item_val)) { |
| 2637 | return sema.resolveBody(block, body); | 2651 | return sema.resolveBody(block, body); |
| 2638 | } | 2652 | } |
| ... | @@ -2652,8 +2666,9 @@ fn analyzeSwitch( | ... | @@ -2652,8 +2666,9 @@ fn analyzeSwitch( |
| 2652 | const body = sema.code.extra[extra_index + 2 * ranges_len ..][0..body_len]; | 2666 | const body = sema.code.extra[extra_index + 2 * ranges_len ..][0..body_len]; |
| 2653 | 2667 | ||
| 2654 | for (items) |item_ref| { | 2668 | for (items) |item_ref| { |
| 2655 | const item = try sema.resolveInst(item_ref); | 2669 | // Validation above ensured these will succeed. |
| 2656 | const item_val = try sema.resolveConstValue(block, item.src, item); | 2670 | const item = sema.resolveInst(item_ref) catch unreachable; |
| 2671 | const item_val = sema.resolveConstValue(block, item.src, item) catch unreachable; | ||
| 2657 | if (operand_val.eql(item_val)) { | 2672 | if (operand_val.eql(item_val)) { |
| 2658 | return sema.resolveBody(block, body); | 2673 | return sema.resolveBody(block, body); |
| 2659 | } | 2674 | } |
| ... | @@ -2666,8 +2681,9 @@ fn analyzeSwitch( | ... | @@ -2666,8 +2681,9 @@ fn analyzeSwitch( |
| 2666 | const item_last = @intToEnum(zir.Inst.Ref, sema.code.extra[extra_index]); | 2681 | const item_last = @intToEnum(zir.Inst.Ref, sema.code.extra[extra_index]); |
| 2667 | extra_index += 1; | 2682 | extra_index += 1; |
| 2668 | 2683 | ||
| 2669 | const first_tv = try sema.resolveInstConst(block, .todo, item_first); | 2684 | // Validation above ensured these will succeed. |
| 2670 | const last_tv = try sema.resolveInstConst(block, .todo, item_last); | 2685 | const first_tv = sema.resolveInstConst(block, .unneeded, item_first) catch unreachable; |
| 2686 | const last_tv = sema.resolveInstConst(block, .unneeded, item_last) catch unreachable; | ||
| 2671 | if (Value.compare(operand_val, .gte, first_tv.val) and | 2687 | if (Value.compare(operand_val, .gte, first_tv.val) and |
| 2672 | Value.compare(operand_val, .lte, last_tv.val)) | 2688 | Value.compare(operand_val, .lte, last_tv.val)) |
| 2673 | { | 2689 | { |
| ... | @@ -2876,7 +2892,7 @@ fn analyzeSwitch( | ... | @@ -2876,7 +2892,7 @@ fn analyzeSwitch( |
| 2876 | }; | 2892 | }; |
| 2877 | 2893 | ||
| 2878 | _ = try child_block.addSwitchBr(src, operand, cases, final_else_body); | 2894 | _ = try child_block.addSwitchBr(src, operand, cases, final_else_body); |
| 2879 | return sema.analyzeBlockBody(block, &child_block, merges); | 2895 | return sema.analyzeBlockBody(block, src, &child_block, merges); |
| 2880 | } | 2896 | } |
| 2881 | 2897 | ||
| 2882 | fn resolveSwitchItemVal( | 2898 | fn resolveSwitchItemVal( |
src/main.zig+2-2| ... | @@ -1487,7 +1487,7 @@ fn buildOutputType( | ... | @@ -1487,7 +1487,7 @@ fn buildOutputType( |
| 1487 | for (diags.arch.?.allCpuModels()) |cpu| { | 1487 | for (diags.arch.?.allCpuModels()) |cpu| { |
| 1488 | help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help; | 1488 | help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help; |
| 1489 | } | 1489 | } |
| 1490 | std.log.info("Available CPUs for architecture '{s}': {s}", .{ | 1490 | std.log.info("Available CPUs for architecture '{s}':\n{s}", .{ |
| 1491 | @tagName(diags.arch.?), help_text.items, | 1491 | @tagName(diags.arch.?), help_text.items, |
| 1492 | }); | 1492 | }); |
| 1493 | } | 1493 | } |
| ... | @@ -1499,7 +1499,7 @@ fn buildOutputType( | ... | @@ -1499,7 +1499,7 @@ fn buildOutputType( |
| 1499 | for (diags.arch.?.allFeaturesList()) |feature| { | 1499 | for (diags.arch.?.allFeaturesList()) |feature| { |
| 1500 | help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help; | 1500 | help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help; |
| 1501 | } | 1501 | } |
| 1502 | std.log.info("Available CPU features for architecture '{s}': {s}", .{ | 1502 | std.log.info("Available CPU features for architecture '{s}':\n{s}", .{ |
| 1503 | @tagName(diags.arch.?), help_text.items, | 1503 | @tagName(diags.arch.?), help_text.items, |
| 1504 | }); | 1504 | }); |
| 1505 | } | 1505 | } |
src/zir.zig+29-34| ... | @@ -168,15 +168,12 @@ pub const Inst = struct { | ... | @@ -168,15 +168,12 @@ pub const Inst = struct { |
| 168 | asm_volatile, | 168 | asm_volatile, |
| 169 | /// Bitwise AND. `&` | 169 | /// Bitwise AND. `&` |
| 170 | bit_and, | 170 | bit_and, |
| 171 | /// TODO delete this instruction, it has no purpose. | 171 | /// Bitcast a value to a different type. |
| 172 | /// Uses the pl_node field with payload `Bin`. | ||
| 172 | bitcast, | 173 | bitcast, |
| 173 | /// An arbitrary typed pointer is pointer-casted to a new Pointer. | ||
| 174 | /// The destination type is given by LHS. The cast is to be evaluated | ||
| 175 | /// as if it were a bit-cast operation from the operand pointer element type to the | ||
| 176 | /// provided destination type. | ||
| 177 | bitcast_ref, | ||
| 178 | /// A typed result location pointer is bitcasted to a new result location pointer. | 174 | /// A typed result location pointer is bitcasted to a new result location pointer. |
| 179 | /// The new result location pointer has an inferred type. | 175 | /// The new result location pointer has an inferred type. |
| 176 | /// Uses the un_node field. | ||
| 180 | bitcast_result_ptr, | 177 | bitcast_result_ptr, |
| 181 | /// Bitwise NOT. `~` | 178 | /// Bitwise NOT. `~` |
| 182 | /// Uses `un_node`. | 179 | /// Uses `un_node`. |
| ... | @@ -338,12 +335,12 @@ pub const Inst = struct { | ... | @@ -338,12 +335,12 @@ pub const Inst = struct { |
| 338 | /// Payload is `Bin` with lhs as the dest type, rhs the operand. | 335 | /// Payload is `Bin` with lhs as the dest type, rhs the operand. |
| 339 | floatcast, | 336 | floatcast, |
| 340 | /// Returns a function type, assuming unspecified calling convention. | 337 | /// Returns a function type, assuming unspecified calling convention. |
| 341 | /// Uses the `fn_type` union field. `payload_index` points to a `FnType`. | 338 | /// Uses the `pl_node` union field. `payload_index` points to a `FnType`. |
| 342 | fn_type, | 339 | fn_type, |
| 343 | /// Same as `fn_type` but the function is variadic. | 340 | /// Same as `fn_type` but the function is variadic. |
| 344 | fn_type_var_args, | 341 | fn_type_var_args, |
| 345 | /// Returns a function type, with a calling convention instruction operand. | 342 | /// Returns a function type, with a calling convention instruction operand. |
| 346 | /// Uses the `fn_type` union field. `payload_index` points to a `FnTypeCc`. | 343 | /// Uses the `pl_node` union field. `payload_index` points to a `FnTypeCc`. |
| 347 | fn_type_cc, | 344 | fn_type_cc, |
| 348 | /// Same as `fn_type_cc` but the function is variadic. | 345 | /// Same as `fn_type_cc` but the function is variadic. |
| 349 | fn_type_cc_var_args, | 346 | fn_type_cc_var_args, |
| ... | @@ -662,7 +659,6 @@ pub const Inst = struct { | ... | @@ -662,7 +659,6 @@ pub const Inst = struct { |
| 662 | .asm_volatile, | 659 | .asm_volatile, |
| 663 | .bit_and, | 660 | .bit_and, |
| 664 | .bitcast, | 661 | .bitcast, |
| 665 | .bitcast_ref, | ||
| 666 | .bitcast_result_ptr, | 662 | .bitcast_result_ptr, |
| 667 | .bit_or, | 663 | .bit_or, |
| 668 | .block, | 664 | .block, |
| ... | @@ -1212,12 +1208,6 @@ pub const Inst = struct { | ... | @@ -1212,12 +1208,6 @@ pub const Inst = struct { |
| 1212 | /// Index into extra. See `PtrType`. | 1208 | /// Index into extra. See `PtrType`. |
| 1213 | payload_index: u32, | 1209 | payload_index: u32, |
| 1214 | }, | 1210 | }, |
| 1215 | fn_type: struct { | ||
| 1216 | return_type: Ref, | ||
| 1217 | /// For `fn_type` this points to a `FnType` in `extra`. | ||
| 1218 | /// For `fn_type_cc` this points to `FnTypeCc` in `extra`. | ||
| 1219 | payload_index: u32, | ||
| 1220 | }, | ||
| 1221 | int_type: struct { | 1211 | int_type: struct { |
| 1222 | /// Offset from Decl AST node index. | 1212 | /// Offset from Decl AST node index. |
| 1223 | /// `Tag` determines which kind of AST node this points to. | 1213 | /// `Tag` determines which kind of AST node this points to. |
| ... | @@ -1289,6 +1279,7 @@ pub const Inst = struct { | ... | @@ -1289,6 +1279,7 @@ pub const Inst = struct { |
| 1289 | /// according to `param_types_len`. | 1279 | /// according to `param_types_len`. |
| 1290 | /// Each param type is a `Ref`. | 1280 | /// Each param type is a `Ref`. |
| 1291 | pub const FnTypeCc = struct { | 1281 | pub const FnTypeCc = struct { |
| 1282 | return_type: Ref, | ||
| 1292 | cc: Ref, | 1283 | cc: Ref, |
| 1293 | param_types_len: u32, | 1284 | param_types_len: u32, |
| 1294 | }; | 1285 | }; |
| ... | @@ -1297,6 +1288,7 @@ pub const Inst = struct { | ... | @@ -1297,6 +1288,7 @@ pub const Inst = struct { |
| 1297 | /// according to `param_types_len`. | 1288 | /// according to `param_types_len`. |
| 1298 | /// Each param type is a `Ref`. | 1289 | /// Each param type is a `Ref`. |
| 1299 | pub const FnType = struct { | 1290 | pub const FnType = struct { |
| 1291 | return_type: Ref, | ||
| 1300 | param_types_len: u32, | 1292 | param_types_len: u32, |
| 1301 | }; | 1293 | }; |
| 1302 | 1294 | ||
| ... | @@ -1640,7 +1632,6 @@ const Writer = struct { | ... | @@ -1640,7 +1632,6 @@ const Writer = struct { |
| 1640 | => try self.writeSwitchCapture(stream, inst), | 1632 | => try self.writeSwitchCapture(stream, inst), |
| 1641 | 1633 | ||
| 1642 | .bitcast, | 1634 | .bitcast, |
| 1643 | .bitcast_ref, | ||
| 1644 | .bitcast_result_ptr, | 1635 | .bitcast_result_ptr, |
| 1645 | .store_to_inferred_ptr, | 1636 | .store_to_inferred_ptr, |
| 1646 | => try stream.writeAll("TODO)"), | 1637 | => try stream.writeAll("TODO)"), |
| ... | @@ -2044,11 +2035,26 @@ const Writer = struct { | ... | @@ -2044,11 +2035,26 @@ const Writer = struct { |
| 2044 | stream: anytype, | 2035 | stream: anytype, |
| 2045 | inst: Inst.Index, | 2036 | inst: Inst.Index, |
| 2046 | var_args: bool, | 2037 | var_args: bool, |
| 2047 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | 2038 | ) !void { |
| 2048 | const inst_data = self.code.instructions.items(.data)[inst].fn_type; | 2039 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 2040 | const src = inst_data.src(); | ||
| 2049 | const extra = self.code.extraData(Inst.FnType, inst_data.payload_index); | 2041 | const extra = self.code.extraData(Inst.FnType, inst_data.payload_index); |
| 2050 | const param_types = self.code.refSlice(extra.end, extra.data.param_types_len); | 2042 | const param_types = self.code.refSlice(extra.end, extra.data.param_types_len); |
| 2051 | return self.writeFnTypeCommon(stream, param_types, inst_data.return_type, var_args, .none); | 2043 | return self.writeFnTypeCommon(stream, param_types, extra.data.return_type, var_args, .none, src); |
| 2044 | } | ||
| 2045 | |||
| 2046 | fn writeFnTypeCc( | ||
| 2047 | self: *Writer, | ||
| 2048 | stream: anytype, | ||
| 2049 | inst: Inst.Index, | ||
| 2050 | var_args: bool, | ||
| 2051 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | ||
| 2052 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 2053 | const src = inst_data.src(); | ||
| 2054 | const extra = self.code.extraData(Inst.FnTypeCc, inst_data.payload_index); | ||
| 2055 | const param_types = self.code.refSlice(extra.end, extra.data.param_types_len); | ||
| 2056 | const cc = extra.data.cc; | ||
| 2057 | return self.writeFnTypeCommon(stream, param_types, extra.data.return_type, var_args, cc, src); | ||
| 2052 | } | 2058 | } |
| 2053 | 2059 | ||
| 2054 | fn writeBoolBr(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 2060 | fn writeBoolBr(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| ... | @@ -2064,19 +2070,6 @@ const Writer = struct { | ... | @@ -2064,19 +2070,6 @@ const Writer = struct { |
| 2064 | try stream.writeAll("})"); | 2070 | try stream.writeAll("})"); |
| 2065 | } | 2071 | } |
| 2066 | 2072 | ||
| 2067 | fn writeFnTypeCc( | ||
| 2068 | self: *Writer, | ||
| 2069 | stream: anytype, | ||
| 2070 | inst: Inst.Index, | ||
| 2071 | var_args: bool, | ||
| 2072 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | ||
| 2073 | const inst_data = self.code.instructions.items(.data)[inst].fn_type; | ||
| 2074 | const extra = self.code.extraData(Inst.FnTypeCc, inst_data.payload_index); | ||
| 2075 | const param_types = self.code.refSlice(extra.end, extra.data.param_types_len); | ||
| 2076 | const cc = extra.data.cc; | ||
| 2077 | return self.writeFnTypeCommon(stream, param_types, inst_data.return_type, var_args, cc); | ||
| 2078 | } | ||
| 2079 | |||
| 2080 | fn writeIntType(self: *Writer, stream: anytype, inst: Inst.Index) !void { | 2073 | fn writeIntType(self: *Writer, stream: anytype, inst: Inst.Index) !void { |
| 2081 | const int_type = self.code.instructions.items(.data)[inst].int_type; | 2074 | const int_type = self.code.instructions.items(.data)[inst].int_type; |
| 2082 | const prefix: u8 = switch (int_type.signedness) { | 2075 | const prefix: u8 = switch (int_type.signedness) { |
| ... | @@ -2110,7 +2103,8 @@ const Writer = struct { | ... | @@ -2110,7 +2103,8 @@ const Writer = struct { |
| 2110 | ret_ty: Inst.Ref, | 2103 | ret_ty: Inst.Ref, |
| 2111 | var_args: bool, | 2104 | var_args: bool, |
| 2112 | cc: Inst.Ref, | 2105 | cc: Inst.Ref, |
| 2113 | ) (@TypeOf(stream).Error || error{OutOfMemory})!void { | 2106 | src: LazySrcLoc, |
| 2107 | ) !void { | ||
| 2114 | try stream.writeAll("["); | 2108 | try stream.writeAll("["); |
| 2115 | for (param_types) |param_type, i| { | 2109 | for (param_types) |param_type, i| { |
| 2116 | if (i != 0) try stream.writeAll(", "); | 2110 | if (i != 0) try stream.writeAll(", "); |
| ... | @@ -2120,7 +2114,8 @@ const Writer = struct { | ... | @@ -2120,7 +2114,8 @@ const Writer = struct { |
| 2120 | try self.writeInstRef(stream, ret_ty); | 2114 | try self.writeInstRef(stream, ret_ty); |
| 2121 | try self.writeOptionalInstRef(stream, ", cc=", cc); | 2115 | try self.writeOptionalInstRef(stream, ", cc=", cc); |
| 2122 | try self.writeFlag(stream, ", var_args", var_args); | 2116 | try self.writeFlag(stream, ", var_args", var_args); |
| 2123 | try stream.writeAll(")"); | 2117 | try stream.writeAll(") "); |
| 2118 | try self.writeSrc(stream, src); | ||
| 2124 | } | 2119 | } |
| 2125 | 2120 | ||
| 2126 | fn writeSmallStr( | 2121 | fn writeSmallStr( |