| ... | ... | @@ -1684,15 +1684,24 @@ fn constantPtr(cg: *CodeGen, ptr_val: Value) !Id { |
| 1684 | 1684 | return cg.derivePtr(ptr_val.typeOf(zcu).ptrAddressSpace(zcu), derivation); |
| 1685 | 1685 | } |
| 1686 | 1686 | |
| 1687 | fn derivedPtrType(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1688 | return cg.ptrType( |
| 1689 | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), |
| 1690 | cg.storageClass(@"addrspace"), |
| 1691 | ); |
| 1692 | } |
| 1693 | |
| 1687 | 1694 | fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Value.PointerDerivation) !Id { |
| 1688 | 1695 | const gpa = cg.gpa; |
| 1689 | 1696 | const zcu = cg.zcu; |
| 1690 | 1697 | const target = zcu.getTarget(); |
| 1691 | 1698 | |
| 1692 | | const result_ty_id = try cg.ptrType( |
| 1693 | | try cg.pointeeType(@"addrspace", derivation.elem_ty, false), |
| 1694 | | cg.storageClass(@"addrspace"), |
| 1695 | | ); |
| 1699 | // A variable on Vulkan and OpenGL is used through its own pointer, so a `nav` resolves this only |
| 1700 | // where it is used; a type emitted and left unused stays in the module. |
| 1701 | const result_ty_id = switch (derivation.addr) { |
| 1702 | .nav => undefined, |
| 1703 | else => try cg.derivedPtrType(@"addrspace", derivation), |
| 1704 | }; |
| 1696 | 1705 | |
| 1697 | 1706 | switch (derivation.addr) { |
| 1698 | 1707 | .comptime_alloc, .comptime_field => unreachable, |
| ... | ... | @@ -1727,10 +1736,10 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1727 | 1736 | |
| 1728 | 1737 | if (ip.isFunctionType(nav_ty.toIntern())) { |
| 1729 | 1738 | if (is_extern) return try cg.resolveExternFn(nav_index); |
| 1730 | | return try cg.constUndef(result_ty_id); |
| 1739 | return try cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1731 | 1740 | } |
| 1732 | 1741 | if (!nav_ty.hasRuntimeBits(zcu) and nav_ty.zigTypeTag(zcu) != .spirv) { |
| 1733 | | return cg.constUndef(result_ty_id); |
| 1742 | return cg.constUndef(try cg.derivedPtrType(@"addrspace", derivation)); |
| 1734 | 1743 | } |
| 1735 | 1744 | if (!is_extern) { |
| 1736 | 1745 | return cg.todo("pointer to constant '{f}'", .{nav.fqn.fmt(ip)}); |
| ... | ... | @@ -1739,23 +1748,23 @@ fn derivePtr(cg: *CodeGen, @"addrspace": std.lang.AddressSpace, derivation: Valu |
| 1739 | 1748 | const as = nav.resolved.?.@"addrspace"; |
| 1740 | 1749 | assert(as != .generic); |
| 1741 | 1750 | |
| 1742 | | const storage_class = cg.storageClass(as); |
| 1743 | 1751 | const var_id = try cg.resolveNav(nav_index); |
| 1744 | | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1745 | | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, storage_class); |
| 1746 | 1752 | if (cg.needsLayout(as, nav_ty)) { |
| 1747 | 1753 | try cg.block_var_ids.put(gpa, var_id, {}); |
| 1748 | 1754 | } |
| 1749 | | |
| 1750 | | if (decl_ptr_ty_id == result_ty_id) return var_id; |
| 1751 | 1755 | switch (target.os.tag) { |
| 1752 | 1756 | .vulkan, .opengl => return var_id, |
| 1753 | 1757 | else => {}, |
| 1754 | 1758 | } |
| 1755 | 1759 | |
| 1760 | const nav_ty_id = try cg.resolveType(nav_ty, .indirect); |
| 1761 | const decl_ptr_ty_id = try cg.ptrType(nav_ty_id, cg.storageClass(as)); |
| 1762 | const nav_result_ty_id = try cg.derivedPtrType(@"addrspace", derivation); |
| 1763 | if (decl_ptr_ty_id == nav_result_ty_id) return var_id; |
| 1764 | |
| 1756 | 1765 | const casted_ptr_id = cg.allocId(); |
| 1757 | 1766 | try cg.body.emit(gpa, .OpBitcast, .{ |
| 1758 | | .id_result_type = result_ty_id, |
| 1767 | .id_result_type = nav_result_ty_id, |
| 1759 | 1768 | .id_result = casted_ptr_id, |
| 1760 | 1769 | .operand = var_id, |
| 1761 | 1770 | }); |