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 {
28342834 /// `(lhs)`. main_token is the `(`; rhs is the token index of the `)`.
28352835 grouped_expression,
28362836 /// `@a(lhs, rhs)`. lhs and rhs may be omitted.
2837 /// main_token is the builtin token.
28372838 builtin_call_two,
28382839 /// Same as builtin_call_two but there is known to be a trailing comma before the rparen.
28392840 builtin_call_two_comma,
28402841 /// `@a(b, c)`. `sub_list[lhs..rhs]`.
2842 /// main_token is the builtin token.
28412843 builtin_call,
28422844 /// Same as builtin_call but there is known to be a trailing comma before the rparen.
28432845 builtin_call_comma,
src/Module.zig+212-150
......@@ -428,14 +428,14 @@ pub const Scope = struct {
428428 }
429429
430430 /// 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 {
432432 switch (self.tag) {
433 .file => return self.cast(File).?.contents.tree,
434 .block => return self.cast(Block).?.src_decl.container.file_scope.contents.tree,
435 .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.contents.tree,
436 .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.contents.tree,
437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.contents.tree,
438 .container => return self.cast(Container).?.file_scope.contents.tree,
433 .file => return self.cast(File).?.tree,
434 .block => return self.cast(Block).?.src_decl.container.file_scope.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.tree,
437 .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
438 .container => return self.cast(Container).?.file_scope.tree,
439439 }
440440 }
441441
......@@ -1008,38 +1008,38 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
10081008 switch (node_tags[fn_proto]) {
10091009 .fn_proto_simple => {
10101010 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));
10121012 },
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)),
10141014 .fn_proto_one => {
10151015 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));
10171017 },
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)),
10191019 else => unreachable,
10201020 }
10211021 },
10221022 .fn_proto_simple => {
10231023 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));
10251025 },
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)),
10271027 .fn_proto_one => {
10281028 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));
10301030 },
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)),
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)),
1036 .aligned_var_decl => return mod.astgenAndSemaVarDecl(decl, tree, tree.alignedVarDecl(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)),
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)),
10371037
10381038 .@"comptime" => {
10391039 decl.analysis = .in_progress;
10401040
10411041 // 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);
10431043 defer analysis_arena.deinit();
10441044 var gen_scope: Scope.GenZIR = .{
10451045 .decl = decl,
......@@ -1047,14 +1047,15 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
10471047 .parent = &decl.container.base,
10481048 .force_comptime = true,
10491049 };
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);
1053 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
1054 zir.dumpZir(self.gpa, "comptime_block", decl.name, gen_scope.instructions.items) catch {};
1052 const block_expr = node_datas[decl_node].lhs;
1053 _ = try astgen.comptimeExpr(mod, &gen_scope.base, .none, block_expr);
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 {};
10551056 }
10561057
1057 var inst_table = Scope.Block.InstTable.init(self.gpa);
1058 var inst_table = Scope.Block.InstTable.init(mod.gpa);
10581059 defer inst_table.deinit();
10591060
10601061 var branch_quota: u32 = default_eval_branch_quota;
......@@ -1071,17 +1072,17 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
10711072 .is_comptime = true,
10721073 .branch_quota = &branch_quota,
10731074 };
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, .{
10771078 .instructions = gen_scope.instructions.items,
10781079 });
10791080
10801081 decl.analysis = .complete;
1081 decl.generation = self.generation;
1082 decl.generation = mod.generation;
10821083 return true;
10831084 },
1084 .UsingNamespace => @panic("TODO usingnamespace decl"),
1085 .@"usingnamespace" => @panic("TODO usingnamespace decl"),
10851086 else => unreachable,
10861087 }
10871088}
......@@ -1099,18 +1100,20 @@ fn astgenAndSemaFn(
10991100 decl.analysis = .in_progress;
11001101
11011102 const token_starts = tree.tokens.items(.start);
1103 const token_tags = tree.tokens.items(.tag);
11021104
11031105 // This arena allocator's memory is discarded at the end of this function. It is used
11041106 // to determine the type of the function, and hence the type of the decl, which is needed
11051107 // 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);
11071109 defer fn_type_scope_arena.deinit();
11081110 var fn_type_scope: Scope.GenZIR = .{
11091111 .decl = decl,
11101112 .arena = &fn_type_scope_arena.allocator,
11111113 .parent = &decl.container.base,
1114 .force_comptime = true,
11121115 };
1113 defer fn_type_scope.instructions.deinit(self.gpa);
1116 defer fn_type_scope.instructions.deinit(mod.gpa);
11141117
11151118 decl.is_pub = fn_proto.visib_token != null;
11161119
......@@ -1126,7 +1129,7 @@ fn astgenAndSemaFn(
11261129 };
11271130 const param_types = try fn_type_scope.arena.alloc(*zir.Inst, param_count);
11281131 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, .{
11301133 .ty = Type.initTag(.type),
11311134 .val = Value.initTag(.type_type),
11321135 });
......@@ -1138,13 +1141,13 @@ fn astgenAndSemaFn(
11381141 while (it.next()) |param| : (param_type_i += 1) {
11391142 if (param.anytype_ellipsis3) |token| {
11401143 switch (token_tags[token]) {
1141 .keyword_anytype => return self.failTok(
1144 .keyword_anytype => return mod.failTok(
11421145 &fn_type_scope.base,
1143 tok_i,
1146 token,
11441147 "TODO implement anytype parameter",
11451148 .{},
11461149 ),
1147 .ellipsis3 => return self.failTok(
1150 .ellipsis3 => return mod.failTok(
11481151 &fn_type_scope.base,
11491152 token,
11501153 "TODO implement var args",
......@@ -1156,7 +1159,7 @@ fn astgenAndSemaFn(
11561159 const param_type_node = param.type_expr;
11571160 assert(param_type_node != 0);
11581161 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);
11601163 }
11611164 assert(param_type_i == param_count);
11621165 }
......@@ -1164,10 +1167,10 @@ fn astgenAndSemaFn(
11641167 // TODO call std.zig.parseStringLiteral
11651168 const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name), "\"");
11661169 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name_str});
1167 const target = self.comp.getTarget();
1170 const target = mod.comp.getTarget();
11681171 if (target_util.is_libc_lib_name(target, lib_name_str)) {
1169 if (!self.comp.bin_file.options.link_libc) {
1170 return self.failTok(
1172 if (!mod.comp.bin_file.options.link_libc) {
1173 return mod.failTok(
11711174 &fn_type_scope.base,
11721175 lib_name,
11731176 "dependency on libc must be explicitly specified in the build command",
......@@ -1177,8 +1180,8 @@ fn astgenAndSemaFn(
11771180 break :blk;
11781181 }
11791182 if (target_util.is_libcpp_lib_name(target, lib_name_str)) {
1180 if (!self.comp.bin_file.options.link_libcpp) {
1181 return self.failTok(
1183 if (!mod.comp.bin_file.options.link_libcpp) {
1184 return mod.failTok(
11821185 &fn_type_scope.base,
11831186 lib_name,
11841187 "dependency on libc++ must be explicitly specified in the build command",
......@@ -1187,16 +1190,16 @@ fn astgenAndSemaFn(
11871190 }
11881191 break :blk;
11891192 }
1190 if (!target.isWasm() and !self.comp.bin_file.options.pic) {
1191 return self.failTok(
1193 if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
1194 return mod.failTok(
11921195 &fn_type_scope.base,
11931196 lib_name,
11941197 "dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
11951198 .{ lib_name, lib_name },
11961199 );
11971200 }
1198 self.comp.stage1AddLinkLib(lib_name_str) catch |err| {
1199 return self.failTok(
1201 mod.comp.stage1AddLinkLib(lib_name_str) catch |err| {
1202 return mod.failTok(
12001203 &fn_type_scope.base,
12011204 lib_name,
12021205 "unable to add link lib '{s}': {s}",
......@@ -1204,45 +1207,55 @@ fn astgenAndSemaFn(
12041207 );
12051208 };
12061209 }
1207 if (fn_proto.ast.align_expr) |align_expr| {
1208 return self.failNode(&fn_type_scope.base, align_expr, "TODO implement function align expression", .{});
1210 if (fn_proto.ast.align_expr != 0) {
1211 return mod.failNode(
1212 &fn_type_scope.base,
1213 fn_proto.ast.align_expr,
1214 "TODO implement function align expression",
1215 .{},
1216 );
12091217 }
1210 if (fn_proto.ast.section_expr) |sect_expr| {
1211 return self.failNode(&fn_type_scope.base, sect_expr, "TODO implement function section expression", .{});
1218 if (fn_proto.ast.section_expr != 0) {
1219 return mod.failNode(
1220 &fn_type_scope.base,
1221 fn_proto.ast.section_expr,
1222 "TODO implement function section expression",
1223 .{},
1224 );
12121225 }
1213 if (fn_proto.ast.callconv_expr) |callconv_expr| {
1214 return self.failNode(
1226 if (fn_proto.ast.callconv_expr != 0) {
1227 return mod.failNode(
12151228 &fn_type_scope.base,
1216 callconv_expr,
1229 fn_proto.ast.callconv_expr,
12171230 "TODO implement function calling convention expression",
12181231 .{},
12191232 );
12201233 }
12211234 const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;
12221235 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", .{});
12241237 }
12251238 const return_type_inst = try astgen.expr(
1226 self,
1239 mod,
12271240 &fn_type_scope.base,
12281241 type_type_rl,
12291242 fn_proto.ast.return_type,
12301243 );
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, .{
12321245 .return_type = return_type_inst,
12331246 .param_types = param_types,
12341247 }, .{});
12351248
1236 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
1237 zir.dumpZir(self.gpa, "fn_type", decl.name, fn_type_scope.instructions.items) catch {};
1249 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1250 zir.dumpZir(mod.gpa, "fn_type", decl.name, fn_type_scope.instructions.items) catch {};
12381251 }
12391252
12401253 // 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);
12421255 errdefer decl_arena.deinit();
12431256 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);
12461259 defer inst_table.deinit();
12471260
12481261 var branch_quota: u32 = default_eval_branch_quota;
......@@ -1259,9 +1272,9 @@ fn astgenAndSemaFn(
12591272 .is_comptime = false,
12601273 .branch_quota = &branch_quota,
12611274 };
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, .{
12651278 .instructions = fn_type_scope.instructions.items,
12661279 });
12671280 if (body_node == 0) {
......@@ -1270,7 +1283,7 @@ fn astgenAndSemaFn(
12701283 if (decl.typedValueManaged()) |tvm| {
12711284 type_changed = !tvm.typed_value.ty.eql(fn_type);
12721285
1273 tvm.deinit(self.gpa);
1286 tvm.deinit(mod.gpa);
12741287 }
12751288 const fn_val = try Value.Tag.extern_fn.create(&decl_arena.allocator, decl);
12761289
......@@ -1282,13 +1295,13 @@ fn astgenAndSemaFn(
12821295 },
12831296 };
12841297 decl.analysis = .complete;
1285 decl.generation = self.generation;
1298 decl.generation = mod.generation;
12861299
1287 try self.comp.bin_file.allocateDeclIndexes(decl);
1288 try self.comp.work_queue.writeItem(.{ .codegen_decl = decl });
1300 try mod.comp.bin_file.allocateDeclIndexes(decl);
1301 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl });
12891302
1290 if (type_changed and self.emit_h != null) {
1291 try self.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
1303 if (type_changed and mod.emit_h != null) {
1304 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
12921305 }
12931306
12941307 return type_changed;
......@@ -1304,17 +1317,17 @@ fn astgenAndSemaFn(
13041317 .arena = &decl_arena.allocator,
13051318 .parent = &decl.container.base,
13061319 };
1307 defer gen_scope.instructions.deinit(self.gpa);
1320 defer gen_scope.instructions.deinit(mod.gpa);
13081321
13091322 // 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);
13111324 var params_scope = &gen_scope.base;
13121325 var i: usize = 0;
13131326 var it = fn_proto.iterate(tree);
13141327 while (it.next()) |param| : (i += 1) {
13151328 const name_token = param.name_token.?;
13161329 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);
13181331 const arg = try decl_arena.allocator.create(zir.Inst.NoOp);
13191332 arg.* = .{
13201333 .base = .{
......@@ -1335,17 +1348,17 @@ fn astgenAndSemaFn(
13351348 params_scope = &sub_scope.base;
13361349 }
13371350
1338 try astgen.blockExpr(self, params_scope, body_node);
1351 try astgen.blockExpr(mod, params_scope, body_node);
13391352
13401353 if (gen_scope.instructions.items.len == 0 or
13411354 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn())
13421355 {
13431356 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);
13451358 }
13461359
1347 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
1348 zir.dumpZir(self.gpa, "fn_body", decl.name, gen_scope.instructions.items) catch {};
1360 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1361 zir.dumpZir(mod.gpa, "fn_body", decl.name, gen_scope.instructions.items) catch {};
13491362 }
13501363
13511364 break :blk .{
......@@ -1379,7 +1392,7 @@ fn astgenAndSemaFn(
13791392 prev_is_inline = prev_func.state == .inline_only;
13801393 }
13811394
1382 tvm.deinit(self.gpa);
1395 tvm.deinit(mod.gpa);
13831396 }
13841397
13851398 decl_arena_state.* = decl_arena.state;
......@@ -1393,25 +1406,25 @@ fn astgenAndSemaFn(
13931406 },
13941407 };
13951408 decl.analysis = .complete;
1396 decl.generation = self.generation;
1409 decl.generation = mod.generation;
13971410
13981411 if (!is_inline and fn_type.hasCodeGenBits()) {
13991412 // We don't fully codegen the decl until later, but we do need to reserve a global
14001413 // offset table index for it. This allows us to codegen decls out of dependency order,
14011414 // increasing how many computations can be done in parallel.
1402 try self.comp.bin_file.allocateDeclIndexes(decl);
1403 try self.comp.work_queue.writeItem(.{ .codegen_decl = decl });
1404 if (type_changed and self.emit_h != null) {
1405 try self.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
1415 try mod.comp.bin_file.allocateDeclIndexes(decl);
1416 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl });
1417 if (type_changed and mod.emit_h != null) {
1418 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
14061419 }
14071420 } else if (!prev_is_inline and prev_type_has_bits) {
1408 self.comp.bin_file.freeDecl(decl);
1421 mod.comp.bin_file.freeDecl(decl);
14091422 }
14101423
14111424 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) {
14131426 if (is_inline) {
1414 return self.failTok(
1427 return mod.failTok(
14151428 &block_scope.base,
14161429 maybe_export_token,
14171430 "export of inline function",
......@@ -1421,7 +1434,7 @@ fn astgenAndSemaFn(
14211434 const export_src = token_starts[maybe_export_token];
14221435 const name = tree.tokenSlice(fn_proto.name_token.?); // TODO identifierTokenString
14231436 // 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);
14251438 }
14261439 }
14271440 return type_changed or is_inline != prev_is_inline;
......@@ -1439,13 +1452,14 @@ fn astgenAndSemaVarDecl(
14391452 decl.analysis = .in_progress;
14401453
14411454 const token_starts = tree.tokens.items(.start);
1455 const token_tags = tree.tokens.items(.tag);
14421456
14431457 // 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);
14451459 errdefer decl_arena.deinit();
14461460 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);
14491463 defer decl_inst_table.deinit();
14501464
14511465 var branch_quota: u32 = default_eval_branch_quota;
......@@ -1462,63 +1476,83 @@ fn astgenAndSemaVarDecl(
14621476 .is_comptime = true,
14631477 .branch_quota = &branch_quota,
14641478 };
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;
14681482 const is_extern = blk: {
1469 const maybe_extern_token = var_decl.getExternExportToken() orelse
1470 break :blk false;
1471 if (tree.token_ids[maybe_extern_token] != .Keyword_extern) break :blk false;
1472 if (var_decl.getInitNode()) |some| {
1473 return self.failNode(&block_scope.base, some, "extern variables have no initializers", .{});
1483 const maybe_extern_token = var_decl.extern_export_token orelse break :blk false;
1484 if (token_tags[maybe_extern_token] != .keyword_extern) break :blk false;
1485 if (var_decl.ast.init_node != 0) {
1486 return mod.failNode(
1487 &block_scope.base,
1488 var_decl.ast.init_node,
1489 "extern variables have no initializers",
1490 .{},
1491 );
14741492 }
14751493 break :blk true;
14761494 };
1477 if (var_decl.getLibName()) |lib_name| {
1495 if (var_decl.lib_name) |lib_name| {
14781496 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", .{});
14801498 }
1481 const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var;
1482 const is_threadlocal = if (var_decl.getThreadLocalToken()) |some| blk: {
1499 const is_mutable = token_tags[var_decl.mut_token] == .keyword_var;
1500 const is_threadlocal = if (var_decl.threadlocal_token) |some| blk: {
14831501 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", .{});
14851503 }
14861504 break :blk true;
14871505 } else false;
1488 assert(var_decl.getComptimeToken() == null);
1489 if (var_decl.getAlignNode()) |align_expr| {
1490 return self.failNode(&block_scope.base, align_expr, "TODO implement function align expression", .{});
1506 assert(var_decl.comptime_token == null);
1507 if (var_decl.ast.align_node != 0) {
1508 return mod.failNode(
1509 &block_scope.base,
1510 var_decl.ast.align_node,
1511 "TODO implement function align expression",
1512 .{},
1513 );
14911514 }
1492 if (var_decl.getSectionNode()) |sect_expr| {
1493 return self.failNode(&block_scope.base, sect_expr, "TODO implement function section expression", .{});
1515 if (var_decl.ast.section_node != 0) {
1516 return mod.failNode(
1517 &block_scope.base,
1518 var_decl.ast.section_node,
1519 "TODO implement function section expression",
1520 .{},
1521 );
14941522 }
14951523
1496 const var_info: struct { ty: Type, val: ?Value } = if (var_decl.getInitNode()) |init_node| vi: {
1497 var gen_scope_arena = std.heap.ArenaAllocator.init(self.gpa);
1524 const var_info: struct { ty: Type, val: ?Value } = if (var_decl.ast.init_node != 0) vi: {
1525 var gen_scope_arena = std.heap.ArenaAllocator.init(mod.gpa);
14981526 defer gen_scope_arena.deinit();
14991527 var gen_scope: Scope.GenZIR = .{
15001528 .decl = decl,
15011529 .arena = &gen_scope_arena.allocator,
15021530 .parent = &decl.container.base,
15031531 };
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: {
1507 const src = token_starts[type_node.firstToken()];
1508 const type_type = try astgen.addZIRInstConst(self, &gen_scope.base, src, .{
1534 const init_result_loc: astgen.ResultLoc = if (var_decl.ast.type_node != 0) rl: {
1535 const type_node = var_decl.ast.type_node;
1536 const src = token_starts[tree.firstToken(type_node)];
1537 const type_type = try astgen.addZIRInstConst(mod, &gen_scope.base, src, .{
15091538 .ty = Type.initTag(.type),
15101539 .val = Value.initTag(.type_type),
15111540 });
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);
15131542 break :rl .{ .ty = var_type };
15141543 } else .none;
15151544
1516 const init_inst = try astgen.comptimeExpr(self, &gen_scope.base, init_result_loc, init_node);
1517 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
1518 zir.dumpZir(self.gpa, "var_init", decl.name, gen_scope.instructions.items) catch {};
1545 const init_inst = try astgen.comptimeExpr(
1546 mod,
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 {};
15191553 }
15201554
1521 var var_inst_table = Scope.Block.InstTable.init(self.gpa);
1555 var var_inst_table = Scope.Block.InstTable.init(mod.gpa);
15221556 defer var_inst_table.deinit();
15231557
15241558 var branch_quota_vi: u32 = default_eval_branch_quota;
......@@ -1534,8 +1568,8 @@ fn astgenAndSemaVarDecl(
15341568 .is_comptime = true,
15351569 .branch_quota = &branch_quota_vi,
15361570 };
1537 defer inner_block.instructions.deinit(self.gpa);
1538 try zir_sema.analyzeBody(self, &inner_block, .{
1571 defer inner_block.instructions.deinit(mod.gpa);
1572 try zir_sema.analyzeBody(mod, &inner_block, .{
15391573 .instructions = gen_scope.instructions.items,
15401574 });
15411575
......@@ -1550,24 +1584,30 @@ fn astgenAndSemaVarDecl(
15501584 .val = try val.copy(block_scope.arena),
15511585 };
15521586 } else if (!is_extern) {
1553 return self.failTok(&block_scope.base, var_decl.firstToken(), "variables must be initialized", .{});
1554 } else if (var_decl.getTypeNode()) |type_node| vi: {
1587 return mod.failTok(
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;
15551595 // 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);
15571597 defer type_scope_arena.deinit();
15581598 var type_scope: Scope.GenZIR = .{
15591599 .decl = decl,
15601600 .arena = &type_scope_arena.allocator,
15611601 .parent = &decl.container.base,
15621602 };
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);
1566 if (std.builtin.mode == .Debug and self.comp.verbose_ir) {
1567 zir.dumpZir(self.gpa, "var_type", decl.name, type_scope.instructions.items) catch {};
1605 const var_type = try astgen.typeExpr(mod, &type_scope.base, type_node);
1606 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
1607 zir.dumpZir(mod.gpa, "var_type", decl.name, type_scope.instructions.items) catch {};
15681608 }
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, .{
15711611 .instructions = type_scope.instructions.items,
15721612 });
15731613 break :vi .{
......@@ -1575,18 +1615,28 @@ fn astgenAndSemaVarDecl(
15751615 .val = null,
15761616 };
15771617 } 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 );
15791624 };
15801625
15811626 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 );
15831633 }
15841634
15851635 var type_changed = true;
15861636 if (decl.typedValueManaged()) |tvm| {
15871637 type_changed = !tvm.typed_value.ty.eql(var_info.ty);
15881638
1589 tvm.deinit(self.gpa);
1639 tvm.deinit(mod.gpa);
15901640 }
15911641
15921642 const new_variable = try decl_arena.allocator.create(Var);
......@@ -1610,14 +1660,15 @@ fn astgenAndSemaVarDecl(
16101660 },
16111661 };
16121662 decl.analysis = .complete;
1613 decl.generation = self.generation;
1663 decl.generation = mod.generation;
16141664
1615 if (var_decl.getExternExportToken()) |maybe_export_token| {
1616 if (tree.token_ids[maybe_export_token] == .Keyword_export) {
1665 if (var_decl.extern_export_token) |maybe_export_token| {
1666 if (token_tags[maybe_export_token] == .keyword_export) {
16171667 const export_src = token_starts[maybe_export_token];
1618 const name = tree.tokenSlice(var_decl.name_token); // TODO identifierTokenString
1668 const name_token = var_decl.ast.mut_token + 1;
1669 const name = tree.tokenSlice(name_token); // TODO identifierTokenString
16191670 // 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);
16211672 }
16221673 }
16231674 return type_changed;
......@@ -1761,7 +1812,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
17611812 decl_node,
17621813 decl_i,
17631814 tree.*,
1764 null,
1815 0,
17651816 tree.fnProtoSimple(&params, decl_node),
17661817 );
17671818 },
......@@ -1771,7 +1822,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
17711822 decl_node,
17721823 decl_i,
17731824 tree.*,
1774 null,
1825 0,
17751826 tree.fnProtoMulti(decl_node),
17761827 ),
17771828 .fn_proto_one => {
......@@ -1782,7 +1833,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
17821833 decl_node,
17831834 decl_i,
17841835 tree.*,
1785 null,
1836 0,
17861837 tree.fnProtoOne(&params, decl_node),
17871838 );
17881839 },
......@@ -1792,7 +1843,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
17921843 decl_node,
17931844 decl_i,
17941845 tree.*,
1795 null,
1846 0,
17961847 tree.fnProto(decl_node),
17971848 ),
17981849
......@@ -1848,7 +1899,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
18481899 decl_node,
18491900 decl_i,
18501901 tree.*,
1851 tree.containerFieldInit(decl),
1902 tree.containerFieldInit(decl_node),
18521903 ),
18531904 .container_field_align => try mod.semaContainerField(
18541905 container_scope,
......@@ -1856,7 +1907,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
18561907 decl_node,
18571908 decl_i,
18581909 tree.*,
1859 tree.containerFieldAlign(decl),
1910 tree.containerFieldAlign(decl_node),
18601911 ),
18611912 .container_field => try mod.semaContainerField(
18621913 container_scope,
......@@ -1864,7 +1915,7 @@ pub fn analyzeContainer(mod: *Module, container_scope: *Scope.Container) !void {
18641915 decl_node,
18651916 decl_i,
18661917 tree.*,
1867 tree.containerField(decl),
1918 tree.containerField(decl_node),
18681919 ),
18691920
18701921 .test_decl => {
......@@ -1936,14 +1987,14 @@ fn semaContainerFn(
19361987 // in `Decl` to notice that the line number did not change.
19371988 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
19381989 },
1939 .c, .wasm => {},
1990 .c, .wasm, .spirv => {},
19401991 }
19411992 }
19421993 } else {
19431994 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);
19441995 container_scope.decls.putAssumeCapacity(new_decl, {});
1945 if (fn_proto.getExternExportInlineToken()) |maybe_export_token| {
1946 if (tree.token_ids[maybe_export_token] == .Keyword_export) {
1996 if (fn_proto.extern_export_token) |maybe_export_token| {
1997 if (token_tags[maybe_export_token] == .keyword_export) {
19471998 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
19481999 }
19492000 }
......@@ -1963,9 +2014,11 @@ fn semaContainerVar(
19632014 defer tracy.end();
19642015
19652016 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];
1968 const name = tree.tokenSlice(var_decl.name_token); // TODO identifierTokenString
2019 const name_token = var_decl.ast.mut_token + 1;
2020 const name_src = token_starts[name_token];
2021 const name = tree.tokenSlice(name_token); // TODO identifierTokenString
19692022 const name_hash = container_scope.fullyQualifiedNameHash(name);
19702023 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
19712024 if (mod.decl_table.get(name_hash)) |decl| {
......@@ -1987,15 +2040,23 @@ fn semaContainerVar(
19872040 } else {
19882041 const new_decl = try mod.createNewDecl(&container_scope.base, name, decl_i, name_hash, contents_hash);
19892042 container_scope.decls.putAssumeCapacity(new_decl, {});
1990 if (var_decl.getExternExportToken()) |maybe_export_token| {
1991 if (tree.token_ids[maybe_export_token] == .Keyword_export) {
2043 if (var_decl.extern_export_token) |maybe_export_token| {
2044 if (token_tags[maybe_export_token] == .keyword_export) {
19922045 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
19932046 }
19942047 }
19952048 }
19962049}
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 {
19992060 const tracy = trace(@src());
20002061 defer tracy.end();
20012062
......@@ -2898,7 +2959,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []
28982959 file_scope.* = .{
28992960 .sub_file_path = resolved_path,
29002961 .source = .{ .unloaded = {} },
2901 .contents = .{ .not_available = {} },
2962 .tree = undefined,
29022963 .status = .never_loaded,
29032964 .pkg = found_pkg orelse cur_pkg,
29042965 .root_container = .{
......@@ -3415,11 +3476,12 @@ pub fn failTok(
34153476pub fn failNode(
34163477 self: *Module,
34173478 scope: *Scope,
3418 ast_node: *ast.Node,
3479 ast_node: ast.Node.Index,
34193480 comptime format: []const u8,
34203481 args: anytype,
34213482) 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)];
34233485 return self.fail(scope, src, format, args);
34243486}
34253487
src/astgen.zig+504-417
......@@ -55,7 +55,7 @@ pub const ResultLoc = union(enum) {
5555 };
5656};
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 {
5959 const type_src = scope.tree().token_locs[type_node.firstToken()].start;
6060 const type_type = try addZIRInstConst(mod, scope, type_src, .{
6161 .ty = Type.initTag(.type),
......@@ -65,134 +65,133 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z
6565 return expr(mod, scope, type_rl, type_node);
6666}
6767
68fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
69 switch (node.tag) {
70 .Root => unreachable,
71 .Use => unreachable,
72 .TestDecl => unreachable,
73 .DocComment => unreachable,
74 .VarDecl => unreachable,
75 .SwitchCase => unreachable,
76 .SwitchElse => unreachable,
77 .Else => unreachable,
78 .Payload => unreachable,
79 .PointerPayload => unreachable,
80 .PointerIndexPayload => unreachable,
81 .ErrorTag => unreachable,
82 .FieldInitializer => unreachable,
83 .ContainerField => unreachable,
84
85 .Assign,
86 .AssignBitAnd,
87 .AssignBitOr,
88 .AssignBitShiftLeft,
89 .AssignBitShiftRight,
90 .AssignBitXor,
91 .AssignDiv,
92 .AssignSub,
93 .AssignSubWrap,
94 .AssignMod,
95 .AssignAdd,
96 .AssignAddWrap,
97 .AssignMul,
98 .AssignMulWrap,
99 .Add,
100 .AddWrap,
101 .Sub,
102 .SubWrap,
103 .Mul,
104 .MulWrap,
105 .Div,
106 .Mod,
107 .BitAnd,
108 .BitOr,
109 .BitShiftLeft,
110 .BitShiftRight,
111 .BitXor,
112 .BangEqual,
113 .EqualEqual,
114 .GreaterThan,
115 .GreaterOrEqual,
116 .LessThan,
117 .LessOrEqual,
118 .ArrayCat,
119 .ArrayMult,
120 .BoolAnd,
121 .BoolOr,
122 .Asm,
123 .StringLiteral,
124 .IntegerLiteral,
125 .Call,
126 .Unreachable,
127 .Return,
128 .If,
129 .While,
130 .BoolNot,
131 .AddressOf,
132 .FloatLiteral,
133 .UndefinedLiteral,
134 .BoolLiteral,
135 .NullLiteral,
136 .OptionalType,
137 .Block,
138 .LabeledBlock,
139 .Break,
68fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
69 const tree = scope.tree();
70 const node_tags = tree.nodes.items(.tag);
71 const main_tokens = tree.nodes.items(.main_token);
72 switch (node_tags[node]) {
73 .root => unreachable,
74 .@"usingnamespace" => unreachable,
75 .test_decl => unreachable,
76 .doc_comment => unreachable,
77 .var_decl => unreachable,
78 .switch_case => unreachable,
79 .switch_else => unreachable,
80 .container_field_init => unreachable,
81 .container_field_align => unreachable,
82 .container_field => unreachable,
83
84 .assign,
85 .assign_bit_and,
86 .assign_bit_or,
87 .assign_bit_shift_left,
88 .assign_bit_shift_right,
89 .assign_bit_xor,
90 .assign_div,
91 .assign_sub,
92 .assign_sub_wrap,
93 .assign_mod,
94 .assign_add,
95 .assign_add_wrap,
96 .assign_mul,
97 .assign_mul_wrap,
98 .add,
99 .add_wrap,
100 .sub,
101 .sub_wrap,
102 .mul,
103 .mul_wrap,
104 .div,
105 .mod,
106 .bit_and,
107 .bit_or,
108 .bit_shift_left,
109 .bit_shift_right,
110 .bit_xor,
111 .bang_equal,
112 .equal_equal,
113 .greater_than,
114 .greater_or_equal,
115 .less_than,
116 .less_or_equal,
117 .array_cat,
118 .array_mult,
119 .bool_and,
120 .bool_or,
121 .@"asm",
122 .string_literal,
123 .integer_literal,
124 .call,
125 .@"unreachable",
126 .@"return",
127 .@"if",
128 .@"while",
129 .bool_not,
130 .address_of,
131 .float_literal,
132 .undefined_literal,
133 .bool_literal,
134 .null_literal,
135 .optional_type,
136 .block,
137 .labeled_block,
138 .@"break",
140139 .PtrType,
141 .ArrayType,
142 .ArrayTypeSentinel,
143 .EnumLiteral,
140 .array_type,
141 .array_type_sentinel,
142 .enum_literal,
144143 .MultilineStringLiteral,
145 .CharLiteral,
146 .Defer,
147 .Catch,
148 .ErrorUnion,
149 .MergeErrorSets,
150 .Range,
151 .Await,
152 .BitNot,
153 .Negation,
154 .NegationWrap,
155 .Resume,
156 .Try,
157 .SliceType,
158 .Slice,
144 .char_literal,
145 .@"defer",
146 .@"catch",
147 .error_union,
148 .merge_error_sets,
149 .range,
150 .@"await",
151 .bit_not,
152 .negation,
153 .negation_wrap,
154 .@"resume",
155 .@"try",
156 .slice_type,
157 .slice,
159158 .ArrayInitializer,
160159 .ArrayInitializerDot,
161160 .StructInitializer,
162161 .StructInitializerDot,
163 .Switch,
164 .For,
165 .Suspend,
166 .Continue,
167 .AnyType,
168 .ErrorType,
162 .@"switch",
163 .@"for",
164 .@"suspend",
165 .@"continue",
166 .@"anytype",
167 .error_type,
169168 .FnProto,
170 .AnyFrameType,
171 .ErrorSetDecl,
169 .anyframe_type,
170 .error_set_decl,
172171 .ContainerDecl,
173 .Comptime,
174 .Nosuspend,
172 .@"comptime",
173 .@"nosuspend",
174 .builtin_call,
175 .builtin_call_comma,
175176 => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),
176177
177 // @field can be assigned to
178 .BuiltinCall => {
179 const call = node.castTag(.BuiltinCall).?;
180 const tree = scope.tree();
181 const builtin_name = tree.tokenSlice(call.builtin_token);
182
178 // `@field` can be assigned to.
179 .builtin_call_two, .builtin_call_two_comma => {
180 const builtin_token = main_tokens[node];
181 const builtin_name = tree.tokenSlice(builtin_token);
183182 if (!mem.eql(u8, builtin_name, "@field")) {
184183 return mod.failNode(scope, node, "invalid left-hand side to assignment", .{});
185184 }
186185 },
187186
188187 // can be assigned to
189 .UnwrapOptional,
190 .Deref,
191 .Period,
192 .ArrayAccess,
193 .Identifier,
194 .GroupedExpression,
195 .OrElse,
188 .unwrap_optional,
189 .deref,
190 .period,
191 .array_access,
192 .identifier,
193 .grouped_expression,
194 .@"orelse",
196195 => {},
197196 }
198197 return expr(mod, scope, .ref, node);
......@@ -202,16 +201,16 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
202201/// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the
203202/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
204203/// 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 {
206205 switch (node.tag) {
207 .Root => unreachable, // Top-level declaration.
208 .Use => unreachable, // Top-level declaration.
209 .TestDecl => unreachable, // Top-level declaration.
210 .DocComment => unreachable, // Top-level declaration.
211 .VarDecl => unreachable, // Handled in `blockExpr`.
212 .SwitchCase => unreachable, // Handled in `switchExpr`.
213 .SwitchElse => unreachable, // Handled in `switchExpr`.
214 .Range => unreachable, // Handled in `switchExpr`.
206 .root => unreachable, // Top-level declaration.
207 .@"usingnamespace" => unreachable, // Top-level declaration.
208 .test_decl => unreachable, // Top-level declaration.
209 .doc_comment => unreachable, // Top-level declaration.
210 .var_decl => unreachable, // Handled in `blockExpr`.
211 .switch_case => unreachable, // Handled in `switchExpr`.
212 .switch_else => unreachable, // Handled in `switchExpr`.
213 .range => unreachable, // Handled in `switchExpr`.
215214 .Else => unreachable, // Handled explicitly the control flow expression functions.
216215 .Payload => unreachable, // Handled explicitly.
217216 .PointerPayload => unreachable, // Handled explicitly.
......@@ -220,114 +219,113 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
220219 .FieldInitializer => unreachable, // Handled explicitly.
221220 .ContainerField => unreachable, // Handled explicitly.
222221
223 .Assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)),
224 .AssignBitAnd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bit_and)),
225 .AssignBitOr => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitOr).?, .bit_or)),
226 .AssignBitShiftLeft => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftLeft).?, .shl)),
227 .AssignBitShiftRight => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftRight).?, .shr)),
228 .AssignBitXor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitXor).?, .xor)),
229 .AssignDiv => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignDiv).?, .div)),
230 .AssignSub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSub).?, .sub)),
231 .AssignSubWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSubWrap).?, .subwrap)),
232 .AssignMod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMod).?, .mod_rem)),
233 .AssignAdd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAdd).?, .add)),
234 .AssignAddWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAddWrap).?, .addwrap)),
235 .AssignMul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMul).?, .mul)),
236 .AssignMulWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMulWrap).?, .mulwrap)),
237
238 .Add => return simpleBinOp(mod, scope, rl, node.castTag(.Add).?, .add),
239 .AddWrap => return simpleBinOp(mod, scope, rl, node.castTag(.AddWrap).?, .addwrap),
240 .Sub => return simpleBinOp(mod, scope, rl, node.castTag(.Sub).?, .sub),
241 .SubWrap => return simpleBinOp(mod, scope, rl, node.castTag(.SubWrap).?, .subwrap),
242 .Mul => return simpleBinOp(mod, scope, rl, node.castTag(.Mul).?, .mul),
243 .MulWrap => return simpleBinOp(mod, scope, rl, node.castTag(.MulWrap).?, .mulwrap),
244 .Div => return simpleBinOp(mod, scope, rl, node.castTag(.Div).?, .div),
245 .Mod => return simpleBinOp(mod, scope, rl, node.castTag(.Mod).?, .mod_rem),
246 .BitAnd => return simpleBinOp(mod, scope, rl, node.castTag(.BitAnd).?, .bit_and),
247 .BitOr => return simpleBinOp(mod, scope, rl, node.castTag(.BitOr).?, .bit_or),
248 .BitShiftLeft => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftLeft).?, .shl),
249 .BitShiftRight => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftRight).?, .shr),
250 .BitXor => return simpleBinOp(mod, scope, rl, node.castTag(.BitXor).?, .xor),
251
252 .BangEqual => return simpleBinOp(mod, scope, rl, node.castTag(.BangEqual).?, .cmp_neq),
253 .EqualEqual => return simpleBinOp(mod, scope, rl, node.castTag(.EqualEqual).?, .cmp_eq),
254 .GreaterThan => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterThan).?, .cmp_gt),
255 .GreaterOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterOrEqual).?, .cmp_gte),
256 .LessThan => return simpleBinOp(mod, scope, rl, node.castTag(.LessThan).?, .cmp_lt),
257 .LessOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.LessOrEqual).?, .cmp_lte),
258
259 .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat),
260 .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul),
261
262 .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?),
263 .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?),
264
265 .BoolNot => return rvalue(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
266 .BitNot => return rvalue(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)),
267 .Negation => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)),
268 .NegationWrap => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)),
269
270 .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?),
271 .Asm => return rvalue(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)),
272 .StringLiteral => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)),
273 .IntegerLiteral => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node.castTag(.IntegerLiteral).?)),
274 .BuiltinCall => return builtinCall(mod, scope, rl, node.castTag(.BuiltinCall).?),
275 .Call => return callExpr(mod, scope, rl, node.castTag(.Call).?),
276 .Unreachable => return unreach(mod, scope, node.castTag(.Unreachable).?),
277 .Return => return ret(mod, scope, node.castTag(.Return).?),
278 .If => return ifExpr(mod, scope, rl, node.castTag(.If).?),
279 .While => return whileExpr(mod, scope, rl, node.castTag(.While).?),
280 .Period => return field(mod, scope, rl, node.castTag(.Period).?),
281 .Deref => return rvalue(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
282 .AddressOf => return rvalue(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
283 .FloatLiteral => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
284 .UndefinedLiteral => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
285 .BoolLiteral => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),
286 .NullLiteral => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node.castTag(.NullLiteral).?)),
287 .OptionalType => return rvalue(mod, scope, rl, try optionalType(mod, scope, node.castTag(.OptionalType).?)),
288 .UnwrapOptional => return unwrapOptional(mod, scope, rl, node.castTag(.UnwrapOptional).?),
289 .Block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),
290 .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?, .block),
291 .Break => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
292 .Continue => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node.castTag(.Continue).?)),
293 .PtrType => return rvalue(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
294 .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr),
295 .ArrayType => return rvalue(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)),
296 .ArrayTypeSentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)),
297 .EnumLiteral => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)),
298 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)),
299 .CharLiteral => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)),
300 .SliceType => return rvalue(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)),
301 .ErrorUnion => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)),
302 .MergeErrorSets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)),
303 .AnyFrameType => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)),
304 .ErrorSetDecl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node.castTag(.ErrorSetDecl).?)),
305 .ErrorType => return rvalue(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)),
306 .For => return forExpr(mod, scope, rl, node.castTag(.For).?),
307 .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?),
308 .Slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)),
309 .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?),
310 .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?),
311 .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?),
312 .Switch => return switchExpr(mod, scope, rl, node.castTag(.Switch).?),
313 .ContainerDecl => return containerDecl(mod, scope, rl, node.castTag(.ContainerDecl).?),
314
315 .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
316 .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
317 .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}),
318 .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
222 .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
223 .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
224 .assign_bit_or => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_or)),
225 .assign_bit_shift_left => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shl)),
226 .assign_bit_shift_right => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shr)),
227 .assign_bit_xor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .xor)),
228 .assign_div => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .div)),
229 .assign_sub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .sub)),
230 .assign_sub_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .subwrap)),
231 .assign_mod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mod_rem)),
232 .assign_add => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .add)),
233 .assign_add_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .addwrap)),
234 .assign_mul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mul)),
235 .assign_mul_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mulwrap)),
236
237 .add => return simpleBinOp(mod, scope, rl, node, .add),
238 .add_wrap => return simpleBinOp(mod, scope, rl, node, .addwrap),
239 .sub => return simpleBinOp(mod, scope, rl, node, .sub),
240 .sub_wrap => return simpleBinOp(mod, scope, rl, node, .subwrap),
241 .mul => return simpleBinOp(mod, scope, rl, node, .mul),
242 .mul_wrap => return simpleBinOp(mod, scope, rl, node, .mulwrap),
243 .div => return simpleBinOp(mod, scope, rl, node, .div),
244 .mod => return simpleBinOp(mod, scope, rl, node, .mod_rem),
245 .bit_and => return simpleBinOp(mod, scope, rl, node, .bit_and),
246 .bit_or => return simpleBinOp(mod, scope, rl, node, .bit_or),
247 .bit_shift_left => return simpleBinOp(mod, scope, rl, node, .shl),
248 .bit_shift_right => return simpleBinOp(mod, scope, rl, node, .shr),
249 .bit_xor => return simpleBinOp(mod, scope, rl, node, .xor),
250
251 .bang_equal => return simpleBinOp(mod, scope, rl, node, .cmp_neq),
252 .equal_equal => return simpleBinOp(mod, scope, rl, node, .cmp_eq),
253 .greater_than => return simpleBinOp(mod, scope, rl, node, .cmp_gt),
254 .greater_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_gte),
255 .less_than => return simpleBinOp(mod, scope, rl, node, .cmp_lt),
256 .less_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_lte),
257
258 .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat),
259 .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul),
260
261 .bool_and => return boolBinOp(mod, scope, rl, node),
262 .bool_or => return boolBinOp(mod, scope, rl, node),
263
264 .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)),
265 .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)),
266 .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)),
267 .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)),
268
269 .identifier => return try identifier(mod, scope, rl, node),
270 .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)),
271 .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)),
272 .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node)),
273 .builtin_call => return builtinCall(mod, scope, rl, node),
274 .call => return callExpr(mod, scope, rl, node),
275 .@"unreachable" => return unreach(mod, scope, node),
276 .@"return" => return ret(mod, scope, node),
277 .@"if" => return ifExpr(mod, scope, rl, node),
278 .@"while" => return whileExpr(mod, scope, rl, node),
279 .period => return field(mod, scope, rl, node),
280 .deref => return rvalue(mod, scope, rl, try deref(mod, scope, node)),
281 .address_of => return rvalue(mod, scope, rl, try addressOf(mod, scope, node)),
282 .float_literal => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node)),
283 .undefined_literal => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node)),
284 .bool_literal => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node)),
285 .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)),
286 .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)),
287 .unwrap_optional => return unwrapOptional(mod, scope, rl, node),
288 .block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node)),
289 .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block),
290 .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)),
291 .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)),
292 .grouped_expression => return expr(mod, scope, rl, node.expr),
293 .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)),
294 .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)),
295 .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)),
296 .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)),
297 .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)),
298 .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)),
299 .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)),
300 .merge_error_sets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .merge_error_sets)),
301 .anyframe_type => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node)),
302 .error_set_decl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node)),
303 .error_type => return rvalue(mod, scope, rl, try errorType(mod, scope, node)),
304 .@"for" => return forExpr(mod, scope, rl, node),
305 .array_access => return arrayAccess(mod, scope, rl, node),
306 .slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node)),
307 .@"catch" => return catchExpr(mod, scope, rl, node),
308 .@"comptime" => return comptimeKeyword(mod, scope, rl, node),
309 .@"orelse" => return orelseExpr(mod, scope, rl, node),
310 .@"switch" => return switchExpr(mod, scope, rl, node),
311 .ContainerDecl => return containerDecl(mod, scope, rl, node),
312
313 .@"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", .{}),
315 .@"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", .{}),
319317 .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}),
320318 .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}),
321319 .StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}),
322320 .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", .{}),
324 .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}),
321 .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),
322 .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),
325323 .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", .{}),
327325 }
328326}
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 {
331329 const tracy = trace(@src());
332330 defer tracy.end();
333331
......@@ -338,7 +336,7 @@ pub fn comptimeExpr(
338336 mod: *Module,
339337 parent_scope: *Scope,
340338 rl: ResultLoc,
341 node: *ast.Node,
339 node: ast.Node.Index,
342340) InnerError!*zir.Inst {
343341 // If we are already in a comptime scope, no need to make another one.
344342 if (parent_scope.isComptime()) {
......@@ -347,7 +345,7 @@ pub fn comptimeExpr(
347345
348346 // Optimization for labeled blocks: don't need to have 2 layers of blocks,
349347 // we can reuse the existing one.
350 if (node.castTag(.LabeledBlock)) |block_node| {
348 if (node.castTag(.labeled_block)) |block_node| {
351349 return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime);
352350 }
353351
......@@ -366,6 +364,8 @@ pub fn comptimeExpr(
366364 _ = try expr(mod, &block_scope.base, rl, node);
367365
368366 const tree = parent_scope.tree();
367 const node_datas = tree.nodes.items(.data);
368 const main_tokens = tree.nodes.items(.main_token);
369369 const src = tree.token_locs[node.firstToken()].start;
370370
371371 const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{
......@@ -381,6 +381,8 @@ fn breakExpr(
381381 node: *ast.Node.ControlFlowExpression,
382382) InnerError!*zir.Inst {
383383 const tree = parent_scope.tree();
384 const node_datas = tree.nodes.items(.data);
385 const main_tokens = tree.nodes.items(.main_token);
384386 const src = tree.token_locs[node.ltoken].start;
385387
386388 // Look for the label in the scope.
......@@ -445,6 +447,8 @@ fn breakExpr(
445447
446448fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
447449 const tree = parent_scope.tree();
450 const node_datas = tree.nodes.items(.data);
451 const main_tokens = tree.nodes.items(.main_token);
448452 const src = tree.token_locs[node.ltoken].start;
449453
450454 // Look for the label in the scope.
......@@ -485,7 +489,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE
485489 }
486490}
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 {
489493 const tracy = trace(@src());
490494 defer tracy.end();
491495
......@@ -502,6 +506,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
502506 if (gen_zir.label) |prev_label| {
503507 if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {
504508 const tree = parent_scope.tree();
509 const node_datas = tree.nodes.items(.data);
510 const main_tokens = tree.nodes.items(.main_token);
505511 const label_src = tree.token_locs[label].start;
506512 const prev_label_src = tree.token_locs[prev_label.token].start;
507513
......@@ -539,7 +545,7 @@ fn labeledBlockExpr(
539545 mod: *Module,
540546 parent_scope: *Scope,
541547 rl: ResultLoc,
542 block_node: *ast.Node.LabeledBlock,
548 block_node: *ast.Node.labeled_block,
543549 zir_tag: zir.Inst.Tag,
544550) InnerError!*zir.Inst {
545551 const tracy = trace(@src());
......@@ -548,6 +554,8 @@ fn labeledBlockExpr(
548554 assert(zir_tag == .block or zir_tag == .block_comptime);
549555
550556 const tree = parent_scope.tree();
557 const node_datas = tree.nodes.items(.data);
558 const main_tokens = tree.nodes.items(.main_token);
551559 const src = tree.token_locs[block_node.lbrace].start;
552560
553561 try checkLabelRedefinition(mod, parent_scope, block_node.label);
......@@ -627,10 +635,12 @@ fn labeledBlockExpr(
627635fn blockExprStmts(
628636 mod: *Module,
629637 parent_scope: *Scope,
630 node: *ast.Node,
631 statements: []*ast.Node,
638 node: ast.Node.Index,
639 statements: []const ast.Node.Index,
632640) !void {
633641 const tree = parent_scope.tree();
642 const node_datas = tree.nodes.items(.data);
643 const main_tokens = tree.nodes.items(.main_token);
634644
635645 var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
636646 defer block_arena.deinit();
......@@ -640,24 +650,24 @@ fn blockExprStmts(
640650 const src = tree.token_locs[statement.firstToken()].start;
641651 _ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
642652 switch (statement.tag) {
643 .VarDecl => {
644 const var_decl_node = statement.castTag(.VarDecl).?;
653 .var_decl => {
654 const var_decl_node = statement.castTag(.var_decl).?;
645655 scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);
646656 },
647 .Assign => try assign(mod, scope, statement.castTag(.Assign).?),
648 .AssignBitAnd => try assignOp(mod, scope, statement.castTag(.AssignBitAnd).?, .bit_and),
649 .AssignBitOr => try assignOp(mod, scope, statement.castTag(.AssignBitOr).?, .bit_or),
650 .AssignBitShiftLeft => try assignOp(mod, scope, statement.castTag(.AssignBitShiftLeft).?, .shl),
651 .AssignBitShiftRight => try assignOp(mod, scope, statement.castTag(.AssignBitShiftRight).?, .shr),
652 .AssignBitXor => try assignOp(mod, scope, statement.castTag(.AssignBitXor).?, .xor),
653 .AssignDiv => try assignOp(mod, scope, statement.castTag(.AssignDiv).?, .div),
654 .AssignSub => try assignOp(mod, scope, statement.castTag(.AssignSub).?, .sub),
655 .AssignSubWrap => try assignOp(mod, scope, statement.castTag(.AssignSubWrap).?, .subwrap),
656 .AssignMod => try assignOp(mod, scope, statement.castTag(.AssignMod).?, .mod_rem),
657 .AssignAdd => try assignOp(mod, scope, statement.castTag(.AssignAdd).?, .add),
658 .AssignAddWrap => try assignOp(mod, scope, statement.castTag(.AssignAddWrap).?, .addwrap),
659 .AssignMul => try assignOp(mod, scope, statement.castTag(.AssignMul).?, .mul),
660 .AssignMulWrap => try assignOp(mod, scope, statement.castTag(.AssignMulWrap).?, .mulwrap),
657 .assign => try assign(mod, scope, statement),
658 .assign_bit_and => try assignOp(mod, scope, statement, .bit_and),
659 .assign_bit_or => try assignOp(mod, scope, statement, .bit_or),
660 .assign_bit_shift_left => try assignOp(mod, scope, statement, .shl),
661 .assign_bit_shift_right => try assignOp(mod, scope, statement, .shr),
662 .assign_bit_xor => try assignOp(mod, scope, statement, .xor),
663 .assign_div => try assignOp(mod, scope, statement, .div),
664 .assign_sub => try assignOp(mod, scope, statement, .sub),
665 .assign_sub_wrap => try assignOp(mod, scope, statement, .subwrap),
666 .assign_mod => try assignOp(mod, scope, statement, .mod_rem),
667 .assign_add => try assignOp(mod, scope, statement, .add),
668 .assign_add_wrap => try assignOp(mod, scope, statement, .addwrap),
669 .assign_mul => try assignOp(mod, scope, statement, .mul),
670 .assign_mul_wrap => try assignOp(mod, scope, statement, .mulwrap),
661671
662672 else => {
663673 const possibly_unused_result = try expr(mod, scope, .none, statement);
......@@ -672,7 +682,7 @@ fn blockExprStmts(
672682fn varDecl(
673683 mod: *Module,
674684 scope: *Scope,
675 node: *ast.Node.VarDecl,
685 node: *ast.Node.var_decl,
676686 block_arena: *Allocator,
677687) InnerError!*Scope {
678688 if (node.getComptimeToken()) |comptime_token| {
......@@ -682,6 +692,8 @@ fn varDecl(
682692 return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});
683693 }
684694 const tree = scope.tree();
695 const node_datas = tree.nodes.items(.data);
696 const main_tokens = tree.nodes.items(.main_token);
685697 const name_src = tree.token_locs[node.name_token].start;
686698 const ident_name = try mod.identifierTokenString(scope, node.name_token);
687699
......@@ -733,7 +745,7 @@ fn varDecl(
733745 return mod.fail(scope, name_src, "variables must be initialized", .{});
734746
735747 switch (tree.token_ids[node.mut_token]) {
736 .Keyword_const => {
748 .keyword_const => {
737749 // Depending on the type of AST the initialization expression is, we may need an lvalue
738750 // or an rvalue as a result location. If it is an rvalue, we can use the instruction as
739751 // the variable, no memory location needed.
......@@ -834,7 +846,7 @@ fn varDecl(
834846 };
835847 return &sub_scope.base;
836848 },
837 .Keyword_var => {
849 .keyword_var => {
838850 var resolve_inferred_alloc: ?*zir.Inst = null;
839851 const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {
840852 const type_inst = try typeExpr(mod, scope, type_node);
......@@ -862,33 +874,39 @@ fn varDecl(
862874 }
863875}
864876
865fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!void {
866 if (infix_node.lhs.castTag(.Identifier)) |ident| {
867 // This intentionally does not support @"_" syntax.
868 const ident_name = scope.tree().tokenSlice(ident.token);
877fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!void {
878 const tree = scope.tree();
879 const node_datas = tree.nodes.items(.data);
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]);
869886 if (mem.eql(u8, ident_name, "_")) {
870887 _ = try expr(mod, scope, .discard, infix_node.rhs);
871888 return;
872889 }
873890 }
874 const lvalue = try lvalExpr(mod, scope, infix_node.lhs);
875 _ = try expr(mod, scope, .{ .ptr = lvalue }, infix_node.rhs);
891 const lvalue = try lvalExpr(mod, scope, lhs);
892 _ = try expr(mod, scope, .{ .ptr = lvalue }, rhs);
876893}
877894
878895fn assignOp(
879896 mod: *Module,
880897 scope: *Scope,
881 infix_node: *ast.Node.SimpleInfixOp,
898 infix_node: ast.Node.Index,
882899 op_inst_tag: zir.Inst.Tag,
883900) 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
889901 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]];
892910 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
893911 _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result);
894912}
......@@ -935,7 +953,7 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn
935953 return addZIRUnOp(mod, scope, src, .optional_type, operand);
936954}
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 {
939957 const tree = scope.tree();
940958 const src = tree.token_locs[node.op_token].start;
941959 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
948966 .Asterisk, .AsteriskAsterisk => .One,
949967 // TODO stage1 type inference bug
950968 .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) {
951 .Identifier => .C,
969 .identifier => .C,
952970 else => .Many,
953971 }),
954972 else => unreachable,
......@@ -998,7 +1016,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo,
9981016 return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
9991017}
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 {
10021020 const tree = scope.tree();
10031021 const src = tree.token_locs[node.op_token].start;
10041022 const usize_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1013,7 +1031,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst
10131031 return addZIRBinOp(mod, scope, src, .array_type, len, elem_type);
10141032}
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 {
10171035 const tree = scope.tree();
10181036 const src = tree.token_locs[node.op_token].start;
10191037 const usize_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1034,7 +1052,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti
10341052 }, .{});
10351053}
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 {
10381056 const tree = scope.tree();
10391057 const src = tree.token_locs[node.anyframe_token].start;
10401058 if (node.result) |some| {
......@@ -1056,7 +1074,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins
10561074 return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload);
10571075}
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 {
10601078 const tree = scope.tree();
10611079 const src = tree.token_locs[node.name].start;
10621080 const name = try mod.identifierTokenString(scope, node.name);
......@@ -1141,13 +1159,13 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
11411159
11421160 var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
11431161 if (node.layout_token) |some| switch (tree.token_ids[some]) {
1144 .Keyword_extern => layout = .Extern,
1145 .Keyword_packed => layout = .Packed,
1162 .keyword_extern => layout = .Extern,
1163 .keyword_packed => layout = .Packed,
11461164 else => unreachable,
11471165 };
11481166
11491167 const container_type = switch (tree.token_ids[node.kind_token]) {
1150 .Keyword_enum => blk: {
1168 .keyword_enum => blk: {
11511169 const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {
11521170 .Type => |t| try typeExpr(mod, &gen_scope.base, t),
11531171 .None => null,
......@@ -1174,7 +1192,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
11741192 };
11751193 break :blk Type.initPayload(&enum_type.base);
11761194 },
1177 .Keyword_struct => blk: {
1195 .keyword_struct => blk: {
11781196 assert(node.init_arg_expr == .None);
11791197 const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
11801198 .fields = try arena.dupe(*zir.Inst, fields.items),
......@@ -1196,7 +1214,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
11961214 };
11971215 break :blk Type.initPayload(&struct_type.base);
11981216 },
1199 .Keyword_union => blk: {
1217 .keyword_union => blk: {
12001218 const init_inst = switch (node.init_arg_expr) {
12011219 .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,
12021220 .None => null,
......@@ -1229,7 +1247,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
12291247 };
12301248 break :blk Type.initPayload(&union_type.base);
12311249 },
1232 .Keyword_opaque => blk: {
1250 .keyword_opaque => blk: {
12331251 if (fields.items.len > 0) {
12341252 return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{});
12351253 }
......@@ -1258,7 +1276,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
12581276 }
12591277}
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 {
12621280 const tree = scope.tree();
12631281 const src = tree.token_locs[node.error_token].start;
12641282 const decls = node.decls();
......@@ -1281,7 +1299,7 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*
12811299 });
12821300}
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 {
12851303 switch (rl) {
12861304 .ref => return orelseCatchExpr(
12871305 mod,
......@@ -1528,7 +1546,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI
15281546 const tree = scope.tree();
15291547 const src = tree.token_locs[node.op_token].start;
15301548 // 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);
15321550 if (rl == .ref) {
15331551 return addZirInstTag(mod, scope, src, .field_ptr, .{
15341552 .object = try expr(mod, scope, .ref, node.lhs),
......@@ -1545,7 +1563,7 @@ fn namedField(
15451563 mod: *Module,
15461564 scope: *Scope,
15471565 rl: ResultLoc,
1548 call: *ast.Node.BuiltinCall,
1566 call: *ast.Node.builtin_call,
15491567) InnerError!*zir.Inst {
15501568 try ensureBuiltinParamCount(mod, scope, call, 2);
15511569
......@@ -1571,7 +1589,7 @@ fn namedField(
15711589 }));
15721590}
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 {
15751593 const tree = scope.tree();
15761594 const src = tree.token_locs[node.rtoken].start;
15771595 const usize_type = try addZIRInstConst(mod, scope, src, .{
......@@ -1592,7 +1610,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array
15921610 }));
15931611}
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 {
15961614 const tree = scope.tree();
15971615 const src = tree.token_locs[node.rtoken].start;
15981616
......@@ -1633,15 +1651,16 @@ fn simpleBinOp(
16331651 mod: *Module,
16341652 scope: *Scope,
16351653 rl: ResultLoc,
1636 infix_node: *ast.Node.SimpleInfixOp,
1654 infix_node: ast.Node.Index,
16371655 op_inst_tag: zir.Inst.Tag,
16381656) InnerError!*zir.Inst {
16391657 const tree = scope.tree();
1640 const src = tree.token_locs[infix_node.op_token].start;
1641
1642 const lhs = try expr(mod, scope, .none, infix_node.lhs);
1643 const rhs = try expr(mod, scope, .none, infix_node.rhs);
1658 const node_datas = tree.nodes.items(.data);
1659 const main_tokens = tree.nodes.items(.main_token);
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]];
16451664 const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
16461665 return rvalue(mod, scope, rl, result);
16471666}
......@@ -1653,6 +1672,9 @@ fn boolBinOp(
16531672 infix_node: *ast.Node.SimpleInfixOp,
16541673) InnerError!*zir.Inst {
16551674 const tree = scope.tree();
1675 const node_datas = tree.nodes.items(.data);
1676 const main_tokens = tree.nodes.items(.main_token);
1677
16561678 const src = tree.token_locs[infix_node.op_token].start;
16571679 const bool_type = try addZIRInstConst(mod, scope, src, .{
16581680 .ty = Type.initTag(.type),
......@@ -1703,7 +1725,7 @@ fn boolBinOp(
17031725 };
17041726 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;
17071729 _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{
17081730 .block = block,
17091731 .operand = try addZIRInstConst(mod, &const_scope.base, src, .{
......@@ -1769,7 +1791,7 @@ const CondKind = union(enum) {
17691791 return &then_scope.base;
17701792 };
17711793 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
17741796 // This intentionally does not support @"_" syntax.
17751797 const ident_name = then_scope.base.tree().tokenSlice(ident_node.token);
......@@ -1788,7 +1810,7 @@ const CondKind = union(enum) {
17881810 const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .err_union_payload_unsafe_ptr, self.err_union.?);
17891811
17901812 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
17931815 // This intentionally does not support @"_" syntax.
17941816 const ident_name = else_scope.base.tree().tokenSlice(ident_node.token);
......@@ -1800,7 +1822,7 @@ const CondKind = union(enum) {
18001822 }
18011823};
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 {
18041826 var cond_kind: CondKind = .bool;
18051827 if (if_node.payload) |_| cond_kind = .{ .optional = null };
18061828 if (if_node.@"else") |else_node| {
......@@ -1819,6 +1841,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn
18191841 defer block_scope.instructions.deinit(mod.gpa);
18201842
18211843 const tree = scope.tree();
1844 const node_datas = tree.nodes.items(.data);
1845 const main_tokens = tree.nodes.items(.main_token);
18221846 const if_src = tree.token_locs[if_node.if_token].start;
18231847 const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition);
18241848
......@@ -1918,7 +1942,7 @@ fn whileExpr(
19181942 mod: *Module,
19191943 scope: *Scope,
19201944 rl: ResultLoc,
1921 while_node: *ast.Node.While,
1945 while_node: *ast.Node.@"while",
19221946) InnerError!*zir.Inst {
19231947 var cond_kind: CondKind = .bool;
19241948 if (while_node.payload) |_| cond_kind = .{ .optional = null };
......@@ -1955,6 +1979,8 @@ fn whileExpr(
19551979 defer continue_scope.instructions.deinit(mod.gpa);
19561980
19571981 const tree = scope.tree();
1982 const node_datas = tree.nodes.items(.data);
1983 const main_tokens = tree.nodes.items(.main_token);
19581984 const while_src = tree.token_locs[while_node.while_token].start;
19591985 const void_type = try addZIRInstConst(mod, scope, while_src, .{
19601986 .ty = Type.initTag(.type),
......@@ -2066,7 +2092,7 @@ fn forExpr(
20662092 mod: *Module,
20672093 scope: *Scope,
20682094 rl: ResultLoc,
2069 for_node: *ast.Node.For,
2095 for_node: *ast.Node.@"for",
20702096) InnerError!*zir.Inst {
20712097 if (for_node.label) |label| {
20722098 try checkLabelRedefinition(mod, scope, label);
......@@ -2077,6 +2103,8 @@ fn forExpr(
20772103
20782104 // setup variables and constants
20792105 const tree = scope.tree();
2106 const node_datas = tree.nodes.items(.data);
2107 const main_tokens = tree.nodes.items(.main_token);
20802108 const for_src = tree.token_locs[for_node.for_token].start;
20812109 const index_ptr = blk: {
20822110 const usize_type = try addZIRInstConst(mod, scope, for_src, .{
......@@ -2246,9 +2274,9 @@ fn forExpr(
22462274 );
22472275}
22482276
2249fn switchCaseUsesRef(node: *ast.Node.Switch) bool {
2277fn switchCaseUsesRef(node: *ast.Node.@"switch") bool {
22502278 for (node.cases()) |uncasted_case| {
2251 const case = uncasted_case.castTag(.SwitchCase).?;
2279 const case = uncasted_case.castTag(.switch_case).?;
22522280 const uncasted_payload = case.payload orelse continue;
22532281 const payload = uncasted_payload.castTag(.PointerPayload).?;
22542282 if (payload.ptr_token) |_| return true;
......@@ -2260,15 +2288,17 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp {
22602288 var cur = node;
22612289 while (true) {
22622290 switch (cur.tag) {
2263 .Range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur),
2264 .GroupedExpression => cur = @fieldParentPtr(ast.Node.GroupedExpression, "base", cur).expr,
2291 .range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur),
2292 .grouped_expression => cur = @fieldParentPtr(ast.Node.grouped_expression, "base", cur).expr,
22652293 else => return null,
22662294 }
22672295 }
22682296}
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 {
22712299 const tree = scope.tree();
2300 const node_datas = tree.nodes.items(.data);
2301 const main_tokens = tree.nodes.items(.main_token);
22722302 const switch_src = tree.token_locs[switch_node.switch_token].start;
22732303 const use_ref = switchCaseUsesRef(switch_node);
22742304
......@@ -2291,12 +2321,12 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
22912321 var first_range: ?*zir.Inst = null;
22922322 var simple_case_count: usize = 0;
22932323 for (switch_node.cases()) |uncasted_case| {
2294 const case = uncasted_case.castTag(.SwitchCase).?;
2324 const case = uncasted_case.castTag(.switch_case).?;
22952325 const case_src = tree.token_locs[case.firstToken()].start;
22962326 assert(case.items_len != 0);
22972327
22982328 // 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) {
23002330 if (else_src) |src| {
23012331 const msg = msg: {
23022332 const msg = try mod.errMsg(
......@@ -2313,7 +2343,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
23132343 }
23142344 else_src = case_src;
23152345 continue;
2316 } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and
2346 } else if (case.items_len == 1 and case.items()[0].tag == .identifier and
23172347 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))
23182348 {
23192349 if (underscore_src) |src| {
......@@ -2412,20 +2442,20 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node
24122442 defer else_scope.instructions.deinit(mod.gpa);
24132443
24142444 // Now generate all but the special cases
2415 var special_case: ?*ast.Node.SwitchCase = null;
2445 var special_case: ?*ast.Node.switch_case = null;
24162446 var items_index: usize = 0;
24172447 var case_index: usize = 0;
24182448 for (switch_node.cases()) |uncasted_case| {
2419 const case = uncasted_case.castTag(.SwitchCase).?;
2449 const case = uncasted_case.castTag(.switch_case).?;
24202450 const case_src = tree.token_locs[case.firstToken()].start;
24212451 // reset without freeing to reduce allocations.
24222452 case_scope.instructions.items.len = 0;
24232453
24242454 // 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) {
24262456 special_case = case;
24272457 continue;
2428 } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and
2458 } else if (case.items_len == 1 and case.items()[0].tag == .identifier and
24292459 mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_"))
24302460 {
24312461 special_case = case;
......@@ -2528,11 +2558,13 @@ fn switchCaseExpr(
25282558 scope: *Scope,
25292559 rl: ResultLoc,
25302560 block: *zir.Inst.Block,
2531 case: *ast.Node.SwitchCase,
2561 case: *ast.Node.switch_case,
25322562 target: *zir.Inst,
25332563 target_ptr: ?*zir.Inst,
25342564) !void {
25352565 const tree = scope.tree();
2566 const node_datas = tree.nodes.items(.data);
2567 const main_tokens = tree.nodes.items(.main_token);
25362568 const case_src = tree.token_locs[case.firstToken()].start;
25372569 const sub_scope = blk: {
25382570 const uncasted_payload = case.payload orelse break :blk scope;
......@@ -2559,6 +2591,8 @@ fn switchCaseExpr(
25592591
25602592fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst {
25612593 const tree = scope.tree();
2594 const node_datas = tree.nodes.items(.data);
2595 const main_tokens = tree.nodes.items(.main_token);
25622596 const src = tree.token_locs[cfe.ltoken].start;
25632597 if (cfe.getRHS()) |rhs_node| {
25642598 if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
......@@ -2580,6 +2614,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
25802614 defer tracy.end();
25812615
25822616 const tree = scope.tree();
2617 const node_datas = tree.nodes.items(.data);
2618 const main_tokens = tree.nodes.items(.main_token);
25832619 const ident_name = try mod.identifierTokenString(scope, ident.token);
25842620 const src = tree.token_locs[ident.token].start;
25852621 if (mem.eql(u8, ident_name, "_")) {
......@@ -2667,6 +2703,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo
26672703
26682704fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
26692705 const tree = scope.tree();
2706 const node_datas = tree.nodes.items(.data);
2707 const main_tokens = tree.nodes.items(.main_token);
26702708 const unparsed_bytes = tree.tokenSlice(str_lit.token);
26712709 const arena = scope.arena();
26722710
......@@ -2686,6 +2724,8 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner
26862724
26872725fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst {
26882726 const tree = scope.tree();
2727 const node_datas = tree.nodes.items(.data);
2728 const main_tokens = tree.nodes.items(.main_token);
26892729 const lines = node.linesConst();
26902730 const src = tree.token_locs[lines[0]].start;
26912731
......@@ -2713,6 +2753,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr
27132753
27142754fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst {
27152755 const tree = scope.tree();
2756 const node_datas = tree.nodes.items(.data);
2757 const main_tokens = tree.nodes.items(.main_token);
27162758 const src = tree.token_locs[node.token].start;
27172759 const slice = tree.tokenSlice(node.token);
27182760
......@@ -2733,6 +2775,8 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst
27332775fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
27342776 const arena = scope.arena();
27352777 const tree = scope.tree();
2778 const node_datas = tree.nodes.items(.data);
2779 const main_tokens = tree.nodes.items(.main_token);
27362780 const prefixed_bytes = tree.tokenSlice(int_lit.token);
27372781 const base = if (mem.startsWith(u8, prefixed_bytes, "0x"))
27382782 16
......@@ -2762,6 +2806,8 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne
27622806fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) InnerError!*zir.Inst {
27632807 const arena = scope.arena();
27642808 const tree = scope.tree();
2809 const node_datas = tree.nodes.items(.data);
2810 const main_tokens = tree.nodes.items(.main_token);
27652811 const bytes = tree.tokenSlice(float_lit.token);
27662812 if (bytes.len > 2 and bytes[1] == 'x') {
27672813 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
27802826fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
27812827 const arena = scope.arena();
27822828 const tree = scope.tree();
2829 const node_datas = tree.nodes.items(.data);
2830 const main_tokens = tree.nodes.items(.main_token);
27832831 const src = tree.token_locs[node.token].start;
27842832 return addZIRInstConst(mod, scope, src, .{
27852833 .ty = Type.initTag(.@"undefined"),
......@@ -2790,12 +2838,14 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro
27902838fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
27912839 const arena = scope.arena();
27922840 const tree = scope.tree();
2841 const node_datas = tree.nodes.items(.data);
2842 const main_tokens = tree.nodes.items(.main_token);
27932843 const src = tree.token_locs[node.token].start;
27942844 return addZIRInstConst(mod, scope, src, .{
27952845 .ty = Type.initTag(.bool),
27962846 .val = switch (tree.token_ids[node.token]) {
2797 .Keyword_true => Value.initTag(.bool_true),
2798 .Keyword_false => Value.initTag(.bool_false),
2847 .keyword_true => Value.initTag(.bool_true),
2848 .keyword_false => Value.initTag(.bool_false),
27992849 else => unreachable,
28002850 },
28012851 });
......@@ -2804,6 +2854,8 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
28042854fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst {
28052855 const arena = scope.arena();
28062856 const tree = scope.tree();
2857 const node_datas = tree.nodes.items(.data);
2858 const main_tokens = tree.nodes.items(.main_token);
28072859 const src = tree.token_locs[node.token].start;
28082860 return addZIRInstConst(mod, scope, src, .{
28092861 .ty = Type.initTag(.@"null"),
......@@ -2811,12 +2863,14 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError
28112863 });
28122864}
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 {
28152867 if (asm_node.outputs.len != 0) {
28162868 return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{});
28172869 }
28182870 const arena = scope.arena();
28192871 const tree = scope.tree();
2872 const node_datas = tree.nodes.items(.data);
2873 const main_tokens = tree.nodes.items(.main_token);
28202874
28212875 const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len);
28222876 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
28392893 .ty = Type.initTag(.type),
28402894 .val = Value.initTag(.void_type),
28412895 });
2842 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{
2896 const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{
28432897 .asm_source = try expr(mod, scope, str_type_rl, asm_node.template),
28442898 .return_type = return_type,
28452899 }, .{
......@@ -2851,7 +2905,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi
28512905 return asm_inst;
28522906}
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 {
28552909 if (call.params_len == count)
28562910 return;
28572911
......@@ -2863,11 +2917,13 @@ fn simpleCast(
28632917 mod: *Module,
28642918 scope: *Scope,
28652919 rl: ResultLoc,
2866 call: *ast.Node.BuiltinCall,
2920 call: *ast.Node.builtin_call,
28672921 inst_tag: zir.Inst.Tag,
28682922) InnerError!*zir.Inst {
28692923 try ensureBuiltinParamCount(mod, scope, call, 2);
28702924 const tree = scope.tree();
2925 const node_datas = tree.nodes.items(.data);
2926 const main_tokens = tree.nodes.items(.main_token);
28712927 const src = tree.token_locs[call.builtin_token].start;
28722928 const params = call.params();
28732929 const dest_type = try typeExpr(mod, scope, params[0]);
......@@ -2876,10 +2932,12 @@ fn simpleCast(
28762932 return rvalue(mod, scope, rl, result);
28772933}
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 {
28802936 try ensureBuiltinParamCount(mod, scope, call, 1);
28812937 const operand = try expr(mod, scope, .none, call.params()[0]);
28822938 const tree = scope.tree();
2939 const node_datas = tree.nodes.items(.data);
2940 const main_tokens = tree.nodes.items(.main_token);
28832941 const src = tree.token_locs[call.builtin_token].start;
28842942 return addZIRUnOp(mod, scope, src, .ptrtoint, operand);
28852943}
......@@ -2888,10 +2946,12 @@ fn as(
28882946 mod: *Module,
28892947 scope: *Scope,
28902948 rl: ResultLoc,
2891 call: *ast.Node.BuiltinCall,
2949 call: *ast.Node.builtin_call,
28922950) InnerError!*zir.Inst {
28932951 try ensureBuiltinParamCount(mod, scope, call, 2);
28942952 const tree = scope.tree();
2953 const node_datas = tree.nodes.items(.data);
2954 const main_tokens = tree.nodes.items(.main_token);
28952955 const src = tree.token_locs[call.builtin_token].start;
28962956 const params = call.params();
28972957 const dest_type = try typeExpr(mod, scope, params[0]);
......@@ -2963,9 +3023,11 @@ fn asRlPtr(
29633023 }
29643024}
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 {
29673027 try ensureBuiltinParamCount(mod, scope, call, 2);
29683028 const tree = scope.tree();
3029 const node_datas = tree.nodes.items(.data);
3030 const main_tokens = tree.nodes.items(.main_token);
29693031 const src = tree.token_locs[call.builtin_token].start;
29703032 const params = call.params();
29713033 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
30073069 }
30083070}
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 {
30113073 try ensureBuiltinParamCount(mod, scope, call, 1);
30123074 const tree = scope.tree();
3075 const node_datas = tree.nodes.items(.data);
3076 const main_tokens = tree.nodes.items(.main_token);
30133077 const src = tree.token_locs[call.builtin_token].start;
30143078 const params = call.params();
30153079 const target = try expr(mod, scope, .none, params[0]);
30163080 return addZIRUnOp(mod, scope, src, .import, target);
30173081}
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 {
30203084 try ensureBuiltinParamCount(mod, scope, call, 1);
30213085 const tree = scope.tree();
3086 const node_datas = tree.nodes.items(.data);
3087 const main_tokens = tree.nodes.items(.main_token);
30223088 const src = tree.token_locs[call.builtin_token].start;
30233089 const params = call.params();
30243090 const target = try expr(mod, scope, .none, params[0]);
30253091 return addZIRUnOp(mod, scope, src, .compile_error, target);
30263092}
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 {
30293095 try ensureBuiltinParamCount(mod, scope, call, 1);
30303096 const tree = scope.tree();
3097 const node_datas = tree.nodes.items(.data);
3098 const main_tokens = tree.nodes.items(.main_token);
30313099 const src = tree.token_locs[call.builtin_token].start;
30323100 const params = call.params();
30333101 const u32_type = try addZIRInstConst(mod, scope, src, .{
......@@ -3038,8 +3106,10 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall)
30383106 return addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota);
30393107}
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 {
30423110 const tree = scope.tree();
3111 const node_datas = tree.nodes.items(.data);
3112 const main_tokens = tree.nodes.items(.main_token);
30433113 const arena = scope.arena();
30443114 const src = tree.token_locs[call.builtin_token].start;
30453115 const params = call.params();
......@@ -3054,8 +3124,10 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal
30543124 items[param_i] = try expr(mod, scope, .none, param);
30553125 return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{}));
30563126}
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 {
30583128 const tree = scope.tree();
3129 const node_datas = tree.nodes.items(.data);
3130 const main_tokens = tree.nodes.items(.main_token);
30593131 const arena = scope.arena();
30603132 const src = tree.token_locs[call.builtin_token].start;
30613133 const params = call.params();
......@@ -3065,8 +3137,10 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerErr
30653137 return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{});
30663138}
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 {
30693141 const tree = scope.tree();
3142 const node_datas = tree.nodes.items(.data);
3143 const main_tokens = tree.nodes.items(.main_token);
30703144 const builtin_name = tree.tokenSlice(call.builtin_token);
30713145
30723146 // 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
31043178 }
31053179}
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 {
31083182 const tree = scope.tree();
3183 const node_datas = tree.nodes.items(.data);
3184 const main_tokens = tree.nodes.items(.main_token);
31093185 const lhs = try expr(mod, scope, .none, node.lhs);
31103186
31113187 const param_nodes = node.params();
......@@ -3130,6 +3206,8 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In
31303206
31313207fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst {
31323208 const tree = scope.tree();
3209 const node_datas = tree.nodes.items(.data);
3210 const main_tokens = tree.nodes.items(.main_token);
31333211 const src = tree.token_locs[unreach_node.token].start;
31343212 return addZIRNoOp(mod, scope, src, .unreachable_safe);
31353213}
......@@ -3176,11 +3254,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
31763254 while (true) {
31773255 switch (node.tag) {
31783256 .Root,
3179 .Use,
3180 .TestDecl,
3181 .DocComment,
3182 .SwitchCase,
3183 .SwitchElse,
3257 .@"usingnamespace",
3258 .test_decl,
3259 .doc_comment,
3260 .switch_case,
3261 .switch_else,
31843262 .Else,
31853263 .Payload,
31863264 .PointerPayload,
......@@ -3190,97 +3268,97 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
31903268 .FieldInitializer,
31913269 => unreachable,
31923270
3193 .Return,
3194 .Break,
3195 .Continue,
3196 .BitNot,
3197 .BoolNot,
3198 .VarDecl,
3199 .Defer,
3200 .AddressOf,
3201 .OptionalType,
3202 .Negation,
3203 .NegationWrap,
3204 .Resume,
3205 .ArrayType,
3206 .ArrayTypeSentinel,
3271 .@"return",
3272 .@"break",
3273 .@"continue",
3274 .bit_not,
3275 .bool_not,
3276 .var_decl,
3277 .@"defer",
3278 .address_of,
3279 .optional_type,
3280 .negation,
3281 .negation_wrap,
3282 .@"resume",
3283 .array_type,
3284 .array_type_sentinel,
32073285 .PtrType,
3208 .SliceType,
3209 .Suspend,
3210 .AnyType,
3211 .ErrorType,
3286 .slice_type,
3287 .@"suspend",
3288 .@"anytype",
3289 .error_type,
32123290 .FnProto,
3213 .AnyFrameType,
3214 .IntegerLiteral,
3215 .FloatLiteral,
3216 .EnumLiteral,
3217 .StringLiteral,
3291 .anyframe_type,
3292 .integer_literal,
3293 .float_literal,
3294 .enum_literal,
3295 .string_literal,
32183296 .MultilineStringLiteral,
3219 .CharLiteral,
3220 .BoolLiteral,
3221 .NullLiteral,
3222 .UndefinedLiteral,
3223 .Unreachable,
3224 .Identifier,
3225 .ErrorSetDecl,
3297 .char_literal,
3298 .bool_literal,
3299 .null_literal,
3300 .undefined_literal,
3301 .@"unreachable",
3302 .identifier,
3303 .error_set_decl,
32263304 .ContainerDecl,
3227 .Asm,
3228 .Add,
3229 .AddWrap,
3230 .ArrayCat,
3231 .ArrayMult,
3232 .Assign,
3233 .AssignBitAnd,
3234 .AssignBitOr,
3235 .AssignBitShiftLeft,
3236 .AssignBitShiftRight,
3237 .AssignBitXor,
3238 .AssignDiv,
3239 .AssignSub,
3240 .AssignSubWrap,
3241 .AssignMod,
3242 .AssignAdd,
3243 .AssignAddWrap,
3244 .AssignMul,
3245 .AssignMulWrap,
3246 .BangEqual,
3247 .BitAnd,
3248 .BitOr,
3249 .BitShiftLeft,
3250 .BitShiftRight,
3251 .BitXor,
3252 .BoolAnd,
3253 .BoolOr,
3254 .Div,
3255 .EqualEqual,
3256 .ErrorUnion,
3257 .GreaterOrEqual,
3258 .GreaterThan,
3259 .LessOrEqual,
3260 .LessThan,
3261 .MergeErrorSets,
3262 .Mod,
3263 .Mul,
3264 .MulWrap,
3265 .Range,
3266 .Period,
3267 .Sub,
3268 .SubWrap,
3269 .Slice,
3270 .Deref,
3271 .ArrayAccess,
3272 .Block,
3305 .@"asm",
3306 .add,
3307 .add_wrap,
3308 .array_cat,
3309 .array_mult,
3310 .assign,
3311 .assign_bit_and,
3312 .assign_bit_or,
3313 .assign_bit_shift_left,
3314 .assign_bit_shift_right,
3315 .assign_bit_xor,
3316 .assign_div,
3317 .assign_sub,
3318 .assign_sub_wrap,
3319 .assign_mod,
3320 .assign_add,
3321 .assign_add_wrap,
3322 .assign_mul,
3323 .assign_mul_wrap,
3324 .bang_equal,
3325 .bit_and,
3326 .bit_or,
3327 .bit_shift_left,
3328 .bit_shift_right,
3329 .bit_xor,
3330 .bool_and,
3331 .bool_or,
3332 .div,
3333 .equal_equal,
3334 .error_union,
3335 .greater_or_equal,
3336 .greater_than,
3337 .less_or_equal,
3338 .less_than,
3339 .merge_error_sets,
3340 .mod,
3341 .mul,
3342 .mul_wrap,
3343 .range,
3344 .period,
3345 .sub,
3346 .sub_wrap,
3347 .slice,
3348 .deref,
3349 .array_access,
3350 .block,
32733351 => return false,
32743352
32753353 // Forward the question to a sub-expression.
3276 .GroupedExpression => node = node.castTag(.GroupedExpression).?.expr,
3277 .Try => node = node.castTag(.Try).?.rhs,
3278 .Await => node = node.castTag(.Await).?.rhs,
3279 .Catch => node = node.castTag(.Catch).?.rhs,
3280 .OrElse => node = node.castTag(.OrElse).?.rhs,
3281 .Comptime => node = node.castTag(.Comptime).?.expr,
3282 .Nosuspend => node = node.castTag(.Nosuspend).?.expr,
3283 .UnwrapOptional => node = node.castTag(.UnwrapOptional).?.lhs,
3354 .grouped_expression => node = node.castTag(.grouped_expression).?.expr,
3355 .@"try" => node = node.castTag(.@"try").?.rhs,
3356 .@"await" => node = node.castTag(.@"await").?.rhs,
3357 .@"catch" => node = node.castTag(.@"catch").?.rhs,
3358 .@"orelse" => node = node.castTag(.@"orelse").?.rhs,
3359 .@"comptime" => node = node.castTag(.@"comptime").?.expr,
3360 .@"nosuspend" => node = node.castTag(.@"nosuspend").?.expr,
3361 .unwrap_optional => node = node.castTag(.unwrap_optional).?.lhs,
32843362
32853363 // True because these are exactly the expressions we need memory locations for.
32863364 .ArrayInitializer,
......@@ -3291,14 +3369,14 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
32913369
32923370 // True because depending on comptime conditions, sub-expressions
32933371 // may be the kind that need memory locations.
3294 .While,
3295 .For,
3296 .Switch,
3297 .Call,
3298 .LabeledBlock,
3372 .@"while",
3373 .@"for",
3374 .@"switch",
3375 .call,
3376 .labeled_block,
32993377 => return true,
33003378
3301 .BuiltinCall => {
3379 .builtin_call => {
33023380 @setEvalBranchQuota(5000);
33033381 const builtin_needs_mem_loc = std.ComptimeStringMap(bool, .{
33043382 .{ "@addWithOverflow", false },
......@@ -3404,12 +3482,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
34043482 .{ "@TypeOf", false },
34053483 .{ "@unionInit", true },
34063484 });
3407 const name = scope.tree().tokenSlice(node.castTag(.BuiltinCall).?.builtin_token);
3485 const name = scope.tree().tokenSlice(node.castTag(.builtin_call).?.builtin_token);
34083486 return builtin_needs_mem_loc.get(name).?;
34093487 },
34103488
34113489 // 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,
34133491 }
34143492 }
34153493}
......@@ -3450,8 +3528,17 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
34503528 }
34513529}
34523530
3453fn rvalueVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, result: void) InnerError!*zir.Inst {
3454 const src = scope.tree().token_locs[node.firstToken()].start;
3531fn rvalueVoid(
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)];
34553542 const void_inst = try addZIRInstConst(mod, scope, src, .{
34563543 .ty = Type.initTag(.void),
34573544 .val = Value.initTag(.void_value),
src/codegen.zig+10-5
......@@ -451,11 +451,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
451451
452452 const src_data: struct { lbrace_src: usize, rbrace_src: usize, source: []const u8 } = blk: {
453453 const container_scope = module_fn.owner_decl.container;
454 const tree = container_scope.file_scope.contents.tree;
455 const fn_proto = tree.root_node.decls()[module_fn.owner_decl.src_index].castTag(.FnProto).?;
456 const block = fn_proto.getBodyNode().?.castTag(.Block).?;
457 const lbrace_src = tree.token_locs[block.lbrace].start;
458 const rbrace_src = tree.token_locs[block.rbrace].start;
454 const tree = container_scope.file_scope.tree;
455 const node_tags = tree.nodes.items(.tag);
456 const node_datas = tree.nodes.items(.data);
457 const token_starts = tree.tokens.items(.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)];
459464 break :blk .{
460465 .lbrace_src = lbrace_src,
461466 .rbrace_src = rbrace_src,
src/ir.zig+1
......@@ -317,6 +317,7 @@ pub const Inst = struct {
317317 pub const base_tag = Tag.arg;
318318
319319 base: Inst,
320 /// This exists to be emitted into debug info.
320321 name: [*:0]const u8,
321322
322323 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 {
22232223 try dbg_line_buffer.ensureCapacity(26);
22242224
22252225 const line_off: u28 = blk: {
2226 const tree = decl.container.file_scope.contents.tree;
2227 const file_ast_decls = tree.root_node.decls();
2226 const tree = decl.container.file_scope.tree;
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();
22282232 // TODO Look into improving the performance here by adding a token-index-to-line
22292233 // lookup table. Currently this involves scanning over the source code for newlines.
2230 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
2231 const block = fn_proto.getBodyNode().?.castTag(.Block).?;
2232 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
2234 const fn_decl = file_ast_decls[decl.src_index];
2235 assert(node_tags[fn_decl] == .fn_decl);
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]);
22332239 break :blk @intCast(u28, line_delta);
22342240 };
22352241
......@@ -2744,13 +2750,19 @@ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Dec
27442750
27452751 if (self.llvm_ir_module) |_| return;
27462752
2747 const tree = decl.container.file_scope.contents.tree;
2748 const file_ast_decls = tree.root_node.decls();
2753 const tree = decl.container.file_scope.tree;
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();
27492759 // TODO Look into improving the performance here by adding a token-index-to-line
27502760 // lookup table. Currently this involves scanning over the source code for newlines.
2751 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
2752 const block = fn_proto.getBodyNode().?.castTag(.Block).?;
2753 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
2761 const fn_decl = file_ast_decls[decl.src_index];
2762 assert(node_tags[fn_decl] == .fn_decl);
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]);
27542766 const casted_line_off = @intCast(u28, line_delta);
27552767
27562768 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
904904 const tracy = trace(@src());
905905 defer tracy.end();
906906
907 const tree = decl.container.file_scope.contents.tree;
908 const file_ast_decls = tree.root_node.decls();
907 const tree = decl.container.file_scope.tree;
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();
909913 // TODO Look into improving the performance here by adding a token-index-to-line
910914 // lookup table. Currently this involves scanning over the source code for newlines.
911 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
912 const block = fn_proto.getBodyNode().?.castTag(.Block).?;
913 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
915 const fn_decl = file_ast_decls[decl.src_index];
916 assert(node_tags[fn_decl] == .fn_decl);
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]);
914920 const casted_line_off = @intCast(u28, line_delta);
915921
916922 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
......@@ -948,13 +954,19 @@ pub fn initDeclDebugBuffers(
948954 try dbg_line_buffer.ensureCapacity(26);
949955
950956 const line_off: u28 = blk: {
951 const tree = decl.container.file_scope.contents.tree;
952 const file_ast_decls = tree.root_node.decls();
957 const tree = decl.container.file_scope.tree;
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();
953963 // TODO Look into improving the performance here by adding a token-index-to-line
954964 // lookup table. Currently this involves scanning over the source code for newlines.
955 const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
956 const block = fn_proto.getBodyNode().?.castTag(.Block).?;
957 const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
965 const fn_decl = file_ast_decls[decl.src_index];
966 assert(node_tags[fn_decl] == .fn_decl);
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]);
958970 break :blk @intCast(u28, line_delta);
959971 };
960972
src/zir.zig+18-3
......@@ -53,6 +53,9 @@ pub const Inst = struct {
5353 indexable_ptr_len,
5454 /// Function parameter value. These must be first in a function's main block,
5555 /// 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.
5659 arg,
5760 /// Type coercion.
5861 as,
......@@ -354,9 +357,8 @@ pub const Inst = struct {
354357 .return_void,
355358 .ret_ptr,
356359 .ret_type,
357 .unreach_nocheck,
358 .@"unreachable",
359 .arg,
360 .unreachable_unsafe,
361 .unreachable_safe,
360362 .void_value,
361363 => NoOp,
362364
......@@ -451,6 +453,7 @@ pub const Inst = struct {
451453 .block_comptime_flat,
452454 => Block,
453455
456 .arg => Arg,
454457 .array_type_sentinel => ArrayTypeSentinel,
455458 .@"break" => Break,
456459 .break_void => BreakVoid,
......@@ -684,6 +687,18 @@ pub const Inst = struct {
684687 kw_args: struct {},
685688 };
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
687702 pub const Block = struct {
688703 pub const base_tag = Tag.block;
689704 base: Inst,