| ... | ... | @@ -1373,7 +1373,9 @@ fn fnProtoExpr( |
| 1373 | 1373 | const main_tokens = tree.nodes.items(.main_token); |
| 1374 | 1374 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 1375 | 1375 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 1376 | | const param_inst = try block_scope.addParam(&param_gz, tag, name_token, param_name, param.first_doc_comment); |
| 1376 | // We pass `prev_param_insts` as `&.{}` here because a function prototype can't refer to previous |
| 1377 | // arguments (we haven't set up scopes here). |
| 1378 | const param_inst = try block_scope.addParam(&param_gz, &.{}, tag, name_token, param_name, param.first_doc_comment); |
| 1377 | 1379 | assert(param_inst_expected == param_inst); |
| 1378 | 1380 | } |
| 1379 | 1381 | } |
| ... | ... | @@ -1423,6 +1425,13 @@ fn fnProtoExpr( |
| 1423 | 1425 | .addrspace_ref = .none, |
| 1424 | 1426 | .addrspace_gz = null, |
| 1425 | 1427 | |
| 1428 | .align_param_refs = &.{}, |
| 1429 | .addrspace_param_refs = &.{}, |
| 1430 | .section_param_refs = &.{}, |
| 1431 | .cc_param_refs = &.{}, |
| 1432 | .ret_param_refs = &.{}, |
| 1433 | .param_insts = &.{}, |
| 1434 | |
| 1426 | 1435 | .param_block = block_inst, |
| 1427 | 1436 | .body_gz = null, |
| 1428 | 1437 | .lib_name = .empty, |
| ... | ... | @@ -3189,28 +3198,13 @@ fn deferStmt( |
| 3189 | 3198 | try checkUsed(gz, scope, sub_scope); |
| 3190 | 3199 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); |
| 3191 | 3200 | |
| 3192 | | // We must handle ref_table for remapped_err_code manually. |
| 3193 | 3201 | const body = defer_gen.instructionsSlice(); |
| 3194 | | const body_len = blk: { |
| 3195 | | var refs: u32 = 0; |
| 3196 | | if (opt_remapped_err_code.unwrap()) |remapped_err_code| { |
| 3197 | | var cur_inst = remapped_err_code; |
| 3198 | | while (gz.astgen.ref_table.get(cur_inst)) |ref_inst| { |
| 3199 | | refs += 1; |
| 3200 | | cur_inst = ref_inst; |
| 3201 | | } |
| 3202 | | } |
| 3203 | | break :blk gz.astgen.countBodyLenAfterFixups(body) + refs; |
| 3204 | | }; |
| 3202 | const extra_insts: []const Zir.Inst.Index = if (opt_remapped_err_code.unwrap()) |ec| &.{ec} else &.{}; |
| 3203 | const body_len = gz.astgen.countBodyLenAfterFixupsExtraRefs(body, extra_insts); |
| 3205 | 3204 | |
| 3206 | 3205 | const index: u32 = @intCast(gz.astgen.extra.items.len); |
| 3207 | 3206 | try gz.astgen.extra.ensureUnusedCapacity(gz.astgen.gpa, body_len); |
| 3208 | | if (opt_remapped_err_code.unwrap()) |remapped_err_code| { |
| 3209 | | if (gz.astgen.ref_table.fetchRemove(remapped_err_code)) |kv| { |
| 3210 | | gz.astgen.appendPossiblyRefdBodyInst(&gz.astgen.extra, kv.value); |
| 3211 | | } |
| 3212 | | } |
| 3213 | | gz.astgen.appendBodyWithFixups(body); |
| 3207 | gz.astgen.appendBodyWithFixupsExtraRefsArrayList(&gz.astgen.extra, body, extra_insts); |
| 3214 | 3208 | |
| 3215 | 3209 | const defer_scope = try block_arena.create(Scope.Defer); |
| 3216 | 3210 | |
| ... | ... | @@ -3313,11 +3307,8 @@ fn varDecl( |
| 3313 | 3307 | const is_comptime = gz.is_comptime or |
| 3314 | 3308 | tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime"; |
| 3315 | 3309 | |
| 3316 | | var resolve_inferred_alloc: Zir.Inst.Ref = .none; |
| 3317 | | var opt_type_inst: Zir.Inst.Ref = .none; |
| 3318 | 3310 | const init_rl: ResultInfo.Loc = if (type_node != 0) init_rl: { |
| 3319 | 3311 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3320 | | opt_type_inst = type_inst; |
| 3321 | 3312 | if (align_inst == .none) { |
| 3322 | 3313 | break :init_rl .{ .ptr = .{ .inst = try gz.addUnNode(.alloc, type_inst, node) } }; |
| 3323 | 3314 | } else { |
| ... | ... | @@ -3345,12 +3336,11 @@ fn varDecl( |
| 3345 | 3336 | .is_comptime = is_comptime, |
| 3346 | 3337 | }); |
| 3347 | 3338 | }; |
| 3348 | | resolve_inferred_alloc = alloc_inst; |
| 3349 | 3339 | break :init_rl .{ .inferred_ptr = alloc_inst }; |
| 3350 | 3340 | }; |
| 3351 | | const var_ptr = switch (init_rl) { |
| 3352 | | .ptr => |ptr| ptr.inst, |
| 3353 | | .inferred_ptr => |inst| inst, |
| 3341 | const var_ptr: Zir.Inst.Ref, const resolve_inferred: bool = switch (init_rl) { |
| 3342 | .ptr => |ptr| .{ ptr.inst, false }, |
| 3343 | .inferred_ptr => |inst| .{ inst, true }, |
| 3354 | 3344 | else => unreachable, |
| 3355 | 3345 | }; |
| 3356 | 3346 | const init_result_info: ResultInfo = .{ .rl = init_rl, .ctx = .const_init }; |
| ... | ... | @@ -3365,10 +3355,10 @@ fn varDecl( |
| 3365 | 3355 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) |
| 3366 | 3356 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3367 | 3357 | |
| 3368 | | const const_ptr = if (resolve_inferred_alloc != .none) p: { |
| 3369 | | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| 3370 | | break :p var_ptr; |
| 3371 | | } else try gz.addUnNode(.make_ptr_const, var_ptr, node); |
| 3358 | const const_ptr = if (resolve_inferred) |
| 3359 | try gz.addUnNode(.resolve_inferred_alloc, var_ptr, node) |
| 3360 | else |
| 3361 | try gz.addUnNode(.make_ptr_const, var_ptr, node); |
| 3372 | 3362 | |
| 3373 | 3363 | try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr); |
| 3374 | 3364 | |
| ... | ... | @@ -3388,8 +3378,7 @@ fn varDecl( |
| 3388 | 3378 | if (var_decl.comptime_token != null and gz.is_comptime) |
| 3389 | 3379 | return astgen.failTok(var_decl.comptime_token.?, "'comptime var' is redundant in comptime scope", .{}); |
| 3390 | 3380 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; |
| 3391 | | var resolve_inferred_alloc: Zir.Inst.Ref = .none; |
| 3392 | | const alloc: Zir.Inst.Ref, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { |
| 3381 | const alloc: Zir.Inst.Ref, const resolve_inferred: bool, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { |
| 3393 | 3382 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); |
| 3394 | 3383 | const alloc = alloc: { |
| 3395 | 3384 | if (align_inst == .none) { |
| ... | ... | @@ -3408,7 +3397,7 @@ fn varDecl( |
| 3408 | 3397 | }); |
| 3409 | 3398 | } |
| 3410 | 3399 | }; |
| 3411 | | break :a .{ alloc, .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; |
| 3400 | break :a .{ alloc, false, .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; |
| 3412 | 3401 | } else a: { |
| 3413 | 3402 | const alloc = alloc: { |
| 3414 | 3403 | if (align_inst == .none) { |
| ... | ... | @@ -3427,25 +3416,24 @@ fn varDecl( |
| 3427 | 3416 | }); |
| 3428 | 3417 | } |
| 3429 | 3418 | }; |
| 3430 | | resolve_inferred_alloc = alloc; |
| 3431 | | break :a .{ alloc, .{ .rl = .{ .inferred_ptr = alloc } } }; |
| 3419 | break :a .{ alloc, true, .{ .rl = .{ .inferred_ptr = alloc } } }; |
| 3432 | 3420 | }; |
| 3433 | 3421 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3434 | 3422 | gz.anon_name_strategy = .dbg_var; |
| 3435 | 3423 | _ = try reachableExprComptime(gz, scope, result_info, var_decl.ast.init_node, node, is_comptime); |
| 3436 | 3424 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3437 | | if (resolve_inferred_alloc != .none) { |
| 3438 | | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| 3439 | | } |
| 3425 | const final_ptr: Zir.Inst.Ref = if (resolve_inferred) ptr: { |
| 3426 | break :ptr try gz.addUnNode(.resolve_inferred_alloc, alloc, node); |
| 3427 | } else alloc; |
| 3440 | 3428 | |
| 3441 | | try gz.addDbgVar(.dbg_var_ptr, ident_name, alloc); |
| 3429 | try gz.addDbgVar(.dbg_var_ptr, ident_name, final_ptr); |
| 3442 | 3430 | |
| 3443 | 3431 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 3444 | 3432 | sub_scope.* = .{ |
| 3445 | 3433 | .parent = scope, |
| 3446 | 3434 | .gen_zir = gz, |
| 3447 | 3435 | .name = ident_name, |
| 3448 | | .ptr = alloc, |
| 3436 | .ptr = final_ptr, |
| 3449 | 3437 | .token_src = name_token, |
| 3450 | 3438 | .maybe_comptime = is_comptime, |
| 3451 | 3439 | .id_cat = .@"local variable", |
| ... | ... | @@ -3726,26 +3714,25 @@ fn assignDestructureMaybeDecls( |
| 3726 | 3714 | else => continue, // We were mutating an existing lvalue - nothing to do |
| 3727 | 3715 | } |
| 3728 | 3716 | const full_var_decl = tree.fullVarDecl(variable_node).?; |
| 3729 | | const raw_ptr = switch (variable_rl) { |
| 3717 | const raw_ptr, const resolve_inferred = switch (variable_rl) { |
| 3730 | 3718 | .discard => unreachable, |
| 3731 | | .typed_ptr => |typed_ptr| typed_ptr.inst, |
| 3732 | | .inferred_ptr => |ptr_inst| ptr_inst, |
| 3719 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, |
| 3720 | .inferred_ptr => |ptr_inst| .{ ptr_inst, true }, |
| 3733 | 3721 | }; |
| 3734 | | // If the alloc was inferred, resolve it. |
| 3735 | | if (full_var_decl.ast.type_node == 0) { |
| 3736 | | _ = try gz.addUnNode(.resolve_inferred_alloc, raw_ptr, variable_node); |
| 3737 | | } |
| 3738 | 3722 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { |
| 3739 | 3723 | .keyword_var => false, |
| 3740 | 3724 | .keyword_const => true, |
| 3741 | 3725 | else => unreachable, |
| 3742 | 3726 | }; |
| 3743 | | // If the alloc was const, make it const. |
| 3744 | | const var_ptr = if (is_const and full_var_decl.ast.type_node != 0) make_const: { |
| 3745 | | // Note that we don't do this if type_node == 0 since `resolve_inferred_alloc` |
| 3746 | | // handles it for us. |
| 3747 | | break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node); |
| 3748 | | } else raw_ptr; |
| 3727 | |
| 3728 | // If the alloc was inferred, resolve it. If the alloc was const, make it const. |
| 3729 | const final_ptr = if (resolve_inferred) |
| 3730 | try gz.addUnNode(.resolve_inferred_alloc, raw_ptr, variable_node) |
| 3731 | else if (is_const) |
| 3732 | try gz.addUnNode(.make_ptr_const, raw_ptr, node) |
| 3733 | else |
| 3734 | raw_ptr; |
| 3735 | |
| 3749 | 3736 | const name_token = full_var_decl.ast.mut_token + 1; |
| 3750 | 3737 | const ident_name_raw = tree.tokenSlice(name_token); |
| 3751 | 3738 | const ident_name = try astgen.identAsString(name_token); |
| ... | ... | @@ -3756,14 +3743,14 @@ fn assignDestructureMaybeDecls( |
| 3756 | 3743 | ident_name_raw, |
| 3757 | 3744 | if (is_const) .@"local constant" else .@"local variable", |
| 3758 | 3745 | ); |
| 3759 | | try gz.addDbgVar(.dbg_var_ptr, ident_name, var_ptr); |
| 3746 | try gz.addDbgVar(.dbg_var_ptr, ident_name, final_ptr); |
| 3760 | 3747 | // Finally, create the scope. |
| 3761 | 3748 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 3762 | 3749 | sub_scope.* = .{ |
| 3763 | 3750 | .parent = cur_scope, |
| 3764 | 3751 | .gen_zir = gz, |
| 3765 | 3752 | .name = ident_name, |
| 3766 | | .ptr = var_ptr, |
| 3753 | .ptr = final_ptr, |
| 3767 | 3754 | .token_src = name_token, |
| 3768 | 3755 | .maybe_comptime = is_const or is_comptime, |
| 3769 | 3756 | .id_cat = if (is_const) .@"local constant" else .@"local variable", |
| ... | ... | @@ -4182,6 +4169,9 @@ fn fnDecl( |
| 4182 | 4169 | |
| 4183 | 4170 | wip_members.nextDecl(decl_inst); |
| 4184 | 4171 | |
| 4172 | // Note that the capacity here may not be sufficient, as this does not include `anytype` parameters. |
| 4173 | var param_insts: std.ArrayListUnmanaged(Zir.Inst.Index) = try .initCapacity(astgen.arena, fn_proto.ast.params.len); |
| 4174 | |
| 4185 | 4175 | var noalias_bits: u32 = 0; |
| 4186 | 4176 | var params_scope = &fn_gz.base; |
| 4187 | 4177 | const is_var_args = is_var_args: { |
| ... | ... | @@ -4266,7 +4256,7 @@ fn fnDecl( |
| 4266 | 4256 | const main_tokens = tree.nodes.items(.main_token); |
| 4267 | 4257 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 4268 | 4258 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; |
| 4269 | | const param_inst = try decl_gz.addParam(&param_gz, tag, name_token, param_name, param.first_doc_comment); |
| 4259 | const param_inst = try decl_gz.addParam(&param_gz, param_insts.items, tag, name_token, param_name, param.first_doc_comment); |
| 4270 | 4260 | assert(param_inst_expected == param_inst); |
| 4271 | 4261 | break :param param_inst.toRef(); |
| 4272 | 4262 | }; |
| ... | ... | @@ -4283,6 +4273,7 @@ fn fnDecl( |
| 4283 | 4273 | .id_cat = .@"function parameter", |
| 4284 | 4274 | }; |
| 4285 | 4275 | params_scope = &sub_scope.base; |
| 4276 | try param_insts.append(astgen.arena, param_inst.toIndex().?); |
| 4286 | 4277 | } |
| 4287 | 4278 | break :is_var_args false; |
| 4288 | 4279 | }; |
| ... | ... | @@ -4316,6 +4307,7 @@ fn fnDecl( |
| 4316 | 4307 | _ = try align_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4317 | 4308 | break :inst inst; |
| 4318 | 4309 | }; |
| 4310 | const align_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4319 | 4311 | |
| 4320 | 4312 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); |
| 4321 | 4313 | defer addrspace_gz.unstack(); |
| ... | ... | @@ -4329,6 +4321,7 @@ fn fnDecl( |
| 4329 | 4321 | _ = try addrspace_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4330 | 4322 | break :inst inst; |
| 4331 | 4323 | }; |
| 4324 | const addrspace_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4332 | 4325 | |
| 4333 | 4326 | var section_gz = decl_gz.makeSubBlock(params_scope); |
| 4334 | 4327 | defer section_gz.unstack(); |
| ... | ... | @@ -4341,6 +4334,7 @@ fn fnDecl( |
| 4341 | 4334 | _ = try section_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4342 | 4335 | break :inst inst; |
| 4343 | 4336 | }; |
| 4337 | const section_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4344 | 4338 | |
| 4345 | 4339 | var cc_gz = decl_gz.makeSubBlock(params_scope); |
| 4346 | 4340 | defer cc_gz.unstack(); |
| ... | ... | @@ -4377,6 +4371,7 @@ fn fnDecl( |
| 4377 | 4371 | break :blk .none; |
| 4378 | 4372 | } |
| 4379 | 4373 | }; |
| 4374 | const cc_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4380 | 4375 | |
| 4381 | 4376 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 4382 | 4377 | defer ret_gz.unstack(); |
| ... | ... | @@ -4389,6 +4384,7 @@ fn fnDecl( |
| 4389 | 4384 | _ = try ret_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4390 | 4385 | break :inst inst; |
| 4391 | 4386 | }; |
| 4387 | const ret_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4392 | 4388 | |
| 4393 | 4389 | const func_inst: Zir.Inst.Ref = if (body_node == 0) func: { |
| 4394 | 4390 | if (!is_extern) { |
| ... | ... | @@ -4401,15 +4397,21 @@ fn fnDecl( |
| 4401 | 4397 | .src_node = decl_node, |
| 4402 | 4398 | .cc_ref = cc_ref, |
| 4403 | 4399 | .cc_gz = &cc_gz, |
| 4400 | .cc_param_refs = cc_body_param_refs, |
| 4404 | 4401 | .align_ref = align_ref, |
| 4405 | 4402 | .align_gz = &align_gz, |
| 4403 | .align_param_refs = align_body_param_refs, |
| 4406 | 4404 | .ret_ref = ret_ref, |
| 4407 | 4405 | .ret_gz = &ret_gz, |
| 4406 | .ret_param_refs = ret_body_param_refs, |
| 4408 | 4407 | .section_ref = section_ref, |
| 4409 | 4408 | .section_gz = &section_gz, |
| 4409 | .section_param_refs = section_body_param_refs, |
| 4410 | 4410 | .addrspace_ref = addrspace_ref, |
| 4411 | 4411 | .addrspace_gz = &addrspace_gz, |
| 4412 | .addrspace_param_refs = addrspace_body_param_refs, |
| 4412 | 4413 | .param_block = decl_inst, |
| 4414 | .param_insts = param_insts.items, |
| 4413 | 4415 | .body_gz = null, |
| 4414 | 4416 | .lib_name = lib_name, |
| 4415 | 4417 | .is_var_args = is_var_args, |
| ... | ... | @@ -4471,17 +4473,23 @@ fn fnDecl( |
| 4471 | 4473 | .src_node = decl_node, |
| 4472 | 4474 | .cc_ref = cc_ref, |
| 4473 | 4475 | .cc_gz = &cc_gz, |
| 4476 | .cc_param_refs = cc_body_param_refs, |
| 4474 | 4477 | .align_ref = align_ref, |
| 4475 | 4478 | .align_gz = &align_gz, |
| 4479 | .align_param_refs = align_body_param_refs, |
| 4476 | 4480 | .ret_ref = ret_ref, |
| 4477 | 4481 | .ret_gz = &ret_gz, |
| 4482 | .ret_param_refs = ret_body_param_refs, |
| 4478 | 4483 | .section_ref = section_ref, |
| 4479 | 4484 | .section_gz = &section_gz, |
| 4485 | .section_param_refs = section_body_param_refs, |
| 4480 | 4486 | .addrspace_ref = addrspace_ref, |
| 4481 | 4487 | .addrspace_gz = &addrspace_gz, |
| 4488 | .addrspace_param_refs = addrspace_body_param_refs, |
| 4482 | 4489 | .lbrace_line = lbrace_line, |
| 4483 | 4490 | .lbrace_column = lbrace_column, |
| 4484 | 4491 | .param_block = decl_inst, |
| 4492 | .param_insts = param_insts.items, |
| 4485 | 4493 | .body_gz = &fn_gz, |
| 4486 | 4494 | .lib_name = lib_name, |
| 4487 | 4495 | .is_var_args = is_var_args, |
| ... | ... | @@ -4972,6 +4980,13 @@ fn testDecl( |
| 4972 | 4980 | .addrspace_ref = .none, |
| 4973 | 4981 | .addrspace_gz = null, |
| 4974 | 4982 | |
| 4983 | .align_param_refs = &.{}, |
| 4984 | .addrspace_param_refs = &.{}, |
| 4985 | .section_param_refs = &.{}, |
| 4986 | .cc_param_refs = &.{}, |
| 4987 | .ret_param_refs = &.{}, |
| 4988 | .param_insts = &.{}, |
| 4989 | |
| 4975 | 4990 | .lbrace_line = lbrace_line, |
| 4976 | 4991 | .lbrace_column = lbrace_column, |
| 4977 | 4992 | .param_block = decl_inst, |
| ... | ... | @@ -7429,19 +7444,7 @@ fn switchExprErrUnion( |
| 7429 | 7444 | } |
| 7430 | 7445 | |
| 7431 | 7446 | const case_slice = case_scope.instructionsSlice(); |
| 7432 | | // Since we use the switch_block_err_union instruction itself to refer |
| 7433 | | // to the capture, which will not be added to the child block, we need |
| 7434 | | // to handle ref_table manually. |
| 7435 | | const refs_len = refs: { |
| 7436 | | var n: usize = 0; |
| 7437 | | var check_inst = switch_block; |
| 7438 | | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 7439 | | n += 1; |
| 7440 | | check_inst = ref_inst; |
| 7441 | | } |
| 7442 | | break :refs n; |
| 7443 | | }; |
| 7444 | | const body_len = refs_len + astgen.countBodyLenAfterFixups(case_slice); |
| 7447 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, &.{switch_block}); |
| 7445 | 7448 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 7446 | 7449 | const capture: Zir.Inst.SwitchBlock.ProngInfo.Capture = switch (node_ty) { |
| 7447 | 7450 | .@"catch" => .none, |
| ... | ... | @@ -7458,10 +7461,7 @@ fn switchExprErrUnion( |
| 7458 | 7461 | .is_inline = false, |
| 7459 | 7462 | .has_tag_capture = false, |
| 7460 | 7463 | }); |
| 7461 | | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { |
| 7462 | | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); |
| 7463 | | } |
| 7464 | | appendBodyWithFixupsArrayList(astgen, payloads, case_slice); |
| 7464 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, &.{switch_block}); |
| 7465 | 7465 | } |
| 7466 | 7466 | |
| 7467 | 7467 | const err_name = blk: { |
| ... | ... | @@ -7624,26 +7624,8 @@ fn switchExprErrUnion( |
| 7624 | 7624 | } |
| 7625 | 7625 | |
| 7626 | 7626 | const case_slice = case_scope.instructionsSlice(); |
| 7627 | | // Since we use the switch_block_err_union instruction itself to refer |
| 7628 | | // to the capture, which will not be added to the child block, we need |
| 7629 | | // to handle ref_table manually. |
| 7630 | | const refs_len = refs: { |
| 7631 | | var n: usize = 0; |
| 7632 | | var check_inst = switch_block; |
| 7633 | | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 7634 | | n += 1; |
| 7635 | | check_inst = ref_inst; |
| 7636 | | } |
| 7637 | | if (uses_err) { |
| 7638 | | check_inst = err_inst; |
| 7639 | | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 7640 | | n += 1; |
| 7641 | | check_inst = ref_inst; |
| 7642 | | } |
| 7643 | | } |
| 7644 | | break :refs n; |
| 7645 | | }; |
| 7646 | | const body_len = refs_len + astgen.countBodyLenAfterFixups(case_slice); |
| 7627 | const extra_insts: []const Zir.Inst.Index = if (uses_err) &.{ switch_block, err_inst } else &.{switch_block}; |
| 7628 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, extra_insts); |
| 7647 | 7629 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 7648 | 7630 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ |
| 7649 | 7631 | .body_len = @intCast(body_len), |
| ... | ... | @@ -7651,15 +7633,7 @@ fn switchExprErrUnion( |
| 7651 | 7633 | .is_inline = case.inline_token != null, |
| 7652 | 7634 | .has_tag_capture = false, |
| 7653 | 7635 | }); |
| 7654 | | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { |
| 7655 | | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); |
| 7656 | | } |
| 7657 | | if (uses_err) { |
| 7658 | | if (astgen.ref_table.fetchRemove(err_inst)) |kv| { |
| 7659 | | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); |
| 7660 | | } |
| 7661 | | } |
| 7662 | | appendBodyWithFixupsArrayList(astgen, payloads, case_slice); |
| 7636 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, extra_insts); |
| 7663 | 7637 | } |
| 7664 | 7638 | } |
| 7665 | 7639 | // Now that the item expressions are generated we can add this. |
| ... | ... | @@ -8106,27 +8080,8 @@ fn switchExpr( |
| 8106 | 8080 | } |
| 8107 | 8081 | |
| 8108 | 8082 | const case_slice = case_scope.instructionsSlice(); |
| 8109 | | // Since we use the switch_block instruction itself to refer to the |
| 8110 | | // capture, which will not be added to the child block, we need to |
| 8111 | | // handle ref_table manually, and the same for the inline tag |
| 8112 | | // capture instruction. |
| 8113 | | const refs_len = refs: { |
| 8114 | | var n: usize = 0; |
| 8115 | | var check_inst = switch_block; |
| 8116 | | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 8117 | | n += 1; |
| 8118 | | check_inst = ref_inst; |
| 8119 | | } |
| 8120 | | if (has_tag_capture) { |
| 8121 | | check_inst = tag_inst; |
| 8122 | | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 8123 | | n += 1; |
| 8124 | | check_inst = ref_inst; |
| 8125 | | } |
| 8126 | | } |
| 8127 | | break :refs n; |
| 8128 | | }; |
| 8129 | | const body_len = refs_len + astgen.countBodyLenAfterFixups(case_slice); |
| 8083 | const extra_insts: []const Zir.Inst.Index = if (has_tag_capture) &.{ switch_block, tag_inst } else &.{switch_block}; |
| 8084 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, extra_insts); |
| 8130 | 8085 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 8131 | 8086 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ |
| 8132 | 8087 | .body_len = @intCast(body_len), |
| ... | ... | @@ -8134,15 +8089,7 @@ fn switchExpr( |
| 8134 | 8089 | .is_inline = case.inline_token != null, |
| 8135 | 8090 | .has_tag_capture = has_tag_capture, |
| 8136 | 8091 | }); |
| 8137 | | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { |
| 8138 | | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); |
| 8139 | | } |
| 8140 | | if (has_tag_capture) { |
| 8141 | | if (astgen.ref_table.fetchRemove(tag_inst)) |kv| { |
| 8142 | | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); |
| 8143 | | } |
| 8144 | | } |
| 8145 | | appendBodyWithFixupsArrayList(astgen, payloads, case_slice); |
| 8092 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, extra_insts); |
| 8146 | 8093 | } |
| 8147 | 8094 | } |
| 8148 | 8095 | |
| ... | ... | @@ -11201,9 +11148,6 @@ fn rvalueInner( |
| 11201 | 11148 | const src_token = tree.firstToken(src_node); |
| 11202 | 11149 | const result_index = coerced_result.toIndex() orelse |
| 11203 | 11150 | return gz.addUnTok(.ref, coerced_result, src_token); |
| 11204 | | const zir_tags = gz.astgen.instructions.items(.tag); |
| 11205 | | if (zir_tags[@intFromEnum(result_index)].isParam() or astgen.isInferred(coerced_result)) |
| 11206 | | return gz.addUnTok(.ref, coerced_result, src_token); |
| 11207 | 11151 | const gop = try astgen.ref_table.getOrPut(astgen.gpa, result_index); |
| 11208 | 11152 | if (!gop.found_existing) { |
| 11209 | 11153 | gop.value_ptr.* = try gz.makeUnTok(.ref, coerced_result, src_token); |
| ... | ... | @@ -12232,36 +12176,46 @@ const GenZir = struct { |
| 12232 | 12176 | /// * ret_gz |
| 12233 | 12177 | /// * body_gz (top) |
| 12234 | 12178 | /// Unstacks all of those except for `gz`. |
| 12235 | | fn addFunc(gz: *GenZir, args: struct { |
| 12236 | | src_node: Ast.Node.Index, |
| 12237 | | lbrace_line: u32 = 0, |
| 12238 | | lbrace_column: u32 = 0, |
| 12239 | | param_block: Zir.Inst.Index, |
| 12240 | | |
| 12241 | | align_gz: ?*GenZir, |
| 12242 | | addrspace_gz: ?*GenZir, |
| 12243 | | section_gz: ?*GenZir, |
| 12244 | | cc_gz: ?*GenZir, |
| 12245 | | ret_gz: ?*GenZir, |
| 12246 | | body_gz: ?*GenZir, |
| 12247 | | |
| 12248 | | align_ref: Zir.Inst.Ref, |
| 12249 | | addrspace_ref: Zir.Inst.Ref, |
| 12250 | | section_ref: Zir.Inst.Ref, |
| 12251 | | cc_ref: Zir.Inst.Ref, |
| 12252 | | ret_ref: Zir.Inst.Ref, |
| 12253 | | |
| 12254 | | lib_name: Zir.NullTerminatedString, |
| 12255 | | noalias_bits: u32, |
| 12256 | | is_var_args: bool, |
| 12257 | | is_inferred_error: bool, |
| 12258 | | is_test: bool, |
| 12259 | | is_extern: bool, |
| 12260 | | is_noinline: bool, |
| 12261 | | |
| 12262 | | /// Ignored if `body_gz == null`. |
| 12263 | | proto_hash: std.zig.SrcHash, |
| 12264 | | }) !Zir.Inst.Ref { |
| 12179 | fn addFunc( |
| 12180 | gz: *GenZir, |
| 12181 | args: struct { |
| 12182 | src_node: Ast.Node.Index, |
| 12183 | lbrace_line: u32 = 0, |
| 12184 | lbrace_column: u32 = 0, |
| 12185 | param_block: Zir.Inst.Index, |
| 12186 | |
| 12187 | align_gz: ?*GenZir, |
| 12188 | addrspace_gz: ?*GenZir, |
| 12189 | section_gz: ?*GenZir, |
| 12190 | cc_gz: ?*GenZir, |
| 12191 | ret_gz: ?*GenZir, |
| 12192 | body_gz: ?*GenZir, |
| 12193 | |
| 12194 | align_param_refs: []Zir.Inst.Index, |
| 12195 | addrspace_param_refs: []Zir.Inst.Index, |
| 12196 | section_param_refs: []Zir.Inst.Index, |
| 12197 | cc_param_refs: []Zir.Inst.Index, |
| 12198 | ret_param_refs: []Zir.Inst.Index, |
| 12199 | param_insts: []Zir.Inst.Index, // refs to params in `body_gz` should still be in `astgen.ref_table` |
| 12200 | |
| 12201 | align_ref: Zir.Inst.Ref, |
| 12202 | addrspace_ref: Zir.Inst.Ref, |
| 12203 | section_ref: Zir.Inst.Ref, |
| 12204 | cc_ref: Zir.Inst.Ref, |
| 12205 | ret_ref: Zir.Inst.Ref, |
| 12206 | |
| 12207 | lib_name: Zir.NullTerminatedString, |
| 12208 | noalias_bits: u32, |
| 12209 | is_var_args: bool, |
| 12210 | is_inferred_error: bool, |
| 12211 | is_test: bool, |
| 12212 | is_extern: bool, |
| 12213 | is_noinline: bool, |
| 12214 | |
| 12215 | /// Ignored if `body_gz == null`. |
| 12216 | proto_hash: std.zig.SrcHash, |
| 12217 | }, |
| 12218 | ) !Zir.Inst.Ref { |
| 12265 | 12219 | assert(args.src_node != 0); |
| 12266 | 12220 | const astgen = gz.astgen; |
| 12267 | 12221 | const gpa = astgen.gpa; |
| ... | ... | @@ -12309,7 +12263,7 @@ const GenZir = struct { |
| 12309 | 12263 | if (args.ret_gz) |ret_gz| |
| 12310 | 12264 | ret_body = ret_gz.instructionsSlice(); |
| 12311 | 12265 | } |
| 12312 | | const body_len = astgen.countBodyLenAfterFixups(body); |
| 12266 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(body, args.param_insts); |
| 12313 | 12267 | |
| 12314 | 12268 | if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or |
| 12315 | 12269 | args.is_extern or args.align_ref != .none or args.section_ref != .none or |
| ... | ... | @@ -12329,11 +12283,11 @@ const GenZir = struct { |
| 12329 | 12283 | try astgen.extra.ensureUnusedCapacity( |
| 12330 | 12284 | gpa, |
| 12331 | 12285 | @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len + |
| 12332 | | fancyFnExprExtraLen(astgen, align_body, args.align_ref) + |
| 12333 | | fancyFnExprExtraLen(astgen, addrspace_body, args.addrspace_ref) + |
| 12334 | | fancyFnExprExtraLen(astgen, section_body, args.section_ref) + |
| 12335 | | fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) + |
| 12336 | | fancyFnExprExtraLen(astgen, ret_body, ret_ref) + |
| 12286 | fancyFnExprExtraLen(astgen, args.align_param_refs, align_body, args.align_ref) + |
| 12287 | fancyFnExprExtraLen(astgen, args.addrspace_param_refs, addrspace_body, args.addrspace_ref) + |
| 12288 | fancyFnExprExtraLen(astgen, args.section_param_refs, section_body, args.section_ref) + |
| 12289 | fancyFnExprExtraLen(astgen, args.cc_param_refs, cc_body, args.cc_ref) + |
| 12290 | fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + |
| 12337 | 12291 | body_len + src_locs_and_hash.len + |
| 12338 | 12292 | @intFromBool(args.lib_name != .empty) + |
| 12339 | 12293 | @intFromBool(args.noalias_bits != 0), |
| ... | ... | @@ -12369,7 +12323,11 @@ const GenZir = struct { |
| 12369 | 12323 | |
| 12370 | 12324 | const zir_datas = astgen.instructions.items(.data); |
| 12371 | 12325 | if (align_body.len != 0) { |
| 12372 | | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body)); |
| 12326 | astgen.extra.appendAssumeCapacity( |
| 12327 | astgen.countBodyLenAfterFixups(args.align_param_refs) + |
| 12328 | astgen.countBodyLenAfterFixups(align_body), |
| 12329 | ); |
| 12330 | astgen.appendBodyWithFixups(args.align_param_refs); |
| 12373 | 12331 | astgen.appendBodyWithFixups(align_body); |
| 12374 | 12332 | const break_extra = zir_datas[@intFromEnum(align_body[align_body.len - 1])].@"break".payload_index; |
| 12375 | 12333 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | ... | @@ -12378,7 +12336,11 @@ const GenZir = struct { |
| 12378 | 12336 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref)); |
| 12379 | 12337 | } |
| 12380 | 12338 | if (addrspace_body.len != 0) { |
| 12381 | | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body)); |
| 12339 | astgen.extra.appendAssumeCapacity( |
| 12340 | astgen.countBodyLenAfterFixups(args.addrspace_param_refs) + |
| 12341 | astgen.countBodyLenAfterFixups(addrspace_body), |
| 12342 | ); |
| 12343 | astgen.appendBodyWithFixups(args.addrspace_param_refs); |
| 12382 | 12344 | astgen.appendBodyWithFixups(addrspace_body); |
| 12383 | 12345 | const break_extra = |
| 12384 | 12346 | zir_datas[@intFromEnum(addrspace_body[addrspace_body.len - 1])].@"break".payload_index; |
| ... | ... | @@ -12388,7 +12350,11 @@ const GenZir = struct { |
| 12388 | 12350 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref)); |
| 12389 | 12351 | } |
| 12390 | 12352 | if (section_body.len != 0) { |
| 12391 | | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body)); |
| 12353 | astgen.extra.appendAssumeCapacity( |
| 12354 | astgen.countBodyLenAfterFixups(args.section_param_refs) + |
| 12355 | astgen.countBodyLenAfterFixups(section_body), |
| 12356 | ); |
| 12357 | astgen.appendBodyWithFixups(args.section_param_refs); |
| 12392 | 12358 | astgen.appendBodyWithFixups(section_body); |
| 12393 | 12359 | const break_extra = |
| 12394 | 12360 | zir_datas[@intFromEnum(section_body[section_body.len - 1])].@"break".payload_index; |
| ... | ... | @@ -12398,7 +12364,11 @@ const GenZir = struct { |
| 12398 | 12364 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref)); |
| 12399 | 12365 | } |
| 12400 | 12366 | if (cc_body.len != 0) { |
| 12401 | | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body)); |
| 12367 | astgen.extra.appendAssumeCapacity( |
| 12368 | astgen.countBodyLenAfterFixups(args.cc_param_refs) + |
| 12369 | astgen.countBodyLenAfterFixups(cc_body), |
| 12370 | ); |
| 12371 | astgen.appendBodyWithFixups(args.cc_param_refs); |
| 12402 | 12372 | astgen.appendBodyWithFixups(cc_body); |
| 12403 | 12373 | const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index; |
| 12404 | 12374 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | ... | @@ -12407,7 +12377,11 @@ const GenZir = struct { |
| 12407 | 12377 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref)); |
| 12408 | 12378 | } |
| 12409 | 12379 | if (ret_body.len != 0) { |
| 12410 | | astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body)); |
| 12380 | astgen.extra.appendAssumeCapacity( |
| 12381 | astgen.countBodyLenAfterFixups(args.ret_param_refs) + |
| 12382 | astgen.countBodyLenAfterFixups(ret_body), |
| 12383 | ); |
| 12384 | astgen.appendBodyWithFixups(args.ret_param_refs); |
| 12411 | 12385 | astgen.appendBodyWithFixups(ret_body); |
| 12412 | 12386 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; |
| 12413 | 12387 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | ... | @@ -12420,7 +12394,7 @@ const GenZir = struct { |
| 12420 | 12394 | astgen.extra.appendAssumeCapacity(args.noalias_bits); |
| 12421 | 12395 | } |
| 12422 | 12396 | |
| 12423 | | astgen.appendBodyWithFixups(body); |
| 12397 | astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts); |
| 12424 | 12398 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12425 | 12399 | |
| 12426 | 12400 | // Order is important when unstacking. |
| ... | ... | @@ -12448,12 +12422,12 @@ const GenZir = struct { |
| 12448 | 12422 | try astgen.extra.ensureUnusedCapacity( |
| 12449 | 12423 | gpa, |
| 12450 | 12424 | @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 + |
| 12451 | | fancyFnExprExtraLen(astgen, ret_body, ret_ref) + |
| 12425 | fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + |
| 12452 | 12426 | body_len + src_locs_and_hash.len, |
| 12453 | 12427 | ); |
| 12454 | 12428 | |
| 12455 | 12429 | const ret_body_len = if (ret_body.len != 0) |
| 12456 | | countBodyLenAfterFixups(astgen, ret_body) |
| 12430 | countBodyLenAfterFixups(astgen, args.ret_param_refs) + countBodyLenAfterFixups(astgen, ret_body) |
| 12457 | 12431 | else |
| 12458 | 12432 | @intFromBool(ret_ref != .none); |
| 12459 | 12433 | |
| ... | ... | @@ -12464,6 +12438,7 @@ const GenZir = struct { |
| 12464 | 12438 | }); |
| 12465 | 12439 | const zir_datas = astgen.instructions.items(.data); |
| 12466 | 12440 | if (ret_body.len != 0) { |
| 12441 | astgen.appendBodyWithFixups(args.ret_param_refs); |
| 12467 | 12442 | astgen.appendBodyWithFixups(ret_body); |
| 12468 | 12443 | |
| 12469 | 12444 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; |
| ... | ... | @@ -12472,7 +12447,7 @@ const GenZir = struct { |
| 12472 | 12447 | } else if (ret_ref != .none) { |
| 12473 | 12448 | astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref)); |
| 12474 | 12449 | } |
| 12475 | | astgen.appendBodyWithFixups(body); |
| 12450 | astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts); |
| 12476 | 12451 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12477 | 12452 | |
| 12478 | 12453 | // Order is important when unstacking. |
| ... | ... | @@ -12498,10 +12473,11 @@ const GenZir = struct { |
| 12498 | 12473 | } |
| 12499 | 12474 | } |
| 12500 | 12475 | |
| 12501 | | fn fancyFnExprExtraLen(astgen: *AstGen, body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 { |
| 12502 | | // In the case of non-empty body, there is one for the body length, |
| 12503 | | // and then one for each instruction. |
| 12504 | | return countBodyLenAfterFixups(astgen, body) + @intFromBool(ref != .none); |
| 12476 | fn fancyFnExprExtraLen(astgen: *AstGen, param_refs_body: []Zir.Inst.Index, main_body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 { |
| 12477 | return countBodyLenAfterFixups(astgen, param_refs_body) + |
| 12478 | countBodyLenAfterFixups(astgen, main_body) + |
| 12479 | // If there is a body, we need an element for its length; otherwise, if there is a ref, we need to include that. |
| 12480 | @intFromBool(main_body.len > 0 or ref != .none); |
| 12505 | 12481 | } |
| 12506 | 12482 | |
| 12507 | 12483 | fn addVar(gz: *GenZir, args: struct { |
| ... | ... | @@ -12673,6 +12649,9 @@ const GenZir = struct { |
| 12673 | 12649 | fn addParam( |
| 12674 | 12650 | gz: *GenZir, |
| 12675 | 12651 | param_gz: *GenZir, |
| 12652 | /// Previous parameters, which might be referenced in `param_gz` (the new parameter type). |
| 12653 | /// `ref`s of these instructions will be put into this param's type body, and removed from `AstGen.ref_table`. |
| 12654 | prev_param_insts: []const Zir.Inst.Index, |
| 12676 | 12655 | tag: Zir.Inst.Tag, |
| 12677 | 12656 | /// Absolute token index. This function does the conversion to Decl offset. |
| 12678 | 12657 | abs_tok_index: Ast.TokenIndex, |
| ... | ... | @@ -12681,7 +12660,7 @@ const GenZir = struct { |
| 12681 | 12660 | ) !Zir.Inst.Index { |
| 12682 | 12661 | const gpa = gz.astgen.gpa; |
| 12683 | 12662 | const param_body = param_gz.instructionsSlice(); |
| 12684 | | const body_len = gz.astgen.countBodyLenAfterFixups(param_body); |
| 12663 | const body_len = gz.astgen.countBodyLenAfterFixupsExtraRefs(param_body, prev_param_insts); |
| 12685 | 12664 | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12686 | 12665 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).@"struct".fields.len + body_len); |
| 12687 | 12666 | |
| ... | ... | @@ -12695,7 +12674,7 @@ const GenZir = struct { |
| 12695 | 12674 | .doc_comment = doc_comment_index, |
| 12696 | 12675 | .body_len = @intCast(body_len), |
| 12697 | 12676 | }); |
| 12698 | | gz.astgen.appendBodyWithFixups(param_body); |
| 12677 | gz.astgen.appendBodyWithFixupsExtraRefsArrayList(&gz.astgen.extra, param_body, prev_param_insts); |
| 12699 | 12678 | param_gz.unstack(); |
| 12700 | 12679 | |
| 12701 | 12680 | const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); |
| ... | ... | @@ -13938,27 +13917,6 @@ fn scanContainer( |
| 13938 | 13917 | return decl_count; |
| 13939 | 13918 | } |
| 13940 | 13919 | |
| 13941 | | fn isInferred(astgen: *AstGen, ref: Zir.Inst.Ref) bool { |
| 13942 | | const inst = ref.toIndex() orelse return false; |
| 13943 | | const zir_tags = astgen.instructions.items(.tag); |
| 13944 | | return switch (zir_tags[@intFromEnum(inst)]) { |
| 13945 | | .alloc_inferred, |
| 13946 | | .alloc_inferred_mut, |
| 13947 | | .alloc_inferred_comptime, |
| 13948 | | .alloc_inferred_comptime_mut, |
| 13949 | | => true, |
| 13950 | | |
| 13951 | | .extended => { |
| 13952 | | const zir_data = astgen.instructions.items(.data); |
| 13953 | | if (zir_data[@intFromEnum(inst)].extended.opcode != .alloc) return false; |
| 13954 | | const small: Zir.Inst.AllocExtended.Small = @bitCast(zir_data[@intFromEnum(inst)].extended.small); |
| 13955 | | return !small.has_type; |
| 13956 | | }, |
| 13957 | | |
| 13958 | | else => false, |
| 13959 | | }; |
| 13960 | | } |
| 13961 | | |
| 13962 | 13920 | /// Assumes capacity for body has already been added. Needed capacity taking into |
| 13963 | 13921 | /// account fixups can be found with `countBodyLenAfterFixups`. |
| 13964 | 13922 | fn appendBodyWithFixups(astgen: *AstGen, body: []const Zir.Inst.Index) void { |
| ... | ... | @@ -13970,6 +13928,20 @@ fn appendBodyWithFixupsArrayList( |
| 13970 | 13928 | list: *std.ArrayListUnmanaged(u32), |
| 13971 | 13929 | body: []const Zir.Inst.Index, |
| 13972 | 13930 | ) void { |
| 13931 | astgen.appendBodyWithFixupsExtraRefsArrayList(list, body, &.{}); |
| 13932 | } |
| 13933 | |
| 13934 | fn appendBodyWithFixupsExtraRefsArrayList( |
| 13935 | astgen: *AstGen, |
| 13936 | list: *std.ArrayListUnmanaged(u32), |
| 13937 | body: []const Zir.Inst.Index, |
| 13938 | extra_refs: []const Zir.Inst.Index, |
| 13939 | ) void { |
| 13940 | for (extra_refs) |extra_inst| { |
| 13941 | if (astgen.ref_table.fetchRemove(extra_inst)) |kv| { |
| 13942 | appendPossiblyRefdBodyInst(astgen, list, kv.value); |
| 13943 | } |
| 13944 | } |
| 13973 | 13945 | for (body) |body_inst| { |
| 13974 | 13946 | appendPossiblyRefdBodyInst(astgen, list, body_inst); |
| 13975 | 13947 | } |
| ... | ... | @@ -13987,6 +13959,14 @@ fn appendPossiblyRefdBodyInst( |
| 13987 | 13959 | } |
| 13988 | 13960 | |
| 13989 | 13961 | fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { |
| 13962 | return astgen.countBodyLenAfterFixupsExtraRefs(body, &.{}); |
| 13963 | } |
| 13964 | |
| 13965 | /// Return the number of instructions in `body` after prepending the `ref` instructions in `ref_table`. |
| 13966 | /// As well as all instructions in `body`, we also prepend `ref`s of any instruction in `extra_refs`. |
| 13967 | /// For instance, if an index has been reserved with a special meaning to a child block, it must be |
| 13968 | /// passed to `extra_refs` to ensure `ref`s of that index are added correctly. |
| 13969 | fn countBodyLenAfterFixupsExtraRefs(astgen: *AstGen, body: []const Zir.Inst.Index, extra_refs: []const Zir.Inst.Index) u32 { |
| 13990 | 13970 | var count = body.len; |
| 13991 | 13971 | for (body) |body_inst| { |
| 13992 | 13972 | var check_inst = body_inst; |
| ... | ... | @@ -13995,6 +13975,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { |
| 13995 | 13975 | check_inst = ref_inst; |
| 13996 | 13976 | } |
| 13997 | 13977 | } |
| 13978 | for (extra_refs) |extra_inst| { |
| 13979 | var check_inst = extra_inst; |
| 13980 | while (astgen.ref_table.get(check_inst)) |ref_inst| { |
| 13981 | count += 1; |
| 13982 | check_inst = ref_inst; |
| 13983 | } |
| 13984 | } |
| 13998 | 13985 | return @intCast(count); |
| 13999 | 13986 | } |
| 14000 | 13987 | |
| ... | ... | @@ -14176,3 +14163,23 @@ fn setDeclaration( |
| 14176 | 14163 | } |
| 14177 | 14164 | value_gz.unstack(); |
| 14178 | 14165 | } |
| 14166 | |
| 14167 | /// Given a list of instructions, returns a list of all instructions which are a `ref` of one of the originals, |
| 14168 | /// from `astgen.ref_table`, non-recursively. The entries are removed from `astgen.ref_table`, and the returned |
| 14169 | /// slice can then be treated as its own body, to append `ref` instructions to a body other than the one they |
| 14170 | /// would normally exist in. |
| 14171 | /// |
| 14172 | /// This is used when lowering functions. Very rarely, the callconv expression, align expression, etc may reference |
| 14173 | /// function parameters via `&param`; in this case, we need to lower to a `ref` instruction in the callconv/align/etc |
| 14174 | /// body, rather than in the declaration body. However, we don't append these bodies to `extra` until we've evaluated |
| 14175 | /// *all* of the bodies into a big `GenZir` stack. Therefore, we use this function to pull out these per-body `ref` |
| 14176 | /// instructions which must be emitted. |
| 14177 | fn fetchRemoveRefEntries(astgen: *AstGen, param_insts: []const Zir.Inst.Index) ![]Zir.Inst.Index { |
| 14178 | var refs: std.ArrayListUnmanaged(Zir.Inst.Index) = .empty; |
| 14179 | for (param_insts) |param_inst| { |
| 14180 | if (astgen.ref_table.fetchRemove(param_inst)) |kv| { |
| 14181 | try refs.append(astgen.arena, kv.value); |
| 14182 | } |
| 14183 | } |
| 14184 | return refs.items; |
| 14185 | } |