authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-12 23:47:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-12 23:47:17-07:00
log7630a5c566b106b6325a55f29eb1ed9e584d0949
treebacdef35e7f63bc6e9ce3fcedcd05e29ed01b453
parenta9db40e8704bd4f87b0770e2d72ba05b94afad1e

stage2: more progress towards Module/astgen building with new mem layout


8 files changed, 791 insertions(+), 595 deletions(-)

lib/std/zig/ast.zig+2
...@@ -2834,10 +2834,12 @@ pub const Node = struct {...@@ -2834,10 +2834,12 @@ pub const Node = struct {
2834 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.2834 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
2835 grouped_expression,2835 grouped_expression,
2836 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.2836 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2837 /// main_token is the builtin token.
2837 builtin_call_two,2838 builtin_call_two,
2838 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.2839 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
2839 builtin_call_two_comma,2840 builtin_call_two_comma,
2840 /// `@a(b, c)`. `sub_list[lhs..rhs]`.2841 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2842 /// main_token is the builtin token.
2841 builtin_call,2843 builtin_call,
2842 /// Same as builtin_call but there is known to be a trailing comma before the rparen.2844 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
2843 builtin_call_comma,2845 builtin_call_comma,
src/Module.zig+212-150
...@@ -428,14 +428,14 @@ pub const Scope = struct {...@@ -428,14 +428,14 @@ pub const Scope = struct {
428 }428 }
429429
430 /// Asserts the scope is a child of a File and has an AST tree and returns the tree.430 /// Asserts the scope is a child of a File and has an AST tree and returns the tree.
431 pub fn tree(self: *Scope) *ast.Tree {431 pub fn tree(self: *Scope) *const ast.Tree {
432 switch (self.tag) {432 switch (self.tag) {
433 .file => return self.cast(File).?.contents.tree,433 .file => return self.cast(File).?.tree,
434 .block => return self.cast(Block).?.src_decl.container.file_scope.contents.tree,434 .block => return self.cast(Block).?.src_decl.container.file_scope.tree,
435 .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.contents.tree,435 .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.tree,
436 .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.contents.tree,436 .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.contents.tree,437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
438 .container => return self.cast(Container).?.file_scope.contents.tree,438 .container => return self.cast(Container).?.file_scope.tree,
439 }439 }
440 }440 }
441441
...@@ -1008,38 +1008,38 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -1008,38 +1008,38 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
1008 switch (node_tags[fn_proto]) {1008 switch (node_tags[fn_proto]) {
1009 .fn_proto_simple => {1009 .fn_proto_simple => {
1010 var params: [1]ast.Node.Index = undefined;1010 var params: [1]ast.Node.Index = undefined;
1011 return mod.astgenAndSemaFn(decl, tree, body, tree.fnProtoSimple(&params, fn_proto));1011 return mod.astgenAndSemaFn(decl, tree.*, body, tree.fnProtoSimple(&params, fn_proto));
1012 },1012 },
1013 .fn_proto_multi => return mod.astgenAndSemaFn(decl, tree, body, tree.fnProtoMulti(fn_proto)),1013 .fn_proto_multi => return mod.astgenAndSemaFn(decl, tree.*, body, tree.fnProtoMulti(fn_proto)),
1014 .fn_proto_one => {1014 .fn_proto_one => {
1015 var params: [1]ast.Node.Index = undefined;1015 var params: [1]ast.Node.Index = undefined;
1016 return mod.astgenAndSemaFn(decl, tree, body, tree.fnProtoOne(&params, fn_proto));1016 return mod.astgenAndSemaFn(decl, tree.*, body, tree.fnProtoOne(&params, fn_proto));
1017 },1017 },
1018 .fn_proto => return mod.astgenAndSemaFn(decl, tree, body, tree.fnProto(fn_proto)),1018 .fn_proto => return mod.astgenAndSemaFn(decl, tree.*, body, tree.fnProto(fn_proto)),
1019 else => unreachable,1019 else => unreachable,
1020 }1020 }
1021 },1021 },
1022 .fn_proto_simple => {1022 .fn_proto_simple => {
1023 var params: [1]ast.Node.Index = undefined;1023 var params: [1]ast.Node.Index = undefined;
1024 return mod.astgenAndSemaFn(decl, tree, null, tree.fnProtoSimple(&params, decl_node));1024 return mod.astgenAndSemaFn(decl, tree.*, 0, tree.fnProtoSimple(&params, decl_node));
1025 },1025 },
1026 .fn_proto_multi => return mod.astgenAndSemaFn(decl, tree, null, tree.fnProtoMulti(decl_node)),1026 .fn_proto_multi => return mod.astgenAndSemaFn(decl, tree.*, 0, tree.fnProtoMulti(decl_node)),
1027 .fn_proto_one => {1027 .fn_proto_one => {
1028 var params: [1]ast.Node.Index = undefined;1028 var params: [1]ast.Node.Index = undefined;
1029 return mod.astgenAndSemaFn(decl, tree, null, tree.fnProtoOne(&params, decl_node));1029 return mod.astgenAndSemaFn(decl, tree.*, 0, tree.fnProtoOne(&params, decl_node));
1030 },1030 },
1031 .fn_proto => return mod.astgenAndSemaFn(decl, tree, null, tree.fnProto(decl_node)),1031 .fn_proto => return mod.astgenAndSemaFn(decl, tree.*, 0, tree.fnProto(decl_node)),
10321032
1033 .global_var_decl => return mod.astgenAndSemaVarDecl(decl, tree, tree.globalVarDecl(decl_node)),1033 .global_var_decl => return mod.astgenAndSemaVarDecl(decl, tree.*, tree.globalVarDecl(decl_node)),
1034 .local_var_decl => return mod.astgenAndSemaVarDecl(decl, tree, tree.localVarDecl(decl_node)),1034 .local_var_decl => return mod.astgenAndSemaVarDecl(decl, tree.*, tree.localVarDecl(decl_node)),
1035 .simple_var_decl => return mod.astgenAndSemaVarDecl(decl, tree, tree.simpleVarDecl(decl_node)),1035 .simple_var_decl => return mod.astgenAndSemaVarDecl(decl, tree.*, tree.simpleVarDecl(decl_node)),
1036 .aligned_var_decl => return mod.astgenAndSemaVarDecl(decl, tree, tree.alignedVarDecl(decl_node)),1036 .aligned_var_decl => return mod.astgenAndSemaVarDecl(decl, tree.*, tree.alignedVarDecl(decl_node)),
10371037
1038 .@"comptime" => {1038 .@"comptime" => {
1039 decl.analysis = .in_progress;1039 decl.analysis = .in_progress;
10401040
1041 // A comptime decl does not store any value so we can just deinit this arena after analysis is done.1041 // A comptime decl does not store any value so we can just deinit this arena after analysis is done.
1042 var analysis_arena = std.heap.ArenaAllocator.init(self.gpa);1042 var analysis_arena = std.heap.ArenaAllocator.init(mod.gpa);
1043 defer analysis_arena.deinit();1043 defer analysis_arena.deinit();
1044 var gen_scope: Scope.GenZIR = .{1044 var gen_scope: Scope.GenZIR = .{
1045 .decl = decl,1045 .decl = decl,
...@@ -1047,14 +1047,15 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -1047,14 +1047,15 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
1047 .parent = &decl.container.base,1047 .parent = &decl.container.base,
1048 .force_comptime = true,1048 .force_comptime = true,
1049 };1049 };
1050 defer gen_scope.instructions.deinit(self.gpa);1050 defer gen_scope.instructions.deinit(mod.gpa);
10511051
1052 _ = try astgen.comptimeExpr(self, &gen_scope.base, .none, comptime_decl.expr);1052 const block_expr = node_datas[decl_node].lhs;
1053 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {1053 _ = try astgen.comptimeExpr(mod, &gen_scope.base, .none, block_expr);
1054 zir.dumpZir(self.gpa, "comptime_block", decl.name, gen_scope.instructions.items) catch {};1054 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1055 zir.dumpZir(mod.gpa, "comptime_block", decl.name, gen_scope.instructions.items) catch {};
1055 }1056 }
10561057
1057 var inst_table = Scope.Block.InstTable.init(self.gpa);1058 var inst_table = Scope.Block.InstTable.init(mod.gpa);
1058 defer inst_table.deinit();1059 defer inst_table.deinit();
10591060
1060 var branch_quota: u32 = default_eval_branch_quota;1061 var branch_quota: u32 = default_eval_branch_quota;
...@@ -1071,17 +1072,17 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {...@@ -1071,17 +1072,17 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
1071 .is_comptime = true,1072 .is_comptime = true,
1072 .branch_quota = &branch_quota,1073 .branch_quota = &branch_quota,
1073 };1074 };
1074 defer block_scope.instructions.deinit(self.gpa);1075 defer block_scope.instructions.deinit(mod.gpa);
10751076
1076 _ = try zir_sema.analyzeBody(self, &block_scope, .{1077 _ = try zir_sema.analyzeBody(mod, &block_scope, .{
1077 .instructions = gen_scope.instructions.items,1078 .instructions = gen_scope.instructions.items,
1078 });1079 });
10791080
1080 decl.analysis = .complete;1081 decl.analysis = .complete;
1081 decl.generation = self.generation;1082 decl.generation = mod.generation;
1082 return true;1083 return true;
1083 },1084 },
1084 .UsingNamespace => @panic("TODO usingnamespace decl"),1085 .@"usingnamespace" => @panic("TODO usingnamespace decl"),
1085 else => unreachable,1086 else => unreachable,
1086 }1087 }
1087}1088}
...@@ -1099,18 +1100,20 @@ fn astgenAndSemaFn(...@@ -1099,18 +1100,20 @@ fn astgenAndSemaFn(
1099 decl.analysis = .in_progress;1100 decl.analysis = .in_progress;
11001101
1101 const token_starts = tree.tokens.items(.start);1102 const token_starts = tree.tokens.items(.start);
1103 const token_tags = tree.tokens.items(.tag);
11021104
1103 // This arena allocator's memory is discarded at the end of this function. It is used1105 // This arena allocator's memory is discarded at the end of this function. It is used
1104 // to determine the type of the function, and hence the type of the decl, which is needed1106 // to determine the type of the function, and hence the type of the decl, which is needed
1105 // to complete the Decl analysis.1107 // to complete the Decl analysis.
1106 var fn_type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);1108 var fn_type_scope_arena = std.heap.ArenaAllocator.init(mod.gpa);
1107 defer fn_type_scope_arena.deinit();1109 defer fn_type_scope_arena.deinit();
1108 var fn_type_scope: Scope.GenZIR = .{1110 var fn_type_scope: Scope.GenZIR = .{
1109 .decl = decl,1111 .decl = decl,
1110 .arena = &fn_type_scope_arena.allocator,1112 .arena = &fn_type_scope_arena.allocator,
1111 .parent = &decl.container.base,1113 .parent = &decl.container.base,
1114 .force_comptime = true,
1112 };1115 };
1113 defer fn_type_scope.instructions.deinit(self.gpa);1116 defer fn_type_scope.instructions.deinit(mod.gpa);
11141117
1115 decl.is_pub = fn_proto.visib_token != null;1118 decl.is_pub = fn_proto.visib_token != null;
11161119
...@@ -1126,7 +1129,7 @@ fn astgenAndSemaFn(...@@ -1126,7 +1129,7 @@ fn astgenAndSemaFn(
1126 };1129 };
1127 const param_types = try fn_type_scope.arena.alloc(*zir.Inst, param_count);1130 const param_types = try fn_type_scope.arena.alloc(*zir.Inst, param_count);
1128 const fn_src = token_starts[fn_proto.ast.fn_token];1131 const fn_src = token_starts[fn_proto.ast.fn_token];
1129 const type_type = try astgen.addZIRInstConst(self, &fn_type_scope.base, fn_src, .{1132 const type_type = try astgen.addZIRInstConst(mod, &fn_type_scope.base, fn_src, .{
1130 .ty = Type.initTag(.type),1133 .ty = Type.initTag(.type),
1131 .val = Value.initTag(.type_type),1134 .val = Value.initTag(.type_type),
1132 });1135 });
...@@ -1138,13 +1141,13 @@ fn astgenAndSemaFn(...@@ -1138,13 +1141,13 @@ fn astgenAndSemaFn(
1138 while (it.next()) |param| : (param_type_i += 1) {1141 while (it.next()) |param| : (param_type_i += 1) {
1139 if (param.anytype_ellipsis3) |token| {1142 if (param.anytype_ellipsis3) |token| {
1140 switch (token_tags[token]) {1143 switch (token_tags[token]) {
1141 .keyword_anytype => return self.failTok(1144 .keyword_anytype => return mod.failTok(
1142 &fn_type_scope.base,1145 &fn_type_scope.base,
1143 tok_i,1146 token,
1144 "TODO implement anytype parameter",1147 "TODO implement anytype parameter",
1145 .{},1148 .{},
1146 ),1149 ),
1147 .ellipsis3 => return self.failTok(1150 .ellipsis3 => return mod.failTok(
1148 &fn_type_scope.base,1151 &fn_type_scope.base,
1149 token,1152 token,
1150 "TODO implement var args",1153 "TODO implement var args",
...@@ -1156,7 +1159,7 @@ fn astgenAndSemaFn(...@@ -1156,7 +1159,7 @@ fn astgenAndSemaFn(
1156 const param_type_node = param.type_expr;1159 const param_type_node = param.type_expr;
1157 assert(param_type_node != 0);1160 assert(param_type_node != 0);
1158 param_types[param_type_i] =1161 param_types[param_type_i] =
1159 try astgen.expr(self, &fn_type_scope.base, type_type_rl, param_type_node);1162 try astgen.expr(mod, &fn_type_scope.base, type_type_rl, param_type_node);
1160 }1163 }
1161 assert(param_type_i == param_count);1164 assert(param_type_i == param_count);
1162 }1165 }
...@@ -1164,10 +1167,10 @@ fn astgenAndSemaFn(...@@ -1164,10 +1167,10 @@ fn astgenAndSemaFn(
1164 // TODO call std.zig.parseStringLiteral1167 // TODO call std.zig.parseStringLiteral
1165 const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name), "\"");1168 const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name), "\"");
1166 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name_str});1169 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name_str});
1167 const target = self.comp.getTarget();1170 const target = mod.comp.getTarget();
1168 if (target_util.is_libc_lib_name(target, lib_name_str)) {1171 if (target_util.is_libc_lib_name(target, lib_name_str)) {
1169 if (!self.comp.bin_file.options.link_libc) {1172 if (!mod.comp.bin_file.options.link_libc) {
1170 return self.failTok(1173 return mod.failTok(
1171 &fn_type_scope.base,1174 &fn_type_scope.base,
1172 lib_name,1175 lib_name,
1173 "dependency on libc must be explicitly specified in the build command",1176 "dependency on libc must be explicitly specified in the build command",
...@@ -1177,8 +1180,8 @@ fn astgenAndSemaFn(...@@ -1177,8 +1180,8 @@ fn astgenAndSemaFn(
1177 break :blk;1180 break :blk;
1178 }1181 }
1179 if (target_util.is_libcpp_lib_name(target, lib_name_str)) {1182 if (target_util.is_libcpp_lib_name(target, lib_name_str)) {
1180 if (!self.comp.bin_file.options.link_libcpp) {1183 if (!mod.comp.bin_file.options.link_libcpp) {
1181 return self.failTok(1184 return mod.failTok(
1182 &fn_type_scope.base,1185 &fn_type_scope.base,
1183 lib_name,1186 lib_name,
1184 "dependency on libc++ must be explicitly specified in the build command",1187 "dependency on libc++ must be explicitly specified in the build command",
...@@ -1187,16 +1190,16 @@ fn astgenAndSemaFn(...@@ -1187,16 +1190,16 @@ fn astgenAndSemaFn(
1187 }1190 }
1188 break :blk;1191 break :blk;
1189 }1192 }
1190 if (!target.isWasm() and !self.comp.bin_file.options.pic) {1193 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
1191 return self.failTok(1194 return mod.failTok(
1192 &fn_type_scope.base,1195 &fn_type_scope.base,
1193 lib_name,1196 lib_name,
1194 "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",1197 "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
1195 .{ lib_name, lib_name },1198 .{ lib_name, lib_name },
1196 );1199 );
1197 }1200 }
1198 self.comp.stage1AddLinkLib(lib_name_str) catch |err| {1201 mod.comp.stage1AddLinkLib(lib_name_str) catch |err| {
1199 return self.failTok(1202 return mod.failTok(
1200 &fn_type_scope.base,1203 &fn_type_scope.base,
1201 lib_name,1204 lib_name,
1202 "unable to add link lib '{s}': {s}",1205 "unable to add link lib '{s}': {s}",
...@@ -1204,45 +1207,55 @@ fn astgenAndSemaFn(...@@ -1204,45 +1207,55 @@ fn astgenAndSemaFn(
1204 );1207 );
1205 };1208 };
1206 }1209 }
1207 if (fn_proto.ast.align_expr) |align_expr| {1210 if (fn_proto.ast.align_expr != 0) {
1208 return self.failNode(&fn_type_scope.base, align_expr, "TODO implement function align expression", .{});1211 return mod.failNode(
1212 &fn_type_scope.base,
1213 fn_proto.ast.align_expr,
1214 "TODO implement function align expression",
1215 .{},
1216 );
1209 }1217 }
1210 if (fn_proto.ast.section_expr) |sect_expr| {1218 if (fn_proto.ast.section_expr != 0) {
1211 return self.failNode(&fn_type_scope.base, sect_expr, "TODO implement function section expression", .{});1219 return mod.failNode(
1220 &fn_type_scope.base,
1221 fn_proto.ast.section_expr,
1222 "TODO implement function section expression",
1223 .{},
1224 );
1212 }1225 }
1213 if (fn_proto.ast.callconv_expr) |callconv_expr| {1226 if (fn_proto.ast.callconv_expr != 0) {
1214 return self.failNode(1227 return mod.failNode(
1215 &fn_type_scope.base,1228 &fn_type_scope.base,
1216 callconv_expr,1229 fn_proto.ast.callconv_expr,
1217 "TODO implement function calling convention expression",1230 "TODO implement function calling convention expression",
1218 .{},1231 .{},
1219 );1232 );
1220 }1233 }
1221 const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;1234 const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;
1222 if (token_tags[maybe_bang] == .bang) {1235 if (token_tags[maybe_bang] == .bang) {
1223 return self.failTok(&fn_type_scope.base, maybe_bang, "TODO implement inferred error sets", .{});1236 return mod.failTok(&fn_type_scope.base, maybe_bang, "TODO implement inferred error sets", .{});
1224 }1237 }
1225 const return_type_inst = try astgen.expr(1238 const return_type_inst = try astgen.expr(
1226 self,1239 mod,
1227 &fn_type_scope.base,1240 &fn_type_scope.base,
1228 type_type_rl,1241 type_type_rl,
1229 fn_proto.ast.return_type,1242 fn_proto.ast.return_type,
1230 );1243 );
1231 const fn_type_inst = try astgen.addZIRInst(self, &fn_type_scope.base, fn_src, zir.Inst.FnType, .{1244 const fn_type_inst = try astgen.addZIRInst(mod, &fn_type_scope.base, fn_src, zir.Inst.FnType, .{
1232 .return_type = return_type_inst,1245 .return_type = return_type_inst,
1233 .param_types = param_types,1246 .param_types = param_types,
1234 }, .{});1247 }, .{});
12351248
1236 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {1249 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1237 zir.dumpZir(self.gpa, "fn_type", decl.name, fn_type_scope.instructions.items) catch {};1250 zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_scope.instructions.items) catch {};
1238 }1251 }
12391252
1240 // We need the memory for the Type to go into the arena for the Decl1253 // We need the memory for the Type to go into the arena for the Decl
1241 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);1254 var decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
1242 errdefer decl_arena.deinit();1255 errdefer decl_arena.deinit();
1243 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);1256 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
12441257
1245 var inst_table = Scope.Block.InstTable.init(self.gpa);1258 var inst_table = Scope.Block.InstTable.init(mod.gpa);
1246 defer inst_table.deinit();1259 defer inst_table.deinit();
12471260
1248 var branch_quota: u32 = default_eval_branch_quota;1261 var branch_quota: u32 = default_eval_branch_quota;
...@@ -1259,9 +1272,9 @@ fn astgenAndSemaFn(...@@ -1259,9 +1272,9 @@ fn astgenAndSemaFn(
1259 .is_comptime = false,1272 .is_comptime = false,
1260 .branch_quota = &branch_quota,1273 .branch_quota = &branch_quota,
1261 };1274 };
1262 defer block_scope.instructions.deinit(self.gpa);1275 defer block_scope.instructions.deinit(mod.gpa);
12631276
1264 const fn_type = try zir_sema.analyzeBodyValueAsType(self, &block_scope, fn_type_inst, .{1277 const fn_type = try zir_sema.analyzeBodyValueAsType(mod, &block_scope, fn_type_inst, .{
1265 .instructions = fn_type_scope.instructions.items,1278 .instructions = fn_type_scope.instructions.items,
1266 });1279 });
1267 if (body_node == 0) {1280 if (body_node == 0) {
...@@ -1270,7 +1283,7 @@ fn astgenAndSemaFn(...@@ -1270,7 +1283,7 @@ fn astgenAndSemaFn(
1270 if (decl.typedValueManaged()) |tvm| {1283 if (decl.typedValueManaged()) |tvm| {
1271 type_changed = !tvm.typed_value.ty.eql(fn_type);1284 type_changed = !tvm.typed_value.ty.eql(fn_type);
12721285
1273 tvm.deinit(self.gpa);1286 tvm.deinit(mod.gpa);
1274 }1287 }
1275 const fn_val = try Value.Tag.extern_fn.create(&decl_arena.allocator, decl);1288 const fn_val = try Value.Tag.extern_fn.create(&decl_arena.allocator, decl);
12761289
...@@ -1282,13 +1295,13 @@ fn astgenAndSemaFn(...@@ -1282,13 +1295,13 @@ fn astgenAndSemaFn(
1282 },1295 },
1283 };1296 };
1284 decl.analysis = .complete;1297 decl.analysis = .complete;
1285 decl.generation = self.generation;1298 decl.generation = mod.generation;
12861299
1287 try self.comp.bin_file.allocateDeclIndexes(decl);1300 try mod.comp.bin_file.allocateDeclIndexes(decl);
1288 try self.comp.work_queue.writeItem(.{ .codegen_decl = decl });1301 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl });
12891302
1290 if (type_changed and self.emit_h != null) {1303 if (type_changed and mod.emit_h != null) {
1291 try self.comp.work_queue.writeItem(.{ .emit_h_decl = decl });1304 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
1292 }1305 }
12931306
1294 return type_changed;1307 return type_changed;
...@@ -1304,17 +1317,17 @@ fn astgenAndSemaFn(...@@ -1304,17 +1317,17 @@ fn astgenAndSemaFn(
1304 .arena = &decl_arena.allocator,1317 .arena = &decl_arena.allocator,
1305 .parent = &decl.container.base,1318 .parent = &decl.container.base,
1306 };1319 };
1307 defer gen_scope.instructions.deinit(self.gpa);1320 defer gen_scope.instructions.deinit(mod.gpa);
13081321
1309 // We need an instruction for each parameter, and they must be first in the body.1322 // We need an instruction for each parameter, and they must be first in the body.
1310 try gen_scope.instructions.resize(self.gpa, param_count);1323 try gen_scope.instructions.resize(mod.gpa, param_count);
1311 var params_scope = &gen_scope.base;1324 var params_scope = &gen_scope.base;
1312 var i: usize = 0;1325 var i: usize = 0;
1313 var it = fn_proto.iterate(tree);1326 var it = fn_proto.iterate(tree);
1314 while (it.next()) |param| : (i += 1) {1327 while (it.next()) |param| : (i += 1) {
1315 const name_token = param.name_token.?;1328 const name_token = param.name_token.?;
1316 const src = token_starts[name_token];1329 const src = token_starts[name_token];
1317 const param_name = try self.identifierTokenString(&gen_scope.base, name_token);1330 const param_name = try mod.identifierTokenString(&gen_scope.base, name_token);
1318 const arg = try decl_arena.allocator.create(zir.Inst.NoOp);1331 const arg = try decl_arena.allocator.create(zir.Inst.NoOp);
1319 arg.* = .{1332 arg.* = .{
1320 .base = .{1333 .base = .{
...@@ -1335,17 +1348,17 @@ fn astgenAndSemaFn(...@@ -1335,17 +1348,17 @@ fn astgenAndSemaFn(
1335 params_scope = &sub_scope.base;1348 params_scope = &sub_scope.base;
1336 }1349 }
13371350
1338 try astgen.blockExpr(self, params_scope, body_node);1351 try astgen.blockExpr(mod, params_scope, body_node);
13391352
1340 if (gen_scope.instructions.items.len == 0 or1353 if (gen_scope.instructions.items.len == 0 or
1341 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())1354 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())
1342 {1355 {
1343 const src = token_starts[tree.lastToken(body_node)];1356 const src = token_starts[tree.lastToken(body_node)];
1344 _ = try astgen.addZIRNoOp(self, &gen_scope.base, src, .returnvoid);1357 _ = try astgen.addZIRNoOp(mod, &gen_scope.base, src, .returnvoid);
1345 }1358 }
13461359
1347 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {1360 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1348 zir.dumpZir(self.gpa, "fn_body", decl.name, gen_scope.instructions.items) catch {};1361 zir.dumpZir(mod.gpa, "fn_body", decl.name, gen_scope.instructions.items) catch {};
1349 }1362 }
13501363
1351 break :blk .{1364 break :blk .{
...@@ -1379,7 +1392,7 @@ fn astgenAndSemaFn(...@@ -1379,7 +1392,7 @@ fn astgenAndSemaFn(
1379 prev_is_inline = prev_func.state == .inline_only;1392 prev_is_inline = prev_func.state == .inline_only;
1380 }1393 }
13811394
1382 tvm.deinit(self.gpa);1395 tvm.deinit(mod.gpa);
1383 }1396 }
13841397
1385 decl_arena_state.* = decl_arena.state;1398 decl_arena_state.* = decl_arena.state;
...@@ -1393,25 +1406,25 @@ fn astgenAndSemaFn(...@@ -1393,25 +1406,25 @@ fn astgenAndSemaFn(
1393 },1406 },
1394 };1407 };
1395 decl.analysis = .complete;1408 decl.analysis = .complete;
1396 decl.generation = self.generation;1409 decl.generation = mod.generation;
13971410
1398 if (!is_inline and fn_type.hasCodeGenBits()) {1411 if (!is_inline and fn_type.hasCodeGenBits()) {
1399 // We don't fully codegen the decl until later, but we do need to reserve a global1412 // We don't fully codegen the decl until later, but we do need to reserve a global
1400 // offset table index for it. This allows us to codegen decls out of dependency order,1413 // offset table index for it. This allows us to codegen decls out of dependency order,
1401 // increasing how many computations can be done in parallel.1414 // increasing how many computations can be done in parallel.
1402 try self.comp.bin_file.allocateDeclIndexes(decl);1415 try mod.comp.bin_file.allocateDeclIndexes(decl);
1403 try self.comp.work_queue.writeItem(.{ .codegen_decl = decl });1416 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl });
1404 if (type_changed and self.emit_h != null) {1417 if (type_changed and mod.emit_h != null) {
1405 try self.comp.work_queue.writeItem(.{ .emit_h_decl = decl });1418 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
1406 }1419 }
1407 } else if (!prev_is_inline and prev_type_has_bits) {1420 } else if (!prev_is_inline and prev_type_has_bits) {
1408 self.comp.bin_file.freeDecl(decl);1421 mod.comp.bin_file.freeDecl(decl);
1409 }1422 }
14101423
1411 if (fn_proto.extern_export_token) |maybe_export_token| {1424 if (fn_proto.extern_export_token) |maybe_export_token| {
1412 if (token_tags[maybe_export_token] == .Keyword_export) {1425 if (token_tags[maybe_export_token] == .keyword_export) {
1413 if (is_inline) {1426 if (is_inline) {
1414 return self.failTok(1427 return mod.failTok(
1415 &block_scope.base,1428 &block_scope.base,
1416 maybe_export_token,1429 maybe_export_token,
1417 "export of inline function",1430 "export of inline function",
...@@ -1421,7 +1434,7 @@ fn astgenAndSemaFn(...@@ -1421,7 +1434,7 @@ fn astgenAndSemaFn(
1421 const export_src = token_starts[maybe_export_token];1434 const export_src = token_starts[maybe_export_token];
1422 const name = tree.tokenSlice(fn_proto.name_token.?); // TODO identifierTokenString1435 const name = tree.tokenSlice(fn_proto.name_token.?); // TODO identifierTokenString
1423 // The scope needs to have the decl in it.1436 // The scope needs to have the decl in it.
1424 try self.analyzeExport(&block_scope.base, export_src, name, decl);1437 try mod.analyzeExport(&block_scope.base, export_src, name, decl);
1425 }1438 }
1426 }1439 }
1427 return type_changed or is_inline != prev_is_inline;1440 return type_changed or is_inline != prev_is_inline;
...@@ -1439,13 +1452,14 @@ fn astgenAndSemaVarDecl(...@@ -1439,13 +1452,14 @@ fn astgenAndSemaVarDecl(
1439 decl.analysis = .in_progress;1452 decl.analysis = .in_progress;
14401453
1441 const token_starts = tree.tokens.items(.start);1454 const token_starts = tree.tokens.items(.start);
1455 const token_tags = tree.tokens.items(.tag);
14421456
1443 // We need the memory for the Type to go into the arena for the Decl1457 // We need the memory for the Type to go into the arena for the Decl
1444 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);1458 var decl_arena = std.heap.ArenaAllocator.init(mod.gpa);
1445 errdefer decl_arena.deinit();1459 errdefer decl_arena.deinit();
1446 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);1460 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
14471461
1448 var decl_inst_table = Scope.Block.InstTable.init(self.gpa);1462 var decl_inst_table = Scope.Block.InstTable.init(mod.gpa);
1449 defer decl_inst_table.deinit();1463 defer decl_inst_table.deinit();
14501464
1451 var branch_quota: u32 = default_eval_branch_quota;1465 var branch_quota: u32 = default_eval_branch_quota;
...@@ -1462,63 +1476,83 @@ fn astgenAndSemaVarDecl(...@@ -1462,63 +1476,83 @@ fn astgenAndSemaVarDecl(
1462 .is_comptime = true,1476 .is_comptime = true,
1463 .branch_quota = &branch_quota,1477 .branch_quota = &branch_quota,
1464 };1478 };
1465 defer block_scope.instructions.deinit(self.gpa);1479 defer block_scope.instructions.deinit(mod.gpa);
14661480
1467 decl.is_pub = var_decl.getVisibToken() != null;1481 decl.is_pub = var_decl.visib_token != null;
1468 const is_extern = blk: {1482 const is_extern = blk: {
1469 const maybe_extern_token = var_decl.getExternExportToken() orelse1483 const maybe_extern_token = var_decl.extern_export_token orelse break :blk false;
1470 break :blk false;1484 if (token_tags[maybe_extern_token] != .keyword_extern) break :blk false;
1471 if (tree.token_ids[maybe_extern_token] != .Keyword_extern) break :blk false;1485 if (var_decl.ast.init_node != 0) {
1472 if (var_decl.getInitNode()) |some| {1486 return mod.failNode(
1473 return self.failNode(&block_scope.base, some, "extern variables have no initializers", .{});1487 &block_scope.base,
1488 var_decl.ast.init_node,
1489 "extern variables have no initializers",
1490 .{},
1491 );
1474 }1492 }
1475 break :blk true;1493 break :blk true;
1476 };1494 };
1477 if (var_decl.getLibName()) |lib_name| {1495 if (var_decl.lib_name) |lib_name| {
1478 assert(is_extern);1496 assert(is_extern);
1479 return self.failNode(&block_scope.base, lib_name, "TODO implement function library name", .{});1497 return mod.failTok(&block_scope.base, lib_name, "TODO implement function library name", .{});
1480 }1498 }
1481 const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var;1499 const is_mutable = token_tags[var_decl.mut_token] == .keyword_var;
1482 const is_threadlocal = if (var_decl.getThreadLocalToken()) |some| blk: {1500 const is_threadlocal = if (var_decl.threadlocal_token) |some| blk: {
1483 if (!is_mutable) {1501 if (!is_mutable) {
1484 return self.failTok(&block_scope.base, some, "threadlocal variable cannot be constant", .{});1502 return mod.failTok(&block_scope.base, some, "threadlocal variable cannot be constant", .{});
1485 }1503 }
1486 break :blk true;1504 break :blk true;
1487 } else false;1505 } else false;
1488 assert(var_decl.getComptimeToken() == null);1506 assert(var_decl.comptime_token == null);
1489 if (var_decl.getAlignNode()) |align_expr| {1507 if (var_decl.ast.align_node != 0) {
1490 return self.failNode(&block_scope.base, align_expr, "TODO implement function align expression", .{});1508 return mod.failNode(
1509 &block_scope.base,
1510 var_decl.ast.align_node,
1511 "TODO implement function align expression",
1512 .{},
1513 );
1491 }1514 }
1492 if (var_decl.getSectionNode()) |sect_expr| {1515 if (var_decl.ast.section_node != 0) {
1493 return self.failNode(&block_scope.base, sect_expr, "TODO implement function section expression", .{});1516 return mod.failNode(
1517 &block_scope.base,
1518 var_decl.ast.section_node,
1519 "TODO implement function section expression",
1520 .{},
1521 );
1494 }1522 }
14951523
1496 const var_info: struct { ty: Type, val: ?Value } = if (var_decl.getInitNode()) |init_node| vi: {1524 const var_info: struct { ty: Type, val: ?Value } = if (var_decl.ast.init_node != 0) vi: {
1497 var gen_scope_arena = std.heap.ArenaAllocator.init(self.gpa);1525 var gen_scope_arena = std.heap.ArenaAllocator.init(mod.gpa);
1498 defer gen_scope_arena.deinit();1526 defer gen_scope_arena.deinit();
1499 var gen_scope: Scope.GenZIR = .{1527 var gen_scope: Scope.GenZIR = .{
1500 .decl = decl,1528 .decl = decl,
1501 .arena = &gen_scope_arena.allocator,1529 .arena = &gen_scope_arena.allocator,
1502 .parent = &decl.container.base,1530 .parent = &decl.container.base,
1503 };1531 };
1504 defer gen_scope.instructions.deinit(self.gpa);1532 defer gen_scope.instructions.deinit(mod.gpa);
15051533
1506 const init_result_loc: astgen.ResultLoc = if (var_decl.getTypeNode()) |type_node| rl: {1534 const init_result_loc: astgen.ResultLoc = if (var_decl.ast.type_node != 0) rl: {
1507 const src = token_starts[type_node.firstToken()];1535 const type_node = var_decl.ast.type_node;
1508 const type_type = try astgen.addZIRInstConst(self, &gen_scope.base, src, .{1536 const src = token_starts[tree.firstToken(type_node)];
1537 const type_type = try astgen.addZIRInstConst(mod, &gen_scope.base, src, .{
1509 .ty = Type.initTag(.type),1538 .ty = Type.initTag(.type),
1510 .val = Value.initTag(.type_type),1539 .val = Value.initTag(.type_type),
1511 });1540 });
1512 const var_type = try astgen.expr(self, &gen_scope.base, .{ .ty = type_type }, type_node);1541 const var_type = try astgen.expr(mod, &gen_scope.base, .{ .ty = type_type }, type_node);
1513 break :rl .{ .ty = var_type };1542 break :rl .{ .ty = var_type };
1514 } else .none;1543 } else .none;
15151544
1516 const init_inst = try astgen.comptimeExpr(self, &gen_scope.base, init_result_loc, init_node);1545 const init_inst = try astgen.comptimeExpr(
1517 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {1546 mod,
1518 zir.dumpZir(self.gpa, "var_init", decl.name, gen_scope.instructions.items) catch {};1547 &gen_scope.base,
1548 init_result_loc,
1549 var_decl.ast.init_node,
1550 );
1551 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1552 zir.dumpZir(mod.gpa, "var_init", decl.name, gen_scope.instructions.items) catch {};
1519 }1553 }
15201554
1521 var var_inst_table = Scope.Block.InstTable.init(self.gpa);1555 var var_inst_table = Scope.Block.InstTable.init(mod.gpa);
1522 defer var_inst_table.deinit();1556 defer var_inst_table.deinit();
15231557
1524 var branch_quota_vi: u32 = default_eval_branch_quota;1558 var branch_quota_vi: u32 = default_eval_branch_quota;
...@@ -1534,8 +1568,8 @@ fn astgenAndSemaVarDecl(...@@ -1534,8 +1568,8 @@ fn astgenAndSemaVarDecl(
1534 .is_comptime = true,1568 .is_comptime = true,
1535 .branch_quota = &branch_quota_vi,1569 .branch_quota = &branch_quota_vi,
1536 };1570 };
1537 defer inner_block.instructions.deinit(self.gpa);1571 defer inner_block.instructions.deinit(mod.gpa);
1538 try zir_sema.analyzeBody(self, &inner_block, .{1572 try zir_sema.analyzeBody(mod, &inner_block, .{
1539 .instructions = gen_scope.instructions.items,1573 .instructions = gen_scope.instructions.items,
1540 });1574 });
15411575
...@@ -1550,24 +1584,30 @@ fn astgenAndSemaVarDecl(...@@ -1550,24 +1584,30 @@ fn astgenAndSemaVarDecl(
1550 .val = try val.copy(block_scope.arena),1584 .val = try val.copy(block_scope.arena),
1551 };1585 };
1552 } else if (!is_extern) {1586 } else if (!is_extern) {
1553 return self.failTok(&block_scope.base, var_decl.firstToken(), "variables must be initialized", .{});1587 return mod.failTok(
1554 } else if (var_decl.getTypeNode()) |type_node| vi: {1588 &block_scope.base,
1589 tree.firstToken(var_decl),
1590 "variables must be initialized",
1591 .{},
1592 );
1593 } else if (var_decl.ast.type_node != 0) vi: {
1594 const type_node = var_decl.ast.type_node;
1555 // Temporary arena for the zir instructions.1595 // Temporary arena for the zir instructions.
1556 var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);1596 var type_scope_arena = std.heap.ArenaAllocator.init(mod.gpa);
1557 defer type_scope_arena.deinit();1597 defer type_scope_arena.deinit();
1558 var type_scope: Scope.GenZIR = .{1598 var type_scope: Scope.GenZIR = .{
1559 .decl = decl,1599 .decl = decl,
1560 .arena = &type_scope_arena.allocator,1600 .arena = &type_scope_arena.allocator,
1561 .parent = &decl.container.base,1601 .parent = &decl.container.base,
1562 };1602 };
1563 defer type_scope.instructions.deinit(self.gpa);1603 defer type_scope.instructions.deinit(mod.gpa);
15641604
1565 const var_type = try astgen.typeExpr(self, &type_scope.base, type_node);1605 const var_type = try astgen.typeExpr(mod, &type_scope.base, type_node);
1566 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {1606 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1567 zir.dumpZir(self.gpa, "var_type", decl.name, type_scope.instructions.items) catch {};1607 zir.dumpZir(mod.gpa, "var_type", decl.name, type_scope.instructions.items) catch {};
1568 }1608 }
15691609
1570 const ty = try zir_sema.analyzeBodyValueAsType(self, &block_scope, var_type, .{1610 const ty = try zir_sema.analyzeBodyValueAsType(mod, &block_scope, var_type, .{
1571 .instructions = type_scope.instructions.items,1611 .instructions = type_scope.instructions.items,
1572 });1612 });
1573 break :vi .{1613 break :vi .{
...@@ -1575,18 +1615,28 @@ fn astgenAndSemaVarDecl(...@@ -1575,18 +1615,28 @@ fn astgenAndSemaVarDecl(
1575 .val = null,1615 .val = null,
1576 };1616 };
1577 } else {1617 } else {
1578 return self.failTok(&block_scope.base, var_decl.firstToken(), "unable to infer variable type", .{});1618 return mod.failTok(
1619 &block_scope.base,
1620 tree.firstToken(var_decl),
1621 "unable to infer variable type",
1622 .{},
1623 );
1579 };1624 };
15801625
1581 if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {1626 if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {
1582 return self.failTok(&block_scope.base, var_decl.firstToken(), "variable of type '{}' must be const", .{var_info.ty});1627 return mod.failTok(
1628 &block_scope.base,
1629 tree.firstToken(var_decl),
1630 "variable of type '{}' must be const",
1631 .{var_info.ty},
1632 );
1583 }1633 }
15841634
1585 var type_changed = true;1635 var type_changed = true;
1586 if (decl.typedValueManaged()) |tvm| {1636 if (decl.typedValueManaged()) |tvm| {
1587 type_changed = !tvm.typed_value.ty.eql(var_info.ty);1637 type_changed = !tvm.typed_value.ty.eql(var_info.ty);
15881638
1589 tvm.deinit(self.gpa);1639 tvm.deinit(mod.gpa);
1590 }1640 }
15911641
1592 const new_variable = try decl_arena.allocator.create(Var);1642 const new_variable = try decl_arena.allocator.create(Var);
...@@ -1610,14 +1660,15 @@ fn astgenAndSemaVarDecl(...@@ -1610,14 +1660,15 @@ fn astgenAndSemaVarDecl(
1610 },1660 },
1611 };1661 };
1612 decl.analysis = .complete;1662 decl.analysis = .complete;
1613 decl.generation = self.generation;1663 decl.generation = mod.generation;
16141664
1615 if (var_decl.getExternExportToken()) |maybe_export_token| {1665 if (var_decl.extern_export_token) |maybe_export_token| {
1616 if (tree.token_ids[maybe_export_token] == .Keyword_export) {1666 if (token_tags[maybe_export_token] == .keyword_export) {
1617 const export_src = token_starts[maybe_export_token];1667 const export_src = token_starts[maybe_export_token];
1618 const name = tree.tokenSlice(var_decl.name_token); // TODO identifierTokenString1668 const name_token = var_decl.ast.mut_token + 1;
1669 const name = tree.tokenSlice(name_token); // TODO identifierTokenString
1619 // The scope needs to have the decl in it.1670 // The scope needs to have the decl in it.
1620 try self.analyzeExport(&block_scope.base, export_src, name, decl);1671 try mod.analyzeExport(&block_scope.base, export_src, name, decl);
1621 }1672 }
1622 }1673 }
1623 return type_changed;1674 return type_changed;
...@@ -1761,7 +1812,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1761,7 +1812,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1761 decl_node,1812 decl_node,
1762 decl_i,1813 decl_i,
1763 tree.*,1814 tree.*,
1764 null,1815 0,
1765 tree.fnProtoSimple(&params, decl_node),1816 tree.fnProtoSimple(&params, decl_node),
1766 );1817 );
1767 },1818 },
...@@ -1771,7 +1822,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1771,7 +1822,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1771 decl_node,1822 decl_node,
1772 decl_i,1823 decl_i,
1773 tree.*,1824 tree.*,
1774 null,1825 0,
1775 tree.fnProtoMulti(decl_node),1826 tree.fnProtoMulti(decl_node),
1776 ),1827 ),
1777 .fn_proto_one => {1828 .fn_proto_one => {
...@@ -1782,7 +1833,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1782,7 +1833,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1782 decl_node,1833 decl_node,
1783 decl_i,1834 decl_i,
1784 tree.*,1835 tree.*,
1785 null,1836 0,
1786 tree.fnProtoOne(&params, decl_node),1837 tree.fnProtoOne(&params, decl_node),
1787 );1838 );
1788 },1839 },
...@@ -1792,7 +1843,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1792,7 +1843,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1792 decl_node,1843 decl_node,
1793 decl_i,1844 decl_i,
1794 tree.*,1845 tree.*,
1795 null,1846 0,
1796 tree.fnProto(decl_node),1847 tree.fnProto(decl_node),
1797 ),1848 ),
17981849
...@@ -1848,7 +1899,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1848,7 +1899,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1848 decl_node,1899 decl_node,
1849 decl_i,1900 decl_i,
1850 tree.*,1901 tree.*,
1851 tree.containerFieldInit(decl),1902 tree.containerFieldInit(decl_node),
1852 ),1903 ),
1853 .container_field_align => try mod.semaContainerField(1904 .container_field_align => try mod.semaContainerField(
1854 container_scope,1905 container_scope,
...@@ -1856,7 +1907,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1856,7 +1907,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1856 decl_node,1907 decl_node,
1857 decl_i,1908 decl_i,
1858 tree.*,1909 tree.*,
1859 tree.containerFieldAlign(decl),1910 tree.containerFieldAlign(decl_node),
1860 ),1911 ),
1861 .container_field => try mod.semaContainerField(1912 .container_field => try mod.semaContainerField(
1862 container_scope,1913 container_scope,
...@@ -1864,7 +1915,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {...@@ -1864,7 +1915,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
1864 decl_node,1915 decl_node,
1865 decl_i,1916 decl_i,
1866 tree.*,1917 tree.*,
1867 tree.containerField(decl),1918 tree.containerField(decl_node),
1868 ),1919 ),
18691920
1870 .test_decl => {1921 .test_decl => {
...@@ -1936,14 +1987,14 @@ fn semaContainerFn(...@@ -1936,14 +1987,14 @@ fn semaContainerFn(
1936 // in `Decl` to notice that the line number did not change.1987 // in `Decl` to notice that the line number did not change.
1937 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });1988 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
1938 },1989 },
1939 .c, .wasm => {},1990 .c, .wasm, .spirv => {},
1940 }1991 }
1941 }1992 }
1942 } else {1993 } else {
1943 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);1994 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);
1944 container_scope.decls.putAssumeCapacity(new_decl, {});1995 container_scope.decls.putAssumeCapacity(new_decl, {});
1945 if (fn_proto.getExternExportInlineToken()) |maybe_export_token| {1996 if (fn_proto.extern_export_token) |maybe_export_token| {
1946 if (tree.token_ids[maybe_export_token] == .Keyword_export) {1997 if (token_tags[maybe_export_token] == .keyword_export) {
1947 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });1998 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
1948 }1999 }
1949 }2000 }
...@@ -1963,9 +2014,11 @@ fn semaContainerVar(...@@ -1963,9 +2014,11 @@ fn semaContainerVar(
1963 defer tracy.end();2014 defer tracy.end();
19642015
1965 const token_starts = tree.tokens.items(.start);2016 const token_starts = tree.tokens.items(.start);
2017 const token_tags = tree.tokens.items(.tag);
19662018
1967 const name_src = token_starts[var_decl.name_token];2019 const name_token = var_decl.ast.mut_token + 1;
1968 const name = tree.tokenSlice(var_decl.name_token); // TODO identifierTokenString2020 const name_src = token_starts[name_token];
2021 const name = tree.tokenSlice(name_token); // TODO identifierTokenString
1969 const name_hash = container_scope.fullyQualifiedNameHash(name);2022 const name_hash = container_scope.fullyQualifiedNameHash(name);
1970 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));2023 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
1971 if (mod.decl_table.get(name_hash)) |decl| {2024 if (mod.decl_table.get(name_hash)) |decl| {
...@@ -1987,15 +2040,23 @@ fn semaContainerVar(...@@ -1987,15 +2040,23 @@ fn semaContainerVar(
1987 } else {2040 } else {
1988 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);2041 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);
1989 container_scope.decls.putAssumeCapacity(new_decl, {});2042 container_scope.decls.putAssumeCapacity(new_decl, {});
1990 if (var_decl.getExternExportToken()) |maybe_export_token| {2043 if (var_decl.extern_export_token) |maybe_export_token| {
1991 if (tree.token_ids[maybe_export_token] == .Keyword_export) {2044 if (token_tags[maybe_export_token] == .keyword_export) {
1992 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });2045 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
1993 }2046 }
1994 }2047 }
1995 }2048 }
1996}2049}
19972050
1998fn semaContainerField() void {2051fn semaContainerField(
2052 mod: *Module,
2053 container_scope: *Scope.Container,
2054 deleted_decls: *std.AutoArrayHashMap(*Decl, void),
2055 decl_node: ast.Node.Index,
2056 decl_i: usize,
2057 tree: ast.Tree,
2058 field: ast.full.ContainerField,
2059) !void {
1999 const tracy = trace(@src());2060 const tracy = trace(@src());
2000 defer tracy.end();2061 defer tracy.end();
20012062
...@@ -2898,7 +2959,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []...@@ -2898,7 +2959,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []
2898 file_scope.* = .{2959 file_scope.* = .{
2899 .sub_file_path = resolved_path,2960 .sub_file_path = resolved_path,
2900 .source = .{ .unloaded = {} },2961 .source = .{ .unloaded = {} },
2901 .contents = .{ .not_available = {} },2962 .tree = undefined,
2902 .status = .never_loaded,2963 .status = .never_loaded,
2903 .pkg = found_pkg orelse cur_pkg,2964 .pkg = found_pkg orelse cur_pkg,
2904 .root_container = .{2965 .root_container = .{
...@@ -3415,11 +3476,12 @@ pub fn failTok(...@@ -3415,11 +3476,12 @@ pub fn failTok(
3415pub fn failNode(3476pub fn failNode(
3416 self: *Module,3477 self: *Module,
3417 scope: *Scope,3478 scope: *Scope,
3418 ast_node: *ast.Node,3479 ast_node: ast.Node.Index,
3419 comptime format: []const u8,3480 comptime format: []const u8,
3420 args: anytype,3481 args: anytype,
3421) InnerError {3482) InnerError {
3422 const src = scope.tree().tokens.items(.start)[ast_node.firstToken()];3483 const tree = scope.tree();
3484 const src = tree.tokens.items(.start)[tree.firstToken(ast_node)];
3423 return self.fail(scope, src, format, args);3485 return self.fail(scope, src, format, args);
3424}3486}
34253487
src/astgen.zig+504-417
...@@ -55,7 +55,7 @@ pub const ResultLoc = union(enum) {...@@ -55,7 +55,7 @@ pub const ResultLoc = union(enum) {
55 };55 };
56};56};
5757
58pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*zir.Inst {58pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
59 const type_src = scope.tree().token_locs[type_node.firstToken()].start;59 const type_src = scope.tree().token_locs[type_node.firstToken()].start;
60 const type_type = try addZIRInstConst(mod, scope, type_src, .{60 const type_type = try addZIRInstConst(mod, scope, type_src, .{
61 .ty = Type.initTag(.type),61 .ty = Type.initTag(.type),
...@@ -65,134 +65,133 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z...@@ -65,134 +65,133 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z
65 return expr(mod, scope, type_rl, type_node);65 return expr(mod, scope, type_rl, type_node);
66}66}
6767
68fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {68fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
69 switch (node.tag) {69 const tree = scope.tree();
70 .Root => unreachable,70 const node_tags = tree.nodes.items(.tag);
71 .Use => unreachable,71 const main_tokens = tree.nodes.items(.main_token);
72 .TestDecl => unreachable,72 switch (node_tags[node]) {
73 .DocComment => unreachable,73 .root => unreachable,
74 .VarDecl => unreachable,74 .@"usingnamespace" => unreachable,
75 .SwitchCase => unreachable,75 .test_decl => unreachable,
76 .SwitchElse => unreachable,76 .doc_comment => unreachable,
77 .Else => unreachable,77 .var_decl => unreachable,
78 .Payload => unreachable,78 .switch_case => unreachable,
79 .PointerPayload => unreachable,79 .switch_else => unreachable,
80 .PointerIndexPayload => unreachable,80 .container_field_init => unreachable,
81 .ErrorTag => unreachable,81 .container_field_align => unreachable,
82 .FieldInitializer => unreachable,82 .container_field => unreachable,
83 .ContainerField => unreachable,83
8484 .assign,
85 .Assign,85 .assign_bit_and,
86 .AssignBitAnd,86 .assign_bit_or,
87 .AssignBitOr,87 .assign_bit_shift_left,
88 .AssignBitShiftLeft,88 .assign_bit_shift_right,
89 .AssignBitShiftRight,89 .assign_bit_xor,
90 .AssignBitXor,90 .assign_div,
91 .AssignDiv,91 .assign_sub,
92 .AssignSub,92 .assign_sub_wrap,
93 .AssignSubWrap,93 .assign_mod,
94 .AssignMod,94 .assign_add,
95 .AssignAdd,95 .assign_add_wrap,
96 .AssignAddWrap,96 .assign_mul,
97 .AssignMul,97 .assign_mul_wrap,
98 .AssignMulWrap,98 .add,
99 .Add,99 .add_wrap,
100 .AddWrap,100 .sub,
101 .Sub,101 .sub_wrap,
102 .SubWrap,102 .mul,
103 .Mul,103 .mul_wrap,
104 .MulWrap,104 .div,
105 .Div,105 .mod,
106 .Mod,106 .bit_and,
107 .BitAnd,107 .bit_or,
108 .BitOr,108 .bit_shift_left,
109 .BitShiftLeft,109 .bit_shift_right,
110 .BitShiftRight,110 .bit_xor,
111 .BitXor,111 .bang_equal,
112 .BangEqual,112 .equal_equal,
113 .EqualEqual,113 .greater_than,
114 .GreaterThan,114 .greater_or_equal,
115 .GreaterOrEqual,115 .less_than,
116 .LessThan,116 .less_or_equal,
117 .LessOrEqual,117 .array_cat,
118 .ArrayCat,118 .array_mult,
119 .ArrayMult,119 .bool_and,
120 .BoolAnd,120 .bool_or,
121 .BoolOr,121 .@"asm",
122 .Asm,122 .string_literal,
123 .StringLiteral,123 .integer_literal,
124 .IntegerLiteral,124 .call,
125 .Call,125 .@"unreachable",
126 .Unreachable,126 .@"return",
127 .Return,127 .@"if",
128 .If,128 .@"while",
129 .While,129 .bool_not,
130 .BoolNot,130 .address_of,
131 .AddressOf,131 .float_literal,
132 .FloatLiteral,132 .undefined_literal,
133 .UndefinedLiteral,133 .bool_literal,
134 .BoolLiteral,134 .null_literal,
135 .NullLiteral,135 .optional_type,
136 .OptionalType,136 .block,
137 .Block,137 .labeled_block,
138 .LabeledBlock,138 .@"break",
139 .Break,
140 .PtrType,139 .PtrType,
141 .ArrayType,140 .array_type,
142 .ArrayTypeSentinel,141 .array_type_sentinel,
143 .EnumLiteral,142 .enum_literal,
144 .MultilineStringLiteral,143 .MultilineStringLiteral,
145 .CharLiteral,144 .char_literal,
146 .Defer,145 .@"defer",
147 .Catch,146 .@"catch",
148 .ErrorUnion,147 .error_union,
149 .MergeErrorSets,148 .merge_error_sets,
150 .Range,149 .range,
151 .Await,150 .@"await",
152 .BitNot,151 .bit_not,
153 .Negation,152 .negation,
154 .NegationWrap,153 .negation_wrap,
155 .Resume,154 .@"resume",
156 .Try,155 .@"try",
157 .SliceType,156 .slice_type,
158 .Slice,157 .slice,
159 .ArrayInitializer,158 .ArrayInitializer,
160 .ArrayInitializerDot,159 .ArrayInitializerDot,
161 .StructInitializer,160 .StructInitializer,
162 .StructInitializerDot,161 .StructInitializerDot,
163 .Switch,162 .@"switch",
164 .For,163 .@"for",
165 .Suspend,164 .@"suspend",
166 .Continue,165 .@"continue",
167 .AnyType,166 .@"anytype",
168 .ErrorType,167 .error_type,
169 .FnProto,168 .FnProto,
170 .AnyFrameType,169 .anyframe_type,
171 .ErrorSetDecl,170 .error_set_decl,
172 .ContainerDecl,171 .ContainerDecl,
173 .Comptime,172 .@"comptime",
174 .Nosuspend,173 .@"nosuspend",
174 .builtin_call,
175 .builtin_call_comma,
175 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),176 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),
176177
177 // @field can be assigned to178 // `@field` can be assigned to.
178 .BuiltinCall => {179 .builtin_call_two, .builtin_call_two_comma => {
179 const call = node.castTag(.BuiltinCall).?;180 const builtin_token = main_tokens[node];
180 const tree = scope.tree();181 const builtin_name = tree.tokenSlice(builtin_token);
181 const builtin_name = tree.tokenSlice(call.builtin_token);
182
183 if (!mem.eql(u8, builtin_name, "@field")) {182 if (!mem.eql(u8, builtin_name, "@field")) {
184 return mod.failNode(scope, node, "invalid left-hand side to assignment", .{});183 return mod.failNode(scope, node, "invalid left-hand side to assignment", .{});
185 }184 }
186 },185 },
187186
188 // can be assigned to187 // can be assigned to
189 .UnwrapOptional,188 .unwrap_optional,
190 .Deref,189 .deref,
191 .Period,190 .period,
192 .ArrayAccess,191 .array_access,
193 .Identifier,192 .identifier,
194 .GroupedExpression,193 .grouped_expression,
195 .OrElse,194 .@"orelse",
196 => {},195 => {},
197 }196 }
198 return expr(mod, scope, .ref, node);197 return expr(mod, scope, .ref, node);
...@@ -202,16 +201,16 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {...@@ -202,16 +201,16 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
202/// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the201/// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the
203/// result instruction can be used to inspect whether it is isNoReturn() but that is it,202/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
204/// it must otherwise not be used.203/// it must otherwise not be used.
205pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerError!*zir.Inst {204pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
206 switch (node.tag) {205 switch (node.tag) {
207 .Root => unreachable, // Top-level declaration.206 .root => unreachable, // Top-level declaration.
208 .Use => unreachable, // Top-level declaration.207 .@"usingnamespace" => unreachable, // Top-level declaration.
209 .TestDecl => unreachable, // Top-level declaration.208 .test_decl => unreachable, // Top-level declaration.
210 .DocComment => unreachable, // Top-level declaration.209 .doc_comment => unreachable, // Top-level declaration.
211 .VarDecl => unreachable, // Handled in `blockExpr`.210 .var_decl => unreachable, // Handled in `blockExpr`.
212 .SwitchCase => unreachable, // Handled in `switchExpr`.211 .switch_case => unreachable, // Handled in `switchExpr`.
213 .SwitchElse => unreachable, // Handled in `switchExpr`.212 .switch_else => unreachable, // Handled in `switchExpr`.
214 .Range => unreachable, // Handled in `switchExpr`.213 .range => unreachable, // Handled in `switchExpr`.
215 .Else => unreachable, // Handled explicitly the control flow expression functions.214 .Else => unreachable, // Handled explicitly the control flow expression functions.
216 .Payload => unreachable, // Handled explicitly.215 .Payload => unreachable, // Handled explicitly.
217 .PointerPayload => unreachable, // Handled explicitly.216 .PointerPayload => unreachable, // Handled explicitly.
...@@ -220,114 +219,113 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr...@@ -220,114 +219,113 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
220 .FieldInitializer => unreachable, // Handled explicitly.219 .FieldInitializer => unreachable, // Handled explicitly.
221 .ContainerField => unreachable, // Handled explicitly.220 .ContainerField => unreachable, // Handled explicitly.
222221
223 .Assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)),222 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
224 .AssignBitAnd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bit_and)),223 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
225 .AssignBitOr => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitOr).?, .bit_or)),224 .assign_bit_or => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_or)),
226 .AssignBitShiftLeft => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftLeft).?, .shl)),225 .assign_bit_shift_left => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shl)),
227 .AssignBitShiftRight => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftRight).?, .shr)),226 .assign_bit_shift_right => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shr)),
228 .AssignBitXor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitXor).?, .xor)),227 .assign_bit_xor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .xor)),
229 .AssignDiv => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignDiv).?, .div)),228 .assign_div => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .div)),
230 .AssignSub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSub).?, .sub)),229 .assign_sub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .sub)),
231 .AssignSubWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSubWrap).?, .subwrap)),230 .assign_sub_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .subwrap)),
232 .AssignMod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMod).?, .mod_rem)),231 .assign_mod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mod_rem)),
233 .AssignAdd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAdd).?, .add)),232 .assign_add => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .add)),
234 .AssignAddWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAddWrap).?, .addwrap)),233 .assign_add_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .addwrap)),
235 .AssignMul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMul).?, .mul)),234 .assign_mul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mul)),
236 .AssignMulWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMulWrap).?, .mulwrap)),235 .assign_mul_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mulwrap)),
237236
238 .Add => return simpleBinOp(mod, scope, rl, node.castTag(.Add).?, .add),237 .add => return simpleBinOp(mod, scope, rl, node, .add),
239 .AddWrap => return simpleBinOp(mod, scope, rl, node.castTag(.AddWrap).?, .addwrap),238 .add_wrap => return simpleBinOp(mod, scope, rl, node, .addwrap),
240 .Sub => return simpleBinOp(mod, scope, rl, node.castTag(.Sub).?, .sub),239 .sub => return simpleBinOp(mod, scope, rl, node, .sub),
241 .SubWrap => return simpleBinOp(mod, scope, rl, node.castTag(.SubWrap).?, .subwrap),240 .sub_wrap => return simpleBinOp(mod, scope, rl, node, .subwrap),
242 .Mul => return simpleBinOp(mod, scope, rl, node.castTag(.Mul).?, .mul),241 .mul => return simpleBinOp(mod, scope, rl, node, .mul),
243 .MulWrap => return simpleBinOp(mod, scope, rl, node.castTag(.MulWrap).?, .mulwrap),242 .mul_wrap => return simpleBinOp(mod, scope, rl, node, .mulwrap),
244 .Div => return simpleBinOp(mod, scope, rl, node.castTag(.Div).?, .div),243 .div => return simpleBinOp(mod, scope, rl, node, .div),
245 .Mod => return simpleBinOp(mod, scope, rl, node.castTag(.Mod).?, .mod_rem),244 .mod => return simpleBinOp(mod, scope, rl, node, .mod_rem),
246 .BitAnd => return simpleBinOp(mod, scope, rl, node.castTag(.BitAnd).?, .bit_and),245 .bit_and => return simpleBinOp(mod, scope, rl, node, .bit_and),
247 .BitOr => return simpleBinOp(mod, scope, rl, node.castTag(.BitOr).?, .bit_or),246 .bit_or => return simpleBinOp(mod, scope, rl, node, .bit_or),
248 .BitShiftLeft => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftLeft).?, .shl),247 .bit_shift_left => return simpleBinOp(mod, scope, rl, node, .shl),
249 .BitShiftRight => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftRight).?, .shr),248 .bit_shift_right => return simpleBinOp(mod, scope, rl, node, .shr),
250 .BitXor => return simpleBinOp(mod, scope, rl, node.castTag(.BitXor).?, .xor),249 .bit_xor => return simpleBinOp(mod, scope, rl, node, .xor),
251250
252 .BangEqual => return simpleBinOp(mod, scope, rl, node.castTag(.BangEqual).?, .cmp_neq),251 .bang_equal => return simpleBinOp(mod, scope, rl, node, .cmp_neq),
253 .EqualEqual => return simpleBinOp(mod, scope, rl, node.castTag(.EqualEqual).?, .cmp_eq),252 .equal_equal => return simpleBinOp(mod, scope, rl, node, .cmp_eq),
254 .GreaterThan => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterThan).?, .cmp_gt),253 .greater_than => return simpleBinOp(mod, scope, rl, node, .cmp_gt),
255 .GreaterOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterOrEqual).?, .cmp_gte),254 .greater_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_gte),
256 .LessThan => return simpleBinOp(mod, scope, rl, node.castTag(.LessThan).?, .cmp_lt),255 .less_than => return simpleBinOp(mod, scope, rl, node, .cmp_lt),
257 .LessOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.LessOrEqual).?, .cmp_lte),256 .less_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_lte),
258257
259 .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat),258 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
260 .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul),259 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
261260
262 .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?),261 .bool_and => return boolBinOp(mod, scope, rl, node),
263 .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?),262 .bool_or => return boolBinOp(mod, scope, rl, node),
264263
265 .BoolNot => return rvalue(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),264 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
266 .BitNot => return rvalue(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)),265 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
267 .Negation => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)),266 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
268 .NegationWrap => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)),267 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
269268
270 .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?),269 .identifier => return try identifier(mod, scope, rl, node),
271 .Asm => return rvalue(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),270 .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)),
272 .StringLiteral => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),271 .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)),
273 .IntegerLiteral => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node.castTag(.IntegerLiteral).?)),272 .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node)),
274 .BuiltinCall => return builtinCall(mod, scope, rl, node.castTag(.BuiltinCall).?),273 .builtin_call => return builtinCall(mod, scope, rl, node),
275 .Call => return callExpr(mod, scope, rl, node.castTag(.Call).?),274 .call => return callExpr(mod, scope, rl, node),
276 .Unreachable => return unreach(mod, scope, node.castTag(.Unreachable).?),275 .@"unreachable" => return unreach(mod, scope, node),
277 .Return => return ret(mod, scope, node.castTag(.Return).?),276 .@"return" => return ret(mod, scope, node),
278 .If => return ifExpr(mod, scope, rl, node.castTag(.If).?),277 .@"if" => return ifExpr(mod, scope, rl, node),
279 .While => return whileExpr(mod, scope, rl, node.castTag(.While).?),278 .@"while" => return whileExpr(mod, scope, rl, node),
280 .Period => return field(mod, scope, rl, node.castTag(.Period).?),279 .period => return field(mod, scope, rl, node),
281 .Deref => return rvalue(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),280 .deref => return rvalue(mod, scope, rl, try deref(mod, scope, node)),
282 .AddressOf => return rvalue(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),281 .address_of => return rvalue(mod, scope, rl, try addressOf(mod, scope, node)),
283 .FloatLiteral => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),282 .float_literal => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node)),
284 .UndefinedLiteral => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),283 .undefined_literal => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node)),
285 .BoolLiteral => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),284 .bool_literal => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node)),
286 .NullLiteral => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node.castTag(.NullLiteral).?)),285 .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)),
287 .OptionalType => return rvalue(mod, scope, rl, try optionalType(mod, scope, node.castTag(.OptionalType).?)),286 .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)),
288 .UnwrapOptional => return unwrapOptional(mod, scope, rl, node.castTag(.UnwrapOptional).?),287 .unwrap_optional => return unwrapOptional(mod, scope, rl, node),
289 .Block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),288 .block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node)),
290 .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?, .block),289 .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block),
291 .Break => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),290 .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)),
292 .Continue => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node.castTag(.Continue).?)),291 .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)),
293 .PtrType => return rvalue(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),292 .grouped_expression => return expr(mod, scope, rl, node.expr),
294 .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),293 .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)),
295 .ArrayType => return rvalue(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),294 .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)),
296 .ArrayTypeSentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),295 .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)),
297 .EnumLiteral => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)),296 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)),
298 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),297 .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)),
299 .CharLiteral => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),298 .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)),
300 .SliceType => return rvalue(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),299 .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)),
301 .ErrorUnion => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),300 .merge_error_sets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .merge_error_sets)),
302 .MergeErrorSets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),301 .anyframe_type => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node)),
303 .AnyFrameType => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),302 .error_set_decl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node)),
304 .ErrorSetDecl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node.castTag(.ErrorSetDecl).?)),303 .error_type => return rvalue(mod, scope, rl, try errorType(mod, scope, node)),
305 .ErrorType => return rvalue(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),304 .@"for" => return forExpr(mod, scope, rl, node),
306 .For => return forExpr(mod, scope, rl, node.castTag(.For).?),305 .array_access => return arrayAccess(mod, scope, rl, node),
307 .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),306 .slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node)),
308 .Slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)),307 .@"catch" => return catchExpr(mod, scope, rl, node),
309 .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),308 .@"comptime" => return comptimeKeyword(mod, scope, rl, node),
310 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),309 .@"orelse" => return orelseExpr(mod, scope, rl, node),
311 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),310 .@"switch" => return switchExpr(mod, scope, rl, node),
312 .Switch => return switchExpr(mod, scope, rl, node.castTag(.Switch).?),311 .ContainerDecl => return containerDecl(mod, scope, rl, node),
313 .ContainerDecl => return containerDecl(mod, scope, rl, node.castTag(.ContainerDecl).?),312
314313 .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),
315 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),314 .@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}),
316 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),315 .@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}),
317 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),316 .@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
318 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
319 .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}),317 .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}),
320 .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}),318 .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}),
321 .StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}),319 .StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}),
322 .StructInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializerDot", .{}),320 .StructInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializerDot", .{}),
323 .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}),321 .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),
324 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),322 .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),
325 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),323 .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}),
326 .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}),324 .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
327 }325 }
328}326}
329327
330fn comptimeKeyword(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Comptime) InnerError!*zir.Inst {328fn comptimeKeyword(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.@"comptime") InnerError!*zir.Inst {
331 const tracy = trace(@src());329 const tracy = trace(@src());
332 defer tracy.end();330 defer tracy.end();
333331
...@@ -338,7 +336,7 @@ pub fn comptimeExpr(...@@ -338,7 +336,7 @@ pub fn comptimeExpr(
338 mod: *Module,336 mod: *Module,
339 parent_scope: *Scope,337 parent_scope: *Scope,
340 rl: ResultLoc,338 rl: ResultLoc,
341 node: *ast.Node,339 node: ast.Node.Index,
342) InnerError!*zir.Inst {340) InnerError!*zir.Inst {
343 // If we are already in a comptime scope, no need to make another one.341 // If we are already in a comptime scope, no need to make another one.
344 if (parent_scope.isComptime()) {342 if (parent_scope.isComptime()) {
...@@ -347,7 +345,7 @@ pub fn comptimeExpr(...@@ -347,7 +345,7 @@ pub fn comptimeExpr(
347345
348 // Optimization for labeled blocks: don't need to have 2 layers of blocks,346 // Optimization for labeled blocks: don't need to have 2 layers of blocks,
349 // we can reuse the existing one.347 // we can reuse the existing one.
350 if (node.castTag(.LabeledBlock)) |block_node| {348 if (node.castTag(.labeled_block)) |block_node| {
351 return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime);349 return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime);
352 }350 }
353351
...@@ -366,6 +364,8 @@ pub fn comptimeExpr(...@@ -366,6 +364,8 @@ pub fn comptimeExpr(
366 _ = try expr(mod, &block_scope.base, rl, node);364 _ = try expr(mod, &block_scope.base, rl, node);
367365
368 const tree = parent_scope.tree();366 const tree = parent_scope.tree();
367 const node_datas = tree.nodes.items(.data);
368 const main_tokens = tree.nodes.items(.main_token);
369 const src = tree.token_locs[node.firstToken()].start;369 const src = tree.token_locs[node.firstToken()].start;
370370
371 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{371 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
...@@ -381,6 +381,8 @@ fn breakExpr(...@@ -381,6 +381,8 @@ fn breakExpr(
381 node: *ast.Node.ControlFlowExpression,381 node: *ast.Node.ControlFlowExpression,
382) InnerError!*zir.Inst {382) InnerError!*zir.Inst {
383 const tree = parent_scope.tree();383 const tree = parent_scope.tree();
384 const node_datas = tree.nodes.items(.data);
385 const main_tokens = tree.nodes.items(.main_token);
384 const src = tree.token_locs[node.ltoken].start;386 const src = tree.token_locs[node.ltoken].start;
385387
386 // Look for the label in the scope.388 // Look for the label in the scope.
...@@ -445,6 +447,8 @@ fn breakExpr(...@@ -445,6 +447,8 @@ fn breakExpr(
445447
446fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {448fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
447 const tree = parent_scope.tree();449 const tree = parent_scope.tree();
450 const node_datas = tree.nodes.items(.data);
451 const main_tokens = tree.nodes.items(.main_token);
448 const src = tree.token_locs[node.ltoken].start;452 const src = tree.token_locs[node.ltoken].start;
449453
450 // Look for the label in the scope.454 // Look for the label in the scope.
...@@ -485,7 +489,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE...@@ -485,7 +489,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
485 }489 }
486}490}
487491
488pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.Block) InnerError!void {492pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.block) InnerError!void {
489 const tracy = trace(@src());493 const tracy = trace(@src());
490 defer tracy.end();494 defer tracy.end();
491495
...@@ -502,6 +506,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn...@@ -502,6 +506,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
502 if (gen_zir.label) |prev_label| {506 if (gen_zir.label) |prev_label| {
503 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {507 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {
504 const tree = parent_scope.tree();508 const tree = parent_scope.tree();
509 const node_datas = tree.nodes.items(.data);
510 const main_tokens = tree.nodes.items(.main_token);
505 const label_src = tree.token_locs[label].start;511 const label_src = tree.token_locs[label].start;
506 const prev_label_src = tree.token_locs[prev_label.token].start;512 const prev_label_src = tree.token_locs[prev_label.token].start;
507513
...@@ -539,7 +545,7 @@ fn labeledBlockExpr(...@@ -539,7 +545,7 @@ fn labeledBlockExpr(
539 mod: *Module,545 mod: *Module,
540 parent_scope: *Scope,546 parent_scope: *Scope,
541 rl: ResultLoc,547 rl: ResultLoc,
542 block_node: *ast.Node.LabeledBlock,548 block_node: *ast.Node.labeled_block,
543 zir_tag: zir.Inst.Tag,549 zir_tag: zir.Inst.Tag,
544) InnerError!*zir.Inst {550) InnerError!*zir.Inst {
545 const tracy = trace(@src());551 const tracy = trace(@src());
...@@ -548,6 +554,8 @@ fn labeledBlockExpr(...@@ -548,6 +554,8 @@ fn labeledBlockExpr(
548 assert(zir_tag == .block or zir_tag == .block_comptime);554 assert(zir_tag == .block or zir_tag == .block_comptime);
549555
550 const tree = parent_scope.tree();556 const tree = parent_scope.tree();
557 const node_datas = tree.nodes.items(.data);
558 const main_tokens = tree.nodes.items(.main_token);
551 const src = tree.token_locs[block_node.lbrace].start;559 const src = tree.token_locs[block_node.lbrace].start;
552560
553 try checkLabelRedefinition(mod, parent_scope, block_node.label);561 try checkLabelRedefinition(mod, parent_scope, block_node.label);
...@@ -627,10 +635,12 @@ fn labeledBlockExpr(...@@ -627,10 +635,12 @@ fn labeledBlockExpr(
627fn blockExprStmts(635fn blockExprStmts(
628 mod: *Module,636 mod: *Module,
629 parent_scope: *Scope,637 parent_scope: *Scope,
630 node: *ast.Node,638 node: ast.Node.Index,
631 statements: []*ast.Node,639 statements: []const ast.Node.Index,
632) !void {640) !void {
633 const tree = parent_scope.tree();641 const tree = parent_scope.tree();
642 const node_datas = tree.nodes.items(.data);
643 const main_tokens = tree.nodes.items(.main_token);
634644
635 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);645 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
636 defer block_arena.deinit();646 defer block_arena.deinit();
...@@ -640,24 +650,24 @@ fn blockExprStmts(...@@ -640,24 +650,24 @@ fn blockExprStmts(
640 const src = tree.token_locs[statement.firstToken()].start;650 const src = tree.token_locs[statement.firstToken()].start;
641 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);651 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
642 switch (statement.tag) {652 switch (statement.tag) {
643 .VarDecl => {653 .var_decl => {
644 const var_decl_node = statement.castTag(.VarDecl).?;654 const var_decl_node = statement.castTag(.var_decl).?;
645 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);655 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);
646 },656 },
647 .Assign => try assign(mod, scope, statement.castTag(.Assign).?),657 .assign => try assign(mod, scope, statement),
648 .AssignBitAnd => try assignOp(mod, scope, statement.castTag(.AssignBitAnd).?, .bit_and),658 .assign_bit_and => try assignOp(mod, scope, statement, .bit_and),
649 .AssignBitOr => try assignOp(mod, scope, statement.castTag(.AssignBitOr).?, .bit_or),659 .assign_bit_or => try assignOp(mod, scope, statement, .bit_or),
650 .AssignBitShiftLeft => try assignOp(mod, scope, statement.castTag(.AssignBitShiftLeft).?, .shl),660 .assign_bit_shift_left => try assignOp(mod, scope, statement, .shl),
651 .AssignBitShiftRight => try assignOp(mod, scope, statement.castTag(.AssignBitShiftRight).?, .shr),661 .assign_bit_shift_right => try assignOp(mod, scope, statement, .shr),
652 .AssignBitXor => try assignOp(mod, scope, statement.castTag(.AssignBitXor).?, .xor),662 .assign_bit_xor => try assignOp(mod, scope, statement, .xor),
653 .AssignDiv => try assignOp(mod, scope, statement.castTag(.AssignDiv).?, .div),663 .assign_div => try assignOp(mod, scope, statement, .div),
654 .AssignSub => try assignOp(mod, scope, statement.castTag(.AssignSub).?, .sub),664 .assign_sub => try assignOp(mod, scope, statement, .sub),
655 .AssignSubWrap => try assignOp(mod, scope, statement.castTag(.AssignSubWrap).?, .subwrap),665 .assign_sub_wrap => try assignOp(mod, scope, statement, .subwrap),
656 .AssignMod => try assignOp(mod, scope, statement.castTag(.AssignMod).?, .mod_rem),666 .assign_mod => try assignOp(mod, scope, statement, .mod_rem),
657 .AssignAdd => try assignOp(mod, scope, statement.castTag(.AssignAdd).?, .add),667 .assign_add => try assignOp(mod, scope, statement, .add),
658 .AssignAddWrap => try assignOp(mod, scope, statement.castTag(.AssignAddWrap).?, .addwrap),668 .assign_add_wrap => try assignOp(mod, scope, statement, .addwrap),
659 .AssignMul => try assignOp(mod, scope, statement.castTag(.AssignMul).?, .mul),669 .assign_mul => try assignOp(mod, scope, statement, .mul),
660 .AssignMulWrap => try assignOp(mod, scope, statement.castTag(.AssignMulWrap).?, .mulwrap),670 .assign_mul_wrap => try assignOp(mod, scope, statement, .mulwrap),
661671
662 else => {672 else => {
663 const possibly_unused_result = try expr(mod, scope, .none, statement);673 const possibly_unused_result = try expr(mod, scope, .none, statement);
...@@ -672,7 +682,7 @@ fn blockExprStmts(...@@ -672,7 +682,7 @@ fn blockExprStmts(
672fn varDecl(682fn varDecl(
673 mod: *Module,683 mod: *Module,
674 scope: *Scope,684 scope: *Scope,
675 node: *ast.Node.VarDecl,685 node: *ast.Node.var_decl,
676 block_arena: *Allocator,686 block_arena: *Allocator,
677) InnerError!*Scope {687) InnerError!*Scope {
678 if (node.getComptimeToken()) |comptime_token| {688 if (node.getComptimeToken()) |comptime_token| {
...@@ -682,6 +692,8 @@ fn varDecl(...@@ -682,6 +692,8 @@ fn varDecl(
682 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});692 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});
683 }693 }
684 const tree = scope.tree();694 const tree = scope.tree();
695 const node_datas = tree.nodes.items(.data);
696 const main_tokens = tree.nodes.items(.main_token);
685 const name_src = tree.token_locs[node.name_token].start;697 const name_src = tree.token_locs[node.name_token].start;
686 const ident_name = try mod.identifierTokenString(scope, node.name_token);698 const ident_name = try mod.identifierTokenString(scope, node.name_token);
687699
...@@ -733,7 +745,7 @@ fn varDecl(...@@ -733,7 +745,7 @@ fn varDecl(
733 return mod.fail(scope, name_src, "variables must be initialized", .{});745 return mod.fail(scope, name_src, "variables must be initialized", .{});
734746
735 switch (tree.token_ids[node.mut_token]) {747 switch (tree.token_ids[node.mut_token]) {
736 .Keyword_const => {748 .keyword_const => {
737 // Depending on the type of AST the initialization expression is, we may need an lvalue749 // Depending on the type of AST the initialization expression is, we may need an lvalue
738 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as750 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
739 // the variable, no memory location needed.751 // the variable, no memory location needed.
...@@ -834,7 +846,7 @@ fn varDecl(...@@ -834,7 +846,7 @@ fn varDecl(
834 };846 };
835 return &sub_scope.base;847 return &sub_scope.base;
836 },848 },
837 .Keyword_var => {849 .keyword_var => {
838 var resolve_inferred_alloc: ?*zir.Inst = null;850 var resolve_inferred_alloc: ?*zir.Inst = null;
839 const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {851 const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {
840 const type_inst = try typeExpr(mod, scope, type_node);852 const type_inst = try typeExpr(mod, scope, type_node);
...@@ -862,33 +874,39 @@ fn varDecl(...@@ -862,33 +874,39 @@ fn varDecl(
862 }874 }
863}875}
864876
865fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!void {877fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!void {
866 if (infix_node.lhs.castTag(.Identifier)) |ident| {878 const tree = scope.tree();
867 // This intentionally does not support @"_" syntax.879 const node_datas = tree.nodes.items(.data);
868 const ident_name = scope.tree().tokenSlice(ident.token);880 const main_tokens = tree.nodes.items(.main_token);
881 const lhs = node_datas[infix_node].lhs;
882 const rhs = node_datas[infix_node].rhs;
883 if (node_tags[lhs] == .identifier) {
884 // This intentionally does not support `@"_"` syntax.
885 const ident_name = tree.tokenSlice(main_tokens[lhs]);
869 if (mem.eql(u8, ident_name, "_")) {886 if (mem.eql(u8, ident_name, "_")) {
870 _ = try expr(mod, scope, .discard, infix_node.rhs);887 _ = try expr(mod, scope, .discard, infix_node.rhs);
871 return;888 return;
872 }889 }
873 }890 }
874 const lvalue = try lvalExpr(mod, scope, infix_node.lhs);891 const lvalue = try lvalExpr(mod, scope, lhs);
875 _ = try expr(mod, scope, .{ .ptr = lvalue }, infix_node.rhs);892 _ = try expr(mod, scope, .{ .ptr = lvalue }, rhs);
876}893}
877894
878fn assignOp(895fn assignOp(
879 mod: *Module,896 mod: *Module,
880 scope: *Scope,897 scope: *Scope,
881 infix_node: *ast.Node.SimpleInfixOp,898 infix_node: ast.Node.Index,
882 op_inst_tag: zir.Inst.Tag,899 op_inst_tag: zir.Inst.Tag,
883) InnerError!void {900) InnerError!void {
884 const lhs_ptr = try lvalExpr(mod, scope, infix_node.lhs);
885 const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);
886 const lhs_type = try addZIRUnOp(mod, scope, lhs_ptr.src, .typeof, lhs);
887 const rhs = try expr(mod, scope, .{ .ty = lhs_type }, infix_node.rhs);
888
889 const tree = scope.tree();901 const tree = scope.tree();
890 const src = tree.token_locs[infix_node.op_token].start;902 const node_datas = tree.nodes.items(.data);
903 const main_tokens = tree.nodes.items(.main_token);
891904
905 const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs);
906 const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);
907 const lhs_type = try addZIRUnOp(mod, scope, lhs_ptr.src, .typeof, lhs);
908 const rhs = try expr(mod, scope, .{ .ty = lhs_type }, node_datas[infix_node].rhs);
909 const src = token_starts[main_tokens[infix_node]];
892 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);910 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
893 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);911 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
894}912}
...@@ -935,7 +953,7 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn...@@ -935,7 +953,7 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn
935 return addZIRUnOp(mod, scope, src, .optional_type, operand);953 return addZIRUnOp(mod, scope, src, .optional_type, operand);
936}954}
937955
938fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.SliceType) InnerError!*zir.Inst {956fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst {
939 const tree = scope.tree();957 const tree = scope.tree();
940 const src = tree.token_locs[node.op_token].start;958 const src = tree.token_locs[node.op_token].start;
941 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice);959 return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice);
...@@ -948,7 +966,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir...@@ -948,7 +966,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir
948 .Asterisk, .AsteriskAsterisk => .One,966 .Asterisk, .AsteriskAsterisk => .One,
949 // TODO stage1 type inference bug967 // TODO stage1 type inference bug
950 .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) {968 .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) {
951 .Identifier => .C,969 .identifier => .C,
952 else => .Many,970 else => .Many,
953 }),971 }),
954 else => unreachable,972 else => unreachable,
...@@ -998,7 +1016,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,...@@ -998,7 +1016,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
998 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);1016 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
999}1017}
10001018
1001fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst {1019fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst {
1002 const tree = scope.tree();1020 const tree = scope.tree();
1003 const src = tree.token_locs[node.op_token].start;1021 const src = tree.token_locs[node.op_token].start;
1004 const usize_type = try addZIRInstConst(mod, scope, src, .{1022 const usize_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1013,7 +1031,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst...@@ -1013,7 +1031,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst
1013 return addZIRBinOp(mod, scope, src, .array_type, len, elem_type);1031 return addZIRBinOp(mod, scope, src, .array_type, len, elem_type);
1014}1032}
10151033
1016fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst {1034fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst {
1017 const tree = scope.tree();1035 const tree = scope.tree();
1018 const src = tree.token_locs[node.op_token].start;1036 const src = tree.token_locs[node.op_token].start;
1019 const usize_type = try addZIRInstConst(mod, scope, src, .{1037 const usize_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1034,7 +1052,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti...@@ -1034,7 +1052,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti
1034 }, .{});1052 }, .{});
1035}1053}
10361054
1037fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.AnyFrameType) InnerError!*zir.Inst {1055fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst {
1038 const tree = scope.tree();1056 const tree = scope.tree();
1039 const src = tree.token_locs[node.anyframe_token].start;1057 const src = tree.token_locs[node.anyframe_token].start;
1040 if (node.result) |some| {1058 if (node.result) |some| {
...@@ -1056,7 +1074,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins...@@ -1056,7 +1074,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins
1056 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);1074 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);
1057}1075}
10581076
1059fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst {1077fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst {
1060 const tree = scope.tree();1078 const tree = scope.tree();
1061 const src = tree.token_locs[node.name].start;1079 const src = tree.token_locs[node.name].start;
1062 const name = try mod.identifierTokenString(scope, node.name);1080 const name = try mod.identifierTokenString(scope, node.name);
...@@ -1141,13 +1159,13 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1141,13 +1159,13 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
11411159
1142 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;1160 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
1143 if (node.layout_token) |some| switch (tree.token_ids[some]) {1161 if (node.layout_token) |some| switch (tree.token_ids[some]) {
1144 .Keyword_extern => layout = .Extern,1162 .keyword_extern => layout = .Extern,
1145 .Keyword_packed => layout = .Packed,1163 .keyword_packed => layout = .Packed,
1146 else => unreachable,1164 else => unreachable,
1147 };1165 };
11481166
1149 const container_type = switch (tree.token_ids[node.kind_token]) {1167 const container_type = switch (tree.token_ids[node.kind_token]) {
1150 .Keyword_enum => blk: {1168 .keyword_enum => blk: {
1151 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {1169 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {
1152 .Type => |t| try typeExpr(mod, &gen_scope.base, t),1170 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
1153 .None => null,1171 .None => null,
...@@ -1174,7 +1192,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1174,7 +1192,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1174 };1192 };
1175 break :blk Type.initPayload(&enum_type.base);1193 break :blk Type.initPayload(&enum_type.base);
1176 },1194 },
1177 .Keyword_struct => blk: {1195 .keyword_struct => blk: {
1178 assert(node.init_arg_expr == .None);1196 assert(node.init_arg_expr == .None);
1179 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{1197 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
1180 .fields = try arena.dupe(*zir.Inst, fields.items),1198 .fields = try arena.dupe(*zir.Inst, fields.items),
...@@ -1196,7 +1214,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1196,7 +1214,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1196 };1214 };
1197 break :blk Type.initPayload(&struct_type.base);1215 break :blk Type.initPayload(&struct_type.base);
1198 },1216 },
1199 .Keyword_union => blk: {1217 .keyword_union => blk: {
1200 const init_inst = switch (node.init_arg_expr) {1218 const init_inst = switch (node.init_arg_expr) {
1201 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,1219 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,
1202 .None => null,1220 .None => null,
...@@ -1229,7 +1247,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1229,7 +1247,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1229 };1247 };
1230 break :blk Type.initPayload(&union_type.base);1248 break :blk Type.initPayload(&union_type.base);
1231 },1249 },
1232 .Keyword_opaque => blk: {1250 .keyword_opaque => blk: {
1233 if (fields.items.len > 0) {1251 if (fields.items.len > 0) {
1234 return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{});1252 return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{});
1235 }1253 }
...@@ -1258,7 +1276,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con...@@ -1258,7 +1276,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
1258 }1276 }
1259}1277}
12601278
1261fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.ErrorSetDecl) InnerError!*zir.Inst {1279fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst {
1262 const tree = scope.tree();1280 const tree = scope.tree();
1263 const src = tree.token_locs[node.error_token].start;1281 const src = tree.token_locs[node.error_token].start;
1264 const decls = node.decls();1282 const decls = node.decls();
...@@ -1281,7 +1299,7 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*...@@ -1281,7 +1299,7 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*
1281 });1299 });
1282}1300}
12831301
1284fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch) InnerError!*zir.Inst {1302fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.@"catch") InnerError!*zir.Inst {
1285 switch (rl) {1303 switch (rl) {
1286 .ref => return orelseCatchExpr(1304 .ref => return orelseCatchExpr(
1287 mod,1305 mod,
...@@ -1528,7 +1546,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI...@@ -1528,7 +1546,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI
1528 const tree = scope.tree();1546 const tree = scope.tree();
1529 const src = tree.token_locs[node.op_token].start;1547 const src = tree.token_locs[node.op_token].start;
1530 // TODO custom AST node for field access so that we don't have to go through a node cast here1548 // TODO custom AST node for field access so that we don't have to go through a node cast here
1531 const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.Identifier).?.token);1549 const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token);
1532 if (rl == .ref) {1550 if (rl == .ref) {
1533 return addZirInstTag(mod, scope, src, .field_ptr, .{1551 return addZirInstTag(mod, scope, src, .field_ptr, .{
1534 .object = try expr(mod, scope, .ref, node.lhs),1552 .object = try expr(mod, scope, .ref, node.lhs),
...@@ -1545,7 +1563,7 @@ fn namedField(...@@ -1545,7 +1563,7 @@ fn namedField(
1545 mod: *Module,1563 mod: *Module,
1546 scope: *Scope,1564 scope: *Scope,
1547 rl: ResultLoc,1565 rl: ResultLoc,
1548 call: *ast.Node.BuiltinCall,1566 call: *ast.Node.builtin_call,
1549) InnerError!*zir.Inst {1567) InnerError!*zir.Inst {
1550 try ensureBuiltinParamCount(mod, scope, call, 2);1568 try ensureBuiltinParamCount(mod, scope, call, 2);
15511569
...@@ -1571,7 +1589,7 @@ fn namedField(...@@ -1571,7 +1589,7 @@ fn namedField(
1571 }));1589 }));
1572}1590}
15731591
1574fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ArrayAccess) InnerError!*zir.Inst {1592fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst {
1575 const tree = scope.tree();1593 const tree = scope.tree();
1576 const src = tree.token_locs[node.rtoken].start;1594 const src = tree.token_locs[node.rtoken].start;
1577 const usize_type = try addZIRInstConst(mod, scope, src, .{1595 const usize_type = try addZIRInstConst(mod, scope, src, .{
...@@ -1592,7 +1610,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array...@@ -1592,7 +1610,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array
1592 }));1610 }));
1593}1611}
15941612
1595fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.Slice) InnerError!*zir.Inst {1613fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst {
1596 const tree = scope.tree();1614 const tree = scope.tree();
1597 const src = tree.token_locs[node.rtoken].start;1615 const src = tree.token_locs[node.rtoken].start;
15981616
...@@ -1633,15 +1651,16 @@ fn simpleBinOp(...@@ -1633,15 +1651,16 @@ fn simpleBinOp(
1633 mod: *Module,1651 mod: *Module,
1634 scope: *Scope,1652 scope: *Scope,
1635 rl: ResultLoc,1653 rl: ResultLoc,
1636 infix_node: *ast.Node.SimpleInfixOp,1654 infix_node: ast.Node.Index,
1637 op_inst_tag: zir.Inst.Tag,1655 op_inst_tag: zir.Inst.Tag,
1638) InnerError!*zir.Inst {1656) InnerError!*zir.Inst {
1639 const tree = scope.tree();1657 const tree = scope.tree();
1640 const src = tree.token_locs[infix_node.op_token].start;1658 const node_datas = tree.nodes.items(.data);
16411659 const main_tokens = tree.nodes.items(.main_token);
1642 const lhs = try expr(mod, scope, .none, infix_node.lhs);
1643 const rhs = try expr(mod, scope, .none, infix_node.rhs);
16441660
1661 const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs);
1662 const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs);
1663 const src = token_starts[main_tokens[infix_node]];
1645 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);1664 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
1646 return rvalue(mod, scope, rl, result);1665 return rvalue(mod, scope, rl, result);
1647}1666}
...@@ -1653,6 +1672,9 @@ fn boolBinOp(...@@ -1653,6 +1672,9 @@ fn boolBinOp(
1653 infix_node: *ast.Node.SimpleInfixOp,1672 infix_node: *ast.Node.SimpleInfixOp,
1654) InnerError!*zir.Inst {1673) InnerError!*zir.Inst {
1655 const tree = scope.tree();1674 const tree = scope.tree();
1675 const node_datas = tree.nodes.items(.data);
1676 const main_tokens = tree.nodes.items(.main_token);
1677
1656 const src = tree.token_locs[infix_node.op_token].start;1678 const src = tree.token_locs[infix_node.op_token].start;
1657 const bool_type = try addZIRInstConst(mod, scope, src, .{1679 const bool_type = try addZIRInstConst(mod, scope, src, .{
1658 .ty = Type.initTag(.type),1680 .ty = Type.initTag(.type),
...@@ -1703,7 +1725,7 @@ fn boolBinOp(...@@ -1703,7 +1725,7 @@ fn boolBinOp(
1703 };1725 };
1704 defer const_scope.instructions.deinit(mod.gpa);1726 defer const_scope.instructions.deinit(mod.gpa);
17051727
1706 const is_bool_and = infix_node.base.tag == .BoolAnd;1728 const is_bool_and = infix_node.base.tag == .bool_and;
1707 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{1729 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{
1708 .block = block,1730 .block = block,
1709 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{1731 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{
...@@ -1769,7 +1791,7 @@ const CondKind = union(enum) {...@@ -1769,7 +1791,7 @@ const CondKind = union(enum) {
1769 return &then_scope.base;1791 return &then_scope.base;
1770 };1792 };
1771 const is_ptr = payload.ptr_token != null;1793 const is_ptr = payload.ptr_token != null;
1772 const ident_node = payload.value_symbol.castTag(.Identifier).?;1794 const ident_node = payload.value_symbol.castTag(.identifier).?;
17731795
1774 // This intentionally does not support @"_" syntax.1796 // This intentionally does not support @"_" syntax.
1775 const ident_name = then_scope.base.tree().tokenSlice(ident_node.token);1797 const ident_name = then_scope.base.tree().tokenSlice(ident_node.token);
...@@ -1788,7 +1810,7 @@ const CondKind = union(enum) {...@@ -1788,7 +1810,7 @@ const CondKind = union(enum) {
1788 const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .err_union_payload_unsafe_ptr, self.err_union.?);1810 const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .err_union_payload_unsafe_ptr, self.err_union.?);
17891811
1790 const payload = payload_node.?.castTag(.Payload).?;1812 const payload = payload_node.?.castTag(.Payload).?;
1791 const ident_node = payload.error_symbol.castTag(.Identifier).?;1813 const ident_node = payload.error_symbol.castTag(.identifier).?;
17921814
1793 // This intentionally does not support @"_" syntax.1815 // This intentionally does not support @"_" syntax.
1794 const ident_name = else_scope.base.tree().tokenSlice(ident_node.token);1816 const ident_name = else_scope.base.tree().tokenSlice(ident_node.token);
...@@ -1800,7 +1822,7 @@ const CondKind = union(enum) {...@@ -1800,7 +1822,7 @@ const CondKind = union(enum) {
1800 }1822 }
1801};1823};
18021824
1803fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) InnerError!*zir.Inst {1825fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") InnerError!*zir.Inst {
1804 var cond_kind: CondKind = .bool;1826 var cond_kind: CondKind = .bool;
1805 if (if_node.payload) |_| cond_kind = .{ .optional = null };1827 if (if_node.payload) |_| cond_kind = .{ .optional = null };
1806 if (if_node.@"else") |else_node| {1828 if (if_node.@"else") |else_node| {
...@@ -1819,6 +1841,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn...@@ -1819,6 +1841,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
1819 defer block_scope.instructions.deinit(mod.gpa);1841 defer block_scope.instructions.deinit(mod.gpa);
18201842
1821 const tree = scope.tree();1843 const tree = scope.tree();
1844 const node_datas = tree.nodes.items(.data);
1845 const main_tokens = tree.nodes.items(.main_token);
1822 const if_src = tree.token_locs[if_node.if_token].start;1846 const if_src = tree.token_locs[if_node.if_token].start;
1823 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);1847 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);
18241848
...@@ -1918,7 +1942,7 @@ fn whileExpr(...@@ -1918,7 +1942,7 @@ fn whileExpr(
1918 mod: *Module,1942 mod: *Module,
1919 scope: *Scope,1943 scope: *Scope,
1920 rl: ResultLoc,1944 rl: ResultLoc,
1921 while_node: *ast.Node.While,1945 while_node: *ast.Node.@"while",
1922) InnerError!*zir.Inst {1946) InnerError!*zir.Inst {
1923 var cond_kind: CondKind = .bool;1947 var cond_kind: CondKind = .bool;
1924 if (while_node.payload) |_| cond_kind = .{ .optional = null };1948 if (while_node.payload) |_| cond_kind = .{ .optional = null };
...@@ -1955,6 +1979,8 @@ fn whileExpr(...@@ -1955,6 +1979,8 @@ fn whileExpr(
1955 defer continue_scope.instructions.deinit(mod.gpa);1979 defer continue_scope.instructions.deinit(mod.gpa);
19561980
1957 const tree = scope.tree();1981 const tree = scope.tree();
1982 const node_datas = tree.nodes.items(.data);
1983 const main_tokens = tree.nodes.items(.main_token);
1958 const while_src = tree.token_locs[while_node.while_token].start;1984 const while_src = tree.token_locs[while_node.while_token].start;
1959 const void_type = try addZIRInstConst(mod, scope, while_src, .{1985 const void_type = try addZIRInstConst(mod, scope, while_src, .{
1960 .ty = Type.initTag(.type),1986 .ty = Type.initTag(.type),
...@@ -2066,7 +2092,7 @@ fn forExpr(...@@ -2066,7 +2092,7 @@ fn forExpr(
2066 mod: *Module,2092 mod: *Module,
2067 scope: *Scope,2093 scope: *Scope,
2068 rl: ResultLoc,2094 rl: ResultLoc,
2069 for_node: *ast.Node.For,2095 for_node: *ast.Node.@"for",
2070) InnerError!*zir.Inst {2096) InnerError!*zir.Inst {
2071 if (for_node.label) |label| {2097 if (for_node.label) |label| {
2072 try checkLabelRedefinition(mod, scope, label);2098 try checkLabelRedefinition(mod, scope, label);
...@@ -2077,6 +2103,8 @@ fn forExpr(...@@ -2077,6 +2103,8 @@ fn forExpr(
20772103
2078 // setup variables and constants2104 // setup variables and constants
2079 const tree = scope.tree();2105 const tree = scope.tree();
2106 const node_datas = tree.nodes.items(.data);
2107 const main_tokens = tree.nodes.items(.main_token);
2080 const for_src = tree.token_locs[for_node.for_token].start;2108 const for_src = tree.token_locs[for_node.for_token].start;
2081 const index_ptr = blk: {2109 const index_ptr = blk: {
2082 const usize_type = try addZIRInstConst(mod, scope, for_src, .{2110 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
...@@ -2246,9 +2274,9 @@ fn forExpr(...@@ -2246,9 +2274,9 @@ fn forExpr(
2246 );2274 );
2247}2275}
22482276
2249fn switchCaseUsesRef(node: *ast.Node.Switch) bool {2277fn switchCaseUsesRef(node: *ast.Node.@"switch") bool {
2250 for (node.cases()) |uncasted_case| {2278 for (node.cases()) |uncasted_case| {
2251 const case = uncasted_case.castTag(.SwitchCase).?;2279 const case = uncasted_case.castTag(.switch_case).?;
2252 const uncasted_payload = case.payload orelse continue;2280 const uncasted_payload = case.payload orelse continue;
2253 const payload = uncasted_payload.castTag(.PointerPayload).?;2281 const payload = uncasted_payload.castTag(.PointerPayload).?;
2254 if (payload.ptr_token) |_| return true;2282 if (payload.ptr_token) |_| return true;
...@@ -2260,15 +2288,17 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp {...@@ -2260,15 +2288,17 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp {
2260 var cur = node;2288 var cur = node;
2261 while (true) {2289 while (true) {
2262 switch (cur.tag) {2290 switch (cur.tag) {
2263 .Range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur),2291 .range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur),
2264 .GroupedExpression => cur = @fieldParentPtr(ast.Node.GroupedExpression, "base", cur).expr,2292 .grouped_expression => cur = @fieldParentPtr(ast.Node.grouped_expression, "base", cur).expr,
2265 else => return null,2293 else => return null,
2266 }2294 }
2267 }2295 }
2268}2296}
22692297
2270fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node.Switch) InnerError!*zir.Inst {2298fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node.@"switch") InnerError!*zir.Inst {
2271 const tree = scope.tree();2299 const tree = scope.tree();
2300 const node_datas = tree.nodes.items(.data);
2301 const main_tokens = tree.nodes.items(.main_token);
2272 const switch_src = tree.token_locs[switch_node.switch_token].start;2302 const switch_src = tree.token_locs[switch_node.switch_token].start;
2273 const use_ref = switchCaseUsesRef(switch_node);2303 const use_ref = switchCaseUsesRef(switch_node);
22742304
...@@ -2291,12 +2321,12 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2291,12 +2321,12 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2291 var first_range: ?*zir.Inst = null;2321 var first_range: ?*zir.Inst = null;
2292 var simple_case_count: usize = 0;2322 var simple_case_count: usize = 0;
2293 for (switch_node.cases()) |uncasted_case| {2323 for (switch_node.cases()) |uncasted_case| {
2294 const case = uncasted_case.castTag(.SwitchCase).?;2324 const case = uncasted_case.castTag(.switch_case).?;
2295 const case_src = tree.token_locs[case.firstToken()].start;2325 const case_src = tree.token_locs[case.firstToken()].start;
2296 assert(case.items_len != 0);2326 assert(case.items_len != 0);
22972327
2298 // Check for else/_ prong, those are handled last.2328 // Check for else/_ prong, those are handled last.
2299 if (case.items_len == 1 and case.items()[0].tag == .SwitchElse) {2329 if (case.items_len == 1 and case.items()[0].tag == .switch_else) {
2300 if (else_src) |src| {2330 if (else_src) |src| {
2301 const msg = msg: {2331 const msg = msg: {
2302 const msg = try mod.errMsg(2332 const msg = try mod.errMsg(
...@@ -2313,7 +2343,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2313,7 +2343,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2313 }2343 }
2314 else_src = case_src;2344 else_src = case_src;
2315 continue;2345 continue;
2316 } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and2346 } else if (case.items_len == 1 and case.items()[0].tag == .identifier and
2317 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))2347 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))
2318 {2348 {
2319 if (underscore_src) |src| {2349 if (underscore_src) |src| {
...@@ -2412,20 +2442,20 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node...@@ -2412,20 +2442,20 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
2412 defer else_scope.instructions.deinit(mod.gpa);2442 defer else_scope.instructions.deinit(mod.gpa);
24132443
2414 // Now generate all but the special cases2444 // Now generate all but the special cases
2415 var special_case: ?*ast.Node.SwitchCase = null;2445 var special_case: ?*ast.Node.switch_case = null;
2416 var items_index: usize = 0;2446 var items_index: usize = 0;
2417 var case_index: usize = 0;2447 var case_index: usize = 0;
2418 for (switch_node.cases()) |uncasted_case| {2448 for (switch_node.cases()) |uncasted_case| {
2419 const case = uncasted_case.castTag(.SwitchCase).?;2449 const case = uncasted_case.castTag(.switch_case).?;
2420 const case_src = tree.token_locs[case.firstToken()].start;2450 const case_src = tree.token_locs[case.firstToken()].start;
2421 // reset without freeing to reduce allocations.2451 // reset without freeing to reduce allocations.
2422 case_scope.instructions.items.len = 0;2452 case_scope.instructions.items.len = 0;
24232453
2424 // Check for else/_ prong, those are handled last.2454 // Check for else/_ prong, those are handled last.
2425 if (case.items_len == 1 and case.items()[0].tag == .SwitchElse) {2455 if (case.items_len == 1 and case.items()[0].tag == .switch_else) {
2426 special_case = case;2456 special_case = case;
2427 continue;2457 continue;
2428 } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and2458 } else if (case.items_len == 1 and case.items()[0].tag == .identifier and
2429 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))2459 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))
2430 {2460 {
2431 special_case = case;2461 special_case = case;
...@@ -2528,11 +2558,13 @@ fn switchCaseExpr(...@@ -2528,11 +2558,13 @@ fn switchCaseExpr(
2528 scope: *Scope,2558 scope: *Scope,
2529 rl: ResultLoc,2559 rl: ResultLoc,
2530 block: *zir.Inst.Block,2560 block: *zir.Inst.Block,
2531 case: *ast.Node.SwitchCase,2561 case: *ast.Node.switch_case,
2532 target: *zir.Inst,2562 target: *zir.Inst,
2533 target_ptr: ?*zir.Inst,2563 target_ptr: ?*zir.Inst,
2534) !void {2564) !void {
2535 const tree = scope.tree();2565 const tree = scope.tree();
2566 const node_datas = tree.nodes.items(.data);
2567 const main_tokens = tree.nodes.items(.main_token);
2536 const case_src = tree.token_locs[case.firstToken()].start;2568 const case_src = tree.token_locs[case.firstToken()].start;
2537 const sub_scope = blk: {2569 const sub_scope = blk: {
2538 const uncasted_payload = case.payload orelse break :blk scope;2570 const uncasted_payload = case.payload orelse break :blk scope;
...@@ -2559,6 +2591,8 @@ fn switchCaseExpr(...@@ -2559,6 +2591,8 @@ fn switchCaseExpr(
25592591
2560fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {2592fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
2561 const tree = scope.tree();2593 const tree = scope.tree();
2594 const node_datas = tree.nodes.items(.data);
2595 const main_tokens = tree.nodes.items(.main_token);
2562 const src = tree.token_locs[cfe.ltoken].start;2596 const src = tree.token_locs[cfe.ltoken].start;
2563 if (cfe.getRHS()) |rhs_node| {2597 if (cfe.getRHS()) |rhs_node| {
2564 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {2598 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
...@@ -2580,6 +2614,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -2580,6 +2614,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
2580 defer tracy.end();2614 defer tracy.end();
25812615
2582 const tree = scope.tree();2616 const tree = scope.tree();
2617 const node_datas = tree.nodes.items(.data);
2618 const main_tokens = tree.nodes.items(.main_token);
2583 const ident_name = try mod.identifierTokenString(scope, ident.token);2619 const ident_name = try mod.identifierTokenString(scope, ident.token);
2584 const src = tree.token_locs[ident.token].start;2620 const src = tree.token_locs[ident.token].start;
2585 if (mem.eql(u8, ident_name, "_")) {2621 if (mem.eql(u8, ident_name, "_")) {
...@@ -2667,6 +2703,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo...@@ -2667,6 +2703,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
26672703
2668fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst {2704fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
2669 const tree = scope.tree();2705 const tree = scope.tree();
2706 const node_datas = tree.nodes.items(.data);
2707 const main_tokens = tree.nodes.items(.main_token);
2670 const unparsed_bytes = tree.tokenSlice(str_lit.token);2708 const unparsed_bytes = tree.tokenSlice(str_lit.token);
2671 const arena = scope.arena();2709 const arena = scope.arena();
26722710
...@@ -2686,6 +2724,8 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner...@@ -2686,6 +2724,8 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner
26862724
2687fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst {2725fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst {
2688 const tree = scope.tree();2726 const tree = scope.tree();
2727 const node_datas = tree.nodes.items(.data);
2728 const main_tokens = tree.nodes.items(.main_token);
2689 const lines = node.linesConst();2729 const lines = node.linesConst();
2690 const src = tree.token_locs[lines[0]].start;2730 const src = tree.token_locs[lines[0]].start;
26912731
...@@ -2713,6 +2753,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr...@@ -2713,6 +2753,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr
27132753
2714fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {2754fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {
2715 const tree = scope.tree();2755 const tree = scope.tree();
2756 const node_datas = tree.nodes.items(.data);
2757 const main_tokens = tree.nodes.items(.main_token);
2716 const src = tree.token_locs[node.token].start;2758 const src = tree.token_locs[node.token].start;
2717 const slice = tree.tokenSlice(node.token);2759 const slice = tree.tokenSlice(node.token);
27182760
...@@ -2733,6 +2775,8 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst...@@ -2733,6 +2775,8 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst
2733fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst {2775fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
2734 const arena = scope.arena();2776 const arena = scope.arena();
2735 const tree = scope.tree();2777 const tree = scope.tree();
2778 const node_datas = tree.nodes.items(.data);
2779 const main_tokens = tree.nodes.items(.main_token);
2736 const prefixed_bytes = tree.tokenSlice(int_lit.token);2780 const prefixed_bytes = tree.tokenSlice(int_lit.token);
2737 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))2781 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))
2738 162782 16
...@@ -2762,6 +2806,8 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne...@@ -2762,6 +2806,8 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne
2762fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) InnerError!*zir.Inst {2806fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
2763 const arena = scope.arena();2807 const arena = scope.arena();
2764 const tree = scope.tree();2808 const tree = scope.tree();
2809 const node_datas = tree.nodes.items(.data);
2810 const main_tokens = tree.nodes.items(.main_token);
2765 const bytes = tree.tokenSlice(float_lit.token);2811 const bytes = tree.tokenSlice(float_lit.token);
2766 if (bytes.len > 2 and bytes[1] == 'x') {2812 if (bytes.len > 2 and bytes[1] == 'x') {
2767 return mod.failTok(scope, float_lit.token, "TODO hex floats", .{});2813 return mod.failTok(scope, float_lit.token, "TODO hex floats", .{});
...@@ -2780,6 +2826,8 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne...@@ -2780,6 +2826,8 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne
2780fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {2826fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
2781 const arena = scope.arena();2827 const arena = scope.arena();
2782 const tree = scope.tree();2828 const tree = scope.tree();
2829 const node_datas = tree.nodes.items(.data);
2830 const main_tokens = tree.nodes.items(.main_token);
2783 const src = tree.token_locs[node.token].start;2831 const src = tree.token_locs[node.token].start;
2784 return addZIRInstConst(mod, scope, src, .{2832 return addZIRInstConst(mod, scope, src, .{
2785 .ty = Type.initTag(.@"undefined"),2833 .ty = Type.initTag(.@"undefined"),
...@@ -2790,12 +2838,14 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro...@@ -2790,12 +2838,14 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro
2790fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {2838fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
2791 const arena = scope.arena();2839 const arena = scope.arena();
2792 const tree = scope.tree();2840 const tree = scope.tree();
2841 const node_datas = tree.nodes.items(.data);
2842 const main_tokens = tree.nodes.items(.main_token);
2793 const src = tree.token_locs[node.token].start;2843 const src = tree.token_locs[node.token].start;
2794 return addZIRInstConst(mod, scope, src, .{2844 return addZIRInstConst(mod, scope, src, .{
2795 .ty = Type.initTag(.bool),2845 .ty = Type.initTag(.bool),
2796 .val = switch (tree.token_ids[node.token]) {2846 .val = switch (tree.token_ids[node.token]) {
2797 .Keyword_true => Value.initTag(.bool_true),2847 .keyword_true => Value.initTag(.bool_true),
2798 .Keyword_false => Value.initTag(.bool_false),2848 .keyword_false => Value.initTag(.bool_false),
2799 else => unreachable,2849 else => unreachable,
2800 },2850 },
2801 });2851 });
...@@ -2804,6 +2854,8 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError...@@ -2804,6 +2854,8 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
2804fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {2854fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
2805 const arena = scope.arena();2855 const arena = scope.arena();
2806 const tree = scope.tree();2856 const tree = scope.tree();
2857 const node_datas = tree.nodes.items(.data);
2858 const main_tokens = tree.nodes.items(.main_token);
2807 const src = tree.token_locs[node.token].start;2859 const src = tree.token_locs[node.token].start;
2808 return addZIRInstConst(mod, scope, src, .{2860 return addZIRInstConst(mod, scope, src, .{
2809 .ty = Type.initTag(.@"null"),2861 .ty = Type.initTag(.@"null"),
...@@ -2811,12 +2863,14 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError...@@ -2811,12 +2863,14 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
2811 });2863 });
2812}2864}
28132865
2814fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zir.Inst {2866fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!*zir.Inst {
2815 if (asm_node.outputs.len != 0) {2867 if (asm_node.outputs.len != 0) {
2816 return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});2868 return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});
2817 }2869 }
2818 const arena = scope.arena();2870 const arena = scope.arena();
2819 const tree = scope.tree();2871 const tree = scope.tree();
2872 const node_datas = tree.nodes.items(.data);
2873 const main_tokens = tree.nodes.items(.main_token);
28202874
2821 const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len);2875 const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len);
2822 const args = try arena.alloc(*zir.Inst, asm_node.inputs.len);2876 const args = try arena.alloc(*zir.Inst, asm_node.inputs.len);
...@@ -2839,7 +2893,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi...@@ -2839,7 +2893,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi
2839 .ty = Type.initTag(.type),2893 .ty = Type.initTag(.type),
2840 .val = Value.initTag(.void_type),2894 .val = Value.initTag(.void_type),
2841 });2895 });
2842 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{2896 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{
2843 .asm_source = try expr(mod, scope, str_type_rl, asm_node.template),2897 .asm_source = try expr(mod, scope, str_type_rl, asm_node.template),
2844 .return_type = return_type,2898 .return_type = return_type,
2845 }, .{2899 }, .{
...@@ -2851,7 +2905,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi...@@ -2851,7 +2905,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi
2851 return asm_inst;2905 return asm_inst;
2852}2906}
28532907
2854fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall, count: u32) !void {2908fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void {
2855 if (call.params_len == count)2909 if (call.params_len == count)
2856 return;2910 return;
28572911
...@@ -2863,11 +2917,13 @@ fn simpleCast(...@@ -2863,11 +2917,13 @@ fn simpleCast(
2863 mod: *Module,2917 mod: *Module,
2864 scope: *Scope,2918 scope: *Scope,
2865 rl: ResultLoc,2919 rl: ResultLoc,
2866 call: *ast.Node.BuiltinCall,2920 call: *ast.Node.builtin_call,
2867 inst_tag: zir.Inst.Tag,2921 inst_tag: zir.Inst.Tag,
2868) InnerError!*zir.Inst {2922) InnerError!*zir.Inst {
2869 try ensureBuiltinParamCount(mod, scope, call, 2);2923 try ensureBuiltinParamCount(mod, scope, call, 2);
2870 const tree = scope.tree();2924 const tree = scope.tree();
2925 const node_datas = tree.nodes.items(.data);
2926 const main_tokens = tree.nodes.items(.main_token);
2871 const src = tree.token_locs[call.builtin_token].start;2927 const src = tree.token_locs[call.builtin_token].start;
2872 const params = call.params();2928 const params = call.params();
2873 const dest_type = try typeExpr(mod, scope, params[0]);2929 const dest_type = try typeExpr(mod, scope, params[0]);
...@@ -2876,10 +2932,12 @@ fn simpleCast(...@@ -2876,10 +2932,12 @@ fn simpleCast(
2876 return rvalue(mod, scope, rl, result);2932 return rvalue(mod, scope, rl, result);
2877}2933}
28782934
2879fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {2935fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
2880 try ensureBuiltinParamCount(mod, scope, call, 1);2936 try ensureBuiltinParamCount(mod, scope, call, 1);
2881 const operand = try expr(mod, scope, .none, call.params()[0]);2937 const operand = try expr(mod, scope, .none, call.params()[0]);
2882 const tree = scope.tree();2938 const tree = scope.tree();
2939 const node_datas = tree.nodes.items(.data);
2940 const main_tokens = tree.nodes.items(.main_token);
2883 const src = tree.token_locs[call.builtin_token].start;2941 const src = tree.token_locs[call.builtin_token].start;
2884 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);2942 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);
2885}2943}
...@@ -2888,10 +2946,12 @@ fn as(...@@ -2888,10 +2946,12 @@ fn as(
2888 mod: *Module,2946 mod: *Module,
2889 scope: *Scope,2947 scope: *Scope,
2890 rl: ResultLoc,2948 rl: ResultLoc,
2891 call: *ast.Node.BuiltinCall,2949 call: *ast.Node.builtin_call,
2892) InnerError!*zir.Inst {2950) InnerError!*zir.Inst {
2893 try ensureBuiltinParamCount(mod, scope, call, 2);2951 try ensureBuiltinParamCount(mod, scope, call, 2);
2894 const tree = scope.tree();2952 const tree = scope.tree();
2953 const node_datas = tree.nodes.items(.data);
2954 const main_tokens = tree.nodes.items(.main_token);
2895 const src = tree.token_locs[call.builtin_token].start;2955 const src = tree.token_locs[call.builtin_token].start;
2896 const params = call.params();2956 const params = call.params();
2897 const dest_type = try typeExpr(mod, scope, params[0]);2957 const dest_type = try typeExpr(mod, scope, params[0]);
...@@ -2963,9 +3023,11 @@ fn asRlPtr(...@@ -2963,9 +3023,11 @@ fn asRlPtr(
2963 }3023 }
2964}3024}
29653025
2966fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3026fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
2967 try ensureBuiltinParamCount(mod, scope, call, 2);3027 try ensureBuiltinParamCount(mod, scope, call, 2);
2968 const tree = scope.tree();3028 const tree = scope.tree();
3029 const node_datas = tree.nodes.items(.data);
3030 const main_tokens = tree.nodes.items(.main_token);
2969 const src = tree.token_locs[call.builtin_token].start;3031 const src = tree.token_locs[call.builtin_token].start;
2970 const params = call.params();3032 const params = call.params();
2971 const dest_type = try typeExpr(mod, scope, params[0]);3033 const dest_type = try typeExpr(mod, scope, params[0]);
...@@ -3007,27 +3069,33 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa...@@ -3007,27 +3069,33 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa
3007 }3069 }
3008}3070}
30093071
3010fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3072fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3011 try ensureBuiltinParamCount(mod, scope, call, 1);3073 try ensureBuiltinParamCount(mod, scope, call, 1);
3012 const tree = scope.tree();3074 const tree = scope.tree();
3075 const node_datas = tree.nodes.items(.data);
3076 const main_tokens = tree.nodes.items(.main_token);
3013 const src = tree.token_locs[call.builtin_token].start;3077 const src = tree.token_locs[call.builtin_token].start;
3014 const params = call.params();3078 const params = call.params();
3015 const target = try expr(mod, scope, .none, params[0]);3079 const target = try expr(mod, scope, .none, params[0]);
3016 return addZIRUnOp(mod, scope, src, .import, target);3080 return addZIRUnOp(mod, scope, src, .import, target);
3017}3081}
30183082
3019fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3083fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3020 try ensureBuiltinParamCount(mod, scope, call, 1);3084 try ensureBuiltinParamCount(mod, scope, call, 1);
3021 const tree = scope.tree();3085 const tree = scope.tree();
3086 const node_datas = tree.nodes.items(.data);
3087 const main_tokens = tree.nodes.items(.main_token);
3022 const src = tree.token_locs[call.builtin_token].start;3088 const src = tree.token_locs[call.builtin_token].start;
3023 const params = call.params();3089 const params = call.params();
3024 const target = try expr(mod, scope, .none, params[0]);3090 const target = try expr(mod, scope, .none, params[0]);
3025 return addZIRUnOp(mod, scope, src, .compile_error, target);3091 return addZIRUnOp(mod, scope, src, .compile_error, target);
3026}3092}
30273093
3028fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3094fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3029 try ensureBuiltinParamCount(mod, scope, call, 1);3095 try ensureBuiltinParamCount(mod, scope, call, 1);
3030 const tree = scope.tree();3096 const tree = scope.tree();
3097 const node_datas = tree.nodes.items(.data);
3098 const main_tokens = tree.nodes.items(.main_token);
3031 const src = tree.token_locs[call.builtin_token].start;3099 const src = tree.token_locs[call.builtin_token].start;
3032 const params = call.params();3100 const params = call.params();
3033 const u32_type = try addZIRInstConst(mod, scope, src, .{3101 const u32_type = try addZIRInstConst(mod, scope, src, .{
...@@ -3038,8 +3106,10 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall)...@@ -3038,8 +3106,10 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall)
3038 return addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota);3106 return addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota);
3039}3107}
30403108
3041fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3109fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3042 const tree = scope.tree();3110 const tree = scope.tree();
3111 const node_datas = tree.nodes.items(.data);
3112 const main_tokens = tree.nodes.items(.main_token);
3043 const arena = scope.arena();3113 const arena = scope.arena();
3044 const src = tree.token_locs[call.builtin_token].start;3114 const src = tree.token_locs[call.builtin_token].start;
3045 const params = call.params();3115 const params = call.params();
...@@ -3054,8 +3124,10 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal...@@ -3054,8 +3124,10 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal
3054 items[param_i] = try expr(mod, scope, .none, param);3124 items[param_i] = try expr(mod, scope, .none, param);
3055 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));3125 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));
3056}3126}
3057fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3127fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3058 const tree = scope.tree();3128 const tree = scope.tree();
3129 const node_datas = tree.nodes.items(.data);
3130 const main_tokens = tree.nodes.items(.main_token);
3059 const arena = scope.arena();3131 const arena = scope.arena();
3060 const src = tree.token_locs[call.builtin_token].start;3132 const src = tree.token_locs[call.builtin_token].start;
3061 const params = call.params();3133 const params = call.params();
...@@ -3065,8 +3137,10 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerErr...@@ -3065,8 +3137,10 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerErr
3065 return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{});3137 return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{});
3066}3138}
30673139
3068fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst {3140fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst {
3069 const tree = scope.tree();3141 const tree = scope.tree();
3142 const node_datas = tree.nodes.items(.data);
3143 const main_tokens = tree.nodes.items(.main_token);
3070 const builtin_name = tree.tokenSlice(call.builtin_token);3144 const builtin_name = tree.tokenSlice(call.builtin_token);
30713145
3072 // We handle the different builtins manually because they have different semantics depending3146 // We handle the different builtins manually because they have different semantics depending
...@@ -3104,8 +3178,10 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built...@@ -3104,8 +3178,10 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built
3104 }3178 }
3105}3179}
31063180
3107fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) InnerError!*zir.Inst {3181fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) InnerError!*zir.Inst {
3108 const tree = scope.tree();3182 const tree = scope.tree();
3183 const node_datas = tree.nodes.items(.data);
3184 const main_tokens = tree.nodes.items(.main_token);
3109 const lhs = try expr(mod, scope, .none, node.lhs);3185 const lhs = try expr(mod, scope, .none, node.lhs);
31103186
3111 const param_nodes = node.params();3187 const param_nodes = node.params();
...@@ -3130,6 +3206,8 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In...@@ -3130,6 +3206,8 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In
31303206
3131fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst {3207fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst {
3132 const tree = scope.tree();3208 const tree = scope.tree();
3209 const node_datas = tree.nodes.items(.data);
3210 const main_tokens = tree.nodes.items(.main_token);
3133 const src = tree.token_locs[unreach_node.token].start;3211 const src = tree.token_locs[unreach_node.token].start;
3134 return addZIRNoOp(mod, scope, src, .unreachable_safe);3212 return addZIRNoOp(mod, scope, src, .unreachable_safe);
3135}3213}
...@@ -3176,11 +3254,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3176,11 +3254,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3176 while (true) {3254 while (true) {
3177 switch (node.tag) {3255 switch (node.tag) {
3178 .Root,3256 .Root,
3179 .Use,3257 .@"usingnamespace",
3180 .TestDecl,3258 .test_decl,
3181 .DocComment,3259 .doc_comment,
3182 .SwitchCase,3260 .switch_case,
3183 .SwitchElse,3261 .switch_else,
3184 .Else,3262 .Else,
3185 .Payload,3263 .Payload,
3186 .PointerPayload,3264 .PointerPayload,
...@@ -3190,97 +3268,97 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3190,97 +3268,97 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3190 .FieldInitializer,3268 .FieldInitializer,
3191 => unreachable,3269 => unreachable,
31923270
3193 .Return,3271 .@"return",
3194 .Break,3272 .@"break",
3195 .Continue,3273 .@"continue",
3196 .BitNot,3274 .bit_not,
3197 .BoolNot,3275 .bool_not,
3198 .VarDecl,3276 .var_decl,
3199 .Defer,3277 .@"defer",
3200 .AddressOf,3278 .address_of,
3201 .OptionalType,3279 .optional_type,
3202 .Negation,3280 .negation,
3203 .NegationWrap,3281 .negation_wrap,
3204 .Resume,3282 .@"resume",
3205 .ArrayType,3283 .array_type,
3206 .ArrayTypeSentinel,3284 .array_type_sentinel,
3207 .PtrType,3285 .PtrType,
3208 .SliceType,3286 .slice_type,
3209 .Suspend,3287 .@"suspend",
3210 .AnyType,3288 .@"anytype",
3211 .ErrorType,3289 .error_type,
3212 .FnProto,3290 .FnProto,
3213 .AnyFrameType,3291 .anyframe_type,
3214 .IntegerLiteral,3292 .integer_literal,
3215 .FloatLiteral,3293 .float_literal,
3216 .EnumLiteral,3294 .enum_literal,
3217 .StringLiteral,3295 .string_literal,
3218 .MultilineStringLiteral,3296 .MultilineStringLiteral,
3219 .CharLiteral,3297 .char_literal,
3220 .BoolLiteral,3298 .bool_literal,
3221 .NullLiteral,3299 .null_literal,
3222 .UndefinedLiteral,3300 .undefined_literal,
3223 .Unreachable,3301 .@"unreachable",
3224 .Identifier,3302 .identifier,
3225 .ErrorSetDecl,3303 .error_set_decl,
3226 .ContainerDecl,3304 .ContainerDecl,
3227 .Asm,3305 .@"asm",
3228 .Add,3306 .add,
3229 .AddWrap,3307 .add_wrap,
3230 .ArrayCat,3308 .array_cat,
3231 .ArrayMult,3309 .array_mult,
3232 .Assign,3310 .assign,
3233 .AssignBitAnd,3311 .assign_bit_and,
3234 .AssignBitOr,3312 .assign_bit_or,
3235 .AssignBitShiftLeft,3313 .assign_bit_shift_left,
3236 .AssignBitShiftRight,3314 .assign_bit_shift_right,
3237 .AssignBitXor,3315 .assign_bit_xor,
3238 .AssignDiv,3316 .assign_div,
3239 .AssignSub,3317 .assign_sub,
3240 .AssignSubWrap,3318 .assign_sub_wrap,
3241 .AssignMod,3319 .assign_mod,
3242 .AssignAdd,3320 .assign_add,
3243 .AssignAddWrap,3321 .assign_add_wrap,
3244 .AssignMul,3322 .assign_mul,
3245 .AssignMulWrap,3323 .assign_mul_wrap,
3246 .BangEqual,3324 .bang_equal,
3247 .BitAnd,3325 .bit_and,
3248 .BitOr,3326 .bit_or,
3249 .BitShiftLeft,3327 .bit_shift_left,
3250 .BitShiftRight,3328 .bit_shift_right,
3251 .BitXor,3329 .bit_xor,
3252 .BoolAnd,3330 .bool_and,
3253 .BoolOr,3331 .bool_or,
3254 .Div,3332 .div,
3255 .EqualEqual,3333 .equal_equal,
3256 .ErrorUnion,3334 .error_union,
3257 .GreaterOrEqual,3335 .greater_or_equal,
3258 .GreaterThan,3336 .greater_than,
3259 .LessOrEqual,3337 .less_or_equal,
3260 .LessThan,3338 .less_than,
3261 .MergeErrorSets,3339 .merge_error_sets,
3262 .Mod,3340 .mod,
3263 .Mul,3341 .mul,
3264 .MulWrap,3342 .mul_wrap,
3265 .Range,3343 .range,
3266 .Period,3344 .period,
3267 .Sub,3345 .sub,
3268 .SubWrap,3346 .sub_wrap,
3269 .Slice,3347 .slice,
3270 .Deref,3348 .deref,
3271 .ArrayAccess,3349 .array_access,
3272 .Block,3350 .block,
3273 => return false,3351 => return false,
32743352
3275 // Forward the question to a sub-expression.3353 // Forward the question to a sub-expression.
3276 .GroupedExpression => node = node.castTag(.GroupedExpression).?.expr,3354 .grouped_expression => node = node.castTag(.grouped_expression).?.expr,
3277 .Try => node = node.castTag(.Try).?.rhs,3355 .@"try" => node = node.castTag(.@"try").?.rhs,
3278 .Await => node = node.castTag(.Await).?.rhs,3356 .@"await" => node = node.castTag(.@"await").?.rhs,
3279 .Catch => node = node.castTag(.Catch).?.rhs,3357 .@"catch" => node = node.castTag(.@"catch").?.rhs,
3280 .OrElse => node = node.castTag(.OrElse).?.rhs,3358 .@"orelse" => node = node.castTag(.@"orelse").?.rhs,
3281 .Comptime => node = node.castTag(.Comptime).?.expr,3359 .@"comptime" => node = node.castTag(.@"comptime").?.expr,
3282 .Nosuspend => node = node.castTag(.Nosuspend).?.expr,3360 .@"nosuspend" => node = node.castTag(.@"nosuspend").?.expr,
3283 .UnwrapOptional => node = node.castTag(.UnwrapOptional).?.lhs,3361 .unwrap_optional => node = node.castTag(.unwrap_optional).?.lhs,
32843362
3285 // True because these are exactly the expressions we need memory locations for.3363 // True because these are exactly the expressions we need memory locations for.
3286 .ArrayInitializer,3364 .ArrayInitializer,
...@@ -3291,14 +3369,14 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3291,14 +3369,14 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
32913369
3292 // True because depending on comptime conditions, sub-expressions3370 // True because depending on comptime conditions, sub-expressions
3293 // may be the kind that need memory locations.3371 // may be the kind that need memory locations.
3294 .While,3372 .@"while",
3295 .For,3373 .@"for",
3296 .Switch,3374 .@"switch",
3297 .Call,3375 .call,
3298 .LabeledBlock,3376 .labeled_block,
3299 => return true,3377 => return true,
33003378
3301 .BuiltinCall => {3379 .builtin_call => {
3302 @setEvalBranchQuota(5000);3380 @setEvalBranchQuota(5000);
3303 const builtin_needs_mem_loc = std.ComptimeStringMap(bool, .{3381 const builtin_needs_mem_loc = std.ComptimeStringMap(bool, .{
3304 .{ "@addWithOverflow", false },3382 .{ "@addWithOverflow", false },
...@@ -3404,12 +3482,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {...@@ -3404,12 +3482,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
3404 .{ "@TypeOf", false },3482 .{ "@TypeOf", false },
3405 .{ "@unionInit", true },3483 .{ "@unionInit", true },
3406 });3484 });
3407 const name = scope.tree().tokenSlice(node.castTag(.BuiltinCall).?.builtin_token);3485 const name = scope.tree().tokenSlice(node.castTag(.builtin_call).?.builtin_token);
3408 return builtin_needs_mem_loc.get(name).?;3486 return builtin_needs_mem_loc.get(name).?;
3409 },3487 },
34103488
3411 // Depending on AST properties, they may need memory locations.3489 // Depending on AST properties, they may need memory locations.
3412 .If => return node.castTag(.If).?.@"else" != null,3490 .@"if" => return node.castTag(.@"if").?.@"else" != null,
3413 }3491 }
3414 }3492 }
3415}3493}
...@@ -3450,8 +3528,17 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr...@@ -3450,8 +3528,17 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
3450 }3528 }
3451}3529}
34523530
3453fn rvalueVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, result: void) InnerError!*zir.Inst {3531fn rvalueVoid(
3454 const src = scope.tree().token_locs[node.firstToken()].start;3532 mod: *Module,
3533 scope: *Scope,
3534 rl: ResultLoc,
3535 node: ast.Node.Index,
3536 result: void,
3537) InnerError!*zir.Inst {
3538 const tree = scope.tree();
3539 const node_datas = tree.nodes.items(.data);
3540 const main_tokens = tree.nodes.items(.main_token);
3541 const src = tree.tokens.items(.start)[tree.firstToken(node)];
3455 const void_inst = try addZIRInstConst(mod, scope, src, .{3542 const void_inst = try addZIRInstConst(mod, scope, src, .{
3456 .ty = Type.initTag(.void),3543 .ty = Type.initTag(.void),
3457 .val = Value.initTag(.void_value),3544 .val = Value.initTag(.void_value),
src/codegen.zig+10-5
...@@ -451,11 +451,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -451,11 +451,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
451451
452 const src_data: struct { lbrace_src: usize, rbrace_src: usize, source: []const u8 } = blk: {452 const src_data: struct { lbrace_src: usize, rbrace_src: usize, source: []const u8 } = blk: {
453 const container_scope = module_fn.owner_decl.container;453 const container_scope = module_fn.owner_decl.container;
454 const tree = container_scope.file_scope.contents.tree;454 const tree = container_scope.file_scope.tree;
455 const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?;455 const node_tags = tree.nodes.items(.tag);
456 const block = fn_proto.getBodyNode().?.castTag(.Block).?;456 const node_datas = tree.nodes.items(.data);
457 const lbrace_src = tree.token_locs[block.lbrace].start;457 const token_starts = tree.tokens.items(.start);
458 const rbrace_src = tree.token_locs[block.rbrace].start;458
459 const fn_decl = tree.rootDecls()[module_fn.owner_decl.src_index];
460 assert(node_tags[fn_decl] == .fn_decl);
461 const block = node_datas[fn_decl].rhs;
462 const lbrace_src = token_starts[tree.firstToken(block)];
463 const rbrace_src = token_starts[tree.lastToken(block)];
459 break :blk .{464 break :blk .{
460 .lbrace_src = lbrace_src,465 .lbrace_src = lbrace_src,
461 .rbrace_src = rbrace_src,466 .rbrace_src = rbrace_src,
src/ir.zig+1
...@@ -317,6 +317,7 @@ pub const Inst = struct {...@@ -317,6 +317,7 @@ pub const Inst = struct {
317 pub const base_tag = Tag.arg;317 pub const base_tag = Tag.arg;
318318
319 base: Inst,319 base: Inst,
320 /// This exists to be emitted into debug info.
320 name: [*:0]const u8,321 name: [*:0]const u8,
321322
322 pub fn operandCount(self: *const Arg) usize {323 pub fn operandCount(self: *const Arg) usize {
src/link/Elf.zig+22-10
...@@ -2223,13 +2223,19 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {...@@ -2223,13 +2223,19 @@ pub fn updateDecl(self: *Elf, module: *Module, decl: *Module.Decl) !void {
2223 try dbg_line_buffer.ensureCapacity(26);2223 try dbg_line_buffer.ensureCapacity(26);
22242224
2225 const line_off: u28 = blk: {2225 const line_off: u28 = blk: {
2226 const tree = decl.container.file_scope.contents.tree;2226 const tree = decl.container.file_scope.tree;
2227 const file_ast_decls = tree.root_node.decls();2227 const node_tags = tree.nodes.items(.tag);
2228 const node_datas = tree.nodes.items(.data);
2229 const token_starts = tree.tokens.items(.start);
2230
2231 const file_ast_decls = tree.rootDecls();
2228 // TODO Look into improving the performance here by adding a token-index-to-line2232 // TODO Look into improving the performance here by adding a token-index-to-line
2229 // lookup table. Currently this involves scanning over the source code for newlines.2233 // lookup table. Currently this involves scanning over the source code for newlines.
2230 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;2234 const fn_decl = file_ast_decls[decl.src_index];
2231 const block = fn_proto.getBodyNode().?.castTag(.Block).?;2235 assert(node_tags[fn_decl] == .fn_decl);
2232 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);2236 const block = node_datas[fn_decl].rhs;
2237 const lbrace = tree.firstToken(block);
2238 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
2233 break :blk @intCast(u28, line_delta);2239 break :blk @intCast(u28, line_delta);
2234 };2240 };
22352241
...@@ -2744,13 +2750,19 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec...@@ -2744,13 +2750,19 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
27442750
2745 if (self.llvm_ir_module) |_| return;2751 if (self.llvm_ir_module) |_| return;
27462752
2747 const tree = decl.container.file_scope.contents.tree;2753 const tree = decl.container.file_scope.tree;
2748 const file_ast_decls = tree.root_node.decls();2754 const node_tags = tree.nodes.items(.tag);
2755 const node_datas = tree.nodes.items(.data);
2756 const token_starts = tree.tokens.items(.start);
2757
2758 const file_ast_decls = tree.rootDecls();
2749 // TODO Look into improving the performance here by adding a token-index-to-line2759 // TODO Look into improving the performance here by adding a token-index-to-line
2750 // lookup table. Currently this involves scanning over the source code for newlines.2760 // lookup table. Currently this involves scanning over the source code for newlines.
2751 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;2761 const fn_decl = file_ast_decls[decl.src_index];
2752 const block = fn_proto.getBodyNode().?.castTag(.Block).?;2762 assert(node_tags[fn_decl] == .fn_decl);
2753 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);2763 const block = node_datas[fn_decl].rhs;
2764 const lbrace = tree.firstToken(block);
2765 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
2754 const casted_line_off = @intCast(u28, line_delta);2766 const casted_line_off = @intCast(u28, line_delta);
27552767
2756 const shdr = &self.sections.items[self.debug_line_section_index.?];2768 const shdr = &self.sections.items[self.debug_line_section_index.?];
src/link/MachO/DebugSymbols.zig+22-10
...@@ -904,13 +904,19 @@ pub fn updateDeclLineNumber(self: *DebugSymbols, module: *Module, decl: *const M...@@ -904,13 +904,19 @@ pub fn updateDeclLineNumber(self: *DebugSymbols, module: *Module, decl: *const M
904 const tracy = trace(@src());904 const tracy = trace(@src());
905 defer tracy.end();905 defer tracy.end();
906906
907 const tree = decl.container.file_scope.contents.tree;907 const tree = decl.container.file_scope.tree;
908 const file_ast_decls = tree.root_node.decls();908 const node_tags = tree.nodes.items(.tag);
909 const node_datas = tree.nodes.items(.data);
910 const token_starts = tree.tokens.items(.start);
911
912 const file_ast_decls = tree.rootDecls();
909 // TODO Look into improving the performance here by adding a token-index-to-line913 // TODO Look into improving the performance here by adding a token-index-to-line
910 // lookup table. Currently this involves scanning over the source code for newlines.914 // lookup table. Currently this involves scanning over the source code for newlines.
911 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;915 const fn_decl = file_ast_decls[decl.src_index];
912 const block = fn_proto.getBodyNode().?.castTag(.Block).?;916 assert(node_tags[fn_decl] == .fn_decl);
913 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);917 const block = node_datas[fn_decl].rhs;
918 const lbrace = tree.firstToken(block);
919 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
914 const casted_line_off = @intCast(u28, line_delta);920 const casted_line_off = @intCast(u28, line_delta);
915921
916 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;922 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
...@@ -948,13 +954,19 @@ pub fn initDeclDebugBuffers(...@@ -948,13 +954,19 @@ pub fn initDeclDebugBuffers(
948 try dbg_line_buffer.ensureCapacity(26);954 try dbg_line_buffer.ensureCapacity(26);
949955
950 const line_off: u28 = blk: {956 const line_off: u28 = blk: {
951 const tree = decl.container.file_scope.contents.tree;957 const tree = decl.container.file_scope.tree;
952 const file_ast_decls = tree.root_node.decls();958 const node_tags = tree.nodes.items(.tag);
959 const node_datas = tree.nodes.items(.data);
960 const token_starts = tree.tokens.items(.start);
961
962 const file_ast_decls = tree.rootDecls();
953 // TODO Look into improving the performance here by adding a token-index-to-line963 // TODO Look into improving the performance here by adding a token-index-to-line
954 // lookup table. Currently this involves scanning over the source code for newlines.964 // lookup table. Currently this involves scanning over the source code for newlines.
955 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;965 const fn_decl = file_ast_decls[decl.src_index];
956 const block = fn_proto.getBodyNode().?.castTag(.Block).?;966 assert(node_tags[fn_decl] == .fn_decl);
957 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);967 const block = node_datas[fn_decl].rhs;
968 const lbrace = tree.firstToken(block);
969 const line_delta = std.zig.lineDelta(tree.source, 0, token_starts[lbrace]);
958 break :blk @intCast(u28, line_delta);970 break :blk @intCast(u28, line_delta);
959 };971 };
960972
src/zir.zig+18-3
...@@ -53,6 +53,9 @@ pub const Inst = struct {...@@ -53,6 +53,9 @@ pub const Inst = struct {
53 indexable_ptr_len,53 indexable_ptr_len,
54 /// Function parameter value. These must be first in a function's main block,54 /// Function parameter value. These must be first in a function's main block,
55 /// in respective order with the parameters.55 /// in respective order with the parameters.
56 /// TODO make this instruction implicit; after we transition to having ZIR
57 /// instructions be same sized and referenced by index, the first N indexes
58 /// will implicitly be references to the parameters of the function.
56 arg,59 arg,
57 /// Type coercion.60 /// Type coercion.
58 as,61 as,
...@@ -354,9 +357,8 @@ pub const Inst = struct {...@@ -354,9 +357,8 @@ pub const Inst = struct {
354 .return_void,357 .return_void,
355 .ret_ptr,358 .ret_ptr,
356 .ret_type,359 .ret_type,
357 .unreach_nocheck,360 .unreachable_unsafe,
358 .@"unreachable",361 .unreachable_safe,
359 .arg,
360 .void_value,362 .void_value,
361 => NoOp,363 => NoOp,
362364
...@@ -451,6 +453,7 @@ pub const Inst = struct {...@@ -451,6 +453,7 @@ pub const Inst = struct {
451 .block_comptime_flat,453 .block_comptime_flat,
452 => Block,454 => Block,
453455
456 .arg => Arg,
454 .array_type_sentinel => ArrayTypeSentinel,457 .array_type_sentinel => ArrayTypeSentinel,
455 .@"break" => Break,458 .@"break" => Break,
456 .break_void => BreakVoid,459 .break_void => BreakVoid,
...@@ -684,6 +687,18 @@ pub const Inst = struct {...@@ -684,6 +687,18 @@ pub const Inst = struct {
684 kw_args: struct {},687 kw_args: struct {},
685 };688 };
686689
690 pub const Arg = struct {
691 pub const base_tag = Tag.arg;
692 base: Inst,
693
694 positionals: struct {
695 /// This exists to be passed to the arg TZIR instruction, which
696 /// needs it for debug info.
697 name: []const u8,
698 },
699 kw_args: struct {},
700 };
701
687 pub const Block = struct {702 pub const Block = struct {
688 pub const base_tag = Tag.block;703 pub const base_tag = Tag.block;
689 base: Inst,704 base: Inst,