| author | |
| committer | |
| log | 7bf91fc79ac9e4eae575baf3a2ca9549bc3bf6c2 |
| tree | f07c76f10c294cdfa7cc302097278ac4ff720c65 |
| parent | 607737d841bc2279cbe5fee68a0a546b9a5a802e |
Now pointer types are stored only in InternPool.15 files changed, 295 insertions(+), 673 deletions(-)
src/InternPool.zig+30-25| ... | @@ -186,17 +186,11 @@ pub const Key = union(enum) { | ... | @@ -186,17 +186,11 @@ pub const Key = union(enum) { |
| 186 | pub const PtrType = struct { | 186 | pub const PtrType = struct { |
| 187 | elem_type: Index, | 187 | elem_type: Index, |
| 188 | sentinel: Index = .none, | 188 | sentinel: Index = .none, |
| 189 | /// If zero use pointee_type.abiAlignment() | 189 | /// `none` indicates the ABI alignment of the pointee_type. In this |
| 190 | /// When creating pointer types, if alignment is equal to pointee type | 190 | /// case, this field *must* be set to `none`, otherwise the |
| 191 | /// abi alignment, this value should be set to 0 instead. | 191 | /// `InternPool` equality and hashing functions will return incorrect |
| 192 | /// | 192 | /// results. |
| 193 | /// Please don't change this to u32 or u29. If you want to save bits, | 193 | alignment: Alignment = .none, |
| 194 | /// migrate the rest of the codebase to use the `Alignment` type rather | ||
| 195 | /// than using byte units. The LLVM backend can only handle `c_uint` | ||
| 196 | /// byte units; we can emit a semantic analysis error if alignment that | ||
| 197 | /// overflows that amount is attempted to be used, but it shouldn't | ||
| 198 | /// affect the other backends. | ||
| 199 | alignment: u64 = 0, | ||
| 200 | /// If this is non-zero it means the pointer points to a sub-byte | 194 | /// If this is non-zero it means the pointer points to a sub-byte |
| 201 | /// range of data, which is backed by a "host integer" with this | 195 | /// range of data, which is backed by a "host integer" with this |
| 202 | /// number of bytes. | 196 | /// number of bytes. |
| ... | @@ -378,15 +372,11 @@ pub const Key = union(enum) { | ... | @@ -378,15 +372,11 @@ pub const Key = union(enum) { |
| 378 | /// Tells whether a parameter is noalias. See `paramIsNoalias` helper | 372 | /// Tells whether a parameter is noalias. See `paramIsNoalias` helper |
| 379 | /// method for accessing this. | 373 | /// method for accessing this. |
| 380 | noalias_bits: u32, | 374 | noalias_bits: u32, |
| 381 | /// If zero use default target function code alignment. | 375 | /// `none` indicates the function has the default alignment for |
| 382 | /// | 376 | /// function code on the target. In this case, this field *must* be set |
| 383 | /// Please don't change this to u32 or u29. If you want to save bits, | 377 | /// to `none`, otherwise the `InternPool` equality and hashing |
| 384 | /// migrate the rest of the codebase to use the `Alignment` type rather | 378 | /// functions will return incorrect results. |
| 385 | /// than using byte units. The LLVM backend can only handle `c_uint` | 379 | alignment: Alignment, |
| 386 | /// byte units; we can emit a semantic analysis error if alignment that | ||
| 387 | /// overflows that amount is attempted to be used, but it shouldn't | ||
| 388 | /// affect the other backends. | ||
| 389 | alignment: u64, | ||
| 390 | cc: std.builtin.CallingConvention, | 380 | cc: std.builtin.CallingConvention, |
| 391 | is_var_args: bool, | 381 | is_var_args: bool, |
| 392 | is_generic: bool, | 382 | is_generic: bool, |
| ... | @@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) { | ... | @@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) { |
| 1500 | none = std.math.maxInt(u6), | 1490 | none = std.math.maxInt(u6), |
| 1501 | _, | 1491 | _, |
| 1502 | 1492 | ||
| 1493 | pub fn toByteUnitsOptional(a: Alignment) ?u64 { | ||
| 1494 | return switch (a) { | ||
| 1495 | .none => null, | ||
| 1496 | _ => @as(u64, 1) << @enumToInt(a), | ||
| 1497 | }; | ||
| 1498 | } | ||
| 1499 | |||
| 1503 | pub fn toByteUnits(a: Alignment, default: u64) u64 { | 1500 | pub fn toByteUnits(a: Alignment, default: u64) u64 { |
| 1504 | return switch (a) { | 1501 | return switch (a) { |
| 1505 | .none => default, | 1502 | .none => default, |
| ... | @@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) { | ... | @@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) { |
| 1509 | 1506 | ||
| 1510 | pub fn fromByteUnits(n: u64) Alignment { | 1507 | pub fn fromByteUnits(n: u64) Alignment { |
| 1511 | if (n == 0) return .none; | 1508 | if (n == 0) return .none; |
| 1509 | assert(std.math.isPowerOfTwo(n)); | ||
| 1512 | return @intToEnum(Alignment, @ctz(n)); | 1510 | return @intToEnum(Alignment, @ctz(n)); |
| 1513 | } | 1511 | } |
| 1512 | |||
| 1513 | pub fn fromNonzeroByteUnits(n: u64) Alignment { | ||
| 1514 | assert(n != 0); | ||
| 1515 | return fromByteUnits(n); | ||
| 1516 | } | ||
| 1514 | }; | 1517 | }; |
| 1515 | 1518 | ||
| 1516 | /// Used for non-sentineled arrays that have length fitting in u32, as well as | 1519 | /// Used for non-sentineled arrays that have length fitting in u32, as well as |
| ... | @@ -1773,7 +1776,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -1773,7 +1776,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 1773 | return .{ .ptr_type = .{ | 1776 | return .{ .ptr_type = .{ |
| 1774 | .elem_type = ptr_info.child, | 1777 | .elem_type = ptr_info.child, |
| 1775 | .sentinel = ptr_info.sentinel, | 1778 | .sentinel = ptr_info.sentinel, |
| 1776 | .alignment = ptr_info.flags.alignment.toByteUnits(0), | 1779 | .alignment = ptr_info.flags.alignment, |
| 1777 | .size = ptr_info.flags.size, | 1780 | .size = ptr_info.flags.size, |
| 1778 | .is_const = ptr_info.flags.is_const, | 1781 | .is_const = ptr_info.flags.is_const, |
| 1779 | .is_volatile = ptr_info.flags.is_volatile, | 1782 | .is_volatile = ptr_info.flags.is_volatile, |
| ... | @@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType { | ... | @@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType { |
| 2013 | .return_type = type_function.data.return_type, | 2016 | .return_type = type_function.data.return_type, |
| 2014 | .comptime_bits = type_function.data.comptime_bits, | 2017 | .comptime_bits = type_function.data.comptime_bits, |
| 2015 | .noalias_bits = type_function.data.noalias_bits, | 2018 | .noalias_bits = type_function.data.noalias_bits, |
| 2016 | .alignment = type_function.data.flags.alignment.toByteUnits(0), | 2019 | .alignment = type_function.data.flags.alignment, |
| 2017 | .cc = type_function.data.flags.cc, | 2020 | .cc = type_function.data.flags.cc, |
| 2018 | .is_var_args = type_function.data.flags.is_var_args, | 2021 | .is_var_args = type_function.data.flags.is_var_args, |
| 2019 | .is_generic = type_function.data.flags.is_generic, | 2022 | .is_generic = type_function.data.flags.is_generic, |
| ... | @@ -2100,16 +2103,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -2100,16 +2103,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 2100 | return @intToEnum(Index, ip.items.len - 1); | 2103 | return @intToEnum(Index, ip.items.len - 1); |
| 2101 | } | 2104 | } |
| 2102 | 2105 | ||
| 2106 | const is_allowzero = ptr_type.is_allowzero or ptr_type.size == .C; | ||
| 2107 | |||
| 2103 | ip.items.appendAssumeCapacity(.{ | 2108 | ip.items.appendAssumeCapacity(.{ |
| 2104 | .tag = .type_pointer, | 2109 | .tag = .type_pointer, |
| 2105 | .data = try ip.addExtra(gpa, Pointer{ | 2110 | .data = try ip.addExtra(gpa, Pointer{ |
| 2106 | .child = ptr_type.elem_type, | 2111 | .child = ptr_type.elem_type, |
| 2107 | .sentinel = ptr_type.sentinel, | 2112 | .sentinel = ptr_type.sentinel, |
| 2108 | .flags = .{ | 2113 | .flags = .{ |
| 2109 | .alignment = Alignment.fromByteUnits(ptr_type.alignment), | 2114 | .alignment = ptr_type.alignment, |
| 2110 | .is_const = ptr_type.is_const, | 2115 | .is_const = ptr_type.is_const, |
| 2111 | .is_volatile = ptr_type.is_volatile, | 2116 | .is_volatile = ptr_type.is_volatile, |
| 2112 | .is_allowzero = ptr_type.is_allowzero, | 2117 | .is_allowzero = is_allowzero, |
| 2113 | .size = ptr_type.size, | 2118 | .size = ptr_type.size, |
| 2114 | .address_space = ptr_type.address_space, | 2119 | .address_space = ptr_type.address_space, |
| 2115 | .vector_index = ptr_type.vector_index, | 2120 | .vector_index = ptr_type.vector_index, |
| ... | @@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 2316 | .comptime_bits = func_type.comptime_bits, | 2321 | .comptime_bits = func_type.comptime_bits, |
| 2317 | .noalias_bits = func_type.noalias_bits, | 2322 | .noalias_bits = func_type.noalias_bits, |
| 2318 | .flags = .{ | 2323 | .flags = .{ |
| 2319 | .alignment = Alignment.fromByteUnits(func_type.alignment), | 2324 | .alignment = func_type.alignment, |
| 2320 | .cc = func_type.cc, | 2325 | .cc = func_type.cc, |
| 2321 | .is_var_args = func_type.is_var_args, | 2326 | .is_var_args = func_type.is_var_args, |
| 2322 | .is_generic = func_type.is_generic, | 2327 | .is_generic = func_type.is_generic, |
src/Module.zig+19-17| ... | @@ -6532,8 +6532,7 @@ pub fn populateTestFunctions( | ... | @@ -6532,8 +6532,7 @@ pub fn populateTestFunctions( |
| 6532 | try mod.ensureDeclAnalyzed(decl_index); | 6532 | try mod.ensureDeclAnalyzed(decl_index); |
| 6533 | } | 6533 | } |
| 6534 | const decl = mod.declPtr(decl_index); | 6534 | const decl = mod.declPtr(decl_index); |
| 6535 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 6535 | const tmp_test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod); |
| 6536 | const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod); | ||
| 6537 | 6536 | ||
| 6538 | const array_decl_index = d: { | 6537 | const array_decl_index = d: { |
| 6539 | // Add mod.test_functions to an array decl then make the test_functions | 6538 | // Add mod.test_functions to an array decl then make the test_functions |
| ... | @@ -6843,28 +6842,31 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type | ... | @@ -6843,28 +6842,31 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type |
| 6843 | } | 6842 | } |
| 6844 | 6843 | ||
| 6845 | pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | 6844 | pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6846 | if (child_type.ip_index == .none) { | ||
| 6847 | // TODO remove this after all types can be represented via the InternPool | ||
| 6848 | return Type.Tag.pointer.create(mod.tmp_hack_arena.allocator(), .{ | ||
| 6849 | .pointee_type = child_type, | ||
| 6850 | .@"addrspace" = .generic, | ||
| 6851 | }); | ||
| 6852 | } | ||
| 6853 | return ptrType(mod, .{ .elem_type = child_type.ip_index }); | 6845 | return ptrType(mod, .{ .elem_type = child_type.ip_index }); |
| 6854 | } | 6846 | } |
| 6855 | 6847 | ||
| 6856 | pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | 6848 | pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6857 | if (child_type.ip_index == .none) { | ||
| 6858 | // TODO remove this after all types can be represented via the InternPool | ||
| 6859 | return Type.Tag.pointer.create(mod.tmp_hack_arena.allocator(), .{ | ||
| 6860 | .pointee_type = child_type, | ||
| 6861 | .mutable = false, | ||
| 6862 | .@"addrspace" = .generic, | ||
| 6863 | }); | ||
| 6864 | } | ||
| 6865 | return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true }); | 6849 | return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true }); |
| 6866 | } | 6850 | } |
| 6867 | 6851 | ||
| 6852 | pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type { | ||
| 6853 | const info = ptr_ty.ptrInfoIp(mod.intern_pool); | ||
| 6854 | return mod.ptrType(.{ | ||
| 6855 | .elem_type = new_child.toIntern(), | ||
| 6856 | |||
| 6857 | .sentinel = info.sentinel, | ||
| 6858 | .alignment = info.alignment, | ||
| 6859 | .host_size = info.host_size, | ||
| 6860 | .bit_offset = info.bit_offset, | ||
| 6861 | .vector_index = info.vector_index, | ||
| 6862 | .size = info.size, | ||
| 6863 | .is_const = info.is_const, | ||
| 6864 | .is_volatile = info.is_volatile, | ||
| 6865 | .is_allowzero = info.is_allowzero, | ||
| 6866 | .address_space = info.address_space, | ||
| 6867 | }); | ||
| 6868 | } | ||
| 6869 | |||
| 6868 | pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type { | 6870 | pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type { |
| 6869 | return (try intern(mod, .{ .func_type = info })).toType(); | 6871 | return (try intern(mod, .{ .func_type = info })).toType(); |
| 6870 | } | 6872 | } |
src/Sema.zig+49-70| ... | @@ -9163,7 +9163,7 @@ fn funcCommon( | ... | @@ -9163,7 +9163,7 @@ fn funcCommon( |
| 9163 | .return_type = return_type.toIntern(), | 9163 | .return_type = return_type.toIntern(), |
| 9164 | .cc = cc_resolved, | 9164 | .cc = cc_resolved, |
| 9165 | .cc_is_generic = cc == null, | 9165 | .cc_is_generic = cc == null, |
| 9166 | .alignment = alignment orelse 0, | 9166 | .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none, |
| 9167 | .align_is_generic = alignment == null, | 9167 | .align_is_generic = alignment == null, |
| 9168 | .section_is_generic = section == .generic, | 9168 | .section_is_generic = section == .generic, |
| 9169 | .addrspace_is_generic = address_space == null, | 9169 | .addrspace_is_generic = address_space == null, |
| ... | @@ -17740,10 +17740,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17740,10 +17740,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17740 | extra_i += 1; | 17740 | extra_i += 1; |
| 17741 | const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src); | 17741 | const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src); |
| 17742 | const val = try sema.resolveConstValue(block, sentinel_src, coerced, "pointer sentinel value must be comptime-known"); | 17742 | const val = try sema.resolveConstValue(block, sentinel_src, coerced, "pointer sentinel value must be comptime-known"); |
| 17743 | break :blk val; | 17743 | break :blk val.toIntern(); |
| 17744 | } else null; | 17744 | } else .none; |
| 17745 | 17745 | ||
| 17746 | const abi_align: u32 = if (inst_data.flags.has_align) blk: { | 17746 | const abi_align: InternPool.Alignment = if (inst_data.flags.has_align) blk: { |
| 17747 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 17747 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 17748 | extra_i += 1; | 17748 | extra_i += 1; |
| 17749 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); | 17749 | const coerced = try sema.coerce(block, Type.u32, try sema.resolveInst(ref), align_src); |
| ... | @@ -17752,13 +17752,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17752,13 +17752,13 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17752 | // which case we can make this 0 without resolving it. | 17752 | // which case we can make this 0 without resolving it. |
| 17753 | if (val.castTag(.lazy_align)) |payload| { | 17753 | if (val.castTag(.lazy_align)) |payload| { |
| 17754 | if (payload.data.eql(elem_ty, sema.mod)) { | 17754 | if (payload.data.eql(elem_ty, sema.mod)) { |
| 17755 | break :blk 0; | 17755 | break :blk .none; |
| 17756 | } | 17756 | } |
| 17757 | } | 17757 | } |
| 17758 | const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?); | 17758 | const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?); |
| 17759 | try sema.validateAlign(block, align_src, abi_align); | 17759 | try sema.validateAlign(block, align_src, abi_align); |
| 17760 | break :blk abi_align; | 17760 | break :blk InternPool.Alignment.fromByteUnits(abi_align); |
| 17761 | } else 0; | 17761 | } else .none; |
| 17762 | 17762 | ||
| 17763 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { | 17763 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { |
| 17764 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); | 17764 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| ... | @@ -17789,7 +17789,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17789,7 +17789,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17789 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); | 17789 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); |
| 17790 | } | 17790 | } |
| 17791 | const fn_align = mod.typeToFunc(elem_ty).?.alignment; | 17791 | const fn_align = mod.typeToFunc(elem_ty).?.alignment; |
| 17792 | if (inst_data.flags.has_align and abi_align != 0 and fn_align != 0 and | 17792 | if (inst_data.flags.has_align and abi_align != .none and fn_align != .none and |
| 17793 | abi_align != fn_align) | 17793 | abi_align != fn_align) |
| 17794 | { | 17794 | { |
| 17795 | return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{}); | 17795 | return sema.fail(block, align_src, "function pointer alignment disagrees with function alignment", .{}); |
| ... | @@ -17815,16 +17815,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -17815,16 +17815,16 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17815 | } | 17815 | } |
| 17816 | } | 17816 | } |
| 17817 | 17817 | ||
| 17818 | const ty = try Type.ptr(sema.arena, sema.mod, .{ | 17818 | const ty = try mod.ptrType(.{ |
| 17819 | .pointee_type = elem_ty, | 17819 | .elem_type = elem_ty.toIntern(), |
| 17820 | .sentinel = sentinel, | 17820 | .sentinel = sentinel, |
| 17821 | .@"align" = abi_align, | 17821 | .alignment = abi_align, |
| 17822 | .@"addrspace" = address_space, | 17822 | .address_space = address_space, |
| 17823 | .bit_offset = bit_offset, | 17823 | .bit_offset = bit_offset, |
| 17824 | .host_size = host_size, | 17824 | .host_size = host_size, |
| 17825 | .mutable = inst_data.flags.is_mutable, | 17825 | .is_const = !inst_data.flags.is_mutable, |
| 17826 | .@"allowzero" = inst_data.flags.is_allowzero, | 17826 | .is_allowzero = inst_data.flags.is_allowzero, |
| 17827 | .@"volatile" = inst_data.flags.is_volatile, | 17827 | .is_volatile = inst_data.flags.is_volatile, |
| 17828 | .size = inst_data.size, | 17828 | .size = inst_data.size, |
| 17829 | }); | 17829 | }); |
| 17830 | return sema.addType(ty); | 17830 | return sema.addType(ty); |
| ... | @@ -18905,10 +18905,13 @@ fn zirReify( | ... | @@ -18905,10 +18905,13 @@ fn zirReify( |
| 18905 | if (!try sema.intFitsInType(alignment_val, Type.u32, null)) { | 18905 | if (!try sema.intFitsInType(alignment_val, Type.u32, null)) { |
| 18906 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 18906 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); |
| 18907 | } | 18907 | } |
| 18908 | const abi_align = @intCast(u29, (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?); | 18908 | |
| 18909 | const abi_align = InternPool.Alignment.fromByteUnits( | ||
| 18910 | (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?, | ||
| 18911 | ); | ||
| 18909 | 18912 | ||
| 18910 | const unresolved_elem_ty = child_val.toType(); | 18913 | const unresolved_elem_ty = child_val.toType(); |
| 18911 | const elem_ty = if (abi_align == 0) | 18914 | const elem_ty = if (abi_align == .none) |
| 18912 | unresolved_elem_ty | 18915 | unresolved_elem_ty |
| 18913 | else t: { | 18916 | else t: { |
| 18914 | const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty); | 18917 | const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty); |
| ... | @@ -18918,18 +18921,21 @@ fn zirReify( | ... | @@ -18918,18 +18921,21 @@ fn zirReify( |
| 18918 | 18921 | ||
| 18919 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); | 18922 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); |
| 18920 | 18923 | ||
| 18921 | var actual_sentinel: ?Value = null; | 18924 | const actual_sentinel: InternPool.Index = s: { |
| 18922 | if (!sentinel_val.isNull(mod)) { | 18925 | if (!sentinel_val.isNull(mod)) { |
| 18923 | if (ptr_size == .One or ptr_size == .C) { | 18926 | if (ptr_size == .One or ptr_size == .C) { |
| 18924 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); | 18927 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); |
| 18928 | } | ||
| 18929 | const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data; | ||
| 18930 | const ptr_ty = try Type.ptr(sema.arena, mod, .{ | ||
| 18931 | .@"addrspace" = .generic, | ||
| 18932 | .pointee_type = try elem_ty.copy(sema.arena), | ||
| 18933 | }); | ||
| 18934 | const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; | ||
| 18935 | break :s sent_val.toIntern(); | ||
| 18925 | } | 18936 | } |
| 18926 | const sentinel_ptr_val = sentinel_val.castTag(.opt_payload).?.data; | 18937 | break :s .none; |
| 18927 | const ptr_ty = try Type.ptr(sema.arena, mod, .{ | 18938 | }; |
| 18928 | .@"addrspace" = .generic, | ||
| 18929 | .pointee_type = try elem_ty.copy(sema.arena), | ||
| 18930 | }); | ||
| 18931 | actual_sentinel = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?; | ||
| 18932 | } | ||
| 18933 | 18939 | ||
| 18934 | if (elem_ty.zigTypeTag(mod) == .NoReturn) { | 18940 | if (elem_ty.zigTypeTag(mod) == .NoReturn) { |
| 18935 | return sema.fail(block, src, "pointer to noreturn not allowed", .{}); | 18941 | return sema.fail(block, src, "pointer to noreturn not allowed", .{}); |
| ... | @@ -18938,7 +18944,7 @@ fn zirReify( | ... | @@ -18938,7 +18944,7 @@ fn zirReify( |
| 18938 | return sema.fail(block, src, "function pointers must be single pointers", .{}); | 18944 | return sema.fail(block, src, "function pointers must be single pointers", .{}); |
| 18939 | } | 18945 | } |
| 18940 | const fn_align = mod.typeToFunc(elem_ty).?.alignment; | 18946 | const fn_align = mod.typeToFunc(elem_ty).?.alignment; |
| 18941 | if (abi_align != 0 and fn_align != 0 and | 18947 | if (abi_align != .none and fn_align != .none and |
| 18942 | abi_align != fn_align) | 18948 | abi_align != fn_align) |
| 18943 | { | 18949 | { |
| 18944 | return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{}); | 18950 | return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{}); |
| ... | @@ -18964,14 +18970,14 @@ fn zirReify( | ... | @@ -18964,14 +18970,14 @@ fn zirReify( |
| 18964 | } | 18970 | } |
| 18965 | } | 18971 | } |
| 18966 | 18972 | ||
| 18967 | const ty = try Type.ptr(sema.arena, mod, .{ | 18973 | const ty = try mod.ptrType(.{ |
| 18968 | .size = ptr_size, | 18974 | .size = ptr_size, |
| 18969 | .mutable = !is_const_val.toBool(mod), | 18975 | .is_const = is_const_val.toBool(mod), |
| 18970 | .@"volatile" = is_volatile_val.toBool(mod), | 18976 | .is_volatile = is_volatile_val.toBool(mod), |
| 18971 | .@"align" = abi_align, | 18977 | .alignment = abi_align, |
| 18972 | .@"addrspace" = mod.toEnum(std.builtin.AddressSpace, address_space_val), | 18978 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), |
| 18973 | .pointee_type = try elem_ty.copy(sema.arena), | 18979 | .elem_type = elem_ty.toIntern(), |
| 18974 | .@"allowzero" = is_allowzero_val.toBool(mod), | 18980 | .is_allowzero = is_allowzero_val.toBool(mod), |
| 18975 | .sentinel = actual_sentinel, | 18981 | .sentinel = actual_sentinel, |
| 18976 | }); | 18982 | }); |
| 18977 | return sema.addType(ty); | 18983 | return sema.addType(ty); |
| ... | @@ -19470,9 +19476,9 @@ fn zirReify( | ... | @@ -19470,9 +19476,9 @@ fn zirReify( |
| 19470 | } | 19476 | } |
| 19471 | const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod)); | 19477 | const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod)); |
| 19472 | if (alignment == target_util.defaultFunctionAlignment(target)) { | 19478 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 19473 | break :alignment 0; | 19479 | break :alignment .none; |
| 19474 | } else { | 19480 | } else { |
| 19475 | break :alignment alignment; | 19481 | break :alignment InternPool.Alignment.fromByteUnits(alignment); |
| 19476 | } | 19482 | } |
| 19477 | }; | 19483 | }; |
| 19478 | const return_type = return_type_val.optionalValue(mod) orelse | 19484 | const return_type = return_type_val.optionalValue(mod) orelse |
| ... | @@ -24291,8 +24297,7 @@ fn fieldPtr( | ... | @@ -24291,8 +24297,7 @@ fn fieldPtr( |
| 24291 | const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty; | 24297 | const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty; |
| 24292 | 24298 | ||
| 24293 | if (mem.eql(u8, field_name, "ptr")) { | 24299 | if (mem.eql(u8, field_name, "ptr")) { |
| 24294 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); | 24300 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); |
| 24295 | const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod); | ||
| 24296 | 24301 | ||
| 24297 | const result_ty = try Type.ptr(sema.arena, mod, .{ | 24302 | const result_ty = try Type.ptr(sema.arena, mod, .{ |
| 24298 | .pointee_type = slice_ptr_ty, | 24303 | .pointee_type = slice_ptr_ty, |
| ... | @@ -27914,7 +27919,7 @@ fn beginComptimePtrMutation( | ... | @@ -27914,7 +27919,7 @@ fn beginComptimePtrMutation( |
| 27914 | sema, | 27919 | sema, |
| 27915 | block, | 27920 | block, |
| 27916 | src, | 27921 | src, |
| 27917 | parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod), | 27922 | parent.ty.slicePtrFieldType(mod), |
| 27918 | &val_ptr.castTag(.slice).?.data.ptr, | 27923 | &val_ptr.castTag(.slice).?.data.ptr, |
| 27919 | ptr_elem_ty, | 27924 | ptr_elem_ty, |
| 27920 | parent.decl_ref_mut, | 27925 | parent.decl_ref_mut, |
| ... | @@ -27981,7 +27986,7 @@ fn beginComptimePtrMutation( | ... | @@ -27981,7 +27986,7 @@ fn beginComptimePtrMutation( |
| 27981 | sema, | 27986 | sema, |
| 27982 | block, | 27987 | block, |
| 27983 | src, | 27988 | src, |
| 27984 | parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod), | 27989 | parent.ty.slicePtrFieldType(mod), |
| 27985 | &val_ptr.castTag(.slice).?.data.ptr, | 27990 | &val_ptr.castTag(.slice).?.data.ptr, |
| 27986 | ptr_elem_ty, | 27991 | ptr_elem_ty, |
| 27987 | parent.decl_ref_mut, | 27992 | parent.decl_ref_mut, |
| ... | @@ -28363,7 +28368,7 @@ fn beginComptimePtrLoad( | ... | @@ -28363,7 +28368,7 @@ fn beginComptimePtrLoad( |
| 28363 | const slice_val = tv.val.castTag(.slice).?.data; | 28368 | const slice_val = tv.val.castTag(.slice).?.data; |
| 28364 | deref.pointee = switch (field_index) { | 28369 | deref.pointee = switch (field_index) { |
| 28365 | Value.Payload.Slice.ptr_index => TypedValue{ | 28370 | Value.Payload.Slice.ptr_index => TypedValue{ |
| 28366 | .ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod), | 28371 | .ty = field_ptr.container_ty.slicePtrFieldType(mod), |
| 28367 | .val = slice_val.ptr, | 28372 | .val = slice_val.ptr, |
| 28368 | }, | 28373 | }, |
| 28369 | Value.Payload.Slice.len_index => TypedValue{ | 28374 | Value.Payload.Slice.len_index => TypedValue{ |
| ... | @@ -29454,8 +29459,7 @@ fn analyzeSlicePtr( | ... | @@ -29454,8 +29459,7 @@ fn analyzeSlicePtr( |
| 29454 | slice_ty: Type, | 29459 | slice_ty: Type, |
| 29455 | ) CompileError!Air.Inst.Ref { | 29460 | ) CompileError!Air.Inst.Ref { |
| 29456 | const mod = sema.mod; | 29461 | const mod = sema.mod; |
| 29457 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); | 29462 | const result_ty = slice_ty.slicePtrFieldType(mod); |
| 29458 | const result_ty = slice_ty.slicePtrFieldType(buf, mod); | ||
| 29459 | if (try sema.resolveMaybeUndefVal(slice)) |val| { | 29463 | if (try sema.resolveMaybeUndefVal(slice)) |val| { |
| 29460 | if (val.isUndef(mod)) return sema.addConstUndef(result_ty); | 29464 | if (val.isUndef(mod)) return sema.addConstUndef(result_ty); |
| 29461 | return sema.addConstant(result_ty, val.slicePtr()); | 29465 | return sema.addConstant(result_ty, val.slicePtr()); |
| ... | @@ -31611,15 +31615,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -31611,15 +31615,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 31611 | .inferred_alloc_mut => unreachable, | 31615 | .inferred_alloc_mut => unreachable, |
| 31612 | .inferred_alloc_const => unreachable, | 31616 | .inferred_alloc_const => unreachable, |
| 31613 | 31617 | ||
| 31614 | .pointer => { | ||
| 31615 | const child_ty = ty.childType(mod); | ||
| 31616 | if (child_ty.zigTypeTag(mod) == .Fn) { | ||
| 31617 | return mod.typeToFunc(child_ty).?.is_generic; | ||
| 31618 | } else { | ||
| 31619 | return sema.resolveTypeRequiresComptime(child_ty); | ||
| 31620 | } | ||
| 31621 | }, | ||
| 31622 | |||
| 31623 | .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), | 31618 | .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), |
| 31624 | }, | 31619 | }, |
| 31625 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 31620 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | @@ -33048,7 +33043,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33048,7 +33043,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33048 | .error_set_merged, | 33043 | .error_set_merged, |
| 33049 | .error_union, | 33044 | .error_union, |
| 33050 | .error_set_inferred, | 33045 | .error_set_inferred, |
| 33051 | .pointer, | ||
| 33052 | => return null, | 33046 | => return null, |
| 33053 | 33047 | ||
| 33054 | .inferred_alloc_const => unreachable, | 33048 | .inferred_alloc_const => unreachable, |
| ... | @@ -33604,12 +33598,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { | ... | @@ -33604,12 +33598,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 33604 | }; | 33598 | }; |
| 33605 | 33599 | ||
| 33606 | switch (ty.tag()) { | 33600 | switch (ty.tag()) { |
| 33607 | .pointer => switch (ty.ptrSize(mod)) { | ||
| 33608 | .Slice => return null, | ||
| 33609 | .C => return ty.optionalChild(mod), | ||
| 33610 | else => return ty, | ||
| 33611 | }, | ||
| 33612 | |||
| 33613 | .inferred_alloc_const => unreachable, | 33601 | .inferred_alloc_const => unreachable, |
| 33614 | .inferred_alloc_mut => unreachable, | 33602 | .inferred_alloc_mut => unreachable, |
| 33615 | 33603 | ||
| ... | @@ -33638,15 +33626,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { | ... | @@ -33638,15 +33626,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 33638 | .inferred_alloc_mut => unreachable, | 33626 | .inferred_alloc_mut => unreachable, |
| 33639 | .inferred_alloc_const => unreachable, | 33627 | .inferred_alloc_const => unreachable, |
| 33640 | 33628 | ||
| 33641 | .pointer => { | ||
| 33642 | const child_ty = ty.childType(mod); | ||
| 33643 | if (child_ty.zigTypeTag(mod) == .Fn) { | ||
| 33644 | return mod.typeToFunc(child_ty).?.is_generic; | ||
| 33645 | } else { | ||
| 33646 | return sema.typeRequiresComptime(child_ty); | ||
| 33647 | } | ||
| 33648 | }, | ||
| 33649 | |||
| 33650 | .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()), | 33629 | .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()), |
| 33651 | }, | 33630 | }, |
| 33652 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 33631 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
src/arch/aarch64/CodeGen.zig+1-2| ... | @@ -3434,8 +3434,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3434,8 +3434,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3434 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 3434 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3435 | const slice_ty = self.typeOf(bin_op.lhs); | 3435 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3436 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 3436 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| 3437 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 3437 | const ptr_ty = slice_ty.slicePtrFieldType(mod); |
| 3438 | const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod); | ||
| 3439 | 3438 | ||
| 3440 | const slice_mcv = try self.resolveInst(bin_op.lhs); | 3439 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 3441 | const base_mcv = slicePtr(slice_mcv); | 3440 | const base_mcv = slicePtr(slice_mcv); |
src/arch/arm/CodeGen.zig+1-2| ... | @@ -2432,8 +2432,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2432,8 +2432,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2432 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 2432 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2433 | const slice_ty = self.typeOf(bin_op.lhs); | 2433 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2434 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | 2434 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| 2435 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2435 | const ptr_ty = slice_ty.slicePtrFieldType(mod); |
| 2436 | const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod); | ||
| 2437 | 2436 | ||
| 2438 | const slice_mcv = try self.resolveInst(bin_op.lhs); | 2437 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 2439 | const base_mcv = slicePtr(slice_mcv); | 2438 | const base_mcv = slicePtr(slice_mcv); |
src/arch/sparc64/CodeGen.zig+1-2| ... | @@ -2462,8 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2462,8 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2462 | const elem_ty = slice_ty.childType(mod); | 2462 | const elem_ty = slice_ty.childType(mod); |
| 2463 | const elem_size = elem_ty.abiSize(mod); | 2463 | const elem_size = elem_ty.abiSize(mod); |
| 2464 | 2464 | ||
| 2465 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2465 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| 2466 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | ||
| 2467 | 2466 | ||
| 2468 | const index_lock: ?RegisterLock = if (index_mcv == .register) | 2467 | const index_lock: ?RegisterLock = if (index_mcv == .register) |
| 2469 | self.register_manager.lockRegAssumeUnused(index_mcv.register) | 2468 | self.register_manager.lockRegAssumeUnused(index_mcv.register) |
src/arch/x86_64/CodeGen.zig+6-15| ... | @@ -4052,8 +4052,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { | ... | @@ -4052,8 +4052,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { |
| 4052 | 4052 | ||
| 4053 | const elem_ty = slice_ty.childType(mod); | 4053 | const elem_ty = slice_ty.childType(mod); |
| 4054 | const elem_size = elem_ty.abiSize(mod); | 4054 | const elem_size = elem_ty.abiSize(mod); |
| 4055 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4055 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| 4056 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | ||
| 4057 | 4056 | ||
| 4058 | const index_ty = self.typeOf(rhs); | 4057 | const index_ty = self.typeOf(rhs); |
| 4059 | const index_mcv = try self.resolveInst(rhs); | 4058 | const index_mcv = try self.resolveInst(rhs); |
| ... | @@ -4082,8 +4081,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4082,8 +4081,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4082 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 4081 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 4083 | const slice_ty = self.typeOf(bin_op.lhs); | 4082 | const slice_ty = self.typeOf(bin_op.lhs); |
| 4084 | 4083 | ||
| 4085 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4084 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); |
| 4086 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | ||
| 4087 | const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs); | 4085 | const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs); |
| 4088 | const dst_mcv = try self.allocRegOrMem(inst, false); | 4086 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4089 | try self.load(dst_mcv, slice_ptr_field_type, elem_ptr); | 4087 | try self.load(dst_mcv, slice_ptr_field_type, elem_ptr); |
| ... | @@ -4281,11 +4279,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4281,11 +4279,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { |
| 4281 | break :blk MCValue{ .register = reg }; | 4279 | break :blk MCValue{ .register = reg }; |
| 4282 | } else ptr; | 4280 | } else ptr; |
| 4283 | 4281 | ||
| 4284 | var ptr_tag_pl: Type.Payload.Pointer = .{ | 4282 | const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); |
| 4285 | .data = ptr_union_ty.ptrInfo(mod), | ||
| 4286 | }; | ||
| 4287 | ptr_tag_pl.data.pointee_type = tag_ty; | ||
| 4288 | const ptr_tag_ty = Type.initPayload(&ptr_tag_pl.base); | ||
| 4289 | try self.store(ptr_tag_ty, adjusted_ptr, tag); | 4283 | try self.store(ptr_tag_ty, adjusted_ptr, tag); |
| 4290 | 4284 | ||
| 4291 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); | 4285 | return self.finishAir(inst, .none, .{ bin_op.lhs, bin_op.rhs, .none }); |
| ... | @@ -8671,9 +8665,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC | ... | @@ -8671,9 +8665,8 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC |
| 8671 | 8665 | ||
| 8672 | const pl_ty = opt_ty.optionalChild(mod); | 8666 | const pl_ty = opt_ty.optionalChild(mod); |
| 8673 | 8667 | ||
| 8674 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 8675 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | 8668 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) |
| 8676 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty } | 8669 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } |
| 8677 | else | 8670 | else |
| 8678 | .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool }; | 8671 | .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool }; |
| 8679 | 8672 | ||
| ... | @@ -8763,9 +8756,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) | ... | @@ -8763,9 +8756,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) |
| 8763 | const opt_ty = ptr_ty.childType(mod); | 8756 | const opt_ty = ptr_ty.childType(mod); |
| 8764 | const pl_ty = opt_ty.optionalChild(mod); | 8757 | const pl_ty = opt_ty.optionalChild(mod); |
| 8765 | 8758 | ||
| 8766 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 8767 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) | 8759 | const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) |
| 8768 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty } | 8760 | .{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(mod) else pl_ty } |
| 8769 | else | 8761 | else |
| 8770 | .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool }; | 8762 | .{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool }; |
| 8771 | 8763 | ||
| ... | @@ -10803,8 +10795,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { | ... | @@ -10803,8 +10795,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { |
| 10803 | // here to elide it. | 10795 | // here to elide it. |
| 10804 | switch (dst_ptr_ty.ptrSize(mod)) { | 10796 | switch (dst_ptr_ty.ptrSize(mod)) { |
| 10805 | .Slice => { | 10797 | .Slice => { |
| 10806 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 10798 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(mod); |
| 10807 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod); | ||
| 10808 | 10799 | ||
| 10809 | // TODO: this only handles slices stored in the stack | 10800 | // TODO: this only handles slices stored in the stack |
| 10810 | const ptr = dst_ptr; | 10801 | const ptr = dst_ptr; |
src/codegen.zig+3-6| ... | @@ -347,8 +347,7 @@ pub fn generateSymbol( | ... | @@ -347,8 +347,7 @@ pub fn generateSymbol( |
| 347 | const slice = typed_value.val.castTag(.slice).?.data; | 347 | const slice = typed_value.val.castTag(.slice).?.data; |
| 348 | 348 | ||
| 349 | // generate ptr | 349 | // generate ptr |
| 350 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 350 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod); |
| 351 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod); | ||
| 352 | switch (try generateSymbol(bin_file, src_loc, .{ | 351 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 353 | .ty = slice_ptr_field_type, | 352 | .ty = slice_ptr_field_type, |
| 354 | .val = slice.ptr, | 353 | .val = slice.ptr, |
| ... | @@ -850,10 +849,9 @@ fn lowerParentPtr( | ... | @@ -850,10 +849,9 @@ fn lowerParentPtr( |
| 850 | reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) { | 849 | reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) { |
| 851 | .Pointer => offset: { | 850 | .Pointer => offset: { |
| 852 | assert(field_ptr.container_ty.isSlice(mod)); | 851 | assert(field_ptr.container_ty.isSlice(mod)); |
| 853 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 854 | break :offset switch (field_ptr.field_index) { | 852 | break :offset switch (field_ptr.field_index) { |
| 855 | 0 => 0, | 853 | 0 => 0, |
| 856 | 1 => field_ptr.container_ty.slicePtrFieldType(&buf, mod).abiSize(mod), | 854 | 1 => field_ptr.container_ty.slicePtrFieldType(mod).abiSize(mod), |
| 857 | else => unreachable, | 855 | else => unreachable, |
| 858 | }; | 856 | }; |
| 859 | }, | 857 | }, |
| ... | @@ -952,8 +950,7 @@ fn lowerDeclRef( | ... | @@ -952,8 +950,7 @@ fn lowerDeclRef( |
| 952 | const mod = bin_file.options.module.?; | 950 | const mod = bin_file.options.module.?; |
| 953 | if (typed_value.ty.isSlice(mod)) { | 951 | if (typed_value.ty.isSlice(mod)) { |
| 954 | // generate ptr | 952 | // generate ptr |
| 955 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 953 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod); |
| 956 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod); | ||
| 957 | switch (try generateSymbol(bin_file, src_loc, .{ | 954 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 958 | .ty = slice_ptr_field_type, | 955 | .ty = slice_ptr_field_type, |
| 959 | .val = typed_value.val, | 956 | .val = typed_value.val, |
src/codegen/c.zig+15-41| ... | @@ -566,8 +566,7 @@ pub const DeclGen = struct { | ... | @@ -566,8 +566,7 @@ pub const DeclGen = struct { |
| 566 | try writer.writeAll("){ .ptr = "); | 566 | try writer.writeAll("){ .ptr = "); |
| 567 | } | 567 | } |
| 568 | 568 | ||
| 569 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 569 | try dg.renderValue(writer, ty.slicePtrFieldType(mod), val.slicePtr(), .Initializer); |
| 570 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer); | ||
| 571 | 570 | ||
| 572 | const len_val = try mod.intValue(Type.usize, val.sliceLen(mod)); | 571 | const len_val = try mod.intValue(Type.usize, val.sliceLen(mod)); |
| 573 | 572 | ||
| ... | @@ -631,11 +630,7 @@ pub const DeclGen = struct { | ... | @@ -631,11 +630,7 @@ pub const DeclGen = struct { |
| 631 | // Ensure complete type definition is visible before accessing fields. | 630 | // Ensure complete type definition is visible before accessing fields. |
| 632 | _ = try dg.typeToIndex(field_ptr.container_ty, .complete); | 631 | _ = try dg.typeToIndex(field_ptr.container_ty, .complete); |
| 633 | 632 | ||
| 634 | var container_ptr_pl: Type.Payload.Pointer = .{ | 633 | const container_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, field_ptr.container_ty); |
| 635 | .data = ptr_ty.ptrInfo(mod), | ||
| 636 | }; | ||
| 637 | container_ptr_pl.data.pointee_type = field_ptr.container_ty; | ||
| 638 | const container_ptr_ty = Type.initPayload(&container_ptr_pl.base); | ||
| 639 | 634 | ||
| 640 | switch (fieldLocation( | 635 | switch (fieldLocation( |
| 641 | field_ptr.container_ty, | 636 | field_ptr.container_ty, |
| ... | @@ -661,11 +656,7 @@ pub const DeclGen = struct { | ... | @@ -661,11 +656,7 @@ pub const DeclGen = struct { |
| 661 | try dg.writeCValue(writer, field); | 656 | try dg.writeCValue(writer, field); |
| 662 | }, | 657 | }, |
| 663 | .byte_offset => |byte_offset| { | 658 | .byte_offset => |byte_offset| { |
| 664 | var u8_ptr_pl: Type.Payload.Pointer = .{ | 659 | const u8_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, Type.u8); |
| 665 | .data = ptr_ty.ptrInfo(mod), | ||
| 666 | }; | ||
| 667 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 668 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 669 | 660 | ||
| 670 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); | 661 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); |
| 671 | 662 | ||
| ... | @@ -788,8 +779,7 @@ pub const DeclGen = struct { | ... | @@ -788,8 +779,7 @@ pub const DeclGen = struct { |
| 788 | } | 779 | } |
| 789 | 780 | ||
| 790 | try writer.writeAll("{("); | 781 | try writer.writeAll("{("); |
| 791 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 782 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 792 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | ||
| 793 | try dg.renderType(writer, ptr_ty); | 783 | try dg.renderType(writer, ptr_ty); |
| 794 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); | 784 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); |
| 795 | } else { | 785 | } else { |
| ... | @@ -1068,10 +1058,9 @@ pub const DeclGen = struct { | ... | @@ -1068,10 +1058,9 @@ pub const DeclGen = struct { |
| 1068 | } | 1058 | } |
| 1069 | 1059 | ||
| 1070 | const slice = val.castTag(.slice).?.data; | 1060 | const slice = val.castTag(.slice).?.data; |
| 1071 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 1072 | 1061 | ||
| 1073 | try writer.writeByte('{'); | 1062 | try writer.writeByte('{'); |
| 1074 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), slice.ptr, initializer_type); | 1063 | try dg.renderValue(writer, ty.slicePtrFieldType(mod), slice.ptr, initializer_type); |
| 1075 | try writer.writeAll(", "); | 1064 | try writer.writeAll(", "); |
| 1076 | try dg.renderValue(writer, Type.usize, slice.len, initializer_type); | 1065 | try dg.renderValue(writer, Type.usize, slice.len, initializer_type); |
| 1077 | try writer.writeByte('}'); | 1066 | try writer.writeByte('}'); |
| ... | @@ -1536,8 +1525,8 @@ pub const DeclGen = struct { | ... | @@ -1536,8 +1525,8 @@ pub const DeclGen = struct { |
| 1536 | 1525 | ||
| 1537 | switch (kind) { | 1526 | switch (kind) { |
| 1538 | .forward => {}, | 1527 | .forward => {}, |
| 1539 | .complete => if (fn_info.alignment > 0) | 1528 | .complete => if (fn_info.alignment.toByteUnitsOptional()) |a| |
| 1540 | try w.print(" zig_align_fn({})", .{fn_info.alignment}), | 1529 | try w.print(" zig_align_fn({})", .{a}), |
| 1541 | else => unreachable, | 1530 | else => unreachable, |
| 1542 | } | 1531 | } |
| 1543 | 1532 | ||
| ... | @@ -1561,8 +1550,8 @@ pub const DeclGen = struct { | ... | @@ -1561,8 +1550,8 @@ pub const DeclGen = struct { |
| 1561 | ); | 1550 | ); |
| 1562 | 1551 | ||
| 1563 | switch (kind) { | 1552 | switch (kind) { |
| 1564 | .forward => if (fn_info.alignment > 0) | 1553 | .forward => if (fn_info.alignment.toByteUnitsOptional()) |a| |
| 1565 | try w.print(" zig_align_fn({})", .{fn_info.alignment}), | 1554 | try w.print(" zig_align_fn({})", .{a}), |
| 1566 | .complete => {}, | 1555 | .complete => {}, |
| 1567 | else => unreachable, | 1556 | else => unreachable, |
| 1568 | } | 1557 | } |
| ... | @@ -4062,8 +4051,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4062,8 +4051,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4062 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 4051 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 4063 | 4052 | ||
| 4064 | const inst_ty = f.typeOfIndex(inst); | 4053 | const inst_ty = f.typeOfIndex(inst); |
| 4065 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4054 | const ptr_ty = inst_ty.slicePtrFieldType(mod); |
| 4066 | const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod); | ||
| 4067 | 4055 | ||
| 4068 | const writer = f.object.writer(); | 4056 | const writer = f.object.writer(); |
| 4069 | const local = try f.allocLocal(inst, inst_ty); | 4057 | const local = try f.allocLocal(inst, inst_ty); |
| ... | @@ -5047,7 +5035,6 @@ fn airIsNull( | ... | @@ -5047,7 +5035,6 @@ fn airIsNull( |
| 5047 | const operand_ty = f.typeOf(un_op); | 5035 | const operand_ty = f.typeOf(un_op); |
| 5048 | const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; | 5036 | const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; |
| 5049 | const payload_ty = optional_ty.optionalChild(mod); | 5037 | const payload_ty = optional_ty.optionalChild(mod); |
| 5050 | var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 5051 | 5038 | ||
| 5052 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) | 5039 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) |
| 5053 | TypedValue{ .ty = Type.bool, .val = Value.true } | 5040 | TypedValue{ .ty = Type.bool, .val = Value.true } |
| ... | @@ -5058,7 +5045,7 @@ fn airIsNull( | ... | @@ -5058,7 +5045,7 @@ fn airIsNull( |
| 5058 | TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) } | 5045 | TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) } |
| 5059 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { | 5046 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { |
| 5060 | try writer.writeAll(".ptr"); | 5047 | try writer.writeAll(".ptr"); |
| 5061 | const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod); | 5048 | const slice_ptr_ty = payload_ty.slicePtrFieldType(mod); |
| 5062 | break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null }; | 5049 | break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null }; |
| 5063 | } else rhs: { | 5050 | } else rhs: { |
| 5064 | try writer.writeAll(".is_null"); | 5051 | try writer.writeAll(".is_null"); |
| ... | @@ -5278,11 +5265,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5278,11 +5265,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5278 | switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) { | 5265 | switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) { |
| 5279 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), | 5266 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), |
| 5280 | .field => |field| { | 5267 | .field => |field| { |
| 5281 | var u8_ptr_pl: Type.Payload.Pointer = .{ | 5268 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5282 | .data = field_ptr_ty.ptrInfo(mod), | ||
| 5283 | }; | ||
| 5284 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 5285 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 5286 | 5269 | ||
| 5287 | try writer.writeAll("(("); | 5270 | try writer.writeAll("(("); |
| 5288 | try f.renderType(writer, u8_ptr_ty); | 5271 | try f.renderType(writer, u8_ptr_ty); |
| ... | @@ -5295,11 +5278,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5295,11 +5278,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5295 | try writer.writeAll("))"); | 5278 | try writer.writeAll("))"); |
| 5296 | }, | 5279 | }, |
| 5297 | .byte_offset => |byte_offset| { | 5280 | .byte_offset => |byte_offset| { |
| 5298 | var u8_ptr_pl: Type.Payload.Pointer = .{ | 5281 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5299 | .data = field_ptr_ty.ptrInfo(mod), | ||
| 5300 | }; | ||
| 5301 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 5302 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 5303 | 5282 | ||
| 5304 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); | 5283 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); |
| 5305 | 5284 | ||
| ... | @@ -5347,11 +5326,7 @@ fn fieldPtr( | ... | @@ -5347,11 +5326,7 @@ fn fieldPtr( |
| 5347 | try f.writeCValueDerefMember(writer, container_ptr_val, field); | 5326 | try f.writeCValueDerefMember(writer, container_ptr_val, field); |
| 5348 | }, | 5327 | }, |
| 5349 | .byte_offset => |byte_offset| { | 5328 | .byte_offset => |byte_offset| { |
| 5350 | var u8_ptr_pl: Type.Payload.Pointer = .{ | 5329 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); |
| 5351 | .data = field_ptr_ty.ptrInfo(mod), | ||
| 5352 | }; | ||
| 5353 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 5354 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 5355 | 5330 | ||
| 5356 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); | 5331 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); |
| 5357 | 5332 | ||
| ... | @@ -5794,8 +5769,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5794,8 +5769,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5794 | // Unfortunately, C does not support any equivalent to | 5769 | // Unfortunately, C does not support any equivalent to |
| 5795 | // &(*(void *)p)[0], although LLVM does via GetElementPtr | 5770 | // &(*(void *)p)[0], although LLVM does via GetElementPtr |
| 5796 | if (operand == .undef) { | 5771 | if (operand == .undef) { |
| 5797 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 5772 | try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(mod) }, .Initializer); |
| 5798 | try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer); | ||
| 5799 | } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5773 | } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5800 | try writer.writeAll("&("); | 5774 | try writer.writeAll("&("); |
| 5801 | try f.writeCValueDeref(writer, operand); | 5775 | try f.writeCValueDeref(writer, operand); |
src/codegen/c/type.zig+1-2| ... | @@ -1431,8 +1431,7 @@ pub const CType = extern union { | ... | @@ -1431,8 +1431,7 @@ pub const CType = extern union { |
| 1431 | .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward), | 1431 | .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward), |
| 1432 | .payload => unreachable, | 1432 | .payload => unreachable, |
| 1433 | }) |fwd_idx| { | 1433 | }) |fwd_idx| { |
| 1434 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 1434 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 1435 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | ||
| 1436 | if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| { | 1435 | if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| { |
| 1437 | self.storage = .{ .anon = undefined }; | 1436 | self.storage = .{ .anon = undefined }; |
| 1438 | self.storage.anon.fields[0] = .{ | 1437 | self.storage.anon.fields[0] = .{ |
src/codegen/llvm.zig+45-74| ... | @@ -1591,40 +1591,30 @@ pub const Object = struct { | ... | @@ -1591,40 +1591,30 @@ pub const Object = struct { |
| 1591 | }, | 1591 | }, |
| 1592 | .Pointer => { | 1592 | .Pointer => { |
| 1593 | // Normalize everything that the debug info does not represent. | 1593 | // Normalize everything that the debug info does not represent. |
| 1594 | const ptr_info = ty.ptrInfo(mod); | 1594 | const ptr_info = ty.ptrInfoIp(mod.intern_pool); |
| 1595 | 1595 | ||
| 1596 | if (ptr_info.sentinel != null or | 1596 | if (ptr_info.sentinel != .none or |
| 1597 | ptr_info.@"addrspace" != .generic or | 1597 | ptr_info.address_space != .generic or |
| 1598 | ptr_info.bit_offset != 0 or | 1598 | ptr_info.bit_offset != 0 or |
| 1599 | ptr_info.host_size != 0 or | 1599 | ptr_info.host_size != 0 or |
| 1600 | ptr_info.vector_index != .none or | 1600 | ptr_info.vector_index != .none or |
| 1601 | ptr_info.@"allowzero" or | 1601 | ptr_info.is_allowzero or |
| 1602 | !ptr_info.mutable or | 1602 | ptr_info.is_const or |
| 1603 | ptr_info.@"volatile" or | 1603 | ptr_info.is_volatile or |
| 1604 | ptr_info.size == .Many or ptr_info.size == .C or | 1604 | ptr_info.size == .Many or ptr_info.size == .C or |
| 1605 | !ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) | 1605 | !ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod)) |
| 1606 | { | 1606 | { |
| 1607 | var payload: Type.Payload.Pointer = .{ | 1607 | const bland_ptr_ty = try mod.ptrType(.{ |
| 1608 | .data = .{ | 1608 | .elem_type = if (!ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod)) |
| 1609 | .pointee_type = ptr_info.pointee_type, | 1609 | .anyopaque_type |
| 1610 | .sentinel = null, | 1610 | else |
| 1611 | .@"align" = ptr_info.@"align", | 1611 | ptr_info.elem_type, |
| 1612 | .@"addrspace" = .generic, | 1612 | .alignment = ptr_info.alignment, |
| 1613 | .bit_offset = 0, | 1613 | .size = switch (ptr_info.size) { |
| 1614 | .host_size = 0, | 1614 | .Many, .C, .One => .One, |
| 1615 | .@"allowzero" = false, | 1615 | .Slice => .Slice, |
| 1616 | .mutable = true, | ||
| 1617 | .@"volatile" = false, | ||
| 1618 | .size = switch (ptr_info.size) { | ||
| 1619 | .Many, .C, .One => .One, | ||
| 1620 | .Slice => .Slice, | ||
| 1621 | }, | ||
| 1622 | }, | 1616 | }, |
| 1623 | }; | 1617 | }); |
| 1624 | if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) { | ||
| 1625 | payload.data.pointee_type = Type.anyopaque; | ||
| 1626 | } | ||
| 1627 | const bland_ptr_ty = Type.initPayload(&payload.base); | ||
| 1628 | const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); | 1618 | const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); |
| 1629 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. | 1619 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1630 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module }); | 1620 | try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module }); |
| ... | @@ -1632,8 +1622,7 @@ pub const Object = struct { | ... | @@ -1632,8 +1622,7 @@ pub const Object = struct { |
| 1632 | } | 1622 | } |
| 1633 | 1623 | ||
| 1634 | if (ty.isSlice(mod)) { | 1624 | if (ty.isSlice(mod)) { |
| 1635 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 1625 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 1636 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | ||
| 1637 | const len_ty = Type.usize; | 1626 | const len_ty = Type.usize; |
| 1638 | 1627 | ||
| 1639 | const name = try ty.nameAlloc(gpa, o.module); | 1628 | const name = try ty.nameAlloc(gpa, o.module); |
| ... | @@ -1711,7 +1700,7 @@ pub const Object = struct { | ... | @@ -1711,7 +1700,7 @@ pub const Object = struct { |
| 1711 | return full_di_ty; | 1700 | return full_di_ty; |
| 1712 | } | 1701 | } |
| 1713 | 1702 | ||
| 1714 | const elem_di_ty = try o.lowerDebugType(ptr_info.pointee_type, .fwd); | 1703 | const elem_di_ty = try o.lowerDebugType(ptr_info.elem_type.toType(), .fwd); |
| 1715 | const name = try ty.nameAlloc(gpa, o.module); | 1704 | const name = try ty.nameAlloc(gpa, o.module); |
| 1716 | defer gpa.free(name); | 1705 | defer gpa.free(name); |
| 1717 | const ptr_di_ty = dib.createPointerType( | 1706 | const ptr_di_ty = dib.createPointerType( |
| ... | @@ -2625,8 +2614,8 @@ pub const DeclGen = struct { | ... | @@ -2625,8 +2614,8 @@ pub const DeclGen = struct { |
| 2625 | }, | 2614 | }, |
| 2626 | } | 2615 | } |
| 2627 | 2616 | ||
| 2628 | if (fn_info.alignment != 0) { | 2617 | if (fn_info.alignment.toByteUnitsOptional()) |a| { |
| 2629 | llvm_fn.setAlignment(@intCast(c_uint, fn_info.alignment)); | 2618 | llvm_fn.setAlignment(@intCast(c_uint, a)); |
| 2630 | } | 2619 | } |
| 2631 | 2620 | ||
| 2632 | // Function attributes that are independent of analysis results of the function body. | 2621 | // Function attributes that are independent of analysis results of the function body. |
| ... | @@ -2819,8 +2808,7 @@ pub const DeclGen = struct { | ... | @@ -2819,8 +2808,7 @@ pub const DeclGen = struct { |
| 2819 | .Bool => return dg.context.intType(1), | 2808 | .Bool => return dg.context.intType(1), |
| 2820 | .Pointer => { | 2809 | .Pointer => { |
| 2821 | if (t.isSlice(mod)) { | 2810 | if (t.isSlice(mod)) { |
| 2822 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2811 | const ptr_type = t.slicePtrFieldType(mod); |
| 2823 | const ptr_type = t.slicePtrFieldType(&buf, mod); | ||
| 2824 | 2812 | ||
| 2825 | const fields: [2]*llvm.Type = .{ | 2813 | const fields: [2]*llvm.Type = .{ |
| 2826 | try dg.lowerType(ptr_type), | 2814 | try dg.lowerType(ptr_type), |
| ... | @@ -3176,11 +3164,10 @@ pub const DeclGen = struct { | ... | @@ -3176,11 +3164,10 @@ pub const DeclGen = struct { |
| 3176 | }, | 3164 | }, |
| 3177 | .slice => { | 3165 | .slice => { |
| 3178 | const param_ty = fn_info.param_types[it.zig_index - 1].toType(); | 3166 | const param_ty = fn_info.param_types[it.zig_index - 1].toType(); |
| 3179 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 3180 | const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional) | 3167 | const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional) |
| 3181 | param_ty.optionalChild(mod).slicePtrFieldType(&buf, mod) | 3168 | param_ty.optionalChild(mod).slicePtrFieldType(mod) |
| 3182 | else | 3169 | else |
| 3183 | param_ty.slicePtrFieldType(&buf, mod); | 3170 | param_ty.slicePtrFieldType(mod); |
| 3184 | const ptr_llvm_ty = try dg.lowerType(ptr_ty); | 3171 | const ptr_llvm_ty = try dg.lowerType(ptr_ty); |
| 3185 | const len_llvm_ty = try dg.lowerType(Type.usize); | 3172 | const len_llvm_ty = try dg.lowerType(Type.usize); |
| 3186 | 3173 | ||
| ... | @@ -3368,10 +3355,9 @@ pub const DeclGen = struct { | ... | @@ -3368,10 +3355,9 @@ pub const DeclGen = struct { |
| 3368 | }, | 3355 | }, |
| 3369 | .slice => { | 3356 | .slice => { |
| 3370 | const slice = tv.val.castTag(.slice).?.data; | 3357 | const slice = tv.val.castTag(.slice).?.data; |
| 3371 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 3372 | const fields: [2]*llvm.Value = .{ | 3358 | const fields: [2]*llvm.Value = .{ |
| 3373 | try dg.lowerValue(.{ | 3359 | try dg.lowerValue(.{ |
| 3374 | .ty = tv.ty.slicePtrFieldType(&buf, mod), | 3360 | .ty = tv.ty.slicePtrFieldType(mod), |
| 3375 | .val = slice.ptr, | 3361 | .val = slice.ptr, |
| 3376 | }), | 3362 | }), |
| 3377 | try dg.lowerValue(.{ | 3363 | try dg.lowerValue(.{ |
| ... | @@ -4171,8 +4157,7 @@ pub const DeclGen = struct { | ... | @@ -4171,8 +4157,7 @@ pub const DeclGen = struct { |
| 4171 | ) Error!*llvm.Value { | 4157 | ) Error!*llvm.Value { |
| 4172 | const mod = self.module; | 4158 | const mod = self.module; |
| 4173 | if (tv.ty.isSlice(mod)) { | 4159 | if (tv.ty.isSlice(mod)) { |
| 4174 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4160 | const ptr_ty = tv.ty.slicePtrFieldType(mod); |
| 4175 | const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod); | ||
| 4176 | const fields: [2]*llvm.Value = .{ | 4161 | const fields: [2]*llvm.Value = .{ |
| 4177 | try self.lowerValue(.{ | 4162 | try self.lowerValue(.{ |
| 4178 | .ty = ptr_ty, | 4163 | .ty = ptr_ty, |
| ... | @@ -6043,17 +6028,14 @@ pub const FuncGen = struct { | ... | @@ -6043,17 +6028,14 @@ pub const FuncGen = struct { |
| 6043 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); | 6028 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 6044 | const field_ptr_ty = try mod.ptrType(.{ | 6029 | const field_ptr_ty = try mod.ptrType(.{ |
| 6045 | .elem_type = llvm_field.ty.ip_index, | 6030 | .elem_type = llvm_field.ty.ip_index, |
| 6046 | .alignment = llvm_field.alignment, | 6031 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), |
| 6047 | }); | 6032 | }); |
| 6048 | if (isByRef(field_ty, mod)) { | 6033 | if (isByRef(field_ty, mod)) { |
| 6049 | if (canElideLoad(self, body_tail)) | 6034 | if (canElideLoad(self, body_tail)) |
| 6050 | return field_ptr; | 6035 | return field_ptr; |
| 6051 | 6036 | ||
| 6052 | const field_alignment = if (llvm_field.alignment != 0) | 6037 | assert(llvm_field.alignment != 0); |
| 6053 | llvm_field.alignment | 6038 | return self.loadByRef(field_ptr, field_ty, llvm_field.alignment, false); |
| 6054 | else | ||
| 6055 | llvm_field.ty.abiAlignment(mod); | ||
| 6056 | return self.loadByRef(field_ptr, field_ty, field_alignment, false); | ||
| 6057 | } else { | 6039 | } else { |
| 6058 | return self.load(field_ptr, field_ptr_ty); | 6040 | return self.load(field_ptr, field_ptr_ty); |
| 6059 | } | 6041 | } |
| ... | @@ -6151,7 +6133,7 @@ pub const FuncGen = struct { | ... | @@ -6151,7 +6133,7 @@ pub const FuncGen = struct { |
| 6151 | const fn_ty = try mod.funcType(.{ | 6133 | const fn_ty = try mod.funcType(.{ |
| 6152 | .param_types = &.{}, | 6134 | .param_types = &.{}, |
| 6153 | .return_type = .void_type, | 6135 | .return_type = .void_type, |
| 6154 | .alignment = 0, | 6136 | .alignment = .none, |
| 6155 | .noalias_bits = 0, | 6137 | .noalias_bits = 0, |
| 6156 | .comptime_bits = 0, | 6138 | .comptime_bits = 0, |
| 6157 | .cc = .Unspecified, | 6139 | .cc = .Unspecified, |
| ... | @@ -6655,8 +6637,7 @@ pub const FuncGen = struct { | ... | @@ -6655,8 +6637,7 @@ pub const FuncGen = struct { |
| 6655 | operand; | 6637 | operand; |
| 6656 | if (payload_ty.isSlice(mod)) { | 6638 | if (payload_ty.isSlice(mod)) { |
| 6657 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); | 6639 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); |
| 6658 | var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 6640 | const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(mod)); |
| 6659 | const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod)); | ||
| 6660 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); | 6641 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); |
| 6661 | } | 6642 | } |
| 6662 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); | 6643 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| ... | @@ -6923,7 +6904,7 @@ pub const FuncGen = struct { | ... | @@ -6923,7 +6904,7 @@ pub const FuncGen = struct { |
| 6923 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); | 6904 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 6924 | const field_ptr_ty = try mod.ptrType(.{ | 6905 | const field_ptr_ty = try mod.ptrType(.{ |
| 6925 | .elem_type = llvm_field.ty.ip_index, | 6906 | .elem_type = llvm_field.ty.ip_index, |
| 6926 | .alignment = llvm_field.alignment, | 6907 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), |
| 6927 | }); | 6908 | }); |
| 6928 | return self.load(field_ptr, field_ptr_ty); | 6909 | return self.load(field_ptr, field_ptr_ty); |
| 6929 | } | 6910 | } |
| ... | @@ -9319,14 +9300,12 @@ pub const FuncGen = struct { | ... | @@ -9319,14 +9300,12 @@ pub const FuncGen = struct { |
| 9319 | const llvm_i = llvmField(result_ty, i, mod).?.index; | 9300 | const llvm_i = llvmField(result_ty, i, mod).?.index; |
| 9320 | indices[1] = llvm_u32.constInt(llvm_i, .False); | 9301 | indices[1] = llvm_u32.constInt(llvm_i, .False); |
| 9321 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); | 9302 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 9322 | var field_ptr_payload: Type.Payload.Pointer = .{ | 9303 | const field_ptr_ty = try mod.ptrType(.{ |
| 9323 | .data = .{ | 9304 | .elem_type = self.typeOf(elem).toIntern(), |
| 9324 | .pointee_type = self.typeOf(elem), | 9305 | .alignment = InternPool.Alignment.fromNonzeroByteUnits( |
| 9325 | .@"align" = result_ty.structFieldAlign(i, mod), | 9306 | result_ty.structFieldAlign(i, mod), |
| 9326 | .@"addrspace" = .generic, | 9307 | ), |
| 9327 | }, | 9308 | }); |
| 9328 | }; | ||
| 9329 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | ||
| 9330 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); | 9309 | try self.store(field_ptr, field_ptr_ty, llvm_elem, .NotAtomic); |
| 9331 | } | 9310 | } |
| 9332 | 9311 | ||
| ... | @@ -9350,13 +9329,9 @@ pub const FuncGen = struct { | ... | @@ -9350,13 +9329,9 @@ pub const FuncGen = struct { |
| 9350 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); | 9329 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); |
| 9351 | 9330 | ||
| 9352 | const array_info = result_ty.arrayInfo(mod); | 9331 | const array_info = result_ty.arrayInfo(mod); |
| 9353 | var elem_ptr_payload: Type.Payload.Pointer = .{ | 9332 | const elem_ptr_ty = try mod.ptrType(.{ |
| 9354 | .data = .{ | 9333 | .elem_type = array_info.elem_type.toIntern(), |
| 9355 | .pointee_type = array_info.elem_type, | 9334 | }); |
| 9356 | .@"addrspace" = .generic, | ||
| 9357 | }, | ||
| 9358 | }; | ||
| 9359 | const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); | ||
| 9360 | 9335 | ||
| 9361 | for (elements, 0..) |elem, i| { | 9336 | for (elements, 0..) |elem, i| { |
| 9362 | const indices: [2]*llvm.Value = .{ | 9337 | const indices: [2]*llvm.Value = .{ |
| ... | @@ -9476,14 +9451,10 @@ pub const FuncGen = struct { | ... | @@ -9476,14 +9451,10 @@ pub const FuncGen = struct { |
| 9476 | // tag and the payload. | 9451 | // tag and the payload. |
| 9477 | const index_type = self.context.intType(32); | 9452 | const index_type = self.context.intType(32); |
| 9478 | 9453 | ||
| 9479 | var field_ptr_payload: Type.Payload.Pointer = .{ | 9454 | const field_ptr_ty = try mod.ptrType(.{ |
| 9480 | .data = .{ | 9455 | .elem_type = field.ty.toIntern(), |
| 9481 | .pointee_type = field.ty, | 9456 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(field_align), |
| 9482 | .@"align" = field_align, | 9457 | }); |
| 9483 | .@"addrspace" = .generic, | ||
| 9484 | }, | ||
| 9485 | }; | ||
| 9486 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | ||
| 9487 | if (layout.tag_size == 0) { | 9458 | if (layout.tag_size == 0) { |
| 9488 | const indices: [3]*llvm.Value = .{ | 9459 | const indices: [3]*llvm.Value = .{ |
| 9489 | index_type.constNull(), | 9460 | index_type.constNull(), |
src/codegen/spirv.zig+2-4| ... | @@ -669,8 +669,7 @@ pub const DeclGen = struct { | ... | @@ -669,8 +669,7 @@ pub const DeclGen = struct { |
| 669 | .slice => { | 669 | .slice => { |
| 670 | const slice = val.castTag(.slice).?.data; | 670 | const slice = val.castTag(.slice).?.data; |
| 671 | 671 | ||
| 672 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 672 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 673 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | ||
| 674 | 673 | ||
| 675 | try self.lower(ptr_ty, slice.ptr); | 674 | try self.lower(ptr_ty, slice.ptr); |
| 676 | try self.addInt(Type.usize, slice.len); | 675 | try self.addInt(Type.usize, slice.len); |
| ... | @@ -2991,9 +2990,8 @@ pub const DeclGen = struct { | ... | @@ -2991,9 +2990,8 @@ pub const DeclGen = struct { |
| 2991 | if (optional_ty.optionalReprIsPayload(mod)) { | 2990 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 2992 | // Pointer payload represents nullability: pointer or slice. | 2991 | // Pointer payload represents nullability: pointer or slice. |
| 2993 | 2992 | ||
| 2994 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 2995 | const ptr_ty = if (payload_ty.isSlice(mod)) | 2993 | const ptr_ty = if (payload_ty.isSlice(mod)) |
| 2996 | payload_ty.slicePtrFieldType(&ptr_buf, mod) | 2994 | payload_ty.slicePtrFieldType(mod) |
| 2997 | else | 2995 | else |
| 2998 | payload_ty; | 2996 | payload_ty; |
| 2999 | 2997 |
src/link/Dwarf.zig+1-2| ... | @@ -277,8 +277,7 @@ pub const DeclState = struct { | ... | @@ -277,8 +277,7 @@ pub const DeclState = struct { |
| 277 | // DW.AT.type, DW.FORM.ref4 | 277 | // DW.AT.type, DW.FORM.ref4 |
| 278 | var index = dbg_info_buffer.items.len; | 278 | var index = dbg_info_buffer.items.len; |
| 279 | try dbg_info_buffer.resize(index + 4); | 279 | try dbg_info_buffer.resize(index + 4); |
| 280 | var buf = try arena.create(Type.SlicePtrFieldTypeBuffer); | 280 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 281 | const ptr_ty = ty.slicePtrFieldType(buf, mod); | ||
| 282 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index)); | 281 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index)); |
| 283 | // DW.AT.data_member_location, DW.FORM.udata | 282 | // DW.AT.data_member_location, DW.FORM.udata |
| 284 | try dbg_info_buffer.ensureUnusedCapacity(6); | 283 | try dbg_info_buffer.ensureUnusedCapacity(6); |
src/type.zig+117-403| ... | @@ -42,7 +42,6 @@ pub const Type = struct { | ... | @@ -42,7 +42,6 @@ pub const Type = struct { |
| 42 | .error_set_merged, | 42 | .error_set_merged, |
| 43 | => return .ErrorSet, | 43 | => return .ErrorSet, |
| 44 | 44 | ||
| 45 | .pointer, | ||
| 46 | .inferred_alloc_const, | 45 | .inferred_alloc_const, |
| 47 | .inferred_alloc_mut, | 46 | .inferred_alloc_mut, |
| 48 | => return .Pointer, | 47 | => return .Pointer, |
| ... | @@ -250,17 +249,9 @@ pub const Type = struct { | ... | @@ -250,17 +249,9 @@ pub const Type = struct { |
| 250 | return elem_ty; | 249 | return elem_ty; |
| 251 | } | 250 | } |
| 252 | 251 | ||
| 252 | /// Asserts the type is a pointer. | ||
| 253 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { | 253 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { |
| 254 | return switch (ty.ip_index) { | 254 | return !mod.intern_pool.indexToKey(ty.ip_index).ptr_type.is_const; |
| 255 | .none => switch (ty.tag()) { | ||
| 256 | .pointer => ty.castTag(.pointer).?.data.mutable, | ||
| 257 | else => unreachable, | ||
| 258 | }, | ||
| 259 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 260 | .ptr_type => |ptr_type| !ptr_type.is_const, | ||
| 261 | else => unreachable, | ||
| 262 | }, | ||
| 263 | }; | ||
| 264 | } | 255 | } |
| 265 | 256 | ||
| 266 | pub const ArrayInfo = struct { | 257 | pub const ArrayInfo = struct { |
| ... | @@ -277,24 +268,21 @@ pub const Type = struct { | ... | @@ -277,24 +268,21 @@ pub const Type = struct { |
| 277 | }; | 268 | }; |
| 278 | } | 269 | } |
| 279 | 270 | ||
| 280 | pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data { | 271 | pub fn ptrInfoIp(ty: Type, ip: InternPool) InternPool.Key.PtrType { |
| 281 | return switch (ty.ip_index) { | 272 | return switch (ip.indexToKey(ty.ip_index)) { |
| 282 | .none => switch (ty.tag()) { | 273 | .ptr_type => |p| p, |
| 283 | .pointer => ty.castTag(.pointer).?.data, | 274 | .opt_type => |child| switch (ip.indexToKey(child)) { |
| 284 | 275 | .ptr_type => |p| p, | |
| 285 | else => unreachable, | ||
| 286 | }, | ||
| 287 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 288 | .ptr_type => |p| Payload.Pointer.Data.fromKey(p), | ||
| 289 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | ||
| 290 | .ptr_type => |p| Payload.Pointer.Data.fromKey(p), | ||
| 291 | else => unreachable, | ||
| 292 | }, | ||
| 293 | else => unreachable, | 276 | else => unreachable, |
| 294 | }, | 277 | }, |
| 278 | else => unreachable, | ||
| 295 | }; | 279 | }; |
| 296 | } | 280 | } |
| 297 | 281 | ||
| 282 | pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data { | ||
| 283 | return Payload.Pointer.Data.fromKey(ptrInfoIp(ty, mod.intern_pool)); | ||
| 284 | } | ||
| 285 | |||
| 298 | pub fn eql(a: Type, b: Type, mod: *Module) bool { | 286 | pub fn eql(a: Type, b: Type, mod: *Module) bool { |
| 299 | if (a.ip_index != .none or b.ip_index != .none) { | 287 | if (a.ip_index != .none or b.ip_index != .none) { |
| 300 | // The InternPool data structure hashes based on Key to make interned objects | 288 | // The InternPool data structure hashes based on Key to make interned objects |
| ... | @@ -335,7 +323,6 @@ pub const Type = struct { | ... | @@ -335,7 +323,6 @@ pub const Type = struct { |
| 335 | return true; | 323 | return true; |
| 336 | }, | 324 | }, |
| 337 | 325 | ||
| 338 | .pointer, | ||
| 339 | .inferred_alloc_const, | 326 | .inferred_alloc_const, |
| 340 | .inferred_alloc_mut, | 327 | .inferred_alloc_mut, |
| 341 | => { | 328 | => { |
| ... | @@ -434,7 +421,6 @@ pub const Type = struct { | ... | @@ -434,7 +421,6 @@ pub const Type = struct { |
| 434 | std.hash.autoHash(hasher, ies); | 421 | std.hash.autoHash(hasher, ies); |
| 435 | }, | 422 | }, |
| 436 | 423 | ||
| 437 | .pointer, | ||
| 438 | .inferred_alloc_const, | 424 | .inferred_alloc_const, |
| 439 | .inferred_alloc_mut, | 425 | .inferred_alloc_mut, |
| 440 | => { | 426 | => { |
| ... | @@ -512,26 +498,6 @@ pub const Type = struct { | ... | @@ -512,26 +498,6 @@ pub const Type = struct { |
| 512 | .inferred_alloc_mut, | 498 | .inferred_alloc_mut, |
| 513 | => unreachable, | 499 | => unreachable, |
| 514 | 500 | ||
| 515 | .pointer => { | ||
| 516 | const payload = self.castTag(.pointer).?.data; | ||
| 517 | const sent: ?Value = if (payload.sentinel) |some| | ||
| 518 | try some.copy(allocator) | ||
| 519 | else | ||
| 520 | null; | ||
| 521 | return Tag.pointer.create(allocator, .{ | ||
| 522 | .pointee_type = try payload.pointee_type.copy(allocator), | ||
| 523 | .sentinel = sent, | ||
| 524 | .@"align" = payload.@"align", | ||
| 525 | .@"addrspace" = payload.@"addrspace", | ||
| 526 | .bit_offset = payload.bit_offset, | ||
| 527 | .host_size = payload.host_size, | ||
| 528 | .vector_index = payload.vector_index, | ||
| 529 | .@"allowzero" = payload.@"allowzero", | ||
| 530 | .mutable = payload.mutable, | ||
| 531 | .@"volatile" = payload.@"volatile", | ||
| 532 | .size = payload.size, | ||
| 533 | }); | ||
| 534 | }, | ||
| 535 | .error_union => { | 501 | .error_union => { |
| 536 | const payload = self.castTag(.error_union).?.data; | 502 | const payload = self.castTag(.error_union).?.data; |
| 537 | return Tag.error_union.create(allocator, .{ | 503 | return Tag.error_union.create(allocator, .{ |
| ... | @@ -623,41 +589,6 @@ pub const Type = struct { | ... | @@ -623,41 +589,6 @@ pub const Type = struct { |
| 623 | while (true) { | 589 | while (true) { |
| 624 | const t = ty.tag(); | 590 | const t = ty.tag(); |
| 625 | switch (t) { | 591 | switch (t) { |
| 626 | .pointer => { | ||
| 627 | const payload = ty.castTag(.pointer).?.data; | ||
| 628 | if (payload.sentinel) |some| switch (payload.size) { | ||
| 629 | .One, .C => unreachable, | ||
| 630 | .Many => try writer.print("[*:{}]", .{some.fmtDebug()}), | ||
| 631 | .Slice => try writer.print("[:{}]", .{some.fmtDebug()}), | ||
| 632 | } else switch (payload.size) { | ||
| 633 | .One => try writer.writeAll("*"), | ||
| 634 | .Many => try writer.writeAll("[*]"), | ||
| 635 | .C => try writer.writeAll("[*c]"), | ||
| 636 | .Slice => try writer.writeAll("[]"), | ||
| 637 | } | ||
| 638 | if (payload.@"align" != 0 or payload.host_size != 0 or payload.vector_index != .none) { | ||
| 639 | try writer.print("align({d}", .{payload.@"align"}); | ||
| 640 | |||
| 641 | if (payload.bit_offset != 0 or payload.host_size != 0) { | ||
| 642 | try writer.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size }); | ||
| 643 | } | ||
| 644 | if (payload.vector_index == .runtime) { | ||
| 645 | try writer.writeAll(":?"); | ||
| 646 | } else if (payload.vector_index != .none) { | ||
| 647 | try writer.print(":{d}", .{@enumToInt(payload.vector_index)}); | ||
| 648 | } | ||
| 649 | try writer.writeAll(") "); | ||
| 650 | } | ||
| 651 | if (payload.@"addrspace" != .generic) { | ||
| 652 | try writer.print("addrspace(.{s}) ", .{@tagName(payload.@"addrspace")}); | ||
| 653 | } | ||
| 654 | if (!payload.mutable) try writer.writeAll("const "); | ||
| 655 | if (payload.@"volatile") try writer.writeAll("volatile "); | ||
| 656 | if (payload.@"allowzero" and payload.size != .C) try writer.writeAll("allowzero "); | ||
| 657 | |||
| 658 | ty = payload.pointee_type; | ||
| 659 | continue; | ||
| 660 | }, | ||
| 661 | .error_union => { | 592 | .error_union => { |
| 662 | const payload = ty.castTag(.error_union).?.data; | 593 | const payload = ty.castTag(.error_union).?.data; |
| 663 | try payload.error_set.dump("", .{}, writer); | 594 | try payload.error_set.dump("", .{}, writer); |
| ... | @@ -734,47 +665,6 @@ pub const Type = struct { | ... | @@ -734,47 +665,6 @@ pub const Type = struct { |
| 734 | try print(error_union.payload, writer, mod); | 665 | try print(error_union.payload, writer, mod); |
| 735 | }, | 666 | }, |
| 736 | 667 | ||
| 737 | .pointer => { | ||
| 738 | const info = ty.ptrInfo(mod); | ||
| 739 | |||
| 740 | if (info.sentinel) |s| switch (info.size) { | ||
| 741 | .One, .C => unreachable, | ||
| 742 | .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}), | ||
| 743 | .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}), | ||
| 744 | } else switch (info.size) { | ||
| 745 | .One => try writer.writeAll("*"), | ||
| 746 | .Many => try writer.writeAll("[*]"), | ||
| 747 | .C => try writer.writeAll("[*c]"), | ||
| 748 | .Slice => try writer.writeAll("[]"), | ||
| 749 | } | ||
| 750 | if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) { | ||
| 751 | if (info.@"align" != 0) { | ||
| 752 | try writer.print("align({d}", .{info.@"align"}); | ||
| 753 | } else { | ||
| 754 | const alignment = info.pointee_type.abiAlignment(mod); | ||
| 755 | try writer.print("align({d}", .{alignment}); | ||
| 756 | } | ||
| 757 | |||
| 758 | if (info.bit_offset != 0 or info.host_size != 0) { | ||
| 759 | try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size }); | ||
| 760 | } | ||
| 761 | if (info.vector_index == .runtime) { | ||
| 762 | try writer.writeAll(":?"); | ||
| 763 | } else if (info.vector_index != .none) { | ||
| 764 | try writer.print(":{d}", .{@enumToInt(info.vector_index)}); | ||
| 765 | } | ||
| 766 | try writer.writeAll(") "); | ||
| 767 | } | ||
| 768 | if (info.@"addrspace" != .generic) { | ||
| 769 | try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")}); | ||
| 770 | } | ||
| 771 | if (!info.mutable) try writer.writeAll("const "); | ||
| 772 | if (info.@"volatile") try writer.writeAll("volatile "); | ||
| 773 | if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero "); | ||
| 774 | |||
| 775 | try print(info.pointee_type, writer, mod); | ||
| 776 | }, | ||
| 777 | |||
| 778 | .error_set => { | 668 | .error_set => { |
| 779 | const names = ty.castTag(.error_set).?.data.names.keys(); | 669 | const names = ty.castTag(.error_set).?.data.names.keys(); |
| 780 | try writer.writeAll("error{"); | 670 | try writer.writeAll("error{"); |
| ... | @@ -951,8 +841,8 @@ pub const Type = struct { | ... | @@ -951,8 +841,8 @@ pub const Type = struct { |
| 951 | try writer.writeAll("..."); | 841 | try writer.writeAll("..."); |
| 952 | } | 842 | } |
| 953 | try writer.writeAll(") "); | 843 | try writer.writeAll(") "); |
| 954 | if (fn_info.alignment != 0) { | 844 | if (fn_info.alignment.toByteUnitsOptional()) |a| { |
| 955 | try writer.print("align({d}) ", .{fn_info.alignment}); | 845 | try writer.print("align({d}) ", .{a}); |
| 956 | } | 846 | } |
| 957 | if (fn_info.cc != .Unspecified) { | 847 | if (fn_info.cc != .Unspecified) { |
| 958 | try writer.writeAll("callconv(."); | 848 | try writer.writeAll("callconv(."); |
| ... | @@ -1032,20 +922,6 @@ pub const Type = struct { | ... | @@ -1032,20 +922,6 @@ pub const Type = struct { |
| 1032 | .error_set_merged, | 922 | .error_set_merged, |
| 1033 | => return true, | 923 | => return true, |
| 1034 | 924 | ||
| 1035 | // Pointers to zero-bit types still have a runtime address; however, pointers | ||
| 1036 | // to comptime-only types do not, with the exception of function pointers. | ||
| 1037 | .pointer => { | ||
| 1038 | if (ignore_comptime_only) { | ||
| 1039 | return true; | ||
| 1040 | } else if (ty.childType(mod).zigTypeTag(mod) == .Fn) { | ||
| 1041 | return !mod.typeToFunc(ty.childType(mod)).?.is_generic; | ||
| 1042 | } else if (strat == .sema) { | ||
| 1043 | return !(try strat.sema.typeRequiresComptime(ty)); | ||
| 1044 | } else { | ||
| 1045 | return !comptimeOnly(ty, mod); | ||
| 1046 | } | ||
| 1047 | }, | ||
| 1048 | |||
| 1049 | .inferred_alloc_const => unreachable, | 925 | .inferred_alloc_const => unreachable, |
| 1050 | .inferred_alloc_mut => unreachable, | 926 | .inferred_alloc_mut => unreachable, |
| 1051 | }, | 927 | }, |
| ... | @@ -1231,8 +1107,6 @@ pub const Type = struct { | ... | @@ -1231,8 +1107,6 @@ pub const Type = struct { |
| 1231 | .empty_struct_type => false, | 1107 | .empty_struct_type => false, |
| 1232 | 1108 | ||
| 1233 | .none => switch (ty.tag()) { | 1109 | .none => switch (ty.tag()) { |
| 1234 | .pointer => true, | ||
| 1235 | |||
| 1236 | .error_set, | 1110 | .error_set, |
| 1237 | .error_set_single, | 1111 | .error_set_single, |
| 1238 | .error_set_inferred, | 1112 | .error_set_inferred, |
| ... | @@ -1410,51 +1284,27 @@ pub const Type = struct { | ... | @@ -1410,51 +1284,27 @@ pub const Type = struct { |
| 1410 | } | 1284 | } |
| 1411 | 1285 | ||
| 1412 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 { | 1286 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 { |
| 1413 | switch (ty.ip_index) { | 1287 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 1414 | .none => switch (ty.tag()) { | 1288 | .ptr_type => |ptr_type| { |
| 1415 | .pointer => { | 1289 | if (ptr_type.alignment.toByteUnitsOptional()) |a| { |
| 1416 | const ptr_info = ty.castTag(.pointer).?.data; | 1290 | return @intCast(u32, a); |
| 1417 | if (ptr_info.@"align" != 0) { | 1291 | } else if (opt_sema) |sema| { |
| 1418 | return ptr_info.@"align"; | 1292 | const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema }); |
| 1419 | } else if (opt_sema) |sema| { | 1293 | return res.scalar; |
| 1420 | const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema }); | 1294 | } else { |
| 1421 | return res.scalar; | 1295 | return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; |
| 1422 | } else { | 1296 | } |
| 1423 | return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | ||
| 1424 | } | ||
| 1425 | }, | ||
| 1426 | |||
| 1427 | else => unreachable, | ||
| 1428 | }, | ||
| 1429 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 1430 | .ptr_type => |ptr_type| { | ||
| 1431 | if (ptr_type.alignment != 0) { | ||
| 1432 | return @intCast(u32, ptr_type.alignment); | ||
| 1433 | } else if (opt_sema) |sema| { | ||
| 1434 | const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema }); | ||
| 1435 | return res.scalar; | ||
| 1436 | } else { | ||
| 1437 | return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | ||
| 1438 | } | ||
| 1439 | }, | ||
| 1440 | .opt_type => |child| return child.toType().ptrAlignmentAdvanced(mod, opt_sema), | ||
| 1441 | else => unreachable, | ||
| 1442 | }, | 1297 | }, |
| 1443 | } | 1298 | .opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema), |
| 1299 | else => unreachable, | ||
| 1300 | }; | ||
| 1444 | } | 1301 | } |
| 1445 | 1302 | ||
| 1446 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { | 1303 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { |
| 1447 | return switch (ty.ip_index) { | 1304 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 1448 | .none => switch (ty.tag()) { | 1305 | .ptr_type => |ptr_type| ptr_type.address_space, |
| 1449 | .pointer => ty.castTag(.pointer).?.data.@"addrspace", | 1306 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space, |
| 1450 | 1307 | else => unreachable, | |
| 1451 | else => unreachable, | ||
| 1452 | }, | ||
| 1453 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 1454 | .ptr_type => |ptr_type| ptr_type.address_space, | ||
| 1455 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space, | ||
| 1456 | else => unreachable, | ||
| 1457 | }, | ||
| 1458 | }; | 1308 | }; |
| 1459 | } | 1309 | } |
| 1460 | 1310 | ||
| ... | @@ -1504,7 +1354,6 @@ pub const Type = struct { | ... | @@ -1504,7 +1354,6 @@ pub const Type = struct { |
| 1504 | switch (ty.ip_index) { | 1354 | switch (ty.ip_index) { |
| 1505 | .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 }, | 1355 | .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 }, |
| 1506 | .none => switch (ty.tag()) { | 1356 | .none => switch (ty.tag()) { |
| 1507 | .pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | ||
| 1508 | 1357 | ||
| 1509 | // TODO revisit this when we have the concept of the error tag type | 1358 | // TODO revisit this when we have the concept of the error tag type |
| 1510 | .error_set_inferred, | 1359 | .error_set_inferred, |
| ... | @@ -1541,10 +1390,11 @@ pub const Type = struct { | ... | @@ -1541,10 +1390,11 @@ pub const Type = struct { |
| 1541 | .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat), | 1390 | .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat), |
| 1542 | .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat), | 1391 | .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat), |
| 1543 | // represents machine code; not a pointer | 1392 | // represents machine code; not a pointer |
| 1544 | .func_type => |func_type| { | 1393 | .func_type => |func_type| return AbiAlignmentAdvanced{ |
| 1545 | const alignment = @intCast(u32, func_type.alignment); | 1394 | .scalar = if (func_type.alignment.toByteUnitsOptional()) |a| |
| 1546 | if (alignment != 0) return AbiAlignmentAdvanced{ .scalar = alignment }; | 1395 | @intCast(u32, a) |
| 1547 | return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) }; | 1396 | else |
| 1397 | target_util.defaultFunctionAlignment(target), | ||
| 1548 | }, | 1398 | }, |
| 1549 | 1399 | ||
| 1550 | .simple_type => |t| switch (t) { | 1400 | .simple_type => |t| switch (t) { |
| ... | @@ -1882,11 +1732,6 @@ pub const Type = struct { | ... | @@ -1882,11 +1732,6 @@ pub const Type = struct { |
| 1882 | .inferred_alloc_const => unreachable, | 1732 | .inferred_alloc_const => unreachable, |
| 1883 | .inferred_alloc_mut => unreachable, | 1733 | .inferred_alloc_mut => unreachable, |
| 1884 | 1734 | ||
| 1885 | .pointer => switch (ty.castTag(.pointer).?.data.size) { | ||
| 1886 | .Slice => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, | ||
| 1887 | else => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | ||
| 1888 | }, | ||
| 1889 | |||
| 1890 | // TODO revisit this when we have the concept of the error tag type | 1735 | // TODO revisit this when we have the concept of the error tag type |
| 1891 | .error_set_inferred, | 1736 | .error_set_inferred, |
| 1892 | .error_set, | 1737 | .error_set, |
| ... | @@ -2201,11 +2046,6 @@ pub const Type = struct { | ... | @@ -2201,11 +2046,6 @@ pub const Type = struct { |
| 2201 | .inferred_alloc_const => unreachable, | 2046 | .inferred_alloc_const => unreachable, |
| 2202 | .inferred_alloc_mut => unreachable, | 2047 | .inferred_alloc_mut => unreachable, |
| 2203 | 2048 | ||
| 2204 | .pointer => switch (ty.castTag(.pointer).?.data.size) { | ||
| 2205 | .Slice => return target.ptrBitWidth() * 2, | ||
| 2206 | else => return target.ptrBitWidth(), | ||
| 2207 | }, | ||
| 2208 | |||
| 2209 | .error_set, | 2049 | .error_set, |
| 2210 | .error_set_single, | 2050 | .error_set_single, |
| 2211 | .error_set_inferred, | 2051 | .error_set_inferred, |
| ... | @@ -2384,8 +2224,6 @@ pub const Type = struct { | ... | @@ -2384,8 +2224,6 @@ pub const Type = struct { |
| 2384 | .inferred_alloc_mut, | 2224 | .inferred_alloc_mut, |
| 2385 | => true, | 2225 | => true, |
| 2386 | 2226 | ||
| 2387 | .pointer => ty.castTag(.pointer).?.data.size == .One, | ||
| 2388 | |||
| 2389 | else => false, | 2227 | else => false, |
| 2390 | }, | 2228 | }, |
| 2391 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2229 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | @@ -2408,8 +2246,6 @@ pub const Type = struct { | ... | @@ -2408,8 +2246,6 @@ pub const Type = struct { |
| 2408 | .inferred_alloc_mut, | 2246 | .inferred_alloc_mut, |
| 2409 | => .One, | 2247 | => .One, |
| 2410 | 2248 | ||
| 2411 | .pointer => ty.castTag(.pointer).?.data.size, | ||
| 2412 | |||
| 2413 | else => null, | 2249 | else => null, |
| 2414 | }, | 2250 | }, |
| 2415 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2251 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | @@ -2421,10 +2257,7 @@ pub const Type = struct { | ... | @@ -2421,10 +2257,7 @@ pub const Type = struct { |
| 2421 | 2257 | ||
| 2422 | pub fn isSlice(ty: Type, mod: *const Module) bool { | 2258 | pub fn isSlice(ty: Type, mod: *const Module) bool { |
| 2423 | return switch (ty.ip_index) { | 2259 | return switch (ty.ip_index) { |
| 2424 | .none => switch (ty.tag()) { | 2260 | .none => false, |
| 2425 | .pointer => ty.castTag(.pointer).?.data.size == .Slice, | ||
| 2426 | else => false, | ||
| 2427 | }, | ||
| 2428 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2261 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2429 | .ptr_type => |ptr_type| ptr_type.size == .Slice, | 2262 | .ptr_type => |ptr_type| ptr_type.size == .Slice, |
| 2430 | else => false, | 2263 | else => false, |
| ... | @@ -2432,50 +2265,14 @@ pub const Type = struct { | ... | @@ -2432,50 +2265,14 @@ pub const Type = struct { |
| 2432 | }; | 2265 | }; |
| 2433 | } | 2266 | } |
| 2434 | 2267 | ||
| 2435 | pub const SlicePtrFieldTypeBuffer = union { | 2268 | pub fn slicePtrFieldType(ty: Type, mod: *const Module) Type { |
| 2436 | pointer: Payload.Pointer, | 2269 | return mod.intern_pool.slicePtrType(ty.ip_index).toType(); |
| 2437 | }; | ||
| 2438 | |||
| 2439 | pub fn slicePtrFieldType(ty: Type, buffer: *SlicePtrFieldTypeBuffer, mod: *const Module) Type { | ||
| 2440 | switch (ty.ip_index) { | ||
| 2441 | .none => switch (ty.tag()) { | ||
| 2442 | .pointer => { | ||
| 2443 | const payload = ty.castTag(.pointer).?.data; | ||
| 2444 | assert(payload.size == .Slice); | ||
| 2445 | |||
| 2446 | buffer.* = .{ | ||
| 2447 | .pointer = .{ | ||
| 2448 | .data = .{ | ||
| 2449 | .pointee_type = payload.pointee_type, | ||
| 2450 | .sentinel = payload.sentinel, | ||
| 2451 | .@"align" = payload.@"align", | ||
| 2452 | .@"addrspace" = payload.@"addrspace", | ||
| 2453 | .bit_offset = payload.bit_offset, | ||
| 2454 | .host_size = payload.host_size, | ||
| 2455 | .vector_index = payload.vector_index, | ||
| 2456 | .@"allowzero" = payload.@"allowzero", | ||
| 2457 | .mutable = payload.mutable, | ||
| 2458 | .@"volatile" = payload.@"volatile", | ||
| 2459 | .size = .Many, | ||
| 2460 | }, | ||
| 2461 | }, | ||
| 2462 | }; | ||
| 2463 | return Type.initPayload(&buffer.pointer.base); | ||
| 2464 | }, | ||
| 2465 | |||
| 2466 | else => unreachable, | ||
| 2467 | }, | ||
| 2468 | else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(), | ||
| 2469 | } | ||
| 2470 | } | 2270 | } |
| 2471 | 2271 | ||
| 2472 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { | 2272 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { |
| 2473 | return switch (ty.ip_index) { | 2273 | return switch (ty.ip_index) { |
| 2474 | .none => switch (ty.tag()) { | 2274 | .none => false, |
| 2475 | .pointer => !ty.castTag(.pointer).?.data.mutable, | 2275 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2476 | else => false, | ||
| 2477 | }, | ||
| 2478 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 2479 | .ptr_type => |ptr_type| ptr_type.is_const, | 2276 | .ptr_type => |ptr_type| ptr_type.is_const, |
| 2480 | else => false, | 2277 | else => false, |
| 2481 | }, | 2278 | }, |
| ... | @@ -2488,10 +2285,7 @@ pub const Type = struct { | ... | @@ -2488,10 +2285,7 @@ pub const Type = struct { |
| 2488 | 2285 | ||
| 2489 | pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool { | 2286 | pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool { |
| 2490 | return switch (ty.ip_index) { | 2287 | return switch (ty.ip_index) { |
| 2491 | .none => switch (ty.tag()) { | 2288 | .none => false, |
| 2492 | .pointer => ty.castTag(.pointer).?.data.@"volatile", | ||
| 2493 | else => false, | ||
| 2494 | }, | ||
| 2495 | else => switch (ip.indexToKey(ty.ip_index)) { | 2289 | else => switch (ip.indexToKey(ty.ip_index)) { |
| 2496 | .ptr_type => |ptr_type| ptr_type.is_volatile, | 2290 | .ptr_type => |ptr_type| ptr_type.is_volatile, |
| 2497 | else => false, | 2291 | else => false, |
| ... | @@ -2501,12 +2295,10 @@ pub const Type = struct { | ... | @@ -2501,12 +2295,10 @@ pub const Type = struct { |
| 2501 | 2295 | ||
| 2502 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { | 2296 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { |
| 2503 | return switch (ty.ip_index) { | 2297 | return switch (ty.ip_index) { |
| 2504 | .none => switch (ty.tag()) { | 2298 | .none => false, |
| 2505 | .pointer => ty.castTag(.pointer).?.data.@"allowzero", | ||
| 2506 | else => ty.zigTypeTag(mod) == .Optional, | ||
| 2507 | }, | ||
| 2508 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2299 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2509 | .ptr_type => |ptr_type| ptr_type.is_allowzero, | 2300 | .ptr_type => |ptr_type| ptr_type.is_allowzero, |
| 2301 | .opt_type => true, | ||
| 2510 | else => false, | 2302 | else => false, |
| 2511 | }, | 2303 | }, |
| 2512 | }; | 2304 | }; |
| ... | @@ -2514,10 +2306,7 @@ pub const Type = struct { | ... | @@ -2514,10 +2306,7 @@ pub const Type = struct { |
| 2514 | 2306 | ||
| 2515 | pub fn isCPtr(ty: Type, mod: *const Module) bool { | 2307 | pub fn isCPtr(ty: Type, mod: *const Module) bool { |
| 2516 | return switch (ty.ip_index) { | 2308 | return switch (ty.ip_index) { |
| 2517 | .none => switch (ty.tag()) { | 2309 | .none => false, |
| 2518 | .pointer => ty.castTag(.pointer).?.data.size == .C, | ||
| 2519 | else => false, | ||
| 2520 | }, | ||
| 2521 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2310 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2522 | .ptr_type => |ptr_type| ptr_type.size == .C, | 2311 | .ptr_type => |ptr_type| ptr_type.size == .C, |
| 2523 | else => false, | 2312 | else => false, |
| ... | @@ -2526,16 +2315,9 @@ pub const Type = struct { | ... | @@ -2526,16 +2315,9 @@ pub const Type = struct { |
| 2526 | } | 2315 | } |
| 2527 | 2316 | ||
| 2528 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { | 2317 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { |
| 2529 | switch (ty.ip_index) { | 2318 | return switch (ty.ip_index) { |
| 2530 | .none => switch (ty.tag()) { | 2319 | .none => false, |
| 2531 | .pointer => switch (ty.castTag(.pointer).?.data.size) { | 2320 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2532 | .Slice => return false, | ||
| 2533 | .One, .Many, .C => return true, | ||
| 2534 | }, | ||
| 2535 | |||
| 2536 | else => return false, | ||
| 2537 | }, | ||
| 2538 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 2539 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 2321 | .ptr_type => |ptr_type| switch (ptr_type.size) { |
| 2540 | .Slice => false, | 2322 | .Slice => false, |
| 2541 | .One, .Many, .C => true, | 2323 | .One, .Many, .C => true, |
| ... | @@ -2549,7 +2331,7 @@ pub const Type = struct { | ... | @@ -2549,7 +2331,7 @@ pub const Type = struct { |
| 2549 | }, | 2331 | }, |
| 2550 | else => false, | 2332 | else => false, |
| 2551 | }, | 2333 | }, |
| 2552 | } | 2334 | }; |
| 2553 | } | 2335 | } |
| 2554 | 2336 | ||
| 2555 | /// For pointer-like optionals, returns true, otherwise returns the allowzero property | 2337 | /// For pointer-like optionals, returns true, otherwise returns the allowzero property |
| ... | @@ -2563,47 +2345,43 @@ pub const Type = struct { | ... | @@ -2563,47 +2345,43 @@ pub const Type = struct { |
| 2563 | 2345 | ||
| 2564 | /// See also `isPtrLikeOptional`. | 2346 | /// See also `isPtrLikeOptional`. |
| 2565 | pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { | 2347 | pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { |
| 2566 | if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2348 | return switch (ty.ip_index) { |
| 2567 | .opt_type => |child| switch (child.toType().zigTypeTag(mod)) { | 2349 | .none => false, |
| 2568 | .Pointer => { | 2350 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2569 | const info = child.toType().ptrInfo(mod); | 2351 | .opt_type => |child| switch (child.toType().zigTypeTag(mod)) { |
| 2570 | switch (info.size) { | 2352 | .Pointer => { |
| 2571 | .C => return false, | 2353 | const info = child.toType().ptrInfo(mod); |
| 2572 | else => return !info.@"allowzero", | 2354 | return switch (info.size) { |
| 2573 | } | 2355 | .C => false, |
| 2356 | else => !info.@"allowzero", | ||
| 2357 | }; | ||
| 2358 | }, | ||
| 2359 | .ErrorSet => true, | ||
| 2360 | else => false, | ||
| 2574 | }, | 2361 | }, |
| 2575 | .ErrorSet => true, | ||
| 2576 | else => false, | 2362 | else => false, |
| 2577 | }, | 2363 | }, |
| 2578 | else => false, | ||
| 2579 | }; | 2364 | }; |
| 2580 | switch (ty.tag()) { | ||
| 2581 | .pointer => return ty.castTag(.pointer).?.data.size == .C, | ||
| 2582 | |||
| 2583 | else => return false, | ||
| 2584 | } | ||
| 2585 | } | 2365 | } |
| 2586 | 2366 | ||
| 2587 | /// Returns true if the type is optional and would be lowered to a single pointer | 2367 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 2588 | /// address value, using 0 for null. Note that this returns true for C pointers. | 2368 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 2589 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. | 2369 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. |
| 2590 | pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { | 2370 | pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { |
| 2591 | if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2371 | return switch (ty.ip_index) { |
| 2592 | .ptr_type => |ptr_type| ptr_type.size == .C, | 2372 | .none => false, |
| 2593 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | 2373 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2594 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 2374 | .ptr_type => |ptr_type| ptr_type.size == .C, |
| 2595 | .Slice, .C => false, | 2375 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { |
| 2596 | .Many, .One => !ptr_type.is_allowzero, | 2376 | .ptr_type => |ptr_type| switch (ptr_type.size) { |
| 2377 | .Slice, .C => false, | ||
| 2378 | .Many, .One => !ptr_type.is_allowzero, | ||
| 2379 | }, | ||
| 2380 | else => false, | ||
| 2597 | }, | 2381 | }, |
| 2598 | else => false, | 2382 | else => false, |
| 2599 | }, | 2383 | }, |
| 2600 | else => false, | ||
| 2601 | }; | 2384 | }; |
| 2602 | switch (ty.tag()) { | ||
| 2603 | .pointer => return ty.castTag(.pointer).?.data.size == .C, | ||
| 2604 | |||
| 2605 | else => return false, | ||
| 2606 | } | ||
| 2607 | } | 2385 | } |
| 2608 | 2386 | ||
| 2609 | /// For *[N]T, returns [N]T. | 2387 | /// For *[N]T, returns [N]T. |
| ... | @@ -2614,14 +2392,7 @@ pub const Type = struct { | ... | @@ -2614,14 +2392,7 @@ pub const Type = struct { |
| 2614 | } | 2392 | } |
| 2615 | 2393 | ||
| 2616 | pub fn childTypeIp(ty: Type, ip: InternPool) Type { | 2394 | pub fn childTypeIp(ty: Type, ip: InternPool) Type { |
| 2617 | return switch (ty.ip_index) { | 2395 | return ip.childType(ty.ip_index).toType(); |
| 2618 | .none => switch (ty.tag()) { | ||
| 2619 | .pointer => ty.castTag(.pointer).?.data.pointee_type, | ||
| 2620 | |||
| 2621 | else => unreachable, | ||
| 2622 | }, | ||
| 2623 | else => ip.childType(ty.ip_index).toType(), | ||
| 2624 | }; | ||
| 2625 | } | 2396 | } |
| 2626 | 2397 | ||
| 2627 | /// For *[N]T, returns T. | 2398 | /// For *[N]T, returns T. |
| ... | @@ -2634,34 +2405,19 @@ pub const Type = struct { | ... | @@ -2634,34 +2405,19 @@ pub const Type = struct { |
| 2634 | /// For []T, returns T. | 2405 | /// For []T, returns T. |
| 2635 | /// For anyframe->T, returns T. | 2406 | /// For anyframe->T, returns T. |
| 2636 | pub fn elemType2(ty: Type, mod: *const Module) Type { | 2407 | pub fn elemType2(ty: Type, mod: *const Module) Type { |
| 2637 | return switch (ty.ip_index) { | 2408 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2638 | .none => switch (ty.tag()) { | 2409 | .ptr_type => |ptr_type| switch (ptr_type.size) { |
| 2639 | .pointer => { | 2410 | .One => ptr_type.elem_type.toType().shallowElemType(mod), |
| 2640 | const info = ty.castTag(.pointer).?.data; | 2411 | .Many, .C, .Slice => ptr_type.elem_type.toType(), |
| 2641 | const child_ty = info.pointee_type; | ||
| 2642 | if (info.size == .One) { | ||
| 2643 | return child_ty.shallowElemType(mod); | ||
| 2644 | } else { | ||
| 2645 | return child_ty; | ||
| 2646 | } | ||
| 2647 | }, | ||
| 2648 | |||
| 2649 | else => unreachable, | ||
| 2650 | }, | 2412 | }, |
| 2651 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 2413 | .anyframe_type => |child| { |
| 2652 | .ptr_type => |ptr_type| switch (ptr_type.size) { | 2414 | assert(child != .none); |
| 2653 | .One => ptr_type.elem_type.toType().shallowElemType(mod), | 2415 | return child.toType(); |
| 2654 | .Many, .C, .Slice => ptr_type.elem_type.toType(), | ||
| 2655 | }, | ||
| 2656 | .anyframe_type => |child| { | ||
| 2657 | assert(child != .none); | ||
| 2658 | return child.toType(); | ||
| 2659 | }, | ||
| 2660 | .vector_type => |vector_type| vector_type.child.toType(), | ||
| 2661 | .array_type => |array_type| array_type.child.toType(), | ||
| 2662 | .opt_type => |child| mod.intern_pool.childType(child).toType(), | ||
| 2663 | else => unreachable, | ||
| 2664 | }, | 2416 | }, |
| 2417 | .vector_type => |vector_type| vector_type.child.toType(), | ||
| 2418 | .array_type => |array_type| array_type.child.toType(), | ||
| 2419 | .opt_type => |child| mod.intern_pool.childType(child).toType(), | ||
| 2420 | else => unreachable, | ||
| 2665 | }; | 2421 | }; |
| 2666 | } | 2422 | } |
| 2667 | 2423 | ||
| ... | @@ -2683,21 +2439,13 @@ pub const Type = struct { | ... | @@ -2683,21 +2439,13 @@ pub const Type = struct { |
| 2683 | /// Asserts that the type is an optional. | 2439 | /// Asserts that the type is an optional. |
| 2684 | /// Note that for C pointers this returns the type unmodified. | 2440 | /// Note that for C pointers this returns the type unmodified. |
| 2685 | pub fn optionalChild(ty: Type, mod: *const Module) Type { | 2441 | pub fn optionalChild(ty: Type, mod: *const Module) Type { |
| 2686 | return switch (ty.ip_index) { | 2442 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2687 | .none => switch (ty.tag()) { | 2443 | .opt_type => |child| child.toType(), |
| 2688 | .pointer, // here we assume it is a C pointer | 2444 | .ptr_type => |ptr_type| b: { |
| 2689 | => return ty, | 2445 | assert(ptr_type.size == .C); |
| 2690 | 2446 | break :b ty; | |
| 2691 | else => unreachable, | ||
| 2692 | }, | ||
| 2693 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 2694 | .opt_type => |child| child.toType(), | ||
| 2695 | .ptr_type => |ptr_type| b: { | ||
| 2696 | assert(ptr_type.size == .C); | ||
| 2697 | break :b ty; | ||
| 2698 | }, | ||
| 2699 | else => unreachable, | ||
| 2700 | }, | 2447 | }, |
| 2448 | else => unreachable, | ||
| 2701 | }; | 2449 | }; |
| 2702 | } | 2450 | } |
| 2703 | 2451 | ||
| ... | @@ -2921,23 +2669,16 @@ pub const Type = struct { | ... | @@ -2921,23 +2669,16 @@ pub const Type = struct { |
| 2921 | 2669 | ||
| 2922 | /// Asserts the type is an array, pointer or vector. | 2670 | /// Asserts the type is an array, pointer or vector. |
| 2923 | pub fn sentinel(ty: Type, mod: *const Module) ?Value { | 2671 | pub fn sentinel(ty: Type, mod: *const Module) ?Value { |
| 2924 | return switch (ty.ip_index) { | 2672 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2925 | .none => switch (ty.tag()) { | 2673 | .vector_type, |
| 2926 | .pointer => ty.castTag(.pointer).?.data.sentinel, | 2674 | .struct_type, |
| 2927 | 2675 | .anon_struct_type, | |
| 2928 | else => unreachable, | 2676 | => null, |
| 2929 | }, | ||
| 2930 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | ||
| 2931 | .vector_type, | ||
| 2932 | .struct_type, | ||
| 2933 | .anon_struct_type, | ||
| 2934 | => null, | ||
| 2935 | 2677 | ||
| 2936 | .array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, | 2678 | .array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, |
| 2937 | .ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, | 2679 | .ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, |
| 2938 | 2680 | ||
| 2939 | else => unreachable, | 2681 | else => unreachable, |
| 2940 | }, | ||
| 2941 | }; | 2682 | }; |
| 2942 | } | 2683 | } |
| 2943 | 2684 | ||
| ... | @@ -3196,7 +2937,6 @@ pub const Type = struct { | ... | @@ -3196,7 +2937,6 @@ pub const Type = struct { |
| 3196 | .error_set, | 2937 | .error_set, |
| 3197 | .error_set_merged, | 2938 | .error_set_merged, |
| 3198 | .error_set_inferred, | 2939 | .error_set_inferred, |
| 3199 | .pointer, | ||
| 3200 | => return null, | 2940 | => return null, |
| 3201 | 2941 | ||
| 3202 | .inferred_alloc_const => unreachable, | 2942 | .inferred_alloc_const => unreachable, |
| ... | @@ -3400,15 +3140,6 @@ pub const Type = struct { | ... | @@ -3400,15 +3140,6 @@ pub const Type = struct { |
| 3400 | .inferred_alloc_mut => unreachable, | 3140 | .inferred_alloc_mut => unreachable, |
| 3401 | .inferred_alloc_const => unreachable, | 3141 | .inferred_alloc_const => unreachable, |
| 3402 | 3142 | ||
| 3403 | .pointer => { | ||
| 3404 | const child_ty = ty.childType(mod); | ||
| 3405 | if (child_ty.zigTypeTag(mod) == .Fn) { | ||
| 3406 | return false; | ||
| 3407 | } else { | ||
| 3408 | return child_ty.comptimeOnly(mod); | ||
| 3409 | } | ||
| 3410 | }, | ||
| 3411 | |||
| 3412 | .error_union => return ty.errorUnionPayload().comptimeOnly(mod), | 3143 | .error_union => return ty.errorUnionPayload().comptimeOnly(mod), |
| 3413 | }, | 3144 | }, |
| 3414 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 3145 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | @@ -4096,7 +3827,6 @@ pub const Type = struct { | ... | @@ -4096,7 +3827,6 @@ pub const Type = struct { |
| 4096 | inferred_alloc_const, // See last_no_payload_tag below. | 3827 | inferred_alloc_const, // See last_no_payload_tag below. |
| 4097 | // After this, the tag requires a payload. | 3828 | // After this, the tag requires a payload. |
| 4098 | 3829 | ||
| 4099 | pointer, | ||
| 4100 | error_union, | 3830 | error_union, |
| 4101 | error_set, | 3831 | error_set, |
| 4102 | error_set_single, | 3832 | error_set_single, |
| ... | @@ -4117,7 +3847,6 @@ pub const Type = struct { | ... | @@ -4117,7 +3847,6 @@ pub const Type = struct { |
| 4117 | .error_set_inferred => Payload.ErrorSetInferred, | 3847 | .error_set_inferred => Payload.ErrorSetInferred, |
| 4118 | .error_set_merged => Payload.ErrorSetMerged, | 3848 | .error_set_merged => Payload.ErrorSetMerged, |
| 4119 | 3849 | ||
| 4120 | .pointer => Payload.Pointer, | ||
| 4121 | .error_union => Payload.ErrorUnion, | 3850 | .error_union => Payload.ErrorUnion, |
| 4122 | .error_set_single => Payload.Name, | 3851 | .error_set_single => Payload.Name, |
| 4123 | }; | 3852 | }; |
| ... | @@ -4230,10 +3959,8 @@ pub const Type = struct { | ... | @@ -4230,10 +3959,8 @@ pub const Type = struct { |
| 4230 | data: *Module.Fn.InferredErrorSet, | 3959 | data: *Module.Fn.InferredErrorSet, |
| 4231 | }; | 3960 | }; |
| 4232 | 3961 | ||
| 3962 | /// TODO: remove this data structure since we have `InternPool.Key.PtrType`. | ||
| 4233 | pub const Pointer = struct { | 3963 | pub const Pointer = struct { |
| 4234 | pub const base_tag = Tag.pointer; | ||
| 4235 | |||
| 4236 | base: Payload = Payload{ .tag = base_tag }, | ||
| 4237 | data: Data, | 3964 | data: Data, |
| 4238 | 3965 | ||
| 4239 | pub const Data = struct { | 3966 | pub const Data = struct { |
| ... | @@ -4270,7 +3997,7 @@ pub const Type = struct { | ... | @@ -4270,7 +3997,7 @@ pub const Type = struct { |
| 4270 | return .{ | 3997 | return .{ |
| 4271 | .pointee_type = p.elem_type.toType(), | 3998 | .pointee_type = p.elem_type.toType(), |
| 4272 | .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, | 3999 | .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, |
| 4273 | .@"align" = @intCast(u32, p.alignment), | 4000 | .@"align" = @intCast(u32, p.alignment.toByteUnits(0)), |
| 4274 | .@"addrspace" = p.address_space, | 4001 | .@"addrspace" = p.address_space, |
| 4275 | .bit_offset = p.bit_offset, | 4002 | .bit_offset = p.bit_offset, |
| 4276 | .host_size = p.host_size, | 4003 | .host_size = p.host_size, |
| ... | @@ -4368,11 +4095,11 @@ pub const Type = struct { | ... | @@ -4368,11 +4095,11 @@ pub const Type = struct { |
| 4368 | pub const err_int = Type.u16; | 4095 | pub const err_int = Type.u16; |
| 4369 | 4096 | ||
| 4370 | pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type { | 4097 | pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type { |
| 4371 | var d = data; | 4098 | // TODO: update callsites of this function to directly call mod.ptrType |
| 4099 | // and then delete this function. | ||
| 4100 | _ = arena; | ||
| 4372 | 4101 | ||
| 4373 | if (d.size == .C) { | 4102 | var d = data; |
| 4374 | d.@"allowzero" = true; | ||
| 4375 | } | ||
| 4376 | 4103 | ||
| 4377 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee | 4104 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee |
| 4378 | // type, we change it to 0 here. If this causes an assertion trip because the | 4105 | // type, we change it to 0 here. If this causes an assertion trip because the |
| ... | @@ -4396,32 +4123,19 @@ pub const Type = struct { | ... | @@ -4396,32 +4123,19 @@ pub const Type = struct { |
| 4396 | } | 4123 | } |
| 4397 | } | 4124 | } |
| 4398 | 4125 | ||
| 4399 | ip: { | 4126 | return mod.ptrType(.{ |
| 4400 | if (d.pointee_type.ip_index == .none) break :ip; | 4127 | .elem_type = d.pointee_type.ip_index, |
| 4401 | 4128 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | |
| 4402 | if (d.sentinel) |s| { | 4129 | .alignment = InternPool.Alignment.fromByteUnits(d.@"align"), |
| 4403 | switch (s.ip_index) { | 4130 | .host_size = d.host_size, |
| 4404 | .none, .null_value => break :ip, | 4131 | .bit_offset = d.bit_offset, |
| 4405 | else => {}, | 4132 | .vector_index = d.vector_index, |
| 4406 | } | 4133 | .size = d.size, |
| 4407 | } | 4134 | .is_const = !d.mutable, |
| 4408 | 4135 | .is_volatile = d.@"volatile", | |
| 4409 | return mod.ptrType(.{ | 4136 | .is_allowzero = d.@"allowzero", |
| 4410 | .elem_type = d.pointee_type.ip_index, | 4137 | .address_space = d.@"addrspace", |
| 4411 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | 4138 | }); |
| 4412 | .alignment = d.@"align", | ||
| 4413 | .host_size = d.host_size, | ||
| 4414 | .bit_offset = d.bit_offset, | ||
| 4415 | .vector_index = d.vector_index, | ||
| 4416 | .size = d.size, | ||
| 4417 | .is_const = !d.mutable, | ||
| 4418 | .is_volatile = d.@"volatile", | ||
| 4419 | .is_allowzero = d.@"allowzero", | ||
| 4420 | .address_space = d.@"addrspace", | ||
| 4421 | }); | ||
| 4422 | } | ||
| 4423 | |||
| 4424 | return Type.Tag.pointer.create(arena, d); | ||
| 4425 | } | 4139 | } |
| 4426 | 4140 | ||
| 4427 | pub fn array( | 4141 | pub fn array( |
src/value.zig+4-8| ... | @@ -1844,8 +1844,7 @@ pub const Value = struct { | ... | @@ -1844,8 +1844,7 @@ pub const Value = struct { |
| 1844 | return false; | 1844 | return false; |
| 1845 | } | 1845 | } |
| 1846 | 1846 | ||
| 1847 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 1847 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 1848 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | ||
| 1849 | 1848 | ||
| 1850 | return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema); | 1849 | return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema); |
| 1851 | }, | 1850 | }, |
| ... | @@ -2001,8 +2000,7 @@ pub const Value = struct { | ... | @@ -2001,8 +2000,7 @@ pub const Value = struct { |
| 2001 | return false; | 2000 | return false; |
| 2002 | } | 2001 | } |
| 2003 | 2002 | ||
| 2004 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2003 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 2005 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | ||
| 2006 | const a_ptr = switch (a_ty.ptrSize(mod)) { | 2004 | const a_ptr = switch (a_ty.ptrSize(mod)) { |
| 2007 | .Slice => a.slicePtr(), | 2005 | .Slice => a.slicePtr(), |
| 2008 | .One => a, | 2006 | .One => a, |
| ... | @@ -2121,8 +2119,7 @@ pub const Value = struct { | ... | @@ -2121,8 +2119,7 @@ pub const Value = struct { |
| 2121 | .Bool, .Int, .ComptimeInt, .Pointer => switch (val.tag()) { | 2119 | .Bool, .Int, .ComptimeInt, .Pointer => switch (val.tag()) { |
| 2122 | .slice => { | 2120 | .slice => { |
| 2123 | const slice = val.castTag(.slice).?.data; | 2121 | const slice = val.castTag(.slice).?.data; |
| 2124 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2122 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 2125 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | ||
| 2126 | hash(slice.ptr, ptr_ty, hasher, mod); | 2123 | hash(slice.ptr, ptr_ty, hasher, mod); |
| 2127 | hash(slice.len, Type.usize, hasher, mod); | 2124 | hash(slice.len, Type.usize, hasher, mod); |
| 2128 | }, | 2125 | }, |
| ... | @@ -2253,8 +2250,7 @@ pub const Value = struct { | ... | @@ -2253,8 +2250,7 @@ pub const Value = struct { |
| 2253 | .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) { | 2250 | .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) { |
| 2254 | .slice => { | 2251 | .slice => { |
| 2255 | const slice = val.castTag(.slice).?.data; | 2252 | const slice = val.castTag(.slice).?.data; |
| 2256 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2253 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 2257 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | ||
| 2258 | slice.ptr.hashUncoerced(ptr_ty, hasher, mod); | 2254 | slice.ptr.hashUncoerced(ptr_ty, hasher, mod); |
| 2259 | }, | 2255 | }, |
| 2260 | else => val.hashPtr(hasher, mod), | 2256 | else => val.hashPtr(hasher, mod), |