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 @@
11this is my WIP branch scratch pad, to be deleted before merging into master
22
33Merge TODO list:
4 * remove the LazySrcLoc.todo tag
5 * update astgen.zig
6 * finish updating Sema.zig
74 * finish implementing SrcLoc byteOffset function
85 * audit all the .unneeded src locations
96 * 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 {
12521252 buffer[0] = data.lhs;
12531253 const params = if (data.lhs == 0) buffer[0..0] else buffer[0..1];
12541254 return tree.fullFnProto(.{
1255 .proto_node = node,
12551256 .fn_token = tree.nodes.items(.main_token)[node],
12561257 .return_type = data.rhs,
12571258 .params = params,
......@@ -1267,6 +1268,7 @@ pub const Tree = struct {
12671268 const params_range = tree.extraData(data.lhs, Node.SubRange);
12681269 const params = tree.extra_data[params_range.start..params_range.end];
12691270 return tree.fullFnProto(.{
1271 .proto_node = node,
12701272 .fn_token = tree.nodes.items(.main_token)[node],
12711273 .return_type = data.rhs,
12721274 .params = params,
......@@ -1283,6 +1285,7 @@ pub const Tree = struct {
12831285 buffer[0] = extra.param;
12841286 const params = if (extra.param == 0) buffer[0..0] else buffer[0..1];
12851287 return tree.fullFnProto(.{
1288 .proto_node = node,
12861289 .fn_token = tree.nodes.items(.main_token)[node],
12871290 .return_type = data.rhs,
12881291 .params = params,
......@@ -1298,6 +1301,7 @@ pub const Tree = struct {
12981301 const extra = tree.extraData(data.lhs, Node.FnProto);
12991302 const params = tree.extra_data[extra.params_start..extra.params_end];
13001303 return tree.fullFnProto(.{
1304 .proto_node = node,
13011305 .fn_token = tree.nodes.items(.main_token)[node],
13021306 .return_type = data.rhs,
13031307 .params = params,
......@@ -2120,6 +2124,7 @@ pub const full = struct {
21202124 ast: Ast,
21212125
21222126 pub const Ast = struct {
2127 proto_node: Node.Index,
21232128 fn_token: TokenIndex,
21242129 return_type: Node.Index,
21252130 params: []const Node.Index,
src/AstGen.zig+24-53
......@@ -133,10 +133,6 @@ pub const ResultLoc = union(enum) {
133133 /// The result instruction from the expression must be ignored.
134134 /// Always an instruction with tag `alloc_inferred`.
135135 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,
140136 /// There is a pointer for the expression to store its result into, however, its type
141137 /// is inferred based on peer type resolution for a `zir.Inst.Block`.
142138 /// The result instruction from the expression must be ignored.
......@@ -172,7 +168,7 @@ pub const ResultLoc = union(enum) {
172168 .tag = .break_void,
173169 .elide_store_to_block_ptr_instructions = false,
174170 },
175 .inferred_ptr, .bitcasted_ptr, .block_ptr => {
171 .inferred_ptr, .block_ptr => {
176172 if (block_scope.rvalue_rl_count == block_scope.break_count) {
177173 // Neither prong of the if consumed the result location, so we can
178174 // use break instructions to create an rvalue.
......@@ -388,7 +384,7 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!zir.Ins
388384}
389385
390386/// 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
392388/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
393389/// it must otherwise not be used.
394390pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
......@@ -1155,7 +1151,6 @@ fn blockExprStmts(
11551151 .asm_volatile,
11561152 .bit_and,
11571153 .bitcast,
1158 .bitcast_ref,
11591154 .bitcast_result_ptr,
11601155 .bit_or,
11611156 .block,
......@@ -1804,7 +1799,7 @@ fn orelseCatchExpr(
18041799 // TODO handle catch
18051800 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
18061801 .ref => .ref,
1807 .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => .none,
1802 .discard, .none, .block_ptr, .inferred_ptr => .none,
18081803 .ty => |elem_ty| blk: {
18091804 const wrapped_ty = try block_scope.addUnNode(.optional_type, elem_ty, node);
18101805 break :blk .{ .ty = wrapped_ty };
......@@ -3519,7 +3514,6 @@ fn as(
35193514 gz: *GenZir,
35203515 scope: *Scope,
35213516 rl: ResultLoc,
3522 builtin_token: ast.TokenIndex,
35233517 node: ast.Node.Index,
35243518 lhs: ast.Node.Index,
35253519 rhs: ast.Node.Index,
......@@ -3538,13 +3532,9 @@ fn as(
35383532 return asRlPtr(gz, scope, rl, block_scope.rl_ptr, rhs, dest_type);
35393533 },
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 },
35453535 .inferred_ptr => |result_alloc| {
35463536 // 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", .{});
35483538 },
35493539 }
35503540}
......@@ -3599,47 +3589,32 @@ fn bitCast(
35993589 gz: *GenZir,
36003590 scope: *Scope,
36013591 rl: ResultLoc,
3602 builtin_token: ast.TokenIndex,
36033592 node: ast.Node.Index,
36043593 lhs: ast.Node.Index,
36053594 rhs: ast.Node.Index,
36063595) InnerError!zir.Inst.Ref {
3607 if (true) @panic("TODO update for zir-memory-layout");
3596 const mod = gz.astgen.mod;
36083597 const dest_type = try typeExpr(gz, scope, lhs);
36093598 switch (rl) {
3610 .none => {
3599 .none, .discard, .ty => {
36113600 const operand = try expr(gz, scope, .none, rhs);
3612 return addZIRBinOp(mod, scope, src, .bitcast, dest_type, operand);
3613 },
3614 .discard => {
3615 const operand = try expr(gz, scope, .none, rhs);
3616 const result = try addZIRBinOp(mod, scope, src, .bitcast, dest_type, operand);
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);
3601 const result = try gz.addPlNode(.bitcast, node, zir.Inst.Bin{
3602 .lhs = dest_type,
3603 .rhs = operand,
3604 });
3605 return rvalue(gz, scope, rl, result, node);
36293606 },
3607 .ref => unreachable, // `@bitCast` is not allowed as an r-value.
36303608 .ptr => |result_ptr| {
3631 const casted_result_ptr = try addZIRUnOp(mod, scope, src, .bitcast_result_ptr, result_ptr);
3632 return expr(gz, scope, .{ .bitcasted_ptr = casted_result_ptr.castTag(.bitcast_result_ptr).? }, rhs);
3633 },
3634 .bitcasted_ptr => |bitcasted_ptr| {
3635 return mod.failTok(scope, builtin_token, "TODO implement @bitCast with result location another @bitCast", .{});
3609 const casted_result_ptr = try gz.addUnNode(.bitcast_result_ptr, result_ptr, node);
3610 return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs);
36363611 },
36373612 .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", .{});
36393614 },
36403615 .inferred_ptr => |result_alloc| {
36413616 // 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", .{});
36433618 },
36443619 }
36453620}
......@@ -3648,12 +3623,11 @@ fn typeOf(
36483623 gz: *GenZir,
36493624 scope: *Scope,
36503625 rl: ResultLoc,
3651 builtin_token: ast.TokenIndex,
36523626 node: ast.Node.Index,
36533627 params: []const ast.Node.Index,
36543628) InnerError!zir.Inst.Ref {
36553629 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", .{});
36573631 }
36583632 if (params.len == 1) {
36593633 const result = try gz.addUnNode(.typeof, try expr(gz, scope, .none, params[0]), node);
......@@ -3693,14 +3667,14 @@ fn builtinCall(
36933667 // Also, some builtins have a variable number of parameters.
36943668
36953669 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}'", .{
36973671 builtin_name,
36983672 });
36993673 };
37003674 if (info.param_count) |expected| {
37013675 if (expected != params.len) {
37023676 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}", .{
37043678 expected, s, params.len,
37053679 });
37063680 }
......@@ -3788,9 +3762,9 @@ fn builtinCall(
37883762 });
37893763 return rvalue(gz, scope, rl, result, node);
37903764 },
3791 .as => return as(gz, scope, rl, builtin_token, node, params[0], params[1]),
3792 .bit_cast => return bitCast(gz, scope, rl, builtin_token, node, params[0], params[1]),
3793 .TypeOf => return typeOf(gz, scope, rl, builtin_token, node, params),
3765 .as => return as(gz, scope, rl, node, params[0], params[1]),
3766 .bit_cast => return bitCast(gz, scope, rl, node, params[0], params[1]),
3767 .TypeOf => return typeOf(gz, scope, rl, node, params),
37943768
37953769 .add_with_overflow,
37963770 .align_cast,
......@@ -3875,7 +3849,7 @@ fn builtinCall(
38753849 .type_info,
38763850 .type_name,
38773851 .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}", .{
38793853 builtin_name,
38803854 }),
38813855
......@@ -3884,7 +3858,7 @@ fn builtinCall(
38843858 .Frame,
38853859 .frame_address,
38863860 .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", .{}),
38883862 }
38893863}
38903864
......@@ -4286,9 +4260,6 @@ fn rvalue(
42864260 });
42874261 return result;
42884262 },
4289 .bitcasted_ptr => |bitcasted_ptr| {
4290 return gz.astgen.mod.failNode(scope, src_node, "TODO implement rvalue .bitcasted_ptr", .{});
4291 },
42924263 .inferred_ptr => |alloc| {
42934264 _ = try gz.addBin(.store_to_inferred_ptr, alloc, result);
42944265 return result;
src/Module.zig+42-27
......@@ -1016,11 +1016,6 @@ pub const Scope = struct {
10161016 gz.break_result_loc = .{ .block_ptr = gz };
10171017 },
10181018
1019 .bitcasted_ptr => |ptr| {
1020 gz.rl_ptr = ptr;
1021 gz.break_result_loc = .{ .block_ptr = gz };
1022 },
1023
10241019 .block_ptr => |parent_block_scope| {
10251020 gz.rl_ty_inst = parent_block_scope.rl_ty_inst;
10261021 gz.rl_ptr = parent_block_scope.rl_ptr;
......@@ -1052,10 +1047,12 @@ pub const Scope = struct {
10521047 }
10531048
10541049 pub fn addFnTypeCc(gz: *GenZir, tag: zir.Inst.Tag, args: struct {
1050 src_node: ast.Node.Index,
10551051 param_types: []const zir.Inst.Ref,
10561052 ret_ty: zir.Inst.Ref,
10571053 cc: zir.Inst.Ref,
10581054 }) !zir.Inst.Ref {
1055 assert(args.src_node != 0);
10591056 assert(args.ret_ty != .none);
10601057 assert(args.cc != .none);
10611058 const gpa = gz.astgen.mod.gpa;
......@@ -1065,6 +1062,7 @@ pub const Scope = struct {
10651062 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);
10661063
10671064 const payload_index = gz.astgen.addExtraAssumeCapacity(zir.Inst.FnTypeCc{
1065 .return_type = args.ret_ty,
10681066 .cc = args.cc,
10691067 .param_types_len = @intCast(u32, args.param_types.len),
10701068 });
......@@ -1073,8 +1071,8 @@ pub const Scope = struct {
10731071 const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len);
10741072 gz.astgen.instructions.appendAssumeCapacity(.{
10751073 .tag = tag,
1076 .data = .{ .fn_type = .{
1077 .return_type = args.ret_ty,
1074 .data = .{ .pl_node = .{
1075 .src_node = gz.astgen.decl.nodeIndexToRelative(args.src_node),
10781076 .payload_index = payload_index,
10791077 } },
10801078 });
......@@ -1082,29 +1080,30 @@ pub const Scope = struct {
10821080 return gz.astgen.indexToRef(new_index);
10831081 }
10841082
1085 pub fn addFnType(
1086 gz: *GenZir,
1087 tag: zir.Inst.Tag,
1083 pub fn addFnType(gz: *GenZir, tag: zir.Inst.Tag, args: struct {
1084 src_node: ast.Node.Index,
10881085 ret_ty: zir.Inst.Ref,
10891086 param_types: []const zir.Inst.Ref,
1090 ) !zir.Inst.Ref {
1091 assert(ret_ty != .none);
1087 }) !zir.Inst.Ref {
1088 assert(args.src_node != 0);
1089 assert(args.ret_ty != .none);
10921090 const gpa = gz.astgen.mod.gpa;
10931091 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
10941092 try gz.astgen.instructions.ensureCapacity(gpa, gz.astgen.instructions.len + 1);
10951093 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
10981096 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),
11001099 });
1101 gz.astgen.appendRefsAssumeCapacity(param_types);
1100 gz.astgen.appendRefsAssumeCapacity(args.param_types);
11021101
11031102 const new_index = @intCast(zir.Inst.Index, gz.astgen.instructions.len);
11041103 gz.astgen.instructions.appendAssumeCapacity(.{
11051104 .tag = tag,
1106 .data = .{ .fn_type = .{
1107 .return_type = ret_ty,
1105 .data = .{ .pl_node = .{
1106 .src_node = gz.astgen.decl.nodeIndexToRelative(args.src_node),
11081107 .payload_index = payload_index,
11091108 } },
11101109 });
......@@ -1513,7 +1512,6 @@ pub const SrcLoc = struct {
15131512 pub fn fileScope(src_loc: SrcLoc) *Scope.File {
15141513 return switch (src_loc.lazy) {
15151514 .unneeded => unreachable,
1516 .todo => unreachable,
15171515
15181516 .byte_abs,
15191517 .token_abs,
......@@ -1542,6 +1540,8 @@ pub const SrcLoc = struct {
15421540 .node_offset_switch_operand,
15431541 .node_offset_switch_special_prong,
15441542 .node_offset_switch_range,
1543 .node_offset_fn_type_cc,
1544 .node_offset_fn_type_ret_ty,
15451545 => src_loc.container.decl.container.file_scope,
15461546 };
15471547 }
......@@ -1549,7 +1549,6 @@ pub const SrcLoc = struct {
15491549 pub fn byteOffset(src_loc: SrcLoc) !u32 {
15501550 switch (src_loc.lazy) {
15511551 .unneeded => unreachable,
1552 .todo => unreachable,
15531552
15541553 .byte_abs => |byte_index| return byte_index,
15551554
......@@ -1676,6 +1675,8 @@ pub const SrcLoc = struct {
16761675 .node_offset_switch_operand => @panic("TODO"),
16771676 .node_offset_switch_special_prong => @panic("TODO"),
16781677 .node_offset_switch_range => @panic("TODO"),
1678 .node_offset_fn_type_cc => @panic("TODO"),
1679 .node_offset_fn_type_ret_ty => @panic("TODO"),
16791680 }
16801681 }
16811682};
......@@ -1695,11 +1696,6 @@ pub const LazySrcLoc = union(enum) {
16951696 /// look into using reverse-continue with a memory watchpoint to see where the
16961697 /// value is being set to this tag.
16971698 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,
17031699 /// The source location points to a byte offset within a source file,
17041700 /// offset from 0. The source file is determined contextually.
17051701 /// Inside a `SrcLoc`, the `file_scope` union field will be active.
......@@ -1824,12 +1820,23 @@ pub const LazySrcLoc = union(enum) {
18241820 /// range nodes. The error applies to all of them.
18251821 /// The Decl is determined contextually.
18261822 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
18281836 /// Upgrade to a `SrcLoc` based on the `Decl` or file in the provided scope.
18291837 pub fn toSrcLoc(lazy: LazySrcLoc, scope: *Scope) SrcLoc {
18301838 return switch (lazy) {
18311839 .unneeded,
1832 .todo,
18331840 .byte_abs,
18341841 .token_abs,
18351842 .node_abs,
......@@ -1860,6 +1867,8 @@ pub const LazySrcLoc = union(enum) {
18601867 .node_offset_switch_operand,
18611868 .node_offset_switch_special_prong,
18621869 .node_offset_switch_range,
1870 .node_offset_fn_type_cc,
1871 .node_offset_fn_type_ret_ty,
18631872 => .{
18641873 .container = .{ .decl = scope.srcDecl().? },
18651874 .lazy = lazy,
......@@ -1871,7 +1880,6 @@ pub const LazySrcLoc = union(enum) {
18711880 pub fn toSrcLocWithDecl(lazy: LazySrcLoc, decl: *Decl) SrcLoc {
18721881 return switch (lazy) {
18731882 .unneeded,
1874 .todo,
18751883 .byte_abs,
18761884 .token_abs,
18771885 .node_abs,
......@@ -1902,6 +1910,8 @@ pub const LazySrcLoc = union(enum) {
19021910 .node_offset_switch_operand,
19031911 .node_offset_switch_special_prong,
19041912 .node_offset_switch_range,
1913 .node_offset_fn_type_cc,
1914 .node_offset_fn_type_ret_ty,
19051915 => .{
19061916 .container = .{ .decl = decl },
19071917 .lazy = lazy,
......@@ -2340,13 +2350,18 @@ fn astgenAndSemaFn(
23402350 const fn_type_inst: zir.Inst.Ref = if (cc != .none) fn_type: {
23412351 const tag: zir.Inst.Tag = if (is_var_args) .fn_type_cc_var_args else .fn_type_cc;
23422352 break :fn_type try fn_type_scope.addFnTypeCc(tag, .{
2353 .src_node = fn_proto.ast.proto_node,
23432354 .ret_ty = return_type_inst,
23442355 .param_types = param_types,
23452356 .cc = cc,
23462357 });
23472358 } else fn_type: {
23482359 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 });
23502365 };
23512366 _ = try fn_type_scope.addBreak(.break_inline, 0, fn_type_inst);
23522367
src/Sema.zig+56-40
......@@ -148,7 +148,6 @@ pub fn analyzeBody(
148148 .bit_not => try sema.zirBitNot(block, inst),
149149 .bit_or => try sema.zirBitwise(block, inst, .bit_or),
150150 .bitcast => try sema.zirBitcast(block, inst),
151 .bitcast_ref => try sema.zirBitcastRef(block, inst),
152151 .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst),
153152 .block => try sema.zirBlock(block, inst),
154153 .bool_not => try sema.zirBoolNot(block, inst),
......@@ -498,12 +497,6 @@ fn zirConst(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*
498497 return sema.mod.constInst(sema.arena, .unneeded, typed_value_copy);
499498}
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
507500fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
508501 const tracy = trace(@src());
509502 defer tracy.end();
......@@ -942,7 +935,7 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE
942935 try child_block.instructions.append(sema.gpa, &loop_inst.base);
943936 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);
946939}
947940
948941fn 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
992985
993986 _ = 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);
996989}
997990
998991fn analyzeBlockBody(
999992 sema: *Sema,
1000993 parent_block: *Scope.Block,
994 src: LazySrcLoc,
1001995 child_block: *Scope.Block,
1002996 merges: *Scope.Block.Merges,
1003997) InnerError!*Inst {
......@@ -1034,7 +1028,7 @@ fn analyzeBlockBody(
10341028 // Need to set the type and emit the Block instruction. This allows machine code generation
10351029 // to emit a jump instruction to after the block when it encounters the break.
10361030 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);
10381032 merges.block_inst.base.ty = resolved_ty;
10391033 merges.block_inst.body = .{
10401034 .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items),
......@@ -1048,7 +1042,7 @@ fn analyzeBlockBody(
10481042 }
10491043 var coerce_block = parent_block.makeSubBlock();
10501044 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);
10521046 // If no instructions were produced, such as in the case of a coercion of a
10531047 // constant value to a new type, we can simply point the br operand to it.
10541048 if (coerce_block.instructions.items.len == 0) {
......@@ -1334,7 +1328,7 @@ fn analyzeCall(
13341328 // the block_inst above.
13351329 _ = 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
13391333 sema.branch_quota = inline_sema.branch_quota;
13401334 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
18451839 const tracy = trace(@src());
18461840 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();
18491844 const extra = sema.code.extraData(zir.Inst.FnType, inst_data.payload_index);
18501845 const param_types = sema.code.refSlice(extra.end, extra.data.param_types_len);
18511846
18521847 return sema.fnTypeCommon(
18531848 block,
1854 .unneeded,
1849 inst_data.src_node,
18551850 param_types,
1856 inst_data.return_type,
1851 extra.data.return_type,
18571852 .Unspecified,
18581853 var_args,
18591854 );
......@@ -1863,21 +1858,23 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args:
18631858 const tracy = trace(@src());
18641859 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 };
18671864 const extra = sema.code.extraData(zir.Inst.FnTypeCc, inst_data.payload_index);
18681865 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);
18711868 // TODO once we're capable of importing and analyzing decls from
18721869 // std.builtin, this needs to change
18731870 const cc_str = cc_tv.val.castTag(.enum_literal).?.data;
18741871 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});
18761873 return sema.fnTypeCommon(
18771874 block,
1878 .unneeded,
1875 inst_data.src_node,
18791876 param_types,
1880 inst_data.return_type,
1877 extra.data.return_type,
18811878 cc,
18821879 var_args,
18831880 );
......@@ -1886,13 +1883,15 @@ fn zirFnTypeCc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args:
18861883fn fnTypeCommon(
18871884 sema: *Sema,
18881885 block: *Scope.Block,
1889 src: LazySrcLoc,
1886 src_node_offset: i32,
18901887 zir_param_types: []const zir.Inst.Ref,
18911888 zir_return_type: zir.Inst.Ref,
18921889 cc: std.builtin.CallingConvention,
18931890 var_args: bool,
18941891) 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
18971896 // Hot path for some common function types.
18981897 if (zir_param_types.len == 0 and !var_args) {
......@@ -1915,12 +1914,11 @@ fn fnTypeCommon(
19151914
19161915 const param_types = try sema.arena.alloc(Type, zir_param_types.len);
19171916 for (zir_param_types) |param_type, i| {
1918 const resolved = try sema.resolveType(block, src, param_type);
1919 // TODO skip for comptime params
1920 if (!resolved.isValidVarType(false)) {
1921 return sema.mod.fail(&block.base, .todo, "parameter of type '{}' must be declared comptime", .{resolved});
1922 }
1923 param_types[i] = resolved;
1917 // TODO make a compile error from `resolveType` report the source location
1918 // of the specific parameter. Will need to take a similar strategy as
1919 // `resolveSwitchItemVal` to avoid resolving the source location unless
1920 // we actually need to report an error.
1921 param_types[i] = try sema.resolveType(block, src, param_type);
19241922 }
19251923
19261924 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
20822080 const tracy = trace(@src());
20832081 defer tracy.end();
20842082
2085 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2086 const dest_type = try sema.resolveType(block, .todo, bin_inst.lhs);
2087 const operand = try sema.resolveInst(bin_inst.rhs);
2083 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2084 const src = inst_data.src();
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);
20882091 return sema.bitcast(block, dest_type, operand);
20892092}
20902093
......@@ -2234,7 +2237,12 @@ fn zirSwitchCapture(
22342237 const tracy = trace(@src());
22352238 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", .{});
22382246}
22392247
22402248fn zirSwitchCaptureElse(
......@@ -2246,7 +2254,12 @@ fn zirSwitchCaptureElse(
22462254 const tracy = trace(@src());
22472255 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", .{});
22502263}
22512264
22522265fn zirSwitchBlock(
......@@ -2631,8 +2644,9 @@ fn analyzeSwitch(
26312644 const body = sema.code.extra[extra_index..][0..body_len];
26322645 extra_index += body_len;
26332646
2634 const item = try sema.resolveInst(item_ref);
2635 const item_val = try sema.resolveConstValue(block, item.src, item);
2647 // Validation above ensured these will succeed.
2648 const item = sema.resolveInst(item_ref) catch unreachable;
2649 const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable;
26362650 if (operand_val.eql(item_val)) {
26372651 return sema.resolveBody(block, body);
26382652 }
......@@ -2652,8 +2666,9 @@ fn analyzeSwitch(
26522666 const body = sema.code.extra[extra_index + 2 * ranges_len ..][0..body_len];
26532667
26542668 for (items) |item_ref| {
2655 const item = try sema.resolveInst(item_ref);
2656 const item_val = try sema.resolveConstValue(block, item.src, item);
2669 // Validation above ensured these will succeed.
2670 const item = sema.resolveInst(item_ref) catch unreachable;
2671 const item_val = sema.resolveConstValue(block, item.src, item) catch unreachable;
26572672 if (operand_val.eql(item_val)) {
26582673 return sema.resolveBody(block, body);
26592674 }
......@@ -2666,8 +2681,9 @@ fn analyzeSwitch(
26662681 const item_last = @intToEnum(zir.Inst.Ref, sema.code.extra[extra_index]);
26672682 extra_index += 1;
26682683
2669 const first_tv = try sema.resolveInstConst(block, .todo, item_first);
2670 const last_tv = try sema.resolveInstConst(block, .todo, item_last);
2684 // Validation above ensured these will succeed.
2685 const first_tv = sema.resolveInstConst(block, .unneeded, item_first) catch unreachable;
2686 const last_tv = sema.resolveInstConst(block, .unneeded, item_last) catch unreachable;
26712687 if (Value.compare(operand_val, .gte, first_tv.val) and
26722688 Value.compare(operand_val, .lte, last_tv.val))
26732689 {
......@@ -2876,7 +2892,7 @@ fn analyzeSwitch(
28762892 };
28772893
28782894 _ = 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);
28802896}
28812897
28822898fn resolveSwitchItemVal(
src/main.zig+2-2
......@@ -1487,7 +1487,7 @@ fn buildOutputType(
14871487 for (diags.arch.?.allCpuModels()) |cpu| {
14881488 help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help;
14891489 }
1490 std.log.info("Available CPUs for architecture '{s}': {s}", .{
1490 std.log.info("Available CPUs for architecture '{s}':\n{s}", .{
14911491 @tagName(diags.arch.?), help_text.items,
14921492 });
14931493 }
......@@ -1499,7 +1499,7 @@ fn buildOutputType(
14991499 for (diags.arch.?.allFeaturesList()) |feature| {
15001500 help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help;
15011501 }
1502 std.log.info("Available CPU features for architecture '{s}': {s}", .{
1502 std.log.info("Available CPU features for architecture '{s}':\n{s}", .{
15031503 @tagName(diags.arch.?), help_text.items,
15041504 });
15051505 }
src/zir.zig+29-34
......@@ -168,15 +168,12 @@ pub const Inst = struct {
168168 asm_volatile,
169169 /// Bitwise AND. `&`
170170 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`.
172173 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,
178174 /// A typed result location pointer is bitcasted to a new result location pointer.
179175 /// The new result location pointer has an inferred type.
176 /// Uses the un_node field.
180177 bitcast_result_ptr,
181178 /// Bitwise NOT. `~`
182179 /// Uses `un_node`.
......@@ -338,12 +335,12 @@ pub const Inst = struct {
338335 /// Payload is `Bin` with lhs as the dest type, rhs the operand.
339336 floatcast,
340337 /// 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`.
342339 fn_type,
343340 /// Same as `fn_type` but the function is variadic.
344341 fn_type_var_args,
345342 /// 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`.
347344 fn_type_cc,
348345 /// Same as `fn_type_cc` but the function is variadic.
349346 fn_type_cc_var_args,
......@@ -662,7 +659,6 @@ pub const Inst = struct {
662659 .asm_volatile,
663660 .bit_and,
664661 .bitcast,
665 .bitcast_ref,
666662 .bitcast_result_ptr,
667663 .bit_or,
668664 .block,
......@@ -1212,12 +1208,6 @@ pub const Inst = struct {
12121208 /// Index into extra. See `PtrType`.
12131209 payload_index: u32,
12141210 },
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 },
12211211 int_type: struct {
12221212 /// Offset from Decl AST node index.
12231213 /// `Tag` determines which kind of AST node this points to.
......@@ -1289,6 +1279,7 @@ pub const Inst = struct {
12891279 /// according to `param_types_len`.
12901280 /// Each param type is a `Ref`.
12911281 pub const FnTypeCc = struct {
1282 return_type: Ref,
12921283 cc: Ref,
12931284 param_types_len: u32,
12941285 };
......@@ -1297,6 +1288,7 @@ pub const Inst = struct {
12971288 /// according to `param_types_len`.
12981289 /// Each param type is a `Ref`.
12991290 pub const FnType = struct {
1291 return_type: Ref,
13001292 param_types_len: u32,
13011293 };
13021294
......@@ -1640,7 +1632,6 @@ const Writer = struct {
16401632 => try self.writeSwitchCapture(stream, inst),
16411633
16421634 .bitcast,
1643 .bitcast_ref,
16441635 .bitcast_result_ptr,
16451636 .store_to_inferred_ptr,
16461637 => try stream.writeAll("TODO)"),
......@@ -2044,11 +2035,26 @@ const Writer = struct {
20442035 stream: anytype,
20452036 inst: Inst.Index,
20462037 var_args: bool,
2047 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
2048 const inst_data = self.code.instructions.items(.data)[inst].fn_type;
2038 ) !void {
2039 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
2040 const src = inst_data.src();
20492041 const extra = self.code.extraData(Inst.FnType, inst_data.payload_index);
20502042 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);
20522058 }
20532059
20542060 fn writeBoolBr(self: *Writer, stream: anytype, inst: Inst.Index) !void {
......@@ -2064,19 +2070,6 @@ const Writer = struct {
20642070 try stream.writeAll("})");
20652071 }
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
20802073 fn writeIntType(self: *Writer, stream: anytype, inst: Inst.Index) !void {
20812074 const int_type = self.code.instructions.items(.data)[inst].int_type;
20822075 const prefix: u8 = switch (int_type.signedness) {
......@@ -2110,7 +2103,8 @@ const Writer = struct {
21102103 ret_ty: Inst.Ref,
21112104 var_args: bool,
21122105 cc: Inst.Ref,
2113 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
2106 src: LazySrcLoc,
2107 ) !void {
21142108 try stream.writeAll("[");
21152109 for (param_types) |param_type, i| {
21162110 if (i != 0) try stream.writeAll(", ");
......@@ -2120,7 +2114,8 @@ const Writer = struct {
21202114 try self.writeInstRef(stream, ret_ty);
21212115 try self.writeOptionalInstRef(stream, ", cc=", cc);
21222116 try self.writeFlag(stream, ", var_args", var_args);
2123 try stream.writeAll(")");
2117 try stream.writeAll(") ");
2118 try self.writeSrc(stream, src);
21242119 }
21252120
21262121 fn writeSmallStr(