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