| ... | @@ -1617,6 +1617,18 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Inner | ... | @@ -1617,6 +1617,18 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Inner |
| 1617 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); | 1617 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 1618 | } | 1618 | } |
| 1619 | | 1619 | |
| | 1620 | fn resolveBlockBody( |
| | 1621 | sema: *Sema, |
| | 1622 | parent_block: *Scope.Block, |
| | 1623 | src: LazySrcLoc, |
| | 1624 | child_block: *Scope.Block, |
| | 1625 | body: []const Zir.Inst.Index, |
| | 1626 | merges: *Scope.Block.Merges, |
| | 1627 | ) InnerError!*Inst { |
| | 1628 | _ = try sema.analyzeBody(child_block, body); |
| | 1629 | return sema.analyzeBlockBody(parent_block, src, child_block, merges); |
| | 1630 | } |
| | 1631 | |
| 1620 | fn analyzeBlockBody( | 1632 | fn analyzeBlockBody( |
| 1621 | sema: *Sema, | 1633 | sema: *Sema, |
| 1622 | parent_block: *Scope.Block, | 1634 | parent_block: *Scope.Block, |
| ... | @@ -1711,11 +1723,23 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! | ... | @@ -1711,11 +1723,23 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError! |
| 1711 | const decl_name = sema.code.nullTerminatedString(extra.decl_name); | 1723 | const decl_name = sema.code.nullTerminatedString(extra.decl_name); |
| 1712 | const decl = try sema.lookupIdentifier(block, lhs_src, decl_name); | 1724 | const decl = try sema.lookupIdentifier(block, lhs_src, decl_name); |
| 1713 | const options = try sema.resolveInstConst(block, rhs_src, extra.options); | 1725 | const options = try sema.resolveInstConst(block, rhs_src, extra.options); |
| | 1726 | const struct_obj = options.ty.castTag(.@"struct").?.data; |
| | 1727 | const fields = options.val.castTag(.@"struct").?.data[0..struct_obj.fields.count()]; |
| | 1728 | const name_index = struct_obj.fields.getIndex("name").?; |
| | 1729 | const linkage_index = struct_obj.fields.getIndex("linkage").?; |
| | 1730 | const section_index = struct_obj.fields.getIndex("section").?; |
| | 1731 | const export_name = try fields[name_index].toAllocatedBytes(sema.arena); |
| | 1732 | const linkage = fields[linkage_index].toEnum( |
| | 1733 | struct_obj.fields.items()[linkage_index].value.ty, |
| | 1734 | std.builtin.GlobalLinkage, |
| | 1735 | ); |
| 1714 | | 1736 | |
| 1715 | // TODO respect the name, linkage, and section options. Until then we export | 1737 | if (linkage != .Strong) { |
| 1716 | // as the decl name. | 1738 | return sema.mod.fail(&block.base, src, "TODO: implement exporting with non-strong linkage", .{}); |
| 1717 | _ = options; | 1739 | } |
| 1718 | const export_name = mem.spanZ(decl.name); | 1740 | if (!fields[section_index].isNull()) { |
| | 1741 | return sema.mod.fail(&block.base, src, "TODO: implement exporting with linksection", .{}); |
| | 1742 | } |
| 1719 | | 1743 | |
| 1720 | try sema.mod.analyzeExport(&block.base, src, export_name, decl); | 1744 | try sema.mod.analyzeExport(&block.base, src, export_name, decl); |
| 1721 | } | 1745 | } |
| ... | @@ -3600,7 +3624,39 @@ fn analyzeSwitch( | ... | @@ -3600,7 +3624,39 @@ fn analyzeSwitch( |
| 3600 | }), | 3624 | }), |
| 3601 | } | 3625 | } |
| 3602 | | 3626 | |
| 3603 | if (try sema.resolveDefinedValue(block, src, operand)) |operand_val| { | 3627 | const block_inst = try sema.arena.create(Inst.Block); |
| | 3628 | block_inst.* = .{ |
| | 3629 | .base = .{ |
| | 3630 | .tag = Inst.Block.base_tag, |
| | 3631 | .ty = undefined, // Set after analysis. |
| | 3632 | .src = src, |
| | 3633 | }, |
| | 3634 | .body = undefined, |
| | 3635 | }; |
| | 3636 | |
| | 3637 | var child_block: Scope.Block = .{ |
| | 3638 | .parent = block, |
| | 3639 | .sema = sema, |
| | 3640 | .src_decl = block.src_decl, |
| | 3641 | .instructions = .{}, |
| | 3642 | // TODO @as here is working around a stage1 miscompilation bug :( |
| | 3643 | .label = @as(?Scope.Block.Label, Scope.Block.Label{ |
| | 3644 | .zir_block = switch_inst, |
| | 3645 | .merges = .{ |
| | 3646 | .results = .{}, |
| | 3647 | .br_list = .{}, |
| | 3648 | .block_inst = block_inst, |
| | 3649 | }, |
| | 3650 | }), |
| | 3651 | .inlining = block.inlining, |
| | 3652 | .is_comptime = block.is_comptime, |
| | 3653 | }; |
| | 3654 | const merges = &child_block.label.?.merges; |
| | 3655 | defer child_block.instructions.deinit(gpa); |
| | 3656 | defer merges.results.deinit(gpa); |
| | 3657 | defer merges.br_list.deinit(gpa); |
| | 3658 | |
| | 3659 | if (try sema.resolveDefinedValue(&child_block, src, operand)) |operand_val| { |
| 3604 | var extra_index: usize = special.end; | 3660 | var extra_index: usize = special.end; |
| 3605 | { | 3661 | { |
| 3606 | var scalar_i: usize = 0; | 3662 | var scalar_i: usize = 0; |
| ... | @@ -3614,9 +3670,9 @@ fn analyzeSwitch( | ... | @@ -3614,9 +3670,9 @@ fn analyzeSwitch( |
| 3614 | | 3670 | |
| 3615 | // Validation above ensured these will succeed. | 3671 | // Validation above ensured these will succeed. |
| 3616 | const item = sema.resolveInst(item_ref) catch unreachable; | 3672 | const item = sema.resolveInst(item_ref) catch unreachable; |
| 3617 | const item_val = sema.resolveConstValue(block, .unneeded, item) catch unreachable; | 3673 | const item_val = sema.resolveConstValue(&child_block, .unneeded, item) catch unreachable; |
| 3618 | if (operand_val.eql(item_val)) { | 3674 | if (operand_val.eql(item_val)) { |
| 3619 | return sema.resolveBody(block, body); | 3675 | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 3620 | } | 3676 | } |
| 3621 | } | 3677 | } |
| 3622 | } | 3678 | } |
| ... | @@ -3636,9 +3692,9 @@ fn analyzeSwitch( | ... | @@ -3636,9 +3692,9 @@ fn analyzeSwitch( |
| 3636 | for (items) |item_ref| { | 3692 | for (items) |item_ref| { |
| 3637 | // Validation above ensured these will succeed. | 3693 | // Validation above ensured these will succeed. |
| 3638 | const item = sema.resolveInst(item_ref) catch unreachable; | 3694 | const item = sema.resolveInst(item_ref) catch unreachable; |
| 3639 | const item_val = sema.resolveConstValue(block, item.src, item) catch unreachable; | 3695 | const item_val = sema.resolveConstValue(&child_block, item.src, item) catch unreachable; |
| 3640 | if (operand_val.eql(item_val)) { | 3696 | if (operand_val.eql(item_val)) { |
| 3641 | return sema.resolveBody(block, body); | 3697 | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 3642 | } | 3698 | } |
| 3643 | } | 3699 | } |
| 3644 | | 3700 | |
| ... | @@ -3650,59 +3706,27 @@ fn analyzeSwitch( | ... | @@ -3650,59 +3706,27 @@ fn analyzeSwitch( |
| 3650 | extra_index += 1; | 3706 | extra_index += 1; |
| 3651 | | 3707 | |
| 3652 | // Validation above ensured these will succeed. | 3708 | // Validation above ensured these will succeed. |
| 3653 | const first_tv = sema.resolveInstConst(block, .unneeded, item_first) catch unreachable; | 3709 | const first_tv = sema.resolveInstConst(&child_block, .unneeded, item_first) catch unreachable; |
| 3654 | const last_tv = sema.resolveInstConst(block, .unneeded, item_last) catch unreachable; | 3710 | const last_tv = sema.resolveInstConst(&child_block, .unneeded, item_last) catch unreachable; |
| 3655 | if (Value.compare(operand_val, .gte, first_tv.val) and | 3711 | if (Value.compare(operand_val, .gte, first_tv.val) and |
| 3656 | Value.compare(operand_val, .lte, last_tv.val)) | 3712 | Value.compare(operand_val, .lte, last_tv.val)) |
| 3657 | { | 3713 | { |
| 3658 | return sema.resolveBody(block, body); | 3714 | return sema.resolveBlockBody(block, src, &child_block, body, merges); |
| 3659 | } | 3715 | } |
| 3660 | } | 3716 | } |
| 3661 | | 3717 | |
| 3662 | extra_index += body_len; | 3718 | extra_index += body_len; |
| 3663 | } | 3719 | } |
| 3664 | } | 3720 | } |
| 3665 | return sema.resolveBody(block, special.body); | 3721 | return sema.resolveBlockBody(block, src, &child_block, special.body, merges); |
| 3666 | } | 3722 | } |
| 3667 | | 3723 | |
| 3668 | if (scalar_cases_len + multi_cases_len == 0) { | 3724 | if (scalar_cases_len + multi_cases_len == 0) { |
| 3669 | return sema.resolveBody(block, special.body); | 3725 | return sema.resolveBlockBody(block, src, &child_block, special.body, merges); |
| 3670 | } | 3726 | } |
| 3671 | | 3727 | |
| 3672 | try sema.requireRuntimeBlock(block, src); | 3728 | try sema.requireRuntimeBlock(block, src); |
| 3673 | | 3729 | |
| 3674 | const block_inst = try sema.arena.create(Inst.Block); | | |
| 3675 | block_inst.* = .{ | | |
| 3676 | .base = .{ | | |
| 3677 | .tag = Inst.Block.base_tag, | | |
| 3678 | .ty = undefined, // Set after analysis. | | |
| 3679 | .src = src, | | |
| 3680 | }, | | |
| 3681 | .body = undefined, | | |
| 3682 | }; | | |
| 3683 | | | |
| 3684 | var child_block: Scope.Block = .{ | | |
| 3685 | .parent = block, | | |
| 3686 | .sema = sema, | | |
| 3687 | .src_decl = block.src_decl, | | |
| 3688 | .instructions = .{}, | | |
| 3689 | // TODO @as here is working around a stage1 miscompilation bug :( | | |
| 3690 | .label = @as(?Scope.Block.Label, Scope.Block.Label{ | | |
| 3691 | .zir_block = switch_inst, | | |
| 3692 | .merges = .{ | | |
| 3693 | .results = .{}, | | |
| 3694 | .br_list = .{}, | | |
| 3695 | .block_inst = block_inst, | | |
| 3696 | }, | | |
| 3697 | }), | | |
| 3698 | .inlining = block.inlining, | | |
| 3699 | .is_comptime = block.is_comptime, | | |
| 3700 | }; | | |
| 3701 | const merges = &child_block.label.?.merges; | | |
| 3702 | defer child_block.instructions.deinit(gpa); | | |
| 3703 | defer merges.results.deinit(gpa); | | |
| 3704 | defer merges.br_list.deinit(gpa); | | |
| 3705 | | | |
| 3706 | // TODO when reworking AIR memory layout make multi cases get generated as cases, | 3730 | // TODO when reworking AIR memory layout make multi cases get generated as cases, |
| 3707 | // not as part of the "else" block. | 3731 | // not as part of the "else" block. |
| 3708 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); | 3732 | const cases = try sema.arena.alloc(Inst.SwitchBr.Case, scalar_cases_len); |
| ... | @@ -4614,7 +4638,8 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro | ... | @@ -4614,7 +4638,8 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro |
| 4614 | } | 4638 | } |
| 4615 | | 4639 | |
| 4616 | fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { | 4640 | fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { |
| 4617 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 4641 | const zir_datas = sema.code.instructions.items(.data); |
| | 4642 | const inst_data = zir_datas[inst].un_node; |
| 4618 | const src = inst_data.src(); | 4643 | const src = inst_data.src(); |
| 4619 | const operand = try sema.resolveInst(inst_data.operand); | 4644 | const operand = try sema.resolveInst(inst_data.operand); |
| 4620 | return sema.mod.constType(sema.arena, src, operand.ty); | 4645 | return sema.mod.constType(sema.arena, src, operand.ty); |
| ... | @@ -5555,15 +5580,7 @@ fn zirFuncExtended( | ... | @@ -5555,15 +5580,7 @@ fn zirFuncExtended( |
| 5555 | const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | 5580 | const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); |
| 5556 | extra_index += 1; | 5581 | extra_index += 1; |
| 5557 | const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref); | 5582 | const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref); |
| 5558 | // TODO this needs to resolve other kinds of Value tags rather than | 5583 | break :blk cc_tv.val.toEnum(cc_tv.ty, std.builtin.CallingConvention); |
| 5559 | // assuming the tag will be .enum_field_index. | | |
| 5560 | const cc_field_index = cc_tv.val.castTag(.enum_field_index).?.data; | | |
| 5561 | // TODO should `@intToEnum` do this `@intCast` for you? | | |
| 5562 | const cc = @intToEnum( | | |
| 5563 | std.builtin.CallingConvention, | | |
| 5564 | @intCast(@typeInfo(std.builtin.CallingConvention).Enum.tag_type, cc_field_index), | | |
| 5565 | ); | | |
| 5566 | break :blk cc; | | |
| 5567 | } else .Unspecified; | 5584 | } else .Unspecified; |
| 5568 | | 5585 | |
| 5569 | const align_val: Value = if (small.has_align) blk: { | 5586 | const align_val: Value = if (small.has_align) blk: { |