authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-18 22:19:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-03-18 22:19:28-07:00
logb2682237dbe90306b569cb36914f8823cd7b0431
tree9f35683ad3d3a2b254de6c2041734d37d8385be2
parentf5aca4a6a1ba867d3bc343a3740454468a7eff13

stage2: get Module and Sema compiling again

There are some `@panic("TODO")` in there but I'm trying to get the branch to the point where collaborators can jump in. Next is to repair the seam between LazySrcLoc and codegen's expected absolute file offsets.

9 files changed, 524 insertions(+), 599 deletions(-)

BRANCH_TODO+2
......@@ -27,6 +27,8 @@ Performance optimizations to look into:
2727 and have it reference source code bytes. Another idea: null terminated
2828 string variants which avoid having to store the length.
2929 - Look into this for enum literals too
30 * make ret_type and ret_ptr instructions be implied indexes; no need to have
31 tags associated with them.
3032
3133
3234Random snippets of code that I deleted and need to make sure get
src/Module.zig+131-98
......@@ -462,11 +462,11 @@ pub const Scope = struct {
462462 switch (scope.tag) {
463463 .file => return &scope.cast(File).?.tree,
464464 .block => return &scope.cast(Block).?.src_decl.container.file_scope.tree,
465 .gen_zir => return &scope.cast(GenZir).?.decl.container.file_scope.tree,
465 .gen_zir => return &scope.cast(GenZir).?.zir_code.decl.container.file_scope.tree,
466466 .local_val => return &scope.cast(LocalVal).?.gen_zir.zir_code.decl.container.file_scope.tree,
467467 .local_ptr => return &scope.cast(LocalPtr).?.gen_zir.zir_code.decl.container.file_scope.tree,
468468 .container => return &scope.cast(Container).?.file_scope.tree,
469 .gen_suspend => return &scope.cast(GenZir).?.decl.container.file_scope.tree,
469 .gen_suspend => return &scope.cast(GenZir).?.zir_code.decl.container.file_scope.tree,
470470 .gen_nosuspend => return &scope.cast(Nosuspend).?.gen_zir.zir_code.decl.container.file_scope.tree,
471471 .decl_ref => return &scope.cast(DeclRef).?.decl.container.file_scope.tree,
472472 }
......@@ -968,18 +968,42 @@ pub const Scope = struct {
968968 used: bool = false,
969969 };
970970
971 /// Only valid to call on the top of the `GenZir` stack. Completes the
972 /// `WipZirCode` into a `zir.Code`. Leaves the `WipZirCode` in an
973 /// initialized, but empty, state.
974 pub fn finish(gz: *GenZir) !zir.Code {
975 const gpa = gz.zir_code.gpa;
976 const root_start = @intCast(u32, gz.zir_code.extra.items.len);
977 const root_len = @intCast(u32, gz.instructions.items.len);
978 try gz.zir_code.extra.appendSlice(gpa, gz.instructions.items);
979 return zir.Code{
980 .instructions = gz.zir_code.instructions.toOwnedSlice(),
981 .string_bytes = gz.zir_code.string_bytes.toOwnedSlice(gpa),
982 .extra = gz.zir_code.extra.toOwnedSlice(gpa),
983 .root_start = root_start,
984 .root_len = root_len,
985 };
986 }
987
988 pub fn tokSrcLoc(gz: *GenZir, token_index: ast.TokenIndex) LazySrcLoc {
989 const decl_token = gz.zir_code.decl.srcToken();
990 return .{ .token_offset = token_index - decl_token };
991 }
992
971993 pub fn addFnTypeCc(gz: *GenZir, args: struct {
972994 param_types: []const zir.Inst.Ref,
973995 ret_ty: zir.Inst.Ref,
974996 cc: zir.Inst.Ref,
975997 }) !zir.Inst.Index {
998 assert(args.ret_ty != 0);
999 assert(args.cc != 0);
9761000 const gpa = gz.zir_code.gpa;
9771001 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
9781002 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
979 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
1003 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
9801004 @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len);
9811005
982 const payload_index = gz.addExtra(zir.Inst.FnTypeCc, .{
1006 const payload_index = gz.zir_code.addExtra(zir.Inst.FnTypeCc{
9831007 .cc = args.cc,
9841008 .param_types_len = @intCast(u32, args.param_types.len),
9851009 }) catch unreachable; // Capacity is ensured above.
......@@ -989,7 +1013,7 @@ pub const Scope = struct {
9891013 gz.zir_code.instructions.appendAssumeCapacity(.{
9901014 .tag = .fn_type_cc,
9911015 .data = .{ .fn_type = .{
992 .return_type = ret_ty,
1016 .return_type = args.ret_ty,
9931017 .payload_index = payload_index,
9941018 } },
9951019 });
......@@ -1003,13 +1027,14 @@ pub const Scope = struct {
10031027 ret_ty: zir.Inst.Ref,
10041028 param_types: []const zir.Inst.Ref,
10051029 ) !zir.Inst.Index {
1030 assert(ret_ty != 0);
10061031 const gpa = gz.zir_code.gpa;
10071032 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
10081033 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1009 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.len +
1034 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
10101035 @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len);
10111036
1012 const payload_index = gz.addExtra(zir.Inst.FnTypeCc, .{
1037 const payload_index = gz.zir_code.addExtra(zir.Inst.FnType{
10131038 .param_types_len = @intCast(u32, param_types.len),
10141039 }) catch unreachable; // Capacity is ensured above.
10151040 gz.zir_code.extra.appendSliceAssumeCapacity(param_types);
......@@ -1027,42 +1052,11 @@ pub const Scope = struct {
10271052 return result;
10281053 }
10291054
1030 pub fn addRetTok(
1031 gz: *GenZir,
1032 operand: zir.Inst.Ref,
1033 /// Absolute token index. This function does the conversion to Decl offset.
1034 abs_tok_index: ast.TokenIndex,
1035 ) !zir.Inst.Index {
1036 const gpa = gz.zir_code.gpa;
1037 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1038 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1039
1040 const new_index = gz.zir_code.instructions.len;
1041 gz.zir_code.instructions.appendAssumeCapacity(.{
1042 .tag = .ret_tok,
1043 .data = .{ .fn_type = .{
1044 .operand = operand,
1045 .src_tok = abs_tok_index - gz.zir_code.decl.srcToken(),
1046 } },
1047 });
1048 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1049 gz.instructions.appendAssumeCapacity(result);
1050 return result;
1051 }
1052
10531055 pub fn addInt(gz: *GenZir, integer: u64) !zir.Inst.Index {
1054 const gpa = gz.zir_code.gpa;
1055 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1056 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1057
1058 const new_index = gz.zir_code.instructions.len;
1059 gz.zir_code.instructions.appendAssumeCapacity(.{
1056 return gz.add(.{
10601057 .tag = .int,
10611058 .data = .{ .int = integer },
10621059 });
1063 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1064 gz.instructions.appendAssumeCapacity(result);
1065 return result;
10661060 }
10671061
10681062 pub fn addUnNode(
......@@ -1072,21 +1066,14 @@ pub const Scope = struct {
10721066 /// Absolute node index. This function does the conversion to offset from Decl.
10731067 abs_node_index: ast.Node.Index,
10741068 ) !zir.Inst.Ref {
1075 const gpa = gz.zir_code.gpa;
1076 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1077 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1078
1079 const new_index = gz.zir_code.instructions.len;
1080 gz.zir_code.instructions.appendAssumeCapacity(.{
1069 assert(operand != 0);
1070 return gz.add(.{
10811071 .tag = tag,
10821072 .data = .{ .un_node = .{
10831073 .operand = operand,
10841074 .src_node = abs_node_index - gz.zir_code.decl.srcNode(),
10851075 } },
10861076 });
1087 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1088 gz.instructions.appendAssumeCapacity(result);
1089 return result;
10901077 }
10911078
10921079 pub fn addUnTok(
......@@ -1096,21 +1083,14 @@ pub const Scope = struct {
10961083 /// Absolute token index. This function does the conversion to Decl offset.
10971084 abs_tok_index: ast.TokenIndex,
10981085 ) !zir.Inst.Ref {
1099 const gpa = gz.zir_code.gpa;
1100 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1101 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1102
1103 const new_index = gz.zir_code.instructions.len;
1104 gz.zir_code.instructions.appendAssumeCapacity(.{
1086 assert(operand != 0);
1087 return gz.add(.{
11051088 .tag = tag,
11061089 .data = .{ .un_tok = .{
11071090 .operand = operand,
11081091 .src_tok = abs_tok_index - gz.zir_code.decl.srcToken(),
11091092 } },
11101093 });
1111 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
1112 gz.instructions.appendAssumeCapacity(result);
1113 return result;
11141094 }
11151095
11161096 pub fn addBin(
......@@ -1119,18 +1099,52 @@ pub const Scope = struct {
11191099 lhs: zir.Inst.Ref,
11201100 rhs: zir.Inst.Ref,
11211101 ) !zir.Inst.Ref {
1122 const gpa = gz.zir_code.gpa;
1123 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1124 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1125
1126 const new_index = gz.zir_code.instructions.len;
1127 gz.zir_code.instructions.appendAssumeCapacity(.{
1102 assert(lhs != 0);
1103 assert(rhs != 0);
1104 return gz.add(.{
11281105 .tag = tag,
11291106 .data = .{ .bin = .{
11301107 .lhs = lhs,
11311108 .rhs = rhs,
11321109 } },
11331110 });
1111 }
1112
1113 pub fn addNode(
1114 gz: *GenZir,
1115 tag: zir.Inst.Tag,
1116 /// Absolute node index. This function does the conversion to offset from Decl.
1117 abs_node_index: ast.Node.Index,
1118 ) !zir.Inst.Ref {
1119 return gz.add(.{
1120 .tag = tag,
1121 .data = .{ .node = abs_node_index - gz.zir_code.decl.srcNode() },
1122 });
1123 }
1124
1125 /// Asserts that `str` is 8 or fewer bytes.
1126 pub fn addSmallStr(
1127 gz: *GenZir,
1128 tag: zir.Inst.Tag,
1129 str: []const u8,
1130 ) !zir.Inst.Ref {
1131 var buf: [9]u8 = undefined;
1132 mem.copy(u8, &buf, str);
1133 buf[str.len] = 0;
1134
1135 return gz.add(.{
1136 .tag = tag,
1137 .data = .{ .small_str = .{ .bytes = buf[0..8].* } },
1138 });
1139 }
1140
1141 fn add(gz: *GenZir, inst: zir.Inst) !zir.Inst.Ref {
1142 const gpa = gz.zir_code.gpa;
1143 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1144 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1145
1146 const new_index = gz.zir_code.instructions.len;
1147 gz.zir_code.instructions.appendAssumeCapacity(inst);
11341148 const result = @intCast(zir.Inst.Ref, new_index + gz.zir_code.ref_start_index);
11351149 gz.instructions.appendAssumeCapacity(result);
11361150 return result;
......@@ -1183,6 +1197,7 @@ pub const Scope = struct {
11831197/// A Work-In-Progress `zir.Code`. This is a shared parent of all
11841198/// `GenZir` scopes. Once the `zir.Code` is produced, this struct
11851199/// is deinitialized.
1200/// The `GenZir.finish` function converts this to a `zir.Code`.
11861201pub const WipZirCode = struct {
11871202 instructions: std.MultiArrayList(zir.Inst) = .{},
11881203 string_bytes: std.ArrayListUnmanaged(u8) = .{},
......@@ -1194,9 +1209,20 @@ pub const WipZirCode = struct {
11941209 gpa: *Allocator,
11951210 arena: *Allocator,
11961211
1197 fn deinit(wip_zir_code: *WipZirCode) void {
1198 wip_zir_code.instructions.deinit(wip_zir_code.gpa);
1199 wip_zir_code.extra.deinit(wip_zir_code.gpa);
1212 pub fn addExtra(wzc: *WipZirCode, extra: anytype) Allocator.Error!u32 {
1213 const fields = std.meta.fields(@TypeOf(extra));
1214 try wzc.extra.ensureCapacity(wzc.gpa, wzc.extra.items.len + fields.len);
1215 const result = @intCast(u32, wzc.extra.items.len);
1216 inline for (fields) |field| {
1217 comptime assert(field.field_type == u32);
1218 wzc.extra.appendAssumeCapacity(@field(extra, field.name));
1219 }
1220 return result;
1221 }
1222
1223 pub fn deinit(wzc: *WipZirCode) void {
1224 wzc.instructions.deinit(wzc.gpa);
1225 wzc.extra.deinit(wzc.gpa);
12001226 }
12011227};
12021228
......@@ -1763,18 +1789,22 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
17631789 .gpa = mod.gpa,
17641790 };
17651791 defer wip_zir_code.deinit();
1792
17661793 var gen_scope: Scope.GenZir = .{
17671794 .force_comptime = true,
17681795 .parent = &decl.container.base,
17691796 .zir_code = &wip_zir_code,
17701797 };
1798 defer gen_scope.instructions.deinit(mod.gpa);
17711799
17721800 const block_expr = node_datas[decl_node].lhs;
17731801 _ = try astgen.comptimeExpr(mod, &gen_scope.base, .none, block_expr);
1802
1803 const code = try gen_scope.finish();
17741804 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1775 zir.dumpZir(mod.gpa, "comptime_block", decl.name, gen_scope.instructions.items) catch {};
1805 zir.dumpZir(mod.gpa, "comptime_block", decl.name, code) catch {};
17761806 }
1777 break :blk wip_zir_code.finish();
1807 break :blk code;
17781808 };
17791809
17801810 var sema: Sema = .{
......@@ -1836,11 +1866,13 @@ fn astgenAndSemaFn(
18361866 .gpa = mod.gpa,
18371867 };
18381868 defer fn_type_wip_zir_exec.deinit();
1869
18391870 var fn_type_scope: Scope.GenZir = .{
18401871 .force_comptime = true,
18411872 .parent = &decl.container.base,
18421873 .zir_code = &fn_type_wip_zir_exec,
18431874 };
1875 defer fn_type_scope.instructions.deinit(mod.gpa);
18441876
18451877 decl.is_pub = fn_proto.visib_token != null;
18461878
......@@ -1855,7 +1887,7 @@ fn astgenAndSemaFn(
18551887 }
18561888 break :blk count;
18571889 };
1858 const param_types = try fn_type_scope_arena.allocator.alloc(zir.Inst.Index, param_count);
1890 const param_types = try fn_type_scope_arena.allocator.alloc(zir.Inst.Ref, param_count);
18591891 const type_type_rl: astgen.ResultLoc = .{ .ty = @enumToInt(zir.Const.type_type) };
18601892
18611893 var is_var_args = false;
......@@ -1970,11 +2002,11 @@ fn astgenAndSemaFn(
19702002 .ty = @enumToInt(zir.Const.enum_literal_type),
19712003 }, fn_proto.ast.callconv_expr)
19722004 else if (is_extern) // note: https://github.com/ziglang/zig/issues/5269
1973 try fn_type_scope.addStrBytes(.enum_literal, "C")
2005 try fn_type_scope.addSmallStr(.enum_literal_small, "C")
19742006 else
19752007 0;
19762008
1977 const fn_type_inst: zir.Inst.Index = if (cc != 0) fn_type: {
2009 const fn_type_inst: zir.Inst.Ref = if (cc != 0) fn_type: {
19782010 const tag: zir.Inst.Tag = if (is_var_args) .fn_type_cc_var_args else .fn_type_cc;
19792011 break :fn_type try fn_type_scope.addFnTypeCc(.{
19802012 .ret_ty = return_type_inst,
......@@ -1983,22 +2015,19 @@ fn astgenAndSemaFn(
19832015 });
19842016 } else fn_type: {
19852017 const tag: zir.Inst.Tag = if (is_var_args) .fn_type_var_args else .fn_type;
1986 break :fn_type try fn_type_scope.addFnType(.{
1987 .ret_ty = return_type_inst,
1988 .param_types = param_types,
1989 });
2018 break :fn_type try fn_type_scope.addFnType(return_type_inst, param_types);
19902019 };
19912020
1992 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1993 zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_scope.instructions.items) catch {};
1994 }
1995
19962021 // We need the memory for the Type to go into the arena for the Decl
19972022 var decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
19982023 errdefer decl_arena.deinit();
19992024 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
20002025
2001 const fn_type_code = fn_type_wip_zir_exec.finish();
2026 const fn_type_code = try fn_type_scope.finish();
2027 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2028 zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_code) catch {};
2029 }
2030
20022031 var fn_type_sema: Sema = .{
20032032 .mod = mod,
20042033 .gpa = mod.gpa,
......@@ -2021,7 +2050,7 @@ fn astgenAndSemaFn(
20212050 };
20222051 defer block_scope.instructions.deinit(mod.gpa);
20232052
2024 const fn_type = try fn_type_sema.rootAsType(mod, &block_scope, fn_type_inst);
2053 const fn_type = try fn_type_sema.rootAsType(&block_scope, fn_type_inst);
20252054 if (body_node == 0) {
20262055 if (!is_extern) {
20272056 return mod.failNode(&block_scope.base, fn_proto.ast.fn_token, "non-extern function has no body", .{});
......@@ -2063,13 +2092,12 @@ fn astgenAndSemaFn(
20632092 const new_func = try decl_arena.allocator.create(Fn);
20642093 const fn_payload = try decl_arena.allocator.create(Value.Payload.Function);
20652094
2066 const fn_zir: zir.Body = blk: {
2095 const fn_zir: zir.Code = blk: {
20672096 // We put the ZIR inside the Decl arena.
20682097 var wip_zir_code: WipZirCode = .{
20692098 .decl = decl,
20702099 .arena = &decl_arena.allocator,
20712100 .gpa = mod.gpa,
2072 .arg_count = param_count,
20732101 };
20742102 defer wip_zir_code.deinit();
20752103
......@@ -2078,6 +2106,8 @@ fn astgenAndSemaFn(
20782106 .parent = &decl.container.base,
20792107 .zir_code = &wip_zir_code,
20802108 };
2109 defer gen_scope.instructions.deinit(mod.gpa);
2110
20812111 // Iterate over the parameters. We put the param names as the first N
20822112 // items inside `extra` so that debug info later can refer to the parameter names
20832113 // even while the respective source code is unloaded.
......@@ -2095,7 +2125,7 @@ fn astgenAndSemaFn(
20952125 .gen_zir = &gen_scope,
20962126 .name = param_name,
20972127 // Implicit const list first, then implicit arg list.
2098 .inst = zir.const_inst_list.len + i,
2128 .inst = @intCast(u32, zir.const_inst_list.len + i),
20992129 };
21002130 params_scope = &sub_scope.base;
21012131
......@@ -2111,18 +2141,19 @@ fn astgenAndSemaFn(
21112141 _ = try astgen.expr(mod, params_scope, .none, body_node);
21122142
21132143 if (gen_scope.instructions.items.len == 0 or
2114 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())
2144 !wip_zir_code.instructions.items(.tag)[gen_scope.instructions.items.len - 1]
2145 .isNoReturn())
21152146 {
2116 _ = try gen_scope.addRetTok(@enumToInt(zir.Const.void_value), tree.lastToken(body_node));
2147 const void_operand = @enumToInt(zir.Const.void_value);
2148 _ = try gen_scope.addUnTok(.ret_tok, void_operand, tree.lastToken(body_node));
21172149 }
21182150
2151 const code = try gen_scope.finish();
21192152 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2120 zir.dumpZir(mod.gpa, "fn_body", decl.name, gen_scope.instructions.items) catch {};
2153 zir.dumpZir(mod.gpa, "fn_body", decl.name, code) catch {};
21212154 }
21222155
2123 break :blk .{
2124 .instructions = try gen_scope.arena.dupe(*zir.Inst, gen_scope.instructions.items),
2125 };
2156 break :blk code;
21262157 };
21272158
21282159 const is_inline = fn_type.fnCallingConvention() == .Inline;
......@@ -2190,7 +2221,8 @@ fn astgenAndSemaFn(
21902221 .{},
21912222 );
21922223 }
2193 const export_src = token_starts[maybe_export_token];
2224 // TODO use a Decl-local source location instead.
2225 const export_src: LazySrcLoc = .{ .token_abs = maybe_export_token };
21942226 const name = tree.tokenSlice(fn_proto.name_token.?); // TODO identifierTokenString
21952227 // The scope needs to have the decl in it.
21962228 try mod.analyzeExport(&block_scope.base, export_src, name, decl);
......@@ -2294,7 +2326,7 @@ fn astgenAndSemaVarDecl(
22942326 init_result_loc,
22952327 var_decl.ast.init_node,
22962328 );
2297 const code = wip_zir_code.finish();
2329 const code = try gen_scope.finish();
22982330 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
22992331 zir.dumpZir(mod.gpa, "var_init", decl.name, code) catch {};
23002332 }
......@@ -2324,13 +2356,13 @@ fn astgenAndSemaVarDecl(
23242356 try sema.root(&block_scope);
23252357
23262358 // The result location guarantees the type coercion.
2327 const analyzed_init_inst = sema.resolveInst(&block_scope, init_inst);
2359 const analyzed_init_inst = try sema.resolveInst(init_inst);
23282360 // The is_comptime in the Scope.Block guarantees the result is comptime-known.
23292361 const val = analyzed_init_inst.value().?;
23302362
23312363 break :vi .{
2332 .ty = try analyzed_init_inst.ty.copy(decl_arena),
2333 .val = try val.copy(decl_arena),
2364 .ty = try analyzed_init_inst.ty.copy(&decl_arena.allocator),
2365 .val = try val.copy(&decl_arena.allocator),
23342366 };
23352367 } else if (!is_extern) {
23362368 return mod.failTok(
......@@ -2358,7 +2390,7 @@ fn astgenAndSemaVarDecl(
23582390 defer type_scope.instructions.deinit(mod.gpa);
23592391
23602392 const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node);
2361 const code = wip_zir_code.finish();
2393 const code = try type_scope.finish();
23622394 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
23632395 zir.dumpZir(mod.gpa, "var_type", decl.name, code) catch {};
23642396 }
......@@ -2388,7 +2420,7 @@ fn astgenAndSemaVarDecl(
23882420 const ty = try sema.rootAsType(&block_scope, var_type);
23892421
23902422 break :vi .{
2391 .ty = try ty.copy(decl_arena),
2423 .ty = try ty.copy(&decl_arena.allocator),
23922424 .val = null,
23932425 };
23942426 } else {
......@@ -2441,7 +2473,8 @@ fn astgenAndSemaVarDecl(
24412473
24422474 if (var_decl.extern_export_token) |maybe_export_token| {
24432475 if (token_tags[maybe_export_token] == .keyword_export) {
2444 const export_src = token_starts[maybe_export_token];
2476 // TODO make this src relative to containing Decl
2477 const export_src: LazySrcLoc = .{ .token_abs = maybe_export_token };
24452478 const name_token = var_decl.ast.mut_token + 1;
24462479 const name = tree.tokenSlice(name_token); // TODO identifierTokenString
24472480 // The scope needs to have the decl in it.
src/Sema.zig+17-8
......@@ -12,7 +12,7 @@ gpa: *Allocator,
1212arena: *Allocator,
1313code: zir.Code,
1414/// Maps ZIR to TZIR.
15inst_map: []*const Inst,
15inst_map: []*Inst,
1616/// When analyzing an inline function call, owner_decl is the Decl of the caller
1717/// and `src_decl` of `Scope.Block` is the `Decl` of the callee.
1818/// This `Decl` owns the arena memory of this `Sema`.
......@@ -58,15 +58,10 @@ pub fn root(sema: *Sema, root_block: *Scope.Block) !void {
5858 return sema.analyzeBody(root_block, root_body);
5959}
6060
61pub fn rootAsType(
62 sema: *Sema,
63 root_block: *Scope.Block,
64 zir_result_inst: zir.Inst.Index,
65) !Type {
61pub fn rootAsType(sema: *Sema, root_block: *Scope.Block, result_inst: zir.Inst.Ref) !Type {
6662 const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len];
6763 try sema.analyzeBody(root_block, root_body);
6864
69 const result_inst = sema.inst_map[zir_result_inst];
7065 // Source location is unneeded because resolveConstValue must have already
7166 // been successfully called when coercing the value to a type, from the
7267 // result location.
......@@ -203,6 +198,7 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde
203198 .array_type => try sema.zirArrayType(block, zir_inst),
204199 .array_type_sentinel => try sema.zirArrayTypeSentinel(block, zir_inst),
205200 .enum_literal => try sema.zirEnumLiteral(block, zir_inst),
201 .enum_literal_small => try sema.zirEnumLiteralSmall(block, zir_inst),
206202 .merge_error_sets => try sema.zirMergeErrorSets(block, zir_inst),
207203 .error_union_type => try sema.zirErrorUnionType(block, zir_inst),
208204 .anyframe_type => try sema.zirAnyframeType(block, zir_inst),
......@@ -232,7 +228,7 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde
232228
233229/// TODO when we rework TZIR memory layout, this function will no longer have a possible error.
234230pub fn resolveInst(sema: *Sema, zir_ref: zir.Inst.Ref) error{OutOfMemory}!*ir.Inst {
235 var i = zir_ref;
231 var i: usize = zir_ref;
236232
237233 // First section of indexes correspond to a set number of constant values.
238234 if (i < zir.const_inst_list.len) {
......@@ -1435,6 +1431,19 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
14351431 });
14361432}
14371433
1434fn zirEnumLiteralSmall(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1435 const tracy = trace(@src());
1436 defer tracy.end();
1437
1438 const name = sema.code.instructions.items(.data)[inst].small_str.get();
1439 const src: LazySrcLoc = .unneeded;
1440 const duped_name = try sema.arena.dupe(u8, name);
1441 return sema.mod.constInst(sema.arena, src, .{
1442 .ty = Type.initTag(.enum_literal),
1443 .val = try Value.Tag.enum_literal.create(sema.arena, duped_name),
1444 });
1445}
1446
14381447/// Pointer in, pointer out.
14391448fn zirOptionalPayloadPtr(
14401449 sema: *Sema,
src/astgen.zig+219-343
......@@ -58,20 +58,14 @@ pub const ResultLoc = union(enum) {
5858 };
5959};
6060
61pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
62 const tree = scope.tree();
63 const token_starts = tree.tokens.items(.start);
61const void_inst: zir.Inst.Ref = @enumToInt(zir.Const.void_value);
6462
65 const type_src = token_starts[tree.firstToken(type_node)];
66 const type_type = try addZIRInstConst(mod, scope, type_src, .{
67 .ty = Type.initTag(.type),
68 .val = Value.initTag(.type_type),
69 });
70 const type_rl: ResultLoc = .{ .ty = type_type };
63pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!zir.Inst.Ref {
64 const type_rl: ResultLoc = .{ .ty = @enumToInt(zir.Const.type_type) };
7165 return expr(mod, scope, type_rl, type_node);
7266}
7367
74fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
68fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
7569 const tree = scope.tree();
7670 const node_tags = tree.nodes.items(.tag);
7771 const main_tokens = tree.nodes.items(.main_token);
......@@ -265,7 +259,7 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
265259/// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the
266260/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
267261/// it must otherwise not be used.
268pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
262pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
269263 const tree = scope.tree();
270264 const main_tokens = tree.nodes.items(.main_token);
271265 const token_tags = tree.tokens.items(.tag);
......@@ -294,20 +288,62 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
294288 .asm_output => unreachable, // Handled in `asmExpr`.
295289 .asm_input => unreachable, // Handled in `asmExpr`.
296290
297 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
298 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
299 .assign_bit_or => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_or)),
300 .assign_bit_shift_left => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shl)),
301 .assign_bit_shift_right => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shr)),
302 .assign_bit_xor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .xor)),
303 .assign_div => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .div)),
304 .assign_sub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .sub)),
305 .assign_sub_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .subwrap)),
306 .assign_mod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mod_rem)),
307 .assign_add => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .add)),
308 .assign_add_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .addwrap)),
309 .assign_mul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mul)),
310 .assign_mul_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mulwrap)),
291 .assign => {
292 try assign(mod, scope, node);
293 return rvalue(mod, scope, rl, void_inst, node);
294 },
295 .assign_bit_and => {
296 try assignOp(mod, scope, node, .bit_and);
297 return rvalue(mod, scope, rl, void_inst, node);
298 },
299 .assign_bit_or => {
300 try assignOp(mod, scope, node, .bit_or);
301 return rvalue(mod, scope, rl, void_inst, node);
302 },
303 .assign_bit_shift_left => {
304 try assignOp(mod, scope, node, .shl);
305 return rvalue(mod, scope, rl, void_inst, node);
306 },
307 .assign_bit_shift_right => {
308 try assignOp(mod, scope, node, .shr);
309 return rvalue(mod, scope, rl, void_inst, node);
310 },
311 .assign_bit_xor => {
312 try assignOp(mod, scope, node, .xor);
313 return rvalue(mod, scope, rl, void_inst, node);
314 },
315 .assign_div => {
316 try assignOp(mod, scope, node, .div);
317 return rvalue(mod, scope, rl, void_inst, node);
318 },
319 .assign_sub => {
320 try assignOp(mod, scope, node, .sub);
321 return rvalue(mod, scope, rl, void_inst, node);
322 },
323 .assign_sub_wrap => {
324 try assignOp(mod, scope, node, .subwrap);
325 return rvalue(mod, scope, rl, void_inst, node);
326 },
327 .assign_mod => {
328 try assignOp(mod, scope, node, .mod_rem);
329 return rvalue(mod, scope, rl, void_inst, node);
330 },
331 .assign_add => {
332 try assignOp(mod, scope, node, .add);
333 return rvalue(mod, scope, rl, void_inst, node);
334 },
335 .assign_add_wrap => {
336 try assignOp(mod, scope, node, .addwrap);
337 return rvalue(mod, scope, rl, void_inst, node);
338 },
339 .assign_mul => {
340 try assignOp(mod, scope, node, .mul);
341 return rvalue(mod, scope, rl, void_inst, node);
342 },
343 .assign_mul_wrap => {
344 try assignOp(mod, scope, node, .mulwrap);
345 return rvalue(mod, scope, rl, void_inst, node);
346 },
311347
312348 .add => return simpleBinOp(mod, scope, rl, node, .add),
313349 .add_wrap => return simpleBinOp(mod, scope, rl, node, .addwrap),
......@@ -336,10 +372,14 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
336372 .bool_and => return boolBinOp(mod, scope, rl, node, true),
337373 .bool_or => return boolBinOp(mod, scope, rl, node, false),
338374
339 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
340 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
341 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
342 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
375 .bool_not => @panic("TODO"),
376 .bit_not => @panic("TODO"),
377 .negation => @panic("TODO"),
378 .negation_wrap => @panic("TODO"),
379 //.bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
380 //.bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
381 //.negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
382 //.negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
343383
344384 .identifier => return identifier(mod, scope, rl, node),
345385
......@@ -377,6 +417,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
377417 },
378418
379419 .unreachable_literal => {
420 if (true) @panic("TODO update for zir-memory-layout");
380421 const main_token = main_tokens[node];
381422 const src = token_starts[main_token];
382423 return addZIRNoOp(mod, scope, src, .unreachable_safe);
......@@ -402,16 +443,19 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
402443 .slice_sentinel => return sliceExpr(mod, scope, rl, tree.sliceSentinel(node)),
403444
404445 .deref => {
446 if (true) @panic("TODO update for zir-memory-layout");
405447 const lhs = try expr(mod, scope, .none, node_datas[node].lhs);
406448 const src = token_starts[main_tokens[node]];
407449 const result = try addZIRUnOp(mod, scope, src, .deref, lhs);
408450 return rvalue(mod, scope, rl, result);
409451 },
410452 .address_of => {
453 if (true) @panic("TODO update for zir-memory-layout");
411454 const result = try expr(mod, scope, .ref, node_datas[node].lhs);
412455 return rvalue(mod, scope, rl, result);
413456 },
414457 .undefined_literal => {
458 if (true) @panic("TODO update for zir-memory-layout");
415459 const main_token = main_tokens[node];
416460 const src = token_starts[main_token];
417461 const result = try addZIRInstConst(mod, scope, src, .{
......@@ -421,6 +465,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
421465 return rvalue(mod, scope, rl, result);
422466 },
423467 .true_literal => {
468 if (true) @panic("TODO update for zir-memory-layout");
424469 const main_token = main_tokens[node];
425470 const src = token_starts[main_token];
426471 const result = try addZIRInstConst(mod, scope, src, .{
......@@ -430,6 +475,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
430475 return rvalue(mod, scope, rl, result);
431476 },
432477 .false_literal => {
478 if (true) @panic("TODO update for zir-memory-layout");
433479 const main_token = main_tokens[node];
434480 const src = token_starts[main_token];
435481 const result = try addZIRInstConst(mod, scope, src, .{
......@@ -439,6 +485,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
439485 return rvalue(mod, scope, rl, result);
440486 },
441487 .null_literal => {
488 if (true) @panic("TODO update for zir-memory-layout");
442489 const main_token = main_tokens[node];
443490 const src = token_starts[main_token];
444491 const result = try addZIRInstConst(mod, scope, src, .{
......@@ -448,12 +495,14 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
448495 return rvalue(mod, scope, rl, result);
449496 },
450497 .optional_type => {
498 if (true) @panic("TODO update for zir-memory-layout");
451499 const src = token_starts[main_tokens[node]];
452500 const operand = try typeExpr(mod, scope, node_datas[node].lhs);
453501 const result = try addZIRUnOp(mod, scope, src, .optional_type, operand);
454502 return rvalue(mod, scope, rl, result);
455503 },
456504 .unwrap_optional => {
505 if (true) @panic("TODO update for zir-memory-layout");
457506 const src = token_starts[main_tokens[node]];
458507 switch (rl) {
459508 .ref => return addZIRUnOp(
......@@ -473,6 +522,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
473522 }
474523 },
475524 .block_two, .block_two_semicolon => {
525 if (true) @panic("TODO update for zir-memory-layout");
476526 const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
477527 if (node_datas[node].lhs == 0) {
478528 return blockExpr(mod, scope, rl, node, statements[0..0]);
......@@ -483,10 +533,12 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
483533 }
484534 },
485535 .block, .block_semicolon => {
536 if (true) @panic("TODO update for zir-memory-layout");
486537 const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
487538 return blockExpr(mod, scope, rl, node, statements);
488539 },
489540 .enum_literal => {
541 if (true) @panic("TODO update for zir-memory-layout");
490542 const ident_token = main_tokens[node];
491543 const gen_zir = scope.getGenZir();
492544 const string_bytes = &gen_zir.zir_exec.string_bytes;
......@@ -497,6 +549,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
497549 return rvalue(mod, scope, rl, result);
498550 },
499551 .error_value => {
552 if (true) @panic("TODO update for zir-memory-layout");
500553 const ident_token = node_datas[node].rhs;
501554 const name = try mod.identifierTokenString(scope, ident_token);
502555 const src = token_starts[ident_token];
......@@ -504,6 +557,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
504557 return rvalue(mod, scope, rl, result);
505558 },
506559 .error_union => {
560 if (true) @panic("TODO update for zir-memory-layout");
507561 const error_set = try typeExpr(mod, scope, node_datas[node].lhs);
508562 const payload = try typeExpr(mod, scope, node_datas[node].rhs);
509563 const src = token_starts[main_tokens[node]];
......@@ -511,6 +565,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
511565 return rvalue(mod, scope, rl, result);
512566 },
513567 .merge_error_sets => {
568 if (true) @panic("TODO update for zir-memory-layout");
514569 const lhs = try typeExpr(mod, scope, node_datas[node].lhs);
515570 const rhs = try typeExpr(mod, scope, node_datas[node].rhs);
516571 const src = token_starts[main_tokens[node]];
......@@ -518,6 +573,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
518573 return rvalue(mod, scope, rl, result);
519574 },
520575 .anyframe_literal => {
576 if (true) @panic("TODO update for zir-memory-layout");
521577 const main_token = main_tokens[node];
522578 const src = token_starts[main_token];
523579 const result = try addZIRInstConst(mod, scope, src, .{
......@@ -527,12 +583,14 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
527583 return rvalue(mod, scope, rl, result);
528584 },
529585 .anyframe_type => {
586 if (true) @panic("TODO update for zir-memory-layout");
530587 const src = token_starts[node_datas[node].lhs];
531588 const return_type = try typeExpr(mod, scope, node_datas[node].rhs);
532589 const result = try addZIRUnOp(mod, scope, src, .anyframe_type, return_type);
533590 return rvalue(mod, scope, rl, result);
534591 },
535592 .@"catch" => {
593 if (true) @panic("TODO update for zir-memory-layout");
536594 const catch_token = main_tokens[node];
537595 const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
538596 catch_token + 2
......@@ -631,9 +689,11 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
631689 .@"switch", .switch_comma => return switchExpr(mod, scope, rl, node),
632690
633691 .@"nosuspend" => return nosuspendExpr(mod, scope, rl, node),
634 .@"suspend" => return rvalue(mod, scope, rl, try suspendExpr(mod, scope, node)),
692 .@"suspend" => @panic("TODO"),
693 //.@"suspend" => return rvalue(mod, scope, rl, try suspendExpr(mod, scope, node)),
635694 .@"await" => return awaitExpr(mod, scope, rl, node),
636 .@"resume" => return rvalue(mod, scope, rl, try resumeExpr(mod, scope, node)),
695 .@"resume" => @panic("TODO"),
696 //.@"resume" => return rvalue(mod, scope, rl, try resumeExpr(mod, scope, node)),
637697
638698 .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),
639699 .@"errdefer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .errdefer", .{}),
......@@ -673,20 +733,22 @@ pub fn comptimeExpr(
673733 parent_scope: *Scope,
674734 rl: ResultLoc,
675735 node: ast.Node.Index,
676) InnerError!*zir.Inst {
736) InnerError!zir.Inst.Ref {
737 if (true) @panic("TODO update for zir-memory-layout branch");
738
677739 // If we are already in a comptime scope, no need to make another one.
678740 if (parent_scope.isComptime()) {
679741 return expr(mod, parent_scope, rl, node);
680742 }
681743
744 const gz = parent_scope.getGenZir();
682745 const tree = parent_scope.tree();
683746 const token_starts = tree.tokens.items(.start);
684747
685748 // Make a scope to collect generated instructions in the sub-expression.
686749 var block_scope: Scope.GenZir = .{
687750 .parent = parent_scope,
688 .decl = parent_scope.ownerDecl().?,
689 .arena = parent_scope.arena(),
751 .zir_code = gz.zir_code,
690752 .force_comptime = true,
691753 .instructions = .{},
692754 };
......@@ -698,7 +760,7 @@ pub fn comptimeExpr(
698760
699761 const src = token_starts[tree.firstToken(node)];
700762 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
701 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
763 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
702764 });
703765
704766 return &block.base;
......@@ -709,7 +771,8 @@ fn breakExpr(
709771 parent_scope: *Scope,
710772 rl: ResultLoc,
711773 node: ast.Node.Index,
712) InnerError!*zir.Inst {
774) InnerError!zir.Inst.Ref {
775 if (true) @panic("TODO update for zir-memory-layout");
713776 const tree = parent_scope.tree();
714777 const node_datas = tree.nodes.items(.data);
715778 const main_tokens = tree.nodes.items(.main_token);
......@@ -787,7 +850,8 @@ fn continueExpr(
787850 parent_scope: *Scope,
788851 rl: ResultLoc,
789852 node: ast.Node.Index,
790) InnerError!*zir.Inst {
853) InnerError!zir.Inst.Ref {
854 if (true) @panic("TODO update for zir-memory-layout");
791855 const tree = parent_scope.tree();
792856 const node_datas = tree.nodes.items(.data);
793857 const main_tokens = tree.nodes.items(.main_token);
......@@ -843,7 +907,7 @@ pub fn blockExpr(
843907 rl: ResultLoc,
844908 block_node: ast.Node.Index,
845909 statements: []const ast.Node.Index,
846) InnerError!*zir.Inst {
910) InnerError!zir.Inst.Ref {
847911 const tracy = trace(@src());
848912 defer tracy.end();
849913
......@@ -859,7 +923,7 @@ pub fn blockExpr(
859923 }
860924
861925 try blockExprStmts(mod, scope, block_node, statements);
862 return rvalueVoid(mod, scope, rl, block_node, {});
926 return rvalue(mod, scope, rl, void_inst, block_node);
863927}
864928
865929fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void {
......@@ -875,21 +939,18 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
875939 const main_tokens = tree.nodes.items(.main_token);
876940 const token_starts = tree.tokens.items(.start);
877941
878 const label_src = token_starts[label];
879 const prev_label_src = token_starts[prev_label.token];
880
881942 const label_name = try mod.identifierTokenString(parent_scope, label);
882943 const msg = msg: {
883944 const msg = try mod.errMsg(
884945 parent_scope,
885 label_src,
946 gen_zir.tokSrcLoc(label),
886947 "redefinition of label '{s}'",
887948 .{label_name},
888949 );
889950 errdefer msg.destroy(mod.gpa);
890951 try mod.errNote(
891952 parent_scope,
892 prev_label_src,
953 gen_zir.tokSrcLoc(prev_label.token),
893954 msg,
894955 "previous definition is here",
895956 .{},
......@@ -917,7 +978,7 @@ fn labeledBlockExpr(
917978 block_node: ast.Node.Index,
918979 statements: []const ast.Node.Index,
919980 zir_tag: zir.Inst.Tag,
920) InnerError!*zir.Inst {
981) InnerError!zir.Inst.Ref {
921982 const tracy = trace(@src());
922983 defer tracy.end();
923984
......@@ -1285,6 +1346,7 @@ fn assignOp(
12851346 infix_node: ast.Node.Index,
12861347 op_inst_tag: zir.Inst.Tag,
12871348) InnerError!void {
1349 if (true) @panic("TODO update for zir-memory-layout");
12881350 const tree = scope.tree();
12891351 const node_datas = tree.nodes.items(.data);
12901352 const main_tokens = tree.nodes.items(.main_token);
......@@ -1299,7 +1361,7 @@ fn assignOp(
12991361 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
13001362}
13011363
1302fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
1364fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
13031365 const tree = scope.tree();
13041366 const node_datas = tree.nodes.items(.data);
13051367 const main_tokens = tree.nodes.items(.main_token);
......@@ -1314,7 +1376,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.In
13141376 return addZIRUnOp(mod, scope, src, .bool_not, operand);
13151377}
13161378
1317fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
1379fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
13181380 const tree = scope.tree();
13191381 const node_datas = tree.nodes.items(.data);
13201382 const main_tokens = tree.nodes.items(.main_token);
......@@ -1330,7 +1392,7 @@ fn negation(
13301392 scope: *Scope,
13311393 node: ast.Node.Index,
13321394 op_inst_tag: zir.Inst.Tag,
1333) InnerError!*zir.Inst {
1395) InnerError!zir.Inst.Ref {
13341396 const tree = scope.tree();
13351397 const node_datas = tree.nodes.items(.data);
13361398 const main_tokens = tree.nodes.items(.main_token);
......@@ -1350,7 +1412,8 @@ fn ptrType(
13501412 scope: *Scope,
13511413 rl: ResultLoc,
13521414 ptr_info: ast.full.PtrType,
1353) InnerError!*zir.Inst {
1415) InnerError!zir.Inst.Ref {
1416 if (true) @panic("TODO update for zir-memory-layout");
13541417 const tree = scope.tree();
13551418 const token_starts = tree.tokens.items(.start);
13561419
......@@ -1394,7 +1457,8 @@ fn ptrType(
13941457 return rvalue(mod, scope, rl, result);
13951458}
13961459
1397fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
1460fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
1461 if (true) @panic("TODO update for zir-memory-layout");
13981462 const tree = scope.tree();
13991463 const main_tokens = tree.nodes.items(.main_token);
14001464 const node_datas = tree.nodes.items(.data);
......@@ -1421,7 +1485,8 @@ fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !
14211485 }
14221486}
14231487
1424fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
1488fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
1489 if (true) @panic("TODO update for zir-memory-layout");
14251490 const tree = scope.tree();
14261491 const main_tokens = tree.nodes.items(.main_token);
14271492 const token_starts = tree.tokens.items(.start);
......@@ -1454,7 +1519,8 @@ fn containerDecl(
14541519 scope: *Scope,
14551520 rl: ResultLoc,
14561521 container_decl: ast.full.ContainerDecl,
1457) InnerError!*zir.Inst {
1522) InnerError!zir.Inst.Ref {
1523 if (true) @panic("TODO update for zir-memory-layout");
14581524 return mod.failTok(scope, container_decl.ast.main_token, "TODO implement container decls", .{});
14591525}
14601526
......@@ -1463,7 +1529,8 @@ fn errorSetDecl(
14631529 scope: *Scope,
14641530 rl: ResultLoc,
14651531 node: ast.Node.Index,
1466) InnerError!*zir.Inst {
1532) InnerError!zir.Inst.Ref {
1533 if (true) @panic("TODO update for zir-memory-layout");
14671534 const tree = scope.tree();
14681535 const main_tokens = tree.nodes.items(.main_token);
14691536 const token_tags = tree.tokens.items(.tag);
......@@ -1516,7 +1583,9 @@ fn orelseCatchExpr(
15161583 unwrap_code_op: zir.Inst.Tag,
15171584 rhs: ast.Node.Index,
15181585 payload_token: ?ast.TokenIndex,
1519) InnerError!*zir.Inst {
1586) InnerError!zir.Inst.Ref {
1587 if (true) @panic("TODO update for zir-memory-layout");
1588
15201589 const tree = scope.tree();
15211590 const token_starts = tree.tokens.items(.start);
15221591
......@@ -1548,7 +1617,7 @@ fn orelseCatchExpr(
15481617 }, .{});
15491618
15501619 const block = try addZIRInstBlock(mod, scope, src, .block, .{
1551 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
1620 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
15521621 });
15531622
15541623 var then_scope: Scope.GenZir = .{
......@@ -1624,11 +1693,11 @@ fn finishThenElseBlock(
16241693 else_body: *zir.Body,
16251694 then_src: usize,
16261695 else_src: usize,
1627 then_result: *zir.Inst,
1696 then_result: zir.Inst.Ref,
16281697 else_result: ?*zir.Inst,
1629 main_block: *zir.Inst.Block,
1630 then_break_block: *zir.Inst.Block,
1631) InnerError!*zir.Inst {
1698 main_block: zir.Inst.Ref.Block,
1699 then_break_block: zir.Inst.Ref.Block,
1700) InnerError!zir.Inst.Ref {
16321701 // We now have enough information to decide whether the result instruction should
16331702 // be communicated via result location pointer or break instructions.
16341703 const strat = rlStrategy(rl, block_scope);
......@@ -1699,7 +1768,8 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as
16991768 return mem.eql(u8, ident_name_1, ident_name_2);
17001769}
17011770
1702pub fn fieldAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
1771pub fn fieldAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
1772 if (true) @panic("TODO update for zir-memory-layout");
17031773 const tree = scope.tree();
17041774 const token_starts = tree.tokens.items(.start);
17051775 const main_tokens = tree.nodes.items(.main_token);
......@@ -1727,7 +1797,8 @@ fn arrayAccess(
17271797 scope: *Scope,
17281798 rl: ResultLoc,
17291799 node: ast.Node.Index,
1730) InnerError!*zir.Inst {
1800) InnerError!zir.Inst.Ref {
1801 if (true) @panic("TODO update for zir-memory-layout");
17311802 const tree = scope.tree();
17321803 const main_tokens = tree.nodes.items(.main_token);
17331804 const token_starts = tree.tokens.items(.start);
......@@ -1756,7 +1827,8 @@ fn sliceExpr(
17561827 scope: *Scope,
17571828 rl: ResultLoc,
17581829 slice: ast.full.Slice,
1759) InnerError!*zir.Inst {
1830) InnerError!zir.Inst.Ref {
1831 if (true) @panic("TODO update for zir-memory-layout");
17601832 const tree = scope.tree();
17611833 const token_starts = tree.tokens.items(.start);
17621834
......@@ -1805,7 +1877,8 @@ fn simpleBinOp(
18051877 rl: ResultLoc,
18061878 infix_node: ast.Node.Index,
18071879 op_inst_tag: zir.Inst.Tag,
1808) InnerError!*zir.Inst {
1880) InnerError!zir.Inst.Ref {
1881 if (true) @panic("TODO update for zir-memory-layout");
18091882 const tree = scope.tree();
18101883 const node_datas = tree.nodes.items(.data);
18111884 const main_tokens = tree.nodes.items(.main_token);
......@@ -1824,7 +1897,8 @@ fn boolBinOp(
18241897 rl: ResultLoc,
18251898 infix_node: ast.Node.Index,
18261899 is_bool_and: bool,
1827) InnerError!*zir.Inst {
1900) InnerError!zir.Inst.Ref {
1901 if (true) @panic("TODO update for zir-memory-layout");
18281902 const tree = scope.tree();
18291903 const node_datas = tree.nodes.items(.data);
18301904 const main_tokens = tree.nodes.items(.main_token);
......@@ -1853,7 +1927,7 @@ fn boolBinOp(
18531927 }, .{});
18541928
18551929 const block = try addZIRInstBlock(mod, scope, src, .block, .{
1856 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
1930 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
18571931 });
18581932
18591933 var rhs_scope: Scope.GenZir = .{
......@@ -1893,15 +1967,15 @@ fn boolBinOp(
18931967 // break rhs
18941968 // else
18951969 // break false
1896 condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) };
1897 condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) };
1970 condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) };
1971 condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) };
18981972 } else {
18991973 // if lhs // OR
19001974 // break true
19011975 // else
19021976 // break rhs
1903 condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(*zir.Inst, const_scope.instructions.items) };
1904 condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(*zir.Inst, rhs_scope.instructions.items) };
1977 condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) };
1978 condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) };
19051979 }
19061980
19071981 return rvalue(mod, scope, rl, &block.base);
......@@ -1912,7 +1986,8 @@ fn ifExpr(
19121986 scope: *Scope,
19131987 rl: ResultLoc,
19141988 if_full: ast.full.If,
1915) InnerError!*zir.Inst {
1989) InnerError!zir.Inst.Ref {
1990 if (true) @panic("TODO update for zir-memory-layout");
19161991 var block_scope: Scope.GenZir = .{
19171992 .parent = scope,
19181993 .decl = scope.ownerDecl().?,
......@@ -1951,7 +2026,7 @@ fn ifExpr(
19512026 }, .{});
19522027
19532028 const block = try addZIRInstBlock(mod, scope, if_src, .block, .{
1954 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
2029 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
19552030 });
19562031
19572032 const then_src = token_starts[tree.lastToken(if_full.ast.then_expr)];
......@@ -2016,7 +2091,7 @@ fn ifExpr(
20162091/// Expects to find exactly 1 .store_to_block_ptr instruction.
20172092fn copyBodyWithElidedStoreBlockPtr(body: *zir.Body, scope: Module.Scope.GenZir) !void {
20182093 body.* = .{
2019 .instructions = try scope.arena.alloc(*zir.Inst, scope.instructions.items.len - 1),
2094 .instructions = try scope.arena.alloc(zir.Inst.Ref, scope.instructions.items.len - 1),
20202095 };
20212096 var dst_index: usize = 0;
20222097 for (scope.instructions.items) |src_inst| {
......@@ -2030,7 +2105,7 @@ fn copyBodyWithElidedStoreBlockPtr(body: *zir.Body, scope: Module.Scope.GenZir)
20302105
20312106fn copyBodyNoEliding(body: *zir.Body, scope: Module.Scope.GenZir) !void {
20322107 body.* = .{
2033 .instructions = try scope.arena.dupe(*zir.Inst, scope.instructions.items),
2108 .instructions = try scope.arena.dupe(zir.Inst.Ref, scope.instructions.items),
20342109 };
20352110}
20362111
......@@ -2039,7 +2114,8 @@ fn whileExpr(
20392114 scope: *Scope,
20402115 rl: ResultLoc,
20412116 while_full: ast.full.While,
2042) InnerError!*zir.Inst {
2117) InnerError!zir.Inst.Ref {
2118 if (true) @panic("TODO update for zir-memory-layout");
20432119 if (while_full.label_token) |label_token| {
20442120 try checkLabelRedefinition(mod, scope, label_token);
20452121 }
......@@ -2096,7 +2172,7 @@ fn whileExpr(
20962172 .else_body = undefined, // populated below
20972173 }, .{});
20982174 const cond_block = try addZIRInstBlock(mod, &loop_scope.base, while_src, .block, .{
2099 .instructions = try loop_scope.arena.dupe(*zir.Inst, continue_scope.instructions.items),
2175 .instructions = try loop_scope.arena.dupe(zir.Inst.Ref, continue_scope.instructions.items),
21002176 });
21012177 // TODO avoid emitting the continue expr when there
21022178 // are no jumps to it. This happens when the last statement of a while body is noreturn
......@@ -2113,13 +2189,13 @@ fn whileExpr(
21132189 },
21142190 .positionals = .{
21152191 .body = .{
2116 .instructions = try scope.arena().dupe(*zir.Inst, loop_scope.instructions.items),
2192 .instructions = try scope.arena().dupe(zir.Inst.Ref, loop_scope.instructions.items),
21172193 },
21182194 },
21192195 .kw_args = .{},
21202196 };
21212197 const while_block = try addZIRInstBlock(mod, scope, while_src, .block, .{
2122 .instructions = try scope.arena().dupe(*zir.Inst, &[1]*zir.Inst{&loop.base}),
2198 .instructions = try scope.arena().dupe(zir.Inst.Ref, &[1]zir.Inst.Ref{&loop.base}),
21232199 });
21242200 loop_scope.break_block = while_block;
21252201 loop_scope.continue_block = cond_block;
......@@ -2195,7 +2271,8 @@ fn forExpr(
21952271 scope: *Scope,
21962272 rl: ResultLoc,
21972273 for_full: ast.full.While,
2198) InnerError!*zir.Inst {
2274) InnerError!zir.Inst.Ref {
2275 if (true) @panic("TODO update for zir-memory-layout");
21992276 if (for_full.label_token) |label_token| {
22002277 try checkLabelRedefinition(mod, scope, label_token);
22012278 }
......@@ -2258,7 +2335,7 @@ fn forExpr(
22582335 .else_body = undefined, // populated below
22592336 }, .{});
22602337 const cond_block = try addZIRInstBlock(mod, &loop_scope.base, for_src, .block, .{
2261 .instructions = try loop_scope.arena.dupe(*zir.Inst, cond_scope.instructions.items),
2338 .instructions = try loop_scope.arena.dupe(zir.Inst.Ref, cond_scope.instructions.items),
22622339 });
22632340
22642341 // increment index variable
......@@ -2278,13 +2355,13 @@ fn forExpr(
22782355 },
22792356 .positionals = .{
22802357 .body = .{
2281 .instructions = try scope.arena().dupe(*zir.Inst, loop_scope.instructions.items),
2358 .instructions = try scope.arena().dupe(zir.Inst.Ref, loop_scope.instructions.items),
22822359 },
22832360 },
22842361 .kw_args = .{},
22852362 };
22862363 const for_block = try addZIRInstBlock(mod, scope, for_src, .block, .{
2287 .instructions = try scope.arena().dupe(*zir.Inst, &[1]*zir.Inst{&loop.base}),
2364 .instructions = try scope.arena().dupe(zir.Inst.Ref, &[1]zir.Inst.Ref{&loop.base}),
22882365 });
22892366 loop_scope.break_block = for_block;
22902367 loop_scope.continue_block = cond_block;
......@@ -2407,7 +2484,8 @@ fn switchExpr(
24072484 scope: *Scope,
24082485 rl: ResultLoc,
24092486 switch_node: ast.Node.Index,
2410) InnerError!*zir.Inst {
2487) InnerError!zir.Inst.Ref {
2488 if (true) @panic("TODO update for zir-memory-layout");
24112489 const tree = scope.tree();
24122490 const node_datas = tree.nodes.items(.data);
24132491 const main_tokens = tree.nodes.items(.main_token);
......@@ -2432,7 +2510,7 @@ fn switchExpr(
24322510 setBlockResultLoc(&block_scope, rl);
24332511 defer block_scope.instructions.deinit(mod.gpa);
24342512
2435 var items = std.ArrayList(*zir.Inst).init(mod.gpa);
2513 var items = std.ArrayList(zir.Inst.Ref).init(mod.gpa);
24362514 defer items.deinit();
24372515
24382516 // First we gather all the switch items and check else/'_' prongs.
......@@ -2549,13 +2627,13 @@ fn switchExpr(
25492627 const switch_inst = try addZirInstT(mod, &block_scope.base, switch_src, zir.Inst.SwitchBr, rl_and_tag.tag, .{
25502628 .target = target,
25512629 .cases = cases,
2552 .items = try block_scope.arena.dupe(*zir.Inst, items.items),
2630 .items = try block_scope.arena.dupe(zir.Inst.Ref, items.items),
25532631 .else_body = undefined, // populated below
25542632 .range = first_range,
25552633 .special_prong = special_prong,
25562634 });
25572635 const block = try addZIRInstBlock(mod, scope, switch_src, .block, .{
2558 .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items),
2636 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items),
25592637 });
25602638
25612639 var case_scope: Scope.GenZir = .{
......@@ -2611,7 +2689,7 @@ fn switchExpr(
26112689
26122690 cases[case_index] = .{
26132691 .item = item,
2614 .body = .{ .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items) },
2692 .body = .{ .instructions = try scope.arena().dupe(zir.Inst.Ref, case_scope.instructions.items) },
26152693 };
26162694 case_index += 1;
26172695 continue;
......@@ -2658,14 +2736,14 @@ fn switchExpr(
26582736 .else_body = undefined, // populated below
26592737 }, .{});
26602738 const cond_block = try addZIRInstBlock(mod, &else_scope.base, case_src, .block, .{
2661 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
2739 .instructions = try scope.arena().dupe(zir.Inst.Ref, case_scope.instructions.items),
26622740 });
26632741
26642742 // reset cond_scope for then_body
26652743 case_scope.instructions.items.len = 0;
26662744 try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
26672745 condbr.positionals.then_body = .{
2668 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
2746 .instructions = try scope.arena().dupe(zir.Inst.Ref, case_scope.instructions.items),
26692747 };
26702748
26712749 // reset cond_scope for else_body
......@@ -2674,7 +2752,7 @@ fn switchExpr(
26742752 .block = cond_block,
26752753 }, .{});
26762754 condbr.positionals.else_body = .{
2677 .instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
2755 .instructions = try scope.arena().dupe(zir.Inst.Ref, case_scope.instructions.items),
26782756 };
26792757 }
26802758
......@@ -2686,7 +2764,7 @@ fn switchExpr(
26862764 _ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);
26872765 }
26882766 switch_inst.positionals.else_body = .{
2689 .instructions = try block_scope.arena.dupe(*zir.Inst, else_scope.instructions.items),
2767 .instructions = try block_scope.arena.dupe(zir.Inst.Ref, else_scope.instructions.items),
26902768 };
26912769
26922770 return &block.base;
......@@ -2698,7 +2776,7 @@ fn switchCaseExpr(
26982776 rl: ResultLoc,
26992777 block: *zir.Inst.Block,
27002778 case: ast.full.SwitchCase,
2701 target: *zir.Inst,
2779 target: zir.Inst.Ref,
27022780) !void {
27032781 const tree = scope.tree();
27042782 const node_datas = tree.nodes.items(.data);
......@@ -2733,27 +2811,22 @@ fn switchCaseExpr(
27332811 }
27342812}
27352813
2736fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
2814fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
27372815 const tree = scope.tree();
27382816 const node_datas = tree.nodes.items(.data);
27392817 const main_tokens = tree.nodes.items(.main_token);
2740 const token_starts = tree.tokens.items(.start);
27412818
2742 const src = token_starts[main_tokens[node]];
2743 const rhs_node = node_datas[node].lhs;
2744 if (rhs_node != 0) {
2745 if (nodeMayNeedMemoryLocation(scope, rhs_node)) {
2746 const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);
2747 const operand = try expr(mod, scope, .{ .ptr = ret_ptr }, rhs_node);
2748 return addZIRUnOp(mod, scope, src, .@"return", operand);
2749 } else {
2750 const fn_ret_ty = try addZIRNoOp(mod, scope, src, .ret_type);
2751 const operand = try expr(mod, scope, .{ .ty = fn_ret_ty }, rhs_node);
2752 return addZIRUnOp(mod, scope, src, .@"return", operand);
2753 }
2754 } else {
2755 return addZIRNoOp(mod, scope, src, .return_void);
2756 }
2819 const operand_node = node_datas[node].lhs;
2820 const gz = scope.getGenZir();
2821 const operand: zir.Inst.Ref = if (operand_node != 0) operand: {
2822 const rl: ResultLoc = if (nodeMayNeedMemoryLocation(scope, operand_node)) .{
2823 .ptr = try gz.addNode(.ret_ptr, node),
2824 } else .{
2825 .ty = try gz.addNode(.ret_type, node),
2826 };
2827 break :operand try expr(mod, scope, rl, operand_node);
2828 } else void_inst;
2829 return gz.addUnNode(.ret_node, operand, node);
27572830}
27582831
27592832fn identifier(
......@@ -2761,7 +2834,8 @@ fn identifier(
27612834 scope: *Scope,
27622835 rl: ResultLoc,
27632836 ident: ast.Node.Index,
2764) InnerError!*zir.Inst {
2837) InnerError!zir.Inst.Ref {
2838 if (true) @panic("TODO update for zir-memory-layout");
27652839 const tracy = trace(@src());
27662840 defer tracy.end();
27672841
......@@ -2882,7 +2956,8 @@ fn stringLiteral(
28822956 scope: *Scope,
28832957 rl: ResultLoc,
28842958 str_lit: ast.Node.Index,
2885) InnerError!*zir.Inst {
2959) InnerError!zir.Inst.Ref {
2960 if (true) @panic("TODO update for zir-memory-layout");
28862961 const tree = scope.tree();
28872962 const main_tokens = tree.nodes.items(.main_token);
28882963 const token_starts = tree.tokens.items(.start);
......@@ -2899,7 +2974,8 @@ fn multilineStringLiteral(
28992974 scope: *Scope,
29002975 rl: ResultLoc,
29012976 str_lit: ast.Node.Index,
2902) InnerError!*zir.Inst {
2977) InnerError!zir.Inst.Ref {
2978 if (true) @panic("TODO update for zir-memory-layout");
29032979 const tree = scope.tree();
29042980 const node_datas = tree.nodes.items(.data);
29052981 const main_tokens = tree.nodes.items(.main_token);
......@@ -2943,7 +3019,8 @@ fn multilineStringLiteral(
29433019 return rvalue(mod, scope, rl, str_inst);
29443020}
29453021
2946fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
3022fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
3023 if (true) @panic("TODO update for zir-memory-layout");
29473024 const tree = scope.tree();
29483025 const main_tokens = tree.nodes.items(.main_token);
29493026 const main_token = main_tokens[node];
......@@ -2970,11 +3047,11 @@ fn integerLiteral(
29703047 mod: *Module,
29713048 scope: *Scope,
29723049 rl: ResultLoc,
2973 int_lit: ast.Node.Index,
2974) InnerError!*zir.Inst {
3050 node: ast.Node.Index,
3051) InnerError!zir.Inst.Ref {
29753052 const tree = scope.tree();
29763053 const main_tokens = tree.nodes.items(.main_token);
2977 const int_token = main_tokens[int_lit];
3054 const int_token = main_tokens[node];
29783055 const prefixed_bytes = tree.tokenSlice(int_token);
29793056 const gz = scope.getGenZir();
29803057 if (std.fmt.parseInt(u64, prefixed_bytes, 0)) |small_int| {
......@@ -2983,9 +3060,9 @@ fn integerLiteral(
29833060 1 => @enumToInt(zir.Const.one),
29843061 else => try gz.addInt(small_int),
29853062 };
2986 return rvalue(mod, scope, rl, result);
3063 return rvalue(mod, scope, rl, result, node);
29873064 } else |err| {
2988 return mod.failTok(scope, int_token, "TODO implement int literals that don't fit in a u64", .{});
3065 return mod.failNode(scope, node, "TODO implement int literals that don't fit in a u64", .{});
29893066 }
29903067}
29913068
......@@ -2994,7 +3071,8 @@ fn floatLiteral(
29943071 scope: *Scope,
29953072 rl: ResultLoc,
29963073 float_lit: ast.Node.Index,
2997) InnerError!*zir.Inst {
3074) InnerError!zir.Inst.Ref {
3075 if (true) @panic("TODO update for zir-memory-layout");
29983076 const arena = scope.arena();
29993077 const tree = scope.tree();
30003078 const main_tokens = tree.nodes.items(.main_token);
......@@ -3016,7 +3094,8 @@ fn floatLiteral(
30163094 return rvalue(mod, scope, rl, result);
30173095}
30183096
3019fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
3097fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!zir.Inst.Ref {
3098 if (true) @panic("TODO update for zir-memory-layout");
30203099 const arena = scope.arena();
30213100 const tree = scope.tree();
30223101 const main_tokens = tree.nodes.items(.main_token);
......@@ -3028,7 +3107,7 @@ fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) Inner
30283107 }
30293108
30303109 const inputs = try arena.alloc([]const u8, full.inputs.len);
3031 const args = try arena.alloc(*zir.Inst, full.inputs.len);
3110 const args = try arena.alloc(zir.Inst.Ref, full.inputs.len);
30323111
30333112 const src = token_starts[full.ast.asm_token];
30343113 const str_type = try addZIRInstConst(mod, scope, src, .{
......@@ -3068,7 +3147,7 @@ fn as(
30683147 src: usize,
30693148 lhs: ast.Node.Index,
30703149 rhs: ast.Node.Index,
3071) InnerError!*zir.Inst {
3150) InnerError!zir.Inst.Ref {
30723151 const dest_type = try typeExpr(mod, scope, lhs);
30733152 switch (rl) {
30743153 .none, .discard, .ref, .ty => {
......@@ -3099,10 +3178,10 @@ fn asRlPtr(
30993178 scope: *Scope,
31003179 rl: ResultLoc,
31013180 src: usize,
3102 result_ptr: *zir.Inst,
3181 result_ptr: zir.Inst.Ref,
31033182 operand_node: ast.Node.Index,
3104 dest_type: *zir.Inst,
3105) InnerError!*zir.Inst {
3183 dest_type: zir.Inst.Ref,
3184) InnerError!zir.Inst.Ref {
31063185 // Detect whether this expr() call goes into rvalue() to store the result into the
31073186 // result location. If it does, elide the coerce_result_ptr instruction
31083187 // as well as the store instruction, instead passing the result as an rvalue.
......@@ -3146,7 +3225,7 @@ fn bitCast(
31463225 src: usize,
31473226 lhs: ast.Node.Index,
31483227 rhs: ast.Node.Index,
3149) InnerError!*zir.Inst {
3228) InnerError!zir.Inst.Ref {
31503229 const dest_type = try typeExpr(mod, scope, lhs);
31513230 switch (rl) {
31523231 .none => {
......@@ -3193,7 +3272,7 @@ fn typeOf(
31933272 builtin_token: ast.TokenIndex,
31943273 src: usize,
31953274 params: []const ast.Node.Index,
3196) InnerError!*zir.Inst {
3275) InnerError!zir.Inst.Ref {
31973276 if (params.len < 1) {
31983277 return mod.failTok(scope, builtin_token, "expected at least 1 argument, found 0", .{});
31993278 }
......@@ -3201,7 +3280,7 @@ fn typeOf(
32013280 return rvalue(mod, scope, rl, try addZIRUnOp(mod, scope, src, .typeof, try expr(mod, scope, .none, params[0])));
32023281 }
32033282 const arena = scope.arena();
3204 var items = try arena.alloc(*zir.Inst, params.len);
3283 var items = try arena.alloc(zir.Inst.Ref, params.len);
32053284 for (params) |param, param_i|
32063285 items[param_i] = try expr(mod, scope, .none, param);
32073286 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));
......@@ -3213,7 +3292,8 @@ fn builtinCall(
32133292 rl: ResultLoc,
32143293 call: ast.Node.Index,
32153294 params: []const ast.Node.Index,
3216) InnerError!*zir.Inst {
3295) InnerError!zir.Inst.Ref {
3296 if (true) @panic("TODO update for zir-memory-layout");
32173297 const tree = scope.tree();
32183298 const main_tokens = tree.nodes.items(.main_token);
32193299 const token_starts = tree.tokens.items(.start);
......@@ -3284,7 +3364,7 @@ fn builtinCall(
32843364 },
32853365 .compile_log => {
32863366 const arena = scope.arena();
3287 var targets = try arena.alloc(*zir.Inst, params.len);
3367 var targets = try arena.alloc(zir.Inst.Ref, params.len);
32883368 for (params) |param, param_i|
32893369 targets[param_i] = try expr(mod, scope, .none, param);
32903370 const result = try addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{});
......@@ -3414,7 +3494,7 @@ fn callExpr(
34143494 rl: ResultLoc,
34153495 node: ast.Node.Index,
34163496 call: ast.full.Call,
3417) InnerError!*zir.Inst {
3497) InnerError!zir.Inst.Ref {
34183498 if (true) {
34193499 @panic("TODO update for zir-memory-layout branch");
34203500 }
......@@ -3459,7 +3539,7 @@ fn callExpr(
34593539 return rvalue(mod, scope, rl, result); // TODO function call with result location
34603540}
34613541
3462fn suspendExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
3542fn suspendExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
34633543 const tree = scope.tree();
34643544 const src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]];
34653545
......@@ -3504,12 +3584,13 @@ fn suspendExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zi
35043584 }
35053585
35063586 const block = try addZIRInstBlock(mod, scope, src, .suspend_block, .{
3507 .instructions = try scope.arena().dupe(*zir.Inst, suspend_scope.instructions.items),
3587 .instructions = try scope.arena().dupe(zir.Inst.Ref, suspend_scope.instructions.items),
35083588 });
35093589 return &block.base;
35103590}
35113591
3512fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
3592fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
3593 if (true) @panic("TODO update for zir-memory-layout");
35133594 const tree = scope.tree();
35143595 var child_scope = Scope.Nosuspend{
35153596 .parent = scope,
......@@ -3520,7 +3601,8 @@ fn nosuspendExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Inde
35203601 return expr(mod, &child_scope.base, rl, tree.nodes.items(.data)[node].lhs);
35213602}
35223603
3523fn awaitExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
3604fn awaitExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!zir.Inst.Ref {
3605 if (true) @panic("TODO update for zir-memory-layout");
35243606 const tree = scope.tree();
35253607 const src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]];
35263608 const is_nosuspend = scope.getNosuspend() != null;
......@@ -3542,7 +3624,7 @@ fn awaitExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) I
35423624 return addZIRUnOp(mod, scope, src, if (is_nosuspend) .nosuspend_await else .@"await", operand);
35433625}
35443626
3545fn resumeExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
3627fn resumeExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!zir.Inst.Ref {
35463628 const tree = scope.tree();
35473629 const src = tree.tokens.items(.start)[tree.nodes.items(.main_token)[node]];
35483630
......@@ -3828,7 +3910,7 @@ fn rvalue(
38283910 // We need a pointer but we have a value.
38293911 const tree = scope.tree();
38303912 const src_token = tree.firstToken(src_node);
3831 return gz.addUnTok(.ref, result, src_tok);
3913 return gz.addUnTok(.ref, result, src_token);
38323914 },
38333915 .ty => |ty_inst| return gz.addBin(.as, ty_inst, result),
38343916 .ptr => |ptr_inst| {
......@@ -3844,31 +3926,12 @@ fn rvalue(
38443926 },
38453927 .block_ptr => |block_scope| {
38463928 block_scope.rvalue_rl_count += 1;
3847 _ = try gz.addBin(.store_to_block_ptr, block_scope.rl_ptr.?, result);
3929 _ = try gz.addBin(.store_to_block_ptr, block_scope.rl_ptr, result);
38483930 return result;
38493931 },
38503932 }
38513933}
38523934
3853/// TODO when reworking ZIR memory layout, make the void value correspond to a hard coded
3854/// index; that way this does not actually need to allocate anything.
3855fn rvalueVoid(
3856 mod: *Module,
3857 scope: *Scope,
3858 rl: ResultLoc,
3859 node: ast.Node.Index,
3860 result: void,
3861) InnerError!*zir.Inst {
3862 const tree = scope.tree();
3863 const main_tokens = tree.nodes.items(.main_token);
3864 const src = tree.tokens.items(.start)[tree.firstToken(node)];
3865 const void_inst = try addZIRInstConst(mod, scope, src, .{
3866 .ty = Type.initTag(.void),
3867 .val = Value.initTag(.void_value),
3868 });
3869 return rvalue(mod, scope, rl, void_inst);
3870}
3871
38723935fn rlStrategy(rl: ResultLoc, block_scope: *Scope.GenZir) ResultLoc.Strategy {
38733936 var elide_store_to_block_ptr_instructions = false;
38743937 switch (rl) {
......@@ -3953,190 +4016,3 @@ fn setBlockResultLoc(block_scope: *Scope.GenZir, parent_rl: ResultLoc) void {
39534016 },
39544017 }
39554018}
3956
3957pub fn addZirInstTag(
3958 mod: *Module,
3959 scope: *Scope,
3960 src: usize,
3961 comptime tag: zir.Inst.Tag,
3962 positionals: std.meta.fieldInfo(tag.Type(), .positionals).field_type,
3963) !*zir.Inst {
3964 const gen_zir = scope.getGenZir();
3965 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
3966 const inst = try gen_zir.arena.create(tag.Type());
3967 inst.* = .{
3968 .base = .{
3969 .tag = tag,
3970 .src = src,
3971 },
3972 .positionals = positionals,
3973 .kw_args = .{},
3974 };
3975 gen_zir.instructions.appendAssumeCapacity(&inst.base);
3976 return &inst.base;
3977}
3978
3979pub fn addZirInstT(
3980 mod: *Module,
3981 scope: *Scope,
3982 src: usize,
3983 comptime T: type,
3984 tag: zir.Inst.Tag,
3985 positionals: std.meta.fieldInfo(T, .positionals).field_type,
3986) !*T {
3987 const gen_zir = scope.getGenZir();
3988 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
3989 const inst = try gen_zir.arena.create(T);
3990 inst.* = .{
3991 .base = .{
3992 .tag = tag,
3993 .src = src,
3994 },
3995 .positionals = positionals,
3996 .kw_args = .{},
3997 };
3998 gen_zir.instructions.appendAssumeCapacity(&inst.base);
3999 return inst;
4000}
4001
4002pub fn addZIRInstSpecial(
4003 mod: *Module,
4004 scope: *Scope,
4005 src: usize,
4006 comptime T: type,
4007 positionals: std.meta.fieldInfo(T, .positionals).field_type,
4008 kw_args: std.meta.fieldInfo(T, .kw_args).field_type,
4009) !*T {
4010 const gen_zir = scope.getGenZir();
4011 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
4012 const inst = try gen_zir.arena.create(T);
4013 inst.* = .{
4014 .base = .{
4015 .tag = T.base_tag,
4016 .src = src,
4017 },
4018 .positionals = positionals,
4019 .kw_args = kw_args,
4020 };
4021 gen_zir.instructions.appendAssumeCapacity(&inst.base);
4022 return inst;
4023}
4024
4025pub fn addZIRNoOpT(mod: *Module, scope: *Scope, src: usize, tag: zir.Inst.Tag) !*zir.Inst.NoOp {
4026 const gen_zir = scope.getGenZir();
4027 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
4028 const inst = try gen_zir.arena.create(zir.Inst.NoOp);
4029 inst.* = .{
4030 .base = .{
4031 .tag = tag,
4032 .src = src,
4033 },
4034 .positionals = .{},
4035 .kw_args = .{},
4036 };
4037 gen_zir.instructions.appendAssumeCapacity(&inst.base);
4038 return inst;
4039}
4040
4041pub fn addZIRNoOp(mod: *Module, scope: *Scope, src: usize, tag: zir.Inst.Tag) !*zir.Inst {
4042 const inst = try addZIRNoOpT(mod, scope, src, tag);
4043 return &inst.base;
4044}
4045
4046pub fn addZIRUnOp(
4047 mod: *Module,
4048 scope: *Scope,
4049 src: usize,
4050 tag: zir.Inst.Tag,
4051 operand: *zir.Inst,
4052) !*zir.Inst {
4053 const gen_zir = scope.getGenZir();
4054 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
4055 const inst = try gen_zir.arena.create(zir.Inst.UnOp);
4056 inst.* = .{
4057 .base = .{
4058 .tag = tag,
4059 .src = src,
4060 },
4061 .positionals = .{
4062 .operand = operand,
4063 },
4064 .kw_args = .{},
4065 };
4066 gen_zir.instructions.appendAssumeCapacity(&inst.base);
4067 return &inst.base;
4068}
4069
4070pub fn addZIRBinOp(
4071 mod: *Module,
4072 scope: *Scope,
4073 src: usize,
4074 tag: zir.Inst.Tag,
4075 lhs: *zir.Inst,
4076 rhs: *zir.Inst,
4077) !*zir.Inst {
4078 const gen_zir = scope.getGenZir();
4079 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
4080 const inst = try gen_zir.arena.create(zir.Inst.BinOp);
4081 inst.* = .{
4082 .base = .{
4083 .tag = tag,
4084 .src = src,
4085 },
4086 .positionals = .{
4087 .lhs = lhs,
4088 .rhs = rhs,
4089 },
4090 .kw_args = .{},
4091 };
4092 gen_zir.instructions.appendAssumeCapacity(&inst.base);
4093 return &inst.base;
4094}
4095
4096pub fn addZIRInstBlock(
4097 mod: *Module,
4098 scope: *Scope,
4099 src: usize,
4100 tag: zir.Inst.Tag,
4101 body: zir.Body,
4102) !*zir.Inst.Block {
4103 const gen_zir = scope.getGenZir();
4104 try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
4105 const inst = try gen_zir.arena.create(zir.Inst.Block);
4106 inst.* = .{
4107 .base = .{
4108 .tag = tag,
4109 .src = src,
4110 },
4111 .positionals = .{
4112 .body = body,
4113 },
4114 .kw_args = .{},
4115 };
4116 gen_zir.instructions.appendAssumeCapacity(&inst.base);
4117 return inst;
4118}
4119
4120pub fn addZIRInst(
4121 mod: *Module,
4122 scope: *Scope,
4123 src: usize,
4124 comptime T: type,
4125 positionals: std.meta.fieldInfo(T, .positionals).field_type,
4126 kw_args: std.meta.fieldInfo(T, .kw_args).field_type,
4127) !*zir.Inst {
4128 const inst_special = try addZIRInstSpecial(mod, scope, src, T, positionals, kw_args);
4129 return &inst_special.base;
4130}
4131
4132/// TODO The existence of this function is a workaround for a bug in stage1.
4133pub fn addZIRInstConst(mod: *Module, scope: *Scope, src: usize, typed_value: TypedValue) !*zir.Inst {
4134 const P = std.meta.fieldInfo(zir.Inst.Const, .positionals).field_type;
4135 return addZIRInst(mod, scope, src, zir.Inst.Const, P{ .typed_value = typed_value }, .{});
4136}
4137
4138/// TODO The existence of this function is a workaround for a bug in stage1.
4139pub fn addZIRInstLoop(mod: *Module, scope: *Scope, src: usize, body: zir.Body) !*zir.Inst.Loop {
4140 const P = std.meta.fieldInfo(zir.Inst.Loop, .positionals).field_type;
4141 return addZIRInstSpecial(mod, scope, src, zir.Inst.Loop, P{ .body = body }, .{});
4142}
src/codegen.zig+2-2
......@@ -499,7 +499,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
499499 defer function.stack.deinit(bin_file.allocator);
500500 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
501501
502 var call_info = function.resolveCallingConventionValues(src_loc.byte_offset, fn_type) catch |err| switch (err) {
502 var call_info = function.resolveCallingConventionValues(src_loc.lazy, fn_type) catch |err| switch (err) {
503503 error.CodegenFail => return Result{ .fail = function.err_msg.? },
504504 else => |e| return e,
505505 };
......@@ -2850,7 +2850,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28502850 return self.fail(inst.base.src, "TODO implement support for more x86 assembly instructions", .{});
28512851 }
28522852
2853 if (inst.output) |output| {
2853 if (inst.output_name) |output| {
28542854 if (output.len < 4 or output[0] != '=' or output[1] != '{' or output[output.len - 1] != '}') {
28552855 return self.fail(inst.base.src, "unrecognized asm output constraint: '{s}'", .{output});
28562856 }
src/codegen/c.zig+16-16
......@@ -14,6 +14,7 @@ const TypedValue = @import("../TypedValue.zig");
1414const C = link.File.C;
1515const Decl = Module.Decl;
1616const trace = @import("../tracy.zig").trace;
17const LazySrcLoc = Module.LazySrcLoc;
1718
1819const Mutability = enum { Const, Mut };
1920
......@@ -145,11 +146,10 @@ pub const DeclGen = struct {
145146 error_msg: ?*Module.ErrorMsg,
146147 typedefs: TypedefMap,
147148
148 fn fail(dg: *DeclGen, src: usize, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
149 dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, .{
150 .file_scope = dg.decl.getFileScope(),
151 .byte_offset = src,
152 }, format, args);
149 fn fail(dg: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } {
150 @setCold(true);
151 const src_loc = src.toSrcLocWithDecl(dg.decl);
152 dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args);
153153 return error.AnalysisFail;
154154 }
155155
......@@ -160,7 +160,7 @@ pub const DeclGen = struct {
160160 val: Value,
161161 ) error{ OutOfMemory, AnalysisFail }!void {
162162 if (val.isUndef()) {
163 return dg.fail(dg.decl.src(), "TODO: C backend: properly handle undefined in all cases (with debug safety?)", .{});
163 return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: properly handle undefined in all cases (with debug safety?)", .{});
164164 }
165165 switch (t.zigTypeTag()) {
166166 .Int => {
......@@ -193,7 +193,7 @@ pub const DeclGen = struct {
193193 try writer.print("{s}", .{decl.name});
194194 },
195195 else => |e| return dg.fail(
196 dg.decl.src(),
196 .{ .node_offset = 0 },
197197 "TODO: C backend: implement Pointer value {s}",
198198 .{@tagName(e)},
199199 ),
......@@ -276,7 +276,7 @@ pub const DeclGen = struct {
276276 try writer.writeAll(", .error = 0 }");
277277 }
278278 },
279 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{
279 else => |e| return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement value {s}", .{
280280 @tagName(e),
281281 }),
282282 }
......@@ -350,7 +350,7 @@ pub const DeclGen = struct {
350350 break;
351351 }
352352 } else {
353 return dg.fail(dg.decl.src(), "TODO: C backend: implement integer types larger than 128 bits", .{});
353 return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement integer types larger than 128 bits", .{});
354354 }
355355 },
356356 else => unreachable,
......@@ -358,7 +358,7 @@ pub const DeclGen = struct {
358358 },
359359 .Pointer => {
360360 if (t.isSlice()) {
361 return dg.fail(dg.decl.src(), "TODO: C backend: implement slices", .{});
361 return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement slices", .{});
362362 } else {
363363 try dg.renderType(w, t.elemType());
364364 try w.writeAll(" *");
......@@ -431,7 +431,7 @@ pub const DeclGen = struct {
431431 dg.typedefs.putAssumeCapacityNoClobber(t, .{ .name = name, .rendered = rendered });
432432 },
433433 .Null, .Undefined => unreachable, // must be const or comptime
434 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{
434 else => |e| return dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement type {s}", .{
435435 @tagName(e),
436436 }),
437437 }
......@@ -575,7 +575,7 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi
575575 .unwrap_errunion_err_ptr => try genUnwrapErrUnionErr(o, inst.castTag(.unwrap_errunion_err_ptr).?),
576576 .wrap_errunion_payload => try genWrapErrUnionPay(o, inst.castTag(.wrap_errunion_payload).?),
577577 .wrap_errunion_err => try genWrapErrUnionErr(o, inst.castTag(.wrap_errunion_err).?),
578 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
578 else => |e| return o.dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement codegen for {}", .{e}),
579579 };
580580 switch (result_value) {
581581 .none => {},
......@@ -756,7 +756,7 @@ fn genCall(o: *Object, inst: *Inst.Call) !CValue {
756756 try writer.writeAll(");\n");
757757 return result_local;
758758 } else {
759 return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement function pointers", .{});
759 return o.dg.fail(.{ .node_offset = 0 }, "TODO: C backend: implement function pointers", .{});
760760 }
761761}
762762
......@@ -913,13 +913,13 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
913913 try o.writeCValue(writer, arg_c_value);
914914 try writer.writeAll(";\n");
915915 } else {
916 return o.dg.fail(o.dg.decl.src(), "TODO non-explicit inline asm regs", .{});
916 return o.dg.fail(.{ .node_offset = 0 }, "TODO non-explicit inline asm regs", .{});
917917 }
918918 }
919919 const volatile_string: []const u8 = if (as.is_volatile) "volatile " else "";
920920 try writer.print("__asm {s}(\"{s}\"", .{ volatile_string, as.asm_source });
921921 if (as.output) |_| {
922 return o.dg.fail(o.dg.decl.src(), "TODO inline asm output", .{});
922 return o.dg.fail(.{ .node_offset = 0 }, "TODO inline asm output", .{});
923923 }
924924 if (as.inputs.len > 0) {
925925 if (as.output == null) {
......@@ -945,7 +945,7 @@ fn genAsm(o: *Object, as: *Inst.Assembly) !CValue {
945945 if (as.base.isUnused())
946946 return CValue.none;
947947
948 return o.dg.fail(o.dg.decl.src(), "TODO: C backend: inline asm expression result used", .{});
948 return o.dg.fail(.{ .node_offset = 0 }, "TODO: C backend: inline asm expression result used", .{});
949949}
950950
951951fn genIsNull(o: *Object, inst: *Inst.UnOp) !CValue {
src/codegen/wasm.zig+9-10
......@@ -14,6 +14,7 @@ const Type = @import("../type.zig").Type;
1414const Value = @import("../value.zig").Value;
1515const Compilation = @import("../Compilation.zig");
1616const AnyMCValue = @import("../codegen.zig").AnyMCValue;
17const LazySrcLoc = Module.LazySrcLoc;
1718
1819/// Wasm Value, created when generating an instruction
1920const WValue = union(enum) {
......@@ -70,11 +71,9 @@ pub const Context = struct {
7071 }
7172
7273 /// Sets `err_msg` on `Context` and returns `error.CodegemFail` which is caught in link/Wasm.zig
73 fn fail(self: *Context, src: usize, comptime fmt: []const u8, args: anytype) InnerError {
74 self.err_msg = try Module.ErrorMsg.create(self.gpa, .{
75 .file_scope = self.decl.getFileScope(),
76 .byte_offset = src,
77 }, fmt, args);
74 fn fail(self: *Context, src: LazySrcLoc, comptime fmt: []const u8, args: anytype) InnerError {
75 const src_loc = src.toSrcLocWithDecl(self.decl);
76 self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, fmt, args);
7877 return error.CodegenFail;
7978 }
8079
......@@ -91,7 +90,7 @@ pub const Context = struct {
9190 }
9291
9392 /// Using a given `Type`, returns the corresponding wasm value type
94 fn genValtype(self: *Context, src: usize, ty: Type) InnerError!u8 {
93 fn genValtype(self: *Context, src: LazySrcLoc, ty: Type) InnerError!u8 {
9594 return switch (ty.tag()) {
9695 .f32 => wasm.valtype(.f32),
9796 .f64 => wasm.valtype(.f64),
......@@ -104,7 +103,7 @@ pub const Context = struct {
104103 /// Using a given `Type`, returns the corresponding wasm value type
105104 /// Differently from `genValtype` this also allows `void` to create a block
106105 /// with no return type
107 fn genBlockType(self: *Context, src: usize, ty: Type) InnerError!u8 {
106 fn genBlockType(self: *Context, src: LazySrcLoc, ty: Type) InnerError!u8 {
108107 return switch (ty.tag()) {
109108 .void, .noreturn => wasm.block_empty,
110109 else => self.genValtype(src, ty),
......@@ -139,7 +138,7 @@ pub const Context = struct {
139138 ty.fnParamTypes(params);
140139 for (params) |param_type| {
141140 // Can we maybe get the source index of each param?
142 const val_type = try self.genValtype(self.decl.src(), param_type);
141 const val_type = try self.genValtype(.{ .node_offset = 0 }, param_type);
143142 try writer.writeByte(val_type);
144143 }
145144 }
......@@ -151,7 +150,7 @@ pub const Context = struct {
151150 else => |ret_type| {
152151 try leb.writeULEB128(writer, @as(u32, 1));
153152 // Can we maybe get the source index of the return type?
154 const val_type = try self.genValtype(self.decl.src(), return_type);
153 const val_type = try self.genValtype(.{ .node_offset = 0 }, return_type);
155154 try writer.writeByte(val_type);
156155 },
157156 }
......@@ -168,7 +167,7 @@ pub const Context = struct {
168167 const mod_fn = blk: {
169168 if (tv.val.castTag(.function)) |func| break :blk func.data;
170169 if (tv.val.castTag(.extern_fn)) |ext_fn| return; // don't need codegen for extern functions
171 return self.fail(self.decl.src(), "TODO: Wasm codegen for decl type '{s}'", .{tv.ty.tag()});
170 return self.fail(.{ .node_offset = 0 }, "TODO: Wasm codegen for decl type '{s}'", .{tv.ty.tag()});
172171 };
173172
174173 // Reserve space to write the size after generating the code as well as space for locals count
src/type.zig+1-1
......@@ -3150,7 +3150,7 @@ pub const Type = extern union {
31503150 => unreachable,
31513151
31523152 .empty_struct => self.castTag(.empty_struct).?.data,
3153 .@"opaque" => &self.castTag(.@"opaque").?.scope,
3153 .@"opaque" => &self.castTag(.@"opaque").?.data,
31543154 };
31553155 }
31563156
src/zir.zig+127-121
......@@ -35,7 +35,7 @@ pub const Code = struct {
3535 extra: []u32,
3636 /// First ZIR instruction in this `Code`.
3737 /// `extra` at this index contains a `Ref` for every root member.
38 root_start: Inst.Index,
38 root_start: u32,
3939 /// Number of ZIR instructions in the implicit root block of the `Code`.
4040 root_len: u32,
4141
......@@ -138,204 +138,205 @@ pub const Const = enum {
138138 bool_false,
139139};
140140
141pub const const_inst_list = enumArray(Const, .{
142 .u8_type = @as(TypedValue, .{
141pub const const_inst_list = std.enums.directEnumArray(Const, TypedValue, 0, .{
142 .unused = undefined,
143 .u8_type = .{
143144 .ty = Type.initTag(.type),
144145 .val = Value.initTag(.u8_type),
145 }),
146 .i8_type = @as(TypedValue, .{
146 },
147 .i8_type = .{
147148 .ty = Type.initTag(.type),
148149 .val = Value.initTag(.i8_type),
149 }),
150 .u16_type = @as(TypedValue, .{
150 },
151 .u16_type = .{
151152 .ty = Type.initTag(.type),
152153 .val = Value.initTag(.u16_type),
153 }),
154 .i16_type = @as(TypedValue, .{
154 },
155 .i16_type = .{
155156 .ty = Type.initTag(.type),
156157 .val = Value.initTag(.i16_type),
157 }),
158 .u32_type = @as(TypedValue, .{
158 },
159 .u32_type = .{
159160 .ty = Type.initTag(.type),
160161 .val = Value.initTag(.u32_type),
161 }),
162 .i32_type = @as(TypedValue, .{
162 },
163 .i32_type = .{
163164 .ty = Type.initTag(.type),
164165 .val = Value.initTag(.i32_type),
165 }),
166 .u64_type = @as(TypedValue, .{
166 },
167 .u64_type = .{
167168 .ty = Type.initTag(.type),
168169 .val = Value.initTag(.u64_type),
169 }),
170 .i64_type = @as(TypedValue, .{
170 },
171 .i64_type = .{
171172 .ty = Type.initTag(.type),
172173 .val = Value.initTag(.i64_type),
173 }),
174 .usize_type = @as(TypedValue, .{
174 },
175 .usize_type = .{
175176 .ty = Type.initTag(.type),
176177 .val = Value.initTag(.usize_type),
177 }),
178 .isize_type = @as(TypedValue, .{
178 },
179 .isize_type = .{
179180 .ty = Type.initTag(.type),
180181 .val = Value.initTag(.isize_type),
181 }),
182 .c_short_type = @as(TypedValue, .{
182 },
183 .c_short_type = .{
183184 .ty = Type.initTag(.type),
184185 .val = Value.initTag(.c_short_type),
185 }),
186 .c_ushort_type = @as(TypedValue, .{
186 },
187 .c_ushort_type = .{
187188 .ty = Type.initTag(.type),
188189 .val = Value.initTag(.c_ushort_type),
189 }),
190 .c_int_type = @as(TypedValue, .{
190 },
191 .c_int_type = .{
191192 .ty = Type.initTag(.type),
192193 .val = Value.initTag(.c_int_type),
193 }),
194 .c_uint_type = @as(TypedValue, .{
194 },
195 .c_uint_type = .{
195196 .ty = Type.initTag(.type),
196197 .val = Value.initTag(.c_uint_type),
197 }),
198 .c_long_type = @as(TypedValue, .{
198 },
199 .c_long_type = .{
199200 .ty = Type.initTag(.type),
200201 .val = Value.initTag(.c_long_type),
201 }),
202 .c_ulong_type = @as(TypedValue, .{
202 },
203 .c_ulong_type = .{
203204 .ty = Type.initTag(.type),
204205 .val = Value.initTag(.c_ulong_type),
205 }),
206 .c_longlong_type = @as(TypedValue, .{
206 },
207 .c_longlong_type = .{
207208 .ty = Type.initTag(.type),
208209 .val = Value.initTag(.c_longlong_type),
209 }),
210 .c_ulonglong_type = @as(TypedValue, .{
210 },
211 .c_ulonglong_type = .{
211212 .ty = Type.initTag(.type),
212213 .val = Value.initTag(.c_ulonglong_type),
213 }),
214 .c_longdouble_type = @as(TypedValue, .{
214 },
215 .c_longdouble_type = .{
215216 .ty = Type.initTag(.type),
216217 .val = Value.initTag(.c_longdouble_type),
217 }),
218 .f16_type = @as(TypedValue, .{
218 },
219 .f16_type = .{
219220 .ty = Type.initTag(.type),
220221 .val = Value.initTag(.f16_type),
221 }),
222 .f32_type = @as(TypedValue, .{
222 },
223 .f32_type = .{
223224 .ty = Type.initTag(.type),
224225 .val = Value.initTag(.f32_type),
225 }),
226 .f64_type = @as(TypedValue, .{
226 },
227 .f64_type = .{
227228 .ty = Type.initTag(.type),
228229 .val = Value.initTag(.f64_type),
229 }),
230 .f128_type = @as(TypedValue, .{
230 },
231 .f128_type = .{
231232 .ty = Type.initTag(.type),
232233 .val = Value.initTag(.f128_type),
233 }),
234 .c_void_type = @as(TypedValue, .{
234 },
235 .c_void_type = .{
235236 .ty = Type.initTag(.type),
236237 .val = Value.initTag(.c_void_type),
237 }),
238 .bool_type = @as(TypedValue, .{
238 },
239 .bool_type = .{
239240 .ty = Type.initTag(.type),
240241 .val = Value.initTag(.bool_type),
241 }),
242 .void_type = @as(TypedValue, .{
242 },
243 .void_type = .{
243244 .ty = Type.initTag(.type),
244245 .val = Value.initTag(.void_type),
245 }),
246 .type_type = @as(TypedValue, .{
246 },
247 .type_type = .{
247248 .ty = Type.initTag(.type),
248249 .val = Value.initTag(.type_type),
249 }),
250 .anyerror_type = @as(TypedValue, .{
250 },
251 .anyerror_type = .{
251252 .ty = Type.initTag(.type),
252253 .val = Value.initTag(.anyerror_type),
253 }),
254 .comptime_int_type = @as(TypedValue, .{
254 },
255 .comptime_int_type = .{
255256 .ty = Type.initTag(.type),
256257 .val = Value.initTag(.comptime_int_type),
257 }),
258 .comptime_float_type = @as(TypedValue, .{
258 },
259 .comptime_float_type = .{
259260 .ty = Type.initTag(.type),
260261 .val = Value.initTag(.comptime_float_type),
261 }),
262 .noreturn_type = @as(TypedValue, .{
262 },
263 .noreturn_type = .{
263264 .ty = Type.initTag(.type),
264265 .val = Value.initTag(.noreturn_type),
265 }),
266 .null_type = @as(TypedValue, .{
266 },
267 .null_type = .{
267268 .ty = Type.initTag(.type),
268269 .val = Value.initTag(.null_type),
269 }),
270 .undefined_type = @as(TypedValue, .{
270 },
271 .undefined_type = .{
271272 .ty = Type.initTag(.type),
272273 .val = Value.initTag(.undefined_type),
273 }),
274 .fn_noreturn_no_args_type = @as(TypedValue, .{
274 },
275 .fn_noreturn_no_args_type = .{
275276 .ty = Type.initTag(.type),
276277 .val = Value.initTag(.fn_noreturn_no_args_type),
277 }),
278 .fn_void_no_args_type = @as(TypedValue, .{
278 },
279 .fn_void_no_args_type = .{
279280 .ty = Type.initTag(.type),
280281 .val = Value.initTag(.fn_void_no_args_type),
281 }),
282 .fn_naked_noreturn_no_args_type = @as(TypedValue, .{
282 },
283 .fn_naked_noreturn_no_args_type = .{
283284 .ty = Type.initTag(.type),
284285 .val = Value.initTag(.fn_naked_noreturn_no_args_type),
285 }),
286 .fn_ccc_void_no_args_type = @as(TypedValue, .{
286 },
287 .fn_ccc_void_no_args_type = .{
287288 .ty = Type.initTag(.type),
288289 .val = Value.initTag(.fn_ccc_void_no_args_type),
289 }),
290 .single_const_pointer_to_comptime_int_type = @as(TypedValue, .{
290 },
291 .single_const_pointer_to_comptime_int_type = .{
291292 .ty = Type.initTag(.type),
292293 .val = Value.initTag(.single_const_pointer_to_comptime_int_type),
293 }),
294 .const_slice_u8_type = @as(TypedValue, .{
294 },
295 .const_slice_u8_type = .{
295296 .ty = Type.initTag(.type),
296297 .val = Value.initTag(.const_slice_u8_type),
297 }),
298 .enum_literal_type = @as(TypedValue, .{
298 },
299 .enum_literal_type = .{
299300 .ty = Type.initTag(.type),
300301 .val = Value.initTag(.enum_literal_type),
301 }),
302 .anyframe_type = @as(TypedValue, .{
302 },
303 .anyframe_type = .{
303304 .ty = Type.initTag(.type),
304305 .val = Value.initTag(.anyframe_type),
305 }),
306 },
306307
307 .undef = @as(TypedValue, .{
308 .undef = .{
308309 .ty = Type.initTag(.@"undefined"),
309310 .val = Value.initTag(.undef),
310 }),
311 .zero = @as(TypedValue, .{
311 },
312 .zero = .{
312313 .ty = Type.initTag(.comptime_int),
313314 .val = Value.initTag(.zero),
314 }),
315 .one = @as(TypedValue, .{
315 },
316 .one = .{
316317 .ty = Type.initTag(.comptime_int),
317318 .val = Value.initTag(.one),
318 }),
319 .void_value = @as(TypedValue, .{
319 },
320 .void_value = .{
320321 .ty = Type.initTag(.void),
321322 .val = Value.initTag(.void_value),
322 }),
323 .unreachable_value = @as(TypedValue, .{
323 },
324 .unreachable_value = .{
324325 .ty = Type.initTag(.noreturn),
325326 .val = Value.initTag(.unreachable_value),
326 }),
327 .null_value = @as(TypedValue, .{
327 },
328 .null_value = .{
328329 .ty = Type.initTag(.@"null"),
329330 .val = Value.initTag(.null_value),
330 }),
331 .bool_true = @as(TypedValue, .{
331 },
332 .bool_true = .{
332333 .ty = Type.initTag(.bool),
333334 .val = Value.initTag(.bool_true),
334 }),
335 .bool_false = @as(TypedValue, .{
335 },
336 .bool_false = .{
336337 .ty = Type.initTag(.bool),
337338 .val = Value.initTag(.bool_false),
338 }),
339 },
339340});
340341
341342/// These are untyped instructions generated from an Abstract Syntax Tree.
......@@ -633,7 +634,7 @@ pub const Inst = struct {
633634 /// Sends control flow back to the function's callee.
634635 /// Includes an operand as the return value.
635636 /// Includes a token source location.
636 /// Uses the un_tok union field.
637 /// Uses the `un_tok` union field.
637638 ret_tok,
638639 /// Changes the maximum number of backwards branches that compile-time
639640 /// code execution can use before giving up and making a compile error.
......@@ -755,6 +756,9 @@ pub const Inst = struct {
755756 ensure_err_payload_void,
756757 /// An enum literal. Uses the `str_tok` union field.
757758 enum_literal,
759 /// An enum literal 8 or fewer bytes. No source location.
760 /// Uses the `small_str` field.
761 enum_literal_small,
758762 /// Suspend an async function. The suspend block has 0 or 1 statements in it.
759763 /// Uses the `un_node` union field.
760764 suspend_block_one,
......@@ -816,6 +820,7 @@ pub const Inst = struct {
816820 .indexable_ptr_len,
817821 .as,
818822 .@"asm",
823 .asm_volatile,
819824 .bit_and,
820825 .bitcast,
821826 .bitcast_ref,
......@@ -831,12 +836,9 @@ pub const Inst = struct {
831836 .breakpoint,
832837 .call,
833838 .call_async_kw,
834 .call_never_tail,
835 .call_never_inline,
836839 .call_no_async,
837 .call_always_tail,
838 .call_always_inline,
839840 .call_compile_time,
841 .call_none,
840842 .cmp_lt,
841843 .cmp_lte,
842844 .cmp_eq,
......@@ -845,13 +847,15 @@ pub const Inst = struct {
845847 .cmp_neq,
846848 .coerce_result_ptr,
847849 .@"const",
848 .dbg_stmt,
850 .dbg_stmt_node,
849851 .decl_ref,
850852 .decl_val,
851853 .deref_node,
852854 .div,
853855 .elem_ptr,
854856 .elem_val,
857 .elem_ptr_node,
858 .elem_val_node,
855859 .ensure_result_used,
856860 .ensure_result_non_error,
857861 .floatcast,
......@@ -882,14 +886,6 @@ pub const Inst = struct {
882886 .ret_type,
883887 .shl,
884888 .shr,
885 .single_const_ptr_type,
886 .single_mut_ptr_type,
887 .many_const_ptr_type,
888 .many_mut_ptr_type,
889 .c_const_ptr_type,
890 .c_mut_ptr_type,
891 .mut_slice_type,
892 .const_slice_type,
893889 .store,
894890 .store_to_block_ptr,
895891 .store_to_inferred_ptr,
......@@ -914,20 +910,21 @@ pub const Inst = struct {
914910 .ptr_type_simple,
915911 .ensure_err_payload_void,
916912 .enum_literal,
913 .enum_literal_small,
917914 .merge_error_sets,
918915 .anyframe_type,
919916 .error_union_type,
920917 .bit_not,
921918 .error_set,
922919 .error_value,
923 .slice,
924920 .slice_start,
921 .slice_end,
922 .slice_sentinel,
925923 .import,
926924 .typeof_peer,
927925 .resolve_inferred_alloc,
928926 .set_eval_branch_quota,
929927 .compile_log,
930 .switch_range,
931928 .@"resume",
932929 .@"await",
933930 .nosuspend_await,
......@@ -942,11 +939,8 @@ pub const Inst = struct {
942939 .unreachable_unsafe,
943940 .unreachable_safe,
944941 .loop,
945 .container_field_named,
946 .container_field_typed,
947 .container_field,
948 .@"suspend",
949942 .suspend_block,
943 .suspend_block_one,
950944 => true,
951945 };
952946 }
......@@ -1017,6 +1011,17 @@ pub const Inst = struct {
10171011 return code.string_bytes[self.start..][0..self.len];
10181012 }
10191013 },
1014 /// Strings 8 or fewer bytes which may not contain null bytes.
1015 small_str: struct {
1016 bytes: [8]u8,
1017
1018 pub fn get(self: @This()) []const u8 {
1019 const end = for (self.bytes) |byte, i| {
1020 if (byte == 0) break i;
1021 } else self.bytes.len;
1022 return self.bytes[0..end];
1023 }
1024 },
10201025 str_tok: struct {
10211026 /// Offset into `string_bytes`. Null-terminated.
10221027 start: u32,
......@@ -1205,7 +1210,8 @@ pub const Inst = struct {
12051210};
12061211
12071212/// For debugging purposes, like dumpFn but for unanalyzed zir blocks
1208pub fn dumpZir(gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8, instructions: []*Inst) !void {
1213pub fn dumpZir(gpa: *Allocator, kind: []const u8, decl_name: [*:0]const u8, code: Code) !void {
1214 if (true) @panic("TODO fix this function for zir-memory-layout branch");
12091215 var fib = std.heap.FixedBufferAllocator.init(&[_]u8{});
12101216 var module = Module{
12111217 .decls = &[_]*Module.Decl{},