| ... | @@ -1373,7 +1373,9 @@ fn fnProtoExpr( | ... | @@ -1373,7 +1373,9 @@ fn fnProtoExpr( |
| 1373 | const main_tokens = tree.nodes.items(.main_token); | 1373 | const main_tokens = tree.nodes.items(.main_token); |
| 1374 | const name_token = param.name_token orelse main_tokens[param_type_node]; | 1374 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 1375 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; | 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 | assert(param_inst_expected == param_inst); | 1379 | assert(param_inst_expected == param_inst); |
| 1378 | } | 1380 | } |
| 1379 | } | 1381 | } |
| ... | @@ -1423,6 +1425,13 @@ fn fnProtoExpr( | ... | @@ -1423,6 +1425,13 @@ fn fnProtoExpr( |
| 1423 | .addrspace_ref = .none, | 1425 | .addrspace_ref = .none, |
| 1424 | .addrspace_gz = null, | 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 | .param_block = block_inst, | 1435 | .param_block = block_inst, |
| 1427 | .body_gz = null, | 1436 | .body_gz = null, |
| 1428 | .lib_name = .empty, | 1437 | .lib_name = .empty, |
| ... | @@ -3189,28 +3198,13 @@ fn deferStmt( | ... | @@ -3189,28 +3198,13 @@ fn deferStmt( |
| 3189 | try checkUsed(gz, scope, sub_scope); | 3198 | try checkUsed(gz, scope, sub_scope); |
| 3190 | _ = try defer_gen.addBreak(.break_inline, @enumFromInt(0), .void_value); | 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 | const body = defer_gen.instructionsSlice(); | 3201 | const body = defer_gen.instructionsSlice(); |
| 3194 | const body_len = blk: { | 3202 | const extra_insts: []const Zir.Inst.Index = if (opt_remapped_err_code.unwrap()) |ec| &.{ec} else &.{}; |
| 3195 | var refs: u32 = 0; | 3203 | const body_len = gz.astgen.countBodyLenAfterFixupsExtraRefs(body, extra_insts); |
| 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 | }; | | |
| 3205 | | 3204 | |
| 3206 | const index: u32 = @intCast(gz.astgen.extra.items.len); | 3205 | const index: u32 = @intCast(gz.astgen.extra.items.len); |
| 3207 | try gz.astgen.extra.ensureUnusedCapacity(gz.astgen.gpa, body_len); | 3206 | try gz.astgen.extra.ensureUnusedCapacity(gz.astgen.gpa, body_len); |
| 3208 | if (opt_remapped_err_code.unwrap()) |remapped_err_code| { | 3207 | gz.astgen.appendBodyWithFixupsExtraRefsArrayList(&gz.astgen.extra, body, extra_insts); |
| 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); | | |
| 3214 | | 3208 | |
| 3215 | const defer_scope = try block_arena.create(Scope.Defer); | 3209 | const defer_scope = try block_arena.create(Scope.Defer); |
| 3216 | | 3210 | |
| ... | @@ -3313,11 +3307,8 @@ fn varDecl( | ... | @@ -3313,11 +3307,8 @@ fn varDecl( |
| 3313 | const is_comptime = gz.is_comptime or | 3307 | const is_comptime = gz.is_comptime or |
| 3314 | tree.nodes.items(.tag)[var_decl.ast.init_node] == .@"comptime"; | 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 | const init_rl: ResultInfo.Loc = if (type_node != 0) init_rl: { | 3310 | const init_rl: ResultInfo.Loc = if (type_node != 0) init_rl: { |
| 3319 | const type_inst = try typeExpr(gz, scope, type_node); | 3311 | const type_inst = try typeExpr(gz, scope, type_node); |
| 3320 | opt_type_inst = type_inst; | | |
| 3321 | if (align_inst == .none) { | 3312 | if (align_inst == .none) { |
| 3322 | break :init_rl .{ .ptr = .{ .inst = try gz.addUnNode(.alloc, type_inst, node) } }; | 3313 | break :init_rl .{ .ptr = .{ .inst = try gz.addUnNode(.alloc, type_inst, node) } }; |
| 3323 | } else { | 3314 | } else { |
| ... | @@ -3345,12 +3336,11 @@ fn varDecl( | ... | @@ -3345,12 +3336,11 @@ fn varDecl( |
| 3345 | .is_comptime = is_comptime, | 3336 | .is_comptime = is_comptime, |
| 3346 | }); | 3337 | }); |
| 3347 | }; | 3338 | }; |
| 3348 | resolve_inferred_alloc = alloc_inst; | | |
| 3349 | break :init_rl .{ .inferred_ptr = alloc_inst }; | 3339 | break :init_rl .{ .inferred_ptr = alloc_inst }; |
| 3350 | }; | 3340 | }; |
| 3351 | const var_ptr = switch (init_rl) { | 3341 | const var_ptr: Zir.Inst.Ref, const resolve_inferred: bool = switch (init_rl) { |
| 3352 | .ptr => |ptr| ptr.inst, | 3342 | .ptr => |ptr| .{ ptr.inst, false }, |
| 3353 | .inferred_ptr => |inst| inst, | 3343 | .inferred_ptr => |inst| .{ inst, true }, |
| 3354 | else => unreachable, | 3344 | else => unreachable, |
| 3355 | }; | 3345 | }; |
| 3356 | const init_result_info: ResultInfo = .{ .rl = init_rl, .ctx = .const_init }; | 3346 | const init_result_info: ResultInfo = .{ .rl = init_rl, .ctx = .const_init }; |
| ... | @@ -3365,10 +3355,10 @@ fn varDecl( | ... | @@ -3365,10 +3355,10 @@ fn varDecl( |
| 3365 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) | 3355 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) |
| 3366 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); | 3356 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 3367 | | 3357 | |
| 3368 | const const_ptr = if (resolve_inferred_alloc != .none) p: { | 3358 | const const_ptr = if (resolve_inferred) |
| 3369 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); | 3359 | try gz.addUnNode(.resolve_inferred_alloc, var_ptr, node) |
| 3370 | break :p var_ptr; | 3360 | else |
| 3371 | } else try gz.addUnNode(.make_ptr_const, var_ptr, node); | 3361 | try gz.addUnNode(.make_ptr_const, var_ptr, node); |
| 3372 | | 3362 | |
| 3373 | try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr); | 3363 | try gz.addDbgVar(.dbg_var_ptr, ident_name, const_ptr); |
| 3374 | | 3364 | |
| ... | @@ -3388,8 +3378,7 @@ fn varDecl( | ... | @@ -3388,8 +3378,7 @@ fn varDecl( |
| 3388 | if (var_decl.comptime_token != null and gz.is_comptime) | 3378 | if (var_decl.comptime_token != null and gz.is_comptime) |
| 3389 | return astgen.failTok(var_decl.comptime_token.?, "'comptime var' is redundant in comptime scope", .{}); | 3379 | return astgen.failTok(var_decl.comptime_token.?, "'comptime var' is redundant in comptime scope", .{}); |
| 3390 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; | 3380 | const is_comptime = var_decl.comptime_token != null or gz.is_comptime; |
| 3391 | var resolve_inferred_alloc: Zir.Inst.Ref = .none; | 3381 | const alloc: Zir.Inst.Ref, const resolve_inferred: bool, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { |
| 3392 | const alloc: Zir.Inst.Ref, const result_info: ResultInfo = if (var_decl.ast.type_node != 0) a: { | | |
| 3393 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); | 3382 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); |
| 3394 | const alloc = alloc: { | 3383 | const alloc = alloc: { |
| 3395 | if (align_inst == .none) { | 3384 | if (align_inst == .none) { |
| ... | @@ -3408,7 +3397,7 @@ fn varDecl( | ... | @@ -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 | } else a: { | 3401 | } else a: { |
| 3413 | const alloc = alloc: { | 3402 | const alloc = alloc: { |
| 3414 | if (align_inst == .none) { | 3403 | if (align_inst == .none) { |
| ... | @@ -3427,25 +3416,24 @@ fn varDecl( | ... | @@ -3427,25 +3416,24 @@ fn varDecl( |
| 3427 | }); | 3416 | }); |
| 3428 | } | 3417 | } |
| 3429 | }; | 3418 | }; |
| 3430 | resolve_inferred_alloc = alloc; | 3419 | break :a .{ alloc, true, .{ .rl = .{ .inferred_ptr = alloc } } }; |
| 3431 | break :a .{ alloc, .{ .rl = .{ .inferred_ptr = alloc } } }; | | |
| 3432 | }; | 3420 | }; |
| 3433 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3421 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3434 | gz.anon_name_strategy = .dbg_var; | 3422 | gz.anon_name_strategy = .dbg_var; |
| 3435 | _ = try reachableExprComptime(gz, scope, result_info, var_decl.ast.init_node, node, is_comptime); | 3423 | _ = try reachableExprComptime(gz, scope, result_info, var_decl.ast.init_node, node, is_comptime); |
| 3436 | gz.anon_name_strategy = prev_anon_name_strategy; | 3424 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3437 | if (resolve_inferred_alloc != .none) { | 3425 | const final_ptr: Zir.Inst.Ref = if (resolve_inferred) ptr: { |
| 3438 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); | 3426 | break :ptr try gz.addUnNode(.resolve_inferred_alloc, alloc, node); |
| 3439 | } | 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 | const sub_scope = try block_arena.create(Scope.LocalPtr); | 3431 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 3444 | sub_scope.* = .{ | 3432 | sub_scope.* = .{ |
| 3445 | .parent = scope, | 3433 | .parent = scope, |
| 3446 | .gen_zir = gz, | 3434 | .gen_zir = gz, |
| 3447 | .name = ident_name, | 3435 | .name = ident_name, |
| 3448 | .ptr = alloc, | 3436 | .ptr = final_ptr, |
| 3449 | .token_src = name_token, | 3437 | .token_src = name_token, |
| 3450 | .maybe_comptime = is_comptime, | 3438 | .maybe_comptime = is_comptime, |
| 3451 | .id_cat = .@"local variable", | 3439 | .id_cat = .@"local variable", |
| ... | @@ -3726,26 +3714,25 @@ fn assignDestructureMaybeDecls( | ... | @@ -3726,26 +3714,25 @@ fn assignDestructureMaybeDecls( |
| 3726 | else => continue, // We were mutating an existing lvalue - nothing to do | 3714 | else => continue, // We were mutating an existing lvalue - nothing to do |
| 3727 | } | 3715 | } |
| 3728 | const full_var_decl = tree.fullVarDecl(variable_node).?; | 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 | .discard => unreachable, | 3718 | .discard => unreachable, |
| 3731 | .typed_ptr => |typed_ptr| typed_ptr.inst, | 3719 | .typed_ptr => |typed_ptr| .{ typed_ptr.inst, false }, |
| 3732 | .inferred_ptr => |ptr_inst| ptr_inst, | 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 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { | 3722 | const is_const = switch (token_tags[full_var_decl.ast.mut_token]) { |
| 3739 | .keyword_var => false, | 3723 | .keyword_var => false, |
| 3740 | .keyword_const => true, | 3724 | .keyword_const => true, |
| 3741 | else => unreachable, | 3725 | else => unreachable, |
| 3742 | }; | 3726 | }; |
| 3743 | // If the alloc was const, make it const. | 3727 | |
| 3744 | const var_ptr = if (is_const and full_var_decl.ast.type_node != 0) make_const: { | 3728 | // If the alloc was inferred, resolve it. If the alloc was const, make it const. |
| 3745 | // Note that we don't do this if type_node == 0 since `resolve_inferred_alloc` | 3729 | const final_ptr = if (resolve_inferred) |
| 3746 | // handles it for us. | 3730 | try gz.addUnNode(.resolve_inferred_alloc, raw_ptr, variable_node) |
| 3747 | break :make_const try gz.addUnNode(.make_ptr_const, raw_ptr, node); | 3731 | else if (is_const) |
| 3748 | } else raw_ptr; | 3732 | try gz.addUnNode(.make_ptr_const, raw_ptr, node) |
| | 3733 | else |
| | 3734 | raw_ptr; |
| | 3735 | |
| 3749 | const name_token = full_var_decl.ast.mut_token + 1; | 3736 | const name_token = full_var_decl.ast.mut_token + 1; |
| 3750 | const ident_name_raw = tree.tokenSlice(name_token); | 3737 | const ident_name_raw = tree.tokenSlice(name_token); |
| 3751 | const ident_name = try astgen.identAsString(name_token); | 3738 | const ident_name = try astgen.identAsString(name_token); |
| ... | @@ -3756,14 +3743,14 @@ fn assignDestructureMaybeDecls( | ... | @@ -3756,14 +3743,14 @@ fn assignDestructureMaybeDecls( |
| 3756 | ident_name_raw, | 3743 | ident_name_raw, |
| 3757 | if (is_const) .@"local constant" else .@"local variable", | 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 | // Finally, create the scope. | 3747 | // Finally, create the scope. |
| 3761 | const sub_scope = try block_arena.create(Scope.LocalPtr); | 3748 | const sub_scope = try block_arena.create(Scope.LocalPtr); |
| 3762 | sub_scope.* = .{ | 3749 | sub_scope.* = .{ |
| 3763 | .parent = cur_scope, | 3750 | .parent = cur_scope, |
| 3764 | .gen_zir = gz, | 3751 | .gen_zir = gz, |
| 3765 | .name = ident_name, | 3752 | .name = ident_name, |
| 3766 | .ptr = var_ptr, | 3753 | .ptr = final_ptr, |
| 3767 | .token_src = name_token, | 3754 | .token_src = name_token, |
| 3768 | .maybe_comptime = is_const or is_comptime, | 3755 | .maybe_comptime = is_const or is_comptime, |
| 3769 | .id_cat = if (is_const) .@"local constant" else .@"local variable", | 3756 | .id_cat = if (is_const) .@"local constant" else .@"local variable", |
| ... | @@ -4182,6 +4169,9 @@ fn fnDecl( | ... | @@ -4182,6 +4169,9 @@ fn fnDecl( |
| 4182 | | 4169 | |
| 4183 | wip_members.nextDecl(decl_inst); | 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 | var noalias_bits: u32 = 0; | 4175 | var noalias_bits: u32 = 0; |
| 4186 | var params_scope = &fn_gz.base; | 4176 | var params_scope = &fn_gz.base; |
| 4187 | const is_var_args = is_var_args: { | 4177 | const is_var_args = is_var_args: { |
| ... | @@ -4266,7 +4256,7 @@ fn fnDecl( | ... | @@ -4266,7 +4256,7 @@ fn fnDecl( |
| 4266 | const main_tokens = tree.nodes.items(.main_token); | 4256 | const main_tokens = tree.nodes.items(.main_token); |
| 4267 | const name_token = param.name_token orelse main_tokens[param_type_node]; | 4257 | const name_token = param.name_token orelse main_tokens[param_type_node]; |
| 4268 | const tag: Zir.Inst.Tag = if (is_comptime) .param_comptime else .param; | 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 | assert(param_inst_expected == param_inst); | 4260 | assert(param_inst_expected == param_inst); |
| 4271 | break :param param_inst.toRef(); | 4261 | break :param param_inst.toRef(); |
| 4272 | }; | 4262 | }; |
| ... | @@ -4283,6 +4273,7 @@ fn fnDecl( | ... | @@ -4283,6 +4273,7 @@ fn fnDecl( |
| 4283 | .id_cat = .@"function parameter", | 4273 | .id_cat = .@"function parameter", |
| 4284 | }; | 4274 | }; |
| 4285 | params_scope = &sub_scope.base; | 4275 | params_scope = &sub_scope.base; |
| | 4276 | try param_insts.append(astgen.arena, param_inst.toIndex().?); |
| 4286 | } | 4277 | } |
| 4287 | break :is_var_args false; | 4278 | break :is_var_args false; |
| 4288 | }; | 4279 | }; |
| ... | @@ -4316,6 +4307,7 @@ fn fnDecl( | ... | @@ -4316,6 +4307,7 @@ fn fnDecl( |
| 4316 | _ = try align_gz.addBreak(.break_inline, @enumFromInt(0), inst); | 4307 | _ = try align_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4317 | break :inst inst; | 4308 | break :inst inst; |
| 4318 | }; | 4309 | }; |
| | 4310 | const align_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4319 | | 4311 | |
| 4320 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); | 4312 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); |
| 4321 | defer addrspace_gz.unstack(); | 4313 | defer addrspace_gz.unstack(); |
| ... | @@ -4329,6 +4321,7 @@ fn fnDecl( | ... | @@ -4329,6 +4321,7 @@ fn fnDecl( |
| 4329 | _ = try addrspace_gz.addBreak(.break_inline, @enumFromInt(0), inst); | 4321 | _ = try addrspace_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4330 | break :inst inst; | 4322 | break :inst inst; |
| 4331 | }; | 4323 | }; |
| | 4324 | const addrspace_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4332 | | 4325 | |
| 4333 | var section_gz = decl_gz.makeSubBlock(params_scope); | 4326 | var section_gz = decl_gz.makeSubBlock(params_scope); |
| 4334 | defer section_gz.unstack(); | 4327 | defer section_gz.unstack(); |
| ... | @@ -4341,6 +4334,7 @@ fn fnDecl( | ... | @@ -4341,6 +4334,7 @@ fn fnDecl( |
| 4341 | _ = try section_gz.addBreak(.break_inline, @enumFromInt(0), inst); | 4334 | _ = try section_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4342 | break :inst inst; | 4335 | break :inst inst; |
| 4343 | }; | 4336 | }; |
| | 4337 | const section_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4344 | | 4338 | |
| 4345 | var cc_gz = decl_gz.makeSubBlock(params_scope); | 4339 | var cc_gz = decl_gz.makeSubBlock(params_scope); |
| 4346 | defer cc_gz.unstack(); | 4340 | defer cc_gz.unstack(); |
| ... | @@ -4377,6 +4371,7 @@ fn fnDecl( | ... | @@ -4377,6 +4371,7 @@ fn fnDecl( |
| 4377 | break :blk .none; | 4371 | break :blk .none; |
| 4378 | } | 4372 | } |
| 4379 | }; | 4373 | }; |
| | 4374 | const cc_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4380 | | 4375 | |
| 4381 | var ret_gz = decl_gz.makeSubBlock(params_scope); | 4376 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 4382 | defer ret_gz.unstack(); | 4377 | defer ret_gz.unstack(); |
| ... | @@ -4389,6 +4384,7 @@ fn fnDecl( | ... | @@ -4389,6 +4384,7 @@ fn fnDecl( |
| 4389 | _ = try ret_gz.addBreak(.break_inline, @enumFromInt(0), inst); | 4384 | _ = try ret_gz.addBreak(.break_inline, @enumFromInt(0), inst); |
| 4390 | break :inst inst; | 4385 | break :inst inst; |
| 4391 | }; | 4386 | }; |
| | 4387 | const ret_body_param_refs = try astgen.fetchRemoveRefEntries(param_insts.items); |
| 4392 | | 4388 | |
| 4393 | const func_inst: Zir.Inst.Ref = if (body_node == 0) func: { | 4389 | const func_inst: Zir.Inst.Ref = if (body_node == 0) func: { |
| 4394 | if (!is_extern) { | 4390 | if (!is_extern) { |
| ... | @@ -4401,15 +4397,21 @@ fn fnDecl( | ... | @@ -4401,15 +4397,21 @@ fn fnDecl( |
| 4401 | .src_node = decl_node, | 4397 | .src_node = decl_node, |
| 4402 | .cc_ref = cc_ref, | 4398 | .cc_ref = cc_ref, |
| 4403 | .cc_gz = &cc_gz, | 4399 | .cc_gz = &cc_gz, |
| | 4400 | .cc_param_refs = cc_body_param_refs, |
| 4404 | .align_ref = align_ref, | 4401 | .align_ref = align_ref, |
| 4405 | .align_gz = &align_gz, | 4402 | .align_gz = &align_gz, |
| | 4403 | .align_param_refs = align_body_param_refs, |
| 4406 | .ret_ref = ret_ref, | 4404 | .ret_ref = ret_ref, |
| 4407 | .ret_gz = &ret_gz, | 4405 | .ret_gz = &ret_gz, |
| | 4406 | .ret_param_refs = ret_body_param_refs, |
| 4408 | .section_ref = section_ref, | 4407 | .section_ref = section_ref, |
| 4409 | .section_gz = &section_gz, | 4408 | .section_gz = &section_gz, |
| | 4409 | .section_param_refs = section_body_param_refs, |
| 4410 | .addrspace_ref = addrspace_ref, | 4410 | .addrspace_ref = addrspace_ref, |
| 4411 | .addrspace_gz = &addrspace_gz, | 4411 | .addrspace_gz = &addrspace_gz, |
| | 4412 | .addrspace_param_refs = addrspace_body_param_refs, |
| 4412 | .param_block = decl_inst, | 4413 | .param_block = decl_inst, |
| | 4414 | .param_insts = param_insts.items, |
| 4413 | .body_gz = null, | 4415 | .body_gz = null, |
| 4414 | .lib_name = lib_name, | 4416 | .lib_name = lib_name, |
| 4415 | .is_var_args = is_var_args, | 4417 | .is_var_args = is_var_args, |
| ... | @@ -4471,17 +4473,23 @@ fn fnDecl( | ... | @@ -4471,17 +4473,23 @@ fn fnDecl( |
| 4471 | .src_node = decl_node, | 4473 | .src_node = decl_node, |
| 4472 | .cc_ref = cc_ref, | 4474 | .cc_ref = cc_ref, |
| 4473 | .cc_gz = &cc_gz, | 4475 | .cc_gz = &cc_gz, |
| | 4476 | .cc_param_refs = cc_body_param_refs, |
| 4474 | .align_ref = align_ref, | 4477 | .align_ref = align_ref, |
| 4475 | .align_gz = &align_gz, | 4478 | .align_gz = &align_gz, |
| | 4479 | .align_param_refs = align_body_param_refs, |
| 4476 | .ret_ref = ret_ref, | 4480 | .ret_ref = ret_ref, |
| 4477 | .ret_gz = &ret_gz, | 4481 | .ret_gz = &ret_gz, |
| | 4482 | .ret_param_refs = ret_body_param_refs, |
| 4478 | .section_ref = section_ref, | 4483 | .section_ref = section_ref, |
| 4479 | .section_gz = &section_gz, | 4484 | .section_gz = &section_gz, |
| | 4485 | .section_param_refs = section_body_param_refs, |
| 4480 | .addrspace_ref = addrspace_ref, | 4486 | .addrspace_ref = addrspace_ref, |
| 4481 | .addrspace_gz = &addrspace_gz, | 4487 | .addrspace_gz = &addrspace_gz, |
| | 4488 | .addrspace_param_refs = addrspace_body_param_refs, |
| 4482 | .lbrace_line = lbrace_line, | 4489 | .lbrace_line = lbrace_line, |
| 4483 | .lbrace_column = lbrace_column, | 4490 | .lbrace_column = lbrace_column, |
| 4484 | .param_block = decl_inst, | 4491 | .param_block = decl_inst, |
| | 4492 | .param_insts = param_insts.items, |
| 4485 | .body_gz = &fn_gz, | 4493 | .body_gz = &fn_gz, |
| 4486 | .lib_name = lib_name, | 4494 | .lib_name = lib_name, |
| 4487 | .is_var_args = is_var_args, | 4495 | .is_var_args = is_var_args, |
| ... | @@ -4972,6 +4980,13 @@ fn testDecl( | ... | @@ -4972,6 +4980,13 @@ fn testDecl( |
| 4972 | .addrspace_ref = .none, | 4980 | .addrspace_ref = .none, |
| 4973 | .addrspace_gz = null, | 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 | .lbrace_line = lbrace_line, | 4990 | .lbrace_line = lbrace_line, |
| 4976 | .lbrace_column = lbrace_column, | 4991 | .lbrace_column = lbrace_column, |
| 4977 | .param_block = decl_inst, | 4992 | .param_block = decl_inst, |
| ... | @@ -7429,19 +7444,7 @@ fn switchExprErrUnion( | ... | @@ -7429,19 +7444,7 @@ fn switchExprErrUnion( |
| 7429 | } | 7444 | } |
| 7430 | | 7445 | |
| 7431 | const case_slice = case_scope.instructionsSlice(); | 7446 | const case_slice = case_scope.instructionsSlice(); |
| 7432 | // Since we use the switch_block_err_union instruction itself to refer | 7447 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, &.{switch_block}); |
| 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); | | |
| 7445 | try payloads.ensureUnusedCapacity(gpa, body_len); | 7448 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 7446 | const capture: Zir.Inst.SwitchBlock.ProngInfo.Capture = switch (node_ty) { | 7449 | const capture: Zir.Inst.SwitchBlock.ProngInfo.Capture = switch (node_ty) { |
| 7447 | .@"catch" => .none, | 7450 | .@"catch" => .none, |
| ... | @@ -7458,10 +7461,7 @@ fn switchExprErrUnion( | ... | @@ -7458,10 +7461,7 @@ fn switchExprErrUnion( |
| 7458 | .is_inline = false, | 7461 | .is_inline = false, |
| 7459 | .has_tag_capture = false, | 7462 | .has_tag_capture = false, |
| 7460 | }); | 7463 | }); |
| 7461 | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { | 7464 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, &.{switch_block}); |
| 7462 | appendPossiblyRefdBodyInst(astgen, payloads, kv.value); | | |
| 7463 | } | | |
| 7464 | appendBodyWithFixupsArrayList(astgen, payloads, case_slice); | | |
| 7465 | } | 7465 | } |
| 7466 | | 7466 | |
| 7467 | const err_name = blk: { | 7467 | const err_name = blk: { |
| ... | @@ -7624,26 +7624,8 @@ fn switchExprErrUnion( | ... | @@ -7624,26 +7624,8 @@ fn switchExprErrUnion( |
| 7624 | } | 7624 | } |
| 7625 | | 7625 | |
| 7626 | const case_slice = case_scope.instructionsSlice(); | 7626 | const case_slice = case_scope.instructionsSlice(); |
| 7627 | // Since we use the switch_block_err_union instruction itself to refer | 7627 | const extra_insts: []const Zir.Inst.Index = if (uses_err) &.{ switch_block, err_inst } else &.{switch_block}; |
| 7628 | // to the capture, which will not be added to the child block, we need | 7628 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, extra_insts); |
| 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); | | |
| 7647 | try payloads.ensureUnusedCapacity(gpa, body_len); | 7629 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 7648 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ | 7630 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ |
| 7649 | .body_len = @intCast(body_len), | 7631 | .body_len = @intCast(body_len), |
| ... | @@ -7651,15 +7633,7 @@ fn switchExprErrUnion( | ... | @@ -7651,15 +7633,7 @@ fn switchExprErrUnion( |
| 7651 | .is_inline = case.inline_token != null, | 7633 | .is_inline = case.inline_token != null, |
| 7652 | .has_tag_capture = false, | 7634 | .has_tag_capture = false, |
| 7653 | }); | 7635 | }); |
| 7654 | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { | 7636 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, extra_insts); |
| 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); | | |
| 7663 | } | 7637 | } |
| 7664 | } | 7638 | } |
| 7665 | // Now that the item expressions are generated we can add this. | 7639 | // Now that the item expressions are generated we can add this. |
| ... | @@ -8106,27 +8080,8 @@ fn switchExpr( | ... | @@ -8106,27 +8080,8 @@ fn switchExpr( |
| 8106 | } | 8080 | } |
| 8107 | | 8081 | |
| 8108 | const case_slice = case_scope.instructionsSlice(); | 8082 | const case_slice = case_scope.instructionsSlice(); |
| 8109 | // Since we use the switch_block instruction itself to refer to the | 8083 | const extra_insts: []const Zir.Inst.Index = if (has_tag_capture) &.{ switch_block, tag_inst } else &.{switch_block}; |
| 8110 | // capture, which will not be added to the child block, we need to | 8084 | const body_len = astgen.countBodyLenAfterFixupsExtraRefs(case_slice, extra_insts); |
| 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); | | |
| 8130 | try payloads.ensureUnusedCapacity(gpa, body_len); | 8085 | try payloads.ensureUnusedCapacity(gpa, body_len); |
| 8131 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ | 8086 | payloads.items[body_len_index] = @bitCast(Zir.Inst.SwitchBlock.ProngInfo{ |
| 8132 | .body_len = @intCast(body_len), | 8087 | .body_len = @intCast(body_len), |
| ... | @@ -8134,15 +8089,7 @@ fn switchExpr( | ... | @@ -8134,15 +8089,7 @@ fn switchExpr( |
| 8134 | .is_inline = case.inline_token != null, | 8089 | .is_inline = case.inline_token != null, |
| 8135 | .has_tag_capture = has_tag_capture, | 8090 | .has_tag_capture = has_tag_capture, |
| 8136 | }); | 8091 | }); |
| 8137 | if (astgen.ref_table.fetchRemove(switch_block)) |kv| { | 8092 | appendBodyWithFixupsExtraRefsArrayList(astgen, payloads, case_slice, extra_insts); |
| 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); | | |
| 8146 | } | 8093 | } |
| 8147 | } | 8094 | } |
| 8148 | | 8095 | |
| ... | @@ -11201,9 +11148,6 @@ fn rvalueInner( | ... | @@ -11201,9 +11148,6 @@ fn rvalueInner( |
| 11201 | const src_token = tree.firstToken(src_node); | 11148 | const src_token = tree.firstToken(src_node); |
| 11202 | const result_index = coerced_result.toIndex() orelse | 11149 | const result_index = coerced_result.toIndex() orelse |
| 11203 | return gz.addUnTok(.ref, coerced_result, src_token); | 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 | const gop = try astgen.ref_table.getOrPut(astgen.gpa, result_index); | 11151 | const gop = try astgen.ref_table.getOrPut(astgen.gpa, result_index); |
| 11208 | if (!gop.found_existing) { | 11152 | if (!gop.found_existing) { |
| 11209 | gop.value_ptr.* = try gz.makeUnTok(.ref, coerced_result, src_token); | 11153 | gop.value_ptr.* = try gz.makeUnTok(.ref, coerced_result, src_token); |
| ... | @@ -12232,36 +12176,46 @@ const GenZir = struct { | ... | @@ -12232,36 +12176,46 @@ const GenZir = struct { |
| 12232 | /// * ret_gz | 12176 | /// * ret_gz |
| 12233 | /// * body_gz (top) | 12177 | /// * body_gz (top) |
| 12234 | /// Unstacks all of those except for `gz`. | 12178 | /// Unstacks all of those except for `gz`. |
| 12235 | fn addFunc(gz: *GenZir, args: struct { | 12179 | fn addFunc( |
| 12236 | src_node: Ast.Node.Index, | 12180 | gz: *GenZir, |
| 12237 | lbrace_line: u32 = 0, | 12181 | args: struct { |
| 12238 | lbrace_column: u32 = 0, | 12182 | src_node: Ast.Node.Index, |
| 12239 | param_block: Zir.Inst.Index, | 12183 | lbrace_line: u32 = 0, |
| 12240 | | 12184 | lbrace_column: u32 = 0, |
| 12241 | align_gz: ?*GenZir, | 12185 | param_block: Zir.Inst.Index, |
| 12242 | addrspace_gz: ?*GenZir, | 12186 | |
| 12243 | section_gz: ?*GenZir, | 12187 | align_gz: ?*GenZir, |
| 12244 | cc_gz: ?*GenZir, | 12188 | addrspace_gz: ?*GenZir, |
| 12245 | ret_gz: ?*GenZir, | 12189 | section_gz: ?*GenZir, |
| 12246 | body_gz: ?*GenZir, | 12190 | cc_gz: ?*GenZir, |
| 12247 | | 12191 | ret_gz: ?*GenZir, |
| 12248 | align_ref: Zir.Inst.Ref, | 12192 | body_gz: ?*GenZir, |
| 12249 | addrspace_ref: Zir.Inst.Ref, | 12193 | |
| 12250 | section_ref: Zir.Inst.Ref, | 12194 | align_param_refs: []Zir.Inst.Index, |
| 12251 | cc_ref: Zir.Inst.Ref, | 12195 | addrspace_param_refs: []Zir.Inst.Index, |
| 12252 | ret_ref: Zir.Inst.Ref, | 12196 | section_param_refs: []Zir.Inst.Index, |
| 12253 | | 12197 | cc_param_refs: []Zir.Inst.Index, |
| 12254 | lib_name: Zir.NullTerminatedString, | 12198 | ret_param_refs: []Zir.Inst.Index, |
| 12255 | noalias_bits: u32, | 12199 | param_insts: []Zir.Inst.Index, // refs to params in `body_gz` should still be in `astgen.ref_table` |
| 12256 | is_var_args: bool, | 12200 | |
| 12257 | is_inferred_error: bool, | 12201 | align_ref: Zir.Inst.Ref, |
| 12258 | is_test: bool, | 12202 | addrspace_ref: Zir.Inst.Ref, |
| 12259 | is_extern: bool, | 12203 | section_ref: Zir.Inst.Ref, |
| 12260 | is_noinline: bool, | 12204 | cc_ref: Zir.Inst.Ref, |
| 12261 | | 12205 | ret_ref: Zir.Inst.Ref, |
| 12262 | /// Ignored if `body_gz == null`. | 12206 | |
| 12263 | proto_hash: std.zig.SrcHash, | 12207 | lib_name: Zir.NullTerminatedString, |
| 12264 | }) !Zir.Inst.Ref { | 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 | assert(args.src_node != 0); | 12219 | assert(args.src_node != 0); |
| 12266 | const astgen = gz.astgen; | 12220 | const astgen = gz.astgen; |
| 12267 | const gpa = astgen.gpa; | 12221 | const gpa = astgen.gpa; |
| ... | @@ -12309,7 +12263,7 @@ const GenZir = struct { | ... | @@ -12309,7 +12263,7 @@ const GenZir = struct { |
| 12309 | if (args.ret_gz) |ret_gz| | 12263 | if (args.ret_gz) |ret_gz| |
| 12310 | ret_body = ret_gz.instructionsSlice(); | 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 | if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or | 12268 | if (args.cc_ref != .none or args.lib_name != .empty or args.is_var_args or args.is_test or |
| 12315 | args.is_extern or args.align_ref != .none or args.section_ref != .none or | 12269 | args.is_extern or args.align_ref != .none or args.section_ref != .none or |
| ... | @@ -12329,11 +12283,11 @@ const GenZir = struct { | ... | @@ -12329,11 +12283,11 @@ const GenZir = struct { |
| 12329 | try astgen.extra.ensureUnusedCapacity( | 12283 | try astgen.extra.ensureUnusedCapacity( |
| 12330 | gpa, | 12284 | gpa, |
| 12331 | @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len + | 12285 | @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len + |
| 12332 | fancyFnExprExtraLen(astgen, align_body, args.align_ref) + | 12286 | fancyFnExprExtraLen(astgen, args.align_param_refs, align_body, args.align_ref) + |
| 12333 | fancyFnExprExtraLen(astgen, addrspace_body, args.addrspace_ref) + | 12287 | fancyFnExprExtraLen(astgen, args.addrspace_param_refs, addrspace_body, args.addrspace_ref) + |
| 12334 | fancyFnExprExtraLen(astgen, section_body, args.section_ref) + | 12288 | fancyFnExprExtraLen(astgen, args.section_param_refs, section_body, args.section_ref) + |
| 12335 | fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) + | 12289 | fancyFnExprExtraLen(astgen, args.cc_param_refs, cc_body, args.cc_ref) + |
| 12336 | fancyFnExprExtraLen(astgen, ret_body, ret_ref) + | 12290 | fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + |
| 12337 | body_len + src_locs_and_hash.len + | 12291 | body_len + src_locs_and_hash.len + |
| 12338 | @intFromBool(args.lib_name != .empty) + | 12292 | @intFromBool(args.lib_name != .empty) + |
| 12339 | @intFromBool(args.noalias_bits != 0), | 12293 | @intFromBool(args.noalias_bits != 0), |
| ... | @@ -12369,7 +12323,11 @@ const GenZir = struct { | ... | @@ -12369,7 +12323,11 @@ const GenZir = struct { |
| 12369 | | 12323 | |
| 12370 | const zir_datas = astgen.instructions.items(.data); | 12324 | const zir_datas = astgen.instructions.items(.data); |
| 12371 | if (align_body.len != 0) { | 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 | astgen.appendBodyWithFixups(align_body); | 12331 | astgen.appendBodyWithFixups(align_body); |
| 12374 | const break_extra = zir_datas[@intFromEnum(align_body[align_body.len - 1])].@"break".payload_index; | 12332 | const break_extra = zir_datas[@intFromEnum(align_body[align_body.len - 1])].@"break".payload_index; |
| 12375 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | 12333 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | @@ -12378,7 +12336,11 @@ const GenZir = struct { | ... | @@ -12378,7 +12336,11 @@ const GenZir = struct { |
| 12378 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref)); | 12336 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.align_ref)); |
| 12379 | } | 12337 | } |
| 12380 | if (addrspace_body.len != 0) { | 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 | astgen.appendBodyWithFixups(addrspace_body); | 12344 | astgen.appendBodyWithFixups(addrspace_body); |
| 12383 | const break_extra = | 12345 | const break_extra = |
| 12384 | zir_datas[@intFromEnum(addrspace_body[addrspace_body.len - 1])].@"break".payload_index; | 12346 | zir_datas[@intFromEnum(addrspace_body[addrspace_body.len - 1])].@"break".payload_index; |
| ... | @@ -12388,7 +12350,11 @@ const GenZir = struct { | ... | @@ -12388,7 +12350,11 @@ const GenZir = struct { |
| 12388 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref)); | 12350 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.addrspace_ref)); |
| 12389 | } | 12351 | } |
| 12390 | if (section_body.len != 0) { | 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 | astgen.appendBodyWithFixups(section_body); | 12358 | astgen.appendBodyWithFixups(section_body); |
| 12393 | const break_extra = | 12359 | const break_extra = |
| 12394 | zir_datas[@intFromEnum(section_body[section_body.len - 1])].@"break".payload_index; | 12360 | zir_datas[@intFromEnum(section_body[section_body.len - 1])].@"break".payload_index; |
| ... | @@ -12398,7 +12364,11 @@ const GenZir = struct { | ... | @@ -12398,7 +12364,11 @@ const GenZir = struct { |
| 12398 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref)); | 12364 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.section_ref)); |
| 12399 | } | 12365 | } |
| 12400 | if (cc_body.len != 0) { | 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 | astgen.appendBodyWithFixups(cc_body); | 12372 | astgen.appendBodyWithFixups(cc_body); |
| 12403 | const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index; | 12373 | const break_extra = zir_datas[@intFromEnum(cc_body[cc_body.len - 1])].@"break".payload_index; |
| 12404 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | 12374 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | @@ -12407,7 +12377,11 @@ const GenZir = struct { | ... | @@ -12407,7 +12377,11 @@ const GenZir = struct { |
| 12407 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref)); | 12377 | astgen.extra.appendAssumeCapacity(@intFromEnum(args.cc_ref)); |
| 12408 | } | 12378 | } |
| 12409 | if (ret_body.len != 0) { | 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 | astgen.appendBodyWithFixups(ret_body); | 12385 | astgen.appendBodyWithFixups(ret_body); |
| 12412 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; | 12386 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; |
| 12413 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = | 12387 | astgen.extra.items[break_extra + std.meta.fieldIndex(Zir.Inst.Break, "block_inst").?] = |
| ... | @@ -12420,7 +12394,7 @@ const GenZir = struct { | ... | @@ -12420,7 +12394,7 @@ const GenZir = struct { |
| 12420 | astgen.extra.appendAssumeCapacity(args.noalias_bits); | 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 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); | 12398 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12425 | | 12399 | |
| 12426 | // Order is important when unstacking. | 12400 | // Order is important when unstacking. |
| ... | @@ -12448,12 +12422,12 @@ const GenZir = struct { | ... | @@ -12448,12 +12422,12 @@ const GenZir = struct { |
| 12448 | try astgen.extra.ensureUnusedCapacity( | 12422 | try astgen.extra.ensureUnusedCapacity( |
| 12449 | gpa, | 12423 | gpa, |
| 12450 | @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 + | 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 | body_len + src_locs_and_hash.len, | 12426 | body_len + src_locs_and_hash.len, |
| 12453 | ); | 12427 | ); |
| 12454 | | 12428 | |
| 12455 | const ret_body_len = if (ret_body.len != 0) | 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 | else | 12431 | else |
| 12458 | @intFromBool(ret_ref != .none); | 12432 | @intFromBool(ret_ref != .none); |
| 12459 | | 12433 | |
| ... | @@ -12464,6 +12438,7 @@ const GenZir = struct { | ... | @@ -12464,6 +12438,7 @@ const GenZir = struct { |
| 12464 | }); | 12438 | }); |
| 12465 | const zir_datas = astgen.instructions.items(.data); | 12439 | const zir_datas = astgen.instructions.items(.data); |
| 12466 | if (ret_body.len != 0) { | 12440 | if (ret_body.len != 0) { |
| | 12441 | astgen.appendBodyWithFixups(args.ret_param_refs); |
| 12467 | astgen.appendBodyWithFixups(ret_body); | 12442 | astgen.appendBodyWithFixups(ret_body); |
| 12468 | | 12443 | |
| 12469 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; | 12444 | const break_extra = zir_datas[@intFromEnum(ret_body[ret_body.len - 1])].@"break".payload_index; |
| ... | @@ -12472,7 +12447,7 @@ const GenZir = struct { | ... | @@ -12472,7 +12447,7 @@ const GenZir = struct { |
| 12472 | } else if (ret_ref != .none) { | 12447 | } else if (ret_ref != .none) { |
| 12473 | astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref)); | 12448 | astgen.extra.appendAssumeCapacity(@intFromEnum(ret_ref)); |
| 12474 | } | 12449 | } |
| 12475 | astgen.appendBodyWithFixups(body); | 12450 | astgen.appendBodyWithFixupsExtraRefsArrayList(&astgen.extra, body, args.param_insts); |
| 12476 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); | 12451 | astgen.extra.appendSliceAssumeCapacity(src_locs_and_hash); |
| 12477 | | 12452 | |
| 12478 | // Order is important when unstacking. | 12453 | // Order is important when unstacking. |
| ... | @@ -12498,10 +12473,11 @@ const GenZir = struct { | ... | @@ -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 { | 12476 | fn fancyFnExprExtraLen(astgen: *AstGen, param_refs_body: []Zir.Inst.Index, main_body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 { |
| 12502 | // In the case of non-empty body, there is one for the body length, | 12477 | return countBodyLenAfterFixups(astgen, param_refs_body) + |
| 12503 | // and then one for each instruction. | 12478 | countBodyLenAfterFixups(astgen, main_body) + |
| 12504 | return countBodyLenAfterFixups(astgen, body) + @intFromBool(ref != .none); | 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 | fn addVar(gz: *GenZir, args: struct { | 12483 | fn addVar(gz: *GenZir, args: struct { |
| ... | @@ -12673,6 +12649,9 @@ const GenZir = struct { | ... | @@ -12673,6 +12649,9 @@ const GenZir = struct { |
| 12673 | fn addParam( | 12649 | fn addParam( |
| 12674 | gz: *GenZir, | 12650 | gz: *GenZir, |
| 12675 | param_gz: *GenZir, | 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 | tag: Zir.Inst.Tag, | 12655 | tag: Zir.Inst.Tag, |
| 12677 | /// Absolute token index. This function does the conversion to Decl offset. | 12656 | /// Absolute token index. This function does the conversion to Decl offset. |
| 12678 | abs_tok_index: Ast.TokenIndex, | 12657 | abs_tok_index: Ast.TokenIndex, |
| ... | @@ -12681,7 +12660,7 @@ const GenZir = struct { | ... | @@ -12681,7 +12660,7 @@ const GenZir = struct { |
| 12681 | ) !Zir.Inst.Index { | 12660 | ) !Zir.Inst.Index { |
| 12682 | const gpa = gz.astgen.gpa; | 12661 | const gpa = gz.astgen.gpa; |
| 12683 | const param_body = param_gz.instructionsSlice(); | 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 | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); | 12664 | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 12686 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).@"struct".fields.len + body_len); | 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,7 +12674,7 @@ const GenZir = struct { |
| 12695 | .doc_comment = doc_comment_index, | 12674 | .doc_comment = doc_comment_index, |
| 12696 | .body_len = @intCast(body_len), | 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 | param_gz.unstack(); | 12678 | param_gz.unstack(); |
| 12700 | | 12679 | |
| 12701 | const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); | 12680 | const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); |
| ... | @@ -13938,27 +13917,6 @@ fn scanContainer( | ... | @@ -13938,27 +13917,6 @@ fn scanContainer( |
| 13938 | return decl_count; | 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 | /// Assumes capacity for body has already been added. Needed capacity taking into | 13920 | /// Assumes capacity for body has already been added. Needed capacity taking into |
| 13963 | /// account fixups can be found with `countBodyLenAfterFixups`. | 13921 | /// account fixups can be found with `countBodyLenAfterFixups`. |
| 13964 | fn appendBodyWithFixups(astgen: *AstGen, body: []const Zir.Inst.Index) void { | 13922 | fn appendBodyWithFixups(astgen: *AstGen, body: []const Zir.Inst.Index) void { |
| ... | @@ -13970,6 +13928,20 @@ fn appendBodyWithFixupsArrayList( | ... | @@ -13970,6 +13928,20 @@ fn appendBodyWithFixupsArrayList( |
| 13970 | list: *std.ArrayListUnmanaged(u32), | 13928 | list: *std.ArrayListUnmanaged(u32), |
| 13971 | body: []const Zir.Inst.Index, | 13929 | body: []const Zir.Inst.Index, |
| 13972 | ) void { | 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 | for (body) |body_inst| { | 13945 | for (body) |body_inst| { |
| 13974 | appendPossiblyRefdBodyInst(astgen, list, body_inst); | 13946 | appendPossiblyRefdBodyInst(astgen, list, body_inst); |
| 13975 | } | 13947 | } |
| ... | @@ -13987,6 +13959,14 @@ fn appendPossiblyRefdBodyInst( | ... | @@ -13987,6 +13959,14 @@ fn appendPossiblyRefdBodyInst( |
| 13987 | } | 13959 | } |
| 13988 | | 13960 | |
| 13989 | fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { | 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 | var count = body.len; | 13970 | var count = body.len; |
| 13991 | for (body) |body_inst| { | 13971 | for (body) |body_inst| { |
| 13992 | var check_inst = body_inst; | 13972 | var check_inst = body_inst; |
| ... | @@ -13995,6 +13975,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { | ... | @@ -13995,6 +13975,13 @@ fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 { |
| 13995 | check_inst = ref_inst; | 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 | return @intCast(count); | 13985 | return @intCast(count); |
| 13999 | } | 13986 | } |
| 14000 | | 13987 | |
| ... | @@ -14176,3 +14163,23 @@ fn setDeclaration( | ... | @@ -14176,3 +14163,23 @@ fn setDeclaration( |
| 14176 | } | 14163 | } |
| 14177 | value_gz.unstack(); | 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 | } |