| 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 | 186 | pub const PtrType = struct { |
| 187 | 187 | elem_type: Index, |
| 188 | 188 | sentinel: Index = .none, |
| 189 | /// If zero use pointee_type.abiAlignment() | |
| 190 | /// When creating pointer types, if alignment is equal to pointee type | |
| 191 | /// abi alignment, this value should be set to 0 instead. | |
| 192 | /// | |
| 193 | /// Please don't change this to u32 or u29. If you want to save bits, | |
| 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, | |
| 189 | /// `none` indicates the ABI alignment of the pointee_type. In this | |
| 190 | /// case, this field *must* be set to `none`, otherwise the | |
| 191 | /// `InternPool` equality and hashing functions will return incorrect | |
| 192 | /// results. | |
| 193 | alignment: Alignment = .none, | |
| 200 | 194 | /// If this is non-zero it means the pointer points to a sub-byte |
| 201 | 195 | /// range of data, which is backed by a "host integer" with this |
| 202 | 196 | /// number of bytes. |
| ... | ... | @@ -378,15 +372,11 @@ pub const Key = union(enum) { |
| 378 | 372 | /// Tells whether a parameter is noalias. See `paramIsNoalias` helper |
| 379 | 373 | /// method for accessing this. |
| 380 | 374 | noalias_bits: u32, |
| 381 | /// If zero use default target function code alignment. | |
| 382 | /// | |
| 383 | /// Please don't change this to u32 or u29. If you want to save bits, | |
| 384 | /// migrate the rest of the codebase to use the `Alignment` type rather | |
| 385 | /// than using byte units. The LLVM backend can only handle `c_uint` | |
| 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, | |
| 375 | /// `none` indicates the function has the default alignment for | |
| 376 | /// function code on the target. In this case, this field *must* be set | |
| 377 | /// to `none`, otherwise the `InternPool` equality and hashing | |
| 378 | /// functions will return incorrect results. | |
| 379 | alignment: Alignment, | |
| 390 | 380 | cc: std.builtin.CallingConvention, |
| 391 | 381 | is_var_args: bool, |
| 392 | 382 | is_generic: bool, |
| ... | ... | @@ -1500,6 +1490,13 @@ pub const Alignment = enum(u6) { |
| 1500 | 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 | 1500 | pub fn toByteUnits(a: Alignment, default: u64) u64 { |
| 1504 | 1501 | return switch (a) { |
| 1505 | 1502 | .none => default, |
| ... | ... | @@ -1509,8 +1506,14 @@ pub const Alignment = enum(u6) { |
| 1509 | 1506 | |
| 1510 | 1507 | pub fn fromByteUnits(n: u64) Alignment { |
| 1511 | 1508 | if (n == 0) return .none; |
| 1509 | assert(std.math.isPowerOfTwo(n)); | |
| 1512 | 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 | 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 | 1776 | return .{ .ptr_type = .{ |
| 1774 | 1777 | .elem_type = ptr_info.child, |
| 1775 | 1778 | .sentinel = ptr_info.sentinel, |
| 1776 | .alignment = ptr_info.flags.alignment.toByteUnits(0), | |
| 1779 | .alignment = ptr_info.flags.alignment, | |
| 1777 | 1780 | .size = ptr_info.flags.size, |
| 1778 | 1781 | .is_const = ptr_info.flags.is_const, |
| 1779 | 1782 | .is_volatile = ptr_info.flags.is_volatile, |
| ... | ... | @@ -2013,7 +2016,7 @@ fn indexToKeyFuncType(ip: InternPool, data: u32) Key.FuncType { |
| 2013 | 2016 | .return_type = type_function.data.return_type, |
| 2014 | 2017 | .comptime_bits = type_function.data.comptime_bits, |
| 2015 | 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 | 2020 | .cc = type_function.data.flags.cc, |
| 2018 | 2021 | .is_var_args = type_function.data.flags.is_var_args, |
| 2019 | 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 | 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 | 2108 | ip.items.appendAssumeCapacity(.{ |
| 2104 | 2109 | .tag = .type_pointer, |
| 2105 | 2110 | .data = try ip.addExtra(gpa, Pointer{ |
| 2106 | 2111 | .child = ptr_type.elem_type, |
| 2107 | 2112 | .sentinel = ptr_type.sentinel, |
| 2108 | 2113 | .flags = .{ |
| 2109 | .alignment = Alignment.fromByteUnits(ptr_type.alignment), | |
| 2114 | .alignment = ptr_type.alignment, | |
| 2110 | 2115 | .is_const = ptr_type.is_const, |
| 2111 | 2116 | .is_volatile = ptr_type.is_volatile, |
| 2112 | .is_allowzero = ptr_type.is_allowzero, | |
| 2117 | .is_allowzero = is_allowzero, | |
| 2113 | 2118 | .size = ptr_type.size, |
| 2114 | 2119 | .address_space = ptr_type.address_space, |
| 2115 | 2120 | .vector_index = ptr_type.vector_index, |
| ... | ... | @@ -2316,7 +2321,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 2316 | 2321 | .comptime_bits = func_type.comptime_bits, |
| 2317 | 2322 | .noalias_bits = func_type.noalias_bits, |
| 2318 | 2323 | .flags = .{ |
| 2319 | .alignment = Alignment.fromByteUnits(func_type.alignment), | |
| 2324 | .alignment = func_type.alignment, | |
| 2320 | 2325 | .cc = func_type.cc, |
| 2321 | 2326 | .is_var_args = func_type.is_var_args, |
| 2322 | 2327 | .is_generic = func_type.is_generic, |
src/Module.zig+19-17| ... | ... | @@ -6532,8 +6532,7 @@ pub fn populateTestFunctions( |
| 6532 | 6532 | try mod.ensureDeclAnalyzed(decl_index); |
| 6533 | 6533 | } |
| 6534 | 6534 | const decl = mod.declPtr(decl_index); |
| 6535 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 6536 | const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod); | |
| 6535 | const tmp_test_fn_ty = decl.ty.slicePtrFieldType(mod).childType(mod); | |
| 6537 | 6536 | |
| 6538 | 6537 | const array_decl_index = d: { |
| 6539 | 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 | 6842 | } |
| 6844 | 6843 | |
| 6845 | 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 | 6845 | return ptrType(mod, .{ .elem_type = child_type.ip_index }); |
| 6854 | 6846 | } |
| 6855 | 6847 | |
| 6856 | 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 | 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 | 6870 | pub fn funcType(mod: *Module, info: InternPool.Key.FuncType) Allocator.Error!Type { |
| 6869 | 6871 | return (try intern(mod, .{ .func_type = info })).toType(); |
| 6870 | 6872 | } |
src/Sema.zig+49-70| ... | ... | @@ -9163,7 +9163,7 @@ fn funcCommon( |
| 9163 | 9163 | .return_type = return_type.toIntern(), |
| 9164 | 9164 | .cc = cc_resolved, |
| 9165 | 9165 | .cc_is_generic = cc == null, |
| 9166 | .alignment = alignment orelse 0, | |
| 9166 | .alignment = if (alignment) |a| InternPool.Alignment.fromByteUnits(a) else .none, | |
| 9167 | 9167 | .align_is_generic = alignment == null, |
| 9168 | 9168 | .section_is_generic = section == .generic, |
| 9169 | 9169 | .addrspace_is_generic = address_space == null, |
| ... | ... | @@ -17740,10 +17740,10 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 17740 | 17740 | extra_i += 1; |
| 17741 | 17741 | const coerced = try sema.coerce(block, elem_ty, try sema.resolveInst(ref), sentinel_src); |
| 17742 | 17742 | const val = try sema.resolveConstValue(block, sentinel_src, coerced, "pointer sentinel value must be comptime-known"); |
| 17743 | break :blk val; | |
| 17744 | } else null; | |
| 17743 | break :blk val.toIntern(); | |
| 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 | 17747 | const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); |
| 17748 | 17748 | extra_i += 1; |
| 17749 | 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 | 17752 | // which case we can make this 0 without resolving it. |
| 17753 | 17753 | if (val.castTag(.lazy_align)) |payload| { |
| 17754 | 17754 | if (payload.data.eql(elem_ty, sema.mod)) { |
| 17755 | break :blk 0; | |
| 17755 | break :blk .none; | |
| 17756 | 17756 | } |
| 17757 | 17757 | } |
| 17758 | 17758 | const abi_align = @intCast(u32, (try val.getUnsignedIntAdvanced(mod, sema)).?); |
| 17759 | 17759 | try sema.validateAlign(block, align_src, abi_align); |
| 17760 | break :blk abi_align; | |
| 17761 | } else 0; | |
| 17760 | break :blk InternPool.Alignment.fromByteUnits(abi_align); | |
| 17761 | } else .none; | |
| 17762 | 17762 | |
| 17763 | 17763 | const address_space: std.builtin.AddressSpace = if (inst_data.flags.has_addrspace) blk: { |
| 17764 | 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 | 17789 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); |
| 17790 | 17790 | } |
| 17791 | 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 | 17793 | abi_align != fn_align) |
| 17794 | 17794 | { |
| 17795 | 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 | 17815 | } |
| 17816 | 17816 | } |
| 17817 | 17817 | |
| 17818 | const ty = try Type.ptr(sema.arena, sema.mod, .{ | |
| 17819 | .pointee_type = elem_ty, | |
| 17818 | const ty = try mod.ptrType(.{ | |
| 17819 | .elem_type = elem_ty.toIntern(), | |
| 17820 | 17820 | .sentinel = sentinel, |
| 17821 | .@"align" = abi_align, | |
| 17822 | .@"addrspace" = address_space, | |
| 17821 | .alignment = abi_align, | |
| 17822 | .address_space = address_space, | |
| 17823 | 17823 | .bit_offset = bit_offset, |
| 17824 | 17824 | .host_size = host_size, |
| 17825 | .mutable = inst_data.flags.is_mutable, | |
| 17826 | .@"allowzero" = inst_data.flags.is_allowzero, | |
| 17827 | .@"volatile" = inst_data.flags.is_volatile, | |
| 17825 | .is_const = !inst_data.flags.is_mutable, | |
| 17826 | .is_allowzero = inst_data.flags.is_allowzero, | |
| 17827 | .is_volatile = inst_data.flags.is_volatile, | |
| 17828 | 17828 | .size = inst_data.size, |
| 17829 | 17829 | }); |
| 17830 | 17830 | return sema.addType(ty); |
| ... | ... | @@ -18905,10 +18905,13 @@ fn zirReify( |
| 18905 | 18905 | if (!try sema.intFitsInType(alignment_val, Type.u32, null)) { |
| 18906 | 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 | 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 | 18915 | unresolved_elem_ty |
| 18913 | 18916 | else t: { |
| 18914 | 18917 | const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty); |
| ... | ... | @@ -18918,18 +18921,21 @@ fn zirReify( |
| 18918 | 18921 | |
| 18919 | 18922 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); |
| 18920 | 18923 | |
| 18921 | var actual_sentinel: ?Value = null; | |
| 18922 | if (!sentinel_val.isNull(mod)) { | |
| 18923 | if (ptr_size == .One or ptr_size == .C) { | |
| 18924 | return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{}); | |
| 18924 | const actual_sentinel: InternPool.Index = s: { | |
| 18925 | if (!sentinel_val.isNull(mod)) { | |
| 18926 | if (ptr_size == .One or ptr_size == .C) { | |
| 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; | |
| 18927 | const ptr_ty = try Type.ptr(sema.arena, mod, .{ | |
| 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 | } | |
| 18937 | break :s .none; | |
| 18938 | }; | |
| 18933 | 18939 | |
| 18934 | 18940 | if (elem_ty.zigTypeTag(mod) == .NoReturn) { |
| 18935 | 18941 | return sema.fail(block, src, "pointer to noreturn not allowed", .{}); |
| ... | ... | @@ -18938,7 +18944,7 @@ fn zirReify( |
| 18938 | 18944 | return sema.fail(block, src, "function pointers must be single pointers", .{}); |
| 18939 | 18945 | } |
| 18940 | 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 | 18948 | abi_align != fn_align) |
| 18943 | 18949 | { |
| 18944 | 18950 | return sema.fail(block, src, "function pointer alignment disagrees with function alignment", .{}); |
| ... | ... | @@ -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 | 18974 | .size = ptr_size, |
| 18969 | .mutable = !is_const_val.toBool(mod), | |
| 18970 | .@"volatile" = is_volatile_val.toBool(mod), | |
| 18971 | .@"align" = abi_align, | |
| 18972 | .@"addrspace" = mod.toEnum(std.builtin.AddressSpace, address_space_val), | |
| 18973 | .pointee_type = try elem_ty.copy(sema.arena), | |
| 18974 | .@"allowzero" = is_allowzero_val.toBool(mod), | |
| 18975 | .is_const = is_const_val.toBool(mod), | |
| 18976 | .is_volatile = is_volatile_val.toBool(mod), | |
| 18977 | .alignment = abi_align, | |
| 18978 | .address_space = mod.toEnum(std.builtin.AddressSpace, address_space_val), | |
| 18979 | .elem_type = elem_ty.toIntern(), | |
| 18980 | .is_allowzero = is_allowzero_val.toBool(mod), | |
| 18975 | 18981 | .sentinel = actual_sentinel, |
| 18976 | 18982 | }); |
| 18977 | 18983 | return sema.addType(ty); |
| ... | ... | @@ -19470,9 +19476,9 @@ fn zirReify( |
| 19470 | 19476 | } |
| 19471 | 19477 | const alignment = @intCast(u29, alignment_val.toUnsignedInt(mod)); |
| 19472 | 19478 | if (alignment == target_util.defaultFunctionAlignment(target)) { |
| 19473 | break :alignment 0; | |
| 19479 | break :alignment .none; | |
| 19474 | 19480 | } else { |
| 19475 | break :alignment alignment; | |
| 19481 | break :alignment InternPool.Alignment.fromByteUnits(alignment); | |
| 19476 | 19482 | } |
| 19477 | 19483 | }; |
| 19478 | 19484 | const return_type = return_type_val.optionalValue(mod) orelse |
| ... | ... | @@ -24291,8 +24297,7 @@ fn fieldPtr( |
| 24291 | 24297 | const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty; |
| 24292 | 24298 | |
| 24293 | 24299 | if (mem.eql(u8, field_name, "ptr")) { |
| 24294 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); | |
| 24295 | const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod); | |
| 24300 | const slice_ptr_ty = inner_ty.slicePtrFieldType(mod); | |
| 24296 | 24301 | |
| 24297 | 24302 | const result_ty = try Type.ptr(sema.arena, mod, .{ |
| 24298 | 24303 | .pointee_type = slice_ptr_ty, |
| ... | ... | @@ -27914,7 +27919,7 @@ fn beginComptimePtrMutation( |
| 27914 | 27919 | sema, |
| 27915 | 27920 | block, |
| 27916 | 27921 | src, |
| 27917 | parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod), | |
| 27922 | parent.ty.slicePtrFieldType(mod), | |
| 27918 | 27923 | &val_ptr.castTag(.slice).?.data.ptr, |
| 27919 | 27924 | ptr_elem_ty, |
| 27920 | 27925 | parent.decl_ref_mut, |
| ... | ... | @@ -27981,7 +27986,7 @@ fn beginComptimePtrMutation( |
| 27981 | 27986 | sema, |
| 27982 | 27987 | block, |
| 27983 | 27988 | src, |
| 27984 | parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod), | |
| 27989 | parent.ty.slicePtrFieldType(mod), | |
| 27985 | 27990 | &val_ptr.castTag(.slice).?.data.ptr, |
| 27986 | 27991 | ptr_elem_ty, |
| 27987 | 27992 | parent.decl_ref_mut, |
| ... | ... | @@ -28363,7 +28368,7 @@ fn beginComptimePtrLoad( |
| 28363 | 28368 | const slice_val = tv.val.castTag(.slice).?.data; |
| 28364 | 28369 | deref.pointee = switch (field_index) { |
| 28365 | 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 | 28372 | .val = slice_val.ptr, |
| 28368 | 28373 | }, |
| 28369 | 28374 | Value.Payload.Slice.len_index => TypedValue{ |
| ... | ... | @@ -29454,8 +29459,7 @@ fn analyzeSlicePtr( |
| 29454 | 29459 | slice_ty: Type, |
| 29455 | 29460 | ) CompileError!Air.Inst.Ref { |
| 29456 | 29461 | const mod = sema.mod; |
| 29457 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); | |
| 29458 | const result_ty = slice_ty.slicePtrFieldType(buf, mod); | |
| 29462 | const result_ty = slice_ty.slicePtrFieldType(mod); | |
| 29459 | 29463 | if (try sema.resolveMaybeUndefVal(slice)) |val| { |
| 29460 | 29464 | if (val.isUndef(mod)) return sema.addConstUndef(result_ty); |
| 29461 | 29465 | return sema.addConstant(result_ty, val.slicePtr()); |
| ... | ... | @@ -31611,15 +31615,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 31611 | 31615 | .inferred_alloc_mut => unreachable, |
| 31612 | 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 | 31618 | .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()), |
| 31624 | 31619 | }, |
| 31625 | 31620 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | ... | @@ -33048,7 +33043,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33048 | 33043 | .error_set_merged, |
| 33049 | 33044 | .error_union, |
| 33050 | 33045 | .error_set_inferred, |
| 33051 | .pointer, | |
| 33052 | 33046 | => return null, |
| 33053 | 33047 | |
| 33054 | 33048 | .inferred_alloc_const => unreachable, |
| ... | ... | @@ -33604,12 +33598,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { |
| 33604 | 33598 | }; |
| 33605 | 33599 | |
| 33606 | 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 | 33601 | .inferred_alloc_const => unreachable, |
| 33614 | 33602 | .inferred_alloc_mut => unreachable, |
| 33615 | 33603 | |
| ... | ... | @@ -33638,15 +33626,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { |
| 33638 | 33626 | .inferred_alloc_mut => unreachable, |
| 33639 | 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 | 33629 | .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()), |
| 33651 | 33630 | }, |
| 33652 | 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 | 3434 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3435 | 3435 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3436 | 3436 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| 3437 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 3438 | const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod); | |
| 3437 | const ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 3439 | 3438 | |
| 3440 | 3439 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 3441 | 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 | 2432 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2433 | 2433 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2434 | 2434 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { |
| 2435 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2436 | const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod); | |
| 2435 | const ptr_ty = slice_ty.slicePtrFieldType(mod); | |
| 2437 | 2436 | |
| 2438 | 2437 | const slice_mcv = try self.resolveInst(bin_op.lhs); |
| 2439 | 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 | 2462 | const elem_ty = slice_ty.childType(mod); |
| 2463 | 2463 | const elem_size = elem_ty.abiSize(mod); |
| 2464 | 2464 | |
| 2465 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2466 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | |
| 2465 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 2467 | 2466 | |
| 2468 | 2467 | const index_lock: ?RegisterLock = if (index_mcv == .register) |
| 2469 | 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 | 4052 | |
| 4053 | 4053 | const elem_ty = slice_ty.childType(mod); |
| 4054 | 4054 | const elem_size = elem_ty.abiSize(mod); |
| 4055 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 4056 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | |
| 4055 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 4057 | 4056 | |
| 4058 | 4057 | const index_ty = self.typeOf(rhs); |
| 4059 | 4058 | const index_mcv = try self.resolveInst(rhs); |
| ... | ... | @@ -4082,8 +4081,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 4082 | 4081 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 4083 | 4082 | const slice_ty = self.typeOf(bin_op.lhs); |
| 4084 | 4083 | |
| 4085 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 4086 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod); | |
| 4084 | const slice_ptr_field_type = slice_ty.slicePtrFieldType(mod); | |
| 4087 | 4085 | const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs); |
| 4088 | 4086 | const dst_mcv = try self.allocRegOrMem(inst, false); |
| 4089 | 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 | 4279 | break :blk MCValue{ .register = reg }; |
| 4282 | 4280 | } else ptr; |
| 4283 | 4281 | |
| 4284 | var ptr_tag_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 4282 | const ptr_tag_ty = try mod.adjustPtrTypeChild(ptr_union_ty, tag_ty); | |
| 4289 | 4283 | try self.store(ptr_tag_ty, adjusted_ptr, tag); |
| 4290 | 4284 | |
| 4291 | 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 | 8665 | |
| 8672 | 8666 | const pl_ty = opt_ty.optionalChild(mod); |
| 8673 | 8667 | |
| 8674 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 8675 | 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 | 8670 | else |
| 8678 | 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 | 8756 | const opt_ty = ptr_ty.childType(mod); |
| 8764 | 8757 | const pl_ty = opt_ty.optionalChild(mod); |
| 8765 | 8758 | |
| 8766 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 8767 | 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 | 8761 | else |
| 8770 | 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 | 10795 | // here to elide it. |
| 10804 | 10796 | switch (dst_ptr_ty.ptrSize(mod)) { |
| 10805 | 10797 | .Slice => { |
| 10806 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 10807 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod); | |
| 10798 | const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(mod); | |
| 10808 | 10799 | |
| 10809 | 10800 | // TODO: this only handles slices stored in the stack |
| 10810 | 10801 | const ptr = dst_ptr; |
src/codegen.zig+3-6| ... | ... | @@ -347,8 +347,7 @@ pub fn generateSymbol( |
| 347 | 347 | const slice = typed_value.val.castTag(.slice).?.data; |
| 348 | 348 | |
| 349 | 349 | // generate ptr |
| 350 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 351 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod); | |
| 350 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod); | |
| 352 | 351 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 353 | 352 | .ty = slice_ptr_field_type, |
| 354 | 353 | .val = slice.ptr, |
| ... | ... | @@ -850,10 +849,9 @@ fn lowerParentPtr( |
| 850 | 849 | reloc_info.offset(@intCast(u32, switch (field_ptr.container_ty.zigTypeTag(mod)) { |
| 851 | 850 | .Pointer => offset: { |
| 852 | 851 | assert(field_ptr.container_ty.isSlice(mod)); |
| 853 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 854 | 852 | break :offset switch (field_ptr.field_index) { |
| 855 | 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 | 855 | else => unreachable, |
| 858 | 856 | }; |
| 859 | 857 | }, |
| ... | ... | @@ -952,8 +950,7 @@ fn lowerDeclRef( |
| 952 | 950 | const mod = bin_file.options.module.?; |
| 953 | 951 | if (typed_value.ty.isSlice(mod)) { |
| 954 | 952 | // generate ptr |
| 955 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 956 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod); | |
| 953 | const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(mod); | |
| 957 | 954 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 958 | 955 | .ty = slice_ptr_field_type, |
| 959 | 956 | .val = typed_value.val, |
src/codegen/c.zig+15-41| ... | ... | @@ -566,8 +566,7 @@ pub const DeclGen = struct { |
| 566 | 566 | try writer.writeAll("){ .ptr = "); |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 570 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer); | |
| 569 | try dg.renderValue(writer, ty.slicePtrFieldType(mod), val.slicePtr(), .Initializer); | |
| 571 | 570 | |
| 572 | 571 | const len_val = try mod.intValue(Type.usize, val.sliceLen(mod)); |
| 573 | 572 | |
| ... | ... | @@ -631,11 +630,7 @@ pub const DeclGen = struct { |
| 631 | 630 | // Ensure complete type definition is visible before accessing fields. |
| 632 | 631 | _ = try dg.typeToIndex(field_ptr.container_ty, .complete); |
| 633 | 632 | |
| 634 | var container_ptr_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 633 | const container_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, field_ptr.container_ty); | |
| 639 | 634 | |
| 640 | 635 | switch (fieldLocation( |
| 641 | 636 | field_ptr.container_ty, |
| ... | ... | @@ -661,11 +656,7 @@ pub const DeclGen = struct { |
| 661 | 656 | try dg.writeCValue(writer, field); |
| 662 | 657 | }, |
| 663 | 658 | .byte_offset => |byte_offset| { |
| 664 | var u8_ptr_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 659 | const u8_ptr_ty = try mod.adjustPtrTypeChild(ptr_ty, Type.u8); | |
| 669 | 660 | |
| 670 | 661 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); |
| 671 | 662 | |
| ... | ... | @@ -788,8 +779,7 @@ pub const DeclGen = struct { |
| 788 | 779 | } |
| 789 | 780 | |
| 790 | 781 | try writer.writeAll("{("); |
| 791 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 792 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | |
| 782 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 793 | 783 | try dg.renderType(writer, ptr_ty); |
| 794 | 784 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); |
| 795 | 785 | } else { |
| ... | ... | @@ -1068,10 +1058,9 @@ pub const DeclGen = struct { |
| 1068 | 1058 | } |
| 1069 | 1059 | |
| 1070 | 1060 | const slice = val.castTag(.slice).?.data; |
| 1071 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 1072 | 1061 | |
| 1073 | 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 | 1064 | try writer.writeAll(", "); |
| 1076 | 1065 | try dg.renderValue(writer, Type.usize, slice.len, initializer_type); |
| 1077 | 1066 | try writer.writeByte('}'); |
| ... | ... | @@ -1536,8 +1525,8 @@ pub const DeclGen = struct { |
| 1536 | 1525 | |
| 1537 | 1526 | switch (kind) { |
| 1538 | 1527 | .forward => {}, |
| 1539 | .complete => if (fn_info.alignment > 0) | |
| 1540 | try w.print(" zig_align_fn({})", .{fn_info.alignment}), | |
| 1528 | .complete => if (fn_info.alignment.toByteUnitsOptional()) |a| | |
| 1529 | try w.print(" zig_align_fn({})", .{a}), | |
| 1541 | 1530 | else => unreachable, |
| 1542 | 1531 | } |
| 1543 | 1532 | |
| ... | ... | @@ -1561,8 +1550,8 @@ pub const DeclGen = struct { |
| 1561 | 1550 | ); |
| 1562 | 1551 | |
| 1563 | 1552 | switch (kind) { |
| 1564 | .forward => if (fn_info.alignment > 0) | |
| 1565 | try w.print(" zig_align_fn({})", .{fn_info.alignment}), | |
| 1553 | .forward => if (fn_info.alignment.toByteUnitsOptional()) |a| | |
| 1554 | try w.print(" zig_align_fn({})", .{a}), | |
| 1566 | 1555 | .complete => {}, |
| 1567 | 1556 | else => unreachable, |
| 1568 | 1557 | } |
| ... | ... | @@ -4062,8 +4051,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4062 | 4051 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| 4063 | 4052 | |
| 4064 | 4053 | const inst_ty = f.typeOfIndex(inst); |
| 4065 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 4066 | const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod); | |
| 4054 | const ptr_ty = inst_ty.slicePtrFieldType(mod); | |
| 4067 | 4055 | |
| 4068 | 4056 | const writer = f.object.writer(); |
| 4069 | 4057 | const local = try f.allocLocal(inst, inst_ty); |
| ... | ... | @@ -5047,7 +5035,6 @@ fn airIsNull( |
| 5047 | 5035 | const operand_ty = f.typeOf(un_op); |
| 5048 | 5036 | const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; |
| 5049 | 5037 | const payload_ty = optional_ty.optionalChild(mod); |
| 5050 | var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 5051 | 5038 | |
| 5052 | 5039 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) |
| 5053 | 5040 | TypedValue{ .ty = Type.bool, .val = Value.true } |
| ... | ... | @@ -5058,7 +5045,7 @@ fn airIsNull( |
| 5058 | 5045 | TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) } |
| 5059 | 5046 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { |
| 5060 | 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 | 5049 | break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null }; |
| 5063 | 5050 | } else rhs: { |
| 5064 | 5051 | try writer.writeAll(".is_null"); |
| ... | ... | @@ -5278,11 +5265,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5278 | 5265 | switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) { |
| 5279 | 5266 | .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), |
| 5280 | 5267 | .field => |field| { |
| 5281 | var u8_ptr_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 5268 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); | |
| 5286 | 5269 | |
| 5287 | 5270 | try writer.writeAll("(("); |
| 5288 | 5271 | try f.renderType(writer, u8_ptr_ty); |
| ... | ... | @@ -5295,11 +5278,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5295 | 5278 | try writer.writeAll("))"); |
| 5296 | 5279 | }, |
| 5297 | 5280 | .byte_offset => |byte_offset| { |
| 5298 | var u8_ptr_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 5281 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); | |
| 5303 | 5282 | |
| 5304 | 5283 | const byte_offset_val = try mod.intValue(Type.usize, byte_offset); |
| 5305 | 5284 | |
| ... | ... | @@ -5347,11 +5326,7 @@ fn fieldPtr( |
| 5347 | 5326 | try f.writeCValueDerefMember(writer, container_ptr_val, field); |
| 5348 | 5327 | }, |
| 5349 | 5328 | .byte_offset => |byte_offset| { |
| 5350 | var u8_ptr_pl: Type.Payload.Pointer = .{ | |
| 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); | |
| 5329 | const u8_ptr_ty = try mod.adjustPtrTypeChild(field_ptr_ty, Type.u8); | |
| 5355 | 5330 | |
| 5356 | 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 | 5769 | // Unfortunately, C does not support any equivalent to |
| 5795 | 5770 | // &(*(void *)p)[0], although LLVM does via GetElementPtr |
| 5796 | 5771 | if (operand == .undef) { |
| 5797 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 5798 | try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer); | |
| 5772 | try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(mod) }, .Initializer); | |
| 5799 | 5773 | } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5800 | 5774 | try writer.writeAll("&("); |
| 5801 | 5775 | try f.writeCValueDeref(writer, operand); |
src/codegen/c/type.zig+1-2| ... | ... | @@ -1431,8 +1431,7 @@ pub const CType = extern union { |
| 1431 | 1431 | .complete, .parameter, .global => try lookup.typeToIndex(ty, .forward), |
| 1432 | 1432 | .payload => unreachable, |
| 1433 | 1433 | }) |fwd_idx| { |
| 1434 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 1435 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | |
| 1434 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 1436 | 1435 | if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| { |
| 1437 | 1436 | self.storage = .{ .anon = undefined }; |
| 1438 | 1437 | self.storage.anon.fields[0] = .{ |
src/codegen/llvm.zig+45-74| ... | ... | @@ -1591,40 +1591,30 @@ pub const Object = struct { |
| 1591 | 1591 | }, |
| 1592 | 1592 | .Pointer => { |
| 1593 | 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 | |
| 1597 | ptr_info.@"addrspace" != .generic or | |
| 1596 | if (ptr_info.sentinel != .none or | |
| 1597 | ptr_info.address_space != .generic or | |
| 1598 | 1598 | ptr_info.bit_offset != 0 or |
| 1599 | 1599 | ptr_info.host_size != 0 or |
| 1600 | 1600 | ptr_info.vector_index != .none or |
| 1601 | ptr_info.@"allowzero" or | |
| 1602 | !ptr_info.mutable or | |
| 1603 | ptr_info.@"volatile" or | |
| 1601 | ptr_info.is_allowzero or | |
| 1602 | ptr_info.is_const or | |
| 1603 | ptr_info.is_volatile or | |
| 1604 | 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 = .{ | |
| 1608 | .data = .{ | |
| 1609 | .pointee_type = ptr_info.pointee_type, | |
| 1610 | .sentinel = null, | |
| 1611 | .@"align" = ptr_info.@"align", | |
| 1612 | .@"addrspace" = .generic, | |
| 1613 | .bit_offset = 0, | |
| 1614 | .host_size = 0, | |
| 1615 | .@"allowzero" = false, | |
| 1616 | .mutable = true, | |
| 1617 | .@"volatile" = false, | |
| 1618 | .size = switch (ptr_info.size) { | |
| 1619 | .Many, .C, .One => .One, | |
| 1620 | .Slice => .Slice, | |
| 1621 | }, | |
| 1607 | const bland_ptr_ty = try mod.ptrType(.{ | |
| 1608 | .elem_type = if (!ptr_info.elem_type.toType().hasRuntimeBitsIgnoreComptime(mod)) | |
| 1609 | .anyopaque_type | |
| 1610 | else | |
| 1611 | ptr_info.elem_type, | |
| 1612 | .alignment = ptr_info.alignment, | |
| 1613 | .size = switch (ptr_info.size) { | |
| 1614 | .Many, .C, .One => .One, | |
| 1615 | .Slice => .Slice, | |
| 1622 | 1616 | }, |
| 1623 | }; | |
| 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); | |
| 1617 | }); | |
| 1628 | 1618 | const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve); |
| 1629 | 1619 | // The recursive call to `lowerDebugType` means we can't use `gop` anymore. |
| 1630 | 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 | 1622 | } |
| 1633 | 1623 | |
| 1634 | 1624 | if (ty.isSlice(mod)) { |
| 1635 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 1636 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | |
| 1625 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 1637 | 1626 | const len_ty = Type.usize; |
| 1638 | 1627 | |
| 1639 | 1628 | const name = try ty.nameAlloc(gpa, o.module); |
| ... | ... | @@ -1711,7 +1700,7 @@ pub const Object = struct { |
| 1711 | 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 | 1704 | const name = try ty.nameAlloc(gpa, o.module); |
| 1716 | 1705 | defer gpa.free(name); |
| 1717 | 1706 | const ptr_di_ty = dib.createPointerType( |
| ... | ... | @@ -2625,8 +2614,8 @@ pub const DeclGen = struct { |
| 2625 | 2614 | }, |
| 2626 | 2615 | } |
| 2627 | 2616 | |
| 2628 | if (fn_info.alignment != 0) { | |
| 2629 | llvm_fn.setAlignment(@intCast(c_uint, fn_info.alignment)); | |
| 2617 | if (fn_info.alignment.toByteUnitsOptional()) |a| { | |
| 2618 | llvm_fn.setAlignment(@intCast(c_uint, a)); | |
| 2630 | 2619 | } |
| 2631 | 2620 | |
| 2632 | 2621 | // Function attributes that are independent of analysis results of the function body. |
| ... | ... | @@ -2819,8 +2808,7 @@ pub const DeclGen = struct { |
| 2819 | 2808 | .Bool => return dg.context.intType(1), |
| 2820 | 2809 | .Pointer => { |
| 2821 | 2810 | if (t.isSlice(mod)) { |
| 2822 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2823 | const ptr_type = t.slicePtrFieldType(&buf, mod); | |
| 2811 | const ptr_type = t.slicePtrFieldType(mod); | |
| 2824 | 2812 | |
| 2825 | 2813 | const fields: [2]*llvm.Type = .{ |
| 2826 | 2814 | try dg.lowerType(ptr_type), |
| ... | ... | @@ -3176,11 +3164,10 @@ pub const DeclGen = struct { |
| 3176 | 3164 | }, |
| 3177 | 3165 | .slice => { |
| 3178 | 3166 | const param_ty = fn_info.param_types[it.zig_index - 1].toType(); |
| 3179 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 3180 | 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 | 3169 | else |
| 3183 | param_ty.slicePtrFieldType(&buf, mod); | |
| 3170 | param_ty.slicePtrFieldType(mod); | |
| 3184 | 3171 | const ptr_llvm_ty = try dg.lowerType(ptr_ty); |
| 3185 | 3172 | const len_llvm_ty = try dg.lowerType(Type.usize); |
| 3186 | 3173 | |
| ... | ... | @@ -3368,10 +3355,9 @@ pub const DeclGen = struct { |
| 3368 | 3355 | }, |
| 3369 | 3356 | .slice => { |
| 3370 | 3357 | const slice = tv.val.castTag(.slice).?.data; |
| 3371 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 3372 | 3358 | const fields: [2]*llvm.Value = .{ |
| 3373 | 3359 | try dg.lowerValue(.{ |
| 3374 | .ty = tv.ty.slicePtrFieldType(&buf, mod), | |
| 3360 | .ty = tv.ty.slicePtrFieldType(mod), | |
| 3375 | 3361 | .val = slice.ptr, |
| 3376 | 3362 | }), |
| 3377 | 3363 | try dg.lowerValue(.{ |
| ... | ... | @@ -4171,8 +4157,7 @@ pub const DeclGen = struct { |
| 4171 | 4157 | ) Error!*llvm.Value { |
| 4172 | 4158 | const mod = self.module; |
| 4173 | 4159 | if (tv.ty.isSlice(mod)) { |
| 4174 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 4175 | const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod); | |
| 4160 | const ptr_ty = tv.ty.slicePtrFieldType(mod); | |
| 4176 | 4161 | const fields: [2]*llvm.Value = .{ |
| 4177 | 4162 | try self.lowerValue(.{ |
| 4178 | 4163 | .ty = ptr_ty, |
| ... | ... | @@ -6043,17 +6028,14 @@ pub const FuncGen = struct { |
| 6043 | 6028 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, ""); |
| 6044 | 6029 | const field_ptr_ty = try mod.ptrType(.{ |
| 6045 | 6030 | .elem_type = llvm_field.ty.ip_index, |
| 6046 | .alignment = llvm_field.alignment, | |
| 6031 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | |
| 6047 | 6032 | }); |
| 6048 | 6033 | if (isByRef(field_ty, mod)) { |
| 6049 | 6034 | if (canElideLoad(self, body_tail)) |
| 6050 | 6035 | return field_ptr; |
| 6051 | 6036 | |
| 6052 | const field_alignment = if (llvm_field.alignment != 0) | |
| 6053 | llvm_field.alignment | |
| 6054 | else | |
| 6055 | llvm_field.ty.abiAlignment(mod); | |
| 6056 | return self.loadByRef(field_ptr, field_ty, field_alignment, false); | |
| 6037 | assert(llvm_field.alignment != 0); | |
| 6038 | return self.loadByRef(field_ptr, field_ty, llvm_field.alignment, false); | |
| 6057 | 6039 | } else { |
| 6058 | 6040 | return self.load(field_ptr, field_ptr_ty); |
| 6059 | 6041 | } |
| ... | ... | @@ -6151,7 +6133,7 @@ pub const FuncGen = struct { |
| 6151 | 6133 | const fn_ty = try mod.funcType(.{ |
| 6152 | 6134 | .param_types = &.{}, |
| 6153 | 6135 | .return_type = .void_type, |
| 6154 | .alignment = 0, | |
| 6136 | .alignment = .none, | |
| 6155 | 6137 | .noalias_bits = 0, |
| 6156 | 6138 | .comptime_bits = 0, |
| 6157 | 6139 | .cc = .Unspecified, |
| ... | ... | @@ -6655,8 +6637,7 @@ pub const FuncGen = struct { |
| 6655 | 6637 | operand; |
| 6656 | 6638 | if (payload_ty.isSlice(mod)) { |
| 6657 | 6639 | const slice_ptr = self.builder.buildExtractValue(loaded, 0, ""); |
| 6658 | var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 6659 | const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod)); | |
| 6640 | const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(mod)); | |
| 6660 | 6641 | return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), ""); |
| 6661 | 6642 | } |
| 6662 | 6643 | return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), ""); |
| ... | ... | @@ -6923,7 +6904,7 @@ pub const FuncGen = struct { |
| 6923 | 6904 | const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, ""); |
| 6924 | 6905 | const field_ptr_ty = try mod.ptrType(.{ |
| 6925 | 6906 | .elem_type = llvm_field.ty.ip_index, |
| 6926 | .alignment = llvm_field.alignment, | |
| 6907 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(llvm_field.alignment), | |
| 6927 | 6908 | }); |
| 6928 | 6909 | return self.load(field_ptr, field_ptr_ty); |
| 6929 | 6910 | } |
| ... | ... | @@ -9319,14 +9300,12 @@ pub const FuncGen = struct { |
| 9319 | 9300 | const llvm_i = llvmField(result_ty, i, mod).?.index; |
| 9320 | 9301 | indices[1] = llvm_u32.constInt(llvm_i, .False); |
| 9321 | 9302 | const field_ptr = self.builder.buildInBoundsGEP(llvm_result_ty, alloca_inst, &indices, indices.len, ""); |
| 9322 | var field_ptr_payload: Type.Payload.Pointer = .{ | |
| 9323 | .data = .{ | |
| 9324 | .pointee_type = self.typeOf(elem), | |
| 9325 | .@"align" = result_ty.structFieldAlign(i, mod), | |
| 9326 | .@"addrspace" = .generic, | |
| 9327 | }, | |
| 9328 | }; | |
| 9329 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | |
| 9303 | const field_ptr_ty = try mod.ptrType(.{ | |
| 9304 | .elem_type = self.typeOf(elem).toIntern(), | |
| 9305 | .alignment = InternPool.Alignment.fromNonzeroByteUnits( | |
| 9306 | result_ty.structFieldAlign(i, mod), | |
| 9307 | ), | |
| 9308 | }); | |
| 9330 | 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 | 9329 | const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); |
| 9351 | 9330 | |
| 9352 | 9331 | const array_info = result_ty.arrayInfo(mod); |
| 9353 | var elem_ptr_payload: Type.Payload.Pointer = .{ | |
| 9354 | .data = .{ | |
| 9355 | .pointee_type = array_info.elem_type, | |
| 9356 | .@"addrspace" = .generic, | |
| 9357 | }, | |
| 9358 | }; | |
| 9359 | const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); | |
| 9332 | const elem_ptr_ty = try mod.ptrType(.{ | |
| 9333 | .elem_type = array_info.elem_type.toIntern(), | |
| 9334 | }); | |
| 9360 | 9335 | |
| 9361 | 9336 | for (elements, 0..) |elem, i| { |
| 9362 | 9337 | const indices: [2]*llvm.Value = .{ |
| ... | ... | @@ -9476,14 +9451,10 @@ pub const FuncGen = struct { |
| 9476 | 9451 | // tag and the payload. |
| 9477 | 9452 | const index_type = self.context.intType(32); |
| 9478 | 9453 | |
| 9479 | var field_ptr_payload: Type.Payload.Pointer = .{ | |
| 9480 | .data = .{ | |
| 9481 | .pointee_type = field.ty, | |
| 9482 | .@"align" = field_align, | |
| 9483 | .@"addrspace" = .generic, | |
| 9484 | }, | |
| 9485 | }; | |
| 9486 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | |
| 9454 | const field_ptr_ty = try mod.ptrType(.{ | |
| 9455 | .elem_type = field.ty.toIntern(), | |
| 9456 | .alignment = InternPool.Alignment.fromNonzeroByteUnits(field_align), | |
| 9457 | }); | |
| 9487 | 9458 | if (layout.tag_size == 0) { |
| 9488 | 9459 | const indices: [3]*llvm.Value = .{ |
| 9489 | 9460 | index_type.constNull(), |
src/codegen/spirv.zig+2-4| ... | ... | @@ -669,8 +669,7 @@ pub const DeclGen = struct { |
| 669 | 669 | .slice => { |
| 670 | 670 | const slice = val.castTag(.slice).?.data; |
| 671 | 671 | |
| 672 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 673 | const ptr_ty = ty.slicePtrFieldType(&buf, mod); | |
| 672 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 674 | 673 | |
| 675 | 674 | try self.lower(ptr_ty, slice.ptr); |
| 676 | 675 | try self.addInt(Type.usize, slice.len); |
| ... | ... | @@ -2991,9 +2990,8 @@ pub const DeclGen = struct { |
| 2991 | 2990 | if (optional_ty.optionalReprIsPayload(mod)) { |
| 2992 | 2991 | // Pointer payload represents nullability: pointer or slice. |
| 2993 | 2992 | |
| 2994 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2995 | 2993 | const ptr_ty = if (payload_ty.isSlice(mod)) |
| 2996 | payload_ty.slicePtrFieldType(&ptr_buf, mod) | |
| 2994 | payload_ty.slicePtrFieldType(mod) | |
| 2997 | 2995 | else |
| 2998 | 2996 | payload_ty; |
| 2999 | 2997 |
src/link/Dwarf.zig+1-2| ... | ... | @@ -277,8 +277,7 @@ pub const DeclState = struct { |
| 277 | 277 | // DW.AT.type, DW.FORM.ref4 |
| 278 | 278 | var index = dbg_info_buffer.items.len; |
| 279 | 279 | try dbg_info_buffer.resize(index + 4); |
| 280 | var buf = try arena.create(Type.SlicePtrFieldTypeBuffer); | |
| 281 | const ptr_ty = ty.slicePtrFieldType(buf, mod); | |
| 280 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 282 | 281 | try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index)); |
| 283 | 282 | // DW.AT.data_member_location, DW.FORM.udata |
| 284 | 283 | try dbg_info_buffer.ensureUnusedCapacity(6); |
src/type.zig+117-403| ... | ... | @@ -42,7 +42,6 @@ pub const Type = struct { |
| 42 | 42 | .error_set_merged, |
| 43 | 43 | => return .ErrorSet, |
| 44 | 44 | |
| 45 | .pointer, | |
| 46 | 45 | .inferred_alloc_const, |
| 47 | 46 | .inferred_alloc_mut, |
| 48 | 47 | => return .Pointer, |
| ... | ... | @@ -250,17 +249,9 @@ pub const Type = struct { |
| 250 | 249 | return elem_ty; |
| 251 | 250 | } |
| 252 | 251 | |
| 252 | /// Asserts the type is a pointer. | |
| 253 | 253 | pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { |
| 254 | return switch (ty.ip_index) { | |
| 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 | }; | |
| 254 | return !mod.intern_pool.indexToKey(ty.ip_index).ptr_type.is_const; | |
| 264 | 255 | } |
| 265 | 256 | |
| 266 | 257 | pub const ArrayInfo = 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 { | |
| 281 | return switch (ty.ip_index) { | |
| 282 | .none => switch (ty.tag()) { | |
| 283 | .pointer => ty.castTag(.pointer).?.data, | |
| 284 | ||
| 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 | }, | |
| 271 | pub fn ptrInfoIp(ty: Type, ip: InternPool) InternPool.Key.PtrType { | |
| 272 | return switch (ip.indexToKey(ty.ip_index)) { | |
| 273 | .ptr_type => |p| p, | |
| 274 | .opt_type => |child| switch (ip.indexToKey(child)) { | |
| 275 | .ptr_type => |p| p, | |
| 293 | 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 | 286 | pub fn eql(a: Type, b: Type, mod: *Module) bool { |
| 299 | 287 | if (a.ip_index != .none or b.ip_index != .none) { |
| 300 | 288 | // The InternPool data structure hashes based on Key to make interned objects |
| ... | ... | @@ -335,7 +323,6 @@ pub const Type = struct { |
| 335 | 323 | return true; |
| 336 | 324 | }, |
| 337 | 325 | |
| 338 | .pointer, | |
| 339 | 326 | .inferred_alloc_const, |
| 340 | 327 | .inferred_alloc_mut, |
| 341 | 328 | => { |
| ... | ... | @@ -434,7 +421,6 @@ pub const Type = struct { |
| 434 | 421 | std.hash.autoHash(hasher, ies); |
| 435 | 422 | }, |
| 436 | 423 | |
| 437 | .pointer, | |
| 438 | 424 | .inferred_alloc_const, |
| 439 | 425 | .inferred_alloc_mut, |
| 440 | 426 | => { |
| ... | ... | @@ -512,26 +498,6 @@ pub const Type = struct { |
| 512 | 498 | .inferred_alloc_mut, |
| 513 | 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 | 501 | .error_union => { |
| 536 | 502 | const payload = self.castTag(.error_union).?.data; |
| 537 | 503 | return Tag.error_union.create(allocator, .{ |
| ... | ... | @@ -623,41 +589,6 @@ pub const Type = struct { |
| 623 | 589 | while (true) { |
| 624 | 590 | const t = ty.tag(); |
| 625 | 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 | 592 | .error_union => { |
| 662 | 593 | const payload = ty.castTag(.error_union).?.data; |
| 663 | 594 | try payload.error_set.dump("", .{}, writer); |
| ... | ... | @@ -734,47 +665,6 @@ pub const Type = struct { |
| 734 | 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 | 668 | .error_set => { |
| 779 | 669 | const names = ty.castTag(.error_set).?.data.names.keys(); |
| 780 | 670 | try writer.writeAll("error{"); |
| ... | ... | @@ -951,8 +841,8 @@ pub const Type = struct { |
| 951 | 841 | try writer.writeAll("..."); |
| 952 | 842 | } |
| 953 | 843 | try writer.writeAll(") "); |
| 954 | if (fn_info.alignment != 0) { | |
| 955 | try writer.print("align({d}) ", .{fn_info.alignment}); | |
| 844 | if (fn_info.alignment.toByteUnitsOptional()) |a| { | |
| 845 | try writer.print("align({d}) ", .{a}); | |
| 956 | 846 | } |
| 957 | 847 | if (fn_info.cc != .Unspecified) { |
| 958 | 848 | try writer.writeAll("callconv(."); |
| ... | ... | @@ -1032,20 +922,6 @@ pub const Type = struct { |
| 1032 | 922 | .error_set_merged, |
| 1033 | 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 | 925 | .inferred_alloc_const => unreachable, |
| 1050 | 926 | .inferred_alloc_mut => unreachable, |
| 1051 | 927 | }, |
| ... | ... | @@ -1231,8 +1107,6 @@ pub const Type = struct { |
| 1231 | 1107 | .empty_struct_type => false, |
| 1232 | 1108 | |
| 1233 | 1109 | .none => switch (ty.tag()) { |
| 1234 | .pointer => true, | |
| 1235 | ||
| 1236 | 1110 | .error_set, |
| 1237 | 1111 | .error_set_single, |
| 1238 | 1112 | .error_set_inferred, |
| ... | ... | @@ -1410,51 +1284,27 @@ pub const Type = struct { |
| 1410 | 1284 | } |
| 1411 | 1285 | |
| 1412 | 1286 | pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 { |
| 1413 | switch (ty.ip_index) { | |
| 1414 | .none => switch (ty.tag()) { | |
| 1415 | .pointer => { | |
| 1416 | const ptr_info = ty.castTag(.pointer).?.data; | |
| 1417 | if (ptr_info.@"align" != 0) { | |
| 1418 | return ptr_info.@"align"; | |
| 1419 | } else if (opt_sema) |sema| { | |
| 1420 | const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema }); | |
| 1421 | return res.scalar; | |
| 1422 | } else { | |
| 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, | |
| 1287 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 1288 | .ptr_type => |ptr_type| { | |
| 1289 | if (ptr_type.alignment.toByteUnitsOptional()) |a| { | |
| 1290 | return @intCast(u32, a); | |
| 1291 | } else if (opt_sema) |sema| { | |
| 1292 | const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema }); | |
| 1293 | return res.scalar; | |
| 1294 | } else { | |
| 1295 | return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; | |
| 1296 | } | |
| 1442 | 1297 | }, |
| 1443 | } | |
| 1298 | .opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema), | |
| 1299 | else => unreachable, | |
| 1300 | }; | |
| 1444 | 1301 | } |
| 1445 | 1302 | |
| 1446 | 1303 | pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace { |
| 1447 | return switch (ty.ip_index) { | |
| 1448 | .none => switch (ty.tag()) { | |
| 1449 | .pointer => ty.castTag(.pointer).?.data.@"addrspace", | |
| 1450 | ||
| 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 | }, | |
| 1304 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 1305 | .ptr_type => |ptr_type| ptr_type.address_space, | |
| 1306 | .opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space, | |
| 1307 | else => unreachable, | |
| 1458 | 1308 | }; |
| 1459 | 1309 | } |
| 1460 | 1310 | |
| ... | ... | @@ -1504,7 +1354,6 @@ pub const Type = struct { |
| 1504 | 1354 | switch (ty.ip_index) { |
| 1505 | 1355 | .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 }, |
| 1506 | 1356 | .none => switch (ty.tag()) { |
| 1507 | .pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, | |
| 1508 | 1357 | |
| 1509 | 1358 | // TODO revisit this when we have the concept of the error tag type |
| 1510 | 1359 | .error_set_inferred, |
| ... | ... | @@ -1541,10 +1390,11 @@ pub const Type = struct { |
| 1541 | 1390 | .opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat), |
| 1542 | 1391 | .error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat), |
| 1543 | 1392 | // represents machine code; not a pointer |
| 1544 | .func_type => |func_type| { | |
| 1545 | const alignment = @intCast(u32, func_type.alignment); | |
| 1546 | if (alignment != 0) return AbiAlignmentAdvanced{ .scalar = alignment }; | |
| 1547 | return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) }; | |
| 1393 | .func_type => |func_type| return AbiAlignmentAdvanced{ | |
| 1394 | .scalar = if (func_type.alignment.toByteUnitsOptional()) |a| | |
| 1395 | @intCast(u32, a) | |
| 1396 | else | |
| 1397 | target_util.defaultFunctionAlignment(target), | |
| 1548 | 1398 | }, |
| 1549 | 1399 | |
| 1550 | 1400 | .simple_type => |t| switch (t) { |
| ... | ... | @@ -1882,11 +1732,6 @@ pub const Type = struct { |
| 1882 | 1732 | .inferred_alloc_const => unreachable, |
| 1883 | 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 | 1735 | // TODO revisit this when we have the concept of the error tag type |
| 1891 | 1736 | .error_set_inferred, |
| 1892 | 1737 | .error_set, |
| ... | ... | @@ -2201,11 +2046,6 @@ pub const Type = struct { |
| 2201 | 2046 | .inferred_alloc_const => unreachable, |
| 2202 | 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 | 2049 | .error_set, |
| 2210 | 2050 | .error_set_single, |
| 2211 | 2051 | .error_set_inferred, |
| ... | ... | @@ -2384,8 +2224,6 @@ pub const Type = struct { |
| 2384 | 2224 | .inferred_alloc_mut, |
| 2385 | 2225 | => true, |
| 2386 | 2226 | |
| 2387 | .pointer => ty.castTag(.pointer).?.data.size == .One, | |
| 2388 | ||
| 2389 | 2227 | else => false, |
| 2390 | 2228 | }, |
| 2391 | 2229 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | ... | @@ -2408,8 +2246,6 @@ pub const Type = struct { |
| 2408 | 2246 | .inferred_alloc_mut, |
| 2409 | 2247 | => .One, |
| 2410 | 2248 | |
| 2411 | .pointer => ty.castTag(.pointer).?.data.size, | |
| 2412 | ||
| 2413 | 2249 | else => null, |
| 2414 | 2250 | }, |
| 2415 | 2251 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | ... | @@ -2421,10 +2257,7 @@ pub const Type = struct { |
| 2421 | 2257 | |
| 2422 | 2258 | pub fn isSlice(ty: Type, mod: *const Module) bool { |
| 2423 | 2259 | return switch (ty.ip_index) { |
| 2424 | .none => switch (ty.tag()) { | |
| 2425 | .pointer => ty.castTag(.pointer).?.data.size == .Slice, | |
| 2426 | else => false, | |
| 2427 | }, | |
| 2260 | .none => false, | |
| 2428 | 2261 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2429 | 2262 | .ptr_type => |ptr_type| ptr_type.size == .Slice, |
| 2430 | 2263 | else => false, |
| ... | ... | @@ -2432,50 +2265,14 @@ pub const Type = struct { |
| 2432 | 2265 | }; |
| 2433 | 2266 | } |
| 2434 | 2267 | |
| 2435 | pub const SlicePtrFieldTypeBuffer = union { | |
| 2436 | pointer: Payload.Pointer, | |
| 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 | } | |
| 2268 | pub fn slicePtrFieldType(ty: Type, mod: *const Module) Type { | |
| 2269 | return mod.intern_pool.slicePtrType(ty.ip_index).toType(); | |
| 2470 | 2270 | } |
| 2471 | 2271 | |
| 2472 | 2272 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { |
| 2473 | 2273 | return switch (ty.ip_index) { |
| 2474 | .none => switch (ty.tag()) { | |
| 2475 | .pointer => !ty.castTag(.pointer).?.data.mutable, | |
| 2476 | else => false, | |
| 2477 | }, | |
| 2478 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2274 | .none => false, | |
| 2275 | else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2479 | 2276 | .ptr_type => |ptr_type| ptr_type.is_const, |
| 2480 | 2277 | else => false, |
| 2481 | 2278 | }, |
| ... | ... | @@ -2488,10 +2285,7 @@ pub const Type = struct { |
| 2488 | 2285 | |
| 2489 | 2286 | pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool { |
| 2490 | 2287 | return switch (ty.ip_index) { |
| 2491 | .none => switch (ty.tag()) { | |
| 2492 | .pointer => ty.castTag(.pointer).?.data.@"volatile", | |
| 2493 | else => false, | |
| 2494 | }, | |
| 2288 | .none => false, | |
| 2495 | 2289 | else => switch (ip.indexToKey(ty.ip_index)) { |
| 2496 | 2290 | .ptr_type => |ptr_type| ptr_type.is_volatile, |
| 2497 | 2291 | else => false, |
| ... | ... | @@ -2501,12 +2295,10 @@ pub const Type = struct { |
| 2501 | 2295 | |
| 2502 | 2296 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { |
| 2503 | 2297 | return switch (ty.ip_index) { |
| 2504 | .none => switch (ty.tag()) { | |
| 2505 | .pointer => ty.castTag(.pointer).?.data.@"allowzero", | |
| 2506 | else => ty.zigTypeTag(mod) == .Optional, | |
| 2507 | }, | |
| 2298 | .none => false, | |
| 2508 | 2299 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2509 | 2300 | .ptr_type => |ptr_type| ptr_type.is_allowzero, |
| 2301 | .opt_type => true, | |
| 2510 | 2302 | else => false, |
| 2511 | 2303 | }, |
| 2512 | 2304 | }; |
| ... | ... | @@ -2514,10 +2306,7 @@ pub const Type = struct { |
| 2514 | 2306 | |
| 2515 | 2307 | pub fn isCPtr(ty: Type, mod: *const Module) bool { |
| 2516 | 2308 | return switch (ty.ip_index) { |
| 2517 | .none => switch (ty.tag()) { | |
| 2518 | .pointer => ty.castTag(.pointer).?.data.size == .C, | |
| 2519 | else => false, | |
| 2520 | }, | |
| 2309 | .none => false, | |
| 2521 | 2310 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 2522 | 2311 | .ptr_type => |ptr_type| ptr_type.size == .C, |
| 2523 | 2312 | else => false, |
| ... | ... | @@ -2526,16 +2315,9 @@ pub const Type = struct { |
| 2526 | 2315 | } |
| 2527 | 2316 | |
| 2528 | 2317 | pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { |
| 2529 | switch (ty.ip_index) { | |
| 2530 | .none => switch (ty.tag()) { | |
| 2531 | .pointer => switch (ty.castTag(.pointer).?.data.size) { | |
| 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)) { | |
| 2318 | return switch (ty.ip_index) { | |
| 2319 | .none => false, | |
| 2320 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2539 | 2321 | .ptr_type => |ptr_type| switch (ptr_type.size) { |
| 2540 | 2322 | .Slice => false, |
| 2541 | 2323 | .One, .Many, .C => true, |
| ... | ... | @@ -2549,7 +2331,7 @@ pub const Type = struct { |
| 2549 | 2331 | }, |
| 2550 | 2332 | else => false, |
| 2551 | 2333 | }, |
| 2552 | } | |
| 2334 | }; | |
| 2553 | 2335 | } |
| 2554 | 2336 | |
| 2555 | 2337 | /// For pointer-like optionals, returns true, otherwise returns the allowzero property |
| ... | ... | @@ -2563,47 +2345,43 @@ pub const Type = struct { |
| 2563 | 2345 | |
| 2564 | 2346 | /// See also `isPtrLikeOptional`. |
| 2565 | 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)) { | |
| 2567 | .opt_type => |child| switch (child.toType().zigTypeTag(mod)) { | |
| 2568 | .Pointer => { | |
| 2569 | const info = child.toType().ptrInfo(mod); | |
| 2570 | switch (info.size) { | |
| 2571 | .C => return false, | |
| 2572 | else => return !info.@"allowzero", | |
| 2573 | } | |
| 2348 | return switch (ty.ip_index) { | |
| 2349 | .none => false, | |
| 2350 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2351 | .opt_type => |child| switch (child.toType().zigTypeTag(mod)) { | |
| 2352 | .Pointer => { | |
| 2353 | const info = child.toType().ptrInfo(mod); | |
| 2354 | return switch (info.size) { | |
| 2355 | .C => false, | |
| 2356 | else => !info.@"allowzero", | |
| 2357 | }; | |
| 2358 | }, | |
| 2359 | .ErrorSet => true, | |
| 2360 | else => false, | |
| 2574 | 2361 | }, |
| 2575 | .ErrorSet => true, | |
| 2576 | 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 | 2367 | /// Returns true if the type is optional and would be lowered to a single pointer |
| 2588 | 2368 | /// address value, using 0 for null. Note that this returns true for C pointers. |
| 2589 | 2369 | /// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`. |
| 2590 | 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)) { | |
| 2592 | .ptr_type => |ptr_type| ptr_type.size == .C, | |
| 2593 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | |
| 2594 | .ptr_type => |ptr_type| switch (ptr_type.size) { | |
| 2595 | .Slice, .C => false, | |
| 2596 | .Many, .One => !ptr_type.is_allowzero, | |
| 2371 | return switch (ty.ip_index) { | |
| 2372 | .none => false, | |
| 2373 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2374 | .ptr_type => |ptr_type| ptr_type.size == .C, | |
| 2375 | .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { | |
| 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 | 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 | 2387 | /// For *[N]T, returns [N]T. |
| ... | ... | @@ -2614,14 +2392,7 @@ pub const Type = struct { |
| 2614 | 2392 | } |
| 2615 | 2393 | |
| 2616 | 2394 | pub fn childTypeIp(ty: Type, ip: InternPool) Type { |
| 2617 | return switch (ty.ip_index) { | |
| 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 | }; | |
| 2395 | return ip.childType(ty.ip_index).toType(); | |
| 2625 | 2396 | } |
| 2626 | 2397 | |
| 2627 | 2398 | /// For *[N]T, returns T. |
| ... | ... | @@ -2634,34 +2405,19 @@ pub const Type = struct { |
| 2634 | 2405 | /// For []T, returns T. |
| 2635 | 2406 | /// For anyframe->T, returns T. |
| 2636 | 2407 | pub fn elemType2(ty: Type, mod: *const Module) Type { |
| 2637 | return switch (ty.ip_index) { | |
| 2638 | .none => switch (ty.tag()) { | |
| 2639 | .pointer => { | |
| 2640 | const info = ty.castTag(.pointer).?.data; | |
| 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, | |
| 2408 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2409 | .ptr_type => |ptr_type| switch (ptr_type.size) { | |
| 2410 | .One => ptr_type.elem_type.toType().shallowElemType(mod), | |
| 2411 | .Many, .C, .Slice => ptr_type.elem_type.toType(), | |
| 2650 | 2412 | }, |
| 2651 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2652 | .ptr_type => |ptr_type| switch (ptr_type.size) { | |
| 2653 | .One => ptr_type.elem_type.toType().shallowElemType(mod), | |
| 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, | |
| 2413 | .anyframe_type => |child| { | |
| 2414 | assert(child != .none); | |
| 2415 | return child.toType(); | |
| 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 | 2439 | /// Asserts that the type is an optional. |
| 2684 | 2440 | /// Note that for C pointers this returns the type unmodified. |
| 2685 | 2441 | pub fn optionalChild(ty: Type, mod: *const Module) Type { |
| 2686 | return switch (ty.ip_index) { | |
| 2687 | .none => switch (ty.tag()) { | |
| 2688 | .pointer, // here we assume it is a C pointer | |
| 2689 | => return ty, | |
| 2690 | ||
| 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, | |
| 2442 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2443 | .opt_type => |child| child.toType(), | |
| 2444 | .ptr_type => |ptr_type| b: { | |
| 2445 | assert(ptr_type.size == .C); | |
| 2446 | break :b ty; | |
| 2700 | 2447 | }, |
| 2448 | else => unreachable, | |
| 2701 | 2449 | }; |
| 2702 | 2450 | } |
| 2703 | 2451 | |
| ... | ... | @@ -2921,23 +2669,16 @@ pub const Type = struct { |
| 2921 | 2669 | |
| 2922 | 2670 | /// Asserts the type is an array, pointer or vector. |
| 2923 | 2671 | pub fn sentinel(ty: Type, mod: *const Module) ?Value { |
| 2924 | return switch (ty.ip_index) { | |
| 2925 | .none => switch (ty.tag()) { | |
| 2926 | .pointer => ty.castTag(.pointer).?.data.sentinel, | |
| 2927 | ||
| 2928 | else => unreachable, | |
| 2929 | }, | |
| 2930 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2931 | .vector_type, | |
| 2932 | .struct_type, | |
| 2933 | .anon_struct_type, | |
| 2934 | => null, | |
| 2672 | return switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 2673 | .vector_type, | |
| 2674 | .struct_type, | |
| 2675 | .anon_struct_type, | |
| 2676 | => null, | |
| 2935 | 2677 | |
| 2936 | .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, | |
| 2678 | .array_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, | |
| 2940 | }, | |
| 2681 | else => unreachable, | |
| 2941 | 2682 | }; |
| 2942 | 2683 | } |
| 2943 | 2684 | |
| ... | ... | @@ -3196,7 +2937,6 @@ pub const Type = struct { |
| 3196 | 2937 | .error_set, |
| 3197 | 2938 | .error_set_merged, |
| 3198 | 2939 | .error_set_inferred, |
| 3199 | .pointer, | |
| 3200 | 2940 | => return null, |
| 3201 | 2941 | |
| 3202 | 2942 | .inferred_alloc_const => unreachable, |
| ... | ... | @@ -3400,15 +3140,6 @@ pub const Type = struct { |
| 3400 | 3140 | .inferred_alloc_mut => unreachable, |
| 3401 | 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 | 3143 | .error_union => return ty.errorUnionPayload().comptimeOnly(mod), |
| 3413 | 3144 | }, |
| 3414 | 3145 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| ... | ... | @@ -4096,7 +3827,6 @@ pub const Type = struct { |
| 4096 | 3827 | inferred_alloc_const, // See last_no_payload_tag below. |
| 4097 | 3828 | // After this, the tag requires a payload. |
| 4098 | 3829 | |
| 4099 | pointer, | |
| 4100 | 3830 | error_union, |
| 4101 | 3831 | error_set, |
| 4102 | 3832 | error_set_single, |
| ... | ... | @@ -4117,7 +3847,6 @@ pub const Type = struct { |
| 4117 | 3847 | .error_set_inferred => Payload.ErrorSetInferred, |
| 4118 | 3848 | .error_set_merged => Payload.ErrorSetMerged, |
| 4119 | 3849 | |
| 4120 | .pointer => Payload.Pointer, | |
| 4121 | 3850 | .error_union => Payload.ErrorUnion, |
| 4122 | 3851 | .error_set_single => Payload.Name, |
| 4123 | 3852 | }; |
| ... | ... | @@ -4230,10 +3959,8 @@ pub const Type = struct { |
| 4230 | 3959 | data: *Module.Fn.InferredErrorSet, |
| 4231 | 3960 | }; |
| 4232 | 3961 | |
| 3962 | /// TODO: remove this data structure since we have `InternPool.Key.PtrType`. | |
| 4233 | 3963 | pub const Pointer = struct { |
| 4234 | pub const base_tag = Tag.pointer; | |
| 4235 | ||
| 4236 | base: Payload = Payload{ .tag = base_tag }, | |
| 4237 | 3964 | data: Data, |
| 4238 | 3965 | |
| 4239 | 3966 | pub const Data = struct { |
| ... | ... | @@ -4270,7 +3997,7 @@ pub const Type = struct { |
| 4270 | 3997 | return .{ |
| 4271 | 3998 | .pointee_type = p.elem_type.toType(), |
| 4272 | 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 | 4001 | .@"addrspace" = p.address_space, |
| 4275 | 4002 | .bit_offset = p.bit_offset, |
| 4276 | 4003 | .host_size = p.host_size, |
| ... | ... | @@ -4368,11 +4095,11 @@ pub const Type = struct { |
| 4368 | 4095 | pub const err_int = Type.u16; |
| 4369 | 4096 | |
| 4370 | 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) { | |
| 4374 | d.@"allowzero" = true; | |
| 4375 | } | |
| 4102 | var d = data; | |
| 4376 | 4103 | |
| 4377 | 4104 | // Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee |
| 4378 | 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 | 4123 | } |
| 4397 | 4124 | } |
| 4398 | 4125 | |
| 4399 | ip: { | |
| 4400 | if (d.pointee_type.ip_index == .none) break :ip; | |
| 4401 | ||
| 4402 | if (d.sentinel) |s| { | |
| 4403 | switch (s.ip_index) { | |
| 4404 | .none, .null_value => break :ip, | |
| 4405 | else => {}, | |
| 4406 | } | |
| 4407 | } | |
| 4408 | ||
| 4409 | return mod.ptrType(.{ | |
| 4410 | .elem_type = d.pointee_type.ip_index, | |
| 4411 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | |
| 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); | |
| 4126 | return mod.ptrType(.{ | |
| 4127 | .elem_type = d.pointee_type.ip_index, | |
| 4128 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | |
| 4129 | .alignment = InternPool.Alignment.fromByteUnits(d.@"align"), | |
| 4130 | .host_size = d.host_size, | |
| 4131 | .bit_offset = d.bit_offset, | |
| 4132 | .vector_index = d.vector_index, | |
| 4133 | .size = d.size, | |
| 4134 | .is_const = !d.mutable, | |
| 4135 | .is_volatile = d.@"volatile", | |
| 4136 | .is_allowzero = d.@"allowzero", | |
| 4137 | .address_space = d.@"addrspace", | |
| 4138 | }); | |
| 4425 | 4139 | } |
| 4426 | 4140 | |
| 4427 | 4141 | pub fn array( |
src/value.zig+4-8| ... | ... | @@ -1844,8 +1844,7 @@ pub const Value = struct { |
| 1844 | 1844 | return false; |
| 1845 | 1845 | } |
| 1846 | 1846 | |
| 1847 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 1848 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | |
| 1847 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 1849 | 1848 | |
| 1850 | 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 | 2000 | return false; |
| 2002 | 2001 | } |
| 2003 | 2002 | |
| 2004 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2005 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | |
| 2003 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 2006 | 2004 | const a_ptr = switch (a_ty.ptrSize(mod)) { |
| 2007 | 2005 | .Slice => a.slicePtr(), |
| 2008 | 2006 | .One => a, |
| ... | ... | @@ -2121,8 +2119,7 @@ pub const Value = struct { |
| 2121 | 2119 | .Bool, .Int, .ComptimeInt, .Pointer => switch (val.tag()) { |
| 2122 | 2120 | .slice => { |
| 2123 | 2121 | const slice = val.castTag(.slice).?.data; |
| 2124 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2125 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | |
| 2122 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 2126 | 2123 | hash(slice.ptr, ptr_ty, hasher, mod); |
| 2127 | 2124 | hash(slice.len, Type.usize, hasher, mod); |
| 2128 | 2125 | }, |
| ... | ... | @@ -2253,8 +2250,7 @@ pub const Value = struct { |
| 2253 | 2250 | .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) { |
| 2254 | 2251 | .slice => { |
| 2255 | 2252 | const slice = val.castTag(.slice).?.data; |
| 2256 | var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | |
| 2257 | const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod); | |
| 2253 | const ptr_ty = ty.slicePtrFieldType(mod); | |
| 2258 | 2254 | slice.ptr.hashUncoerced(ptr_ty, hasher, mod); |
| 2259 | 2255 | }, |
| 2260 | 2256 | else => val.hashPtr(hasher, mod), |