authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-31 21:36:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-31 21:36:32-07:00
logb27d0526768a5be715eeb9381a61d335e9a05e9e
treea94afd7f10280876250778528490137b74a0e920
parente8143f6cbe3d1bdaeda5cd5af13447f6639b80ad

stage2: finish source location reworkings in the branch

* 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 @@
1this is my WIP branch scratch pad, to be deleted before merging into master1this is my WIP branch scratch pad, to be deleted before merging into master
22
3Merge TODO list:3Merge TODO list:
4 * remove the LazySrcLoc.todo tag
5 * update astgen.zig
6 * finish updating Sema.zig
7 * finish implementing SrcLoc byteOffset function4 * finish implementing SrcLoc byteOffset function
8 * audit all the .unneeded src locations5 * audit all the .unneeded src locations
9 * audit the calls in codegen toSrcLocWithDecl specifically if there is inlined function6 * 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,
21212125
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 type136 /// 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 can173 // 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}
389385
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, the387/// 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.
394pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {390pub 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 catch1799 // 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 },
35403534
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.
36943668
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),
37943768
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 }),
38813855
...@@ -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}
38903864
...@@ -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 },
10181018
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 }
10531048
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);
10661063
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 }
10841082
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);
10971095
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);
11021101
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,
15171515
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,
15531552
1554 .byte_abs => |byte_index| return byte_index,1553 .byte_abs => |byte_index| return byte_index,
15551554
...@@ -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 the1696 /// 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,
18271835
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);
23522367
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}
500499
501fn 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
507fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {500fn 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) };
944937
945 return sema.analyzeBlockBody(parent_block, &child_block, merges);938 return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
946}939}
947940
948fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {941fn 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
992985
993 _ = try sema.analyzeBody(&child_block, body);986 _ = try sema.analyzeBody(&child_block, body);
994987
995 return sema.analyzeBlockBody(parent_block, &child_block, merges);988 return sema.analyzeBlockBody(parent_block, src, &child_block, merges);
996}989}
997990
998fn analyzeBlockBody(991fn 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 generation1028 // 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 a1046 // 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);
13361330
1337 const result = try inline_sema.analyzeBlockBody(block, &child_block, merges);1331 const result = try inline_sema.analyzeBlockBody(block, call_src, &child_block, merges);
13381332
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();
18471841
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);
18511846
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();
18651860
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);
18691866
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 from1868 // TODO once we're capable of importing and analyzing decls from
1872 // std.builtin, this needs to change1869 // 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) orelse1871 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:
1886fn fnTypeCommon(1883fn 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);
18961895
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(
19151914
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 params1918 // 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 }
19251923
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();
20842082
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}
20902093
...@@ -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();
22362239
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}
22392247
2240fn zirSwitchCaptureElse(2248fn 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();
22482256
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}
22512264
2252fn zirSwitchBlock(2265fn 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;
26332646
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];
26532667
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;
26682683
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) and2687 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 };
28772893
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}
28812897
2882fn resolveSwitchItemVal(2898fn 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 };
13021294
...@@ -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),
16411633
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 }
20532059
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 }
20662072
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 }
21252120
2126 fn writeSmallStr(2121 fn writeSmallStr(